diff --git a/Src/java/.vscode/settings.json b/Src/java/.vscode/settings.json index a866b22c3..a4c43a682 100644 --- a/Src/java/.vscode/settings.json +++ b/Src/java/.vscode/settings.json @@ -10,7 +10,10 @@ "fhirpath", "hamcrest", "Inferencing", + "Instancio", + "Objenesis", "qicore", + "Randomizer", "testng", "tngtech", "trackback" diff --git a/Src/java/buildSrc/src/main/groovy/cql.java-conventions.gradle b/Src/java/buildSrc/src/main/groovy/cql.java-conventions.gradle index 07124b22d..5ae2d3185 100644 --- a/Src/java/buildSrc/src/main/groovy/cql.java-conventions.gradle +++ b/Src/java/buildSrc/src/main/groovy/cql.java-conventions.gradle @@ -29,7 +29,7 @@ dependencies { testImplementation 'org.testng:testng:7.4.0' testImplementation 'org.hamcrest:hamcrest-all:1.3' testImplementation 'uk.co.datumedge:hamcrest-json:0.2' - testImplementation 'junit:junit:4.12' + testImplementation 'junit:junit:4.13.2' testImplementation 'org.slf4j:slf4j-simple:1.7.36' // These are JAXB dependencies excluded because the libraries need to work diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java index 1f1c62eda..bec0db122 100644 --- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java +++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmRequirementsVisitor.java @@ -1,6 +1,6 @@ package org.cqframework.cql.elm.requirements; -import org.cqframework.cql.elm.visiting.ElmBaseLibraryVisitor; +import org.cqframework.cql.elm.visiting.BaseElmLibraryVisitor; import org.hl7.cql.model.ListType; import org.hl7.elm.r1.*; @@ -46,7 +46,7 @@ At an AND, if there are already lists of lists, the condition is too complex for At a logical expression, return ElmConjunctiveRequirement or ElmDisjunctiveRequirement */ -public class ElmRequirementsVisitor extends ElmBaseLibraryVisitor { +public class ElmRequirementsVisitor extends BaseElmLibraryVisitor { public ElmRequirementsVisitor() { super(); @@ -105,7 +105,8 @@ public ElmRequirement visitExpressionRef(ExpressionRef elm, ElmRequirementsConte result = context.reportExpressionRef(elm); } if (result != null) { - // If the expression ref is to a retrieve or a single-source query, surface it as an "inferred" requirement + // If the expression ref is to a retrieve or a single-source query, surface it + // as an "inferred" requirement // in the referencing scope if (result instanceof ElmDataRequirement) { ElmDataRequirement inferredRequirement = ElmDataRequirement.inferFrom((ElmDataRequirement) result); @@ -134,7 +135,8 @@ public ElmRequirement visitFunctionRef(FunctionRef elm, ElmRequirementsContext c if (elm.getOperand().size() != 1 || (elm.getOperand().get(0).getResultType() instanceof ListType && !(elm.getResultType() instanceof ListType))) { - // Note that the assumption here is that the data requirement has already been reported to the context + // Note that the assumption here is that the data requirement has already been + // reported to the context return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm) .combine((ElmDataRequirement) result); } @@ -169,8 +171,10 @@ public ElmRequirement visitRetrieve(Retrieve elm, ElmRequirementsContext context if (elmPertinenceContext != null) { result.setPertinenceContext(elmPertinenceContext); } - // If not analyzing requirements, or in a query context, report the data requirement - // If in a query context, the requirement will be reported as an inferred requirement at the query boundary + // If not analyzing requirements, or in a query context, report the data + // requirement + // If in a query context, the requirement will be reported as an inferred + // requirement at the query boundary if (!context.getOptions().getAnalyzeDataRequirements() || !context.inQueryContext()) { context.reportRequirements(result, null); } @@ -247,30 +251,18 @@ public ElmRequirement visitConceptDef(ConceptDef elm, ElmRequirementsContext con return super.visitConceptDef(elm, context); } - @Override - public ElmRequirement visitExpression(Expression elm, ElmRequirementsContext context) { - return super.visitExpression(elm, context); - } - - @Override - public ElmRequirement visitOperatorExpression(OperatorExpression elm, ElmRequirementsContext context) { - return super.visitOperatorExpression(elm, context); - } - - @Override - public ElmRequirement visitUnaryExpression(UnaryExpression elm, ElmRequirementsContext context) { - return super.visitUnaryExpression(elm, context); - } - /** - * If both sides are column references that point to the same column in the same alias - * the condition is a tautology - * If both sides are column references that point to different columns in the same alias - * the condition is a constraint + * If both sides are column references that point to the same column in the same + * alias + * the condition is a tautology + * If both sides are column references that point to different columns in the + * same alias + * the condition is a constraint * If both sides are column references that point to different aliases - * the condition is a join + * the condition is a join * If one side or the other is a column reference - * the condition is a potentially sargeable condition + * the condition is a potentially sargeable condition + * * @param elm * @param context * @param left @@ -322,22 +314,26 @@ protected ElmRequirement inferConditionRequirement( } @Override - public ElmRequirement visitChildren(BinaryExpression elm, ElmRequirementsContext context) { - // Override visit children behavior to determine whether to create an ElmConditionRequirement + public ElmRequirement visitFields(BinaryExpression elm, ElmRequirementsContext context) { + // Override visit children behavior to determine whether to create an + // ElmConditionRequirement if (elm.getOperand().size() != 2) { - return super.visitChildren(elm, context); + throw new IllegalArgumentException("BinaryExpression must have two operands."); } switch (elm.getClass().getSimpleName()) { /** * Determine whether the condition is sargeable: * - * A op B + * A op B * * Where: - * * A is an order-preserving expression with a single property reference to a property of some source in the current query context - * * op is a positive relative comparison operation (=, >, <, >=, <=) or a membership operator (in, contains) - * * B is a functional, repeatable, and deterministic context literal expression with respect to the current query context + * * A is an order-preserving expression with a single property reference to a + * property of some source in the current query context + * * op is a positive relative comparison operation (=, >, <, >=, <=) or a + * membership operator (in, contains) + * * B is a functional, repeatable, and deterministic context literal expression + * with respect to the current query context */ case "Equal": case "Equivalent": @@ -358,9 +354,11 @@ public ElmRequirement visitChildren(BinaryExpression elm, ElmRequirementsContext } /** - * Gather sargeable conditions as Lists of conditions. At an AND, combine conditions from sub-nodes. + * Gather sargeable conditions as Lists of conditions. At an AND, combine + * conditions from sub-nodes. * At an OR, the result is separate lists of condition lists. - * At an AND, if there are already lists of lists, the condition is too complex for analysis (i.e. it's not in DNF or CNF) + * At an AND, if there are already lists of lists, the condition is too complex + * for analysis (i.e. it's not in DNF or CNF) */ // TODO: Normalize to DNF case "And": { @@ -415,17 +413,12 @@ public ElmRequirement visitChildren(BinaryExpression elm, ElmRequirementsContext case "ProperIncludes": case "ProperIncludedIn": default: { - super.visitChildren(elm, context); + super.visitFields(elm, context); return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm); } } } - @Override - public ElmRequirement visitBinaryExpression(BinaryExpression elm, ElmRequirementsContext context) { - return super.visitBinaryExpression(elm, context); - } - @Override public ElmRequirement visitTernaryExpression(TernaryExpression elm, ElmRequirementsContext context) { ElmRequirement requirements = super.visitTernaryExpression(elm, context); @@ -438,11 +431,6 @@ public ElmRequirement visitNaryExpression(NaryExpression elm, ElmRequirementsCon return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm).combine(requirements); } - @Override - public ElmRequirement visitOperandDef(OperandDef elm, ElmRequirementsContext context) { - return super.visitOperandDef(elm, context); - } - @Override public ElmRequirement visitOperandRef(OperandRef elm, ElmRequirementsContext context) { return new ElmExpressionRequirement(context.getCurrentLibraryIdentifier(), elm); @@ -458,26 +446,6 @@ public ElmRequirement visitLiteral(Literal elm, ElmRequirementsContext context) return new ElmExpressionRequirement(context.getCurrentLibraryIdentifier(), elm); } - @Override - public ElmRequirement visitTupleElement(TupleElement elm, ElmRequirementsContext context) { - return super.visitTupleElement(elm, context); - } - - @Override - public ElmRequirement visitTuple(Tuple elm, ElmRequirementsContext context) { - return super.visitTuple(elm, context); - } - - @Override - public ElmRequirement visitInstanceElement(InstanceElement elm, ElmRequirementsContext context) { - return super.visitInstanceElement(elm, context); - } - - @Override - public ElmRequirement visitInstance(Instance elm, ElmRequirementsContext context) { - return super.visitInstance(elm, context); - } - @Override public ElmRequirement visitInterval(Interval elm, ElmRequirementsContext context) { ElmRequirement result = super.visitInterval(elm, context); @@ -486,42 +454,12 @@ public ElmRequirement visitInterval(Interval elm, ElmRequirementsContext context return finalResult; } - @Override - public ElmRequirement visitList(List elm, ElmRequirementsContext context) { - return super.visitList(elm, context); - } - - @Override - public ElmRequirement visitAnd(And elm, ElmRequirementsContext context) { - return super.visitAnd(elm, context); - } - - @Override - public ElmRequirement visitOr(Or elm, ElmRequirementsContext context) { - return super.visitOr(elm, context); - } - - @Override - public ElmRequirement visitXor(Xor elm, ElmRequirementsContext context) { - return super.visitXor(elm, context); - } - - @Override - public ElmRequirement visitNot(Not elm, ElmRequirementsContext context) { - return super.visitNot(elm, context); - } - @Override public ElmRequirement visitIf(If elm, ElmRequirementsContext context) { // TODO: Rewrite the if as equivalent logic return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm); } - @Override - public ElmRequirement visitCaseItem(CaseItem elm, ElmRequirementsContext context) { - return super.visitCaseItem(elm, context); - } - @Override public ElmRequirement visitCase(Case elm, ElmRequirementsContext context) { // TODO: Rewrite the case as equivalent logic @@ -556,295 +494,16 @@ public ElmRequirement visitNull(Null elm, ElmRequirementsContext context) { return new ElmExpressionRequirement(context.getCurrentLibraryIdentifier(), elm); } - @Override - public ElmRequirement visitIsNull(IsNull elm, ElmRequirementsContext context) { - return super.visitIsNull(elm, context); - } - - @Override - public ElmRequirement visitIsTrue(IsTrue elm, ElmRequirementsContext context) { - return super.visitIsTrue(elm, context); - } - - @Override - public ElmRequirement visitIsFalse(IsFalse elm, ElmRequirementsContext context) { - return super.visitIsFalse(elm, context); - } - - @Override - public ElmRequirement visitCoalesce(Coalesce elm, ElmRequirementsContext context) { - return super.visitCoalesce(elm, context); - } - - @Override - public ElmRequirement visitIs(Is elm, ElmRequirementsContext context) { - return super.visitIs(elm, context); - } - - @Override - public ElmRequirement visitAs(As elm, ElmRequirementsContext context) { - return super.visitAs(elm, context); - } - - @Override - public ElmRequirement visitConvert(Convert elm, ElmRequirementsContext context) { - return super.visitConvert(elm, context); - } - - @Override - public ElmRequirement visitToBoolean(ToBoolean elm, ElmRequirementsContext context) { - return super.visitToBoolean(elm, context); - } - - @Override - public ElmRequirement visitToConcept(ToConcept elm, ElmRequirementsContext context) { - return super.visitToConcept(elm, context); - } - - @Override - public ElmRequirement visitToDateTime(ToDateTime elm, ElmRequirementsContext context) { - return super.visitToDateTime(elm, context); - } - - @Override - public ElmRequirement visitToDecimal(ToDecimal elm, ElmRequirementsContext context) { - return super.visitToDecimal(elm, context); - } - - @Override - public ElmRequirement visitToInteger(ToInteger elm, ElmRequirementsContext context) { - return super.visitToInteger(elm, context); - } - - @Override - public ElmRequirement visitToQuantity(ToQuantity elm, ElmRequirementsContext context) { - return super.visitToQuantity(elm, context); - } - - @Override - public ElmRequirement visitToString(ToString elm, ElmRequirementsContext context) { - return super.visitToString(elm, context); - } - - @Override - public ElmRequirement visitToTime(ToTime elm, ElmRequirementsContext context) { - return super.visitToTime(elm, context); - } - - @Override - public ElmRequirement visitEqual(Equal elm, ElmRequirementsContext context) { - return super.visitEqual(elm, context); - } - - @Override - public ElmRequirement visitEquivalent(Equivalent elm, ElmRequirementsContext context) { - return super.visitEquivalent(elm, context); - } - - @Override - public ElmRequirement visitNotEqual(NotEqual elm, ElmRequirementsContext context) { - return super.visitNotEqual(elm, context); - } - - @Override - public ElmRequirement visitLess(Less elm, ElmRequirementsContext context) { - return super.visitLess(elm, context); - } - - @Override - public ElmRequirement visitGreater(Greater elm, ElmRequirementsContext context) { - return super.visitGreater(elm, context); - } - - @Override - public ElmRequirement visitLessOrEqual(LessOrEqual elm, ElmRequirementsContext context) { - return super.visitLessOrEqual(elm, context); - } - - @Override - public ElmRequirement visitGreaterOrEqual(GreaterOrEqual elm, ElmRequirementsContext context) { - return super.visitGreaterOrEqual(elm, context); - } - - @Override - public ElmRequirement visitAdd(Add elm, ElmRequirementsContext context) { - return super.visitAdd(elm, context); - } - - @Override - public ElmRequirement visitSubtract(Subtract elm, ElmRequirementsContext context) { - return super.visitSubtract(elm, context); - } - - @Override - public ElmRequirement visitMultiply(Multiply elm, ElmRequirementsContext context) { - return super.visitMultiply(elm, context); - } - - @Override - public ElmRequirement visitDivide(Divide elm, ElmRequirementsContext context) { - return super.visitDivide(elm, context); - } - - @Override - public ElmRequirement visitTruncatedDivide(TruncatedDivide elm, ElmRequirementsContext context) { - return super.visitTruncatedDivide(elm, context); - } - - @Override - public ElmRequirement visitModulo(Modulo elm, ElmRequirementsContext context) { - return super.visitModulo(elm, context); - } - - @Override - public ElmRequirement visitCeiling(Ceiling elm, ElmRequirementsContext context) { - return super.visitCeiling(elm, context); - } - - @Override - public ElmRequirement visitFloor(Floor elm, ElmRequirementsContext context) { - return super.visitFloor(elm, context); - } - - @Override - public ElmRequirement visitTruncate(Truncate elm, ElmRequirementsContext context) { - return super.visitTruncate(elm, context); - } - - @Override - public ElmRequirement visitAbs(Abs elm, ElmRequirementsContext context) { - return super.visitAbs(elm, context); - } - - @Override - public ElmRequirement visitNegate(Negate elm, ElmRequirementsContext context) { - return super.visitNegate(elm, context); - } - - @Override - public ElmRequirement visitRound(Round elm, ElmRequirementsContext context) { - return super.visitRound(elm, context); - } - - @Override - public ElmRequirement visitLn(Ln elm, ElmRequirementsContext context) { - return super.visitLn(elm, context); - } - - @Override - public ElmRequirement visitExp(Exp elm, ElmRequirementsContext context) { - return super.visitExp(elm, context); - } - - @Override - public ElmRequirement visitLog(Log elm, ElmRequirementsContext context) { - return super.visitLog(elm, context); - } - - @Override - public ElmRequirement visitPower(Power elm, ElmRequirementsContext context) { - return super.visitPower(elm, context); - } - - @Override - public ElmRequirement visitSuccessor(Successor elm, ElmRequirementsContext context) { - return super.visitSuccessor(elm, context); - } - - @Override - public ElmRequirement visitPredecessor(Predecessor elm, ElmRequirementsContext context) { - return super.visitPredecessor(elm, context); - } - - @Override - public ElmRequirement visitMinValue(MinValue elm, ElmRequirementsContext context) { - return super.visitMinValue(elm, context); - } - - @Override - public ElmRequirement visitMaxValue(MaxValue elm, ElmRequirementsContext context) { - return super.visitMaxValue(elm, context); - } - - @Override - public ElmRequirement visitConcatenate(Concatenate elm, ElmRequirementsContext context) { - return super.visitConcatenate(elm, context); - } - - @Override - public ElmRequirement visitCombine(Combine elm, ElmRequirementsContext context) { - return super.visitCombine(elm, context); - } - @Override public ElmRequirement visitSplit(Split elm, ElmRequirementsContext context) { - // If the separator is a literal, infer based only on the string to split argument + // If the separator is a literal, infer based only on the string to split + // argument if (elm.getSeparator() instanceof Literal) { return visitElement(elm.getStringToSplit(), context); } return super.visitSplit(elm, context); } - @Override - public ElmRequirement visitLength(Length elm, ElmRequirementsContext context) { - return super.visitLength(elm, context); - } - - @Override - public ElmRequirement visitUpper(Upper elm, ElmRequirementsContext context) { - return super.visitUpper(elm, context); - } - - @Override - public ElmRequirement visitLower(Lower elm, ElmRequirementsContext context) { - return super.visitLower(elm, context); - } - - @Override - public ElmRequirement visitIndexer(Indexer elm, ElmRequirementsContext context) { - return super.visitIndexer(elm, context); - } - - @Override - public ElmRequirement visitPositionOf(PositionOf elm, ElmRequirementsContext context) { - return super.visitPositionOf(elm, context); - } - - @Override - public ElmRequirement visitSubstring(Substring elm, ElmRequirementsContext context) { - return super.visitSubstring(elm, context); - } - - @Override - public ElmRequirement visitDurationBetween(DurationBetween elm, ElmRequirementsContext context) { - return super.visitDurationBetween(elm, context); - } - - @Override - public ElmRequirement visitDifferenceBetween(DifferenceBetween elm, ElmRequirementsContext context) { - return super.visitDifferenceBetween(elm, context); - } - - @Override - public ElmRequirement visitDateFrom(DateFrom elm, ElmRequirementsContext context) { - return super.visitDateFrom(elm, context); - } - - @Override - public ElmRequirement visitTimeFrom(TimeFrom elm, ElmRequirementsContext context) { - return super.visitTimeFrom(elm, context); - } - - @Override - public ElmRequirement visitTimezoneOffsetFrom(TimezoneOffsetFrom elm, ElmRequirementsContext context) { - return super.visitTimezoneOffsetFrom(elm, context); - } - - @Override - public ElmRequirement visitDateTimeComponentFrom(DateTimeComponentFrom elm, ElmRequirementsContext context) { - return super.visitDateTimeComponentFrom(elm, context); - } - @Override public ElmRequirement visitTimeOfDay(TimeOfDay elm, ElmRequirementsContext context) { return new ElmOperatorRequirement(context.getCurrentLibraryIdentifier(), elm); @@ -968,276 +627,6 @@ public ElmRequirement visitTime(Time elm, ElmRequirementsContext context) { return result; } - @Override - public ElmRequirement visitSameAs(SameAs elm, ElmRequirementsContext context) { - return super.visitSameAs(elm, context); - } - - @Override - public ElmRequirement visitSameOrBefore(SameOrBefore elm, ElmRequirementsContext context) { - return super.visitSameOrBefore(elm, context); - } - - @Override - public ElmRequirement visitSameOrAfter(SameOrAfter elm, ElmRequirementsContext context) { - return super.visitSameOrAfter(elm, context); - } - - @Override - public ElmRequirement visitWidth(Width elm, ElmRequirementsContext context) { - return super.visitWidth(elm, context); - } - - @Override - public ElmRequirement visitStart(Start elm, ElmRequirementsContext context) { - return super.visitStart(elm, context); - } - - @Override - public ElmRequirement visitEnd(End elm, ElmRequirementsContext context) { - return super.visitEnd(elm, context); - } - - @Override - public ElmRequirement visitContains(Contains elm, ElmRequirementsContext context) { - return super.visitContains(elm, context); - } - - @Override - public ElmRequirement visitProperContains(ProperContains elm, ElmRequirementsContext context) { - return super.visitProperContains(elm, context); - } - - @Override - public ElmRequirement visitIn(In elm, ElmRequirementsContext context) { - return super.visitIn(elm, context); - } - - @Override - public ElmRequirement visitProperIn(ProperIn elm, ElmRequirementsContext context) { - return super.visitProperIn(elm, context); - } - - @Override - public ElmRequirement visitIncludes(Includes elm, ElmRequirementsContext context) { - return super.visitIncludes(elm, context); - } - - @Override - public ElmRequirement visitIncludedIn(IncludedIn elm, ElmRequirementsContext context) { - return super.visitIncludedIn(elm, context); - } - - @Override - public ElmRequirement visitProperIncludes(ProperIncludes elm, ElmRequirementsContext context) { - return super.visitProperIncludes(elm, context); - } - - @Override - public ElmRequirement visitProperIncludedIn(ProperIncludedIn elm, ElmRequirementsContext context) { - return super.visitProperIncludedIn(elm, context); - } - - @Override - public ElmRequirement visitBefore(Before elm, ElmRequirementsContext context) { - return super.visitBefore(elm, context); - } - - @Override - public ElmRequirement visitAfter(After elm, ElmRequirementsContext context) { - return super.visitAfter(elm, context); - } - - @Override - public ElmRequirement visitMeets(Meets elm, ElmRequirementsContext context) { - return super.visitMeets(elm, context); - } - - @Override - public ElmRequirement visitMeetsBefore(MeetsBefore elm, ElmRequirementsContext context) { - return super.visitMeetsBefore(elm, context); - } - - @Override - public ElmRequirement visitMeetsAfter(MeetsAfter elm, ElmRequirementsContext context) { - return super.visitMeetsAfter(elm, context); - } - - @Override - public ElmRequirement visitOverlaps(Overlaps elm, ElmRequirementsContext context) { - return super.visitOverlaps(elm, context); - } - - @Override - public ElmRequirement visitOverlapsBefore(OverlapsBefore elm, ElmRequirementsContext context) { - return super.visitOverlapsBefore(elm, context); - } - - @Override - public ElmRequirement visitOverlapsAfter(OverlapsAfter elm, ElmRequirementsContext context) { - return super.visitOverlapsAfter(elm, context); - } - - @Override - public ElmRequirement visitStarts(Starts elm, ElmRequirementsContext context) { - return super.visitStarts(elm, context); - } - - @Override - public ElmRequirement visitEnds(Ends elm, ElmRequirementsContext context) { - return super.visitEnds(elm, context); - } - - @Override - public ElmRequirement visitCollapse(Collapse elm, ElmRequirementsContext context) { - return super.visitCollapse(elm, context); - } - - @Override - public ElmRequirement visitUnion(Union elm, ElmRequirementsContext context) { - return super.visitUnion(elm, context); - } - - @Override - public ElmRequirement visitIntersect(Intersect elm, ElmRequirementsContext context) { - return super.visitIntersect(elm, context); - } - - @Override - public ElmRequirement visitExcept(Except elm, ElmRequirementsContext context) { - return super.visitExcept(elm, context); - } - - @Override - public ElmRequirement visitExists(Exists elm, ElmRequirementsContext context) { - return super.visitExists(elm, context); - } - - @Override - public ElmRequirement visitTimes(Times elm, ElmRequirementsContext context) { - return super.visitTimes(elm, context); - } - - @Override - public ElmRequirement visitFilter(Filter elm, ElmRequirementsContext context) { - return super.visitFilter(elm, context); - } - - @Override - public ElmRequirement visitFirst(First elm, ElmRequirementsContext context) { - return super.visitFirst(elm, context); - } - - @Override - public ElmRequirement visitLast(Last elm, ElmRequirementsContext context) { - return super.visitLast(elm, context); - } - - @Override - public ElmRequirement visitIndexOf(IndexOf elm, ElmRequirementsContext context) { - return super.visitIndexOf(elm, context); - } - - @Override - public ElmRequirement visitFlatten(Flatten elm, ElmRequirementsContext context) { - return super.visitFlatten(elm, context); - } - - @Override - public ElmRequirement visitSort(Sort elm, ElmRequirementsContext context) { - return super.visitSort(elm, context); - } - - @Override - public ElmRequirement visitForEach(ForEach elm, ElmRequirementsContext context) { - return super.visitForEach(elm, context); - } - - @Override - public ElmRequirement visitDistinct(Distinct elm, ElmRequirementsContext context) { - return super.visitDistinct(elm, context); - } - - @Override - public ElmRequirement visitCurrent(Current elm, ElmRequirementsContext context) { - return super.visitCurrent(elm, context); - } - - @Override - public ElmRequirement visitSingletonFrom(SingletonFrom elm, ElmRequirementsContext context) { - return super.visitSingletonFrom(elm, context); - } - - @Override - public ElmRequirement visitAggregateExpression(AggregateExpression elm, ElmRequirementsContext context) { - return super.visitAggregateExpression(elm, context); - } - - @Override - public ElmRequirement visitCount(Count elm, ElmRequirementsContext context) { - return super.visitCount(elm, context); - } - - @Override - public ElmRequirement visitSum(Sum elm, ElmRequirementsContext context) { - return super.visitSum(elm, context); - } - - @Override - public ElmRequirement visitMin(Min elm, ElmRequirementsContext context) { - return super.visitMin(elm, context); - } - - @Override - public ElmRequirement visitMax(Max elm, ElmRequirementsContext context) { - return super.visitMax(elm, context); - } - - @Override - public ElmRequirement visitAvg(Avg elm, ElmRequirementsContext context) { - return super.visitAvg(elm, context); - } - - @Override - public ElmRequirement visitMedian(Median elm, ElmRequirementsContext context) { - return super.visitMedian(elm, context); - } - - @Override - public ElmRequirement visitMode(Mode elm, ElmRequirementsContext context) { - return super.visitMode(elm, context); - } - - @Override - public ElmRequirement visitVariance(Variance elm, ElmRequirementsContext context) { - return super.visitVariance(elm, context); - } - - @Override - public ElmRequirement visitPopulationVariance(PopulationVariance elm, ElmRequirementsContext context) { - return super.visitPopulationVariance(elm, context); - } - - @Override - public ElmRequirement visitStdDev(StdDev elm, ElmRequirementsContext context) { - return super.visitStdDev(elm, context); - } - - @Override - public ElmRequirement visitPopulationStdDev(PopulationStdDev elm, ElmRequirementsContext context) { - return super.visitPopulationStdDev(elm, context); - } - - @Override - public ElmRequirement visitAllTrue(AllTrue elm, ElmRequirementsContext context) { - return super.visitAllTrue(elm, context); - } - - @Override - public ElmRequirement visitAnyTrue(AnyTrue elm, ElmRequirementsContext context) { - return super.visitAnyTrue(elm, context); - } - @Override public ElmRequirement visitProperty(Property elm, ElmRequirementsContext context) { ElmRequirement visitResult = super.visitProperty(elm, context); @@ -1265,8 +654,9 @@ public ElmRequirement visitProperty(Property elm, ElmRequirementsContext context } @Override - public ElmRequirement visitChildren(AliasedQuerySource elm, ElmRequirementsContext context) { - // Override visit behavior because we need to exit the definition context prior to traversing the such that + public ElmRequirement visitFields(AliasedQuerySource elm, ElmRequirementsContext context) { + // Override visit behavior because we need to exit the definition context prior + // to traversing the such that // condition // Such that traversal happens in the visitChildren relationship ElmRequirement result = defaultResult(elm, context); @@ -1280,7 +670,8 @@ public ElmRequirement visitChildren(AliasedQuerySource elm, ElmRequirementsConte } finally { aliasContext = context.getCurrentQueryContext().exitAliasDefinitionContext(result); } - // If this is an operator requirement, report it directly to the context, otherwise the context it contains will + // If this is an operator requirement, report it directly to the context, + // otherwise the context it contains will // not be reported // since query requirements are abstracted to an ElmDataRequirement if (result instanceof ElmOperatorRequirement) { @@ -1290,32 +681,26 @@ public ElmRequirement visitChildren(AliasedQuerySource elm, ElmRequirementsConte } @Override - public ElmRequirement visitAliasedQuerySource(AliasedQuerySource elm, ElmRequirementsContext context) { - return super.visitAliasedQuerySource(elm, context); - } + public ElmRequirement visitWith(With elm, ElmRequirementsContext context) { + ElmRequirement result = visitFields((AliasedQuerySource) elm, context); - @Override - public ElmRequirement visitLetClause(LetClause elm, ElmRequirementsContext context) { - ElmRequirement result = defaultResult(elm, context); - ElmQueryLetContext letContext = null; - context.getCurrentQueryContext().enterLetDefinitionContext(elm); - try { - if (elm.getExpression() != null) { - ElmRequirement childResult = super.visitLetClause(elm, context); - result = aggregateResult(result, childResult); - } - } finally { - letContext = context.getCurrentQueryContext().exitLetDefinitionContext(result); + if (elm.getSuchThat() != null) { + ElmRequirement childResult = visitExpression(elm.getSuchThat(), context); + context.getCurrentQueryContext().reportQueryRequirements(childResult); + result = aggregateResult(result, childResult); } - return letContext.getRequirements(); + + context.getCurrentQueryContext().descopeAlias(elm); + + return result; } @Override - public ElmRequirement visitChildren(RelationshipClause elm, ElmRequirementsContext context) { - ElmRequirement result = visitChildren((AliasedQuerySource) elm, context); + public ElmRequirement visitWithout(Without elm, ElmRequirementsContext context) { + ElmRequirement result = visitFields((AliasedQuerySource) elm, context); if (elm.getSuchThat() != null) { - ElmRequirement childResult = visitSuchThatClause(elm.getSuchThat(), elm instanceof With, context); + ElmRequirement childResult = visitExpression(elm.getSuchThat(), context); result = aggregateResult(result, childResult); } @@ -1325,65 +710,74 @@ public ElmRequirement visitChildren(RelationshipClause elm, ElmRequirementsConte } @Override - public ElmRequirement visitRelationshipClause(RelationshipClause elm, ElmRequirementsContext context) { - return super.visitRelationshipClause(elm, context); - } - - @Override - public ElmRequirement visitWith(With elm, ElmRequirementsContext context) { - return super.visitWith(elm, context); - } + public ElmRequirement visitAliasedQuerySource(AliasedQuerySource elm, ElmRequirementsContext context) { + if (elm instanceof RelationshipClause) { + return visitRelationshipClause((RelationshipClause) elm, context); + } - @Override - public ElmRequirement visitWithout(Without elm, ElmRequirementsContext context) { - return super.visitWithout(elm, context); + return visitFields(elm, context); } @Override - public ElmRequirement visitSortByItem(SortByItem elm, ElmRequirementsContext context) { - return super.visitSortByItem(elm, context); + public ElmRequirement visitLetClause(LetClause elm, ElmRequirementsContext context) { + ElmRequirement result = defaultResult(elm, context); + ElmQueryLetContext letContext = null; + context.getCurrentQueryContext().enterLetDefinitionContext(elm); + try { + if (elm.getExpression() != null) { + ElmRequirement childResult = super.visitLetClause(elm, context); + result = aggregateResult(result, childResult); + } + } finally { + letContext = context.getCurrentQueryContext().exitLetDefinitionContext(result); + } + return letContext.getRequirements(); } - @Override - public ElmRequirement visitByDirection(ByDirection elm, ElmRequirementsContext context) { - return super.visitByDirection(elm, context); - } + protected ElmRequirement visitFields(Query elm, ElmRequirementsContext context) { + ElmRequirement result = visitFields((Expression) elm, context); - @Override - public ElmRequirement visitByColumn(ByColumn elm, ElmRequirementsContext context) { - return super.visitByColumn(elm, context); - } + for (var source : elm.getSource()) { + ElmRequirement childResult = visitAliasedQuerySource(source, context); + result = aggregateResult(result, childResult); + } + for (var let : elm.getLet()) { + ElmRequirement childResult = visitLetClause(let, context); + result = aggregateResult(result, childResult); + } - @Override - public ElmRequirement visitByExpression(ByExpression elm, ElmRequirementsContext context) { - return super.visitByExpression(elm, context); - } + for (var r : elm.getRelationship()) { + ElmRequirement childResult = visitRelationshipClause(r, context); + result = aggregateResult(result, childResult); + } - @Override - public ElmRequirement visitSortClause(SortClause elm, ElmRequirementsContext context) { - return super.visitSortClause(elm, context); - } + if (elm.getWhere() != null) { + ElmRequirement childResult = visitExpression(elm.getWhere(), context); + // This is the one line that's different between this implementation + // and the super implementation + context.getCurrentQueryContext().reportQueryRequirements(childResult); + result = aggregateResult(result, childResult); + } + if (elm.getReturn() != null) { + ElmRequirement childResult = visitReturnClause(elm.getReturn(), context); + result = aggregateResult(result, childResult); + } - @Override - public ElmRequirement visitReturnClause(ReturnClause elm, ElmRequirementsContext context) { - return super.visitReturnClause(elm, context); - } + if (elm.getAggregate() != null) { + ElmRequirement childResult = visitAggregateClause(elm.getAggregate(), context); + result = aggregateResult(result, childResult); + } - @Override - public ElmRequirement visitWhereClause(Expression elm, ElmRequirementsContext context) { - ElmRequirement childResult = super.visitWhereClause(elm, context); - context.getCurrentQueryContext().reportQueryRequirements(childResult); - return childResult; - } + if (elm.getSort() != null) { + ElmRequirement childResult = visitSortClause(elm.getSort(), context); + result = aggregateResult(result, childResult); + } - @Override - public ElmRequirement visitSuchThatClause(Expression elm, boolean isWith, ElmRequirementsContext context) { - ElmRequirement childResult = super.visitSuchThatClause(elm, isWith, context); - if (isWith) { - context.getCurrentQueryContext().reportQueryRequirements(childResult); + if (elm.getResultTypeSpecifier() != null) { + ElmRequirement childResult = visitTypeSpecifier(elm.getResultTypeSpecifier(), context); + result = aggregateResult(result, childResult); } - // TODO: Determine how to incorporate requirements from a without clause - return childResult; + return result; } @Override @@ -1392,7 +786,7 @@ public ElmRequirement visitQuery(Query elm, ElmRequirementsContext context) { ElmQueryContext queryContext = null; context.enterQueryContext(elm); try { - childResult = super.visitQuery(elm, context); + childResult = visitFields(elm, context); } finally { queryContext = context.exitQueryContext(); } @@ -1402,26 +796,6 @@ public ElmRequirement visitQuery(Query elm, ElmRequirementsContext context) { return result; } - @Override - public ElmRequirement visitAliasRef(AliasRef elm, ElmRequirementsContext context) { - return super.visitAliasRef(elm, context); - } - - @Override - public ElmRequirement visitQueryLetRef(QueryLetRef elm, ElmRequirementsContext context) { - return super.visitQueryLetRef(elm, context); - } - - @Override - public ElmRequirement visitCode(Code elm, ElmRequirementsContext context) { - return super.visitCode(elm, context); - } - - @Override - public ElmRequirement visitConcept(Concept elm, ElmRequirementsContext context) { - return super.visitConcept(elm, context); - } - @Override public ElmRequirement visitInCodeSystem(InCodeSystem elm, ElmRequirementsContext context) { if (elm.getCode() != null && (elm.getCodesystem() != null || elm.getCodesystemExpression() != null)) { @@ -1474,56 +848,6 @@ public ElmRequirement visitAnyInValueSet(AnyInValueSet elm, ElmRequirementsConte return super.visitAnyInValueSet(elm, context); } - @Override - public ElmRequirement visitQuantity(Quantity elm, ElmRequirementsContext context) { - return super.visitQuantity(elm, context); - } - - @Override - public ElmRequirement visitCalculateAge(CalculateAge elm, ElmRequirementsContext context) { - return super.visitCalculateAge(elm, context); - } - - @Override - public ElmRequirement visitCalculateAgeAt(CalculateAgeAt elm, ElmRequirementsContext context) { - return super.visitCalculateAgeAt(elm, context); - } - - @Override - public ElmRequirement visitElement(Element elm, ElmRequirementsContext context) { - return super.visitElement(elm, context); - } - - @Override - public ElmRequirement visitTypeSpecifier(TypeSpecifier elm, ElmRequirementsContext context) { - return super.visitTypeSpecifier(elm, context); - } - - @Override - public ElmRequirement visitNamedTypeSpecifier(NamedTypeSpecifier elm, ElmRequirementsContext context) { - return super.visitNamedTypeSpecifier(elm, context); - } - - @Override - public ElmRequirement visitIntervalTypeSpecifier(IntervalTypeSpecifier elm, ElmRequirementsContext context) { - return super.visitIntervalTypeSpecifier(elm, context); - } - - @Override - public ElmRequirement visitListTypeSpecifier(ListTypeSpecifier elm, ElmRequirementsContext context) { - return super.visitListTypeSpecifier(elm, context); - } - - @Override - public ElmRequirement visitTupleElementDefinition(TupleElementDefinition elm, ElmRequirementsContext context) { - return super.visitTupleElementDefinition(elm, context); - } - - @Override - public ElmRequirement visitTupleTypeSpecifier(TupleTypeSpecifier elm, ElmRequirementsContext context) { - return super.visitTupleTypeSpecifier(elm, context); - } - @Override public ElmRequirement visitUsingDef(UsingDef elm, ElmRequirementsContext context) { context.reportUsingDef(elm); diff --git a/Src/java/elm/build.gradle b/Src/java/elm/build.gradle index 2b9842213..9791c0612 100644 --- a/Src/java/elm/build.gradle +++ b/Src/java/elm/build.gradle @@ -5,6 +5,8 @@ plugins { dependencies { api project(':model') + testImplementation 'org.jeasy:easy-random-core:5.0.0' + testImplementation 'com.tngtech.archunit:archunit:1.2.1' } generateSources { diff --git a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseClinicalVisitor.java b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmClinicalVisitor.java similarity index 82% rename from Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseClinicalVisitor.java rename to Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmClinicalVisitor.java index 64510b3f9..410ffdfdf 100644 --- a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseClinicalVisitor.java +++ b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmClinicalVisitor.java @@ -7,9 +7,9 @@ * * @param The return type of the visit operation. Use {@link Void} for * @param The type of context passed to each visit method - * operations with no return type. + * operations with no return type. */ -public class ElmBaseClinicalVisitor extends ElmBaseVisitor implements ElmClinicalVisitor { +public abstract class BaseElmClinicalVisitor extends BaseElmVisitor implements ElmClinicalVisitor { @Override public T visitElement(Element elm, C context) { @@ -106,7 +106,7 @@ public T visitBinaryExpression(BinaryExpression elm, C context) { * @return the visitor result */ public T visitExpandValueSet(ExpandValueSet elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -118,11 +118,12 @@ public T visitExpandValueSet(ExpandValueSet elm, C context) { * @return the visitor result */ public T visitCodeFilterElement(CodeFilterElement elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); if (elm.getValue() != null) { - T childResult = visitElement(elm.getValue(), context); + T childResult = visitExpression(elm.getValue(), context); result = aggregateResult(result, childResult); } + return result; } @@ -135,11 +136,13 @@ public T visitCodeFilterElement(CodeFilterElement elm, C context) { * @return the visitor result */ public T visitDateFilterElement(DateFilterElement elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getValue() != null) { - T childResult = visitElement(elm.getValue(), context); + T childResult = visitExpression(elm.getValue(), context); result = aggregateResult(result, childResult); } + return result; } @@ -152,11 +155,13 @@ public T visitDateFilterElement(DateFilterElement elm, C context) { * @return the visitor result */ public T visitOtherFilterElement(OtherFilterElement elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getValue() != null) { - T childResult = visitElement(elm.getValue(), context); + T childResult = visitExpression(elm.getValue(), context); result = aggregateResult(result, childResult); } + return result; } @@ -169,7 +174,7 @@ public T visitOtherFilterElement(OtherFilterElement elm, C context) { * @return the visitor result */ public T visitIncludeElement(IncludeElement elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -181,35 +186,45 @@ public T visitIncludeElement(IncludeElement elm, C context) { * @return the visitor result */ public T visitRetrieve(Retrieve elm, C context) { - T result = defaultResult(elm, context); - if (elm.getCodes() != null) { - T childResult = visitElement(elm.getCodes(), context); + T result = visitFields(elm, context); + + for (var cfe : elm.getCodeFilter()) { + T childResult = visitCodeFilterElement(cfe, context); result = aggregateResult(result, childResult); } - if (elm.getDateRange() != null) { - T childResult = visitElement(elm.getDateRange(), context); + + if (elm.getCodes() != null) { + T childResult = visitExpression(elm.getCodes(), context); result = aggregateResult(result, childResult); } if (elm.getContext() != null) { - T childResult = visitElement(elm.getContext(), context); + T childResult = visitExpression(elm.getContext(), context); + result = aggregateResult(result, childResult); + } + for (var dfe : elm.getDateFilter()) { + T childResult = visitDateFilterElement(dfe, context); result = aggregateResult(result, childResult); } - for (IncludeElement ie : elm.getInclude()) { - T childResult = visitElement(ie, context); + if (elm.getDateRange() != null) { + T childResult = visitExpression(elm.getDateRange(), context); result = aggregateResult(result, childResult); } - for (CodeFilterElement cfe : elm.getCodeFilter()) { - T childResult = visitElement(cfe, context); + + if (elm.getId() != null) { + T childResult = visitExpression(elm.getId(), context); result = aggregateResult(result, childResult); } - for (DateFilterElement dfe : elm.getDateFilter()) { - T childResult = visitElement(dfe, context); + + for (var ie : elm.getInclude()) { + T childResult = visitIncludeElement(ie, context); result = aggregateResult(result, childResult); } - for (OtherFilterElement ofe : elm.getOtherFilter()) { - T childResult = visitElement(ofe, context); + + for (var ofe : elm.getOtherFilter()) { + T childResult = visitOtherFilterElement(ofe, context); result = aggregateResult(result, childResult); } + return result; } @@ -238,7 +253,14 @@ public T visitProperty(Property elm, C context) { * @return the visitor result */ public T visitSearch(Search elm, C context) { - return visitChildren(elm, context); + T result = visitFields(elm, context); + + if (elm.getSource() != null) { + T childResult = visitExpression(elm.getSource(), context); + result = aggregateResult(result, childResult); + } + + return result; } /** @@ -250,11 +272,12 @@ public T visitSearch(Search elm, C context) { * @return the visitor result */ public T visitCodeSystemDef(CodeSystemDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); if (elm.getAccessLevel() != null) { T childResult = visitAccessModifier(elm.getAccessLevel(), context); result = aggregateResult(result, childResult); } + return result; } @@ -267,15 +290,17 @@ public T visitCodeSystemDef(CodeSystemDef elm, C context) { * @return the visitor result */ public T visitValueSetDef(ValueSetDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getAccessLevel() != null) { T childResult = visitAccessModifier(elm.getAccessLevel(), context); result = aggregateResult(result, childResult); } for (CodeSystemRef codeSystemRef : elm.getCodeSystem()) { - T childResult = visitElement(codeSystemRef, context); + T childResult = visitCodeSystemRef(codeSystemRef, context); result = aggregateResult(result, childResult); } + return result; } @@ -288,7 +313,8 @@ public T visitValueSetDef(ValueSetDef elm, C context) { * @return the visitor result */ public T visitCodeDef(CodeDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getAccessLevel() != null) { T childResult = visitAccessModifier(elm.getAccessLevel(), context); result = aggregateResult(result, childResult); @@ -297,6 +323,7 @@ public T visitCodeDef(CodeDef elm, C context) { T childResult = visitCodeSystemRef(elm.getCodeSystem(), context); result = aggregateResult(result, childResult); } + return result; } @@ -309,15 +336,17 @@ public T visitCodeDef(CodeDef elm, C context) { * @return the visitor result */ public T visitConceptDef(ConceptDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getAccessLevel() != null) { T childResult = visitAccessModifier(elm.getAccessLevel(), context); result = aggregateResult(result, childResult); } for (CodeRef cr : elm.getCode()) { - T childResult = visitElement(cr, context); + T childResult = visitCodeRef(cr, context); result = aggregateResult(result, childResult); } + return result; } @@ -330,7 +359,7 @@ public T visitConceptDef(ConceptDef elm, C context) { * @return the visitor result */ public T visitCodeSystemRef(CodeSystemRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -342,7 +371,7 @@ public T visitCodeSystemRef(CodeSystemRef elm, C context) { * @return the visitor result */ public T visitValueSetRef(ValueSetRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -354,7 +383,7 @@ public T visitValueSetRef(ValueSetRef elm, C context) { * @return the visitor result */ public T visitCodeRef(CodeRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -366,7 +395,7 @@ public T visitCodeRef(CodeRef elm, C context) { * @return the visitor result */ public T visitConceptRef(ConceptRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -378,11 +407,13 @@ public T visitConceptRef(ConceptRef elm, C context) { * @return the visitor result */ public T visitCode(Code elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSystem() != null) { - T childResult = visitElement(elm.getSystem(), context); + T childResult = visitCodeSystemRef(elm.getSystem(), context); result = aggregateResult(result, childResult); } + return result; } @@ -395,11 +426,13 @@ public T visitCode(Code elm, C context) { * @return the visitor result */ public T visitConcept(Concept elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + for (Code c : elm.getCode()) { - T childResult = visitElement(c, context); + T childResult = visitCode(c, context); result = aggregateResult(result, childResult); } + return result; } @@ -412,19 +445,21 @@ public T visitConcept(Concept elm, C context) { * @return the visitor result */ public T visitInCodeSystem(InCodeSystem elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getCode() != null) { - T childResult = visitElement(elm.getCode(), context); + T childResult = visitExpression(elm.getCode(), context); result = aggregateResult(result, childResult); } if (elm.getCodesystem() != null) { - T childResult = visitElement(elm.getCodesystem(), context); + T childResult = visitCodeSystemRef(elm.getCodesystem(), context); result = aggregateResult(result, childResult); } if (elm.getCodesystemExpression() != null) { - T childResult = visitElement(elm.getCodesystemExpression(), context); + T childResult = visitExpression(elm.getCodesystemExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -437,19 +472,21 @@ public T visitInCodeSystem(InCodeSystem elm, C context) { * @return the visitor result */ public T visitAnyInCodeSystem(AnyInCodeSystem elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getCodes() != null) { - T childResult = visitElement(elm.getCodes(), context); + T childResult = visitExpression(elm.getCodes(), context); result = aggregateResult(result, childResult); } if (elm.getCodesystem() != null) { - T childResult = visitElement(elm.getCodesystem(), context); + T childResult = visitCodeSystemRef(elm.getCodesystem(), context); result = aggregateResult(result, childResult); } if (elm.getCodesystemExpression() != null) { - T childResult = visitElement(elm.getCodesystemExpression(), context); + T childResult = visitExpression(elm.getCodesystemExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -462,19 +499,21 @@ public T visitAnyInCodeSystem(AnyInCodeSystem elm, C context) { * @return the visitor result */ public T visitInValueSet(InValueSet elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getCode() != null) { - T childResult = visitElement(elm.getCode(), context); + T childResult = visitExpression(elm.getCode(), context); result = aggregateResult(result, childResult); } if (elm.getValueset() != null) { - T childResult = visitElement(elm.getValueset(), context); + T childResult = visitValueSetRef(elm.getValueset(), context); result = aggregateResult(result, childResult); } if (elm.getValuesetExpression() != null) { - T childResult = visitElement(elm.getValuesetExpression(), context); + T childResult = visitExpression(elm.getValuesetExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -487,19 +526,21 @@ public T visitInValueSet(InValueSet elm, C context) { * @return the visitor result */ public T visitAnyInValueSet(AnyInValueSet elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getCodes() != null) { - T childResult = visitElement(elm.getCodes(), context); + T childResult = visitExpression(elm.getCodes(), context); result = aggregateResult(result, childResult); } if (elm.getValueset() != null) { - T childResult = visitElement(elm.getValueset(), context); + T childResult = visitValueSetRef(elm.getValueset(), context); result = aggregateResult(result, childResult); } if (elm.getValuesetExpression() != null) { - T childResult = visitElement(elm.getValuesetExpression(), context); + T childResult = visitExpression(elm.getValuesetExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -512,7 +553,7 @@ public T visitAnyInValueSet(AnyInValueSet elm, C context) { * @return the visitor result */ public T visitSubsumes(Subsumes elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -524,7 +565,7 @@ public T visitSubsumes(Subsumes elm, C context) { * @return the visitor result */ public T visitSubsumedBy(SubsumedBy elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -536,7 +577,7 @@ public T visitSubsumedBy(SubsumedBy elm, C context) { * @return the visitor result */ public T visitQuantity(Quantity elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -548,15 +589,17 @@ public T visitQuantity(Quantity elm, C context) { * @return the visitor result */ public T visitRatio(Ratio elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getDenominator() != null) { - T childResult = visitElement(elm.getDenominator(), context); + T childResult = visitQuantity(elm.getDenominator(), context); result = aggregateResult(result, childResult); } if (elm.getNumerator() != null) { - T childResult = visitElement(elm.getNumerator(), context); + T childResult = visitQuantity(elm.getNumerator(), context); result = aggregateResult(result, childResult); } + return result; } @@ -569,7 +612,7 @@ public T visitRatio(Ratio elm, C context) { * @return the visitor result */ public T visitCalculateAge(CalculateAge elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -581,6 +624,6 @@ public T visitCalculateAge(CalculateAge elm, C context) { * @return the visitor result */ public T visitCalculateAgeAt(CalculateAgeAt elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } } diff --git a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseLibraryVisitor.java b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmLibraryVisitor.java similarity index 85% rename from Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseLibraryVisitor.java rename to Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmLibraryVisitor.java index d0d57a419..9cf418c0c 100644 --- a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseLibraryVisitor.java +++ b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmLibraryVisitor.java @@ -5,7 +5,8 @@ /** * Created by Bryn on 4/14/2016. */ -public class ElmBaseLibraryVisitor extends ElmBaseClinicalVisitor implements ElmLibraryVisitor { +public abstract class BaseElmLibraryVisitor extends BaseElmClinicalVisitor + implements ElmLibraryVisitor { /** * Visit an Element in an ELM tree. This method will be called for @@ -33,12 +34,12 @@ public T visitElement(Element elm, C context) { * @return the visitor result */ public T visitLibrary(Library elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); if (elm.getUsings() != null && elm.getUsings().getDef() != null && !elm.getUsings().getDef().isEmpty()) { for (UsingDef def : elm.getUsings().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitUsingDef(def, context); result = aggregateResult(result, childResult); } } @@ -46,7 +47,7 @@ public T visitLibrary(Library elm, C context) { && elm.getIncludes().getDef() != null && !elm.getIncludes().getDef().isEmpty()) { for (IncludeDef def : elm.getIncludes().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitIncludeDef(def, context); result = aggregateResult(result, childResult); } } @@ -54,7 +55,7 @@ public T visitLibrary(Library elm, C context) { && elm.getCodeSystems().getDef() != null && !elm.getCodeSystems().getDef().isEmpty()) { for (CodeSystemDef def : elm.getCodeSystems().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitCodeSystemDef(def, context); result = aggregateResult(result, childResult); } } @@ -62,7 +63,7 @@ public T visitLibrary(Library elm, C context) { && elm.getValueSets().getDef() != null && !elm.getValueSets().getDef().isEmpty()) { for (ValueSetDef def : elm.getValueSets().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitValueSetDef(def, context); result = aggregateResult(result, childResult); } } @@ -78,7 +79,7 @@ public T visitLibrary(Library elm, C context) { && elm.getConcepts().getDef() != null && !elm.getConcepts().getDef().isEmpty()) { for (ConceptDef def : elm.getConcepts().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitConceptDef(def, context); result = aggregateResult(result, childResult); } } @@ -86,7 +87,7 @@ public T visitLibrary(Library elm, C context) { && elm.getParameters().getDef() != null && !elm.getParameters().getDef().isEmpty()) { for (ParameterDef def : elm.getParameters().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitParameterDef(def, context); result = aggregateResult(result, childResult); } } @@ -94,7 +95,7 @@ public T visitLibrary(Library elm, C context) { && elm.getContexts().getDef() != null && !elm.getContexts().getDef().isEmpty()) { for (ContextDef def : elm.getContexts().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitContextDef(def, context); result = aggregateResult(result, childResult); } } @@ -102,10 +103,11 @@ public T visitLibrary(Library elm, C context) { && elm.getStatements().getDef() != null && !elm.getStatements().getDef().isEmpty()) { for (ExpressionDef def : elm.getStatements().getDef()) { - T childResult = visitElement(def, context); + T childResult = visitExpressionDef(def, context); result = aggregateResult(result, childResult); } } + return result; } @@ -118,7 +120,7 @@ public T visitLibrary(Library elm, C context) { * @return the visitor result */ public T visitUsingDef(UsingDef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -130,7 +132,7 @@ public T visitUsingDef(UsingDef elm, C context) { * @return the visitor result */ public T visitIncludeDef(IncludeDef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -142,6 +144,6 @@ public T visitIncludeDef(IncludeDef elm, C context) { * @return the visitor result */ public T visitContextDef(ContextDef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } } diff --git a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseVisitor.java b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmVisitor.java similarity index 83% rename from Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseVisitor.java rename to Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmVisitor.java index f9cf349da..e4cec60ad 100644 --- a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmBaseVisitor.java +++ b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/BaseElmVisitor.java @@ -3,17 +3,37 @@ import org.cqframework.cql.elm.tracking.Trackable; import org.hl7.elm.r1.*; +/* + Design notes: + There are two types of methods in this class: + + 1. visitFields + + visitFields visits the fields of an object, traversing up the class hierarchy to visit superclass fields. + + 2. visitXYZ, where XYZ is the name of an ELM class + + The visitXYZ methods come in two flavors: + + A. visits on abstract or base classes forward to the correct visit method for the concrete or derived class. + B. visits on concrete or derived classes visit the fields of its base class using visitFields, and then visits the fields itself. + + TypeSpecifiers are considered to be terminal nodes in the ELM graph. TypeSpecifiers themselves are Elements and thus + have recursive TypeSpecifiers, but these are not visited. +*/ + /** * Provides the base implementation for an ElmVisitor. * - * @param The return type of the visit operation. Use {@link Void} for + * @param The return type of the visit operation. Use {@link Void} for no return value. * @param The type of context passed to each visit method - * operations with no return type. + * operations with no return type. */ -public class ElmBaseVisitor implements ElmVisitor { +public abstract class BaseElmVisitor implements ElmVisitor { /** * Provides the default result of a visit + * * @return */ protected T defaultResult(Trackable elm, C context) { @@ -25,7 +45,7 @@ protected T defaultResult(Trackable elm, C context) { * Default behavior returns the next result, ignoring the current * aggregate. * - * @param aggregate Current aggregate result + * @param aggregate Current aggregate result * @param nextResult Next result to be aggregated * @return The result of aggregating the nextResult into aggregate */ @@ -42,20 +62,19 @@ protected T aggregateResult(T aggregate, T nextResult) { * @return the visitor result */ public T visitElement(Element elm, C context) { - if (elm instanceof AliasedQuerySource) return visitAliasedQuerySource((AliasedQuerySource) elm, context); + if (elm instanceof Expression) return visitExpression((Expression) elm, context); else if (elm instanceof CaseItem) return visitCaseItem((CaseItem) elm, context); - else if (elm instanceof Expression) return visitExpression((Expression) elm, context); else if (elm instanceof LetClause) return visitLetClause((LetClause) elm, context); else if (elm instanceof OperandDef) return visitOperandDef((OperandDef) elm, context); else if (elm instanceof ParameterDef) return visitParameterDef((ParameterDef) elm, context); - else if (elm instanceof ReturnClause) return visitReturnClause((ReturnClause) elm, context); - else if (elm instanceof AggregateClause) return visitAggregateClause((AggregateClause) elm, context); else if (elm instanceof SortByItem) return visitSortByItem((SortByItem) elm, context); else if (elm instanceof SortClause) return visitSortClause((SortClause) elm, context); else if (elm instanceof TupleElementDefinition) return visitTupleElementDefinition((TupleElementDefinition) elm, context); else if (elm instanceof TypeSpecifier) return visitTypeSpecifier((TypeSpecifier) elm, context); - else return defaultResult(elm, context); + else + throw new IllegalArgumentException( + "Unknown Element type: " + elm.getClass().getName()); } /** @@ -74,7 +93,23 @@ else if (elm instanceof IntervalTypeSpecifier) else if (elm instanceof TupleTypeSpecifier) return visitTupleTypeSpecifier((TupleTypeSpecifier) elm, context); else if (elm instanceof ChoiceTypeSpecifier) return visitChoiceTypeSpecifier((ChoiceTypeSpecifier) elm, context); - else return defaultResult(elm, context); + else if (elm instanceof ParameterTypeSpecifier) + return visitParameterTypeSpecifier((ParameterTypeSpecifier) elm, context); + else + throw new IllegalArgumentException( + "Unknown TypeSpecifier type: " + elm.getClass().getName()); + } + + /** + * Visit a ParameterTypeSpecifier. This method will be called for + * every node in the tree that is a ParameterTypeSpecifier. + * + * @param elm the ELM tree + * @param context the context passed to the visitor + * @return the visitor result + */ + public T visitParameterTypeSpecifier(ParameterTypeSpecifier elm, C context) { + return defaultResult(elm, context); } /** @@ -99,8 +134,13 @@ public T visitNamedTypeSpecifier(NamedTypeSpecifier elm, C context) { */ public T visitIntervalTypeSpecifier(IntervalTypeSpecifier elm, C context) { T result = defaultResult(elm, context); - T childResult = visitTypeSpecifier(elm.getPointType(), context); - return aggregateResult(result, childResult); + + if (elm.getPointType() != null) { + T childResult = visitTypeSpecifier(elm.getPointType(), context); + result = aggregateResult(result, childResult); + } + + return result; } /** @@ -113,8 +153,13 @@ public T visitIntervalTypeSpecifier(IntervalTypeSpecifier elm, C context) { */ public T visitListTypeSpecifier(ListTypeSpecifier elm, C context) { T result = defaultResult(elm, context); - T childResult = visitTypeSpecifier(elm.getElementType(), context); - return aggregateResult(result, childResult); + + if (elm.getElementType() != null) { + T childResult = visitTypeSpecifier(elm.getElementType(), context); + result = aggregateResult(result, childResult); + } + + return result; } /** @@ -126,9 +171,19 @@ public T visitListTypeSpecifier(ListTypeSpecifier elm, C context) { * @return the visitor result */ public T visitTupleElementDefinition(TupleElementDefinition elm, C context) { - T result = defaultResult(elm, context); - T childResult = visitTypeSpecifier(elm.getElementType(), context); - return aggregateResult(result, childResult); + T result = visitFields(elm, context); + + if (elm.getElementType() != null) { + T childResult = visitTypeSpecifier(elm.getElementType(), context); + result = aggregateResult(result, childResult); + } + + if (elm.getType() != null) { + T childResult = visitTypeSpecifier(elm.getType(), context); + result = aggregateResult(result, childResult); + } + + return result; } /** @@ -141,6 +196,7 @@ public T visitTupleElementDefinition(TupleElementDefinition elm, C context) { */ public T visitTupleTypeSpecifier(TupleTypeSpecifier elm, C context) { T result = defaultResult(elm, context); + for (TupleElementDefinition element : elm.getElement()) { T childResult = visitTupleElementDefinition(element, context); result = aggregateResult(result, childResult); @@ -158,10 +214,17 @@ public T visitTupleTypeSpecifier(TupleTypeSpecifier elm, C context) { */ public T visitChoiceTypeSpecifier(ChoiceTypeSpecifier elm, C context) { T result = defaultResult(elm, context); - for (TypeSpecifier choice : elm.getChoice()) { - T childResult = visitElement(choice, context); + + for (var choice : elm.getChoice()) { + T childResult = visitTypeSpecifier(choice, context); + result = aggregateResult(result, childResult); + } + + for (var type : elm.getType()) { + T childResult = visitTypeSpecifier(type, context); result = aggregateResult(result, childResult); } + return result; } @@ -174,9 +237,7 @@ public T visitChoiceTypeSpecifier(ChoiceTypeSpecifier elm, C context) { * @return the visitor result */ public T visitExpression(Expression elm, C context) { - if (elm instanceof AggregateExpression) return visitAggregateExpression((AggregateExpression) elm, context); - else if (elm instanceof OperatorExpression) return visitOperatorExpression((OperatorExpression) elm, context); - else if (elm instanceof AliasRef) return visitAliasRef((AliasRef) elm, context); + if (elm instanceof AliasRef) return visitAliasRef((AliasRef) elm, context); else if (elm instanceof Case) return visitCase((Case) elm, context); else if (elm instanceof Current) return visitCurrent((Current) elm, context); else if (elm instanceof ExpressionRef) return visitExpressionRef((ExpressionRef) elm, context); @@ -201,7 +262,12 @@ public T visitExpression(Expression elm, C context) { else if (elm instanceof Sort) return visitSort((Sort) elm, context); else if (elm instanceof Total) return visitTotal((Total) elm, context); else if (elm instanceof Tuple) return visitTuple((Tuple) elm, context); - else return defaultResult(elm, context); + else if (elm instanceof AggregateExpression) + return visitAggregateExpression((AggregateExpression) elm, context); + else if (elm instanceof OperatorExpression) return visitOperatorExpression((OperatorExpression) elm, context); + else + throw new IllegalArgumentException( + "Unknown Expression type: " + elm.getClass().getName()); } /** @@ -213,11 +279,7 @@ public T visitExpression(Expression elm, C context) { * @return the visitor result */ public T visitOperatorExpression(OperatorExpression elm, C context) { - if (elm instanceof UnaryExpression) return visitUnaryExpression((UnaryExpression) elm, context); - else if (elm instanceof BinaryExpression) return visitBinaryExpression((BinaryExpression) elm, context); - else if (elm instanceof TernaryExpression) return visitTernaryExpression((TernaryExpression) elm, context); - else if (elm instanceof NaryExpression) return visitNaryExpression((NaryExpression) elm, context); - else if (elm instanceof Round) return visitRound((Round) elm, context); + if (elm instanceof Round) return visitRound((Round) elm, context); else if (elm instanceof Combine) return visitCombine((Combine) elm, context); else if (elm instanceof Split) return visitSplit((Split) elm, context); else if (elm instanceof SplitOnMatches) return visitSplitOnMatches((SplitOnMatches) elm, context); @@ -237,22 +299,13 @@ public T visitOperatorExpression(OperatorExpression elm, C context) { else if (elm instanceof Children) return visitChildren((Children) elm, context); else if (elm instanceof Descendents) return visitDescendents((Descendents) elm, context); else if (elm instanceof Message) return visitMessage((Message) elm, context); - return defaultResult(elm, context); - } - - /** - * Visits the children of a UnaryExpression - * @param elm - * @param context - * @return - */ - public T visitChildren(UnaryExpression elm, C context) { - T result = defaultResult(elm, context); - if (elm.getOperand() != null) { - T childResult = visitElement(elm.getOperand(), context); - result = aggregateResult(result, childResult); - } - return result; + else if (elm instanceof UnaryExpression) return visitUnaryExpression((UnaryExpression) elm, context); + else if (elm instanceof BinaryExpression) return visitBinaryExpression((BinaryExpression) elm, context); + else if (elm instanceof TernaryExpression) return visitTernaryExpression((TernaryExpression) elm, context); + else if (elm instanceof NaryExpression) return visitNaryExpression((NaryExpression) elm, context); + else + throw new IllegalArgumentException( + "Unknown OperatorExpression type: " + elm.getClass().getName()); } /** @@ -323,22 +376,9 @@ else if (elm instanceof DateTimeComponentFrom) else if (elm instanceof Truncate) return visitTruncate((Truncate) elm, context); else if (elm instanceof Upper) return visitUpper((Upper) elm, context); else if (elm instanceof Width) return visitWidth((Width) elm, context); - else return visitChildren(elm, context); - } - - /** - * Visits the children of a BinaryExpression - * @param elm - * @param context - * @return - */ - public T visitChildren(BinaryExpression elm, C context) { - T result = defaultResult(elm, context); - for (Expression e : elm.getOperand()) { - T childResult = visitElement(e, context); - result = aggregateResult(result, childResult); - } - return result; + else + throw new IllegalArgumentException( + "Unknown UnaryExpression type: " + elm.getClass().getName()); } /** @@ -403,22 +443,9 @@ public T visitBinaryExpression(BinaryExpression elm, C context) { else if (elm instanceof Times) return visitTimes((Times) elm, context); else if (elm instanceof TruncatedDivide) return visitTruncatedDivide((TruncatedDivide) elm, context); else if (elm instanceof Xor) return visitXor((Xor) elm, context); - else return visitChildren(elm, context); - } - - /** - * Visits the children of a TernaryExpression - * @param elm - * @param context - * @return - */ - public T visitChildren(TernaryExpression elm, C context) { - T result = defaultResult(elm, context); - for (Expression e : elm.getOperand()) { - T childResult = visitElement(e, context); - result = aggregateResult(result, childResult); - } - return result; + else + throw new IllegalArgumentException( + "Unknown BinaryExpression type: " + elm.getClass().getName()); } /** @@ -430,26 +457,10 @@ public T visitChildren(TernaryExpression elm, C context) { * @return the visitor result */ public T visitTernaryExpression(TernaryExpression elm, C context) { - for (Expression element : elm.getOperand()) { - visitElement(element, context); - } if (elm instanceof ReplaceMatches) return visitReplaceMatches((ReplaceMatches) elm, context); - return visitChildren(elm, context); - } - - /** - * Visits the children of an NaryExpression - * @param elm - * @param context - * @return - */ - public T visitChildren(NaryExpression elm, C context) { - T result = defaultResult(elm, context); - for (Expression e : elm.getOperand()) { - T childResult = visitElement(e, context); - result = aggregateResult(result, childResult); - } - return result; + else + throw new IllegalArgumentException( + "Unknown TernaryExpression type: " + elm.getClass().getName()); } /** @@ -466,26 +477,9 @@ public T visitNaryExpression(NaryExpression elm, C context) { else if (elm instanceof Except) return visitExcept((Except) elm, context); else if (elm instanceof Intersect) return visitIntersect((Intersect) elm, context); else if (elm instanceof Union) return visitUnion((Union) elm, context); - else return visitChildren(elm, context); - } - - /** - * Visits the children of an ExpressionDef - * @param elm - * @param context - * @return - */ - public T visitChildren(ExpressionDef elm, C context) { - T result = defaultResult(elm, context); - if (elm.getAccessLevel() != null) { - T childResult = visitAccessModifier(elm.getAccessLevel(), context); - result = aggregateResult(result, childResult); - } - if (elm.getExpression() != null) { - T childResult = visitElement(elm.getExpression(), context); - result = aggregateResult(result, childResult); - } - return result; + else + throw new IllegalArgumentException( + "Unknown NaryExpression type: " + elm.getClass().getName()); } /** @@ -500,7 +494,8 @@ public T visitExpressionDef(ExpressionDef elm, C context) { if (elm instanceof FunctionDef) { return visitFunctionDef((FunctionDef) elm, context); } - return visitChildren(elm, context); + + return visitFields(elm, context); } /** @@ -512,15 +507,13 @@ public T visitExpressionDef(ExpressionDef elm, C context) { * @return the visitor result */ public T visitFunctionDef(FunctionDef elm, C context) { - T result = visitChildren(elm, context); - for (Element operand : elm.getOperand()) { - T childResult = visitElement(operand, context); - result = aggregateResult(result, childResult); - } - if (elm.getResultTypeSpecifier() != null) { - T childResult = visitElement(elm.getResultTypeSpecifier(), context); + T result = visitFields(elm, context); + + for (var operand : elm.getOperand()) { + T childResult = visitOperandDef(operand, context); result = aggregateResult(result, childResult); } + return result; } @@ -549,7 +542,8 @@ public T visitExpressionRef(ExpressionRef elm, C context) { if (elm instanceof FunctionRef) { return visitFunctionRef((FunctionRef) elm, context); } - return defaultResult(elm, context); + + return visitFields(elm, context); } /** @@ -561,11 +555,18 @@ public T visitExpressionRef(ExpressionRef elm, C context) { * @return the visitor result */ public T visitFunctionRef(FunctionRef elm, C context) { - T result = defaultResult(elm, context); - for (Expression element : elm.getOperand()) { - T childResult = visitElement(element, context); + T result = visitFields(elm, context); + + for (var element : elm.getOperand()) { + T childResult = visitExpression(element, context); + result = aggregateResult(result, childResult); + } + + for (var s : elm.getSignature()) { + T childResult = visitTypeSpecifier(s, context); result = aggregateResult(result, childResult); } + return result; } @@ -578,14 +579,15 @@ public T visitFunctionRef(FunctionRef elm, C context) { * @return the visitor result */ public T visitParameterDef(ParameterDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getParameterTypeSpecifier() != null) { - T childResult = visitElement(elm.getParameterTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getParameterTypeSpecifier(), context); result = aggregateResult(result, childResult); } if (elm.getDefault() != null) { - T childResult = visitElement(elm.getDefault(), context); + T childResult = visitExpression(elm.getDefault(), context); result = aggregateResult(result, childResult); } @@ -601,7 +603,7 @@ public T visitParameterDef(ParameterDef elm, C context) { * @return the visitor result */ public T visitParameterRef(ParameterRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -613,11 +615,13 @@ public T visitParameterRef(ParameterRef elm, C context) { * @return the visitor result */ public T visitOperandDef(OperandDef elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getOperandTypeSpecifier() != null) { - T childResult = visitElement(elm.getOperandTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getOperandTypeSpecifier(), context); result = aggregateResult(result, childResult); } + return result; } @@ -630,7 +634,7 @@ public T visitOperandDef(OperandDef elm, C context) { * @return the visitor result */ public T visitOperandRef(OperandRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -642,7 +646,7 @@ public T visitOperandRef(OperandRef elm, C context) { * @return the visitor result */ public T visitIdentifierRef(IdentifierRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -654,7 +658,7 @@ public T visitIdentifierRef(IdentifierRef elm, C context) { * @return the visitor result */ public T visitLiteral(Literal elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -667,10 +671,12 @@ public T visitLiteral(Literal elm, C context) { */ public T visitTupleElement(TupleElement elm, C context) { T result = defaultResult(elm, context); + if (elm.getValue() != null) { T childResult = visitExpression(elm.getValue(), context); result = aggregateResult(result, childResult); } + return result; } @@ -683,11 +689,13 @@ public T visitTupleElement(TupleElement elm, C context) { * @return the visitor result */ public T visitTuple(Tuple elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + for (TupleElement element : elm.getElement()) { T childResult = visitTupleElement(element, context); result = aggregateResult(result, childResult); } + return result; } @@ -701,10 +709,12 @@ public T visitTuple(Tuple elm, C context) { */ public T visitInstanceElement(InstanceElement elm, C context) { T result = defaultResult(elm, context); + if (elm.getValue() != null) { T childResult = visitExpression(elm.getValue(), context); result = aggregateResult(result, childResult); } + return result; } @@ -717,11 +727,13 @@ public T visitInstanceElement(InstanceElement elm, C context) { * @return the visitor result */ public T visitInstance(Instance elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + for (InstanceElement element : elm.getElement()) { T childResult = visitInstanceElement(element, context); result = aggregateResult(result, childResult); } + return result; } @@ -734,23 +746,25 @@ public T visitInstance(Instance elm, C context) { * @return the visitor result */ public T visitInterval(Interval elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getLow() != null) { - T childResult = visitElement(elm.getLow(), context); + T childResult = visitExpression(elm.getLow(), context); result = aggregateResult(result, childResult); } if (elm.getLowClosedExpression() != null) { - T childResult = visitElement(elm.getLowClosedExpression(), context); + T childResult = visitExpression(elm.getLowClosedExpression(), context); result = aggregateResult(result, childResult); } if (elm.getHigh() != null) { - T childResult = visitElement(elm.getHigh(), context); + T childResult = visitExpression(elm.getHigh(), context); result = aggregateResult(result, childResult); } if (elm.getHighClosedExpression() != null) { - T childResult = visitElement(elm.getHighClosedExpression(), context); + T childResult = visitExpression(elm.getHighClosedExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -763,15 +777,18 @@ public T visitInterval(Interval elm, C context) { * @return the visitor result */ public T visitList(List elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getTypeSpecifier() != null) { - T childResult = visitElement(elm.getTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getTypeSpecifier(), context); result = aggregateResult(result, childResult); } + for (Expression element : elm.getElement()) { - T childResult = visitElement(element, context); + T childResult = visitExpression(element, context); result = aggregateResult(result, childResult); } + return result; } @@ -784,7 +801,7 @@ public T visitList(List elm, C context) { * @return the visitor result */ public T visitAnd(And elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -796,7 +813,7 @@ public T visitAnd(And elm, C context) { * @return the visitor result */ public T visitOr(Or elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -808,7 +825,7 @@ public T visitOr(Or elm, C context) { * @return the visitor result */ public T visitXor(Xor elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -820,7 +837,7 @@ public T visitXor(Xor elm, C context) { * @return the visitor result */ public T visitImplies(Implies elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -832,7 +849,7 @@ public T visitImplies(Implies elm, C context) { * @return the visitor result */ public T visitNot(Not elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -844,19 +861,21 @@ public T visitNot(Not elm, C context) { * @return the visitor result */ public T visitIf(If elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getCondition() != null) { - T childResult = visitElement(elm.getCondition(), context); + T childResult = visitExpression(elm.getCondition(), context); result = aggregateResult(result, childResult); } if (elm.getThen() != null) { - T childResult = visitElement(elm.getThen(), context); + T childResult = visitExpression(elm.getThen(), context); result = aggregateResult(result, childResult); } if (elm.getElse() != null) { - T childResult = visitElement(elm.getElse(), context); + T childResult = visitExpression(elm.getElse(), context); result = aggregateResult(result, childResult); } + return result; } @@ -869,15 +888,17 @@ public T visitIf(If elm, C context) { * @return the visitor result */ public T visitCaseItem(CaseItem elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getWhen() != null) { - T childResult = visitElement(elm.getWhen(), context); + T childResult = visitExpression(elm.getWhen(), context); result = aggregateResult(result, childResult); } if (elm.getThen() != null) { - T childResult = visitElement(elm.getThen(), context); + T childResult = visitExpression(elm.getThen(), context); result = aggregateResult(result, childResult); } + return result; } @@ -890,19 +911,23 @@ public T visitCaseItem(CaseItem elm, C context) { * @return the visitor result */ public T visitCase(Case elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getComparand() != null) { - T childResult = visitElement(elm.getComparand(), context); + T childResult = visitExpression(elm.getComparand(), context); result = aggregateResult(result, childResult); } + for (CaseItem ci : elm.getCaseItem()) { - T childResult = visitElement(ci, context); + T childResult = visitCaseItem(ci, context); result = aggregateResult(result, childResult); } + if (elm.getElse() != null) { - T childResult = visitElement(elm.getElse(), context); + T childResult = visitExpression(elm.getElse(), context); result = aggregateResult(result, childResult); } + return result; } @@ -915,7 +940,7 @@ public T visitCase(Case elm, C context) { * @return the visitor result */ public T visitNull(Null elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -927,7 +952,7 @@ public T visitNull(Null elm, C context) { * @return the visitor result */ public T visitIsNull(IsNull elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -939,7 +964,7 @@ public T visitIsNull(IsNull elm, C context) { * @return the visitor result */ public T visitIsTrue(IsTrue elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -951,7 +976,7 @@ public T visitIsTrue(IsTrue elm, C context) { * @return the visitor result */ public T visitIsFalse(IsFalse elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -963,7 +988,7 @@ public T visitIsFalse(IsFalse elm, C context) { * @return the visitor result */ public T visitCoalesce(Coalesce elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -975,11 +1000,13 @@ public T visitCoalesce(Coalesce elm, C context) { * @return the visitor result */ public T visitIs(Is elm, C context) { - T result = visitChildren(elm, context); + T result = visitFields(elm, context); + if (elm.getIsTypeSpecifier() != null) { - T childResult = visitElement(elm.getIsTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getIsTypeSpecifier(), context); result = aggregateResult(result, childResult); } + return result; } @@ -992,11 +1019,13 @@ public T visitIs(Is elm, C context) { * @return the visitor result */ public T visitAs(As elm, C context) { - T result = visitChildren(elm, context); + T result = visitFields(elm, context); + if (elm.getAsTypeSpecifier() != null) { - T childResult = visitElement(elm.getAsTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getAsTypeSpecifier(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1009,11 +1038,13 @@ public T visitAs(As elm, C context) { * @return the visitor result */ public T visitConvert(Convert elm, C context) { - T result = visitChildren(elm, context); + T result = visitFields(elm, context); + if (elm.getToTypeSpecifier() != null) { - T childResult = visitElement(elm.getToTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getToTypeSpecifier(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1026,11 +1057,13 @@ public T visitConvert(Convert elm, C context) { * @return the visitor result */ public T visitCanConvert(CanConvert elm, C context) { - T result = visitChildren(elm, context); + T result = visitFields(elm, context); + if (elm.getToTypeSpecifier() != null) { - T childResult = visitElement(elm.getToTypeSpecifier(), context); + T childResult = visitTypeSpecifier(elm.getToTypeSpecifier(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1043,7 +1076,7 @@ public T visitCanConvert(CanConvert elm, C context) { * @return the visitor result */ public T visitConvertsToBoolean(ConvertsToBoolean elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1055,7 +1088,7 @@ public T visitConvertsToBoolean(ConvertsToBoolean elm, C context) { * @return the visitor result */ public T visitToBoolean(ToBoolean elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1067,7 +1100,7 @@ public T visitToBoolean(ToBoolean elm, C context) { * @return the visitor result */ public T visitToChars(ToChars elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1079,7 +1112,7 @@ public T visitToChars(ToChars elm, C context) { * @return the visitor result */ public T visitToConcept(ToConcept elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1091,7 +1124,7 @@ public T visitToConcept(ToConcept elm, C context) { * @return the visitor result */ public T visitConvertsToDate(ConvertsToDate elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1103,7 +1136,7 @@ public T visitConvertsToDate(ConvertsToDate elm, C context) { * @return the visitor result */ public T visitToDate(ToDate elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1115,7 +1148,7 @@ public T visitToDate(ToDate elm, C context) { * @return the visitor result */ public T visitConvertsToDateTime(ConvertsToDateTime elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1127,7 +1160,7 @@ public T visitConvertsToDateTime(ConvertsToDateTime elm, C context) { * @return the visitor result */ public T visitToDateTime(ToDateTime elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1139,7 +1172,7 @@ public T visitToDateTime(ToDateTime elm, C context) { * @return the visitor result */ public T visitConvertsToLong(ConvertsToLong elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1151,7 +1184,7 @@ public T visitConvertsToLong(ConvertsToLong elm, C context) { * @return the visitor result */ public T visitToLong(ToLong elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1163,7 +1196,7 @@ public T visitToLong(ToLong elm, C context) { * @return the visitor result */ public T visitConvertsToDecimal(ConvertsToDecimal elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1175,7 +1208,7 @@ public T visitConvertsToDecimal(ConvertsToDecimal elm, C context) { * @return the visitor result */ public T visitToDecimal(ToDecimal elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1187,7 +1220,7 @@ public T visitToDecimal(ToDecimal elm, C context) { * @return the visitor result */ public T visitConvertsToInteger(ConvertsToInteger elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1199,7 +1232,7 @@ public T visitConvertsToInteger(ConvertsToInteger elm, C context) { * @return the visitor result */ public T visitToInteger(ToInteger elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1211,7 +1244,7 @@ public T visitToInteger(ToInteger elm, C context) { * @return the visitor result */ public T visitToList(ToList elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1223,7 +1256,7 @@ public T visitToList(ToList elm, C context) { * @return the visitor result */ public T visitConvertQuantity(ConvertQuantity elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1235,7 +1268,7 @@ public T visitConvertQuantity(ConvertQuantity elm, C context) { * @return the visitor result */ public T visitCanConvertQuantity(CanConvertQuantity elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1247,7 +1280,7 @@ public T visitCanConvertQuantity(CanConvertQuantity elm, C context) { * @return the visitor result */ public T visitConvertsToQuantity(ConvertsToQuantity elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1259,7 +1292,7 @@ public T visitConvertsToQuantity(ConvertsToQuantity elm, C context) { * @return the visitor result */ public T visitToQuantity(ToQuantity elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1271,7 +1304,7 @@ public T visitToQuantity(ToQuantity elm, C context) { * @return the visitor result */ public T visitConvertsToRatio(ConvertsToRatio elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1283,7 +1316,7 @@ public T visitConvertsToRatio(ConvertsToRatio elm, C context) { * @return the visitor result */ public T visitToRatio(ToRatio elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1295,7 +1328,7 @@ public T visitToRatio(ToRatio elm, C context) { * @return the visitor result */ public T visitConvertsToString(ConvertsToString elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1307,7 +1340,7 @@ public T visitConvertsToString(ConvertsToString elm, C context) { * @return the visitor result */ public T visitToString(ToString elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1319,7 +1352,7 @@ public T visitToString(ToString elm, C context) { * @return the visitor result */ public T visitConvertsToTime(ConvertsToTime elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1331,7 +1364,7 @@ public T visitConvertsToTime(ConvertsToTime elm, C context) { * @return the visitor result */ public T visitToTime(ToTime elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1343,7 +1376,7 @@ public T visitToTime(ToTime elm, C context) { * @return the visitor result */ public T visitEqual(Equal elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1355,7 +1388,7 @@ public T visitEqual(Equal elm, C context) { * @return the visitor result */ public T visitEquivalent(Equivalent elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1367,7 +1400,7 @@ public T visitEquivalent(Equivalent elm, C context) { * @return the visitor result */ public T visitNotEqual(NotEqual elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1379,7 +1412,7 @@ public T visitNotEqual(NotEqual elm, C context) { * @return the visitor result */ public T visitLess(Less elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1391,7 +1424,7 @@ public T visitLess(Less elm, C context) { * @return the visitor result */ public T visitGreater(Greater elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1403,7 +1436,7 @@ public T visitGreater(Greater elm, C context) { * @return the visitor result */ public T visitLessOrEqual(LessOrEqual elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1415,7 +1448,7 @@ public T visitLessOrEqual(LessOrEqual elm, C context) { * @return the visitor result */ public T visitGreaterOrEqual(GreaterOrEqual elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1427,7 +1460,7 @@ public T visitGreaterOrEqual(GreaterOrEqual elm, C context) { * @return the visitor result */ public T visitAdd(Add elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1439,7 +1472,7 @@ public T visitAdd(Add elm, C context) { * @return the visitor result */ public T visitSubtract(Subtract elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1451,7 +1484,7 @@ public T visitSubtract(Subtract elm, C context) { * @return the visitor result */ public T visitMultiply(Multiply elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1463,7 +1496,7 @@ public T visitMultiply(Multiply elm, C context) { * @return the visitor result */ public T visitDivide(Divide elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1475,7 +1508,7 @@ public T visitDivide(Divide elm, C context) { * @return the visitor result */ public T visitTruncatedDivide(TruncatedDivide elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1487,7 +1520,7 @@ public T visitTruncatedDivide(TruncatedDivide elm, C context) { * @return the visitor result */ public T visitModulo(Modulo elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1499,7 +1532,7 @@ public T visitModulo(Modulo elm, C context) { * @return the visitor result */ public T visitCeiling(Ceiling elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1511,7 +1544,7 @@ public T visitCeiling(Ceiling elm, C context) { * @return the visitor result */ public T visitFloor(Floor elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1523,7 +1556,7 @@ public T visitFloor(Floor elm, C context) { * @return the visitor result */ public T visitTruncate(Truncate elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1535,7 +1568,7 @@ public T visitTruncate(Truncate elm, C context) { * @return the visitor result */ public T visitAbs(Abs elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1547,7 +1580,7 @@ public T visitAbs(Abs elm, C context) { * @return the visitor result */ public T visitNegate(Negate elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1559,15 +1592,17 @@ public T visitNegate(Negate elm, C context) { * @return the visitor result */ public T visitRound(Round elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); if (elm.getOperand() != null) { - T childResult = visitElement(elm.getOperand(), context); + T childResult = visitExpression(elm.getOperand(), context); result = aggregateResult(result, childResult); } + if (elm.getPrecision() != null) { - T childResult = visitElement(elm.getPrecision(), context); + T childResult = visitExpression(elm.getPrecision(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1580,7 +1615,7 @@ public T visitRound(Round elm, C context) { * @return the visitor result */ public T visitLn(Ln elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1592,7 +1627,7 @@ public T visitLn(Ln elm, C context) { * @return the visitor result */ public T visitExp(Exp elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1604,7 +1639,7 @@ public T visitExp(Exp elm, C context) { * @return the visitor result */ public T visitLog(Log elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1616,7 +1651,7 @@ public T visitLog(Log elm, C context) { * @return the visitor result */ public T visitPower(Power elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1628,7 +1663,7 @@ public T visitPower(Power elm, C context) { * @return the visitor result */ public T visitSuccessor(Successor elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1640,7 +1675,7 @@ public T visitSuccessor(Successor elm, C context) { * @return the visitor result */ public T visitPredecessor(Predecessor elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1652,7 +1687,7 @@ public T visitPredecessor(Predecessor elm, C context) { * @return the visitor result */ public T visitMinValue(MinValue elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -1664,7 +1699,7 @@ public T visitMinValue(MinValue elm, C context) { * @return the visitor result */ public T visitMaxValue(MaxValue elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -1676,7 +1711,7 @@ public T visitMaxValue(MaxValue elm, C context) { * @return the visitor result */ public T visitPrecision(Precision elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1688,7 +1723,7 @@ public T visitPrecision(Precision elm, C context) { * @return the visitor result */ public T visitLowBoundary(LowBoundary elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1700,7 +1735,7 @@ public T visitLowBoundary(LowBoundary elm, C context) { * @return the visitor result */ public T visitHighBoundary(HighBoundary elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1712,7 +1747,7 @@ public T visitHighBoundary(HighBoundary elm, C context) { * @return the visitor result */ public T visitConcatenate(Concatenate elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1724,15 +1759,17 @@ public T visitConcatenate(Concatenate elm, C context) { * @return the visitor result */ public T visitCombine(Combine elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getSeparator() != null) { - T childResult = visitElement(elm.getSeparator(), context); + T childResult = visitExpression(elm.getSeparator(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1745,7 +1782,8 @@ public T visitCombine(Combine elm, C context) { * @return the visitor result */ public T visitSplit(Split elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getStringToSplit() != null) { T childResult = visitExpression(elm.getStringToSplit(), context); result = aggregateResult(result, childResult); @@ -1754,6 +1792,7 @@ public T visitSplit(Split elm, C context) { T childResult = visitExpression(elm.getSeparator(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1766,7 +1805,8 @@ public T visitSplit(Split elm, C context) { * @return the visitor result */ public T visitSplitOnMatches(SplitOnMatches elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getStringToSplit() != null) { T childResult = visitExpression(elm.getStringToSplit(), context); result = aggregateResult(result, childResult); @@ -1775,6 +1815,7 @@ public T visitSplitOnMatches(SplitOnMatches elm, C context) { T childResult = visitExpression(elm.getSeparatorPattern(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1787,7 +1828,7 @@ public T visitSplitOnMatches(SplitOnMatches elm, C context) { * @return the visitor result */ public T visitLength(Length elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1799,7 +1840,7 @@ public T visitLength(Length elm, C context) { * @return the visitor result */ public T visitUpper(Upper elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1811,7 +1852,7 @@ public T visitUpper(Upper elm, C context) { * @return the visitor result */ public T visitLower(Lower elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1823,7 +1864,7 @@ public T visitLower(Lower elm, C context) { * @return the visitor result */ public T visitIndexer(Indexer elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1835,7 +1876,8 @@ public T visitIndexer(Indexer elm, C context) { * @return the visitor result */ public T visitPositionOf(PositionOf elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getPattern() != null) { T childResult = visitExpression(elm.getPattern(), context); result = aggregateResult(result, childResult); @@ -1844,6 +1886,7 @@ public T visitPositionOf(PositionOf elm, C context) { T childResult = visitExpression(elm.getString(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1856,7 +1899,8 @@ public T visitPositionOf(PositionOf elm, C context) { * @return the visitor result */ public T visitLastPositionOf(LastPositionOf elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getPattern() != null) { T childResult = visitExpression(elm.getPattern(), context); result = aggregateResult(result, childResult); @@ -1865,6 +1909,7 @@ public T visitLastPositionOf(LastPositionOf elm, C context) { T childResult = visitExpression(elm.getString(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1877,7 +1922,8 @@ public T visitLastPositionOf(LastPositionOf elm, C context) { * @return the visitor result */ public T visitSubstring(Substring elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getStringToSub() != null) { T childResult = visitExpression(elm.getStringToSub(), context); result = aggregateResult(result, childResult); @@ -1890,6 +1936,7 @@ public T visitSubstring(Substring elm, C context) { T childResult = visitExpression(elm.getLength(), context); result = aggregateResult(result, childResult); } + return result; } @@ -1902,7 +1949,7 @@ public T visitSubstring(Substring elm, C context) { * @return the visitor result */ public T visitStartsWith(StartsWith elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1914,7 +1961,7 @@ public T visitStartsWith(StartsWith elm, C context) { * @return the visitor result */ public T visitEndsWith(EndsWith elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1926,7 +1973,7 @@ public T visitEndsWith(EndsWith elm, C context) { * @return the visitor result */ public T visitMatches(Matches elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1938,7 +1985,7 @@ public T visitMatches(Matches elm, C context) { * @return the visitor result */ public T visitReplaceMatches(ReplaceMatches elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1950,7 +1997,7 @@ public T visitReplaceMatches(ReplaceMatches elm, C context) { * @return the visitor result */ public T visitDurationBetween(DurationBetween elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1962,7 +2009,7 @@ public T visitDurationBetween(DurationBetween elm, C context) { * @return the visitor result */ public T visitDifferenceBetween(DifferenceBetween elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1974,7 +2021,7 @@ public T visitDifferenceBetween(DifferenceBetween elm, C context) { * @return the visitor result */ public T visitDateFrom(DateFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1986,7 +2033,7 @@ public T visitDateFrom(DateFrom elm, C context) { * @return the visitor result */ public T visitTimeFrom(TimeFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -1998,7 +2045,7 @@ public T visitTimeFrom(TimeFrom elm, C context) { * @return the visitor result */ public T visitTimezoneFrom(TimezoneFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2010,7 +2057,7 @@ public T visitTimezoneFrom(TimezoneFrom elm, C context) { * @return the visitor result */ public T visitTimezoneOffsetFrom(TimezoneOffsetFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2022,7 +2069,7 @@ public T visitTimezoneOffsetFrom(TimezoneOffsetFrom elm, C context) { * @return the visitor result */ public T visitDateTimeComponentFrom(DateTimeComponentFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2034,7 +2081,7 @@ public T visitDateTimeComponentFrom(DateTimeComponentFrom elm, C context) { * @return the visitor result */ public T visitTimeOfDay(TimeOfDay elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2046,7 +2093,7 @@ public T visitTimeOfDay(TimeOfDay elm, C context) { * @return the visitor result */ public T visitToday(Today elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2058,7 +2105,7 @@ public T visitToday(Today elm, C context) { * @return the visitor result */ public T visitNow(Now elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2070,7 +2117,8 @@ public T visitNow(Now elm, C context) { * @return the visitor result */ public T visitDateTime(DateTime elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getYear() != null) { T childResult = visitExpression(elm.getYear(), context); result = aggregateResult(result, childResult); @@ -2103,6 +2151,7 @@ public T visitDateTime(DateTime elm, C context) { T childResult = visitExpression(elm.getTimezoneOffset(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2115,7 +2164,8 @@ public T visitDateTime(DateTime elm, C context) { * @return the visitor result */ public T visitDate(Date elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getYear() != null) { T childResult = visitExpression(elm.getYear(), context); result = aggregateResult(result, childResult); @@ -2128,6 +2178,7 @@ public T visitDate(Date elm, C context) { T childResult = visitExpression(elm.getDay(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2140,7 +2191,8 @@ public T visitDate(Date elm, C context) { * @return the visitor result */ public T visitTime(Time elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getHour() != null) { T childResult = visitExpression(elm.getHour(), context); result = aggregateResult(result, childResult); @@ -2157,6 +2209,7 @@ public T visitTime(Time elm, C context) { T childResult = visitExpression(elm.getMillisecond(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2169,7 +2222,7 @@ public T visitTime(Time elm, C context) { * @return the visitor result */ public T visitSameAs(SameAs elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2181,7 +2234,7 @@ public T visitSameAs(SameAs elm, C context) { * @return the visitor result */ public T visitSameOrBefore(SameOrBefore elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2193,7 +2246,7 @@ public T visitSameOrBefore(SameOrBefore elm, C context) { * @return the visitor result */ public T visitSameOrAfter(SameOrAfter elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2205,7 +2258,7 @@ public T visitSameOrAfter(SameOrAfter elm, C context) { * @return the visitor result */ public T visitWidth(Width elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2217,7 +2270,7 @@ public T visitWidth(Width elm, C context) { * @return the visitor result */ public T visitSize(Size elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2229,7 +2282,7 @@ public T visitSize(Size elm, C context) { * @return the visitor result */ public T visitPointFrom(PointFrom elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2241,7 +2294,7 @@ public T visitPointFrom(PointFrom elm, C context) { * @return the visitor result */ public T visitStart(Start elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2253,7 +2306,7 @@ public T visitStart(Start elm, C context) { * @return the visitor result */ public T visitEnd(End elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2265,7 +2318,7 @@ public T visitEnd(End elm, C context) { * @return the visitor result */ public T visitContains(Contains elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2277,7 +2330,7 @@ public T visitContains(Contains elm, C context) { * @return the visitor result */ public T visitProperContains(ProperContains elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2289,7 +2342,7 @@ public T visitProperContains(ProperContains elm, C context) { * @return the visitor result */ public T visitIn(In elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2301,7 +2354,7 @@ public T visitIn(In elm, C context) { * @return the visitor result */ public T visitProperIn(ProperIn elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2313,7 +2366,7 @@ public T visitProperIn(ProperIn elm, C context) { * @return the visitor result */ public T visitIncludes(Includes elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2325,7 +2378,7 @@ public T visitIncludes(Includes elm, C context) { * @return the visitor result */ public T visitIncludedIn(IncludedIn elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2337,7 +2390,7 @@ public T visitIncludedIn(IncludedIn elm, C context) { * @return the visitor result */ public T visitProperIncludes(ProperIncludes elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2349,7 +2402,7 @@ public T visitProperIncludes(ProperIncludes elm, C context) { * @return the visitor result */ public T visitProperIncludedIn(ProperIncludedIn elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2361,7 +2414,7 @@ public T visitProperIncludedIn(ProperIncludedIn elm, C context) { * @return the visitor result */ public T visitBefore(Before elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2373,7 +2426,7 @@ public T visitBefore(Before elm, C context) { * @return the visitor result */ public T visitAfter(After elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2385,7 +2438,7 @@ public T visitAfter(After elm, C context) { * @return the visitor result */ public T visitMeets(Meets elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2397,7 +2450,7 @@ public T visitMeets(Meets elm, C context) { * @return the visitor result */ public T visitMeetsBefore(MeetsBefore elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2409,7 +2462,7 @@ public T visitMeetsBefore(MeetsBefore elm, C context) { * @return the visitor result */ public T visitMeetsAfter(MeetsAfter elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2421,7 +2474,7 @@ public T visitMeetsAfter(MeetsAfter elm, C context) { * @return the visitor result */ public T visitOverlaps(Overlaps elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2433,7 +2486,7 @@ public T visitOverlaps(Overlaps elm, C context) { * @return the visitor result */ public T visitOverlapsBefore(OverlapsBefore elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2445,7 +2498,7 @@ public T visitOverlapsBefore(OverlapsBefore elm, C context) { * @return the visitor result */ public T visitOverlapsAfter(OverlapsAfter elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2457,7 +2510,7 @@ public T visitOverlapsAfter(OverlapsAfter elm, C context) { * @return the visitor result */ public T visitStarts(Starts elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2469,7 +2522,7 @@ public T visitStarts(Starts elm, C context) { * @return the visitor result */ public T visitEnds(Ends elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2481,7 +2534,7 @@ public T visitEnds(Ends elm, C context) { * @return the visitor result */ public T visitCollapse(Collapse elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2493,7 +2546,7 @@ public T visitCollapse(Collapse elm, C context) { * @return the visitor result */ public T visitExpand(Expand elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2505,7 +2558,7 @@ public T visitExpand(Expand elm, C context) { * @return the visitor result */ public T visitUnion(Union elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2517,7 +2570,7 @@ public T visitUnion(Union elm, C context) { * @return the visitor result */ public T visitIntersect(Intersect elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2529,7 +2582,7 @@ public T visitIntersect(Intersect elm, C context) { * @return the visitor result */ public T visitExcept(Except elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2541,7 +2594,7 @@ public T visitExcept(Except elm, C context) { * @return the visitor result */ public T visitExists(Exists elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2553,7 +2606,7 @@ public T visitExists(Exists elm, C context) { * @return the visitor result */ public T visitTimes(Times elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2565,15 +2618,17 @@ public T visitTimes(Times elm, C context) { * @return the visitor result */ public T visitFilter(Filter elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getCondition() != null) { - T childResult = visitElement(elm.getCondition(), context); + T childResult = visitExpression(elm.getCondition(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2586,11 +2641,13 @@ public T visitFilter(Filter elm, C context) { * @return the visitor result */ public T visitFirst(First elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2603,11 +2660,13 @@ public T visitFirst(First elm, C context) { * @return the visitor result */ public T visitLast(Last elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2620,19 +2679,21 @@ public T visitLast(Last elm, C context) { * @return the visitor result */ public T visitSlice(Slice elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getStartIndex() != null) { - T childResult = visitElement(elm.getStartIndex(), context); + T childResult = visitExpression(elm.getStartIndex(), context); result = aggregateResult(result, childResult); } if (elm.getEndIndex() != null) { - T childResult = visitElement(elm.getEndIndex(), context); + T childResult = visitExpression(elm.getEndIndex(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2645,11 +2706,13 @@ public T visitSlice(Slice elm, C context) { * @return the visitor result */ public T visitChildren(Children elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2662,11 +2725,13 @@ public T visitChildren(Children elm, C context) { * @return the visitor result */ public T visitDescendents(Descendents elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2679,27 +2744,29 @@ public T visitDescendents(Descendents elm, C context) { * @return the visitor result */ public T visitMessage(Message elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getCondition() != null) { - T childResult = visitElement(elm.getCondition(), context); + T childResult = visitExpression(elm.getCondition(), context); result = aggregateResult(result, childResult); } if (elm.getCode() != null) { - T childResult = visitElement(elm.getCode(), context); + T childResult = visitExpression(elm.getCode(), context); result = aggregateResult(result, childResult); } if (elm.getSeverity() != null) { - T childResult = visitElement(elm.getSeverity(), context); + T childResult = visitExpression(elm.getSeverity(), context); result = aggregateResult(result, childResult); } if (elm.getMessage() != null) { - T childResult = visitElement(elm.getMessage(), context); + T childResult = visitExpression(elm.getMessage(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2712,15 +2779,17 @@ public T visitMessage(Message elm, C context) { * @return the visitor result */ public T visitIndexOf(IndexOf elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getElement() != null) { - T childResult = visitElement(elm.getElement(), context); + T childResult = visitExpression(elm.getElement(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2733,7 +2802,7 @@ public T visitIndexOf(IndexOf elm, C context) { * @return the visitor result */ public T visitFlatten(Flatten elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2745,15 +2814,17 @@ public T visitFlatten(Flatten elm, C context) { * @return the visitor result */ public T visitSort(Sort elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } for (SortByItem sbi : elm.getBy()) { - T childResult = visitElement(sbi, context); + T childResult = visitSortByItem(sbi, context); result = aggregateResult(result, childResult); } + return result; } @@ -2766,15 +2837,17 @@ public T visitSort(Sort elm, C context) { * @return the visitor result */ public T visitForEach(ForEach elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getElement() != null) { - T childResult = visitElement(elm.getElement(), context); + T childResult = visitExpression(elm.getElement(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2787,15 +2860,17 @@ public T visitForEach(ForEach elm, C context) { * @return the visitor result */ public T visitRepeat(Repeat elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } if (elm.getElement() != null) { - T childResult = visitElement(elm.getElement(), context); + T childResult = visitExpression(elm.getElement(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2808,7 +2883,7 @@ public T visitRepeat(Repeat elm, C context) { * @return the visitor result */ public T visitDistinct(Distinct elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2820,7 +2895,7 @@ public T visitDistinct(Distinct elm, C context) { * @return the visitor result */ public T visitCurrent(Current elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2832,7 +2907,7 @@ public T visitCurrent(Current elm, C context) { * @return the visitor result */ public T visitIteration(Iteration elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2844,7 +2919,7 @@ public T visitIteration(Iteration elm, C context) { * @return the visitor result */ public T visitTotal(Total elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -2856,22 +2931,7 @@ public T visitTotal(Total elm, C context) { * @return the visitor result */ public T visitSingletonFrom(SingletonFrom elm, C context) { - return visitChildren(elm, context); - } - - /** - * Visits the children of an AggregateExpression - * @param elm - * @param context - * @return - */ - public T visitChildren(AggregateExpression elm, C context) { - T result = defaultResult(elm, context); - if (elm.getSource() != null) { - T childResult = visitElement(elm.getSource(), context); - result = aggregateResult(result, childResult); - } - return result; + return visitFields(elm, context); } /** @@ -2899,7 +2959,9 @@ public T visitAggregateExpression(AggregateExpression elm, C context) { else if (elm instanceof PopulationStdDev) return visitPopulationStdDev((PopulationStdDev) elm, context); else if (elm instanceof AllTrue) return visitAllTrue((AllTrue) elm, context); else if (elm instanceof AnyTrue) return visitAnyTrue((AnyTrue) elm, context); - return visitChildren(elm, context); + else + throw new IllegalArgumentException( + "Unsupported AggregateExpression type: " + elm.getClass().getName()); } /** @@ -2911,7 +2973,8 @@ public T visitAggregateExpression(AggregateExpression elm, C context) { * @return the visitor result */ public T visitAggregate(Aggregate elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields((AggregateExpression) elm, context); + if (elm.getInitialValue() != null) { T childResult = visitExpression(elm.getInitialValue(), context); result = aggregateResult(result, childResult); @@ -2920,6 +2983,7 @@ public T visitAggregate(Aggregate elm, C context) { T childResult = visitExpression(elm.getIteration(), context); result = aggregateResult(result, childResult); } + return result; } @@ -2932,7 +2996,7 @@ public T visitAggregate(Aggregate elm, C context) { * @return the visitor result */ public T visitCount(Count elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2944,7 +3008,7 @@ public T visitCount(Count elm, C context) { * @return the visitor result */ public T visitSum(Sum elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2956,7 +3020,7 @@ public T visitSum(Sum elm, C context) { * @return the visitor result */ public T visitProduct(Product elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2968,7 +3032,7 @@ public T visitProduct(Product elm, C context) { * @return the visitor result */ public T visitGeometricMean(GeometricMean elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2980,7 +3044,7 @@ public T visitGeometricMean(GeometricMean elm, C context) { * @return the visitor result */ public T visitMin(Min elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -2992,7 +3056,7 @@ public T visitMin(Min elm, C context) { * @return the visitor result */ public T visitMax(Max elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3004,7 +3068,7 @@ public T visitMax(Max elm, C context) { * @return the visitor result */ public T visitAvg(Avg elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3016,7 +3080,7 @@ public T visitAvg(Avg elm, C context) { * @return the visitor result */ public T visitMedian(Median elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3028,7 +3092,7 @@ public T visitMedian(Median elm, C context) { * @return the visitor result */ public T visitMode(Mode elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3040,7 +3104,7 @@ public T visitMode(Mode elm, C context) { * @return the visitor result */ public T visitVariance(Variance elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3052,7 +3116,7 @@ public T visitVariance(Variance elm, C context) { * @return the visitor result */ public T visitPopulationVariance(PopulationVariance elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3064,7 +3128,7 @@ public T visitPopulationVariance(PopulationVariance elm, C context) { * @return the visitor result */ public T visitStdDev(StdDev elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3076,7 +3140,7 @@ public T visitStdDev(StdDev elm, C context) { * @return the visitor result */ public T visitPopulationStdDev(PopulationStdDev elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3088,7 +3152,7 @@ public T visitPopulationStdDev(PopulationStdDev elm, C context) { * @return the visitor result */ public T visitAllTrue(AllTrue elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3100,22 +3164,7 @@ public T visitAllTrue(AllTrue elm, C context) { * @return the visitor result */ public T visitAnyTrue(AnyTrue elm, C context) { - return visitChildren(elm, context); - } - - /** - * Visits the children of a Property - * @param elm - * @param context - * @return - */ - public T visitChildren(Property elm, C context) { - T result = defaultResult(elm, context); - if (elm.getSource() != null) { - T childResult = visitExpression(elm.getSource(), context); - result = aggregateResult(result, childResult); - } - return result; + return visitFields(elm, context); } /** @@ -3127,21 +3176,13 @@ public T visitChildren(Property elm, C context) { * @return the visitor result */ public T visitProperty(Property elm, C context) { - return visitChildren(elm, context); - } + T result = visitFields(elm, context); - /** - * Visits the children of an AliasedQuerySource - * @param elm - * @param context - * @return - */ - public T visitChildren(AliasedQuerySource elm, C context) { - T result = defaultResult(elm, context); - if (elm.getExpression() != null) { - T childResult = visitExpression(elm.getExpression(), context); + if (elm.getSource() != null) { + T childResult = visitExpression(elm.getSource(), context); result = aggregateResult(result, childResult); } + return result; } @@ -3157,7 +3198,8 @@ public T visitAliasedQuerySource(AliasedQuerySource elm, C context) { if (elm instanceof RelationshipClause) { return visitRelationshipClause((RelationshipClause) elm, context); } - return visitChildren(elm, context); + + return visitFields(elm, context); } /** @@ -3169,41 +3211,13 @@ public T visitAliasedQuerySource(AliasedQuerySource elm, C context) { * @return the visitor result */ public T visitLetClause(LetClause elm, C context) { - if (elm.getExpression() != null) { - return visitElement(elm.getExpression(), context); - } - return null; - } - - /** - * Visits an expression that is the condition of a such that clause in a - * with or without clause. The isWith parameter indicates whether the clause - * is a with or a without. - * @param elm - * @param isWith - * @param context - * @return - */ - public T visitSuchThatClause(Expression elm, boolean isWith, C context) { - return visitElement(elm, context); - } + T result = visitFields(elm, context); - /** - * Visits the children of a RelationshipClause - * @param elm - * @param context - * @return - */ - public T visitChildren(RelationshipClause elm, C context) { - T result = defaultResult(elm, context); if (elm.getExpression() != null) { - T childResult = visitElement(elm.getExpression(), context); - result = aggregateResult(result, childResult); - } - if (elm.getSuchThat() != null) { - T childResult = visitSuchThatClause(elm.getSuchThat(), elm instanceof With, context); + T childResult = visitExpression(elm.getExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -3220,8 +3234,10 @@ public T visitRelationshipClause(RelationshipClause elm, C context) { return visitWith((With) elm, context); } else if (elm instanceof Without) { return visitWithout((Without) elm, context); + } else { + throw new IllegalArgumentException( + "Unknown RelationshipClause type: " + elm.getClass().getName()); } - return visitChildren(elm, context); } /** @@ -3233,7 +3249,7 @@ public T visitRelationshipClause(RelationshipClause elm, C context) { * @return the visitor result */ public T visitWith(With elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3245,7 +3261,7 @@ public T visitWith(With elm, C context) { * @return the visitor result */ public T visitWithout(Without elm, C context) { - return visitChildren(elm, context); + return visitFields(elm, context); } /** @@ -3257,18 +3273,15 @@ public T visitWithout(Without elm, C context) { * @return the visitor result */ public T visitSortByItem(SortByItem elm, C context) { - T result = defaultResult(elm, context); if (elm instanceof ByDirection) { - T childResult = visitByDirection((ByDirection) elm, context); - result = aggregateResult(result, childResult); + return visitByDirection((ByDirection) elm, context); } else if (elm instanceof ByColumn) { - T childResult = visitByColumn((ByColumn) elm, context); - result = aggregateResult(result, childResult); + return visitByColumn((ByColumn) elm, context); } else if (elm instanceof ByExpression) { - T childResult = visitByExpression((ByExpression) elm, context); - result = aggregateResult(result, childResult); - } - return result; + return visitByExpression((ByExpression) elm, context); + } else + throw new IllegalArgumentException( + "Unknown SortByItem type: " + elm.getClass().getName()); } /** @@ -3280,7 +3293,7 @@ public T visitSortByItem(SortByItem elm, C context) { * @return the visitor result */ public T visitByDirection(ByDirection elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -3292,7 +3305,7 @@ public T visitByDirection(ByDirection elm, C context) { * @return the visitor result */ public T visitByColumn(ByColumn elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -3304,11 +3317,13 @@ public T visitByColumn(ByColumn elm, C context) { * @return the visitor result */ public T visitByExpression(ByExpression elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getExpression() != null) { - T childResult = visitElement(elm.getExpression(), context); + T childResult = visitExpression(elm.getExpression(), context); result = aggregateResult(result, childResult); } + return result; } @@ -3321,11 +3336,13 @@ public T visitByExpression(ByExpression elm, C context) { * @return the visitor result */ public T visitSortClause(SortClause elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + for (SortByItem sbi : elm.getBy()) { - T childResult = visitElement(sbi, context); + T childResult = visitSortByItem(sbi, context); result = aggregateResult(result, childResult); } + return result; } @@ -3338,15 +3355,17 @@ public T visitSortClause(SortClause elm, C context) { * @return the visitor result */ public T visitAggregateClause(AggregateClause elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getExpression() != null) { - T childResult = visitElement(elm.getExpression(), context); + T childResult = visitExpression(elm.getExpression(), context); result = aggregateResult(result, childResult); } if (elm.getStarting() != null) { - T childResult = visitElement(elm.getStarting(), context); + T childResult = visitExpression(elm.getStarting(), context); result = aggregateResult(result, childResult); } + return result; } @@ -3359,23 +3378,14 @@ public T visitAggregateClause(AggregateClause elm, C context) { * @return the visitor result */ public T visitReturnClause(ReturnClause elm, C context) { - T result = defaultResult(elm, context); + T result = visitFields(elm, context); + if (elm.getExpression() != null) { T childResult = visitExpression(elm.getExpression(), context); result = aggregateResult(result, childResult); } - return result; - } - /** - * Visits an Expression that is the condition for a where clause - * in a Query. - * @param elm - * @param context - * @return - */ - public T visitWhereClause(Expression elm, C context) { - return visitElement(elm, context); + return result; } /** @@ -3387,39 +3397,41 @@ public T visitWhereClause(Expression elm, C context) { * @return the visitor result */ public T visitQuery(Query elm, C context) { - T result = defaultResult(elm, context); - for (AliasedQuerySource source : elm.getSource()) { - T childResult = visitElement(source, context); + T result = visitFields(elm, context); + + for (var source : elm.getSource()) { + T childResult = visitAliasedQuerySource(source, context); result = aggregateResult(result, childResult); } - if (elm.getLet() != null && !elm.getLet().isEmpty()) { - for (Element let : elm.getLet()) { - T childResult = visitElement(let, context); - result = aggregateResult(result, childResult); - } + for (var let : elm.getLet()) { + T childResult = visitLetClause(let, context); + result = aggregateResult(result, childResult); } - if (elm.getRelationship() != null && !elm.getRelationship().isEmpty()) { - for (Element relationship : elm.getRelationship()) { - T childResult = visitElement(relationship, context); - result = aggregateResult(result, childResult); - } + + for (var r : elm.getRelationship()) { + T childResult = visitRelationshipClause(r, context); + result = aggregateResult(result, childResult); } + if (elm.getWhere() != null) { - T childResult = visitWhereClause(elm.getWhere(), context); + T childResult = visitExpression(elm.getWhere(), context); result = aggregateResult(result, childResult); } if (elm.getReturn() != null) { - T childResult = visitElement(elm.getReturn(), context); + T childResult = visitReturnClause(elm.getReturn(), context); result = aggregateResult(result, childResult); } + if (elm.getAggregate() != null) { - T childResult = visitElement(elm.getAggregate(), context); + T childResult = visitAggregateClause(elm.getAggregate(), context); result = aggregateResult(result, childResult); } + if (elm.getSort() != null) { - T childResult = visitElement(elm.getSort(), context); + T childResult = visitSortClause(elm.getSort(), context); result = aggregateResult(result, childResult); } + return result; } @@ -3432,7 +3444,7 @@ public T visitQuery(Query elm, C context) { * @return the visitor result */ public T visitAliasRef(AliasRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); } /** @@ -3444,6 +3456,177 @@ public T visitAliasRef(AliasRef elm, C context) { * @return the visitor result */ public T visitQueryLetRef(QueryLetRef elm, C context) { - return defaultResult(elm, context); + return visitFields(elm, context); + } + + protected T visitFields(Element elm, C context) { + T result = defaultResult(elm, context); + + if (elm.getResultTypeSpecifier() != null) { + T childResult = visitTypeSpecifier(elm.getResultTypeSpecifier(), context); + result = aggregateResult(result, childResult); + } + + return result; + } + + protected T visitFields(Expression elm, C context) { + return visitFields((Element) elm, context); + } + + protected T visitFields(RelationshipClause elm, C context) { + T result = visitFields((AliasedQuerySource) elm, context); + + if (elm.getSuchThat() != null) { + T childResult = visitExpression(elm.getSuchThat(), context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * visits the fields of an AggregateExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(AggregateExpression elm, C context) { + T result = visitFields((Expression) elm, context); + + if (elm.getSource() != null) { + T childResult = visitExpression(elm.getSource(), context); + result = aggregateResult(result, childResult); + } + + for (var s : elm.getSignature()) { + T childResult = visitTypeSpecifier(s, context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * Visit the fields of an ExpressionDef + * @param elm + * @param context + * @return + */ + protected T visitFields(ExpressionDef elm, C context) { + T result = visitFields((Element) elm, context); + + if (elm.getAccessLevel() != null) { + T childResult = visitAccessModifier(elm.getAccessLevel(), context); + result = aggregateResult(result, childResult); + } + if (elm.getExpression() != null) { + T childResult = visitExpression(elm.getExpression(), context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * Visits the fields of a UnaryExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(UnaryExpression elm, C context) { + T result = visitFields((OperatorExpression) elm, context); + + if (elm.getOperand() != null) { + T childResult = visitExpression(elm.getOperand(), context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * visits the fields of an NaryExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(NaryExpression elm, C context) { + T result = visitFields((OperatorExpression) elm, context); + + for (Expression e : elm.getOperand()) { + T childResult = visitExpression(e, context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * Visits the fields of a TernaryExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(TernaryExpression elm, C context) { + T result = visitFields((OperatorExpression) elm, context); + + for (var s : elm.getOperand()) { + T childResult = visitExpression(s, context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * Visits the fields of an OperatorExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(OperatorExpression elm, C context) { + T result = visitFields((Expression) elm, context); + + for (var s : elm.getSignature()) { + T childResult = visitTypeSpecifier(s, context); + result = aggregateResult(result, childResult); + } + + return result; + } + + /** + * visits the fields of a BinaryExpression + * + * @param elm + * @param context + * @return + */ + protected T visitFields(BinaryExpression elm, C context) { + T result = visitFields((OperatorExpression) elm, context); + + for (Expression e : elm.getOperand()) { + T childResult = visitExpression(e, context); + result = aggregateResult(result, childResult); + } + + return result; + } + + protected T visitFields(AliasedQuerySource elm, C context) { + T result = visitFields((Element) elm, context); + + if (elm.getExpression() != null) { + T childResult = visitExpression(elm.getExpression(), context); + result = aggregateResult(result, childResult); + } + + return result; } } diff --git a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitor.java b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitor.java similarity index 84% rename from Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitor.java rename to Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitor.java index c3b753490..38973e2f5 100644 --- a/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitor.java +++ b/Src/java/elm/src/main/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitor.java @@ -9,7 +9,7 @@ * Useful for quick visitor implementations, such as counting all nodes, or finding a specific element * type. */ -public class ElmFunctionalVisitor extends ElmBaseLibraryVisitor { +public class FunctionalElmLibraryVisitor extends BaseElmLibraryVisitor { private final BiFunction defaultResult; private final BiFunction aggregateResult; @@ -19,7 +19,7 @@ public class ElmFunctionalVisitor extends ElmBaseLibraryVisitor { * @param defaultResult the function for processing a visited element * @param aggregateResult the function for aggregating results */ - public ElmFunctionalVisitor(BiFunction defaultResult, BiFunction aggregateResult) { + public FunctionalElmLibraryVisitor(BiFunction defaultResult, BiFunction aggregateResult) { this.defaultResult = Objects.requireNonNull(defaultResult); this.aggregateResult = Objects.requireNonNull(aggregateResult); } diff --git a/Src/java/elm/src/test/java/org/cqframework/cql/elm/ElmBaseVisitorTest.java b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/BaseElmVisitorTest.java similarity index 84% rename from Src/java/elm/src/test/java/org/cqframework/cql/elm/ElmBaseVisitorTest.java rename to Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/BaseElmVisitorTest.java index e9d83f813..6125f697c 100644 --- a/Src/java/elm/src/test/java/org/cqframework/cql/elm/ElmBaseVisitorTest.java +++ b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/BaseElmVisitorTest.java @@ -1,22 +1,20 @@ -package org.cqframework.cql.elm; +package org.cqframework.cql.elm.visiting; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.cqframework.cql.elm.tracking.Trackable; -import org.cqframework.cql.elm.visiting.ElmBaseVisitor; import org.hl7.elm.r1.ByDirection; import org.hl7.elm.r1.Sort; import org.hl7.elm.r1.SortByItem; import org.junit.Test; -public class ElmBaseVisitorTest { +public class BaseElmVisitorTest { @Test public void sortByVisited() { - // set up visitor that returns true if it visits a SortByItem - var sortByFinder = new ElmBaseVisitor() { + var sortByFinder = new BaseElmVisitor() { @Override public Boolean defaultResult(Trackable t, Void context) { if (t instanceof SortByItem) { diff --git a/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/DesignTests.java b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/DesignTests.java new file mode 100644 index 000000000..f5b0cd8d7 --- /dev/null +++ b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/DesignTests.java @@ -0,0 +1,69 @@ +package org.cqframework.cql.elm.visiting; + +import static com.tngtech.archunit.base.DescribedPredicate.and; +import static com.tngtech.archunit.base.DescribedPredicate.anyElementThat; +import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo; +import static com.tngtech.archunit.core.domain.properties.HasModifiers.Predicates.modifier; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods; + +import com.tngtech.archunit.core.domain.JavaClasses; +import com.tngtech.archunit.core.domain.JavaMethod; +import com.tngtech.archunit.core.domain.JavaModifier; +import com.tngtech.archunit.core.importer.ClassFileImporter; +import com.tngtech.archunit.lang.ArchCondition; +import com.tngtech.archunit.lang.ConditionEvents; +import com.tngtech.archunit.lang.SimpleConditionEvent; +import org.hl7.elm.r1.Element; +import org.junit.Test; + +public class DesignTests { + + private static final JavaClasses importedClasses = + new ClassFileImporter().importPackages("org.cqframework.cql.elm", "org.hl7.elm.r1"); + + @Test + public void ensureVisitAbstractDoesNotCallDefaultResult() { + + var isAbstractElementType = and(modifier(JavaModifier.ABSTRACT), assignableTo(Element.class)); + + methods() + .that() + .areDeclaredInClassesThat() + .areAssignableTo(BaseElmVisitor.class) + .and() + .haveNameStartingWith("visit") + .and() + .doNotHaveName("visitFields") + .and() + .haveRawParameterTypes(anyElementThat(isAbstractElementType)) + .should(new NotCallDefaultResult()) + .because("The visitXYZ (where XYZ is an Element type) methods " + + "for abstract classes should not call defaultResult or visitFields, " + + "since that means the subtypes properties are probably missed. " + + "Instead, those methods should forward to the subtype visit method.") + .check(importedClasses); + } + + static class NotCallDefaultResult extends ArchCondition { + + public NotCallDefaultResult() { + super("not call the defaultVisit method"); + } + + @Override + public void check(JavaMethod item, ConditionEvents events) { + var callsDefaultResult = item.getCallsFromSelf().stream() + .anyMatch(x -> x.getTarget().getName().equals("defaultResult")); + + var callsVisitFields = item.getCallsFromSelf().stream() + .anyMatch(x -> x.getTarget().getName().equals("visitFields")); + if (callsDefaultResult || callsVisitFields) { + events.add(SimpleConditionEvent.violated( + item, String.format("Method %s calls defaultResult or visitFields", item.getFullName()))); + } else { + events.add(SimpleConditionEvent.satisfied( + item, String.format("Method %s does not call defaultResult", item.getFullName()))); + } + } + } +} diff --git a/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitorTest.java b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitorTest.java similarity index 62% rename from Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitorTest.java rename to Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitorTest.java index 2a0dfd876..abf6c7218 100644 --- a/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/ElmFunctionalVisitorTest.java +++ b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/FunctionalElmLibraryVisitorTest.java @@ -9,12 +9,12 @@ import org.hl7.elm.r1.Library.Statements; import org.junit.Test; -public class ElmFunctionalVisitorTest { +public class FunctionalElmLibraryVisitorTest { @Test public void countTest() { // set up visitor that counts all visited elements - var trackableCounter = new ElmFunctionalVisitor((elm, context) -> 1, Integer::sum); + var trackableCounter = new FunctionalElmLibraryVisitor((elm, context) -> 1, Integer::sum); var library = new Library(); library.setStatements(new Statements()); @@ -26,13 +26,13 @@ public void countTest() { assertEquals(4 + 3, result.intValue()); // ELM elements + implicit access modifiers // set up visitor that counts all visited ELM elements - var elmCounter = - new ElmFunctionalVisitor((elm, context) -> elm instanceof Element ? 1 : 0, Integer::sum); + var elmCounter = new FunctionalElmLibraryVisitor( + (elm, context) -> elm instanceof Element ? 1 : 0, Integer::sum); result = elmCounter.visitLibrary(library, null); assertEquals(4, result.intValue()); - var maxFiveCounter = new ElmFunctionalVisitor( + var maxFiveCounter = new FunctionalElmLibraryVisitor( (elm, context) -> 1, (aggregate, nextResult) -> aggregate >= 5 ? aggregate : aggregate + nextResult); result = maxFiveCounter.visitLibrary(library, null); @@ -41,8 +41,10 @@ public void countTest() { @Test public void nullVisitorTest() { - assertThrows(NullPointerException.class, () -> new ElmFunctionalVisitor(null, null)); - assertThrows(NullPointerException.class, () -> new ElmFunctionalVisitor(null, Integer::sum)); - assertThrows(NullPointerException.class, () -> new ElmFunctionalVisitor((x, y) -> 1, null)); + assertThrows(NullPointerException.class, () -> new FunctionalElmLibraryVisitor(null, null)); + assertThrows( + NullPointerException.class, () -> new FunctionalElmLibraryVisitor(null, Integer::sum)); + assertThrows( + NullPointerException.class, () -> new FunctionalElmLibraryVisitor((x, y) -> 1, null)); } } diff --git a/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/RandomElmGraphTest.java b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/RandomElmGraphTest.java new file mode 100644 index 000000000..a9ac8c425 --- /dev/null +++ b/Src/java/elm/src/test/java/org/cqframework/cql/elm/visiting/RandomElmGraphTest.java @@ -0,0 +1,162 @@ +package org.cqframework.cql.elm.visiting; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Field; +import java.nio.charset.Charset; +import java.util.HashMap; +import javax.xml.namespace.QName; +import org.hl7.cql_annotations.r1.Narrative; +import org.hl7.elm.r1.AccessModifier; +import org.hl7.elm.r1.Element; +import org.hl7.elm.r1.Library; +import org.hl7.elm.r1.TypeSpecifier; +import org.jeasy.random.EasyRandom; +import org.jeasy.random.EasyRandomParameters; +import org.jeasy.random.ObjenesisObjectFactory; +import org.jeasy.random.api.ExclusionPolicy; +import org.jeasy.random.api.RandomizerContext; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; + +@RunWith(Parameterized.class) +public class RandomElmGraphTest { + + @Parameters + public static Iterable seeds() { + // I randomly picked these seeds until + // I got 3 in a row that passed without errors. + // Not perfect, but it's a start. + return java.util.Arrays.asList(new Object[][] {{96874}, {15895}, {121873}, {174617}}); + } + + public RandomElmGraphTest(int seed) { + this.seed = seed; + } + + private int seed; + + @Test + public void allNodesVisited() { + allNodesVisited(seed); + } + + public void allNodesVisited(int seed) { + // This test generates a random ELM graph and verifies that all nodes are + // visited exactly once. + var elementsGenerated = new HashMap(); + var countingObjectFactory = new ObjenesisObjectFactory() { + @Override + public T createInstance(Class type, RandomizerContext context) { + var t = super.createInstance(type, context); + if (t instanceof Element) { + var hash = System.identityHashCode(t); + elementsGenerated.put(hash, (Element) t); + } + + // Debugging for specific types and paths + // that aren't being visited. + // if (t instanceof ConvertsToDate || t instanceof SplitOnMatches || t instanceof DateFrom) { + // printContext((Element) t, context); + // } + + return t; + } + + private void printContext(Element t, RandomizerContext context) { + System.err.println(String.format( + "Type: %s, Parent: %s, Path: %s, Hash: %s", + t.getClass().getSimpleName(), + context.getCurrentObject().getClass().getSimpleName(), + context.getCurrentField(), + System.identityHashCode(t))); + } + }; + + var randomParams = new EasyRandomParameters() + .objectFactory(countingObjectFactory) + .seed(seed) + .randomizationDepth(15) + .objectPoolSize(1000) // Never reuse objects + .charset(Charset.forName("UTF-8")) + .stringLengthRange(5, 50) + .collectionSizeRange(1, 3) + .exclusionPolicy(new NoTypeSpecifierRecursionPolicy()) + .scanClasspathForConcreteTypes(true); + + var randomElmGenerator = new EasyRandom(randomParams); + var randomElm = randomElmGenerator.nextObject(Library.class); + + var elementsGeneratedCount = elementsGenerated.size(); + + var elementsVisited = new HashMap(); + var elementsDuplicated = new HashMap(); + var countingVisitor = new FunctionalElmLibraryVisitor>( + (x, y) -> { + if (x instanceof Element) { + var hash = System.identityHashCode(x); + if (!elementsVisited.containsKey(hash)) { + elementsVisited.put(hash, (Element) x); + return 1; + } + elementsDuplicated.put(hash, (Element) x); + return 0; + } + return 0; + }, + (a, b) -> a + b); + + var visitorCount = countingVisitor.visitLibrary(randomElm, elementsVisited); + + elementsGenerated.keySet().removeAll(elementsVisited.keySet()); + if (!elementsGenerated.isEmpty()) { + System.err.println("Elements Missed:"); + elementsGenerated.forEach((x, e) -> System.err.println( + String.format("Type: %s, Hash: %s", e.getClass().getSimpleName(), x))); + } + + // No missed nodes, working as intended + assertEquals(0, elementsGenerated.size()); + + // Check that we didn't double-visit any nodes + if (!elementsDuplicated.isEmpty()) { + System.err.println("Elements Duplicated:"); + elementsDuplicated.forEach((x, e) -> System.err.println( + String.format("Type: %s, Hash: %s", e.getClass().getSimpleName(), x))); + } + + // No duplicate visits, working as intended + assertEquals(0, elementsDuplicated.size()); + + // if these are equal, then aggregateResult + // ran once for every node in the graph (working as intended) + assertEquals(elementsGeneratedCount, visitorCount.intValue()); + } + + class NoTypeSpecifierRecursionPolicy implements ExclusionPolicy { + + // Don't recurse into TypeSpecifier.resultTypeSpecifier + @Override + public boolean shouldBeExcluded(Field field, RandomizerContext context) { + if (field.getType().getPackageName().startsWith("org.hl7.cql")) { + return true; + } + + return (field.getName().equals("resultTypeSpecifier") + && TypeSpecifier.class.isAssignableFrom(field.getType())) + || field.getName().equals("signature"); + } + + // These are excluded to simplify the ELM graph while bugs are being worked out. + @Override + public boolean shouldBeExcluded(Class type, RandomizerContext context) { + if (type.getPackageName().startsWith("org.hl7.cql")) { + return true; + } + + return type == QName.class || type == Narrative.class || type == AccessModifier.class; + } + } +} diff --git a/Src/java/engine/src/main/java/org/opencds/cqf/cql/engine/execution/EvaluationVisitor.java b/Src/java/engine/src/main/java/org/opencds/cqf/cql/engine/execution/EvaluationVisitor.java index 12d91cee8..b841b2def 100644 --- a/Src/java/engine/src/main/java/org/opencds/cqf/cql/engine/execution/EvaluationVisitor.java +++ b/Src/java/engine/src/main/java/org/opencds/cqf/cql/engine/execution/EvaluationVisitor.java @@ -4,14 +4,14 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -import org.cqframework.cql.elm.visiting.ElmBaseLibraryVisitor; +import org.cqframework.cql.elm.visiting.BaseElmLibraryVisitor; import org.hl7.cql.model.IntervalType; import org.hl7.cql.model.ListType; import org.hl7.elm.r1.*; import org.opencds.cqf.cql.engine.elm.executing.*; import org.opencds.cqf.cql.engine.runtime.TemporalHelper; -public class EvaluationVisitor extends ElmBaseLibraryVisitor { +public class EvaluationVisitor extends BaseElmLibraryVisitor { @Override public Object visitExpressionDef(ExpressionDef expressionDef, State state) { diff --git a/Src/java/engine/src/test/java/org/opencds/cqf/cql/engine/execution/CqlLibraryLoadingTest.java b/Src/java/engine/src/test/java/org/opencds/cqf/cql/engine/execution/CqlLibraryLoadingTest.java index e03d8f5f8..413a39036 100644 --- a/Src/java/engine/src/test/java/org/opencds/cqf/cql/engine/execution/CqlLibraryLoadingTest.java +++ b/Src/java/engine/src/test/java/org/opencds/cqf/cql/engine/execution/CqlLibraryLoadingTest.java @@ -1,7 +1,7 @@ package org.opencds.cqf.cql.engine.execution; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; -import static org.junit.Assert.assertThat; import org.cqframework.cql.cql2elm.CqlIncludeException; import org.hl7.elm.r1.VersionedIdentifier; diff --git a/codecov.yaml b/codecov.yaml index 9b5f5654a..fd907fd55 100644 --- a/codecov.yaml +++ b/codecov.yaml @@ -1,3 +1,6 @@ +codecov: + max_report_age: off + coverage: status: project: