diff --git a/lkql/build/railroad-diagrams/binding_pattern.svg b/lkql/build/railroad-diagrams/binding_pattern.svg deleted file mode 100644 index 7acf16018..000000000 --- a/lkql/build/railroad-diagrams/binding_pattern.svg +++ /dev/null @@ -1,41 +0,0 @@ - - - -binding_pattern - - -id -'@' -value_pattern -value_pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/chained_node_pattern.svg b/lkql/build/railroad-diagrams/chained_node_pattern.svg deleted file mode 100644 index 633760fe0..000000000 --- a/lkql/build/railroad-diagrams/chained_node_pattern.svg +++ /dev/null @@ -1,56 +0,0 @@ - - - -chained_node_pattern - - -filtered_pattern - - - -selector_call -'is' -filtered_pattern - -'.' -id -'is' -filtered_pattern - -'.' -fun_call -'is' -filtered_pattern - -filtered_pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/detail_value.svg b/lkql/build/railroad-diagrams/detail_value.svg deleted file mode 100644 index 848e70831..000000000 --- a/lkql/build/railroad-diagrams/detail_value.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - -detail_value - - -pattern - -expr \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/filtered_pattern.svg b/lkql/build/railroad-diagrams/filtered_pattern.svg deleted file mode 100644 index 6ae305bd6..000000000 --- a/lkql/build/railroad-diagrams/filtered_pattern.svg +++ /dev/null @@ -1,41 +0,0 @@ - - - -filtered_pattern - - -binding_pattern -'when' -expr -binding_pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/list_pattern.svg b/lkql/build/railroad-diagrams/list_pattern.svg index 39f416053..c14349354 100644 --- a/lkql/build/railroad-diagrams/list_pattern.svg +++ b/lkql/build/railroad-diagrams/list_pattern.svg @@ -1,4 +1,4 @@ - + list_pattern - + '[' - - -binding_pattern -splat_pattern -',' -']' \ No newline at end of file + + +splat_pattern +value_pattern +',' +']' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/or_pattern.svg b/lkql/build/railroad-diagrams/or_pattern.svg new file mode 100644 index 000000000..288f9b6d5 --- /dev/null +++ b/lkql/build/railroad-diagrams/or_pattern.svg @@ -0,0 +1,41 @@ + + + +or_pattern + + +pattern +'|' +or_pattern +pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/pattern.svg b/lkql/build/railroad-diagrams/pattern.svg index 84651c033..9b6f6494b 100644 --- a/lkql/build/railroad-diagrams/pattern.svg +++ b/lkql/build/railroad-diagrams/pattern.svg @@ -1,4 +1,4 @@ - + pattern - - -filtered_pattern -'or' -pattern -filtered_pattern \ No newline at end of file + + +value_pattern +'when' +expr +value_pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/pattern_arg.svg b/lkql/build/railroad-diagrams/pattern_arg.svg index 8d0c4cd92..6cb95e2da 100644 --- a/lkql/build/railroad-diagrams/pattern_arg.svg +++ b/lkql/build/railroad-diagrams/pattern_arg.svg @@ -1,4 +1,4 @@ - + pattern_arg - - + + selector_call -'is' -pattern - +':' +or_pattern + id -'is' -pattern - +':' +or_pattern + fun_call -'is' -pattern \ No newline at end of file +':' +or_pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/query.svg b/lkql/build/railroad-diagrams/query.svg index 8133f221f..718acfc58 100644 --- a/lkql/build/railroad-diagrams/query.svg +++ b/lkql/build/railroad-diagrams/query.svg @@ -1,4 +1,4 @@ - + -query - - - - -'from' - -expr - -'*' -expr - - - -'through' - -expr -'select' - - -Identifier - -pattern \ No newline at end of file +query + + +'from' + + +'*' +expr + + + +'through' + +expr +'select' + + +Identifier + +pattern + + + + +'through' + +expr +'select' + + +Identifier + +pattern \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/selector_arm.svg b/lkql/build/railroad-diagrams/selector_arm.svg index 633de5f65..1b7e90b4e 100644 --- a/lkql/build/railroad-diagrams/selector_arm.svg +++ b/lkql/build/railroad-diagrams/selector_arm.svg @@ -1,4 +1,4 @@ - + selector_arm - + '|' pattern -'=>' - -selector_expr -'<>' \ No newline at end of file +'=>' +expr \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/selector_expr.svg b/lkql/build/railroad-diagrams/selector_expr.svg index cfd156511..2fa4d8788 100644 --- a/lkql/build/railroad-diagrams/selector_expr.svg +++ b/lkql/build/railroad-diagrams/selector_expr.svg @@ -1,4 +1,4 @@ - + -selector_expr - - - -'rec' - -'skip' - - -expr - -'*' -expr \ No newline at end of file +selector_expr + + +'rec' +'(' + + +'*' +expr +',' + + +'*' +expr +')' + +'rec' +'(' + + +'*' +expr +')' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/tuple_pattern.svg b/lkql/build/railroad-diagrams/tuple_pattern.svg index 5a5183f9f..db3c070e8 100644 --- a/lkql/build/railroad-diagrams/tuple_pattern.svg +++ b/lkql/build/railroad-diagrams/tuple_pattern.svg @@ -1,4 +1,4 @@ - + tuple_pattern - + '(' - -binding_pattern -',' -')' \ No newline at end of file + +value_pattern +',' +')' \ No newline at end of file diff --git a/lkql/build/railroad-diagrams/value_expr.svg b/lkql/build/railroad-diagrams/value_expr.svg index 03c0a3b83..ef45dee44 100644 --- a/lkql/build/railroad-diagrams/value_expr.svg +++ b/lkql/build/railroad-diagrams/value_expr.svg @@ -1,4 +1,4 @@ - + value_pattern - - - - -'*' - -kind_name - + + + + +'*' + +kind_name + '(' -pattern -')' - -'(' - -pattern_arg -',' -')' - -kind_name - -'*' - -'null' -regex_pattern - -'not' -value_pattern -bool_pattern -integer_pattern -list_pattern -object_pattern - -'(' -pattern -')' -tuple_pattern \ No newline at end of file +or_pattern +')' + +'(' + +pattern_arg +',' +')' + +kind_name + +'*' + +'null' +regex_pattern + +'not' +value_pattern +bool_pattern +integer_pattern +list_pattern +object_pattern + +id + + + +'@' +value_pattern + +'(' +or_pattern +')' +tuple_pattern \ No newline at end of file diff --git a/lkql/language/parser.py b/lkql/language/parser.py index 119b043ab..ad7713f23 100644 --- a/lkql/language/parser.py +++ b/lkql/language/parser.py @@ -303,15 +303,12 @@ class ArithBinOp(BinOp): pass -class Unpack(Expr): +class Unpack(LkqlNode): """ - Unpacking operator, written ``*``. - - For instance:: - - \\*listValue + Qualifier for unpack operator ("*"). """ - collection_expr = Field(type=Expr) + enum_node = True + qualifier = True class ValDecl(Declaration): @@ -415,7 +412,7 @@ class BindingPattern(BasePattern): """ binding = Field(type=Identifier) - value_pattern = Field(type=ValuePattern) + value_pattern = Field(type=BasePattern) class IsClause(Expr): @@ -531,7 +528,7 @@ class NotPattern(ValuePattern): let non_objects = select not ObjectDecl """ - pattern = Field(type=ValuePattern) + pattern = Field(type=BasePattern) @abstract @@ -555,6 +552,7 @@ class Query(Expr): select ObjectDecl [child] AspectAssoc """ + unpack_from = Field(type=Unpack) from_expr = Field(type=Expr) through_expr = Field(type=Expr) query_kind = Field(type=QueryKind) @@ -847,27 +845,15 @@ def min_depth_expr(): Self.depth_expr) -class SelectorExprMode(LkqlNode): +class RecExpr(Expr): """ - Modes for selector values: - - - ``default``: add the value to the result set - - ``rec``: add the value to the result set and call the selector - recursively - - ``skip``: call the selector recursively without adding the value to the - result set + Expression that is only valid in a selector. Describes the next actions of + a selector. """ - enum_node = True - - alternatives = ['default', 'rec', 'skip'] - - -class SelectorExpr(LkqlNode): - """ - Expression appearing in the right part of a selector arm. - """ - mode = Field(type=SelectorExprMode) - expr = Field(type=Expr) + recurse_unpack = Field(type=Unpack) + recurse_expr = Field(type=Expr) + result_unpack = Field(type=Unpack) + result_expr = Field(type=Expr) class SelectorArm(LkqlNode): @@ -880,7 +866,7 @@ class SelectorArm(LkqlNode): """ pattern = Field(type=BasePattern) - exprs_list = Field(type=SelectorExpr.list) + expr = Field(type=Expr) class SelectorDecl(Declaration): @@ -897,20 +883,6 @@ class SelectorDecl(Declaration): def doc(): return Self.doc_node - @langkit_property(return_type=SelectorExpr.list, public=True) - def nth_expressions(n=(T.Int, 0)): - """ - Return the selector expressions associated with the nth selector arm. - """ - return Self.arms.at(n - 1).exprs_list - - @langkit_property(return_type=BasePattern.entity.array, public=True) - def patterns(): - """ - Return a list of the patterns that appear n the selector's arms. - """ - return Self.arms.map(lambda x: x.pattern.as_entity) - class SelectorCall(LkqlNode): """ @@ -1067,28 +1039,32 @@ class Tuple(Expr): import_clause=Import("import", G.id), - query=Query( - Opt("from", Or(G.expr, Unpack("*", G.expr))), - Opt("through", Or(G.expr)), - "select", c(), - Or(QueryKind.alt_first(L.Identifier(match_text="first")), - QueryKind.alt_all()), - G.pattern - ), - - pattern=Or( - OrPattern(G.filtered_pattern, "or", G.pattern), - G.filtered_pattern + query=Or( + Query( + "from", Unpack("*"), G.expr, + Opt("through", Or(G.expr)), + "select", c(), + Or(QueryKind.alt_first(L.Identifier(match_text="first")), + QueryKind.alt_all()), + G.pattern + ), + Query( + Null(Unpack), Null(G.expr), + Opt("through", Or(G.expr)), + "select", c(), + Or(QueryKind.alt_first(L.Identifier(match_text="first")), + QueryKind.alt_all()), + G.pattern + ), ), - filtered_pattern=Or( - FilteredPattern(G.binding_pattern, "when", G.expr), - G.binding_pattern - + or_pattern=Or( + OrPattern(G.pattern, "|", G.or_pattern), + G.pattern ), - binding_pattern=Or( - BindingPattern(G.id, "@", G.value_pattern), + pattern=Or( + FilteredPattern(G.value_pattern, "when", G.expr), G.value_pattern ), @@ -1099,7 +1075,7 @@ class Tuple(Expr): Or(UniversalPattern("*"), NodeKindPattern(G.kind_name), - ParenPattern("(", G.pattern, ")")), + ParenPattern("(", G.or_pattern, ")")), Pick("(", c(), List(G.pattern_arg, sep=","), ")") ), @@ -1112,7 +1088,8 @@ class Tuple(Expr): G.integer_pattern, G.list_pattern, G.object_pattern, - ParenPattern("(", G.pattern, ")"), + BindingPattern(G.id, Opt("@", G.value_pattern)), + ParenPattern("(", G.or_pattern, ")"), G.tuple_pattern ), @@ -1128,19 +1105,19 @@ class Tuple(Expr): integer_pattern=IntegerPattern(Token.Integer), list_pattern=ListPattern( "[", - List(G.binding_pattern | G.splat_pattern, sep=","), "]" + List(G.splat_pattern | G.value_pattern, sep=","), "]" ), object_pattern=ObjectPattern( "{", List(G.object_pattern_assoc | G.splat_pattern, sep=",", empty_valid=False), "}" ), - tuple_pattern=TuplePattern("(", List(G.binding_pattern, sep=","), ")"), + tuple_pattern=TuplePattern("(", List(G.value_pattern, sep=","), ")"), pattern_arg=Or( - NodePatternSelector(G.selector_call, "is", G.pattern), - NodePatternField(G.id, "is", c(), G.pattern), - NodePatternProperty(G.fun_call, "is", c(), G.pattern) + NodePatternSelector(G.selector_call, ":", G.or_pattern), + NodePatternField(G.id, ":", c(), G.or_pattern), + NodePatternProperty(G.fun_call, ":", c(), G.or_pattern) ), selector_call=SelectorCall( @@ -1248,6 +1225,7 @@ class Tuple(Expr): SafeAccess(G.value_expr, "?.", c(), G.id), Indexing(G.value_expr, "[", c(), G.expr, "]"), SafeIndexing(G.value_expr, "?[", c(), G.expr, "]"), + G.selector_expr, FunCall( G.value_expr, Safe("?"), "(", c(), List(G.arg, empty_valid=True, sep=","), ")" @@ -1328,16 +1306,12 @@ class Tuple(Expr): selector_arm=SelectorArm( "|", G.pattern, - "=>", - List(G.selector_expr, - empty_valid=False, sep="<>") + "=>", G.expr ), - selector_expr=SelectorExpr( - Or(SelectorExprMode.alt_rec("rec"), - SelectorExprMode.alt_skip("skip"), - SelectorExprMode.alt_default()), - Or(G.expr, Unpack("*", G.expr)) + selector_expr=Or( + RecExpr("rec", "(", Unpack("*"), G.expr, ",", Unpack("*"), G.expr, ")"), + RecExpr("rec", "(", Unpack("*"), G.expr, Null(Unpack), Null(G.expr), ")") ), match=Match("match", G.expr, List(G.match_arm, empty_valid=False)), diff --git a/lkql_checker/share/lkql/abstract_type_declarations.lkql b/lkql_checker/share/lkql/abstract_type_declarations.lkql index bd4a7b52e..281893ace 100644 --- a/lkql_checker/share/lkql/abstract_type_declarations.lkql +++ b/lkql_checker/share/lkql/abstract_type_declarations.lkql @@ -5,5 +5,5 @@ @check(message="declaration of abstract type", help="abstract types", category="Feature") fun abstract_type_declarations(node) = - node is (RecordTypeDef or DerivedTypeDef or PrivateTypeDef) + node is (RecordTypeDef | DerivedTypeDef | PrivateTypeDef) when node.f_has_abstract.p_as_bool() diff --git a/lkql_checker/share/lkql/access_to_local_objects.lkql b/lkql_checker/share/lkql/access_to_local_objects.lkql index ff94e4807..9955b293b 100644 --- a/lkql_checker/share/lkql/access_to_local_objects.lkql +++ b/lkql_checker/share/lkql/access_to_local_objects.lkql @@ -13,8 +13,8 @@ import stdlib fun has_access_type(n) = - n.p_type_expression() is TypeExpr(p_designated_type_decl() is - BaseTypeDecl(p_is_access_type() is true)) + n.p_type_expression() is TypeExpr(p_designated_type_decl(): + BaseTypeDecl(p_is_access_type(): true)) fun denotes_local_object(n) = { fun dotted_prefix(n) = @@ -29,7 +29,7 @@ fun denotes_local_object(n) = { denotes_local_object(n.f_prefix) | p@GenericPackageInstantiation => stdlib.has_local_scope(p) or denotes_local_object(n.f_prefix) - | r@* => + | r => (not has_access_type(r)) and denotes_local_object(n.f_prefix); match n diff --git a/lkql_checker/share/lkql/actual_parameters.lkql b/lkql_checker/share/lkql/actual_parameters.lkql index 04c22ef44..842de408d 100644 --- a/lkql_checker/share/lkql/actual_parameters.lkql +++ b/lkql_checker/share/lkql/actual_parameters.lkql @@ -16,7 +16,7 @@ fun strip(node) = | ParenExpr => strip(node.f_expr) # Strip type qualifications and conversions | QualExpr => strip(node.f_suffix) - | CallExpr(f_name is Name(p_referenced_decl() is BaseTypeDecl)) + | CallExpr(f_name: Name(p_referenced_decl(): BaseTypeDecl)) => strip(node.f_suffix[1].f_r_expr) | * => node @@ -35,7 +35,7 @@ fun check_actual(name, expected) = @check(message="actual parameter mismatch", category="Style", subcategory="Programming Practice") fun actual_parameters(node, forbidden=[]) = - node is AssocList(parent is call@CallExpr(p_is_call() is true)) + node is AssocList(parent: call@CallExpr(p_is_call(): true)) when { val n = call.f_name.p_referenced_decl()?. p_canonical_fully_qualified_name?(); @@ -45,9 +45,9 @@ fun actual_parameters(node, forbidden=[]) = [p for p in params if p.param.text.to_lower_case == item[2] and strip(p.actual) is name@Name( - p_referenced_decl() is ObjectDecl or NumberDecl or - ParamSpec or GenericFormalObjDecl or - BaseSubpBody or BasicSubpDecl) + p_referenced_decl(): ObjectDecl | NumberDecl | + ParamSpec | GenericFormalObjDecl | + BaseSubpBody | BasicSubpDecl) when check_actual(name.p_referenced_defining_name(), item[3])] ] } diff --git a/lkql_checker/share/lkql/ada05_formal_packages.lkql b/lkql_checker/share/lkql/ada05_formal_packages.lkql index 51d4b3329..aed382c66 100644 --- a/lkql_checker/share/lkql/ada05_formal_packages.lkql +++ b/lkql_checker/share/lkql/ada05_formal_packages.lkql @@ -6,7 +6,7 @@ @check(message="Ada 2005 formal package declaration", category="Style", subcategory="Programming Practice") fun ada05_formal_packages(node) = - node is GenericPackageInstantiation(parent is GenericFormalPackage) + node is GenericPackageInstantiation(parent: GenericFormalPackage) when { val num_box = [p for p in node.f_params.children if p.f_r_expr is BoxExpr].length; diff --git a/lkql_checker/share/lkql/ada_2022_in_ghost_code.lkql b/lkql_checker/share/lkql/ada_2022_in_ghost_code.lkql index d25ed553b..009bedaac 100644 --- a/lkql_checker/share/lkql/ada_2022_in_ghost_code.lkql +++ b/lkql_checker/share/lkql/ada_2022_in_ghost_code.lkql @@ -7,30 +7,30 @@ fun is_ada_2022(node) = # 'Image for all types | a@AttributeRef( - f_prefix is Name(p_expression_type() is b@BaseTypeDecl) + f_prefix: Name(p_expression_type(): b@BaseTypeDecl) ) when a.f_attribute.p_name_is("Image") and not b.p_is_scalar_type() => true # 'Reduce attribute, declare expression, @, delta aggregates - | ReduceAttributeRef or DeclExpr or TargetName or DeltaAggregate => true + | (ReduceAttributeRef | DeclExpr | TargetName | DeltaAggregate) => true # Iterators - | Aggregate(any children is IteratedAssoc) => true + | Aggregate(any children: IteratedAssoc) => true # Expr fns and null procs in protected bodies - | (ExprFunction or NullSubpDecl)(any parent is ProtectedBody) => true + | (ExprFunction | NullSubpDecl)(any parent: ProtectedBody) => true # User defined literals - | a@AspectAssoc(f_id is n@Name) + | a@AspectAssoc(f_id: n@Name) when n.p_name_is("String_Literal") or n.p_name_is("Integer_Literal") or n.p_name_is("Real_Literal") => true # Aspects on formal params - | AspectSpec(any parent is ParamSpec) => true + | AspectSpec(any parent: ParamSpec) => true # Pre/Post aspects on formal subprogram declarations - | a@AspectAssoc(f_id is n@Name, any parent is FormalSubpDecl) + | a@AspectAssoc(f_id: n@Name, any parent: FormalSubpDecl) when n.p_name_is("Pre") or n.p_name_is("Post") => true # In the general case, return false @@ -38,9 +38,9 @@ fun is_ada_2022(node) = fun is_in_ghost_code(node) = |" Return true iff node is in ghost code. - node is *(any parent is ( - BasicDecl or PragmaNode or AspectAssoc - )(p_is_ghost_code() is true)) + node is *(any parent: ( + BasicDecl | PragmaNode | AspectAssoc + )(p_is_ghost_code(): true)) @check(message="Ada 2022 construct forbidden outside of ghost code", category="Style", subcategory="Programming Practice", diff --git a/lkql_checker/share/lkql/address_attribute_for_non_volatile_objects.lkql b/lkql_checker/share/lkql/address_attribute_for_non_volatile_objects.lkql index b3ea214d9..4b2dc0ebc 100644 --- a/lkql_checker/share/lkql/address_attribute_for_non_volatile_objects.lkql +++ b/lkql_checker/share/lkql/address_attribute_for_non_volatile_objects.lkql @@ -8,7 +8,7 @@ import stdlib fun is_non_volatile_object(o) = - o is ObjectDecl(f_has_constant is ConstantAbsent) + o is ObjectDecl(f_has_constant: ConstantAbsent) and not (o?.p_has_aspect("Volatile") or o?.p_has_aspect("Atomic") or o?.p_has_aspect("Shared")) diff --git a/lkql_checker/share/lkql/address_specifications_for_initialized_objects.lkql b/lkql_checker/share/lkql/address_specifications_for_initialized_objects.lkql index bbb74fc89..c21ee21a6 100644 --- a/lkql_checker/share/lkql/address_specifications_for_initialized_objects.lkql +++ b/lkql_checker/share/lkql/address_specifications_for_initialized_objects.lkql @@ -5,22 +5,22 @@ category="Style", subcategory="Programming Practice") fun address_specifications_for_initialized_objects(node) = # for X'Address use ... - node is a@AttributeDefClause( - f_attribute_expr is AttributeRef( + node is (a@AttributeDefClause( + f_attribute_expr: AttributeRef( # Defined attribute is Address - f_attribute is Name(p_name_is("Address") is true), + f_attribute: Name(p_name_is("Address"): true), # X has a default value - f_prefix is Name(p_referenced_decl() is - ObjectDecl(f_default_expr is not null)))) + f_prefix: Name(p_referenced_decl(): + ObjectDecl(f_default_expr: not null)))) # X := ... with Address => ... - or AspectAssoc( + | AspectAssoc( # Associated aspect is Address - f_id is Name(p_name_is("Address") is true), + f_id: Name(p_name_is("Address"): true), # X has a default value - any parent is ObjectDecl(f_default_expr is not null)) + any parent: ObjectDecl(f_default_expr: not null)) # for X use at xxx'Address - or AtClause(f_expr is AttributeRef(f_attribute is - Name(p_name_is("Address") is true)), + | AtClause(f_expr: AttributeRef(f_attribute: + Name(p_name_is("Address"): true)), # X has a default value - f_name is Name(p_referenced_decl() is - ObjectDecl(f_default_expr is not null))) + f_name: Name(p_referenced_decl(): + ObjectDecl(f_default_expr: not null)))) diff --git a/lkql_checker/share/lkql/address_specifications_for_local_objects.lkql b/lkql_checker/share/lkql/address_specifications_for_local_objects.lkql index f28ff2a0d..275697560 100644 --- a/lkql_checker/share/lkql/address_specifications_for_local_objects.lkql +++ b/lkql_checker/share/lkql/address_specifications_for_local_objects.lkql @@ -5,6 +5,6 @@ @check(message="address specification for local object", category="Style", subcategory="Programming Practice") fun address_specifications_for_local_objects(node) = - node is ObjectDecl (any parent is s@SubpBody + node is ObjectDecl (any parent: s@SubpBody when not s.parent is LibraryItem) when node.p_has_aspect("Address") diff --git a/lkql_checker/share/lkql/anonymous_access.lkql b/lkql_checker/share/lkql/anonymous_access.lkql index e61dfc098..9b2bf8ef7 100644 --- a/lkql_checker/share/lkql/anonymous_access.lkql +++ b/lkql_checker/share/lkql/anonymous_access.lkql @@ -2,5 +2,5 @@ @check(message="anonymous access type", category="Feature") fun anonymous_access(node) = - node is AnonymousTypeDecl(any parent is ObjectDecl or ComponentDecl, - f_type_def is TypeAccessDef) + node is AnonymousTypeDecl(any parent: ObjectDecl | ComponentDecl, + f_type_def: TypeAccessDef) diff --git a/lkql_checker/share/lkql/anonymous_arrays.lkql b/lkql_checker/share/lkql/anonymous_arrays.lkql index 8ca7c2202..680855fb3 100644 --- a/lkql_checker/share/lkql/anonymous_arrays.lkql +++ b/lkql_checker/share/lkql/anonymous_arrays.lkql @@ -4,5 +4,5 @@ @check(message="anonymous array type", category="Style", subcategory="Programming Practice") fun anonymous_arrays(node) = - node is AnonymousTypeDecl(any parent is ObjectDecl, - f_type_def is ArrayTypeDef) + node is AnonymousTypeDecl(any parent: ObjectDecl, + f_type_def: ArrayTypeDef) diff --git a/lkql_checker/share/lkql/anonymous_subtypes.lkql b/lkql_checker/share/lkql/anonymous_subtypes.lkql index 359447db8..e36fb14a2 100644 --- a/lkql_checker/share/lkql/anonymous_subtypes.lkql +++ b/lkql_checker/share/lkql/anonymous_subtypes.lkql @@ -20,11 +20,11 @@ # Any part of the tree is a discriminant of the enclosing type decl fun is_using_discriminant(node, type_decl) = type_decl and - node is *(any children is id@Identifier + node is *(any children: id@Identifier when type_decl is TypeDecl( - any children(depth=3) is DiscriminantSpec( - f_ids is DefiningNameList( - any children is i@Identifier + any children(depth=3): DiscriminantSpec( + f_ids: DefiningNameList( + any children: i@Identifier when i.p_name_matches(id))))) fun get_type_decl(node) = @@ -33,31 +33,31 @@ fun get_type_decl(node) = # A self-reference has the form Type'Access fun is_self_referencing(expr, type_decl) = type_decl and - expr is *(any children is at@AttributeRef + expr is *(any children: at@AttributeRef when at.f_attribute.p_name_is("Access") and at.f_prefix.p_name_matches(type_decl.f_name?.f_name)) @check(message="anonymous subtype", category="Feature") fun anonymous_subtypes(node) = - node is (SubtypeIndication(f_constraint is constraint@Constraint) + node is ((SubtypeIndication(f_constraint: constraint@Constraint) when (not (constraint is - CompositeConstraint(p_is_discriminant_constraint() is true) + CompositeConstraint(p_is_discriminant_constraint(): true) and is_self_referencing(constraint, get_type_decl(node)))) and not (node.parent is SubtypeDecl and constraint is - RangeConstraint or + (RangeConstraint | (CompositeConstraint when constraint.p_is_discriminant_constraint() # If it's an index constraint, check that all # constraints are references to other types or not [c for c in constraint.f_constraints.children if c.f_constraint_expr is not Name( - p_referenced_decl() is BaseTypeDecl)]))) - or BinOp(f_op is OpDoubleDot, - parent is not RangeSpec(parent is TypeDef or ComponentClause), - all parent is not Constraint(parent is SubtypeIndication)) - or AttributeRef(f_attribute is Identifier(p_name_is("Range") is true), - parent is not RangeSpec(parent is - TypeDef or ComponentClause), - all parent is not Constraint(parent is SubtypeIndication)) + p_referenced_decl(): BaseTypeDecl)])))) + | BinOp(f_op: OpDoubleDot, + parent: not RangeSpec(parent: TypeDef | ComponentClause), + all parent: not Constraint(parent: SubtypeIndication)) + | AttributeRef(f_attribute: Identifier(p_name_is("Range"): true), + parent: not RangeSpec(parent: + TypeDef | ComponentClause), + all parent: not Constraint(parent: SubtypeIndication))) and not is_using_discriminant(node, get_type_decl(node)) diff --git a/lkql_checker/share/lkql/at_representation_clauses.lkql b/lkql_checker/share/lkql/at_representation_clauses.lkql index 04a1c76e0..d23fa7573 100644 --- a/lkql_checker/share/lkql/at_representation_clauses.lkql +++ b/lkql_checker/share/lkql/at_representation_clauses.lkql @@ -2,4 +2,4 @@ @check(message="AT representation clause", category="Feature") fun at_representation_clauses(node) = - node is AtClause or RecordRepClause(f_at_expr is not null) + node is (AtClause | RecordRepClause(f_at_expr: not null)) diff --git a/lkql_checker/share/lkql/binary_case_statements.lkql b/lkql_checker/share/lkql/binary_case_statements.lkql index 68c1a8837..c752b3e4f 100644 --- a/lkql_checker/share/lkql/binary_case_statements.lkql +++ b/lkql_checker/share/lkql/binary_case_statements.lkql @@ -8,8 +8,8 @@ category="Style", subcategory="Programming Practice") fun binary_case_statements(node, except_enums = false) = node is CaseStmt( - f_alternatives is CaseStmtAlternativeList( - all children(depth=1) is a@CaseStmtAlternative + f_alternatives: CaseStmtAlternativeList( + all children(depth=1): a@CaseStmtAlternative when a.f_choices.children_count == 1 ) when node.f_alternatives.children_count == 2 diff --git a/lkql_checker/share/lkql/bit_records_without_layout_definition.lkql b/lkql_checker/share/lkql/bit_records_without_layout_definition.lkql index 7bcc956b2..11b009cfa 100644 --- a/lkql_checker/share/lkql/bit_records_without_layout_definition.lkql +++ b/lkql_checker/share/lkql/bit_records_without_layout_definition.lkql @@ -10,8 +10,8 @@ fun lal_is_mod_type(n) = category="Style", subcategory="Portability") fun bit_records_without_layout_definition(node) = node is TypeDecl - when node.f_type_def is RecordTypeDef or DerivedTypeDef + when node.f_type_def is (RecordTypeDef | DerivedTypeDef) and node.p_has_aspect("Pack") and not node.p_get_record_representation_clause() - and node is *(any children is c@(ComponentDef or DiscriminantSpec) + and node is *(any children: c@(ComponentDef | DiscriminantSpec) when lal_is_mod_type(c)) diff --git a/lkql_checker/share/lkql/boolean_negations.lkql b/lkql_checker/share/lkql/boolean_negations.lkql index 0d8eb8f16..4b2e87f96 100644 --- a/lkql_checker/share/lkql/boolean_negations.lkql +++ b/lkql_checker/share/lkql/boolean_negations.lkql @@ -12,8 +12,8 @@ fun strip_parentheses(node) = @check(message="negation of boolean operator", category="Style", subcategory="Programming Practice") fun boolean_negations(node) = - node is UnOp(f_op is op@OpNot when stdlib.is_predefined_op(op)) + node is UnOp(f_op: op@OpNot when stdlib.is_predefined_op(op)) when stdlib.is_standard_boolean(node) and strip_parentheses(node.f_expr) is - expr_op@(RelationOp or UnOp(f_op is OpNot)) + expr_op@(RelationOp | UnOp(f_op: OpNot)) when stdlib.is_predefined_op(expr_op.f_op) diff --git a/lkql_checker/share/lkql/calls_in_exception_handlers.lkql b/lkql_checker/share/lkql/calls_in_exception_handlers.lkql index 81c06b4a5..a0a62166e 100644 --- a/lkql_checker/share/lkql/calls_in_exception_handlers.lkql +++ b/lkql_checker/share/lkql/calls_in_exception_handlers.lkql @@ -5,7 +5,7 @@ category="Style", subcategory="Programming Practice") fun calls_in_exception_handlers(node, subprograms=[]) = node is ExceptionHandler - when (from node.f_stmts select first id@BaseId(p_is_call() is true) + when (from node.f_stmts select first id@BaseId(p_is_call(): true) when { val name = id.p_referenced_defining_name()?. p_canonical_fully_qualified_name?(); diff --git a/lkql_checker/share/lkql/calls_outside_elaboration.lkql b/lkql_checker/share/lkql/calls_outside_elaboration.lkql index c28aac5e1..4d0243ef5 100644 --- a/lkql_checker/share/lkql/calls_outside_elaboration.lkql +++ b/lkql_checker/share/lkql/calls_outside_elaboration.lkql @@ -7,9 +7,9 @@ import stdlib @check(message="call performed outside elaboration", category="Style", subcategory="Programming Practice") fun calls_outside_elaboration(node, forbidden=[]) = - node is BaseId(p_is_call() is true, - any stdlib.semantic_parent is BasicSubpDecl or SubpBody or TaskBody or - ExprFunction or EntryBody or ProtectedBody) + node is BaseId(p_is_call(): true, + any stdlib.semantic_parent: BasicSubpDecl | SubpBody | TaskBody | + ExprFunction | EntryBody | ProtectedBody) when node.p_referenced_decl() is subp@BasicDecl when { val name = subp.p_canonical_fully_qualified_name(); diff --git a/lkql_checker/share/lkql/complex_inlined_subprograms.lkql b/lkql_checker/share/lkql/complex_inlined_subprograms.lkql index 89755d5b7..fb8424bde 100644 --- a/lkql_checker/share/lkql/complex_inlined_subprograms.lkql +++ b/lkql_checker/share/lkql/complex_inlined_subprograms.lkql @@ -15,15 +15,15 @@ import stdlib fun complex_declaration(decls) = |" Return the first complex declaration found in decls, null otherwise from decls - select first SubpBody or PackageDecl or TaskBody or ProtectedBody - or GenericPackageInstantiation - or (node@GenericSubpInstantiation - when not stdlib.is_unchecked_conversion(node)) + select first (SubpBody | PackageDecl | TaskBody | ProtectedBody + | GenericPackageInstantiation + | (node@GenericSubpInstantiation + when not stdlib.is_unchecked_conversion(node))) @memoized fun complex_statement(stmts) = |" Return the first complex statement found in stmts, null otherwise - from stmts select first BaseLoopStmt or CaseStmt or IfStmt + from stmts select first (BaseLoopStmt | CaseStmt | IfStmt) fun is_complex_subp(node, n) = |" Return true is node is a complex subprogram body as defined above @@ -48,6 +48,6 @@ fun complex_inlined_subprograms(unit, n : int = 5) = [ ), loc: if nod is SubpRenamingDecl then stdlib.get_subp_body(nod) else nod} for nod in from unit.root - select node@(SubpBody or GenericSubpInstantiation or SubpRenamingDecl) + select node@(SubpBody | GenericSubpInstantiation | SubpRenamingDecl) when node.p_has_aspect("Inline") and is_complex_subp(stdlib.get_subp_body(node), n)] diff --git a/lkql_checker/share/lkql/concurrent_interfaces.lkql b/lkql_checker/share/lkql/concurrent_interfaces.lkql index feae03e99..e083bc6aa 100644 --- a/lkql_checker/share/lkql/concurrent_interfaces.lkql +++ b/lkql_checker/share/lkql/concurrent_interfaces.lkql @@ -3,6 +3,6 @@ @check(message="concurrent interface", category="Style", subcategory="Programming Practice") fun concurrent_interfaces(node) = - node is InterfaceKindSynchronized or - InterfaceKindTask or - InterfaceKindProtected + node is (InterfaceKindSynchronized | + InterfaceKindTask | + InterfaceKindProtected) diff --git a/lkql_checker/share/lkql/constant_overlays.lkql b/lkql_checker/share/lkql/constant_overlays.lkql index 347f41b22..e3c7f6564 100644 --- a/lkql_checker/share/lkql/constant_overlays.lkql +++ b/lkql_checker/share/lkql/constant_overlays.lkql @@ -30,10 +30,10 @@ fun check_overlay(decl, overlaid) = @check(message="non-constant object overlays a constant", category="Style", subcategory="Programming Practice") fun constant_overlays(node) = match node - | AspectAssoc(f_id is id@Identifier, any parent(depth=3) is o@ObjectDecl + | AspectAssoc(f_id: id@Identifier, any parent(depth=3): o@ObjectDecl when id.p_name_is("address") and check_overlay (o, node.f_expr)) => true - | AttributeDefClause(f_attribute_expr is at@AttributeRef + | AttributeDefClause(f_attribute_expr: at@AttributeRef when at.f_attribute.p_name_is("address") and check_overlay(at.f_prefix.p_referenced_decl(), node.f_expr)) => true diff --git a/lkql_checker/share/lkql/constructors.lkql b/lkql_checker/share/lkql/constructors.lkql index c4cf33218..f974f695c 100644 --- a/lkql_checker/share/lkql/constructors.lkql +++ b/lkql_checker/share/lkql/constructors.lkql @@ -7,10 +7,10 @@ import stdlib @check(message="declaration of constructor function", category="Style", subcategory="Object Orientation") fun constructors(node) = - node is (BasicSubpDecl or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) + node is (BasicSubpDecl | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) # Get subprogram declarations that are primitive of a tagged type when node.p_subp_spec_or_null() is - spec@BaseSubpSpec(p_primitive_subp_tagged_type() is BaseTypeDecl) + spec@BaseSubpSpec(p_primitive_subp_tagged_type(): BaseTypeDecl) when stdlib.is_constructor(spec) diff --git a/lkql_checker/share/lkql/control_flow.lkql b/lkql_checker/share/lkql/control_flow.lkql index 98d87568a..46bb28e18 100644 --- a/lkql_checker/share/lkql/control_flow.lkql +++ b/lkql_checker/share/lkql/control_flow.lkql @@ -14,10 +14,10 @@ selector executed_children |" exist execution scenarios in which where they are not taken. | null => () | BodyNode => () - | IfStmt => rec this.f_cond_expr - | CaseStmt => rec this.f_expr - | BaseLoopStmt => rec this.f_spec - | * => rec *this.children + | IfStmt => rec(this.f_cond_expr) + | CaseStmt => rec(this.f_expr) + | BaseLoopStmt => rec(this.f_spec) + | * => rec(*this.children) fun all_branches(stmt) = |" Return a list of branches corresponding to alternative execution paths diff --git a/lkql_checker/share/lkql/controlled_type_declarations.lkql b/lkql_checker/share/lkql/controlled_type_declarations.lkql index 6a844e4bb..6c58b9d95 100644 --- a/lkql_checker/share/lkql/controlled_type_declarations.lkql +++ b/lkql_checker/share/lkql/controlled_type_declarations.lkql @@ -13,14 +13,14 @@ fun canonical_fully_qualified_name(t) = selector complete_super_types | b@BaseTypeDecl when b.p_is_private() => - rec *this.p_next_part()?.p_base_types?() + rec(*this.p_next_part()?.p_base_types?()) | BaseTypeDecl => - rec *this.p_base_types() + rec(*this.p_base_types()) | * => () @check(message="declaration of controlled type", category="Feature") fun controlled_type_declarations(node) = node is BaseTypeDecl ( - any complete_super_types is b @ * + any complete_super_types: b when canonical_fully_qualified_name(b) == "ada.finalization.controlled" ) diff --git a/lkql_checker/share/lkql/declarations_in_blocks.lkql b/lkql_checker/share/lkql/declarations_in_blocks.lkql index eb6e1614b..14f0f2eae 100644 --- a/lkql_checker/share/lkql/declarations_in_blocks.lkql +++ b/lkql_checker/share/lkql/declarations_in_blocks.lkql @@ -5,6 +5,6 @@ @check(message="block statement with local declaration", category="Feature") fun declarations_in_blocks(node) = node is DeclBlock - (any children(depth=1) is DeclarativePart - (f_decls is AdaNodeList(all children(depth=2) is not - (UseClause or PragmaNode)))) + (any children(depth=1): DeclarativePart + (f_decls: AdaNodeList(all children(depth=2): not + (UseClause | PragmaNode)))) diff --git a/lkql_checker/share/lkql/deep_inheritance_hierarchies.lkql b/lkql_checker/share/lkql/deep_inheritance_hierarchies.lkql index 5a8f90490..88311d0c7 100644 --- a/lkql_checker/share/lkql/deep_inheritance_hierarchies.lkql +++ b/lkql_checker/share/lkql/deep_inheritance_hierarchies.lkql @@ -16,9 +16,9 @@ fun deep_inheritance(type, n) = follow_generic_instantiations=true, category="Style", subcategory="Object Orientation") fun deep_inheritance_hierarchies(node, n: int = 2) = - node is TypeDecl(parent is not GenericFormalTypeDecl, - f_type_def is not - DerivedTypeDef(f_has_with_private is WithPrivatePresent), - p_is_tagged_type() is true, - p_next_part_for_decl() is null) + node is TypeDecl(parent: not GenericFormalTypeDecl, + f_type_def: not + DerivedTypeDef(f_has_with_private: WithPrivatePresent), + p_is_tagged_type(): true, + p_next_part_for_decl(): null) when deep_inheritance(node, n+1) diff --git a/lkql_checker/share/lkql/deep_library_hierarchy.lkql b/lkql_checker/share/lkql/deep_library_hierarchy.lkql index d5b8085a7..20aa6a15e 100644 --- a/lkql_checker/share/lkql/deep_library_hierarchy.lkql +++ b/lkql_checker/share/lkql/deep_library_hierarchy.lkql @@ -9,7 +9,7 @@ @check(message="unit has too many ancestors", category="Style", subcategory="Program Structure") fun deep_library_hierarchy(node, n: int = 3) = - node is BasePackageDecl(f_package_name is - DefiningName(any children(depth=n+2) is Name)) - or GenericPackageInstantiation(f_name is - DefiningName(any children(depth=n+2) is Name)) + node is (BasePackageDecl(f_package_name: + DefiningName(any children(depth=n+2): Name)) + | GenericPackageInstantiation(f_name: + DefiningName(any children(depth=n+2): Name))) diff --git a/lkql_checker/share/lkql/deeply_nested_inlining.lkql b/lkql_checker/share/lkql/deeply_nested_inlining.lkql index 3b0398764..a707f9b6d 100644 --- a/lkql_checker/share/lkql/deeply_nested_inlining.lkql +++ b/lkql_checker/share/lkql/deeply_nested_inlining.lkql @@ -12,9 +12,9 @@ fun inlined_body(name) = match name.p_referenced_decl() | b@BaseSubpBody when b?.p_has_aspect("Inline") => b | EnumLiteralDecl => null - | GenericSubpInstantiation(f_generic_subp_name is *( - p_referenced_decl() is b@GenericSubpDecl( - p_has_aspect("Inline") is true))) + | GenericSubpInstantiation(f_generic_subp_name: *( + p_referenced_decl(): b@GenericSubpDecl( + p_has_aspect("Inline"): true))) => b?.p_body_part() | d@BasicDecl when d?.p_is_subprogram() and d?.p_has_aspect("Inline") => d?.p_body_part() diff --git a/lkql_checker/share/lkql/deeply_nested_instantiations.lkql b/lkql_checker/share/lkql/deeply_nested_instantiations.lkql index f117d47bc..9becdae5a 100644 --- a/lkql_checker/share/lkql/deeply_nested_instantiations.lkql +++ b/lkql_checker/share/lkql/deeply_nested_instantiations.lkql @@ -8,11 +8,11 @@ fun check_instantiations(node, n : int) = match node | GenericPackageInstantiation => node.f_generic_pkg_name?.p_referenced_decl() is - *(any c@children is GenericInstantiation) + *(any c@children: GenericInstantiation) when [x for x in c if check_instantiations(x, n - 1)] | GenericSubpInstantiation => node.f_generic_subp_name?.p_referenced_decl() is - *(any c@children is GenericInstantiation) + *(any c@children: GenericInstantiation) when [x for x in c if check_instantiations(x, n - 1)] | * => false diff --git a/lkql_checker/share/lkql/default_parameters.lkql b/lkql_checker/share/lkql/default_parameters.lkql index 7b086917f..a2a2dc23c 100644 --- a/lkql_checker/share/lkql/default_parameters.lkql +++ b/lkql_checker/share/lkql/default_parameters.lkql @@ -8,5 +8,5 @@ @check(message="too many parameters with default value", category="Feature") fun default_parameters(node, n: int = 0, ignore = false) = node is Params - when (from (from node.f_params select ParamSpec(f_default_expr is Expr)) + when (from (from node.f_params select ParamSpec(f_default_expr: Expr)) select DefiningName).length > n diff --git a/lkql_checker/share/lkql/default_values_for_record_components.lkql b/lkql_checker/share/lkql/default_values_for_record_components.lkql index 96d95854e..8a936e5d5 100644 --- a/lkql_checker/share/lkql/default_values_for_record_components.lkql +++ b/lkql_checker/share/lkql/default_values_for_record_components.lkql @@ -8,4 +8,4 @@ fun default_values_for_record_components(node) = node is ComponentDecl when node.f_default_expr - and not node is *(any parent is ProtectedDef) + and not node is *(any parent: ProtectedDef) diff --git a/lkql_checker/share/lkql/deriving_from_predefined_type.lkql b/lkql_checker/share/lkql/deriving_from_predefined_type.lkql index 1281de047..f3b8b041c 100644 --- a/lkql_checker/share/lkql/deriving_from_predefined_type.lkql +++ b/lkql_checker/share/lkql/deriving_from_predefined_type.lkql @@ -8,6 +8,6 @@ import stdlib follow_generic_instantiations=true, category="Style", subcategory="Programming Practice") fun deriving_from_predefined_type(node) = - node is DerivedTypeDef(f_has_with_private is WithPrivateAbsent, - f_record_extension is null) + node is DerivedTypeDef(f_has_with_private: WithPrivateAbsent, + f_record_extension: null) when stdlib.is_predefined_type(node.f_subtype_indication.f_name) diff --git a/lkql_checker/share/lkql/direct_calls_to_primitives.lkql b/lkql_checker/share/lkql/direct_calls_to_primitives.lkql index 2830ac563..a96f538b0 100644 --- a/lkql_checker/share/lkql/direct_calls_to_primitives.lkql +++ b/lkql_checker/share/lkql/direct_calls_to_primitives.lkql @@ -24,10 +24,10 @@ fun is_parent_primitive(body, decl, parent_type) = @check(message="non-dispatching call to primitive operation", category="Style", subcategory="Object Orientation") fun direct_calls_to_primitives(node, except_constructors=false) = node is - BaseId(p_is_static_call() is true) + BaseId(p_is_static_call(): true) when stdlib.ultimate_subprogram_alias(node.p_referenced_decl()) is - decl@BasicDecl(p_subp_spec_or_null() is - spec@BaseSubpSpec(p_primitive_subp_tagged_type() is + decl@BasicDecl(p_subp_spec_or_null(): + spec@BaseSubpSpec(p_primitive_subp_tagged_type(): t@BaseTypeDecl)) when t.p_most_visible_part(node).p_is_tagged_type() and (not (except_constructors and stdlib.is_constructor(spec))) diff --git a/lkql_checker/share/lkql/direct_equalities.lkql b/lkql_checker/share/lkql/direct_equalities.lkql index e88a6ff2e..8f41e587f 100644 --- a/lkql_checker/share/lkql/direct_equalities.lkql +++ b/lkql_checker/share/lkql/direct_equalities.lkql @@ -9,15 +9,15 @@ import stdlib fun match_name(name, actuals) = name is Name( - p_referenced_defining_name() is DefiningName( - p_basic_decl() is ObjectDecl or NumberDecl or - ParamSpec or GenericFormalObjDecl, - p_canonical_fully_qualified_name() is str@*)) when + p_referenced_defining_name(): DefiningName( + p_basic_decl(): ObjectDecl | NumberDecl | + ParamSpec | GenericFormalObjDecl, + p_canonical_fully_qualified_name(): str)) when [s for s in actuals if str == s.to_lower_case] @check(message="direct (in)equality", category="Style", subcategory="Programming Practice") fun direct_equalities(node, actuals = []) = - node is BinOp(f_op is op@(OpEq or OpNeq)) + node is BinOp(f_op: op@(OpEq | OpNeq)) when stdlib.is_predefined_op(op) and match_name(node.f_left, actuals) or match_name(node.f_right, actuals) diff --git a/lkql_checker/share/lkql/discriminated_records.lkql b/lkql_checker/share/lkql/discriminated_records.lkql index a614bceb4..140bc6ccf 100644 --- a/lkql_checker/share/lkql/discriminated_records.lkql +++ b/lkql_checker/share/lkql/discriminated_records.lkql @@ -15,13 +15,13 @@ # U407-040 for list iterators # U407-032 for in list checks fun nodelist_contains_id(l, id) = - l is *(any children is BaseId(p_name_matches(id) is true)) + l is *(any children: BaseId(p_name_matches(id): true)) # Return true iff id identifies a discriminant of type_def fun id_is_a_discriminant(id, type_def) = type_def is DerivedTypeDef( - any children is assoc@CompositeConstraintAssoc( - f_constraint_expr is i@BaseId + any children: assoc@CompositeConstraintAssoc( + f_constraint_expr: i@BaseId when i?.p_name_matches(id) ) # f_ids contains the defining name (named assoc.) or is null (positional) @@ -32,9 +32,9 @@ fun id_is_a_discriminant(id, type_def) = # (eg to initialize a component, array size...). fun is_using_discriminant_in_declaration(type_decl) = type_decl.f_discriminants?.f_discr_specs is *( - all children(depth=1) is DiscriminantSpec( - f_ids is DefiningNameList( - all children(depth=2) is decl@BaseId + all children(depth=1): DiscriminantSpec( + f_ids: DefiningNameList( + all children(depth=2): decl@BaseId when id_is_a_discriminant(decl, type_decl?.f_type_def) ) ) @@ -43,7 +43,7 @@ fun is_using_discriminant_in_declaration(type_decl) = @check(message="declaration of discriminated record", category="Feature") fun discriminated_records(node) = node is TypeDecl( - any children(depth=2) is DiscriminantSpecList + any children(depth=2): DiscriminantSpecList when not ( node.f_type_def is PrivateTypeDef or is_using_discriminant_in_declaration(node) diff --git a/lkql_checker/share/lkql/downward_view_conversions.lkql b/lkql_checker/share/lkql/downward_view_conversions.lkql index acac205a5..88f381776 100644 --- a/lkql_checker/share/lkql/downward_view_conversions.lkql +++ b/lkql_checker/share/lkql/downward_view_conversions.lkql @@ -16,7 +16,7 @@ fun is_tagged(typ) = |" Whether typ is tagged or an access to a tagged type |" TODO: Maybe share in the stdlib? typ.p_is_tagged_type() - or typ.p_accessed_type() is BaseTypeDecl(p_is_tagged_type() is true) + or typ.p_accessed_type() is BaseTypeDecl(p_is_tagged_type(): true) @check(message="downward view conversion", category="Style", subcategory="Object Orientation") @@ -24,8 +24,8 @@ fun downward_view_conversions(node) = node is CallExpr( # Select type conversions - p_referenced_decl() is BaseTypeDecl( - p_base_subtype() is t@BaseTypeDecl when is_tagged (t) + p_referenced_decl(): BaseTypeDecl( + p_base_subtype(): t@BaseTypeDecl when is_tagged (t) ) ) diff --git a/lkql_checker/share/lkql/duplicate_branches.lkql b/lkql_checker/share/lkql/duplicate_branches.lkql index 58de2dcfb..c853c5574 100644 --- a/lkql_checker/share/lkql/duplicate_branches.lkql +++ b/lkql_checker/share/lkql/duplicate_branches.lkql @@ -46,6 +46,6 @@ fun message(node, min_size, min_stmt) = { fun duplicate_branches(unit, min_size: int = 14, min_stmt: int = 4) = [ message(n, min_size, min_stmt) for n in from unit.root - select node@(IfStmt or IfExpr or CaseStmt or CaseExpr) + select node@(IfStmt | IfExpr | CaseStmt | CaseExpr) when check_list(gather_stmts(node), min_size, min_stmt) ] diff --git a/lkql_checker/share/lkql/enumeration_ranges_in_case_statements.lkql b/lkql_checker/share/lkql/enumeration_ranges_in_case_statements.lkql index 55af83be1..d73ee987c 100644 --- a/lkql_checker/share/lkql/enumeration_ranges_in_case_statements.lkql +++ b/lkql_checker/share/lkql/enumeration_ranges_in_case_statements.lkql @@ -17,14 +17,14 @@ category="Style", subcategory="Programming Practice") fun enumeration_ranges_in_case_statements(node) = node is AlternativesList( - any parent(depth=3) is CaseStmt( + any parent(depth=3): CaseStmt( # case statement over enumeration - f_expr is e@Expr - when e.p_expression_type() is BaseTypeDecl(p_is_enum_type() is true)), - any children is + f_expr: e@Expr + when e.p_expression_type() is BaseTypeDecl(p_is_enum_type(): true)), + any children: # explicit range - BinOp(f_op is OpDoubleDot) or + BinOp(f_op: OpDoubleDot) | # subtype mark - Identifier(p_referenced_decl() is BaseTypeDecl) or + Identifier(p_referenced_decl(): BaseTypeDecl) | # range attribute - AttributeRef(f_attribute is Identifier(p_name_is("Range") is true))) + AttributeRef(f_attribute: Identifier(p_name_is("Range"): true))) diff --git a/lkql_checker/share/lkql/exception_propagation_from_callbacks.lkql b/lkql_checker/share/lkql/exception_propagation_from_callbacks.lkql index 0b9592054..f3d97df0d 100644 --- a/lkql_checker/share/lkql/exception_propagation_from_callbacks.lkql +++ b/lkql_checker/share/lkql/exception_propagation_from_callbacks.lkql @@ -17,7 +17,7 @@ fun get_uninstantiated_subp(subp) = |" Works around an inconsistency in LAL's API wrt. generic subprograms |" TODO: Fix when eng/libadalang/libadalang/-/issues/1127 is fixed match subp - | GenericSubpInstantiation(f_generic_subp_name is s@*) => + | GenericSubpInstantiation(f_generic_subp_name: s) => s.p_referenced_decl().p_get_uninstantiated_node() | AdaNode => subp.p_get_uninstantiated_node() | * => null @@ -29,12 +29,12 @@ fun get_uninstantiated_subp(subp) = fun exception_propagation_from_callbacks(node, callbacks=[]) = # Select 'Access or 'Address on subprograms in a subprogram call node is AttributeRef( - f_attribute is id@Identifier + f_attribute: id@Identifier when id.p_name_is("Address") or id.p_name_is("Access")) when node.f_prefix.p_referenced_decl() is - subp@(SubpBody or SubpDecl or SubpBodyStub or GenericSubpInstantiation) + subp@(SubpBody | SubpDecl | SubpBodyStub | GenericSubpInstantiation) when (from node through parent - select first CallExpr(p_is_call() is true)) is call@CallExpr + select first CallExpr(p_is_call(): true)) is call@CallExpr when { val uninst_subp_name = get_uninstantiated_subp( call.f_name.p_referenced_decl() diff --git a/lkql_checker/share/lkql/exceptions_as_control_flow.lkql b/lkql_checker/share/lkql/exceptions_as_control_flow.lkql index aa308b9aa..58ab26d1a 100644 --- a/lkql_checker/share/lkql/exceptions_as_control_flow.lkql +++ b/lkql_checker/share/lkql/exceptions_as_control_flow.lkql @@ -19,9 +19,9 @@ fun canonical_exception(name) = { category="Style", subcategory="Programming Practice") fun exceptions_as_control_flow(node) = # Select raise statements that are directly part of a subprogram body - node is r@RaiseStmt(f_exception_name is exc@Name) + node is r@RaiseStmt(f_exception_name: exc@Name) when stdlib.enclosing_body(r) is BaseSubpBody( - any children is exc_handler@ExceptionHandler when { + any children: exc_handler@ExceptionHandler when { val exc_block = exc_handler.parent; val stmt_block = exc_block?.parent; val canonical_exc = canonical_exception(exc); @@ -29,14 +29,14 @@ fun exceptions_as_control_flow(node) = # Where there is a handler that handles this same exception (either # via an others clause, or a direct name handling) exc_handler.f_handled_exceptions is *( - any children is OthersDesignator or - i@Identifier(p_referenced_decl() is ExceptionDecl) + any children: OthersDesignator | + i@Identifier(p_referenced_decl(): ExceptionDecl) when canonical_exception(i) == canonical_exc) # And the handler belongs to a block that encloses this raise statement - and r is *(any parent is p@* when p.parent == stmt_block) + and r is *(any parent: p when p.parent == stmt_block) # But the raise statement is not directly part of the handler - and not r is *(any parent is p@* when p.parent == exc_block) + and not r is *(any parent: p when p.parent == exc_block) } ) diff --git a/lkql_checker/share/lkql/exit_statements_with_no_loop_name.lkql b/lkql_checker/share/lkql/exit_statements_with_no_loop_name.lkql index 157970c9d..7eb61f5a6 100644 --- a/lkql_checker/share/lkql/exit_statements_with_no_loop_name.lkql +++ b/lkql_checker/share/lkql/exit_statements_with_no_loop_name.lkql @@ -20,6 +20,6 @@ fun is_in_nested_loop(n) = { category="Style", subcategory="Programming Practice") fun exit_statements_with_no_loop_name(node, nested_only=false) = if nested_only then - node is e@ExitStmt(f_loop_name is null) when is_in_nested_loop(e) + node is e@ExitStmt(f_loop_name: null) when is_in_nested_loop(e) else - node is ExitStmt(f_loop_name is null) + node is ExitStmt(f_loop_name: null) diff --git a/lkql_checker/share/lkql/exits_from_conditional_loops.lkql b/lkql_checker/share/lkql/exits_from_conditional_loops.lkql index 78b453273..df4ca15ee 100644 --- a/lkql_checker/share/lkql/exits_from_conditional_loops.lkql +++ b/lkql_checker/share/lkql/exits_from_conditional_loops.lkql @@ -8,4 +8,4 @@ fun exits_from_conditional_loops(node) = node is ExitStmt when [l for l in node.parents(include_self=false) - if l is BaseLoopStmt][1] is ForLoopStmt or WhileLoopStmt + if l is BaseLoopStmt][1] is (ForLoopStmt | WhileLoopStmt) diff --git a/lkql_checker/share/lkql/expanded_loop_exit_names.lkql b/lkql_checker/share/lkql/expanded_loop_exit_names.lkql index bce04f401..398582b6f 100644 --- a/lkql_checker/share/lkql/expanded_loop_exit_names.lkql +++ b/lkql_checker/share/lkql/expanded_loop_exit_names.lkql @@ -2,4 +2,4 @@ @check(message="expanded loop name in exit statement", category="SPARK") fun expanded_loop_exit_names(node) = - node is ExitStmt(f_loop_name is DottedName) + node is ExitStmt(f_loop_name: DottedName) diff --git a/lkql_checker/share/lkql/explicit_full_discrete_ranges.lkql b/lkql_checker/share/lkql/explicit_full_discrete_ranges.lkql index 0d493e1e0..48888230b 100644 --- a/lkql_checker/share/lkql/explicit_full_discrete_ranges.lkql +++ b/lkql_checker/share/lkql/explicit_full_discrete_ranges.lkql @@ -5,9 +5,9 @@ fun full_range(l, r) = and l.f_attribute.p_name_is("First") and r.f_attribute.p_name_is("Last") and l.f_prefix.p_referenced_decl() == r.f_prefix.p_referenced_decl() # Exclude function calls which may return different values - and l.f_prefix is not Name(p_is_call() is true) + and l.f_prefix is not Name(p_is_call(): true) @check(message="range could be replaced by subtype mark or 'Range", category="Feature") fun explicit_full_discrete_ranges(node) = - node is BinOp(f_op is OpDoubleDot) when full_range(node.f_left, node.f_right) + node is BinOp(f_op: OpDoubleDot) when full_range(node.f_left, node.f_right) diff --git a/lkql_checker/share/lkql/explicit_inlining.lkql b/lkql_checker/share/lkql/explicit_inlining.lkql index fe42ca84a..379fc815e 100644 --- a/lkql_checker/share/lkql/explicit_inlining.lkql +++ b/lkql_checker/share/lkql/explicit_inlining.lkql @@ -3,8 +3,8 @@ @check(message="subprogram marked inline", category="Feature") fun explicit_inlining(node) = - node is (SubpBody or GenericSubpInstantiation or ExprFunction or - SubpBodyStub or BasicSubpDecl) + node is (SubpBody | GenericSubpInstantiation | ExprFunction | + SubpBodyStub | BasicSubpDecl) when node.p_has_aspect("Inline") - and (node is (BasicSubpDecl or GenericSubpInstantiation) or + and (node is (BasicSubpDecl | GenericSubpInstantiation) or not node.p_previous_part()) diff --git a/lkql_checker/share/lkql/final_package.lkql b/lkql_checker/share/lkql/final_package.lkql index 6607e5b1e..85a1bcd41 100644 --- a/lkql_checker/share/lkql/final_package.lkql +++ b/lkql_checker/share/lkql/final_package.lkql @@ -10,7 +10,7 @@ fun is_final_pkg(pkg) = pkg is BasePackageDecl when { val aspect = pkg.p_get_aspect("Annotate"); aspect.exists and aspect.value is Aggregate( - f_assocs is a@* when a[1] is "GNATcheck" and a[2] is "Final" + f_assocs: a when a[1] is "GNATcheck" and a[2] is "Final" ) } @@ -36,5 +36,5 @@ fun final_package(node) = |" |" package Pkg.Child.Grandchild is -- NOT FLAGGED |" end Pkg.Child.Grandchild; - node is BasePackageDecl(parent is LibraryItem) + node is BasePackageDecl(parent: LibraryItem) when is_final_pkg(node.p_semantic_parent()) diff --git a/lkql_checker/share/lkql/fixed_equality_checks.lkql b/lkql_checker/share/lkql/fixed_equality_checks.lkql index d8d11a728..bc8783f15 100644 --- a/lkql_checker/share/lkql/fixed_equality_checks.lkql +++ b/lkql_checker/share/lkql/fixed_equality_checks.lkql @@ -8,13 +8,13 @@ import stdlib @check(message="use of equality operation for fixed values", category="Feature") fun fixed_equality_checks(node) = - node is (RelationOp(f_op is op@(OpEq or OpNeq)) + node is ((RelationOp(f_op: op@(OpEq | OpNeq)) when stdlib.is_predefined_op(op) and node.f_left.p_expression_type() is - BaseTypeDecl(p_is_fixed_point() is true)) - or CallExpr + BaseTypeDecl(p_is_fixed_point(): true)) + | CallExpr when (node.f_name.p_name_is("\"=\"") or node.f_name.p_name_is("\"/=\"")) and stdlib.is_predefined_op(node) and node.f_suffix[1].f_r_expr.p_expression_type() is - BaseTypeDecl(p_is_fixed_point() is true) + BaseTypeDecl(p_is_fixed_point(): true)) diff --git a/lkql_checker/share/lkql/float_equality_checks.lkql b/lkql_checker/share/lkql/float_equality_checks.lkql index ccc3c28d3..0961a39ff 100644 --- a/lkql_checker/share/lkql/float_equality_checks.lkql +++ b/lkql_checker/share/lkql/float_equality_checks.lkql @@ -13,12 +13,12 @@ fun is_float(n) = @check(message="use of equality operation for float values", category="Feature") fun float_equality_checks(node, follow_renamings=false) = - node is ( - RelationOp(f_op is op@(OpEq or OpNeq)) + node is (( + RelationOp(f_op: op@(OpEq | OpNeq)) when stdlib.is_predefined_op(op, follow_renamings) and is_float(node.f_left) ) - or CallExpr + | CallExpr when (node.f_name.p_name_is("\"=\"") or node.f_name.p_name_is("\"/=\"")) and stdlib.is_predefined_op(node, follow_renamings) - and is_float(node.f_suffix[1].f_r_expr) + and is_float(node.f_suffix[1].f_r_expr)) diff --git a/lkql_checker/share/lkql/forbidden_aspects.lkql b/lkql_checker/share/lkql/forbidden_aspects.lkql index e0fe0ade6..c9d2a8ac1 100644 --- a/lkql_checker/share/lkql/forbidden_aspects.lkql +++ b/lkql_checker/share/lkql/forbidden_aspects.lkql @@ -7,7 +7,7 @@ category="Style", subcategory="Portability") fun forbidden_aspects(unit, all=false, forbidden=[], allowed=[]) = [ {message: "use of aspect " & node.f_id.text, loc: node} - for node in from unit.root select AspectAssoc(f_id is id@Name) + for node in from unit.root select AspectAssoc(f_id: id@Name) # Note that p_name_is doesn't work on e.g. AttributeRef, so compare strings # directly instead. when { diff --git a/lkql_checker/share/lkql/forbidden_attributes.lkql b/lkql_checker/share/lkql/forbidden_attributes.lkql index d8ce0d56b..4916840b8 100644 --- a/lkql_checker/share/lkql/forbidden_attributes.lkql +++ b/lkql_checker/share/lkql/forbidden_attributes.lkql @@ -7,6 +7,6 @@ category="Style", subcategory="Portability") fun forbidden_attributes(unit, all=false, forbidden=[], allowed=[]) = [ {message: "use of attribute " & node.f_attribute.text, loc: node} - for node in from unit.root select AttributeRef(f_attribute is id@Identifier) + for node in from unit.root select AttributeRef(f_attribute: id@Identifier) when (all or [p for p in forbidden if id.p_name_is(p)]) and not [p for p in allowed if id.p_name_is(p)]] diff --git a/lkql_checker/share/lkql/forbidden_pragmas.lkql b/lkql_checker/share/lkql/forbidden_pragmas.lkql index 4b5321a85..22c1ae85a 100644 --- a/lkql_checker/share/lkql/forbidden_pragmas.lkql +++ b/lkql_checker/share/lkql/forbidden_pragmas.lkql @@ -7,6 +7,6 @@ category="Style", subcategory="Portability") fun forbidden_pragmas(unit, all=false, forbidden=[], allowed=[]) = [ {message: "use of pragma " & node.f_id.text, loc: node} - for node in from unit.root select PragmaNode(f_id is id@Identifier) + for node in from unit.root select PragmaNode(f_id: id@Identifier) when (all or [p for p in forbidden if id.p_name_is(p)]) and not [p for p in allowed if id.p_name_is(p)]] diff --git a/lkql_checker/share/lkql/function_style_procedures.lkql b/lkql_checker/share/lkql/function_style_procedures.lkql index 70f53ad7c..7daf3db9f 100644 --- a/lkql_checker/share/lkql/function_style_procedures.lkql +++ b/lkql_checker/share/lkql/function_style_procedures.lkql @@ -18,11 +18,11 @@ fun params_out(s) = @check(message="procedure can be rewritten as function", category="Feature") fun function_style_procedures(node) = - node is (SubpBody or SubpBodyStub or ClassicSubpDecl or GenericSubpInternal) - when (node is (ClassicSubpDecl or GenericSubpInternal) or + node is (SubpBody | SubpBodyStub | ClassicSubpDecl | GenericSubpInternal) + when (node is (ClassicSubpDecl | GenericSubpInternal) or not node.p_previous_part()) and node.f_subp_spec.f_subp_kind is SubpKindProcedure - and node.p_get_aspect_spec_expr("Global") is null or NullLiteral + and node.p_get_aspect_spec_expr("Global") is (null | NullLiteral) and not in_out_params(node.f_subp_spec) and ({ # Check for 1 out parameter of a non limited type @@ -30,9 +30,9 @@ fun function_style_procedures(node) = p_out.length == 1 and p_out[1].f_ids.children_count == 1 and p_out[1].f_type_expr.p_designated_type_decl() is not - TypeDecl(f_type_def is - (def@(DerivedTypeDef or PrivateTypeDef or + TypeDecl(f_type_def: + (def@(DerivedTypeDef | PrivateTypeDef | RecordTypeDef) when def.f_has_limited.p_as_bool()) - or InterfaceTypeDef(f_interface_kind is + | InterfaceTypeDef(f_interface_kind: InterfaceKindLimited))}) diff --git a/lkql_checker/share/lkql/generic_in_out_objects.lkql b/lkql_checker/share/lkql/generic_in_out_objects.lkql index abc4e7ffb..6e541560a 100644 --- a/lkql_checker/share/lkql/generic_in_out_objects.lkql +++ b/lkql_checker/share/lkql/generic_in_out_objects.lkql @@ -2,4 +2,4 @@ @check(message="generic IN OUT object", category="Feature") fun generic_in_out_objects(node) = - node is GenericFormalObjDecl(f_decl is ObjectDecl(f_mode is ModeInOut)) + node is GenericFormalObjDecl(f_decl: ObjectDecl(f_mode: ModeInOut)) diff --git a/lkql_checker/share/lkql/generics_in_subprograms.lkql b/lkql_checker/share/lkql/generics_in_subprograms.lkql index 3c0159dc9..def964eca 100644 --- a/lkql_checker/share/lkql/generics_in_subprograms.lkql +++ b/lkql_checker/share/lkql/generics_in_subprograms.lkql @@ -6,5 +6,5 @@ @check(message="generic definition in subprogram body", category="Feature") fun generics_in_subprograms(node) = - node is GenericDecl(any parent is BaseSubpBody, - all parent is not GenericPackageDecl) + node is GenericDecl(any parent: BaseSubpBody, + all parent: not GenericPackageDecl) diff --git a/lkql_checker/share/lkql/global_variables.lkql b/lkql_checker/share/lkql/global_variables.lkql index 61f2328e5..b503e042f 100644 --- a/lkql_checker/share/lkql/global_variables.lkql +++ b/lkql_checker/share/lkql/global_variables.lkql @@ -8,8 +8,8 @@ @check(message="declaration of global variable", category="Style", subcategory="Programming Practice") fun global_variables(node, only_public=false) = - node is ObjectDecl(p_is_constant_object() is false, - p_semantic_parent() is s@* when { + node is ObjectDecl(p_is_constant_object(): false, + p_semantic_parent(): s when { # Grab the enclosing package when the semantic parent is either val pkg = match s @@ -19,16 +19,16 @@ fun global_variables(node, only_public=false) = | p@PackageDecl when not ( # (if only public, filter private packages) only_public - and p.parent is LibraryItem(f_has_private is PrivatePresent) + and p.parent is LibraryItem(f_has_private: PrivatePresent) ) => p # 3. A generic package decl | p@GenericPackageInternal when not ( # (if only public, filter private packages) only_public - and p.parent.parent is LibraryItem(f_has_private is PrivatePresent) + and p.parent.parent is LibraryItem(f_has_private: PrivatePresent) ) => p | * => null; # Filter out variables declared in nested packages - pkg is BasePackageDecl(all parent is not BasePackageDecl) + pkg is BasePackageDecl(all parent: not BasePackageDecl) }) diff --git a/lkql_checker/share/lkql/goto_statements.lkql b/lkql_checker/share/lkql/goto_statements.lkql index 9563a0c1d..0bfd80ca0 100644 --- a/lkql_checker/share/lkql/goto_statements.lkql +++ b/lkql_checker/share/lkql/goto_statements.lkql @@ -6,4 +6,4 @@ fun goto_statements(node, only_unconditional=false) = node is GotoStmt # If unconditional option is true, only flag unconditional goto statements when not only_unconditional - or not node.parent.parent is IfStmt or CaseStmtAlternative + or not node.parent.parent is (IfStmt | CaseStmtAlternative) diff --git a/lkql_checker/share/lkql/identifier_casing.lkql b/lkql_checker/share/lkql/identifier_casing.lkql index 619cede8a..c0fb4799a 100644 --- a/lkql_checker/share/lkql/identifier_casing.lkql +++ b/lkql_checker/share/lkql/identifier_casing.lkql @@ -109,15 +109,15 @@ fun identifier_casing(unit, then str & scheme & ")" else "in the dictionary"; match n.parent - | (t@BaseTypeDecl when t is not SingleTaskTypeDecl or - p@TaskBody when p.p_previous_part() is not SingleTaskDecl) + | (t@BaseTypeDecl when t is (not SingleTaskTypeDecl | + p@TaskBody when p.p_previous_part() is not SingleTaskDecl)) when type != "" => msg("for subtype names (", type) | EnumLiteralDecl when enum != "" => msg("for enumeration literals (", enum) - | p@* => + | p => match p.parent - | (ObjectDecl(p_is_constant_object() is true) or + | (ObjectDecl(p_is_constant_object(): true) | NumberDecl) when constant != "" => msg("for constant names (", constant) @@ -131,14 +131,14 @@ fun identifier_casing(unit, }), loc: n} for n in from unit.root - select node@DefiningName(f_name is id@Identifier) + select node@DefiningName(f_name: id@Identifier) when match node.parent # Task objects - | SingleTaskDecl or SingleTaskTypeDecl + | (SingleTaskDecl | SingleTaskTypeDecl) => check_casing(id, others, exclude) # Types and subtypes, including TaskBody when the spec is a task type - | (BaseTypeDecl or + | (BaseTypeDecl | p@TaskBody when p.p_previous_part() is not SingleTaskDecl) when type != "" => check_casing(id, type, exclude) @@ -146,10 +146,10 @@ fun identifier_casing(unit, | EnumLiteralDecl when enum != "" => check_casing(id, enum, exclude) # Look one level up for remaining cases - | p@* => match p.parent + | p => match p.parent # Constants - | (ObjectDecl(p_is_constant_object() is true) or + | (ObjectDecl(p_is_constant_object(): true) | NumberDecl) when constant != "" => check_casing(id, constant, exclude) diff --git a/lkql_checker/share/lkql/identifier_prefixes.lkql b/lkql_checker/share/lkql/identifier_prefixes.lkql index bc3c6c558..ef92d3e53 100644 --- a/lkql_checker/share/lkql/identifier_prefixes.lkql +++ b/lkql_checker/share/lkql/identifier_prefixes.lkql @@ -120,26 +120,26 @@ fun identifier_prefixes(unit, [{message: n.text & (match n.parent - | p@(TaskTypeDecl or ProtectedTypeDecl or - SubtypeDecl(p_canonical_type() is TaskTypeDecl or ProtectedTypeDecl)) + | p@(TaskTypeDecl | ProtectedTypeDecl | + SubtypeDecl(p_canonical_type(): TaskTypeDecl | ProtectedTypeDecl)) when p is not SingleTaskTypeDecl and concurrent != "-" => str_prefix & "concurrent prefix " & concurrent - | (TypeDecl(f_type_def is TypeAccessDef(f_subtype_indication is *(f_name is - AttributeRef(f_attribute is Identifier(p_name_is("Class") is true))))) or - SubtypeDecl(p_canonical_type() is TypeDecl(f_type_def is - TypeAccessDef(f_subtype_indication is *(f_name is - AttributeRef(f_attribute is Identifier(p_name_is("Class") is true))))))) + | (TypeDecl(f_type_def: TypeAccessDef(f_subtype_indication: *(f_name: + AttributeRef(f_attribute: Identifier(p_name_is("Class"): true))))) | + SubtypeDecl(p_canonical_type(): TypeDecl(f_type_def: + TypeAccessDef(f_subtype_indication: *(f_name: + AttributeRef(f_attribute: Identifier(p_name_is("Class"): true))))))) when class_access != "-" => str_prefix & "access-to-class prefix " & class_access - | (TypeDecl(f_type_def is AccessToSubpDef) or - SubtypeDecl(p_canonical_type() is - TypeDecl(f_type_def is AccessToSubpDef))) + | (TypeDecl(f_type_def: AccessToSubpDef) | + SubtypeDecl(p_canonical_type(): + TypeDecl(f_type_def: AccessToSubpDef))) when subprogram_access != "-" => str_prefix & "access-to-subprogram prefix " & subprogram_access - | (TypeDecl(f_type_def is AccessDef) or - SubtypeDecl(p_canonical_type() is TypeDecl(f_type_def is AccessDef))) + | (TypeDecl(f_type_def: AccessDef) | + SubtypeDecl(p_canonical_type(): TypeDecl(f_type_def: AccessDef))) when access != "-" => str_prefix & "access prefix " & access - | p@(TypeDecl(f_type_def is DerivedTypeDef) or SubtypeDecl) + | p@(TypeDecl(f_type_def: DerivedTypeDef) | SubtypeDecl) when derived != [] and p.p_canonical_type().p_base_type() is t@BaseTypeDecl when get_derived(t, derived) != "" @@ -151,8 +151,8 @@ fun identifier_prefixes(unit, | BaseTypeDecl => str_prefix & "subtype prefix " & type | EnumLiteralDecl => str_prefix & "enumeration prefix " & enum - | p@* => match p.parent - | ObjectDecl or NumberDecl => + | p => match p.parent + | (ObjectDecl | NumberDecl) => str_prefix & "constant prefix " & constant | SubpRenamingDecl => str_prefix & "enumeration prefix " & enum | ExceptionDecl => str_prefix & "exception prefix " & exception @@ -160,48 +160,48 @@ fun identifier_prefixes(unit, loc: n} for n in from unit.root select node@DefiningName when match node.parent # Concurrent types - | p@(TaskTypeDecl or ProtectedTypeDecl or TaskBody or ProtectedBody or - SubtypeDecl(p_canonical_type() is TaskTypeDecl or ProtectedTypeDecl)) + | p@(TaskTypeDecl | ProtectedTypeDecl | TaskBody | ProtectedBody | + SubtypeDecl(p_canonical_type(): TaskTypeDecl | ProtectedTypeDecl)) when p is not SingleTaskTypeDecl and concurrent != "-" => - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and ((not node.f_name.text.starts_with(concurrent)) or check_exclusive(node.f_name.text, exclusive=exclusive, concurrent_exclusive=false)) # 'Class access - | (p@TypeDecl(f_type_def is TypeAccessDef(f_subtype_indication is *(f_name is - AttributeRef(f_attribute is Identifier(p_name_is("Class") is true))))) or - p@SubtypeDecl(p_canonical_type() is TypeDecl(f_type_def is - TypeAccessDef(f_subtype_indication is *(f_name is - AttributeRef(f_attribute is Identifier(p_name_is("Class") is true))))))) + | (p@TypeDecl(f_type_def: TypeAccessDef(f_subtype_indication: *(f_name: + AttributeRef(f_attribute: Identifier(p_name_is("Class"): true))))) | + p@SubtypeDecl(p_canonical_type(): TypeDecl(f_type_def: + TypeAccessDef(f_subtype_indication: *(f_name: + AttributeRef(f_attribute: Identifier(p_name_is("Class"): true))))))) when class_access != "-" => - p?.p_previous_part() is (null or IncompleteTypeDecl) and + p?.p_previous_part() is (null | IncompleteTypeDecl) and ((not node.f_name.text.starts_with(class_access)) or check_exclusive(node.f_name.text, exclusive=exclusive, class_access_exclusive=false)) # Subprogram access - | (p@TypeDecl(f_type_def is AccessToSubpDef) or - p@SubtypeDecl(p_canonical_type() is - TypeDecl(f_type_def is AccessToSubpDef))) + | (p@TypeDecl(f_type_def: AccessToSubpDef) | + p@SubtypeDecl(p_canonical_type(): + TypeDecl(f_type_def: AccessToSubpDef))) when subprogram_access != "-" => - p?.p_previous_part() is (null or IncompleteTypeDecl) and + p?.p_previous_part() is (null | IncompleteTypeDecl) and ((not node.f_name.text.starts_with(subprogram_access)) or check_exclusive(node.f_name.text, exclusive=exclusive, subprogram_access_exclusive=false)) # Other access types - | (p@TypeDecl(f_type_def is AccessDef) or - p@SubtypeDecl(p_canonical_type() is TypeDecl(f_type_def is AccessDef))) + | (p@TypeDecl(f_type_def: AccessDef) | + p@SubtypeDecl(p_canonical_type(): TypeDecl(f_type_def: AccessDef))) when access != "-" => - p?.p_previous_part() is (null or IncompleteTypeDecl) and + p?.p_previous_part() is (null | IncompleteTypeDecl) and ((not node.f_name.text.starts_with(access)) or check_exclusive(node.f_name.text, exclusive=exclusive, @@ -213,13 +213,13 @@ fun identifier_prefixes(unit, type_exclusive=false)) # (Sub)Types derived from `derived` - | p@(TypeDecl(f_type_def is DerivedTypeDef) or SubtypeDecl) + | p@(TypeDecl(f_type_def: DerivedTypeDef) | SubtypeDecl) when derived != [] and p.p_canonical_type().p_base_type() is t@BaseTypeDecl when get_derived(t, derived) != "" => { val t = p.p_canonical_type().p_base_type(); - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and not node.f_name.text.starts_with(get_derived(t, derived) .split(":")[2]) } @@ -229,7 +229,7 @@ fun identifier_prefixes(unit, # Other types and subtypes | p@BaseTypeDecl when p is not SingleTaskTypeDecl => - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and ((type != "-" and not node.f_name.text.starts_with(type)) or check_exclusive(node.f_name.text, exclusive=exclusive, @@ -239,10 +239,10 @@ fun identifier_prefixes(unit, | EnumLiteralDecl => check_enum(node.f_name.text) # Look one level up for remaining cases - | p@* => match p.parent + | p => match p.parent # Constants - | (ObjectDecl(p_is_constant_object() is true) when not node.p_previous_part()) - or NumberDecl + | ((ObjectDecl(p_is_constant_object(): true) when not node.p_previous_part()) + | NumberDecl) => (constant != "-" and not node.f_name.text.starts_with(constant)) or check_exclusive(node.f_name.text, @@ -264,8 +264,8 @@ fun identifier_prefixes(unit, # Check all other defining names for exclusion except for completions # and renaming-as-body - | p2@* => - (not p2 is (BodyNode or SubpRenamingDecl) or not p2.p_previous_part()) and + | p2 => + (not p2 is (BodyNode | SubpRenamingDecl) or not p2.p_previous_part()) and (not p2 is ObjectDecl or not node.p_previous_part()) and check_exclusive(node.f_name.text, exclusive=exclusive)] } diff --git a/lkql_checker/share/lkql/identifier_suffixes.lkql b/lkql_checker/share/lkql/identifier_suffixes.lkql index 68784f76c..2750b3c5c 100644 --- a/lkql_checker/share/lkql/identifier_suffixes.lkql +++ b/lkql_checker/share/lkql/identifier_suffixes.lkql @@ -80,26 +80,26 @@ fun identifier_suffixes(unit, match n.parent | SubpSpec when interrupt_suffix != "" => "interrupt suffix " & interrupt_suffix - | TypeDecl(p_is_access_type() is true, - p_accessed_type() is - ClasswideTypeDecl or - SubtypeDecl(p_canonical_type() is + | TypeDecl(p_is_access_type(): true, + p_accessed_type(): + ClasswideTypeDecl | + SubtypeDecl(p_canonical_type(): ClasswideTypeDecl)) when class_access_suffix != "" => "access-to-class suffix " & class_access_suffix - | BaseSubtypeDecl(p_base_subtype() is ClasswideTypeDecl) + | BaseSubtypeDecl(p_base_subtype(): ClasswideTypeDecl) when class_subtype_suffix != "" => "class-wide suffix " & class_subtype_suffix - | p@TypeDecl(p_is_access_type() is true) + | p@TypeDecl(p_is_access_type(): true) when access_suffix != "" => if access_access_suffix != "" and p.p_accessed_type() is - BaseTypeDecl(p_is_access_type() is true) + BaseTypeDecl(p_is_access_type(): true) then "access-to-access suffix " & access_suffix & access_access_suffix else "access suffix " & access_suffix | TypeDecl => "type suffix " & type_suffix | PackageRenamingDecl => "renaming suffix " & renaming_suffix - | p@* => if p.parent is not ObjectDecl or + | p => if p.parent is not ObjectDecl or constant_suffix == "" or p.parent.f_type_expr.p_designated_type_decl(). p_is_access_type() @@ -109,32 +109,32 @@ fun identifier_suffixes(unit, for n in from unit.root select node@DefiningName when match node.parent # Interrupt handlers | s@SubpSpec when interrupt_suffix != "" => - s is SubpSpec(any parent(depth=4) is ProtectedDef, parent is d@SubpDecl) + s is SubpSpec(any parent(depth=4): ProtectedDef, parent: d@SubpDecl) when (d.p_has_aspect("Interrupt_Handler") or d.p_has_aspect("Attach_Handler")) and not node.f_name.text.ends_with(interrupt_suffix) # 'Class access - | p@TypeDecl(p_is_access_type() is true, - p_accessed_type() is - ClasswideTypeDecl or - SubtypeDecl(p_canonical_type() is ClasswideTypeDecl)) + | p@TypeDecl(p_is_access_type(): true, + p_accessed_type(): + ClasswideTypeDecl | + SubtypeDecl(p_canonical_type(): ClasswideTypeDecl)) when class_access_suffix != "" => - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and not node.f_name.text.ends_with(class_access_suffix) # 'Class subtype - | p@BaseSubtypeDecl(p_base_subtype() is ClasswideTypeDecl) + | p@BaseSubtypeDecl(p_base_subtype(): ClasswideTypeDecl) when class_subtype_suffix != "" => - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and not node.f_name.text.ends_with(class_subtype_suffix) # Other access types - | p@TypeDecl(p_is_access_type() is true) when access_suffix != "" + | p@TypeDecl(p_is_access_type(): true) when access_suffix != "" => - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and not node.f_name.text.ends_with( if access_access_suffix != "" and p.p_accessed_type() is t@BaseTypeDecl @@ -149,7 +149,7 @@ fun identifier_suffixes(unit, # Other types | p@TypeDecl => type_suffix != "" and - p.p_previous_part() is (null or IncompleteTypeDecl) and + p.p_previous_part() is (null | IncompleteTypeDecl) and not node.f_name.text.ends_with(type_suffix) | p@PackageRenamingDecl => @@ -157,26 +157,26 @@ fun identifier_suffixes(unit, not node.f_name.text.ends_with(renaming_suffix) # Look one level up for remaining cases - | p@* => node.p_previous_part() == null and match p.parent + | p => node.p_previous_part() == null and match p.parent # Access data objects - | (ObjectDecl(f_type_expr is TypeExpr(p_designated_type_decl() is - BaseTypeDecl(p_is_access_type() is true))) or - ComponentDecl(f_component_def is - ComponentDef(f_type_expr is - TypeExpr(p_designated_type_decl() is - BaseTypeDecl(p_is_access_type() is true)))) or - ParamSpec(f_type_expr is - TypeExpr(p_designated_type_decl() is - BaseTypeDecl(p_is_access_type() is true))) or - DiscriminantSpec(f_type_expr is - TypeExpr(p_designated_type_decl() is - BaseTypeDecl(p_is_access_type() is true)))) + | (ObjectDecl(f_type_expr: TypeExpr(p_designated_type_decl(): + BaseTypeDecl(p_is_access_type(): true))) | + ComponentDecl(f_component_def: + ComponentDef(f_type_expr: + TypeExpr(p_designated_type_decl(): + BaseTypeDecl(p_is_access_type(): true)))) | + ParamSpec(f_type_expr: + TypeExpr(p_designated_type_decl(): + BaseTypeDecl(p_is_access_type(): true))) | + DiscriminantSpec(f_type_expr: + TypeExpr(p_designated_type_decl(): + BaseTypeDecl(p_is_access_type(): true)))) when access_obj_suffix != "" => not node.f_name.text.ends_with(access_obj_suffix) # Constants - | ObjectDecl(p_is_constant_object() is true) + | ObjectDecl(p_is_constant_object(): true) when constant_suffix != "" => not node.f_name.text.ends_with(constant_suffix) diff --git a/lkql_checker/share/lkql/implicit_in_mode_parameters.lkql b/lkql_checker/share/lkql/implicit_in_mode_parameters.lkql index c296fb37a..99f3eea39 100644 --- a/lkql_checker/share/lkql/implicit_in_mode_parameters.lkql +++ b/lkql_checker/share/lkql/implicit_in_mode_parameters.lkql @@ -5,6 +5,6 @@ @check(message="implicit IN mode in parameter specification", remediation="TRIVIAL", category="Feature") fun implicit_in_mode_parameters(node) = - node is ParamSpec(f_mode is ModeDefault) + node is ParamSpec(f_mode: ModeDefault) when not node.f_type_expr is - AnonymousType(f_type_decl is *(f_type_def is AccessDef)) + AnonymousType(f_type_decl: *(f_type_def: AccessDef)) diff --git a/lkql_checker/share/lkql/implicit_small_for_fixed_point_types.lkql b/lkql_checker/share/lkql/implicit_small_for_fixed_point_types.lkql index 75bc4e3d8..0f638504e 100644 --- a/lkql_checker/share/lkql/implicit_small_for_fixed_point_types.lkql +++ b/lkql_checker/share/lkql/implicit_small_for_fixed_point_types.lkql @@ -6,5 +6,5 @@ @check(message="fixed point type declaration with no 'Small clause", category="Style", subcategory="Portability") fun implicit_small_for_fixed_point_types(node) = - node is TypeDecl(any children is OrdinaryFixedPointDef, - p_has_aspect("Small") is false) + node is TypeDecl(any children: OrdinaryFixedPointDef, + p_has_aspect("Small"): false) diff --git a/lkql_checker/share/lkql/improperly_located_instantiations.lkql b/lkql_checker/share/lkql/improperly_located_instantiations.lkql index e3e08fab1..4b45ee331 100644 --- a/lkql_checker/share/lkql/improperly_located_instantiations.lkql +++ b/lkql_checker/share/lkql/improperly_located_instantiations.lkql @@ -8,14 +8,14 @@ import stdlib @unit_check(help="instantiations not properly located", category="Feature") fun improperly_located_instantiations(unit) = [ {message: "instantiation in a " & - (if node is GenericInstantiation(any parent is BaseSubpBody) + (if node is GenericInstantiation(any parent: BaseSubpBody) then "subprogram body" else (if unit.root.f_body.f_item is GenericPackageDecl then "generic " else "") & "library package spec"), loc: node.p_defining_name()} for node in if unit.root is CompilationUnit then (match unit.root.f_body - | LibraryItem(f_item is GenericPackageDecl or BasePackageDecl) + | LibraryItem(f_item: GenericPackageDecl | BasePackageDecl) => from unit.root select GenericInstantiation | * => from (from unit.root select BaseSubpBody) select GenericInstantiation) diff --git a/lkql_checker/share/lkql/integer_types_as_enum.lkql b/lkql_checker/share/lkql/integer_types_as_enum.lkql index a8a43f815..e0c99daee 100644 --- a/lkql_checker/share/lkql/integer_types_as_enum.lkql +++ b/lkql_checker/share/lkql/integer_types_as_enum.lkql @@ -11,10 +11,10 @@ fun arithmetic_ops() = |" Return a list of all types referenced in any arithmetic operator unique([op.p_expression_type() for op in select - BinOp(f_op is OpDiv or OpMinus or OpMod or OpMult or - OpPlus or OpPow or OpRem or OpXor or - OpAnd or OpOr) or - UnOp(f_op is OpAbs or OpMinus or OpPlus or OpNot)].to_list) + (BinOp(f_op: OpDiv | OpMinus | OpMod | OpMult | + OpPlus | OpPow | OpRem | OpXor | + OpAnd | OpOr) | + UnOp(f_op: OpAbs | OpMinus | OpPlus | OpNot))].to_list) @memoized fun instantiations() = @@ -30,18 +30,18 @@ fun types() = |" and target), subtype declarations and type derivations in the project. unique(concat([[c.p_referenced_decl(), c.f_suffix[1].f_r_expr.p_expression_type()] - for c in select CallExpr(p_referenced_decl() is TypeDecl)]. + for c in select CallExpr(p_referenced_decl(): TypeDecl)]. to_list) & [s.f_subtype.f_name.p_referenced_decl() for s in select SubtypeDecl].to_list & [c.f_type_def.f_subtype_indication?.f_name?.p_referenced_decl() - for c in select TypeDecl(f_type_def is DerivedTypeDef)].to_list) + for c in select TypeDecl(f_type_def: DerivedTypeDef)].to_list) @check(help="integer type may be replaced by an enumeration (global analysis required)", message="integer type may be replaced by an enumeration", category="Style", subcategory="Programming Practice") fun integer_types_as_enum(node) = - node is TypeDecl(p_is_int_type() is true) + node is TypeDecl(p_is_int_type(): true) when not [t for t in types() if t == node] and not [t for t in instantiations() if t == node] and not [t for t in arithmetic_ops() if t == node] diff --git a/lkql_checker/share/lkql/kp/KP-18614.lkql b/lkql_checker/share/lkql/kp/KP-18614.lkql index 5ad9d0fcf..174fa9669 100644 --- a/lkql_checker/share/lkql/kp/KP-18614.lkql +++ b/lkql_checker/share/lkql/kp/KP-18614.lkql @@ -6,8 +6,8 @@ fun multiple_of(v, multiple) = v / multiple * multiple == v message="possible occurrence of KP 18614 if compiled with optimization", impact="2[0-3].*", target="powerpc*,leon*,sparc*") fun kp_18614(node) = - node is Aggregate(p_expression_type() is - t@BaseTypeDecl(p_is_array_type() is true) + node is Aggregate(p_expression_type(): + t@BaseTypeDecl(p_is_array_type(): true) when { val aspect = t.p_get_aspect("Size"); aspect.exists and diff --git a/lkql_checker/share/lkql/kp/KP-18636.lkql b/lkql_checker/share/lkql/kp/KP-18636.lkql index 3c1a0f99c..7464fa8ff 100644 --- a/lkql_checker/share/lkql/kp/KP-18636.lkql +++ b/lkql_checker/share/lkql/kp/KP-18636.lkql @@ -5,6 +5,6 @@ fun kp_18636(node) = node is AttributeRef when node.f_attribute.p_name_is("Image") and node.f_prefix is Name( - p_referenced_decl() is ObjectDecl or ParamSpec or GenericFormalObjDecl, - p_expression_type() is ClasswideTypeDecl( - p_is_interface_type() is true)) + p_referenced_decl(): ObjectDecl | ParamSpec | GenericFormalObjDecl, + p_expression_type(): ClasswideTypeDecl( + p_is_interface_type(): true)) diff --git a/lkql_checker/share/lkql/kp/KP-18637.lkql b/lkql_checker/share/lkql/kp/KP-18637.lkql index 6ad744a5a..7596b9f3c 100644 --- a/lkql_checker/share/lkql/kp/KP-18637.lkql +++ b/lkql_checker/share/lkql/kp/KP-18637.lkql @@ -1,16 +1,18 @@ # Flag type conversions from expressions of a class-wide interface type # to some ancestor (possibly class-wide) type. +import stdlib + @check(message="possible occurrence of KP 18637", impact="23.*") fun kp_18637(node) = node is CallExpr( - f_name is Name( - p_referenced_decl() is t@BaseTypeDecl(p_is_interface_type() is true))) + f_name: Name( + p_referenced_decl(): t@BaseTypeDecl(p_is_interface_type(): true))) when { val type = if t is ClasswideTypeDecl then t.p_specific_type() else t; node.f_suffix[1].f_r_expr is Expr( - p_expression_type() is ClasswideTypeDecl( - p_is_interface_type() is true, - p_specific_type() is BaseTypeDecl( - any super_types is p@BaseTypeDecl when p == type))) + p_expression_type(): ClasswideTypeDecl( + p_is_interface_type(): true, + p_specific_type(): BaseTypeDecl( + any stdlib.super_types: p@BaseTypeDecl when p == type))) } diff --git a/lkql_checker/share/lkql/kp/KP-18701.lkql b/lkql_checker/share/lkql/kp/KP-18701.lkql index 0c3543e4e..e493b19a6 100644 --- a/lkql_checker/share/lkql/kp/KP-18701.lkql +++ b/lkql_checker/share/lkql/kp/KP-18701.lkql @@ -7,7 +7,7 @@ import stdlib fun kp_18701(node) = node is Aggregate when node.p_expression_type() is BaseTypeDecl( - p_canonical_type() is type@ConcreteTypeDecl + p_canonical_type(): type@ConcreteTypeDecl # Type has discriminants when type.f_discriminants is KnownDiscriminantPart # with default values diff --git a/lkql_checker/share/lkql/kp/KP-18718.lkql b/lkql_checker/share/lkql/kp/KP-18718.lkql index 7f6349c6d..e9a591e77 100644 --- a/lkql_checker/share/lkql/kp/KP-18718.lkql +++ b/lkql_checker/share/lkql/kp/KP-18718.lkql @@ -9,7 +9,7 @@ fun kp_18718(node) = node is ObjectDecl( # An ObjectDecl with a default expression being a function call - f_default_expr is c@Name(p_is_call() is true) + f_default_expr: c@Name(p_is_call(): true) when { # Retrieve the function body for the call val b = match c.p_referenced_decl() @@ -18,10 +18,10 @@ fun kp_18718(node) = | * => null; # An expression function or a function with a single return - (b is ExprFunction or + (b is (ExprFunction | SubpBody when b.f_stmts.f_stmts.children_count == 1 - and b.f_stmts.f_stmts[1] is ReturnStmt or - ExtendedReturnStmt) and + and b.f_stmts.f_stmts[1] is (ReturnStmt | + ExtendedReturnStmt))) and # Retrieve the return type b.f_subp_spec.p_return_type() is t@BaseTypeDecl when t.p_canonical_type().p_full_view() is type@TypeDecl diff --git a/lkql_checker/share/lkql/kp/KP-18801.lkql b/lkql_checker/share/lkql/kp/KP-18801.lkql index c2ac4b970..f963cd071 100644 --- a/lkql_checker/share/lkql/kp/KP-18801.lkql +++ b/lkql_checker/share/lkql/kp/KP-18801.lkql @@ -8,26 +8,26 @@ fun is_overloaded(n) = { val d = if n is BodyNode then n.p_decl_part() else n; val decl = if d == null then n else d; - decl is (ClassicSubpDecl or BaseSubpBody) and + decl is (ClassicSubpDecl | BaseSubpBody) and decl.f_subp_spec.f_subp_name is name@DefiningName - when (decl is *(any prev_siblings is sib@SubpDecl + when (decl is *(any prev_siblings: sib@SubpDecl when sib.f_subp_spec.f_subp_name.p_name_matches(name)) or - decl is *(any next_siblings is sib@SubpDecl + decl is *(any next_siblings: sib@SubpDecl when sib.f_subp_spec.f_subp_name.p_name_matches(name))) } fun is_wrong_call(n, pkg) = # n is a function call - n is Name(p_is_call() is true, + n is Name(p_is_call(): true, # declared in pkg - any stdlib.semantic_parent() is + any stdlib.semantic_parent(): p@GenericPackageDecl when p == pkg, - p_referenced_decl() is decl@*) + p_referenced_decl(): decl) # and is overloaded when is_overloaded(decl) # and the result type is declared outside pkg and n.p_expression_type() is not - BasicDecl(any stdlib.semantic_parent is p@GenericPackageDecl + BasicDecl(any stdlib.semantic_parent: p@GenericPackageDecl when p == pkg) fun check_params(n) = { @@ -48,6 +48,6 @@ fun check_params(n) = { message="possible occurrence of KP 18801", impact="23.*") fun kp_18801(node) = - node is (BinOp(f_op is OpEq) or - CallExpr(p_kind() is "call") when node.f_name.p_name_is("\"=\"")) + node is (BinOp(f_op: OpEq) | + CallExpr(p_kind(): "call") when node.f_name.p_name_is("\"=\"")) when check_params(node) diff --git a/lkql_checker/share/lkql/kp/KP-19134.lkql b/lkql_checker/share/lkql/kp/KP-19134.lkql index 62a697b39..a9e91671a 100644 --- a/lkql_checker/share/lkql/kp/KP-19134.lkql +++ b/lkql_checker/share/lkql/kp/KP-19134.lkql @@ -7,8 +7,8 @@ import stdlib # Check that 'type_decl' is an array of int fun is_array_of_int(type_decl) = type_decl.p_root_type() is TypeDecl( - p_is_array_type() is true, - f_type_def is def@ArrayTypeDef + p_is_array_type(): true, + f_type_def: def@ArrayTypeDef when def.f_component_type.f_type_expr.p_designated_type_decl().p_is_int_type() ) @@ -29,6 +29,6 @@ fun is_unck_conv_to_array_of_int(call) = message="possible occurrence of KP 19134", impact="23.*,24.*") fun kp_19134(node) = - node is CallExpr(p_is_call() is true) + node is CallExpr(p_is_call(): true) when stdlib.any([is_unck_conv_to_array_of_int(p.actual) for p in node.p_call_params()]) diff --git a/lkql_checker/share/lkql/kp/KP-19142.lkql b/lkql_checker/share/lkql/kp/KP-19142.lkql index e1bcdc72f..5fcd7ecda 100644 --- a/lkql_checker/share/lkql/kp/KP-19142.lkql +++ b/lkql_checker/share/lkql/kp/KP-19142.lkql @@ -22,10 +22,10 @@ fun is_unconstrained_discriminated(type_decl) = match type_decl | SubtypeDecl => not type_decl.f_subtype.p_subtype_constraint() and is_unconstrained_discriminated(type_decl.p_get_type()) - | BaseTypeDecl(p_base_type() is not null) + | BaseTypeDecl(p_base_type(): not null) => not type_decl.f_type_def.f_subtype_indication.p_subtype_constraint() and is_unconstrained_discriminated(type_decl.p_base_type()) - | BaseTypeDecl(p_private_completion() is not null) + | BaseTypeDecl(p_private_completion(): not null) => is_unconstrained_discriminated(type_decl.p_private_completion()) # TODO: Remove the 'p_discriminants_list' parameter when langkit#776 will be resolved | BaseTypeDecl => stdlib.any([d.f_default_expr != null @@ -46,4 +46,4 @@ fun kp_19142(node) = for id in p.f_ids.children]) for p in node.f_subp_spec.p_params() if is_unconstrained_discriminated(p.p_formal_type()) - and p.f_mode is (ModeOut or ModeInOut)]) + and p.f_mode is (ModeOut | ModeInOut)]) diff --git a/lkql_checker/share/lkql/kp/KP-OB03-009.lkql b/lkql_checker/share/lkql/kp/KP-OB03-009.lkql index 32d081cb3..db60bba36 100644 --- a/lkql_checker/share/lkql/kp/KP-OB03-009.lkql +++ b/lkql_checker/share/lkql/kp/KP-OB03-009.lkql @@ -4,9 +4,9 @@ @check(message="possible occurrence of KP OB03-009", impact="19.*") fun kp_ob03_009(node) = # Look for record types with discriminants and Implicit_Dereference aspect - node is TypeDecl(f_discriminants is part@KnownDiscriminantPart, - p_has_aspect("Implicit_Dereference") is true) + node is TypeDecl(f_discriminants: part@KnownDiscriminantPart, + p_has_aspect("Implicit_Dereference"): true) # with an access-to-class-wide discriminant when [s for s in (from part.f_discr_specs select DiscriminantSpec) - if s.f_type_expr is AnonymousType(f_type_decl is t@AnonymousTypeDecl) + if s.f_type_expr is AnonymousType(f_type_decl: t@AnonymousTypeDecl) when t.p_accessed_type() is ClasswideTypeDecl] diff --git a/lkql_checker/share/lkql/kp/KP-P226-024.lkql b/lkql_checker/share/lkql/kp/KP-P226-024.lkql index 040439a61..75c5ea3e9 100644 --- a/lkql_checker/share/lkql/kp/KP-P226-024.lkql +++ b/lkql_checker/share/lkql/kp/KP-P226-024.lkql @@ -18,4 +18,4 @@ fun kp_p226_024(node) = when has_no_local_po_restriction(node.p_enclosing_compilation_unit()) and stdlib.has_local_scope(node) and node.f_type_expr.p_designated_type_decl() is - BaseTypeDecl(any stdlib.component_types is ProtectedTypeDecl) + BaseTypeDecl(any stdlib.component_types: ProtectedTypeDecl) diff --git a/lkql_checker/share/lkql/kp/KP-Q609-033.lkql b/lkql_checker/share/lkql/kp/KP-Q609-033.lkql index a2916b353..c772d3390 100644 --- a/lkql_checker/share/lkql/kp/KP-Q609-033.lkql +++ b/lkql_checker/share/lkql/kp/KP-Q609-033.lkql @@ -19,6 +19,6 @@ fun kp_q609_033(node) = when has_no_local_timing_events_restriction(node.p_enclosing_compilation_unit()) and stdlib.has_local_scope(node) and node.f_type_expr.p_designated_type_decl() is BaseTypeDecl( - any stdlib.component_types is type@TypeDecl + any stdlib.component_types: type@TypeDecl when type.p_fully_qualified_name() == "Ada.Real_Time.Timing_Events.Timing_Event") diff --git a/lkql_checker/share/lkql/kp/KP-QC02-001.lkql b/lkql_checker/share/lkql/kp/KP-QC02-001.lkql index 20cc612cb..0eea7a6c1 100644 --- a/lkql_checker/share/lkql/kp/KP-QC02-001.lkql +++ b/lkql_checker/share/lkql/kp/KP-QC02-001.lkql @@ -14,9 +14,9 @@ fun array_with_align(type) = impact="7.[1-4].*,17.*,18.[12]", follow_generic_instantiations=true) fun kp_qc02_001(node) = - node is AttributeRef(parent is not AttributeDefClause) + node is AttributeRef(parent: not AttributeDefClause) when node.f_attribute.p_name_is("Size") and node.f_prefix.p_expression_type() is t@BaseTypeDecl when t.p_full_view() is type@BaseTypeDecl when (array_with_align(type) or - type is *(any stdlib.full_parent_types is p@BaseTypeDecl when array_with_align(p))) + type is *(any stdlib.full_parent_types: p@BaseTypeDecl when array_with_align(p))) diff --git a/lkql_checker/share/lkql/kp/KP-R316-001.lkql b/lkql_checker/share/lkql/kp/KP-R316-001.lkql index e9fff85d9..334693eb2 100644 --- a/lkql_checker/share/lkql/kp/KP-R316-001.lkql +++ b/lkql_checker/share/lkql/kp/KP-R316-001.lkql @@ -10,15 +10,15 @@ fun get_type_def(t) = @check(message="possible occurrence of KP R316-001", impact="18.*,19.[1-4],20.[12]") fun kp_r316_001(node) = - node is (ClassicSubpDecl or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) + node is (ClassicSubpDecl | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) when node.f_subp_spec is spec@SubpSpec( - f_subp_kind is SubpKindFunction, - p_return_type() is ret@TypeDecl( - f_type_def is ArrayTypeDef(f_indices is UnconstrainedArrayIndices) + f_subp_kind: SubpKindFunction, + p_return_type(): ret@TypeDecl( + f_type_def: ArrayTypeDef(f_indices: UnconstrainedArrayIndices) ) when get_type_def(ret.p_comp_type()) is - def@(DerivedTypeDef or PrivateTypeDef or RecordTypeDef) + def@(DerivedTypeDef | PrivateTypeDef | RecordTypeDef) when def.f_has_limited is LimitedPresent ) diff --git a/lkql_checker/share/lkql/kp/KP-R410-028.lkql b/lkql_checker/share/lkql/kp/KP-R410-028.lkql index 404e963f2..e732d2132 100644 --- a/lkql_checker/share/lkql/kp/KP-R410-028.lkql +++ b/lkql_checker/share/lkql/kp/KP-R410-028.lkql @@ -9,22 +9,22 @@ fun has_rec_with_discriminants(type) = fun check_type(type) = type is BaseTypeDecl and (has_rec_with_discriminants(type) or - type is *(any stdlib.component_types is t@BaseTypeDecl + type is *(any stdlib.component_types: t@BaseTypeDecl when has_rec_with_discriminants(t))) fun check_subp(subp) = - subp.f_subp_spec is spec@SubpSpec(f_subp_kind is SubpKindFunction) + subp.f_subp_spec is spec@SubpSpec(f_subp_kind: SubpKindFunction) when check_type(stdlib.full_root_type(spec.f_subp_returns. p_designated_type_decl())) @check(message="possible occurrence of KP R410-028", impact="7.[123].*") fun kp_r410_028(node) = node is BaseId( - p_is_call() is true, - any parent is ForLoopSpec, - p_referenced_decl() is - (decl@(ClassicSubpDecl or BaseSubpBody or SubpBodyStub) + p_is_call(): true, + any parent: ForLoopSpec, + p_referenced_decl(): + (decl@(ClassicSubpDecl | BaseSubpBody | SubpBodyStub) when check_subp(decl)) - or + | inst@GenericSubpInstantiation when check_subp(inst.p_designated_subp())) diff --git a/lkql_checker/share/lkql/kp/KP-R511-017.lkql b/lkql_checker/share/lkql/kp/KP-R511-017.lkql index 9bed352c3..e75b06361 100644 --- a/lkql_checker/share/lkql/kp/KP-R511-017.lkql +++ b/lkql_checker/share/lkql/kp/KP-R511-017.lkql @@ -6,7 +6,7 @@ import stdlib impact="7.[1-4].*,17.*,18.*") fun kp_r511_017(node) = node is SubtypeDecl( - p_has_aspect("Object_Size") is true, - any stdlib.full_parent_types is - BaseTypeDecl(p_has_aspect("Pack") is true, - p_is_array_type() is true)) + p_has_aspect("Object_Size"): true, + any stdlib.full_parent_types: + BaseTypeDecl(p_has_aspect("Pack"): true, + p_is_array_type(): true)) diff --git a/lkql_checker/share/lkql/kp/KP-R517-023.lkql b/lkql_checker/share/lkql/kp/KP-R517-023.lkql index 43263dea3..5b4073cb3 100644 --- a/lkql_checker/share/lkql/kp/KP-R517-023.lkql +++ b/lkql_checker/share/lkql/kp/KP-R517-023.lkql @@ -26,12 +26,12 @@ fun get_type(type) = impact="7.[1-4].*,17.*,18.[12]", follow_generic_instantiations = true) fun kp_r517_023(node) = - node is CallExpr(p_is_call() is true) + node is CallExpr(p_is_call(): true) when [p for p in node.p_call_params() - if p.param.parent.parent is spec@ParamSpec(f_mode is ModeOut or ModeInOut) - when p.actual is DottedName(p_referenced_decl() is comp@ComponentDecl) + if p.param.parent.parent is spec@ParamSpec(f_mode: ModeOut | ModeInOut) + when p.actual is DottedName(p_referenced_decl(): comp@ComponentDecl) when comp.p_semantic_parent().p_get_record_representation_clause() != null and get_type(spec.f_type_expr) is TypeDecl( - p_is_array_type() is true, - p_has_aspect("Pack") is true, - f_type_def is ArrayTypeDef(f_indices is UnconstrainedArrayIndices))] + p_is_array_type(): true, + p_has_aspect("Pack"): true, + f_type_def: ArrayTypeDef(f_indices: UnconstrainedArrayIndices))] diff --git a/lkql_checker/share/lkql/kp/KP-S114-015.lkql b/lkql_checker/share/lkql/kp/KP-S114-015.lkql index 219e242ef..eba7171c8 100644 --- a/lkql_checker/share/lkql/kp/KP-S114-015.lkql +++ b/lkql_checker/share/lkql/kp/KP-S114-015.lkql @@ -10,8 +10,8 @@ fun primitives(decl) = @check(message="possible occurrence of KP S124-035", impact="18.*,19.*") fun kp_s114_015(node) = # Look for variant record types - node is TypeDecl(f_discriminants is not null, - f_type_def is def@RecordTypeDef) + node is TypeDecl(f_discriminants: not null, + f_type_def: def@RecordTypeDef) when (from def.f_record_def.f_components select first VariantPart) != null # Look for all components definitions and check whether their corresponding # type has a user-defined equality diff --git a/lkql_checker/share/lkql/kp/KP-S124-035.lkql b/lkql_checker/share/lkql/kp/KP-S124-035.lkql index 006ba7b7a..657201306 100644 --- a/lkql_checker/share/lkql/kp/KP-S124-035.lkql +++ b/lkql_checker/share/lkql/kp/KP-S124-035.lkql @@ -6,7 +6,7 @@ import stdlib @check(message="possible occurrence of KP S124-035", impact="7.[1-4].*,1[7-9].*") fun kp_s124_035(node) = - node is CallExpr(p_is_call() is true) + node is CallExpr(p_is_call(): true) when node.f_name.p_referenced_decl() is i@GenericSubpInstantiation when stdlib.is_unchecked_conversion(i) and (from node.f_suffix select first Aggregate) != null diff --git a/lkql_checker/share/lkql/kp/KP-S521-014.lkql b/lkql_checker/share/lkql/kp/KP-S521-014.lkql index b6129d63b..7dbd38627 100644 --- a/lkql_checker/share/lkql/kp/KP-S521-014.lkql +++ b/lkql_checker/share/lkql/kp/KP-S521-014.lkql @@ -1,7 +1,9 @@ # Flag tagged types that implement interfaces and have discriminants. +import stdlib + @check(message="possible occurrence of KP S521-014", impact="19.*") fun kp_s521_014(node) = - node is TypeDecl(p_is_tagged_type() is true, - f_discriminants is not null, - any super_types is TypeDecl(p_is_interface_type() is true)) + node is TypeDecl(p_is_tagged_type(): true, + f_discriminants: not null, + any stdlib.super_types: TypeDecl(p_is_interface_type(): true)) diff --git a/lkql_checker/share/lkql/kp/KP-S621-051.lkql b/lkql_checker/share/lkql/kp/KP-S621-051.lkql index ec39305d8..13cbd5385 100644 --- a/lkql_checker/share/lkql/kp/KP-S621-051.lkql +++ b/lkql_checker/share/lkql/kp/KP-S621-051.lkql @@ -6,15 +6,15 @@ import stdlib @check(message="possible occurrence of KP S621-051", impact="19.*") fun kp_s621_051(node) = node is ParamAssoc( - parent is AssocList(parent is c@CallExpr( - p_is_call() is true + parent: AssocList(parent: c@CallExpr( + p_is_call(): true ) when c.f_name.p_referenced_decl() is decl@BasicDecl( - p_has_aspect("Import") is false + p_has_aspect("Import"): false ) when stdlib.enclosing_body(decl) == stdlib.enclosing_body(node) ), - f_r_expr is Name( - p_referenced_decl() is ParamSpec, - p_expression_type() is AnonymousTypeDecl(p_is_access_type() is true) + f_r_expr: Name( + p_referenced_decl(): ParamSpec, + p_expression_type(): AnonymousTypeDecl(p_is_access_type(): true) ) ) diff --git a/lkql_checker/share/lkql/kp/KP-S722-023.lkql b/lkql_checker/share/lkql/kp/KP-S722-023.lkql index d6484846b..37b1e2e2f 100644 --- a/lkql_checker/share/lkql/kp/KP-S722-023.lkql +++ b/lkql_checker/share/lkql/kp/KP-S722-023.lkql @@ -2,7 +2,7 @@ fun is_array_slice(expr) = |" Return whether the given expression corresponds to an array slice. - if expr is CallExpr(p_is_array_slice() is true) + if expr is CallExpr(p_is_array_slice(): true) then true else match expr.p_referenced_decl() | o@ObjectDecl => o.f_renaming_clause is r@RenamingClause @@ -11,9 +11,9 @@ fun is_array_slice(expr) = # This node means we have a reference to a generic formal object. # Exclude "in" objects since the bug cannot occur there. expr.p_get_uninstantiated_node(). - p_referenced_decl() is ObjectDecl(f_mode is ModeOut or ModeInOut) and + p_referenced_decl() is ObjectDecl(f_mode: ModeOut | ModeInOut) and is_array_slice(a.f_expr) - | o@* => false + | o => false @check(message="possible occurrence of KP S722-023", impact="7.[1-4].*,17.*,18.[12],19.[123]", diff --git a/lkql_checker/share/lkql/kp/KP-T528-043.lkql b/lkql_checker/share/lkql/kp/KP-T528-043.lkql index b6ec44326..0472af4e2 100644 --- a/lkql_checker/share/lkql/kp/KP-T528-043.lkql +++ b/lkql_checker/share/lkql/kp/KP-T528-043.lkql @@ -6,12 +6,12 @@ import stdlib @check(message="possible occurrence of KP T528-043", impact="18.*,19.[1-5],20.[12]") fun kp_t528_043(node) = - node is ObjectDecl when + node is (ObjectDecl when node.p_has_aspect("Address") and stdlib.has_non_default_sso(node.f_type_expr.p_designated_type_decl()) - or GenericSubpInstantiation when + | GenericSubpInstantiation when stdlib.is_unchecked_conversion(node) and (stdlib.has_non_default_sso(node.f_params[1].f_r_expr. p_referenced_decl()) or stdlib.has_non_default_sso(node.f_params[2].f_r_expr. - p_referenced_decl())) + p_referenced_decl()))) diff --git a/lkql_checker/share/lkql/kp/KP-T602-028.lkql b/lkql_checker/share/lkql/kp/KP-T602-028.lkql index bb7474b73..ba4c00ef5 100644 --- a/lkql_checker/share/lkql/kp/KP-T602-028.lkql +++ b/lkql_checker/share/lkql/kp/KP-T602-028.lkql @@ -15,10 +15,10 @@ fun kp_t602_028(node) = when is_access(node.f_attribute) # where prefix is a protected subprogram and node.f_prefix.p_referenced_decl() is - decl@SubpDecl(any parent is ProtectedDef) + decl@SubpDecl(any parent: ProtectedDef) # and this subprogram is overloaded when decl.f_subp_spec.f_subp_name is name@DefiningName - when (decl is *(any prev_siblings is sib@SubpDecl + when (decl is *(any prev_siblings: sib@SubpDecl when sib.f_subp_spec.f_subp_name.p_name_matches(name)) or - decl is *(any next_siblings is sib@SubpDecl + decl is *(any next_siblings: sib@SubpDecl when sib.f_subp_spec.f_subp_name.p_name_matches(name))) diff --git a/lkql_checker/share/lkql/kp/KP-T708-064.lkql b/lkql_checker/share/lkql/kp/KP-T708-064.lkql index bab87577d..5b027a340 100644 --- a/lkql_checker/share/lkql/kp/KP-T708-064.lkql +++ b/lkql_checker/share/lkql/kp/KP-T708-064.lkql @@ -21,8 +21,8 @@ fun has_variant_with_varsize(t) = from (from def.f_components select Variant) select c@ComponentDef when c.f_type_expr is - s@SubtypeIndication(f_constraint is CompositeConstraint( - p_is_discriminant_constraint() is true)) + s@SubtypeIndication(f_constraint: CompositeConstraint( + p_is_discriminant_constraint(): true)) when has_varsize_comp(s.f_name.p_referenced_decl())] @check(message="possible occurrence of KP T708-064", impact="20.[12]") @@ -34,6 +34,6 @@ fun kp_t708_064(node) = from (from def.f_components select Variant) select c@ComponentDef when c.f_type_expr is - s@SubtypeIndication(f_constraint is CompositeConstraint( - p_is_discriminant_constraint() is true)) + s@SubtypeIndication(f_constraint: CompositeConstraint( + p_is_discriminant_constraint(): true)) when has_variant_with_varsize(s.f_name.p_referenced_decl())] diff --git a/lkql_checker/share/lkql/kp/KP-T805-037.lkql b/lkql_checker/share/lkql/kp/KP-T805-037.lkql index 5e75236ca..a64d962ee 100644 --- a/lkql_checker/share/lkql/kp/KP-T805-037.lkql +++ b/lkql_checker/share/lkql/kp/KP-T805-037.lkql @@ -5,15 +5,15 @@ @check(message="possible occurrence of KP T805-037", impact="20.[12]") fun kp_t805_037(node) = node is TypeDecl( - f_discriminants is part@KnownDiscriminantPart, - f_type_def is r@RecordTypeDef(f_record_def is def@RecordDef) + f_discriminants: part@KnownDiscriminantPart, + f_type_def: r@RecordTypeDef(f_record_def: def@RecordDef) ) when { val discs = from part select DefiningName; [decl for decl in from def.f_components select c@ComponentDecl when c.f_component_def.f_type_expr is - s@SubtypeIndication(f_constraint is CompositeConstraint( - p_is_discriminant_constraint() is true) + s@SubtypeIndication(f_constraint: CompositeConstraint( + p_is_discriminant_constraint(): true) and [id for id in (from c.f_default_expr select Identifier) if [d for d in discs if d.p_name_matches(id)]]] } diff --git a/lkql_checker/share/lkql/kp/KP-TA10-002.lkql b/lkql_checker/share/lkql/kp/KP-TA10-002.lkql index 47519434a..99d619d7f 100644 --- a/lkql_checker/share/lkql/kp/KP-TA10-002.lkql +++ b/lkql_checker/share/lkql/kp/KP-TA10-002.lkql @@ -6,10 +6,10 @@ import stdlib @check(message="possible occurrence of KP TA10-002", impact="21.*,22.*,23.1") fun kp_ta10_002(node) = - node is CondExpr(any parent is ReturnStmt or ExprFunction) - when (from node select first c@BaseId(p_is_call() is true) + node is CondExpr(any parent: ReturnStmt | ExprFunction) + when (from node select first c@BaseId(p_is_call(): true) when c.p_expression_type() is BasicDecl( - any stdlib.full_parent_types is TypeDecl( - f_type_def is RecordTypeDef(f_has_limited is LimitedPresent) or + any stdlib.full_parent_types: TypeDecl( + f_type_def: RecordTypeDef(f_has_limited: LimitedPresent) | InterfaceTypeDef( - f_interface_kind is InterfaceKindLimited)))) + f_interface_kind: InterfaceKindLimited)))) diff --git a/lkql_checker/share/lkql/kp/KP-TA15-022.lkql b/lkql_checker/share/lkql/kp/KP-TA15-022.lkql index b7dc9c817..6098c8d53 100644 --- a/lkql_checker/share/lkql/kp/KP-TA15-022.lkql +++ b/lkql_checker/share/lkql/kp/KP-TA15-022.lkql @@ -4,8 +4,8 @@ @check(message="possible occurrence of KP TA15-022", impact="18.[1-3],19.[1-6],20.[12]") fun kp_ta15_022(node) = - node is (RaiseStmt(f_exception_name is DottedName) or + node is (RaiseStmt(f_exception_name: DottedName) | PragmaNode when node.f_id.p_name_is("Assert") and node.f_args[1].p_assoc_expr() is e@Expr when e.p_is_static_expr() and e.p_eval_as_int() == 0) - and node is *(any parent is s@HandledStmts when s.f_exceptions[1] != null) + and node is *(any parent: s@HandledStmts when s.f_exceptions[1] != null) diff --git a/lkql_checker/share/lkql/kp/KP-TA30-032.lkql b/lkql_checker/share/lkql/kp/KP-TA30-032.lkql index 8bb7cca60..4e0c713f8 100644 --- a/lkql_checker/share/lkql/kp/KP-TA30-032.lkql +++ b/lkql_checker/share/lkql/kp/KP-TA30-032.lkql @@ -15,9 +15,9 @@ fun range_length(t) = fun kp_ta30_032(node) = node is ObjectDecl when node.f_type_expr is - SubtypeIndication(f_constraint is - c@CompositeConstraint(p_is_index_constraint() is true)) - when c.f_constraints[1].f_constraint_expr is op@BinOp(f_op is OpDoubleDot) + SubtypeIndication(f_constraint: + c@CompositeConstraint(p_is_index_constraint(): true)) + when c.f_constraints[1].f_constraint_expr is op@BinOp(f_op: OpDoubleDot) when stdlib.range_values(op.f_left, op.f_right) == 0 and node.f_type_expr.p_designated_type_decl() is t@BaseTypeDecl when t.p_is_array_type() diff --git a/lkql_checker/share/lkql/kp/KP-TB09-038.lkql b/lkql_checker/share/lkql/kp/KP-TB09-038.lkql index 00262accc..a44761c4a 100644 --- a/lkql_checker/share/lkql/kp/KP-TB09-038.lkql +++ b/lkql_checker/share/lkql/kp/KP-TB09-038.lkql @@ -9,10 +9,10 @@ fun is_positive(n) = n.p_is_static_expr() and n.p_eval_as_int() >= 0 @check(message="possible occurrence of KP TB09-038", impact="20.[12]") fun kp_tb09_038(node) = # Look for an integer type declaration - node is TypeDecl(p_is_int_type() is true, - f_type_def is def@SignedIntTypeDef) + node is TypeDecl(p_is_int_type(): true, + f_type_def: def@SignedIntTypeDef) # with an explicit range definition - when def.f_range.f_range is op@BinOp(f_op is OpDoubleDot) + when def.f_range.f_range is op@BinOp(f_op: OpDoubleDot) # and both range values of the same sign when (if is_positive(op.f_left) then is_positive(op.f_right) diff --git a/lkql_checker/share/lkql/kp/KP-TB23-035.lkql b/lkql_checker/share/lkql/kp/KP-TB23-035.lkql index c023ef934..1c4d48da3 100644 --- a/lkql_checker/share/lkql/kp/KP-TB23-035.lkql +++ b/lkql_checker/share/lkql/kp/KP-TB23-035.lkql @@ -6,11 +6,11 @@ import stdlib @check(message="possible occurrence of KP TB23-035", impact="20.[12]") fun kp_tb23_035(node) = - node is AssignStmt(f_dest is DottedName(p_referenced_decl() is + node is AssignStmt(f_dest: DottedName(p_referenced_decl(): c@ComponentDecl)) when c.p_semantic_parent().p_get_record_representation_clause() != null and stdlib.strip_conversions(node.f_expr) is CallExpr and node.f_expr.p_expression_type() is - TypeDecl(p_is_record_type() is true, - f_discriminants is discr@KnownDiscriminantPart) + TypeDecl(p_is_record_type(): true, + f_discriminants: discr@KnownDiscriminantPart) when [s for s in discr.f_discr_specs.children if s.f_default_expr != null] diff --git a/lkql_checker/share/lkql/kp/KP-TC01-050.lkql b/lkql_checker/share/lkql/kp/KP-TC01-050.lkql index 7167a8df1..92b27f7a3 100644 --- a/lkql_checker/share/lkql/kp/KP-TC01-050.lkql +++ b/lkql_checker/share/lkql/kp/KP-TC01-050.lkql @@ -7,9 +7,9 @@ import stdlib impact="19.[1-4],20.[12],21.1") fun kp_tc01_050(node) = node is MembershipExpr( - f_membership_exprs is l@ExprAlternativesList + f_membership_exprs: l@ExprAlternativesList when l.children_count == 1 - and l[1] is Name(p_referenced_decl() is t@TypeDecl + and l[1] is Name(p_referenced_decl(): t@TypeDecl when stdlib.has_interfaces(t)) ) diff --git a/lkql_checker/share/lkql/kp/KP-U225-018.lkql b/lkql_checker/share/lkql/kp/KP-U225-018.lkql index ec97ffedd..820e7d7f7 100644 --- a/lkql_checker/share/lkql/kp/KP-U225-018.lkql +++ b/lkql_checker/share/lkql/kp/KP-U225-018.lkql @@ -7,9 +7,9 @@ import stdlib message="possible occurrence of KP U225-018 if -gnatVfm is enabled", impact="20.[12],21.[1-3]") fun kp_u225_018(node) = - node is CallExpr(parent is ParamAssoc(parent is l@AssocList( - parent is CallExpr(p_is_call() is true)))) - when node.f_name.p_referenced_decl() is BaseTypeDecl(p_is_float_type() is true) + node is CallExpr(parent: ParamAssoc(parent: l@AssocList( + parent: CallExpr(p_is_call(): true)))) + when node.f_name.p_referenced_decl() is BaseTypeDecl(p_is_float_type(): true) and node.f_suffix[1].f_r_expr.p_expression_type().p_is_fixed_point() and stdlib.get_parameter(l.p_zip_with_params(),node). parent.parent.f_mode is ModeInOut diff --git a/lkql_checker/share/lkql/kp/KP-U310-012.lkql b/lkql_checker/share/lkql/kp/KP-U310-012.lkql index 3349d565d..351aecc83 100644 --- a/lkql_checker/share/lkql/kp/KP-U310-012.lkql +++ b/lkql_checker/share/lkql/kp/KP-U310-012.lkql @@ -3,13 +3,13 @@ fun is_unconstrained(t) = t.f_type_def is - ArrayTypeDef(f_indices is UnconstrainedArrayIndices) or - t is ConcreteTypeDecl(f_discriminants is KnownDiscriminantPart) + ArrayTypeDef(f_indices: UnconstrainedArrayIndices) or + t is ConcreteTypeDecl(f_discriminants: KnownDiscriminantPart) @check(message="possible occurrence of KP U310-012", impact="22.*") fun kp_u310_012(node) = - node is SubpSpec(f_subp_kind is SubpKindFunction) - when node.p_return_type() is TypeDecl(p_full_view() is ret@TypeDecl) + node is SubpSpec(f_subp_kind: SubpKindFunction) + when node.p_return_type() is TypeDecl(p_full_view(): ret@TypeDecl) when is_unconstrained(ret) and (node.parent.p_has_aspect("Post") or ret.p_has_aspect("Type_Invariant")) diff --git a/lkql_checker/share/lkql/kp/KP-U629-002.lkql b/lkql_checker/share/lkql/kp/KP-U629-002.lkql index 4aab734ce..c5196a073 100644 --- a/lkql_checker/share/lkql/kp/KP-U629-002.lkql +++ b/lkql_checker/share/lkql/kp/KP-U629-002.lkql @@ -8,17 +8,17 @@ import stdlib @check(message="possible occurrence of KP U629-002", impact="21.*") fun kp_u629_002(node) = # Look for type(xxx.all) as part of a return or expression function body - node is ExplicitDeref(parent is ParamAssoc(parent is AssocList( - parent is CallExpr( - any parent is ExprFunction or ReturnStmt, + node is ExplicitDeref(parent: ParamAssoc(parent: AssocList( + parent: CallExpr( + any parent: ExprFunction | ReturnStmt, # the return object is a controlling parameter - any parent is BaseSubpBody(f_subp_spec is spec@SubpSpec) + any parent: BaseSubpBody(f_subp_spec: spec@SubpSpec) when stdlib.is_controlling_param_type(spec.p_returns(), spec), - f_name is Identifier( - p_referenced_decl() is BaseTypeDecl( + f_name: Identifier( + p_referenced_decl(): BaseTypeDecl( # where type is tagged and the root type is an interface - p_is_tagged_type() is true, - p_root_type() is BaseTypeDecl(p_is_interface_type() is true))))))) + p_is_tagged_type(): true, + p_root_type(): BaseTypeDecl(p_is_interface_type(): true))))))) # and the type of node is a class wide access when node.f_prefix.p_referenced_decl()?.p_type_expression?()?. p_designated_type_decl?()?.p_accessed_type?() is ClasswideTypeDecl diff --git a/lkql_checker/share/lkql/kp/KP-U702-038.lkql b/lkql_checker/share/lkql/kp/KP-U702-038.lkql index 143c39a61..d5ef8c47b 100644 --- a/lkql_checker/share/lkql/kp/KP-U702-038.lkql +++ b/lkql_checker/share/lkql/kp/KP-U702-038.lkql @@ -4,9 +4,9 @@ @check(message="possible occurrence of KP U702-038", impact="21.*") fun kp_u702_038(node) = node is ObjectDecl( - f_default_expr is Allocator, - f_type_expr is TypeExpr( - p_designated_type_decl() is AnonymousTypeDecl( - p_accessed_type() is - ClasswideTypeDecl or - BaseSubtypeDecl(p_base_subtype() is ClasswideTypeDecl)))) + f_default_expr: Allocator, + f_type_expr: TypeExpr( + p_designated_type_decl(): AnonymousTypeDecl( + p_accessed_type(): + ClasswideTypeDecl | + BaseSubtypeDecl(p_base_subtype(): ClasswideTypeDecl)))) diff --git a/lkql_checker/share/lkql/kp/KP-U727-033.lkql b/lkql_checker/share/lkql/kp/KP-U727-033.lkql index df11d746b..7a2b5648b 100644 --- a/lkql_checker/share/lkql/kp/KP-U727-033.lkql +++ b/lkql_checker/share/lkql/kp/KP-U727-033.lkql @@ -5,5 +5,5 @@ impact="7.4.*,1[7-9].*,2[01].*", target="leon*") fun kp_u727_033(node) = - node is LibraryItem(f_item is b@BaseSubpBody) + node is LibraryItem(f_item: b@BaseSubpBody) when b.f_subp_spec.f_subp_params == null diff --git a/lkql_checker/share/lkql/kp/KP-U803-030.lkql b/lkql_checker/share/lkql/kp/KP-U803-030.lkql index e1fb89896..0e1273f71 100644 --- a/lkql_checker/share/lkql/kp/KP-U803-030.lkql +++ b/lkql_checker/share/lkql/kp/KP-U803-030.lkql @@ -16,10 +16,10 @@ fun outermost_package_decl(n) = impact="21.*") fun kp_u803_030(node) = node is CallExpr( - p_is_call() is true, - p_referenced_decl() is func@ExprFunction + p_is_call(): true, + p_referenced_decl(): func@ExprFunction ) when not stdlib.has_local_scope(func) and outermost_package_decl(func) is decl@BasePackageDecl( - p_body_part() is null + p_body_part(): null ) when decl != outermost_package_decl(node) diff --git a/lkql_checker/share/lkql/kp/KP-U812-034.lkql b/lkql_checker/share/lkql/kp/KP-U812-034.lkql index ca41041b0..f4388a4f0 100644 --- a/lkql_checker/share/lkql/kp/KP-U812-034.lkql +++ b/lkql_checker/share/lkql/kp/KP-U812-034.lkql @@ -8,7 +8,7 @@ fun kp_u812_034(node) = node is AttributeRef when node.f_attribute.p_name_is("Access") and stdlib.ultimate_prefix(node.f_prefix).p_referenced_decl() is - ObjectDecl(f_renaming_clause is - RenamingClause(f_renamed_object is c@CallExpr + ObjectDecl(f_renaming_clause: + RenamingClause(f_renamed_object: c@CallExpr when c.f_name.p_referenced_decl() is - BaseTypeDecl(p_is_tagged_type() is true))) + BaseTypeDecl(p_is_tagged_type(): true))) diff --git a/lkql_checker/share/lkql/kp/KP-U923-018.lkql b/lkql_checker/share/lkql/kp/KP-U923-018.lkql index 016b6d46b..8229df4a4 100644 --- a/lkql_checker/share/lkql/kp/KP-U923-018.lkql +++ b/lkql_checker/share/lkql/kp/KP-U923-018.lkql @@ -6,10 +6,10 @@ import stdlib message="possible occurrence of KP U923-018 on powerpc64 targets", impact="21.*", target="powerpc64*") fun kp_u923_018(node) = - node is (ClassicSubpDecl or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) - when node.f_subp_spec is spec@SubpSpec(f_subp_kind is SubpKindFunction) + node is (ClassicSubpDecl | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) + when node.f_subp_spec is spec@SubpSpec(f_subp_kind: SubpKindFunction) when spec.f_subp_returns.p_designated_type_decl() is t@BaseTypeDecl when t.p_is_array_type() and t.p_comp_type().p_is_float_type() @@ -18,7 +18,7 @@ fun kp_u923_018(node) = # will return the base type. and (( t is TypeDecl when t.f_type_def.f_indices[1] is c@ConstraintList - when c[1] is op@BinOp(f_op is OpDoubleDot) + when c[1] is op@BinOp(f_op: OpDoubleDot) when stdlib.range_values(op.f_left, op.f_right) == 2 ) or ( stdlib.number_of_values(t.p_index_type(0)) == 2 diff --git a/lkql_checker/share/lkql/kp/KP-U928-018.lkql b/lkql_checker/share/lkql/kp/KP-U928-018.lkql index 0d5ce242f..8cef3153e 100644 --- a/lkql_checker/share/lkql/kp/KP-U928-018.lkql +++ b/lkql_checker/share/lkql/kp/KP-U928-018.lkql @@ -3,9 +3,9 @@ @check(message="possible occurrence of KP U928-018", impact="22.*,23.1") fun kp_u928_018(node) = - node is ForLoopStmt(f_spec is spec@ForLoopSpec( - f_loop_type is IterTypeOf) + node is ForLoopStmt(f_spec: spec@ForLoopSpec( + f_loop_type: IterTypeOf) # Find a CallExpr whose f_name's type has a Constant_Indexing aspect when (from spec select first c@CallExpr when c.f_name.p_expression_type() is ConcreteTypeDecl( - p_has_aspect("Constant_Indexing") is true)) + p_has_aspect("Constant_Indexing"): true)) diff --git a/lkql_checker/share/lkql/kp/KP-UA12-036.lkql b/lkql_checker/share/lkql/kp/KP-UA12-036.lkql index e2c535600..c7dea39c6 100644 --- a/lkql_checker/share/lkql/kp/KP-UA12-036.lkql +++ b/lkql_checker/share/lkql/kp/KP-UA12-036.lkql @@ -10,7 +10,7 @@ fun is_over_aligned(t, alignment) = { val aspect=t.p_get_aspect("Alignment"); (aspect.exists and aspect.value is IntLiteral and aspect.value.p_denoted_value() > alignment) or - [f for f in from t select ComponentDef or DiscriminantSpec + [f for f in from t select (ComponentDef | DiscriminantSpec) if is_over_aligned(f.f_type_expr.p_designated_type_decl(), alignment)] } diff --git a/lkql_checker/share/lkql/kp/KP-UB15-001.lkql b/lkql_checker/share/lkql/kp/KP-UB15-001.lkql index bc815c40d..0ed7040d7 100644 --- a/lkql_checker/share/lkql/kp/KP-UB15-001.lkql +++ b/lkql_checker/share/lkql/kp/KP-UB15-001.lkql @@ -4,4 +4,4 @@ message="possible occurrence of KP UB15-001: use of Small aspect", impact="18.*,19.*,20.*,21.*") fun kp_ub15_001(node) = - node is AspectAssoc(f_id is Identifier(p_name_is("Small") is true)) + node is AspectAssoc(f_id: Identifier(p_name_is("Small"): true)) diff --git a/lkql_checker/share/lkql/kp/KP-UB22-022.lkql b/lkql_checker/share/lkql/kp/KP-UB22-022.lkql index 402b250f9..9909978d8 100644 --- a/lkql_checker/share/lkql/kp/KP-UB22-022.lkql +++ b/lkql_checker/share/lkql/kp/KP-UB22-022.lkql @@ -4,17 +4,17 @@ @check(message="possible occurrence of KP UB22-022", impact="19.*,20.*,21.*") fun kp_ub22_022(node) = - node is ForLoopStmt(f_spec is ForLoopSpec( - f_loop_type is IterTypeOf, - f_iter_expr is DottedName( + node is ForLoopStmt(f_spec: ForLoopSpec( + f_loop_type: IterTypeOf, + f_iter_expr: DottedName( # Check whether Comp1 is a discriminated component - f_prefix is DottedName(f_suffix is id@Identifier( - p_referenced_decl() is c@ComponentDecl + f_prefix: DottedName(f_suffix: id@Identifier( + p_referenced_decl(): c@ComponentDecl when c.f_component_def.f_type_expr.p_designated_type_decl() is - BaseTypeDecl(p_is_record_type() is true, - f_discriminants is KnownDiscriminantPart))), + BaseTypeDecl(p_is_record_type(): true, + f_discriminants: KnownDiscriminantPart))), # Check whether Comp2 is an array-valued component - f_suffix is id@Identifier( - p_referenced_decl() is c@ComponentDecl + f_suffix: id@Identifier( + p_referenced_decl(): c@ComponentDecl when c.f_component_def.f_type_expr.p_designated_type_decl()?. p_is_array_type())))) diff --git a/lkql_checker/share/lkql/kp/KP-V114-047.lkql b/lkql_checker/share/lkql/kp/KP-V114-047.lkql index 1e7e14f5c..517e9e144 100644 --- a/lkql_checker/share/lkql/kp/KP-V114-047.lkql +++ b/lkql_checker/share/lkql/kp/KP-V114-047.lkql @@ -4,5 +4,5 @@ message="possible occurrence of KP V114-047 if runtime is ravenscar*zynq*", target="arm-elf", impact="18.*,19.*,20.*,21.*,22.1") fun kp_v114_047(node) = - node is ProtectedTypeDecl or SingleProtectedDecl - when node.p_has_aspect("Interrupt_Priority") + node is (ProtectedTypeDecl | SingleProtectedDecl + when node.p_has_aspect("Interrupt_Priority")) diff --git a/lkql_checker/share/lkql/kp/KP-V120-015.lkql b/lkql_checker/share/lkql/kp/KP-V120-015.lkql index 9f91ea2b8..3626f5454 100644 --- a/lkql_checker/share/lkql/kp/KP-V120-015.lkql +++ b/lkql_checker/share/lkql/kp/KP-V120-015.lkql @@ -14,7 +14,7 @@ fun check_type(t) = t.p_get_record_representation_clause() is rep@RecordRepClause when # and at least one component clause has a size that is not a power of two [f for f in (from rep select ComponentClause( - f_range is RangeSpec(f_range is r@BinOp(f_op is OpDoubleDot)) + f_range: RangeSpec(f_range: r@BinOp(f_op: OpDoubleDot)) when not is_power_of_two(r.f_right.p_eval_as_int() - r.f_left.p_eval_as_int() + 1) ))] diff --git a/lkql_checker/share/lkql/kp/KP-V127-049.lkql b/lkql_checker/share/lkql/kp/KP-V127-049.lkql index 0c65f81d8..2c18d064b 100644 --- a/lkql_checker/share/lkql/kp/KP-V127-049.lkql +++ b/lkql_checker/share/lkql/kp/KP-V127-049.lkql @@ -17,10 +17,10 @@ fun is_operator(params, expr) = @check(message="possible occurrence of KP V127-049", impact="21.*,22.1") fun kp_v127_049(node) = # Look for parameter associations of generic instantiations - node is ParamAssoc(parent is AssocList(parent is inst@GenericInstantiation), - f_r_expr is expr@Name) + node is ParamAssoc(parent: AssocList(parent: inst@GenericInstantiation), + f_r_expr: expr@Name) # where the parameter is a subprogram - when expr.p_referenced_decl() is decl@(BaseSubpBody or ClassicSubpDecl or + when expr.p_referenced_decl() is decl@(BaseSubpBody | ClassicSubpDecl | SubpBodyStub) # returning a boolean (sub)type when (decl.f_subp_spec.f_subp_returns is t@TypeExpr diff --git a/lkql_checker/share/lkql/kp/KP-V214-016.lkql b/lkql_checker/share/lkql/kp/KP-V214-016.lkql index dd240a7e6..f3955be1a 100644 --- a/lkql_checker/share/lkql/kp/KP-V214-016.lkql +++ b/lkql_checker/share/lkql/kp/KP-V214-016.lkql @@ -9,9 +9,9 @@ fun check_type(params) = p.param.p_name_is("T") and p.actual.p_referenced_decl().p_root_type() is root@BaseTypeDecl when ( root.f_type_def.f_has_limited.p_as_bool() and - root is TypeDecl(all stdlib.component_types is not TaskTypeDecl) and + root is TypeDecl(all stdlib.component_types: not TaskTypeDecl) and [t for t in root.p_find_all_derived_types(stdlib.list_of_units()) if - t is TypeDecl(any stdlib.component_types is TaskTypeDecl)] + t is TypeDecl(any stdlib.component_types: TaskTypeDecl)] ) ] diff --git a/lkql_checker/share/lkql/kp/KP-V216-031.lkql b/lkql_checker/share/lkql/kp/KP-V216-031.lkql index db3e0c9a0..275b134cb 100644 --- a/lkql_checker/share/lkql/kp/KP-V216-031.lkql +++ b/lkql_checker/share/lkql/kp/KP-V216-031.lkql @@ -9,5 +9,5 @@ fun has_detect_blocking(unit) = @check(help="possible occurrence of KP V216-031 - global analysis required", message="possible occurrence of KP V216-031", impact="21.*") fun kp_v216_031(node) = - node is ForLoopSpec(f_loop_type is IterTypeOf) + node is ForLoopSpec(f_loop_type: IterTypeOf) when has_detect_blocking(node.p_enclosing_compilation_unit()) diff --git a/lkql_checker/share/lkql/kp/KP-V302-021.lkql b/lkql_checker/share/lkql/kp/KP-V302-021.lkql index 9caa169ab..e92fa549e 100644 --- a/lkql_checker/share/lkql/kp/KP-V302-021.lkql +++ b/lkql_checker/share/lkql/kp/KP-V302-021.lkql @@ -5,9 +5,9 @@ import stdlib @check(message="possible occurrence of KP V302-021", impact="21.*,22.1") fun kp_v302_021(node) = - node is BaseSubpSpec(p_return_type() is ret@TypeDecl, - p_primitive_subp_tagged_type() is type@BaseTypeDecl, - parent is decl@BasicDecl(p_previous_part_for_decl() is null)) + node is BaseSubpSpec(p_return_type(): ret@TypeDecl, + p_primitive_subp_tagged_type(): type@BaseTypeDecl, + parent: decl@BasicDecl(p_previous_part_for_decl(): null)) when stdlib.is_limited_type(ret) and { val num_types = type.p_find_all_derived_types(stdlib.list_of_units()).length; diff --git a/lkql_checker/share/lkql/kp/KP-V329-046.lkql b/lkql_checker/share/lkql/kp/KP-V329-046.lkql index 47b77c07b..aea436da8 100644 --- a/lkql_checker/share/lkql/kp/KP-V329-046.lkql +++ b/lkql_checker/share/lkql/kp/KP-V329-046.lkql @@ -3,8 +3,8 @@ @check(message="possible occurrence of KP V329-046", impact="22.1") fun kp_v329_046(node) = - node is ObjectDecl(f_type_expr is AnonymousType( - f_type_decl is AnonymousTypeDecl(f_type_def is acc@AccessToSubpDef))) + node is ObjectDecl(f_type_expr: AnonymousType( + f_type_decl: AnonymousTypeDecl(f_type_def: acc@AccessToSubpDef))) when { val aspect = node.p_get_aspect("Convention"); aspect.exists and aspect.value.p_name_is("C") diff --git a/lkql_checker/share/lkql/kp/KP-V407-011.lkql b/lkql_checker/share/lkql/kp/KP-V407-011.lkql index 5b3e62f00..e00e64f9a 100644 --- a/lkql_checker/share/lkql/kp/KP-V407-011.lkql +++ b/lkql_checker/share/lkql/kp/KP-V407-011.lkql @@ -12,13 +12,13 @@ fun check_prefix(param, n) = |" - param is a parameter of an anonymous access type |" - n is of a type that implements an interface type. param.p_referenced_decl() is ParamSpec and - param.p_expression_type() is AnonymousTypeDecl(p_is_access_type() is true) and + param.p_expression_type() is AnonymousTypeDecl(p_is_access_type(): true) and n.p_expression_type() is t@TypeDecl when stdlib.has_interfaces(t) @check(message="possible occurrence of KP V407-011", impact="20.*,21.*,22.1") fun kp_v407_011(node) = # Look for 'Access as a parameter of a CallExpr - node is AttributeRef(parent is ParamAssoc(parent is l@AssocList(parent is CallExpr))) + node is AttributeRef(parent: ParamAssoc(parent: l@AssocList(parent: CallExpr))) when node.f_attribute.p_name_is("Access") # Check that we have a dereference (direct or indirect) and a type # implementing some interface @@ -28,7 +28,7 @@ fun kp_v407_011(node) = # Check that the formal parameter is of a named general access type # designating a class-wide type that implements some interface. and stdlib.get_parameter(l.p_zip_with_params(), node).parent.parent is - ParamSpec(f_type_expr is SubtypeIndication(f_name is n@Name) + ParamSpec(f_type_expr: SubtypeIndication(f_name: n@Name) when n.p_referenced_decl() is t@TypeDecl when t.p_accessed_type() is cw@ClasswideTypeDecl when stdlib.has_interfaces(cw) diff --git a/lkql_checker/share/lkql/kp/KP-V505-020.lkql b/lkql_checker/share/lkql/kp/KP-V505-020.lkql index 36dc0c4ca..fce1ec31e 100644 --- a/lkql_checker/share/lkql/kp/KP-V505-020.lkql +++ b/lkql_checker/share/lkql/kp/KP-V505-020.lkql @@ -2,5 +2,5 @@ @check(message="possible occurrence of KP V505-020", impact="22.*") fun kp_v505_020(node) = - node is ExprFunction(p_decl_part() is null) + node is ExprFunction(p_decl_part(): null) when node.f_subp_spec.p_primitive_subp_tagged_type() is BaseTypeDecl diff --git a/lkql_checker/share/lkql/kp/KP-V616-018.lkql b/lkql_checker/share/lkql/kp/KP-V616-018.lkql index a02ea265c..2966dda93 100644 --- a/lkql_checker/share/lkql/kp/KP-V616-018.lkql +++ b/lkql_checker/share/lkql/kp/KP-V616-018.lkql @@ -3,16 +3,16 @@ fun access_to_unconstrained_array(t) = t is TypeDecl( - p_is_access_type() is true, - p_accessed_type() is TypeDecl( - f_type_def is ArrayTypeDef(f_indices is UnconstrainedArrayIndices))) + p_is_access_type(): true, + p_accessed_type(): TypeDecl( + f_type_def: ArrayTypeDef(f_indices: UnconstrainedArrayIndices))) @check(message="possible occurrence of KP V616-018", impact="22.*") fun kp_v616_018(node) = node is ComponentDecl( - p_semantic_parent() is TypeDecl(f_type_def is DerivedTypeDef), - f_component_def is ComponentDef( - f_type_expr is SubtypeIndication( - f_name is n@Name - when access_to_unconstrained_array(n.p_referenced_decl())) or + p_semantic_parent(): TypeDecl(f_type_def: DerivedTypeDef), + f_component_def: ComponentDef( + f_type_expr: SubtypeIndication( + f_name: n@Name + when access_to_unconstrained_array(n.p_referenced_decl())) | a@AnonymousType when access_to_unconstrained_array(a.f_type_decl) diff --git a/lkql_checker/share/lkql/kp/KP-V624-025.lkql b/lkql_checker/share/lkql/kp/KP-V624-025.lkql index 6f4ba7386..5b62da487 100644 --- a/lkql_checker/share/lkql/kp/KP-V624-025.lkql +++ b/lkql_checker/share/lkql/kp/KP-V624-025.lkql @@ -10,7 +10,7 @@ fun kp_v624_025(node) = when node.f_attribute.p_name_is("Valid_Scalars") and node.f_prefix.p_expression_type() is t@TypeDecl when t.p_full_view() is TypeDecl( - p_is_record_type() is true, - any stdlib.component_types is t@TypeDecl(p_is_private() is true) + p_is_record_type(): true, + any stdlib.component_types: t@TypeDecl(p_is_private(): true) when stdlib.full_root_type(t) is TypeDecl( - f_type_def is SignedIntTypeDef)) + f_type_def: SignedIntTypeDef)) diff --git a/lkql_checker/share/lkql/kp/KP-V708-029.lkql b/lkql_checker/share/lkql/kp/KP-V708-029.lkql index 3a7c44f13..ed00afac5 100644 --- a/lkql_checker/share/lkql/kp/KP-V708-029.lkql +++ b/lkql_checker/share/lkql/kp/KP-V708-029.lkql @@ -7,6 +7,6 @@ fun kp_v708_029(node) = when node.f_attribute.p_name_is("Image") and match node.f_prefix.p_referenced_decl() | t@BaseTypeDecl => not t.p_is_discrete_type() - | o@(ObjectDecl or ParamSpec) => + | o@(ObjectDecl | ParamSpec) => not o.f_type_expr.p_designated_type_decl().p_is_discrete_type() | * => not node.p_expression_type().p_is_discrete_type() diff --git a/lkql_checker/share/lkql/kp/KP-V712-039.lkql b/lkql_checker/share/lkql/kp/KP-V712-039.lkql index 4a797a087..899645793 100644 --- a/lkql_checker/share/lkql/kp/KP-V712-039.lkql +++ b/lkql_checker/share/lkql/kp/KP-V712-039.lkql @@ -6,10 +6,10 @@ import stdlib @check(message="possible occurrence of KP V712-039", impact="22.*") fun kp_v712_039(node) = node is ForLoopStmt( - f_spec is ForLoopSpec(f_iter_expr is Expr( - p_expression_type() is TypeDecl( - p_has_aspect("Iterable") is true, - p_full_view() is TypeDecl( - any stdlib.component_types is TypeDecl( - p_has_aspect("Default_Initial_Condition") is true)))))) + f_spec: ForLoopSpec(f_iter_expr: Expr( + p_expression_type(): TypeDecl( + p_has_aspect("Iterable"): true, + p_full_view(): TypeDecl( + any stdlib.component_types: TypeDecl( + p_has_aspect("Default_Initial_Condition"): true)))))) diff --git a/lkql_checker/share/lkql/kp/KP-V719-024.lkql b/lkql_checker/share/lkql/kp/KP-V719-024.lkql index 2b6526ac7..0cc52ac5e 100644 --- a/lkql_checker/share/lkql/kp/KP-V719-024.lkql +++ b/lkql_checker/share/lkql/kp/KP-V719-024.lkql @@ -4,9 +4,9 @@ @check(message="possible occurrence of KP V719-024", impact="22.*") fun kp_v719_024(node) = # Look for record types with discriminants and a Dynamic_Predicate aspect - node is TypeDecl(f_discriminants is not null, - f_type_def is def@RecordTypeDef, - p_has_aspect("Dynamic_Predicate") is true) + node is TypeDecl(f_discriminants: not null, + f_type_def: def@RecordTypeDef, + p_has_aspect("Dynamic_Predicate"): true) # containing a variant part with an "others" choice when (from def.f_record_def.f_components select first part@VariantPart diff --git a/lkql_checker/share/lkql/kp/KP-V720-003.lkql b/lkql_checker/share/lkql/kp/KP-V720-003.lkql index 2099c6a76..66dbb2497 100644 --- a/lkql_checker/share/lkql/kp/KP-V720-003.lkql +++ b/lkql_checker/share/lkql/kp/KP-V720-003.lkql @@ -9,8 +9,8 @@ fun has_initialize_scalars(unit) = message="possible occurrence of KP V720-003 if -gnatVo and -gnateA are used", impact="22.*") fun kp_v720_003(node) = - node is AssocList(parent is call@CallExpr(p_is_call() is true)) + node is AssocList(parent: call@CallExpr(p_is_call(): true)) when has_initialize_scalars(node.p_enclosing_compilation_unit()) and node.children_count >= 2 and [p for p in call.p_call_params() - if p.param.parent.parent is ParamSpec(f_mode is ModeOut or ModeInOut)] + if p.param.parent.parent is ParamSpec(f_mode: ModeOut | ModeInOut)] diff --git a/lkql_checker/share/lkql/kp/KP-V907-005.lkql b/lkql_checker/share/lkql/kp/KP-V907-005.lkql index b2c6c630c..bd610dbd8 100644 --- a/lkql_checker/share/lkql/kp/KP-V907-005.lkql +++ b/lkql_checker/share/lkql/kp/KP-V907-005.lkql @@ -6,10 +6,10 @@ impact="22.*") fun kp_v907_005(node) = node is BaseLoopStmt( - any parent is BaseLoopStmt, - any children is AssignStmt(f_dest is c@CallExpr + any parent: BaseLoopStmt, + any children: AssignStmt(f_dest: c@CallExpr when c.p_kind() == "array_index" and [p for p in c.f_suffix.children if not p.f_r_expr is - Expr(p_is_static_expr() is true) or - Identifier(p_referenced_decl() is ForLoopVarDecl])) + (Expr(p_is_static_expr(): true) | + Identifier(p_referenced_decl(): ForLoopVarDecl))])) diff --git a/lkql_checker/share/lkql/kp/KP-V924-001.lkql b/lkql_checker/share/lkql/kp/KP-V924-001.lkql index 6840dc4a0..f8ab5a524 100644 --- a/lkql_checker/share/lkql/kp/KP-V924-001.lkql +++ b/lkql_checker/share/lkql/kp/KP-V924-001.lkql @@ -3,5 +3,5 @@ @check(help="possible occurrence of KP V924-001", impact="22.*", message="possible occurrence of KP V924-001 if -gnatVo is used") fun kp_v924_001(node) = - node is (ProtectedTypeDecl or SingleProtectedDecl) + node is (ProtectedTypeDecl | SingleProtectedDecl) when node.p_has_aspect("Lock_Free") diff --git a/lkql_checker/share/lkql/kp/KP-VA03-035.lkql b/lkql_checker/share/lkql/kp/KP-VA03-035.lkql index c49a0ddbf..408666c45 100644 --- a/lkql_checker/share/lkql/kp/KP-VA03-035.lkql +++ b/lkql_checker/share/lkql/kp/KP-VA03-035.lkql @@ -4,7 +4,7 @@ @check(message="possible occurrence of KP VA03-035", impact="22.*") fun kp_va03_035(node) = node is SubpBody - when node.p_decl_part() is BasicDecl(p_semantic_parent() is - BasicDecl(p_has_aspect("Lock_Free") is true)) + when node.p_decl_part() is BasicDecl(p_semantic_parent(): + BasicDecl(p_has_aspect("Lock_Free"): true)) and (from node select first - DottedName(p_referenced_decl() is ObjectDecl)) != null + DottedName(p_referenced_decl(): ObjectDecl)) != null diff --git a/lkql_checker/share/lkql/kp/KP-VA06-034.lkql b/lkql_checker/share/lkql/kp/KP-VA06-034.lkql index 1354d5590..a0e6c9048 100644 --- a/lkql_checker/share/lkql/kp/KP-VA06-034.lkql +++ b/lkql_checker/share/lkql/kp/KP-VA06-034.lkql @@ -3,8 +3,8 @@ @check(message="possible occurrence of KP VA06-034", impact="22.*") fun kp_va06_034(node) = - node is AttributeRef(parent is c@CallExpr) + node is AttributeRef(parent: c@CallExpr) when node.f_attribute.p_name_is("Image") and node.f_prefix.p_referenced_decl() is - TypeDecl(p_has_aspect("Put_Image") is true) + TypeDecl(p_has_aspect("Put_Image"): true) and c.f_suffix[1].f_r_expr.p_is_static_expr() diff --git a/lkql_checker/share/lkql/kp/KP-VA18-003.lkql b/lkql_checker/share/lkql/kp/KP-VA18-003.lkql index 6558dd958..459d0bf62 100644 --- a/lkql_checker/share/lkql/kp/KP-VA18-003.lkql +++ b/lkql_checker/share/lkql/kp/KP-VA18-003.lkql @@ -5,8 +5,8 @@ message="possible occurrence of KP VA18-003 if No_Tag is passed", impact="21.*,22.*") fun kp_va18_003(node) = - node is CallExpr(f_suffix is l@AssocList, - p_referenced_decl() is decl@SubpDecl) + node is CallExpr(f_suffix: l@AssocList, + p_referenced_decl(): decl@SubpDecl) when (match decl.p_canonical_fully_qualified_name() | "^ada\.tags\.descendant_tag$" => true | "^ada\.tags\.interface_ancestor_tags$" => true @@ -15,6 +15,6 @@ fun kp_va18_003(node) = # check all parameters of type Tag and [a for a in l.children if a.f_r_expr is not - AttributeRef(f_attribute is - Identifier(p_name_is("Tag") is true) and + AttributeRef(f_attribute: + Identifier(p_name_is("Tag"): true) and a.f_r_expr.p_expression_type().p_relative_name().p_name_is("Tag")] diff --git a/lkql_checker/share/lkql/kp/KP-VB20-002.lkql b/lkql_checker/share/lkql/kp/KP-VB20-002.lkql index 44f2ff52b..54e988529 100644 --- a/lkql_checker/share/lkql/kp/KP-VB20-002.lkql +++ b/lkql_checker/share/lkql/kp/KP-VB20-002.lkql @@ -4,7 +4,7 @@ import stdlib fun sso_array_type(typ) = - typ is BaseTypeDecl(p_is_array_type() is true) + typ is BaseTypeDecl(p_is_array_type(): true) and stdlib.has_non_default_sso(typ) @check(help="possible occurrence of KP VB20-002", impact="22.*", diff --git a/lkql_checker/share/lkql/kp/KP-VB24-008.lkql b/lkql_checker/share/lkql/kp/KP-VB24-008.lkql index c63aaf823..f81a69633 100644 --- a/lkql_checker/share/lkql/kp/KP-VB24-008.lkql +++ b/lkql_checker/share/lkql/kp/KP-VB24-008.lkql @@ -3,10 +3,10 @@ @check(message="possible occurrence of KP VB24-008", impact="23.*") fun kp_vb24_008(node) = - node is AspectAssoc(f_id is Name(p_name_is("Post") is true)) + node is AspectAssoc(f_id: Name(p_name_is("Post"): true)) when (from node.f_expr select first - AttributeRef(f_attribute is Identifier(p_name_is("Old") is true))) != null + AttributeRef(f_attribute: Identifier(p_name_is("Old"): true))) != null and (from node.f_expr select first - op@BinOp(f_op is OpEq or OpNeq) + op@BinOp(f_op: OpEq | OpNeq) when op.f_left is NullLiteral or op.f_right is NullLiteral) != null diff --git a/lkql_checker/share/lkql/kp/KP-W330-020.lkql b/lkql_checker/share/lkql/kp/KP-W330-020.lkql index 681a20250..09807b07e 100644 --- a/lkql_checker/share/lkql/kp/KP-W330-020.lkql +++ b/lkql_checker/share/lkql/kp/KP-W330-020.lkql @@ -3,7 +3,7 @@ @check(message="possible occurrence of KP W330-020", impact="20.*,21.*,22.*,23.1") fun kp_w330_020(node) = node is AttributeRef( - f_attribute is Identifier(p_name_is("Address") is true), - f_prefix is Name(p_referenced_defining_name() is DefiningName( - p_basic_decl() is ObjectDecl, - p_has_aspect("Size") is true))) + f_attribute: Identifier(p_name_is("Address"): true), + f_prefix: Name(p_referenced_defining_name(): DefiningName( + p_basic_decl(): ObjectDecl, + p_has_aspect("Size"): true))) diff --git a/lkql_checker/share/lkql/library_level_subprograms.lkql b/lkql_checker/share/lkql/library_level_subprograms.lkql index 0c56c8422..f41d75807 100644 --- a/lkql_checker/share/lkql/library_level_subprograms.lkql +++ b/lkql_checker/share/lkql/library_level_subprograms.lkql @@ -3,5 +3,5 @@ @check(message="declaration of library level subprogram", category="Feature") fun library_level_subprograms(node) = - node is (BaseSubpBody or GenericSubpInstantiation) + node is (BaseSubpBody | GenericSubpInstantiation) when node.parent is LibraryItem diff --git a/lkql_checker/share/lkql/local_instantiations.lkql b/lkql_checker/share/lkql/local_instantiations.lkql index 0a634be3a..4bd77406b 100644 --- a/lkql_checker/share/lkql/local_instantiations.lkql +++ b/lkql_checker/share/lkql/local_instantiations.lkql @@ -7,8 +7,8 @@ import stdlib @check(message="local instantiation", category="Style", subcategory="Programming Practice") fun local_instantiations(node, packages=[]) = - node is (GenericPackageInstantiation(f_generic_pkg_name is name@Name) or - GenericSubpInstantiation(f_generic_subp_name is name@Name)) + node is (GenericPackageInstantiation(f_generic_pkg_name: name@Name) | + GenericSubpInstantiation(f_generic_subp_name: name@Name)) when stdlib.has_local_scope(node) and (packages == [] or { val full_name = name.p_referenced_decl()?. diff --git a/lkql_checker/share/lkql/local_packages.lkql b/lkql_checker/share/lkql/local_packages.lkql index fd6fc1372..66f864a7d 100644 --- a/lkql_checker/share/lkql/local_packages.lkql +++ b/lkql_checker/share/lkql/local_packages.lkql @@ -4,5 +4,5 @@ @check(message="declaration of local package", category="Style", subcategory="Program Structure") fun local_packages(node) = - node is PackageDecl(any parent is PackageDecl or GenericPackageDecl) - and not node is *(any parent is PackageBody) + node is PackageDecl(any parent: PackageDecl | GenericPackageDecl) + and not node is *(any parent: PackageBody) diff --git a/lkql_checker/share/lkql/max_identifier_length.lkql b/lkql_checker/share/lkql/max_identifier_length.lkql index 8af03f286..f30fe1fb9 100644 --- a/lkql_checker/share/lkql/max_identifier_length.lkql +++ b/lkql_checker/share/lkql/max_identifier_length.lkql @@ -7,7 +7,7 @@ help="maximal identifier length", remediation="EASY", category="Style", subcategory="Readability") fun max_identifier_length(node, n: int = 20) = - node is DefiningName(parent is not EnumLiteralDecl) + node is DefiningName(parent: not EnumLiteralDecl) when (if node.f_name is DottedName then node.f_name.f_suffix else node.f_name).text.length > n diff --git a/lkql_checker/share/lkql/maximum_expression_complexity.lkql b/lkql_checker/share/lkql/maximum_expression_complexity.lkql index f88a1d2e0..1b2b462f0 100644 --- a/lkql_checker/share/lkql/maximum_expression_complexity.lkql +++ b/lkql_checker/share/lkql/maximum_expression_complexity.lkql @@ -10,8 +10,8 @@ fun num_expr(node) = |" Return the number of relevant expressions as defined above of a given |" node. - (from node select (e@SingleTokNode when e is not Op) or CondExpr or - QuantifiedExpr or BaseAggregate or TargetName).length + (from node select ((e@SingleTokNode when e is not Op) | CondExpr | + QuantifiedExpr | BaseAggregate | TargetName)).length @unit_check(help="maximum complexity of an expression", category="Style", subcategory="Program Structure") @@ -23,6 +23,6 @@ fun maximum_expression_complexity(unit, n: int = 10) = [ # slow down this rule significantly and checking one level is good enough # in practice. # Exclude standalone identifiers which are not expressions per se. - expr@Expr(parent is not Expr) - when expr is not (Identifier or DefiningName or EndName) + expr@Expr(parent: not Expr) + when expr is not (Identifier | DefiningName | EndName) and num_expr(expr) > n] diff --git a/lkql_checker/share/lkql/maximum_out_parameters.lkql b/lkql_checker/share/lkql/maximum_out_parameters.lkql index b2a55b83d..a38af64da 100644 --- a/lkql_checker/share/lkql/maximum_out_parameters.lkql +++ b/lkql_checker/share/lkql/maximum_out_parameters.lkql @@ -12,7 +12,7 @@ fun num_out_params(node) = |" Return the number of out parameters of a subprogram node (from node.f_subp_spec?.f_subp_params?.f_params select n@DefiningName - when n.parent.parent.f_mode is (ModeOut or ModeInOut)).length + when n.parent.parent.f_mode is (ModeOut | ModeInOut)).length @unit_check(help="maximum number of subprogram OUT parameters", category="Style", subcategory="Programming Practice") @@ -20,7 +20,7 @@ fun maximum_out_parameters(unit, n: int = 3) = [ {message: "too many formal OUT parameters (" & img(num_out_params(n)) & ")", loc: n.p_defining_name()} for n in from unit.root select - node@(SubpBody or ExprFunction or NullSubpDecl or SubpBodyStub or + node@(SubpBody | ExprFunction | NullSubpDecl | SubpBodyStub | ClassicSubpDecl) when (node is ClassicSubpDecl or not node.p_previous_part()) and num_out_params(node) > n] diff --git a/lkql_checker/share/lkql/maximum_parameters.lkql b/lkql_checker/share/lkql/maximum_parameters.lkql index 7953be25b..8dbde3c59 100644 --- a/lkql_checker/share/lkql/maximum_parameters.lkql +++ b/lkql_checker/share/lkql/maximum_parameters.lkql @@ -18,8 +18,8 @@ fun maximum_parameters(unit, n: int = 3) = [ {message: "too many formal parameters (" & img(num_params(n)) & ")", loc: n.p_defining_name()} for n in from unit.root select - node@(SubpBody or ExprFunction or NullSubpDecl or SubpBodyStub or - ClassicSubpDecl or GenericSubpInternal) - when (node is (ClassicSubpDecl or GenericSubpInternal) or + node@(SubpBody | ExprFunction | NullSubpDecl | SubpBodyStub | + ClassicSubpDecl | GenericSubpInternal) + when (node is (ClassicSubpDecl | GenericSubpInternal) or node.p_previous_part() == null) and num_params(node) > n] diff --git a/lkql_checker/share/lkql/maximum_subprogram_lines.lkql b/lkql_checker/share/lkql/maximum_subprogram_lines.lkql index 7983ee16a..63cea5875 100644 --- a/lkql_checker/share/lkql/maximum_subprogram_lines.lkql +++ b/lkql_checker/share/lkql/maximum_subprogram_lines.lkql @@ -11,5 +11,5 @@ fun maximum_subprogram_lines(unit, n: int = 1000) = [ {message: "too many lines in subprogram body: " & img(count_lines(n)), loc: n.token_start().previous(exclude_trivia=true)} for n in from unit.root - select node@HandledStmts(parent is SubpBody) when count_lines(node) > n + select node@HandledStmts(parent: SubpBody) when count_lines(node) > n ] diff --git a/lkql_checker/share/lkql/membership_for_validity.lkql b/lkql_checker/share/lkql/membership_for_validity.lkql index bee2e7876..00d74446e 100644 --- a/lkql_checker/share/lkql/membership_for_validity.lkql +++ b/lkql_checker/share/lkql/membership_for_validity.lkql @@ -4,24 +4,24 @@ fun type_of(name) = match name.p_referenced_decl() - | BasicDecl(p_type_expression() is t@TypeExpr) => t.p_designated_type_decl() + | BasicDecl(p_type_expression(): t@TypeExpr) => t.p_designated_type_decl() | * => null @check(message="membership test instead of 'Valid", category="Style", subcategory="Portability") fun membership_for_validity(node) = - node is MembershipExpr(f_expr is var@Name) + node is MembershipExpr(f_expr: var@Name) when not node.f_membership_exprs[2] and node.f_membership_exprs[1] is - (typ@Name when type_of(var) == typ.p_referenced_decl()) or - bin_op@BinOp(f_op is OpDoubleDot, - f_left is at1@AttributeRef(f_prefix is typ1@*) + ((typ@Name when type_of(var) == typ.p_referenced_decl()) | + bin_op@BinOp(f_op: OpDoubleDot, + f_left: at1@AttributeRef(f_prefix: typ1) when at1.f_attribute.p_name_is("First") and at1.f_prefix is Name, - f_right is at2@AttributeRef(f_prefix is typ2@*) + f_right: at2@AttributeRef(f_prefix: typ2) when at2.f_attribute.p_name_is("Last") and at2.f_prefix is Name) when ( typ1.p_referenced_decl() == typ2.p_referenced_decl() and type_of(var) == typ1.p_referenced_decl() - ) + )) diff --git a/lkql_checker/share/lkql/metrics.lkql b/lkql_checker/share/lkql/metrics.lkql index b2583a1b0..304e4ddb0 100644 --- a/lkql_checker/share/lkql/metrics.lkql +++ b/lkql_checker/share/lkql/metrics.lkql @@ -6,10 +6,10 @@ selector eligible_children | BodyNode => # Don't recurse on bodies except if it's the root node (depth == 0) - rec *(if depth == 0 then this.children else []) + rec(*if depth == 0 then this.children else []) | n@PragmaNode when n.p_is_ghost_code() => () | null => () - | * => rec *this.children + | * => rec(*this.children) fun parent_quantified_expr(s) = |" Helper: All quantified expressions containing ``s`` @@ -19,8 +19,8 @@ fun expr_complexity(body, exempt_case=false) = |" Return the cyclomatic complexity of expressions in the given body { fun node_weight (n) = match n - | BinOp(f_op is OpOrElse or OpAndThen) or IfExpr or ElsifExprPart => 1 - | CaseExpr(f_cases is c@*) => if exempt_case then 1 else c.children_count - 1 + | (BinOp(f_op: OpOrElse | OpAndThen) | IfExpr | ElsifExprPart) => 1 + | CaseExpr(f_cases: c) => if exempt_case then 1 else c.children_count - 1 | QuantifiedExpr => 2 | * => 0; @@ -29,18 +29,18 @@ fun expr_complexity(body, exempt_case=false) = 0) } -fun statement_complexity(body, exempt_case=false) = +fun statement_complexity(body, exempt_case=false) = |" Return the cyclomatic complexity of statements in the given body { fun node_weight (n) = match n - | IfStmt or ElsifStmtPart or WhileLoopSpec => 1 + | (IfStmt | ElsifStmtPart | WhileLoopSpec) => 1 | f@ForLoopSpec when not parent_quantified_expr(f) => 1 | c@CaseStmt => if exempt_case then 1 else c.f_alternatives.children_count - 1 - | e@ExitStmt(f_cond_expr is not null) => 1 + | e@ExitStmt(f_cond_expr: not null) => 1 | s@SelectStmt( - f_guards is guards@*, - f_else_stmts is elses_stmts@*, - f_abort_stmts is abort_stmts@* + f_guards: guards, + f_else_stmts: elses_stmts, + f_abort_stmts: abort_stmts ) => guards.children_count + (if elses_stmts.children_count == 0 then 0 else 1) + (if abort_stmts.children_count == 0 then 0 else 1) @@ -51,7 +51,7 @@ fun statement_complexity(body, exempt_case=false) = (comp, node) => comp + node_weight(node), 1 ) -} +} fun cyclomatic_complexity(body, exempt_case=false) = |" Return the cyclomatic complexity for the given body @@ -60,25 +60,25 @@ fun cyclomatic_complexity(body, exempt_case=false) = selector composite_parents |" Return a list of composite statement parents, stopping at the enclosing |" declaration. - | *(parent is CaseStmt or IfStmt or ForLoopStmt - or LoopStmt or WhileLoopStmt or SelectStmt) => rec this.parent + | *(parent: CaseStmt | IfStmt | ForLoopStmt + | LoopStmt | WhileLoopStmt | SelectStmt) => rec(this.parent) # Stop exploring downwards when we get out of the current decl - | BasicDecl => () + | BasicDecl => () # Skip every other node - | * => skip this.parent + | * => rec(this.parent, ()) # TODO: There might be a way to build on top of ``composite_parents``, rt. # duplicating it selector composite_parents_stop_at_loop |" Return a list of composite statement parents, stopping at the enclosing |" declaration or at the enclosing loop. - | *(parent is ForLoopStmt or LoopStmt or WhileLoopStmt) => this.parent - | *(parent is CaseStmt or IfStmt or SelectStmt) => rec this.parent + | *(parent: ForLoopStmt | LoopStmt | WhileLoopStmt) => rec((), this.parent) + | *(parent: CaseStmt | IfStmt | SelectStmt) => rec(this.parent) # Stop exploring downwards when we get out of the current decl - | BasicDecl => () - | * => skip this.parent + | BasicDecl => () + | * => rec(this.parent, ()) fun essential_complexity(body, treat_exit_as_goto=true) = @@ -86,11 +86,11 @@ fun essential_complexity(body, treat_exit_as_goto=true) = { val jump_nodes = [ i for i in stdlib.children_no_nested(body) - if i is ReturnStmt or RaiseStmt or TerminateAlternative or GotoStmt - or (ExitStmt when treat_exit_as_goto) + if i is (ReturnStmt | RaiseStmt | TerminateAlternative | GotoStmt + | (ExitStmt when treat_exit_as_goto)) ]; - val to_count_nodes = + val to_count_nodes = if not jump_nodes then [] else reduce( jump_nodes, @@ -110,15 +110,15 @@ fun logical_slocs (node) = { # TODO: And pattern - val nodes = (from node select ( - s@Stmt when s is not (Label or TerminateAlternative or NamedStmt) - ) or ( - b@(BasicDecl or EntryIndexSpec) when b is not ( - GenericFormal or GenericPackageInternal or AnonymousTypeDecl - or NamedStmtDecl or LabelDecl or SingleTaskTypeDecl - or GenericSubpInternal or ExceptionHandler + val nodes = (from node select (( + s@Stmt when s is not (Label | TerminateAlternative | NamedStmt) + ) | ( + b@(BasicDecl | EntryIndexSpec) when b is not ( + GenericFormal | GenericPackageInternal | AnonymousTypeDecl + | NamedStmtDecl | LabelDecl | SingleTaskTypeDecl + | GenericSubpInternal | ExceptionHandler ) - ) or ExceptionHandler(f_exception_name is not null)); + ) | ExceptionHandler(f_exception_name: not null))); nodes.length } diff --git a/lkql_checker/share/lkql/metrics_cyclomatic_complexity.lkql b/lkql_checker/share/lkql/metrics_cyclomatic_complexity.lkql index 6c2ed3ade..de402bab2 100644 --- a/lkql_checker/share/lkql/metrics_cyclomatic_complexity.lkql +++ b/lkql_checker/share/lkql/metrics_cyclomatic_complexity.lkql @@ -11,7 +11,7 @@ fun metrics_cyclomatic_complexity(unit, n : int = 5, { message: "cyclomatic complexity is too high: " & img(t[2]), loc: t[1] } for t in [(body, metrics.cyclomatic_complexity(body, exempt_case_statements)) for body in (from unit.root select - BaseSubpBody or PackageBody or TaskBody or EntryBody)] + (BaseSubpBody | PackageBody | TaskBody | EntryBody))] if t[2] > n ] diff --git a/lkql_checker/share/lkql/metrics_lsloc.lkql b/lkql_checker/share/lkql/metrics_lsloc.lkql index 85a837ddd..d4f7fbb31 100644 --- a/lkql_checker/share/lkql/metrics_lsloc.lkql +++ b/lkql_checker/share/lkql/metrics_lsloc.lkql @@ -15,10 +15,10 @@ fun metrics_lsloc(unit, n : int = 5, subprograms=false) = { if subprograms then (from unit.root select BaseSubpBody) else (from unit.root select - GenericPackageDecl or PackageDecl or PackageBody or - BaseSubpBody or - TaskTypeDecl or SingleTaskDecl or TaskBody or - SingleProtectedDecl or ProtectedTypeDecl or ProtectedBody); + (GenericPackageDecl | PackageDecl | PackageBody | + BaseSubpBody | + TaskTypeDecl | SingleTaskDecl | TaskBody | + SingleProtectedDecl | ProtectedTypeDecl | ProtectedBody)); [ { message: "LSLOC is too high: " & img(t[2]), loc: t[1] } diff --git a/lkql_checker/share/lkql/min_identifier_length.lkql b/lkql_checker/share/lkql/min_identifier_length.lkql index 9eb82c90a..9a48dba8d 100644 --- a/lkql_checker/share/lkql/min_identifier_length.lkql +++ b/lkql_checker/share/lkql/min_identifier_length.lkql @@ -6,6 +6,6 @@ fun min_identifier_length(node, n: int = 2) = node is DefiningName when node.text.length < n - and node.p_basic_decl()?.p_type_expression() is null or - TypeExpr(p_designated_type_decl() is t@BaseTypeDecl - when not (t.p_is_int_type() or t.p_is_real_type())) + and node.p_basic_decl()?.p_type_expression() is (null | + TypeExpr(p_designated_type_decl(): t@BaseTypeDecl + when not (t.p_is_int_type() or t.p_is_real_type()))) diff --git a/lkql_checker/share/lkql/misnamed_controlling_parameters.lkql b/lkql_checker/share/lkql/misnamed_controlling_parameters.lkql index 65d6058be..3cd0e4168 100644 --- a/lkql_checker/share/lkql/misnamed_controlling_parameters.lkql +++ b/lkql_checker/share/lkql/misnamed_controlling_parameters.lkql @@ -11,12 +11,12 @@ import stdlib @check(message="first parameter should have name 'This' and proper type", remediation="EASY", category="Style", subcategory="Readability") fun misnamed_controlling_parameters(node) = - node is (BasicSubpDecl or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) + node is (BasicSubpDecl | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) # Get subprogram declarations that are primitive of a tagged type when node.p_subp_spec_or_null() is - spec@BaseSubpSpec(p_primitive_subp_tagged_type() is BaseTypeDecl) + spec@BaseSubpSpec(p_primitive_subp_tagged_type(): BaseTypeDecl) when { val params = spec.p_params(); params and not diff --git a/lkql_checker/share/lkql/misplaced_representation_items.lkql b/lkql_checker/share/lkql/misplaced_representation_items.lkql index 651e02459..f6b8d7b7c 100644 --- a/lkql_checker/share/lkql/misplaced_representation_items.lkql +++ b/lkql_checker/share/lkql/misplaced_representation_items.lkql @@ -34,7 +34,7 @@ fun associated_decl(pragma_node) = fun misplaced_node(n, decl) = match n.previous_sibling() | d@BasicDecl => d != decl - | a@AttributeDefClause(f_attribute_expr is AttributeRef) => + | a@AttributeDefClause(f_attribute_expr: AttributeRef) => a.f_attribute_expr.f_prefix.p_referenced_decl() != decl or misplaced_node(a, decl) | e@EnumRepClause => e.f_type_name.p_referenced_decl() != decl or @@ -52,7 +52,7 @@ fun misplaced_node(n, decl) = category="Style", subcategory="Programming Practice") fun misplaced_representation_items(node) = match node - | AttributeDefClause(f_attribute_expr is AttributeRef) => + | AttributeDefClause(f_attribute_expr: AttributeRef) => misplaced_node(node, node.f_attribute_expr.f_prefix.p_referenced_decl()) | EnumRepClause => diff --git a/lkql_checker/share/lkql/multiple_entries_in_protected_definitions.lkql b/lkql_checker/share/lkql/multiple_entries_in_protected_definitions.lkql index fb1121603..358b0d64a 100644 --- a/lkql_checker/share/lkql/multiple_entries_in_protected_definitions.lkql +++ b/lkql_checker/share/lkql/multiple_entries_in_protected_definitions.lkql @@ -7,4 +7,4 @@ @check(message="more than one entry in protected definition", category="Style", subcategory="Tasking") fun multiple_entries_in_protected_definitions(node) = - node is EntryDecl(any prev_siblings is EntryDecl) + node is EntryDecl(any prev_siblings: EntryDecl) diff --git a/lkql_checker/share/lkql/nested_paths.lkql b/lkql_checker/share/lkql/nested_paths.lkql index aeda5ba0c..01f167caf 100644 --- a/lkql_checker/share/lkql/nested_paths.lkql +++ b/lkql_checker/share/lkql/nested_paths.lkql @@ -7,7 +7,7 @@ fun has_last_breaking_stmt(list) = match list[list.children_count] - | RaiseStmt or ReturnStmt or ExitStmt(f_cond_expr is null) or GotoStmt => true + | (RaiseStmt | ReturnStmt | ExitStmt(f_cond_expr: null) | GotoStmt) => true | b@BlockStmt => b.f_stmts.f_exceptions[1] == null and has_last_breaking_stmt(b.f_stmts.f_stmts) | * => false @@ -15,7 +15,7 @@ fun has_last_breaking_stmt(list) = @check(message="nested path may be moved outside if statement", category="Style", subcategory="Programming Practice") fun nested_paths(node) = - node is StmtList(parent is if_stmt@IfStmt) + node is StmtList(parent: if_stmt@IfStmt) when if_stmt.f_alternatives[1] == null and if_stmt.f_else_stmts[1] != null and not has_last_breaking_stmt(node) diff --git a/lkql_checker/share/lkql/nested_subprograms.lkql b/lkql_checker/share/lkql/nested_subprograms.lkql index 55dcb0cf6..9020197a5 100644 --- a/lkql_checker/share/lkql/nested_subprograms.lkql +++ b/lkql_checker/share/lkql/nested_subprograms.lkql @@ -12,11 +12,11 @@ import stdlib @check(message="subprogram declared in executable body", category="Style", subcategory="Programming Practice") fun nested_subprograms(node) = - node is (SubpBody or ExprFunction or SubpBodyStub or BasicSubpDecl or + node is (SubpBody | ExprFunction | SubpBodyStub | BasicSubpDecl | GenericSubpInstantiation) - when (node is (BasicSubpDecl or GenericSubpInstantiation) or - node.p_previous_part() is null or SubpBodyStub) + when (node is (BasicSubpDecl | GenericSubpInstantiation) or + node.p_previous_part() is (null | SubpBodyStub)) and node.p_semantic_parent() - is not (ProtectedTypeDecl or SingleProtectedDecl) - and node is not ClassicSubpDecl(p_body_part() is NullSubpDecl) - and node is *(any stdlib.semantic_parent is BaseSubpBody or TaskBody or EntryBody) + is not (ProtectedTypeDecl | SingleProtectedDecl) + and node is not ClassicSubpDecl(p_body_part(): NullSubpDecl) + and node is *(any stdlib.semantic_parent: BaseSubpBody | TaskBody | EntryBody) diff --git a/lkql_checker/share/lkql/no_closing_names.lkql b/lkql_checker/share/lkql/no_closing_names.lkql index 5bf655bc7..069ad3ba7 100644 --- a/lkql_checker/share/lkql/no_closing_names.lkql +++ b/lkql_checker/share/lkql/no_closing_names.lkql @@ -4,11 +4,11 @@ @check(message="no closing name", remediation="TRIVIAL", category="Style", subcategory="Programming Practice") fun no_closing_names(node, n : int = 0) = - node is SubpBody or PackageBody or BasePackageDecl or - TaskTypeDecl or TaskBody or - ProtectedTypeDecl or SingleProtectedDecl or ProtectedBody + node is (SubpBody | PackageBody | BasePackageDecl | + TaskTypeDecl | TaskBody | + ProtectedTypeDecl | SingleProtectedDecl | ProtectedBody) and node.token_end().end_line - node.token_start().start_line >= n and match node - | TaskTypeDecl or ProtectedTypeDecl or SingleProtectedDecl + | (TaskTypeDecl | ProtectedTypeDecl | SingleProtectedDecl) => node.f_definition.f_end_name == null | * => node.f_end_name == null diff --git a/lkql_checker/share/lkql/no_explicit_real_range.lkql b/lkql_checker/share/lkql/no_explicit_real_range.lkql index e5134dd1d..e5f23cb7b 100644 --- a/lkql_checker/share/lkql/no_explicit_real_range.lkql +++ b/lkql_checker/share/lkql/no_explicit_real_range.lkql @@ -4,16 +4,16 @@ fun is_real_without_range(decl) = decl is - (TypeDecl + ((TypeDecl when decl.f_type_def is - RealTypeDef(f_range is null) or + (RealTypeDef(f_range: null) | d@DerivedTypeDef when not (from d.f_subtype_indication.f_constraint select first RangeSpec) - and is_real_without_range(decl.p_base_type())) - or SubtypeDecl + and is_real_without_range(decl.p_base_type()))) + | SubtypeDecl when not (from decl.f_subtype.f_constraint select first RangeSpec) - and is_real_without_range(decl.p_base_subtype()) + and is_real_without_range(decl.p_base_subtype())) @check(message="real type with no range definition", category="Style", subcategory="Portability") diff --git a/lkql_checker/share/lkql/no_inherited_classwide_pre.lkql b/lkql_checker/share/lkql/no_inherited_classwide_pre.lkql index aca0b64ff..814602b6d 100644 --- a/lkql_checker/share/lkql/no_inherited_classwide_pre.lkql +++ b/lkql_checker/share/lkql/no_inherited_classwide_pre.lkql @@ -17,7 +17,7 @@ fun no_inherited_classwide_pre(unit) = [ tok.unit.name.base_name & ":" & img(tok.start_line) & ":" & img(tok.start_column) & ")"}), loc: n.p_defining_name()} - for n in from unit.root select node@(BasicSubpDecl or BaseSubpBody) + for n in from unit.root select node@(BasicSubpDecl | BaseSubpBody) # Get subprogram declarations that are primitive of a tagged type when node.p_subp_spec_or_null()?.p_primitive_subp_tagged_type() and ({ diff --git a/lkql_checker/share/lkql/no_others_in_exception_handlers.lkql b/lkql_checker/share/lkql/no_others_in_exception_handlers.lkql index e4553c93a..13c4ac5f2 100644 --- a/lkql_checker/share/lkql/no_others_in_exception_handlers.lkql +++ b/lkql_checker/share/lkql/no_others_in_exception_handlers.lkql @@ -5,7 +5,7 @@ fun check_others(stmts) = stmts.f_exceptions is AdaNodeList(all children(depth=3) - is not OthersDesignator) + : not OthersDesignator) @unit_check(help="no OTHERS choice in exception handlers", category="Style", subcategory="Programming Practice") @@ -21,9 +21,9 @@ fun no_others_in_exception_handlers(unit, | * => {message: "no OTHERS choice in exception handler", loc: n.f_exceptions.token_start().previous()}) for n in from unit.root select - (node@((TaskBody when task) or (SubpBody when subprogram)) + ((node@((TaskBody when task) | (SubpBody when subprogram)) when not node.f_stmts.f_exceptions[1] or check_others(node.f_stmts)) - or node@HandledStmts + | node@HandledStmts when all_handlers and node.f_exceptions[1] and - check_others(node) + check_others(node)) ] diff --git a/lkql_checker/share/lkql/no_scalar_storage_order_specified.lkql b/lkql_checker/share/lkql/no_scalar_storage_order_specified.lkql index f0fc1dc6b..c68349b4e 100644 --- a/lkql_checker/share/lkql/no_scalar_storage_order_specified.lkql +++ b/lkql_checker/share/lkql/no_scalar_storage_order_specified.lkql @@ -6,7 +6,7 @@ fun non_empty_rep_clause(n) = n.p_get_record_representation_clause() is - RecordRepClause(f_components is *(any children(depth=1) is ComponentClause)) + RecordRepClause(f_components: *(any children(depth=1): ComponentClause)) fun bit_order_image(n) = { val aspect = n.p_get_aspect("Bit_Order"); @@ -22,11 +22,11 @@ fun no_scalar_storage_order_specified(unit) = [ loc: n} for n in from unit.root select node@TypeDecl when (node.f_type_def is - (RecordTypeDef when not node.p_has_aspect("Scalar_Storage_Order")) or + ((RecordTypeDef when not node.p_has_aspect("Scalar_Storage_Order")) | DerivedTypeDef when not (node.p_has_aspect("Scalar_Storage_Order") or [p for p in node.p_base_types() - if p.p_has_aspect("Scalar_Storage_Order")])) + if p.p_has_aspect("Scalar_Storage_Order")]))) and (non_empty_rep_clause(node) or [p for p in node.p_base_types() if non_empty_rep_clause(p)]) ] diff --git a/lkql_checker/share/lkql/non_component_in_barriers.lkql b/lkql_checker/share/lkql/non_component_in_barriers.lkql index 1c0dccca1..4a81808e2 100644 --- a/lkql_checker/share/lkql/non_component_in_barriers.lkql +++ b/lkql_checker/share/lkql/non_component_in_barriers.lkql @@ -13,14 +13,14 @@ fun is_protected_component(id, decl, names) = { fun non_component_in_barriers(unit) = [ {message: "barrier references non component variable", loc: n.f_barrier} for n in from unit.root select node@EntryBody( - any parent is b@ProtectedBody + any parent: b@ProtectedBody when { val names = from b.p_decl_part()?.f_definition?.f_private_part?.f_decls select DefiningName; [id for id in (from node.f_barrier select Identifier) if id.p_referenced_decl() is - ObjectDecl or ParamSpec or - d@ComponentDecl when not is_protected_component(id, d, names)] + (ObjectDecl | ParamSpec | + d@ComponentDecl when not is_protected_component(id, d, names))] } ) ] diff --git a/lkql_checker/share/lkql/non_constant_overlays.lkql b/lkql_checker/share/lkql/non_constant_overlays.lkql index d680e4f7d..5aa69b67e 100644 --- a/lkql_checker/share/lkql/non_constant_overlays.lkql +++ b/lkql_checker/share/lkql/non_constant_overlays.lkql @@ -21,7 +21,7 @@ fun check_non_const_overlay(decl, overlaid) = val overlaid_object = stdlib.ultimate_alias(overlaid.f_prefix); # Check that overlaid is an object or a formal parameter, - overlaid_object is ObjectDecl or ParamSpec and + overlaid_object is (ObjectDecl | ParamSpec) and # that overlaid is constant, not stdlib.is_constant_object(overlaid_object) @@ -33,8 +33,8 @@ fun check_non_const_overlay(decl, overlaid) = # or if overlaid object is not a parameter, it is not marked as # Volatile or (overlaid_object is - not (ParamSpec or - ObjectDecl(parent is GenericFormalObjDecl)) + not (ParamSpec | + ObjectDecl(parent: GenericFormalObjDecl)) and not overlaid_object.p_has_aspect("Volatile")))}) # TODO: customize message: @@ -45,10 +45,10 @@ fun check_non_const_overlay(decl, overlaid) = @check(message="constant object overlays a variable object", category="Style", subcategory="Programming Practice") fun non_constant_overlays(node) = match node - | AspectAssoc(f_id is id@Identifier, any parent(depth=3) is o@ObjectDecl + | AspectAssoc(f_id: id@Identifier, any parent(depth=3): o@ObjectDecl when id.p_name_is("Address") and check_non_const_overlay(o, node.f_expr)) => true - | AttributeDefClause(f_attribute_expr is at@AttributeRef + | AttributeDefClause(f_attribute_expr: at@AttributeRef when at.f_attribute.p_name_is("Address") and check_non_const_overlay(at.f_prefix.p_referenced_decl(), node.f_expr)) => true diff --git a/lkql_checker/share/lkql/non_qualified_aggregates.lkql b/lkql_checker/share/lkql/non_qualified_aggregates.lkql index a68f46ef4..3a7f7be37 100644 --- a/lkql_checker/share/lkql/non_qualified_aggregates.lkql +++ b/lkql_checker/share/lkql/non_qualified_aggregates.lkql @@ -7,7 +7,7 @@ @check(message="aggregate is not a part of a qualified expression", remediation="EASY", category="Feature") fun non_qualified_aggregates(node) = - node is Aggregate(p_expression_type() is not AnonymousTypeDecl, - p_is_subaggregate() is false, - all parent is not (QualExpr or AspectClause or Aggregate( - p_expression_type() is not AnonymousTypeDecl))) + node is Aggregate(p_expression_type(): not AnonymousTypeDecl, + p_is_subaggregate(): false, + all parent: not (QualExpr | AspectClause | Aggregate( + p_expression_type(): not AnonymousTypeDecl))) diff --git a/lkql_checker/share/lkql/non_short_circuit_operators.lkql b/lkql_checker/share/lkql/non_short_circuit_operators.lkql index 202273078..d669c7bc0 100644 --- a/lkql_checker/share/lkql/non_short_circuit_operators.lkql +++ b/lkql_checker/share/lkql/non_short_circuit_operators.lkql @@ -22,11 +22,11 @@ fun operator_image(node) = fun non_short_circuit_operators(unit, except_assertions=false) = [ {message: "use of predefined " & operator_image(n) & " for boolean type", loc: n} - for n in from unit.root select node@(((OpAnd or OpOr) + for n in from unit.root select node@(((OpAnd | OpOr) when stdlib.is_predefined_op(node) and stdlib.is_standard_boolean(node.parent) and stdlib.is_standard_boolean(node.parent?.f_left)) - or CallExpr(p_relative_name() is n@Name + | CallExpr(p_relative_name(): n@Name when n?.p_name_is("\"and\"") or n?.p_name_is("\"or\"")) when stdlib.is_predefined_op(node) and stdlib.is_standard_boolean(node) diff --git a/lkql_checker/share/lkql/non_tagged_derived_types.lkql b/lkql_checker/share/lkql/non_tagged_derived_types.lkql index f0ba767f1..9e1d1e432 100644 --- a/lkql_checker/share/lkql/non_tagged_derived_types.lkql +++ b/lkql_checker/share/lkql/non_tagged_derived_types.lkql @@ -2,5 +2,5 @@ @check(message="derived type that is not a type extension", category="SPARK") fun non_tagged_derived_types(node) = - node is DerivedTypeDef(f_record_extension is null, - f_has_with_private is WithPrivateAbsent) + node is DerivedTypeDef(f_record_extension: null, + f_has_with_private: WithPrivateAbsent) diff --git a/lkql_checker/share/lkql/non_visible_exceptions.lkql b/lkql_checker/share/lkql/non_visible_exceptions.lkql index 9e9b6903e..b5cc9b70d 100644 --- a/lkql_checker/share/lkql/non_visible_exceptions.lkql +++ b/lkql_checker/share/lkql/non_visible_exceptions.lkql @@ -28,22 +28,22 @@ fun non_visible_exceptions(unit) = [ loc: n} for n in from unit.root select # Find exception identifiers part of an ExceptionDecl and not a renaming... - node@(Identifier(parent is DefiningName(parent is DefiningNameList(parent is - e@ExceptionDecl(f_renames is null) + node@(Identifier(parent: DefiningName(parent: DefiningNameList(parent: + e@ExceptionDecl(f_renames: null) # ...declared in a subprogram body, task body or block - when e.p_semantic_parent() is p@(SubpBody or TaskBody or DeclBlock) + when e.p_semantic_parent() is p@(SubpBody | TaskBody | DeclBlock) # with either no exception handler when not p.f_stmts.f_exceptions # or no handler referencing node or "others" or not p.f_stmts.f_exceptions is - AdaNodeList(any children(depth=3) is - OthersDesignator or - (id@(Identifier or DottedName) + AdaNodeList(any children(depth=3): + OthersDesignator | + (id@(Identifier | DottedName) when stdlib.ultimate_exception_alias(id) == e))))) # Find also raise statements in an exception handler of a subprogram body, # task body or block statement - or RaiseStmt(any parent is h@ExceptionHandler - when h.p_semantic_parent() is p@(SubpBody or TaskBody or DeclBlock) + | RaiseStmt(any parent: h@ExceptionHandler + when h.p_semantic_parent() is p@(SubpBody | TaskBody | DeclBlock) when # raises a locally declared exception if node.f_exception_name @@ -51,5 +51,5 @@ fun non_visible_exceptions(unit) = [ == p.f_decls # does not specify an exception name and the enclosing handler # contains a locally declared exception in its choices - else h.f_handled_exceptions is *(any children is id@Identifier + else h.f_handled_exceptions is *(any children: id@Identifier when id.p_referenced_decl()?.p_semantic_parent?() == p)))] diff --git a/lkql_checker/share/lkql/nonoverlay_address_specifications.lkql b/lkql_checker/share/lkql/nonoverlay_address_specifications.lkql index 44ee8090a..f339bee49 100644 --- a/lkql_checker/share/lkql/nonoverlay_address_specifications.lkql +++ b/lkql_checker/share/lkql/nonoverlay_address_specifications.lkql @@ -13,15 +13,15 @@ fun check_nonoverlay(overlaid) = # Check that overlaid does NOT correspond to an object or parameter # specification. stdlib.ultimate_alias(overlaid.f_prefix, false) - is not (ObjectDecl or ParamSpec) + is not (ObjectDecl | ParamSpec) @check(message="nonoverlay address specification", category="Style", subcategory="Programming Practice") fun nonoverlay_address_specifications(node) = node is - (AspectAssoc(f_id is id@Identifier, any parent(depth=3) is ObjectDecl + ((AspectAssoc(f_id: id@Identifier, any parent(depth=3): ObjectDecl when id.p_name_is("address") and check_nonoverlay (node.f_expr))) - or AttributeDefClause(f_attribute_expr is at@AttributeRef + | AttributeDefClause(f_attribute_expr: at@AttributeRef when at.f_attribute.p_name_is("address") and at.f_prefix.p_referenced_decl() is ObjectDecl - and check_nonoverlay(node.f_expr)) + and check_nonoverlay(node.f_expr))) diff --git a/lkql_checker/share/lkql/not_imported_overlays.lkql b/lkql_checker/share/lkql/not_imported_overlays.lkql index be3c7b1a6..e02a6e9bd 100644 --- a/lkql_checker/share/lkql/not_imported_overlays.lkql +++ b/lkql_checker/share/lkql/not_imported_overlays.lkql @@ -8,16 +8,16 @@ import stdlib @check(message="not imported overlay", category="Style", subcategory="Programming Practice") fun not_imported_overlays(node) = - node is ( - AspectAssoc(f_id is Identifier(p_name_is("Address") is true), - any parent(depth=3) is o@ObjectDecl + node is (( + AspectAssoc(f_id: Identifier(p_name_is("Address"): true), + any parent(depth=3): o@ObjectDecl when not o.p_has_aspect("Import"))) - or (AttributeDefClause(f_attribute_expr is at@AttributeRef + | (AttributeDefClause(f_attribute_expr: at@AttributeRef when at.f_attribute.p_name_is("Address") and at.f_prefix.p_referenced_decl() is o@ObjectDecl - when not o.p_has_aspect("Import"))) + when not o.p_has_aspect("Import")))) # Check that we have an Overlaid'Address expression and that Overlaid is # an identifier corresponding to an ObjectDecl or ParamSpec and node.f_expr is at@AttributeRef when at.f_attribute.p_name_is("Address") - and stdlib.ultimate_alias(at.f_prefix, false) is ObjectDecl or ParamSpec + and stdlib.ultimate_alias(at.f_prefix, false) is (ObjectDecl | ParamSpec) diff --git a/lkql_checker/share/lkql/null_paths.lkql b/lkql_checker/share/lkql/null_paths.lkql index 9776ea840..bf5a1b362 100644 --- a/lkql_checker/share/lkql/null_paths.lkql +++ b/lkql_checker/share/lkql/null_paths.lkql @@ -8,9 +8,9 @@ fun null_paths(node, except_enums = false) = node is StmtList when node[1] - and node is StmtList(any parent is - IfStmt or BaseLoopStmt or + and node is StmtList(any parent: + IfStmt | BaseLoopStmt | c@CaseStmt when not (except_enums and c.f_expr.p_expression_type().p_is_enum_type()), - all children is NullStmt) + all children: NullStmt) diff --git a/lkql_checker/share/lkql/numeric_indexing.lkql b/lkql_checker/share/lkql/numeric_indexing.lkql index 8335252f3..93d8406bf 100644 --- a/lkql_checker/share/lkql/numeric_indexing.lkql +++ b/lkql_checker/share/lkql/numeric_indexing.lkql @@ -8,7 +8,7 @@ import stdlib @check(message="integer literal as index value", category="Feature") fun numeric_indexing(node) = node is IntLiteral when { - val n = if node.parent is UnOp(f_op is op@OpMinus + val n = if node.parent is UnOp(f_op: op@OpMinus when stdlib.is_predefined_op(op)) then node.parent else node; @@ -16,5 +16,5 @@ fun numeric_indexing(node) = # Exclude subcomponents by accessing directly parent.parent.parent n.parent?.parent?.parent is c@CallExpr when c.f_name.p_expression_type() is - BaseTypeDecl(p_is_array_type() is true) + BaseTypeDecl(p_is_array_type(): true) } diff --git a/lkql_checker/share/lkql/numeric_literals.lkql b/lkql_checker/share/lkql/numeric_literals.lkql index b254d71e6..a7348d4b1 100644 --- a/lkql_checker/share/lkql/numeric_literals.lkql +++ b/lkql_checker/share/lkql/numeric_literals.lkql @@ -32,13 +32,13 @@ fun numeric_literals(node, n : int = 1, all = false, statements_only = false) = # check parameter N if we have an integer literal, unless ALL is set when (all or (node is RealLiteral or node.p_denoted_value() > n) # exclude right expression of an exponentiation - and (not node.parent is BinOp(f_op is OpPow) + and (not node.parent is BinOp(f_op: OpPow) when node.parent.f_right == node) # exclude indexing of an array attribute and (not node.parent is ParamAssoc( - parent is AssocList( - parent is AttributeRef( - f_attribute is id@Identifier + parent: AssocList( + parent: AttributeRef( + f_attribute: id@Identifier when id.p_name_is("First") or id.p_name_is("Last") or id.p_name_is("Length"))))) diff --git a/lkql_checker/share/lkql/objects_of_anonymous_types.lkql b/lkql_checker/share/lkql/objects_of_anonymous_types.lkql index 00a64f6c3..be6e7e9fc 100644 --- a/lkql_checker/share/lkql/objects_of_anonymous_types.lkql +++ b/lkql_checker/share/lkql/objects_of_anonymous_types.lkql @@ -9,6 +9,6 @@ import stdlib @check(message="object of anonymous type", remediation="EASY", category="Style", subcategory="Programming Practice") fun objects_of_anonymous_types(node) = - node is ObjectDecl(f_type_expr is TypeExpr(p_designated_type_decl() is + node is ObjectDecl(f_type_expr: TypeExpr(p_designated_type_decl(): AnonymousTypeDecl)) when stdlib.is_in_package_scope(node) diff --git a/lkql_checker/share/lkql/one_construct_per_line.lkql b/lkql_checker/share/lkql/one_construct_per_line.lkql index 0e923d991..f75c6b5b3 100644 --- a/lkql_checker/share/lkql/one_construct_per_line.lkql +++ b/lkql_checker/share/lkql/one_construct_per_line.lkql @@ -14,18 +14,18 @@ import stdlib category="Style", subcategory="Readability") fun one_construct_per_line(node) = # Flag any statement, declaration or representation clause - node is (Stmt or BasicDecl or AttributeDefClause or - EnumRepClause or RecordRepClause or AtClause) + node is (Stmt | BasicDecl | AttributeDefClause | + EnumRepClause | RecordRepClause | AtClause) # except for enum literal, param spec, discriminant spec - when (not node is (EnumLiteralDecl or ParamSpec or DiscriminantSpec or + when (not node is (EnumLiteralDecl | ParamSpec | DiscriminantSpec | # or loop param or entry index. - ForLoopVarDecl or EntryIndexSpec or + ForLoopVarDecl | EntryIndexSpec | # Also ignore anonymous or nested constructs # generating false positives. - SingleTaskTypeDecl or AnonymousTypeDecl or - LabelDecl or GenericSubpInternal or - ConcreteFormalSubpDecl or - ExtendedReturnStmtObjectDecl or + SingleTaskTypeDecl | AnonymousTypeDecl | + LabelDecl | GenericSubpInternal | + ConcreteFormalSubpDecl | + ExtendedReturnStmtObjectDecl | NamedStmtDecl)) and (node.token_end().end_line == stdlib.next_non_blank_token_line(node.token_end()) diff --git a/lkql_checker/share/lkql/one_tagged_type_per_package.lkql b/lkql_checker/share/lkql/one_tagged_type_per_package.lkql index 3a66c8437..5d5bf2195 100644 --- a/lkql_checker/share/lkql/one_tagged_type_per_package.lkql +++ b/lkql_checker/share/lkql/one_tagged_type_per_package.lkql @@ -4,6 +4,6 @@ @check(message="more than one tagged type declared in package spec", category="Style", subcategory="Program Structure") fun one_tagged_type_per_package(node) = - node is BasePackageDecl(f_public_part is *(f_decls is decls@*)) + node is BasePackageDecl(f_public_part: *(f_decls: decls)) when (from decls select t@BaseTypeDecl when t.p_is_tagged_type() and t.parent == decls).length > 1 diff --git a/lkql_checker/share/lkql/others_in_aggregates.lkql b/lkql_checker/share/lkql/others_in_aggregates.lkql index 2aff59448..fb6c2c4ae 100644 --- a/lkql_checker/share/lkql/others_in_aggregates.lkql +++ b/lkql_checker/share/lkql/others_in_aggregates.lkql @@ -9,20 +9,20 @@ @check(message="OTHERS choice in aggregate", remediation="EASY", category="Style", subcategory="Programming Practice") fun others_in_aggregates(node) = - node is OthersDesignator(parent is l@AlternativesList( - parent is a@AggregateAssoc + node is OthersDesignator(parent: l@AlternativesList( + parent: a@AggregateAssoc # Flag all aggregates with more than 2 alternatives when a?.parent.children_count > 2 # Flag all extension aggregates - or a?.parent is AssocList(any parent is - Aggregate(f_ancestor_expr is AdaNode)) + or a?.parent is (AssocList(any parent: + Aggregate(f_ancestor_expr: AdaNode)) # Find the single alternative and flag in the following cases: - or AssocList(any children is assoc@AggregateAssoc + | AssocList(any children: assoc@AggregateAssoc when assoc != a # More than one value and (assoc.f_designators.children_count > 1 or # A range - assoc.f_designators[1] is BinOp(f_op is OpDoubleDot) or + assoc.f_designators[1] is BinOp(f_op: OpDoubleDot) or # A (sub)type designator assoc.f_designators[1] is - Identifier(p_referenced_decl() is BaseTypeDecl))))) + Identifier(p_referenced_decl(): BaseTypeDecl)))))) diff --git a/lkql_checker/share/lkql/others_in_case_statements.lkql b/lkql_checker/share/lkql/others_in_case_statements.lkql index 1947df61f..b57a6a7bd 100644 --- a/lkql_checker/share/lkql/others_in_case_statements.lkql +++ b/lkql_checker/share/lkql/others_in_case_statements.lkql @@ -10,7 +10,7 @@ fun choices(list) = comp + (match node | BinOp => stdlib.range_values(node.f_left, node.f_right) - | Identifier(p_referenced_decl() is type@BaseTypeDecl) => + | Identifier(p_referenced_decl(): type@BaseTypeDecl) => stdlib.number_of_values(type) | * => 1), 0) @@ -24,7 +24,7 @@ fun remaining_values(case) = @check(message="OTHERS choice in case statement", remediation="EASY", category="Style", subcategory="Programming Practice") fun others_in_case_statements(node, n : int = 0, ignore = false) = - node is OthersDesignator(parent is AlternativesList( - parent is alt@CaseStmtAlternative)) + node is OthersDesignator(parent: AlternativesList( + parent: alt@CaseStmtAlternative)) when n == 0 or { val v = remaining_values(alt.parent.parent); v > 0 and v < n } diff --git a/lkql_checker/share/lkql/others_in_exception_handlers.lkql b/lkql_checker/share/lkql/others_in_exception_handlers.lkql index 0aede59bf..94b3c13a4 100644 --- a/lkql_checker/share/lkql/others_in_exception_handlers.lkql +++ b/lkql_checker/share/lkql/others_in_exception_handlers.lkql @@ -3,5 +3,5 @@ @check(message="OTHERS choice in exception handler", category="Style", subcategory="Programming Practice") fun others_in_exception_handlers(node) = - node is OthersDesignator(parent is AlternativesList( - parent is ExceptionHandler)) + node is OthersDesignator(parent: AlternativesList( + parent: ExceptionHandler)) diff --git a/lkql_checker/share/lkql/outbound_protected_assignments.lkql b/lkql_checker/share/lkql/outbound_protected_assignments.lkql index 34745ac1d..23ca936bf 100644 --- a/lkql_checker/share/lkql/outbound_protected_assignments.lkql +++ b/lkql_checker/share/lkql/outbound_protected_assignments.lkql @@ -7,9 +7,9 @@ import stdlib @check(message="assignment from protected body to outside object", category="Style", subcategory="Programming Practice") fun outbound_protected_assignments(node) = - node is AssignStmt(any parent is p@ProtectedBody + node is AssignStmt(any parent: p@ProtectedBody when not (stdlib.ultimate_alias(node.f_dest) is - *(any parent is pr@(ProtectedTypeDecl or - SingleProtectedDecl or + *(any parent: pr@(ProtectedTypeDecl | + SingleProtectedDecl | ProtectedBody) when pr == p or pr == p.p_decl_part()))) diff --git a/lkql_checker/share/lkql/outer_loop_exits.lkql b/lkql_checker/share/lkql/outer_loop_exits.lkql index 89f5df06f..9ef26f798 100644 --- a/lkql_checker/share/lkql/outer_loop_exits.lkql +++ b/lkql_checker/share/lkql/outer_loop_exits.lkql @@ -3,7 +3,7 @@ @check(message="exit out of the nesting loop", category="SPARK") fun outer_loop_exits(node) = - node is ExitStmt(f_loop_name is Identifier) + node is ExitStmt(f_loop_name: Identifier) when [p for p in node.parents(include_self=false) if p is BaseLoopStmt].to_list[1] is l@BaseLoopStmt when not l.f_end_name or diff --git a/lkql_checker/share/lkql/overly_nested_control_structures.lkql b/lkql_checker/share/lkql/overly_nested_control_structures.lkql index c334cbf41..6f22005a1 100644 --- a/lkql_checker/share/lkql/overly_nested_control_structures.lkql +++ b/lkql_checker/share/lkql/overly_nested_control_structures.lkql @@ -12,24 +12,23 @@ fun check_control_parent(node, n) = |" Return true if node and its parents contain more than n control structure - if not node then false - else if node is (IfStmt or CaseStmt or BaseLoopStmt or SelectStmt) - then (if n == 0 then true - else check_control_parent(node.parent, n - 1)) - else check_control_parent(node.parent, n) + match node + | null => false + | (IfStmt | CaseStmt | BaseLoopStmt | SelectStmt) => + if n == 0 then true else check_control_parent(node.parent, n - 1) + | * => check_control_parent(node.parent, n) fun check_loop_parent(node, n) = |" Return true if node and its parents contain more than n loops - if not node then false - else if node is BaseLoopStmt - then (if n == 0 then true - else check_loop_parent(node.parent, n - 1)) - else check_loop_parent(node.parent, n) + match node + | null => false + | BaseLoopStmt => if n == 0 then true else check_control_parent(node.parent, n - 1) + | * => check_control_parent(node.parent, n) @check(message="nesting level of control structures too deep", category="Style", subcategory="Programming Practice") fun overly_nested_control_structures(node, n: int = 3, loops_only = false) = if loops_only then node is BaseLoopStmt when check_loop_parent(node.parent, n) - else node is (IfStmt or CaseStmt or BaseLoopStmt or SelectStmt) + else node is (IfStmt | CaseStmt | BaseLoopStmt | SelectStmt) when check_control_parent(node.parent, n) diff --git a/lkql_checker/share/lkql/overly_nested_scopes.lkql b/lkql_checker/share/lkql/overly_nested_scopes.lkql index 0870856eb..e9f1abc9d 100644 --- a/lkql_checker/share/lkql/overly_nested_scopes.lkql +++ b/lkql_checker/share/lkql/overly_nested_scopes.lkql @@ -11,10 +11,10 @@ fun check_decl_parent(node, n) = |" Return true if node and its parents contain more than n decl constructs if node == null then false - else if node is (BasePackageDecl or PackageBody or BasicSubpDecl or - BaseSubpBody or TaskTypeDecl or SingleTaskDecl or - TaskBody or ProtectedTypeDecl or SingleProtectedDecl or - ProtectedBody or EntryBody or BlockStmt) + else if node is (BasePackageDecl | PackageBody | BasicSubpDecl | + BaseSubpBody | TaskTypeDecl | SingleTaskDecl | + TaskBody | ProtectedTypeDecl | SingleProtectedDecl | + ProtectedBody | EntryBody | BlockStmt) then (if n == 0 then true else check_decl_parent(node.parent, n - 1)) else check_decl_parent(node.parent, n) @@ -22,8 +22,8 @@ fun check_decl_parent(node, n) = @check(message="nesting level of scopes too deep", category="Style", subcategory="Programming Practice") fun overly_nested_scopes(node, n: int = 10) = - node is (BasePackageDecl or PackageBody or BasicSubpDecl or BaseSubpBody or - TaskTypeDecl or SingleTaskDecl or TaskBody or - ProtectedTypeDecl or SingleProtectedDecl or ProtectedBody or - EntryBody or BlockStmt) + node is (BasePackageDecl | PackageBody | BasicSubpDecl | BaseSubpBody | + TaskTypeDecl | SingleTaskDecl | TaskBody | + ProtectedTypeDecl | SingleProtectedDecl | ProtectedBody | + EntryBody | BlockStmt) when check_decl_parent(node.parent, n) diff --git a/lkql_checker/share/lkql/parameters_aliasing.lkql b/lkql_checker/share/lkql/parameters_aliasing.lkql index 55fa13ef4..c720ced4d 100644 --- a/lkql_checker/share/lkql/parameters_aliasing.lkql +++ b/lkql_checker/share/lkql/parameters_aliasing.lkql @@ -11,9 +11,9 @@ import stdlib fun can_eval_as_int(expr) = |" Return true is expr is an expression on which p_eval_as_int() can be |" called. - expr is Expr(p_is_static_expr() is true, - p_expression_type() is BaseTypeDecl( - p_is_discrete_type() is true)) + expr is Expr(p_is_static_expr(): true, + p_expression_type(): BaseTypeDecl( + p_is_discrete_type(): true)) @memoized fun fully_expanded_name(name, canonical_indexes) = @@ -33,7 +33,7 @@ fun fully_expanded_name(name, canonical_indexes) = # Punt on aggregates | BaseAggregate => "NO MATCH" # Punt for now on attribute references - | AttributeRef or ReduceAttributeRef or UpdateAttributeRef => "NO MATCH" + | (AttributeRef | ReduceAttributeRef | UpdateAttributeRef) => "NO MATCH" # Strip dereferences | ExplicitDeref => fully_expanded_name(name.f_prefix, canonical_indexes) # Strip type qualifications @@ -41,7 +41,7 @@ fun fully_expanded_name(name, canonical_indexes) = | DottedName => # Strip named blocks and subprograms (if name.f_prefix is Identifier( - p_referenced_decl() is NamedStmtDecl or BasicSubpDecl or + p_referenced_decl(): NamedStmtDecl | BasicSubpDecl | BaseSubpBody) then "" else fully_expanded_name(name.f_prefix, canonical_indexes) & ".") & @@ -52,7 +52,7 @@ fun fully_expanded_name(name, canonical_indexes) = # Punt on subprogram calls ("call") (if name.p_is_call() then "NO MATCH" - else if name.f_name is Name(p_referenced_decl() is BaseTypeDecl) + else if name.f_name is Name(p_referenced_decl(): BaseTypeDecl) # Strip type conversions ("type_conversion") then fully_expanded_name(name.f_suffix[1].f_r_expr, canonical_indexes) else if name.p_is_array_slice() @@ -75,19 +75,19 @@ fun fully_expanded_name(name, canonical_indexes) = then img([(if can_eval_as_int(n.f_r_expr) then img(n.f_r_expr.p_eval_as_int()) else 0) - for n in name.f_suffix.children]) + for n in name.f_suffix.children].to_list) else img([fully_expanded_name(n.f_r_expr, canonical_indexes) - for n in name.f_suffix.children])) & ")") + for n in name.f_suffix.children].to_list)) & ")") | Name => (match name.p_referenced_decl() # Follow renamings - | ObjectDecl(f_renaming_clause is r@RenamingClause) => + | ObjectDecl(f_renaming_clause: r@RenamingClause) => fully_expanded_name(r.f_renamed_object, canonical_indexes) | decl@PackageRenamingDecl => fully_expanded_name(decl.p_final_renamed_package(), canonical_indexes) | * => name.text.to_lower_case) | BasicDecl => name.p_defining_name().text.to_lower_case - | StringLiteral or CharLiteral => name.text + | (StringLiteral | CharLiteral) => name.text # Punt on all other expressions | Expr => "NO MATCH" # Default fallback: take the name in lower case @@ -116,14 +116,14 @@ fun second_param(params, p, canonical_indexes) = # the second pair. [q for q in params if p != q and - q.param.parent.parent is ParamSpec(f_mode is ModeOut or ModeInOut) and + q.param.parent.parent is ParamSpec(f_mode: ModeOut | ModeInOut) and param_aliasing(p.actual, q.actual, canonical_indexes)] fun params_aliasing(params, in_parameters, canonical_indexes = false) = # We consider out and in (if in_parameters) here, and only out parameters # in second_param, since at least one of the aliases should be [in] out. [p for p in params - if (p.param.parent.parent is ParamSpec(f_mode is ModeOut or ModeInOut) or + if (p.param.parent.parent is ParamSpec(f_mode: ModeOut | ModeInOut) or (in_parameters and not stdlib.is_by_copy(p))) and second_param(params, p, canonical_indexes)] @@ -140,6 +140,6 @@ fun parameters_aliasing(unit, in_parameters = false) = [ param_image(n.parent.p_call_params(), in_parameters), loc: n.parent} for n in from unit.root select - AssocList(parent is call@CallExpr(p_is_call() is true)) + AssocList(parent: call@CallExpr(p_is_call(): true)) when params_aliasing(call.p_call_params(), in_parameters) ] diff --git a/lkql_checker/share/lkql/parameters_out_of_order.lkql b/lkql_checker/share/lkql/parameters_out_of_order.lkql index 8495f0846..bc4d7ef61 100644 --- a/lkql_checker/share/lkql/parameters_out_of_order.lkql +++ b/lkql_checker/share/lkql/parameters_out_of_order.lkql @@ -19,17 +19,17 @@ fun priority(spec, order) = | ModeInOut => index(order, "in_out") | ModeIn => index(order, "in") | ModeDefault => if spec.f_type_expr is - AnonymousType(f_type_decl is - *(f_type_def is AccessDef)) + AnonymousType(f_type_decl: + *(f_type_def: AccessDef)) then index(order, "access") else index(order, "in") @check(message="parameter out of order", remediation="EASY", category="Feature") fun parameters_out_of_order(node, order = ["in", "access", "in_out", "out", "defaulted_in"]) = - node is ParamSpec(any parent(depth=3) is not EntryCompletionFormalParams) + node is ParamSpec(any parent(depth=3): not EntryCompletionFormalParams) when ({ val prio = priority(node, order); - node is *(any next_siblings is + node is *(any next_siblings: sib@ParamSpec when priority(sib, order) < prio) }) diff --git a/lkql_checker/share/lkql/positional_actuals_for_defaulted_generic_parameters.lkql b/lkql_checker/share/lkql/positional_actuals_for_defaulted_generic_parameters.lkql index 052943c42..11596fced 100644 --- a/lkql_checker/share/lkql/positional_actuals_for_defaulted_generic_parameters.lkql +++ b/lkql_checker/share/lkql/positional_actuals_for_defaulted_generic_parameters.lkql @@ -8,7 +8,7 @@ fun get_formal(decls, pos, n: int = 1) = match decls[n] | f@GenericFormal => { val count = match f.f_decl - | d@(ObjectDecl or NumberDecl) => d.f_ids.children_count + | d@(ObjectDecl | NumberDecl) => d.f_ids.children_count | * => 1; if pos <= count then f else get_formal(decls, pos - count, n + 1) } | * => get_formal(decls, pos, n + 1) @@ -16,13 +16,13 @@ fun get_formal(decls, pos, n: int = 1) = fun check_generic(n, node) = get_formal(n.p_referenced_decl().f_formal_part.f_decls, stdlib.param_pos(node)) is - GenericFormal(f_decl is d@(FormalSubpDecl or ObjectDecl) + GenericFormal(f_decl: d@(FormalSubpDecl | ObjectDecl) when d.f_default_expr) @check(message="use named notation when passing actual to defaulted generic parameter", remediation="EASY", category="Style", subcategory="Programming Practice") fun positional_actuals_for_defaulted_generic_parameters(node) = - node is ParamAssoc(f_designator is null, parent is l@AssocList) + node is ParamAssoc(f_designator: null, parent: l@AssocList) when match l.parent | p@GenericSubpInstantiation => check_generic(p.f_generic_subp_name, node) diff --git a/lkql_checker/share/lkql/positional_actuals_for_defaulted_parameters.lkql b/lkql_checker/share/lkql/positional_actuals_for_defaulted_parameters.lkql index 0b725e95d..39a36ec33 100644 --- a/lkql_checker/share/lkql/positional_actuals_for_defaulted_parameters.lkql +++ b/lkql_checker/share/lkql/positional_actuals_for_defaulted_parameters.lkql @@ -24,5 +24,5 @@ fun check_actual(spec, node) = @check(message="use named notation when passing actual to defaulted parameter", remediation="EASY", category="Style", subcategory="Programming Practice") fun positional_actuals_for_defaulted_parameters(node) = - node is ParamAssoc(f_designator is null, parent is l@AssocList) + node is ParamAssoc(f_designator: null, parent: l@AssocList) when l.parent is c@CallExpr when check_actual(c.p_called_subp_spec(), node) diff --git a/lkql_checker/share/lkql/positional_components.lkql b/lkql_checker/share/lkql/positional_components.lkql index 93a4073f3..92dd9450d 100644 --- a/lkql_checker/share/lkql/positional_components.lkql +++ b/lkql_checker/share/lkql/positional_components.lkql @@ -7,6 +7,6 @@ fun is_array_or_record(n) = @check(message="aggregate with a positional component association", remediation="EASY", category="Style", subcategory="Programming Practice") fun positional_components(node) = - node is Aggregate(f_assocs is *(any children(depth=2) is a@AlternativesList + node is Aggregate(f_assocs: *(any children(depth=2): a@AlternativesList when not a[1])) when is_array_or_record(node.p_expression_type()) diff --git a/lkql_checker/share/lkql/positional_generic_parameters.lkql b/lkql_checker/share/lkql/positional_generic_parameters.lkql index 80a0650ff..14c4cc833 100644 --- a/lkql_checker/share/lkql/positional_generic_parameters.lkql +++ b/lkql_checker/share/lkql/positional_generic_parameters.lkql @@ -5,7 +5,7 @@ fun check_generic(n) = |" Return true if the generic decl corresponding to n contains more than 1 |" formal parameter. [(match x.f_decl - | d@(ObjectDecl or NumberDecl) => d.f_ids.children_count + | d@(ObjectDecl | NumberDecl) => d.f_ids.children_count | * => 1) for x in from n.p_referenced_decl().f_formal_part.f_decls select GenericFormal].length > 1 @@ -13,8 +13,8 @@ fun check_generic(n) = @check(message="positional generic association", remediation="EASY", category="Style", subcategory="Programming Practice") fun positional_generic_parameters(node) = - node is ParamAssoc(f_designator is null, - parent is l@AssocList(parent is g@GenericInstantiation)) + node is ParamAssoc(f_designator: null, + parent: l@AssocList(parent: g@GenericInstantiation)) when l.children_count > 1 or match g | p@GenericSubpInstantiation => check_generic(p.f_generic_subp_name) diff --git a/lkql_checker/share/lkql/positional_parameters.lkql b/lkql_checker/share/lkql/positional_parameters.lkql index 77bc1435c..78548d19e 100644 --- a/lkql_checker/share/lkql/positional_parameters.lkql +++ b/lkql_checker/share/lkql/positional_parameters.lkql @@ -26,10 +26,10 @@ fun check_actual_param(spec, node, check_dot) = @check(message="positional parameter association", remediation="EASY", category="Style", subcategory="Programming Practice") fun positional_parameters(node, all=false) = - node is ParamAssoc(f_designator is null, parent is l@AssocList) + node is ParamAssoc(f_designator: null, parent: l@AssocList) when l.parent is c@CallExpr( - p_is_call() is true, - f_name is not AttributeRef, - f_name is id@*(p_is_operator_name() is false) + p_is_call(): true, + f_name: not AttributeRef, + f_name: id@*(p_is_operator_name(): false) when (all or check_actual_param(c.p_called_subp_spec(), node, id.p_is_dot_call()))) diff --git a/lkql_checker/share/lkql/potential_parameters_aliasing.lkql b/lkql_checker/share/lkql/potential_parameters_aliasing.lkql index 0f093af06..70cf6061e 100644 --- a/lkql_checker/share/lkql/potential_parameters_aliasing.lkql +++ b/lkql_checker/share/lkql/potential_parameters_aliasing.lkql @@ -17,7 +17,7 @@ fun potential_parameters_aliasing(unit, in_parameters = false) = [ canonical_indexes=true), loc: n.parent} for n in from unit.root select - AssocList(parent is call@CallExpr(p_is_call() is true)) + AssocList(parent: call@CallExpr(p_is_call(): true)) when parameters_aliasing.params_aliasing( call.p_call_params(), in_parameters, canonical_indexes=true) ] diff --git a/lkql_checker/share/lkql/predefined_numeric_types.lkql b/lkql_checker/share/lkql/predefined_numeric_types.lkql index 1a685562b..42ca3a932 100644 --- a/lkql_checker/share/lkql/predefined_numeric_types.lkql +++ b/lkql_checker/share/lkql/predefined_numeric_types.lkql @@ -6,5 +6,5 @@ import stdlib @check(message="explicit reference to predefined numeric subtype", category="Style", subcategory="Portability") fun predefined_numeric_types(node) = - node is Identifier(p_referenced_decl() is t@BaseTypeDecl + node is Identifier(p_referenced_decl(): t@BaseTypeDecl when stdlib.is_standard_numeric(t.p_canonical_fully_qualified_name())) diff --git a/lkql_checker/share/lkql/predicate_testing.lkql b/lkql_checker/share/lkql/predicate_testing.lkql index f2a22d0ec..01379afb6 100644 --- a/lkql_checker/share/lkql/predicate_testing.lkql +++ b/lkql_checker/share/lkql/predicate_testing.lkql @@ -11,13 +11,13 @@ import stdlib # Return true if t represents a SubtypeDecl with a predicate (directly or via # a parent type). fun has_predicate(t) = - t is SubtypeDecl + t is (SubtypeDecl when t.p_has_aspect("Predicate") or t.p_has_aspect("Static_Predicate") or t.p_has_aspect("Dynamic_Predicate") or has_predicate(t.f_subtype?.f_name?.p_referenced_decl()) - or TypeDecl(f_type_def is d@DerivedTypeDef) - when has_predicate(d.f_subtype_indication.f_name.p_referenced_decl()) + | TypeDecl(f_type_def: d@DerivedTypeDef) + when has_predicate(d.f_subtype_indication.f_name.p_referenced_decl())) @check(message="expression needs subtype predicate evaluation", category="Feature") diff --git a/lkql_checker/share/lkql/profile_discrepancies.lkql b/lkql_checker/share/lkql/profile_discrepancies.lkql index 75c4d7580..d1a6d63a6 100644 --- a/lkql_checker/share/lkql/profile_discrepancies.lkql +++ b/lkql_checker/share/lkql/profile_discrepancies.lkql @@ -52,9 +52,9 @@ fun profile_discrepancies(unit) = [ {message: "structure of parameter profile differs from " & stdlib.sloc_image(n.p_decl_part()), loc: n.p_defining_name()} - for n in from unit.root select node@((BaseSubpBody or SubpBodyStub) + for n in from unit.root select node@((BaseSubpBody | SubpBodyStub) when match node.p_decl_part() | g@GenericSubpDecl => subp_mismatch(node, g?.f_subp_decl) | s@BasicSubpDecl => subp_mismatch(node, s) | * => false - or EntryBody when entry_mismatch(node))] + | EntryBody when entry_mismatch(node))] diff --git a/lkql_checker/share/lkql/raising_external_exceptions.lkql b/lkql_checker/share/lkql/raising_external_exceptions.lkql index 328094dba..be367f772 100644 --- a/lkql_checker/share/lkql/raising_external_exceptions.lkql +++ b/lkql_checker/share/lkql/raising_external_exceptions.lkql @@ -15,14 +15,14 @@ fun is_predefined_exception(e) = { fun check_raise(n, lib) = { val e = n.f_exception_name.p_referenced_decl(); not (is_predefined_exception(e) - or e is *(all parent is not PrivatePart, - any parent is exc_lib@LibraryItem when exc_lib == lib)) + or e is *(all parent: not PrivatePart, + any parent: exc_lib@LibraryItem when exc_lib == lib)) } @check(message="raised exception is not declared in visible part of enclosing library package", category="Style", subcategory="Program Structure") fun raising_external_exceptions(node) = - node is RaiseStmt(f_exception_name is Name, any parent is lib@LibraryItem + node is RaiseStmt(f_exception_name: Name, any parent: lib@LibraryItem when match lib.f_item | BasePackageDecl => check_raise(node, lib) | PackageBody => check_raise(node, lib.f_item.p_decl_part()?.parent) diff --git a/lkql_checker/share/lkql/raising_predefined_exceptions.lkql b/lkql_checker/share/lkql/raising_predefined_exceptions.lkql index f54f3b0b7..c214e59ed 100644 --- a/lkql_checker/share/lkql/raising_predefined_exceptions.lkql +++ b/lkql_checker/share/lkql/raising_predefined_exceptions.lkql @@ -18,5 +18,5 @@ fun canonical_exception_name(name) = { @check(message="explicit raise of a predefined exception", category="Feature") fun raising_predefined_exceptions(node) = - node is RaiseStmt(f_exception_name is exc@Name) + node is RaiseStmt(f_exception_name: exc@Name) when is_predefined_raise(canonical_exception_name(exc)) diff --git a/lkql_checker/share/lkql/recursive_subprograms.lkql b/lkql_checker/share/lkql/recursive_subprograms.lkql index 732ea26d0..1571908be 100644 --- a/lkql_checker/share/lkql/recursive_subprograms.lkql +++ b/lkql_checker/share/lkql/recursive_subprograms.lkql @@ -35,13 +35,13 @@ fun get_body(node) = # Get the bodies of the functions called statically by a given function body @memoized selector static_calls - | b@(BodyNode or GenericDecl) => rec * + | b@(BodyNode | GenericDecl) => rec(* # Grab the bodies for every static call [get_body(a) for a in stdlib.children_no_nested(b) - if a is GenericInstantiation or + if a is (GenericInstantiation | BaseId when a.p_is_static_call() or - a.p_referenced_decl() is TaskTypeDecl].to_list + a.p_referenced_decl() is TaskTypeDecl)].to_list) | * => () @memoized @@ -55,7 +55,7 @@ fun root_subp_decls(subp) = # Given a `name`, return all the bodies of the decl referenced by `name`, # taking dispatching calls into account. fun bodies(name) = - if name is Expr(p_is_dispatching_call() is true) then { + if name is Expr(p_is_dispatching_call(): true) then { val root = name.p_referenced_decl().p_canonical_part(); val roots = root_subp_decls(root); val subp = if not roots then root else roots[1]; @@ -65,14 +65,14 @@ fun bodies(name) = fun calls_helper(b) = concat([bodies(a) for a in stdlib.children_no_nested(b) - if a is GenericInstantiation or + if a is (GenericInstantiation | (BaseId when a.p_is_direct_call() or - a.p_referenced_decl() is TaskTypeDecl)]. + a.p_referenced_decl() is TaskTypeDecl))]. to_list) @memoized selector calls - | b@(BodyNode or GenericDecl) => rec * calls_helper(b) + | b@(BodyNode | GenericDecl) => rec(*calls_helper(b)) # Grab the bodies for every direct call | * => () @@ -86,13 +86,13 @@ fun recursive_subprograms(node, follow_dispatching_calls=false, follow_ghost_code=false) = - node is (ClassicSubpDecl or SubpBodyStub(p_previous_part() is null) or - BaseSubpBody(p_previous_part() is null or GenericSubpDecl)) + node is (ClassicSubpDecl | SubpBodyStub(p_previous_part(): null) | + BaseSubpBody(p_previous_part(): null | GenericSubpDecl)) when (not stdlib.in_generic_template(node)) and (follow_ghost_code or not node.p_is_ghost_code()) and stdlib.get_subp_body(node) is b@BaseSubpBody when if follow_dispatching_calls - then b is body@BaseSubpBody(any calls is c@BaseSubpBody when body == c) - else b is body@BaseSubpBody(any static_calls is c@BaseSubpBody + then b is body@BaseSubpBody(any calls: c@BaseSubpBody when body == c) + else b is body@BaseSubpBody(any static_calls: c@BaseSubpBody when body == c) diff --git a/lkql_checker/share/lkql/redundant_boolean_expressions.lkql b/lkql_checker/share/lkql/redundant_boolean_expressions.lkql index 3f8787952..9d7d443e1 100644 --- a/lkql_checker/share/lkql/redundant_boolean_expressions.lkql +++ b/lkql_checker/share/lkql/redundant_boolean_expressions.lkql @@ -30,23 +30,24 @@ fun check_then_else(then_stmt, else_stmt) = @check(message="redundant boolean expression", category="Style", subcategory="Programming Practice") fun redundant_boolean_expressions(node) = - node is RelationOp(f_op is op@(OpEq or OpNeq) + node is (RelationOp(f_op: op@(OpEq | OpNeq) when stdlib.is_predefined_op(op) and (node.f_right is name@Name when { val n = name.p_referenced_defining_name()?. p_canonical_fully_qualified_name?(); n == "standard.boolean.true" or n == "standard.boolean.false" })) - or - (IfStmt when node.f_alternatives[1] == null + + | (IfStmt when node.f_alternatives[1] == null and node.f_else_stmts.children_count == 1 and node.f_then_stmts.children_count == 1 and check_then_else(node.f_then_stmts[1], node.f_else_stmts[1])) - or - (IfExpr when node.f_alternatives[1] == null + + | (IfExpr when node.f_alternatives[1] == null and true_and_false(node.f_then_expr, node.f_else_expr)) - or (UnOp(f_op is op@OpNot + + | (UnOp(f_op: op@OpNot when stdlib.is_predefined_op(op) and stdlib.strip_conversions(node.f_expr) is rel@RelationOp - when stdlib.is_predefined_op(rel.f_op))) + when stdlib.is_predefined_op(rel.f_op)))) diff --git a/lkql_checker/share/lkql/relative_delay_statements.lkql b/lkql_checker/share/lkql/relative_delay_statements.lkql index defaec63b..d5c138db7 100644 --- a/lkql_checker/share/lkql/relative_delay_statements.lkql +++ b/lkql_checker/share/lkql/relative_delay_statements.lkql @@ -3,4 +3,4 @@ @check(message="relative delay statement", category="Feature") fun relative_delay_statements(node) = - node is DelayStmt(f_has_until is UntilAbsent) + node is DelayStmt(f_has_until: UntilAbsent) diff --git a/lkql_checker/share/lkql/representation_specifications.lkql b/lkql_checker/share/lkql/representation_specifications.lkql index 44480b15f..785b46cc0 100644 --- a/lkql_checker/share/lkql/representation_specifications.lkql +++ b/lkql_checker/share/lkql/representation_specifications.lkql @@ -8,7 +8,7 @@ selector defining_names |" Return all the defining names of this basic decl. This can be used |" instead of `any children is DefiningName...` to avoid selecting the |" defining names of nested basic decls. - | BasicDecl => *(this.p_defining_names()) + | BasicDecl => rec(*[d for d in this.p_defining_names() if d != null]) | * => () fun has_aspect(node, aspect) = { @@ -44,8 +44,8 @@ fun representation_specifications(unit, record_rep_clauses_only=false) = [ else "representation specification", loc: n} for n in from unit.root - select RecordRepClause or - (EnumRepClause when not record_rep_clauses_only) or - (BasicDecl(any defining_names is dn@*(p_previous_part() is null) when has_rep_aspect(dn)) - when not record_rep_clauses_only) + select (RecordRepClause | + (EnumRepClause when not record_rep_clauses_only) | + (BasicDecl(any defining_names: dn@*(p_previous_part(): null) when has_rep_aspect(dn)) + when not record_rep_clauses_only)) ] diff --git a/lkql_checker/share/lkql/same_logic.lkql b/lkql_checker/share/lkql/same_logic.lkql index e710a9ccb..83c4c5113 100644 --- a/lkql_checker/share/lkql/same_logic.lkql +++ b/lkql_checker/share/lkql/same_logic.lkql @@ -26,7 +26,7 @@ fun message(node) = { fun same_logic(unit) = [ message (n) for n in from unit.root - select node@BinOp(f_op is op@(OpAnd or OpAndThen or OpOr or OpOrElse or + select node@BinOp(f_op: op@(OpAnd | OpAndThen | OpOr | OpOrElse | OpXor)) when { val kind = op.kind; diff --git a/lkql_checker/share/lkql/same_operands.lkql b/lkql_checker/share/lkql/same_operands.lkql index eb324e3c9..33812efb3 100644 --- a/lkql_checker/share/lkql/same_operands.lkql +++ b/lkql_checker/share/lkql/same_operands.lkql @@ -5,8 +5,8 @@ @check(message="same operands", category="Style", subcategory="Programming Practice") fun same_operands(node) = - node is BinOp(f_op is OpDiv or OpEq or OpGt or OpGte or OpLt or OpLte or - OpMinus or OpMod or OpNeq or OpRem) + node is BinOp(f_op: OpDiv | OpEq | OpGt | OpGte | OpLt | OpLte | + OpMinus | OpMod | OpNeq | OpRem) when node.f_left.p_expression_type() is not - BaseTypeDecl(p_is_float_type() is true) + BaseTypeDecl(p_is_float_type(): true) and node.f_left.same_tokens(node.f_right) diff --git a/lkql_checker/share/lkql/same_tests.lkql b/lkql_checker/share/lkql/same_tests.lkql index cb08bc24f..5318d540e 100644 --- a/lkql_checker/share/lkql/same_tests.lkql +++ b/lkql_checker/share/lkql/same_tests.lkql @@ -19,7 +19,7 @@ fun message(node) = { fun same_tests(unit) = [ message(n) for n in from unit.root select - node@(IfStmt or IfExpr) + node@(IfStmt | IfExpr) when check_list([node.f_cond_expr] & [n.f_cond_expr for n in node.f_alternatives.children].to_list) ] diff --git a/lkql_checker/share/lkql/separate_numeric_error_handlers.lkql b/lkql_checker/share/lkql/separate_numeric_error_handlers.lkql index 9690fa277..698a16a8b 100644 --- a/lkql_checker/share/lkql/separate_numeric_error_handlers.lkql +++ b/lkql_checker/share/lkql/separate_numeric_error_handlers.lkql @@ -9,14 +9,14 @@ fun decl_name(n) = @check(message="Constraint_Error is handled separately from Numeric_Error", category="Style", subcategory="Portability") fun separate_numeric_error_handlers(node) = - node is BaseId(parent is l @ AlternativesList(parent is ExceptionHandler)) + node is BaseId(parent: l @ AlternativesList(parent: ExceptionHandler)) when ( decl_name(node) == "standard.constraint_error" - and not l is *(any children(depth=1) is e@* + and not l is *(any children(depth=1): e when decl_name(e) == "standard.numeric_error") ) or ( decl_name(node) == "standard.numeric_error" - and not l is *(any children(depth=1) is e@* + and not l is *(any children(depth=1): e when decl_name(e) == "standard.constraint_error") ) diff --git a/lkql_checker/share/lkql/side_effect_parameters.lkql b/lkql_checker/share/lkql/side_effect_parameters.lkql index 355b7d918..29f8b7002 100644 --- a/lkql_checker/share/lkql/side_effect_parameters.lkql +++ b/lkql_checker/share/lkql/side_effect_parameters.lkql @@ -10,7 +10,7 @@ fun check_list(l, functions) = val func = f.to_lower_case; # Find at least two calls to the same function [n for n in (from [p.actual for p in l].to_list select BaseId) - if n.p_referenced_decl() is decl@BasicDecl(p_is_subprogram() is true) + if n.p_referenced_decl() is decl@BasicDecl(p_is_subprogram(): true) when stdlib.ultimate_subprogram_alias(decl) is decl@BasicSubpDecl when decl.p_canonical_fully_qualified_name() == func]?[2] != () }] @@ -18,8 +18,8 @@ fun check_list(l, functions) = @check(message="call with side effects", category="Style", subcategory="Programming Practice") fun side_effect_parameters(node, functions=[]) = - node is GenericInstantiation + node is (GenericInstantiation when check_list(node.p_inst_params(), functions) - or - AssocList(parent is n@Name(p_is_call() is true)) - when check_list(n.p_call_params(), functions) + | + AssocList(parent: n@Name(p_is_call(): true)) + when check_list(n.p_call_params(), functions)) diff --git a/lkql_checker/share/lkql/silent_exception_handlers.lkql b/lkql_checker/share/lkql/silent_exception_handlers.lkql index 45c335d8c..b02e1735f 100644 --- a/lkql_checker/share/lkql/silent_exception_handlers.lkql +++ b/lkql_checker/share/lkql/silent_exception_handlers.lkql @@ -13,14 +13,14 @@ import control_flow category="Style", subcategory="Programming Practice") fun silent_exception_handlers(node, subprograms=[], subprogram_regexps=[]) = { fun is_raise_or_log(stmt) = - stmt is RaiseStmt - or n@BaseId(p_is_call() is true) + stmt is (RaiseStmt + | n@BaseId(p_is_call(): true) when n.p_referenced_decl() is decl@BasicDecl when match decl.p_canonical_fully_qualified_name() | "^ada.exceptions.(raise_exception|reraise_occurrence)$" => true - | n@* => [s for s in subprograms if n == s] or + | n => [s for s in subprograms if n == s] or [r for r in subprogram_regexps - if n.contains(pattern(r, case_sensitive=false))]; + if n.contains(pattern(r, case_sensitive=false))]); # Run a `must` control-flow analysis on the given exception handler to check # that *all* execution paths contain a raise statement or a call to an diff --git a/lkql_checker/share/lkql/size_attribute_for_types.lkql b/lkql_checker/share/lkql/size_attribute_for_types.lkql index b112d11ed..4451085d2 100644 --- a/lkql_checker/share/lkql/size_attribute_for_types.lkql +++ b/lkql_checker/share/lkql/size_attribute_for_types.lkql @@ -8,4 +8,4 @@ fun size_attribute_for_types(node) = node is AttributeRef when node.f_attribute?.p_name_is("Size") and node.f_prefix?.p_referenced_decl() is BaseTypeDecl - and not node is *(any parent is AttributeDefClause or AspectSpec) + and not node is *(any parent: AttributeDefClause | AspectSpec) diff --git a/lkql_checker/share/lkql/slices.lkql b/lkql_checker/share/lkql/slices.lkql index ac56351e6..564791a4c 100644 --- a/lkql_checker/share/lkql/slices.lkql +++ b/lkql_checker/share/lkql/slices.lkql @@ -1,4 +1,4 @@ # Flag all uses of array slicing. @check(message="slice", category="SPARK") -fun slices(node) = node is CallExpr(p_is_array_slice() is true) +fun slices(node) = node is CallExpr(p_is_array_slice(): true) diff --git a/lkql_checker/share/lkql/spark_procedures_without_globals.lkql b/lkql_checker/share/lkql/spark_procedures_without_globals.lkql index ab5135114..0b16622c2 100644 --- a/lkql_checker/share/lkql/spark_procedures_without_globals.lkql +++ b/lkql_checker/share/lkql/spark_procedures_without_globals.lkql @@ -4,6 +4,6 @@ import stdlib category="Style", subcategory="Programming Practice") fun spark_procedures_without_globals(node) = |" Check that every SPARK subprogram has a Global aspect - (node is BasicSubpDecl(p_has_spark_mode_on() is true, - p_subp_decl_spec() is BaseSubpSpec(p_return_type() is null))) + (node is BasicSubpDecl(p_has_spark_mode_on(): true, + p_subp_decl_spec(): BaseSubpSpec(p_return_type(): null))) and not node.p_has_aspect("Global") diff --git a/lkql_checker/share/lkql/specific_parent_type_invariant.lkql b/lkql_checker/share/lkql/specific_parent_type_invariant.lkql index 3b11c0767..47c8b89e4 100644 --- a/lkql_checker/share/lkql/specific_parent_type_invariant.lkql +++ b/lkql_checker/share/lkql/specific_parent_type_invariant.lkql @@ -5,16 +5,18 @@ fun check_aspect(n, aspect) = n != null and n.p_has_aspect(aspect) -fun base_type(t) = if t is SubtypeDecl then base_type(t.p_base_subtype()) else t +fun base_type(t) = match t + | SubtypeDecl(p_base_subtype(): s) => base_type(s) + | * => t @check(message="parent type has specific Type_Invariant aspect", category="Style", subcategory="Object Orientation") fun specific_parent_type_invariant(node) = # Flag any tagged type extension - node is DerivedTypeDef(parent is p@BaseTypeDecl(p_is_tagged_type() is true)) + node is DerivedTypeDef(parent: p@BaseTypeDecl(p_is_tagged_type(): true)) # exclude private completions when not p.p_previous_part() is TypeDecl( - f_type_def is DerivedTypeDef(f_has_with_private is WithPrivatePresent)) + f_type_def: DerivedTypeDef(f_has_with_private: WithPrivatePresent)) # exclude also formal derived types and p.parent is not GenericFormalTypeDecl # check for a parent type with a Type_Invariant aspect (current or public diff --git a/lkql_checker/share/lkql/specific_pre_post.lkql b/lkql_checker/share/lkql/specific_pre_post.lkql index c6b1d50a1..becb8bc4e 100644 --- a/lkql_checker/share/lkql/specific_pre_post.lkql +++ b/lkql_checker/share/lkql/specific_pre_post.lkql @@ -4,12 +4,12 @@ @check(message="definition of non class-wide aspect", category="Style", subcategory="Object Orientation") fun specific_pre_post(node) = - node is (BasicSubpDecl or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) + node is (BasicSubpDecl | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) # Get subprogram declarations when node.p_subp_spec_or_null() is # primitive of a tagged type - AdaNode(p_primitive_subp_tagged_type() is AdaNode) + AdaNode(p_primitive_subp_tagged_type(): AdaNode) # with direct pre/post aspect definitions when node.p_has_aspect("Pre", true) or node.p_has_aspect("Post", true) diff --git a/lkql_checker/share/lkql/specific_type_invariants.lkql b/lkql_checker/share/lkql/specific_type_invariants.lkql index f9d833e9a..7b3834025 100644 --- a/lkql_checker/share/lkql/specific_type_invariants.lkql +++ b/lkql_checker/share/lkql/specific_type_invariants.lkql @@ -7,5 +7,5 @@ category="Style", subcategory="Object Orientation") fun specific_type_invariants(node) = node is AspectAssoc( - f_id is Identifier(p_name_is("Type_Invariant") is true), - any parent(depth=3) is BaseTypeDecl(p_is_tagged_type() is true)) + f_id: Identifier(p_name_is("Type_Invariant"): true), + any parent(depth=3): BaseTypeDecl(p_is_tagged_type(): true)) diff --git a/lkql_checker/share/lkql/stdlib.lkql b/lkql_checker/share/lkql/stdlib.lkql index 1542ea83b..664ed0048 100644 --- a/lkql_checker/share/lkql/stdlib.lkql +++ b/lkql_checker/share/lkql/stdlib.lkql @@ -4,10 +4,15 @@ |" These functions may be moved in the future in Libadalang or LKQL's builtin |" library. +selector super_types + |" Yields the chain of super types for the given type + | BaseTypeDecl => rec(*this.p_base_types()) + | * => () + selector semantic_parent |" Return all semantic parent nodes starting from a given node. | null => () - | * => rec this.p_semantic_parent() + | * => rec(this.p_semantic_parent()) selector children_no_nested |" Return all children nodes starting from a base subprogram body, but not @@ -15,9 +20,9 @@ selector children_no_nested | BodyNode => # Don't recurse on bodies except if it's the root node (depth == 0) - rec *(if depth == 0 then this.children else []) + rec(*if depth == 0 then this.children else []) | null => () - | * => rec *this.children + | * => rec(*this.children) fun all(iterable) = |" Return whether all elements in the given iterable are truthy @@ -61,9 +66,9 @@ fun is_assert_aspect(s) = fun within_assert(node) = |" Return ``true`` if ``node`` is part of an assertion-related pragma or |" aspect. - node is *(any parent is + node is *(any parent: (p@PragmaNode when is_assert_pragma(p.f_id?.p_canonical_text())) - or a@AspectAssoc + | a@AspectAssoc when (match a.f_id | id@Identifier => is_assert_aspect(id.p_canonical_text()) @@ -79,11 +84,11 @@ fun ultimate_alias(name, all_nodes=true, strip_component=false) = |" ``DottedName``. If ``strip_component`` is true, go to the prefix when |" encountering a component, otherwise stop at the ``ComponentDecl``. - if all_nodes or name is (BaseId or DottedName) then { + if all_nodes or name is (BaseId | DottedName) then { val decl = name.p_referenced_decl(); match decl - | ObjectDecl(f_renaming_clause is r@RenamingClause) => + | ObjectDecl(f_renaming_clause: r@RenamingClause) => ultimate_alias(r.f_renamed_object, all_nodes, strip_component) | ComponentDecl when strip_component and name is DottedName => ultimate_alias(name.f_prefix, all_nodes, strip_component) @@ -96,7 +101,7 @@ fun ultimate_exception_alias(name) = { val decl = name.p_referenced_decl(); - if decl is ExceptionDecl(f_renames is RenamingClause) + if decl is ExceptionDecl(f_renames: RenamingClause) then ultimate_exception_alias(decl?.f_renames?.f_renamed_object) else decl } @@ -113,13 +118,13 @@ fun ultimate_subprogram_alias(name) = fun has_local_scope(n) = |" Return ``true`` if ``n`` is enclosed in a local scope n.parent is GenericFormalObjDecl or - n is *(any semantic_parent is BasicSubpDecl or SubpBody or TaskBody or - ExprFunction or BlockStmt or EntryBody or + n is *(any semantic_parent: BasicSubpDecl | SubpBody | TaskBody | + ExprFunction | BlockStmt | EntryBody | ProtectedBody) fun is_local_object(o) = |" Return ``true`` if ``o`` represents a local ``ObjectDecl`` or ``ParamSpec`` - o is ParamSpec or ObjectDecl when has_local_scope(o) + o is (ParamSpec | ObjectDecl when has_local_scope(o)) @memoized fun is_in_package_scope(o) = @@ -141,12 +146,12 @@ fun is_in_package_scope(o) = fun is_program_unit(n) = |" Return ``true`` if ``n`` is a program unit spec, body or stub - n is SubpDecl or AbstractSubpDecl or BaseSubpBody - or BasePackageDecl or PackageBody or GenericPackageInstantiation - or GenericDecl or GenericInstantiation - or SingleTaskDecl or TaskTypeDecl or TaskBody - or SubpBodyStub or ProtectedBodyStub or PackageBodyStub or TaskBodyStub - or SingleProtectedDecl or ProtectedTypeDecl + n is (SubpDecl | AbstractSubpDecl | BaseSubpBody + | BasePackageDecl | PackageBody | GenericPackageInstantiation + | GenericDecl | GenericInstantiation + | SingleTaskDecl | TaskTypeDecl | TaskBody + | SubpBodyStub | ProtectedBodyStub | PackageBodyStub | TaskBodyStub + | SingleProtectedDecl | ProtectedTypeDecl) @memoized fun is_in_library_unit_body(o) = @@ -215,8 +220,8 @@ fun is_predefined_type(n) = ].to_list; packages and packages[packages.length] is - BasePackageDecl(f_package_name is - DefiningName(p_canonical_part() is name@DefiningName)) + BasePackageDecl(f_package_name: + DefiningName(p_canonical_part(): name@DefiningName)) when name.p_name_is("Standard") or name.p_name_is("System") or name.p_name_is("Ada") @@ -230,14 +235,14 @@ selector parent_decl_chain |" This allows us to, if in a generic template, always find back the |" generic formal. | null => () - | BaseSubpBody or PackageBody => rec { + | (BaseSubpBody | PackageBody) => rec({ val prev_part = this.p_decl_part(); # Some subprogram bodies don't have a previous part because they're # also the decl. In that case, return the semantic parent. if prev_part then prev_part else this.p_semantic_parent() - } - | * => rec this.p_semantic_parent() + }) + | * => rec(this.p_semantic_parent()) fun closest_enclosing_generic(n) = |" If ``n`` is part of a generic package or subprogram, whether it is @@ -296,7 +301,7 @@ fun enclosing_package(n) = |" null otherwise { val pkg = [p for p in n.parents(include_self=false) - if p is BasePackageDecl or PackageBody]?[1]; + if p is (BasePackageDecl | PackageBody)]?[1]; if pkg then pkg else null } @@ -312,14 +317,14 @@ fun ultimate_designated_generic_subp(subp_inst) = # TODO: move to LAL fun is_classwide_type(t) = |" Return true if t is a classwide TypeDecl. - t is ClasswideTypeDecl or - BaseSubtypeDecl(p_base_subtype() is ClasswideTypeDecl) + t is (ClasswideTypeDecl | + BaseSubtypeDecl(p_base_subtype(): ClasswideTypeDecl)) # TODO: move to LAL fun is_controlling_param_type(t, spec) = |" Return true if `t` is a TypeExpr corresponding to a controlling |" parameter of the subprogram spec `spec`. - t is TypeExpr(p_designated_type_decl() is d@BaseTypeDecl) + t is TypeExpr(p_designated_type_decl(): d@BaseTypeDecl) when ((d.p_is_tagged_type() and not is_classwide_type(d)) or (d is AnonymousTypeDecl and d.p_accessed_type()?.p_is_tagged_type() and @@ -337,7 +342,7 @@ fun is_constructor(spec) = fun is_constant_object(node) = |" Return true is node represents a constant object, false otherwise - node is ObjectDecl or ParamSpec and node.p_is_constant_object() + node is (ObjectDecl | ParamSpec) and node.p_is_constant_object() fun is_unchecked_conversion(node) = |" Return true if node represents an instantiation of the @@ -387,9 +392,9 @@ fun get_subp_body(node) = fun is_limited_type(type) = |" Return `true` if type is a limited type type.f_type_def is - (def@(DerivedTypeDef or PrivateTypeDef or RecordTypeDef) - when def.f_has_limited.p_as_bool()) or - InterfaceTypeDef(f_interface_kind is InterfaceKindLimited) + ((def@(DerivedTypeDef | PrivateTypeDef | RecordTypeDef) + when def.f_has_limited.p_as_bool()) | + InterfaceTypeDef(f_interface_kind: InterfaceKindLimited)) @memoized fun list_of_units() = @@ -463,52 +468,32 @@ fun range_values(left, right) = fun number_of_values(type) = |" Return the number of values covered by a given BaseTypeDecl, -1 if |" this value cannot be determined. -{ - fun count_values_decl(decl) = { - val def = decl.f_type_def; - match def - | EnumTypeDef => ( - match decl.f_name?.p_canonical_fully_qualified_name() + match type + | SubtypeDecl(f_subtype: *(f_constraint: RangeConstraint(f_range: *(f_range: op@BinOp)) => range_values(op.f_left, op.f_right) + | SubtypeDecl => number_of_values(type.f_subtype.f_name.p_referenced_decl()) + | * when type == type.p_universal_int_type() => -1 + | TypeDecl(f_type_def: type_def) => match type_def + | EnumTypeDef(f_enum_literals: e) => ( + match type.f_name?.p_canonical_fully_qualified_name() | "standard.character" => 256 | "standard.wide_character" => 65536 | "standard.wide_wide_character" => 2147483648 - | * => def.f_enum_literals.children_count + | * => e.children_count ) - | ModIntTypeDef => if def.f_expr.p_is_static_expr() - then def.f_expr.p_eval_as_int() else -1 - | SignedIntTypeDef - when def.f_range.f_range is BinOp(f_op is OpDoubleDot) => { - val op = def.f_range.f_range; + | m@ModIntTypeDef when m.f_expr.p_is_static_expr() => m.f_expr.p_eval_as_int() + | s@SignedIntTypeDef when s.f_range.f_range is BinOp(f_op: OpDoubleDot) => { + val op = s.f_range.f_range; + range_values(op.f_left, op.f_right) + } + | DerivedTypeDef(f_subtype_indication: *(f_constraint: RangeConstraint(f_range: *(f_range: op@BinOp)))) => range_values(op.f_left, op.f_right) - } - | DerivedTypeDef => - (match def.f_subtype_indication.f_constraint - | r@RangeConstraint => - (match r.f_range.f_range - | op@BinOp => range_values(op.f_left, op.f_right) - | * => -1) - | * => number_of_values( - def.f_subtype_indication.f_name.p_referenced_decl())) - | FormalDiscreteTypeDef => -1 + | DerivedTypeDef(f_subtype_indication: s) => number_of_values(s.f_name.p_referenced_decl()) | * => -1 - }; - - if type is SubtypeDecl - then (match type.f_subtype.f_constraint - | r@RangeConstraint => (match r.f_range.f_range - | op@BinOp => range_values(op.f_left, op.f_right) - | * => -1) - | * => number_of_values( - type.f_subtype.f_name.p_referenced_decl())) - else if type == type.p_universal_int_type() - then -1 - else count_values_decl(type) -} fun has_interfaces(n) = |" Return true if ``n`` is an interface or implements some interfaces n.p_is_interface_type() or - n is TypeDecl(any super_types is TypeDecl(p_is_interface_type() is true)) + n is TypeDecl(any super_types: TypeDecl(p_is_interface_type(): true)) @memoized fun propagate_exceptions(body) = @@ -526,17 +511,17 @@ fun propagate_exceptions(body) = select first OthersDesignator) != null] and # and no (re)raise statement (from body.f_stmts.f_exceptions.children - select first RaiseStmt or - CallStmt(f_call is c@CallExpr) when { + select first (RaiseStmt | + CallStmt(f_call: c@CallExpr) when { val name = c.f_name.p_referenced_decl()?. p_fully_qualified_name?(); name == "Ada.Exceptions.Raise_Exception" or - name == "Ada.Exceptions.Reraise_Occurrence" }) == null) + name == "Ada.Exceptions.Reraise_Occurrence" })) == null) fun is_by_copy(param) = |" Return true if ``param`` (a ``ParamActual``) has a non aliased by-copy |" type - not (param.param.parent.parent is ParamSpec(f_has_aliased is AliasedPresent)) and + not (param.param.parent.parent is ParamSpec(f_has_aliased: AliasedPresent)) and param.actual.p_expression_type() is expr@BaseTypeDecl when expr.p_root_type().p_full_view().p_root_type() is t@BaseTypeDecl when t.p_is_discrete_type() or t.p_is_access_type() or @@ -562,7 +547,7 @@ fun strip_conversions(node) = # Strip type qualifications | QualExpr => strip_conversions(node.f_suffix) # Strip type conversions - | CallExpr(p_kind() is "type_conversion") + | CallExpr(p_kind(): "type_conversion") => strip_conversions(node.f_suffix[1].f_r_expr) | * => node @@ -579,15 +564,15 @@ fun default_bit_order() = |" clause is found, null otherwise. { val w = (select first w@WithClause - when from w select first Name(p_name_is("System") is true)); + when from w select first Name(p_name_is("System"): true)); if w == null then null else { - val system = from w select first Name(p_name_is("System") is true); + val system = from w select first Name(p_name_is("System"): true); (from system.p_referenced_decl() - select first decl@ObjectDecl(f_has_constant is ConstantPresent, - f_default_expr is not null) + select first decl@ObjectDecl(f_has_constant: ConstantPresent, + f_default_expr: not null) when decl.p_canonical_fully_qualified_name() == "system.default_bit_order").f_default_expr } @@ -602,7 +587,7 @@ fun has_non_default_sso(decl) = aspect.exists and match default_bit_order() | null => true - | expr@* => match expr.text + | expr => match expr.text | "High_Order_First" => ultimate_alias(aspect.value).p_canonical_fully_qualified_name() != "system.bit_order.high_order_first" @@ -615,23 +600,23 @@ fun has_non_default_sso(decl) = selector component_types |" Return all the ``BaseTypeDecl`` corresponding to all fields of a given |" type, including their full views, base types and subtypes. - | TypeDecl(f_type_def is d@RecordTypeDef) => - skip *(from d select ComponentDecl) - | TypeDecl(f_type_def is DerivedTypeDef(f_record_extension is + | TypeDecl(f_type_def: d@RecordTypeDef) => + rec(*(from d select ComponentDecl), ()) + | TypeDecl(f_type_def: DerivedTypeDef(f_record_extension: def@BaseRecordDef)) => - skip *([this.p_base_type()] & (from def select ComponentDecl)) - | TypeDecl(f_type_def is DerivedTypeDef) => rec this.p_base_type() - | TypeDecl(f_type_def is ArrayTypeDef) => rec this.p_comp_type() - | TypeDecl(f_type_def is PrivateTypeDef) => rec this.p_full_view() - | SubtypeDecl => rec this.p_base_subtype() - | ComponentDecl(f_component_def is ComponentDef(f_type_expr is + rec(*([this.p_base_type()] & (from def select ComponentDecl)), ()) + | TypeDecl(f_type_def: DerivedTypeDef) => rec(this.p_base_type()) + | TypeDecl(f_type_def: ArrayTypeDef) => rec(this.p_comp_type()) + | TypeDecl(f_type_def: PrivateTypeDef) => rec(this.p_full_view()) + | SubtypeDecl => rec(this.p_base_subtype()) + | ComponentDecl(f_component_def: ComponentDef(f_type_expr: ind@SubtypeIndication)) => - rec ind.f_name.p_referenced_decl() + rec(ind.f_name.p_referenced_decl()) | * => () selector full_parent_types |" Return all base (sub)types full views - | SubtypeDecl => rec this.p_base_subtype().p_full_view() - | ClasswideTypeDecl => rec this.f_name.p_basic_decl().p_full_view() - | BaseTypeDecl => rec *this.p_full_view().p_base_types() + | SubtypeDecl => rec(this.p_base_subtype().p_full_view()) + | ClasswideTypeDecl => rec(this.f_name.p_basic_decl().p_full_view()) + | BaseTypeDecl => rec(*this.p_full_view().p_base_types()) | * => () diff --git a/lkql_checker/share/lkql/suspicious_equalities.lkql b/lkql_checker/share/lkql/suspicious_equalities.lkql index 27aea7432..cffa92ad1 100644 --- a/lkql_checker/share/lkql/suspicious_equalities.lkql +++ b/lkql_checker/share/lkql/suspicious_equalities.lkql @@ -3,32 +3,31 @@ # are equality expressions comparing a same variable against two literals. fun name_of(node) = - if node.f_left is Name then - node.f_left - else - node.f_right + match node + | BinOp(f_left: n@Name) => n + | BinOp(f_right: r) => r fun is_literal(node) = - node is CharLiteral or NumLiteral or StringLiteral + node is (CharLiteral | NumLiteral | StringLiteral) fun is_name_binop_literal(node) = (node.f_left is Name and is_literal(node.f_right)) or (is_literal(node.f_left) and node.f_right is Name) fun is_name_neq_literal(node) = - node is BinOp(f_op is OpNeq) and is_name_binop_literal(node) + node is BinOp(f_op: OpNeq) and is_name_binop_literal(node) fun is_or_neq(node) = - node is BinOp(f_op is OpOr or OpOrElse) + node is BinOp(f_op: OpOr | OpOrElse) when is_name_neq_literal(node.f_left) and is_name_neq_literal(node.f_right) and name_of(node.f_left).p_name_matches(name_of(node.f_right)) fun is_name_eq_literal(node) = - node is BinOp(f_op is OpEq) and is_name_binop_literal(node) + node is BinOp(f_op: OpEq) and is_name_binop_literal(node) fun is_and_eq(node) = - node is BinOp(f_op is OpAnd or OpAndThen) + node is BinOp(f_op: OpAnd | OpAndThen) when is_name_eq_literal(node.f_left) and is_name_eq_literal(node.f_right) and name_of(node.f_left).p_name_matches(name_of(node.f_right)) diff --git a/lkql_checker/share/lkql/too_many_dependencies.lkql b/lkql_checker/share/lkql/too_many_dependencies.lkql index f919f14e1..2ca7bcb64 100644 --- a/lkql_checker/share/lkql/too_many_dependencies.lkql +++ b/lkql_checker/share/lkql/too_many_dependencies.lkql @@ -21,10 +21,10 @@ fun dependencies(unit, parent) = { if p.p_referenced_decl() != parent].to_list for w in (from unit.f_prelude select WithClause)].to_list); unique(match unit.f_body - | LibraryItem(f_item is BodyNode(p_previous_part() - is prev@BasicDecl)) + | LibraryItem(f_item: BodyNode(p_previous_part() + : prev@BasicDecl)) => l & dependencies(comp_unit(prev), parent) - | Subunit(f_body is *(p_previous_part() is prev@BasicDecl)) + | Subunit(f_body: *(p_previous_part(): prev@BasicDecl)) => l & dependencies(comp_unit(prev), parent) | * => l) } @@ -44,7 +44,7 @@ fun too_many_dependencies(unit, n : int = 5) = [ else num_deps(node.parent, node.p_semantic_parent())) & ")", loc: node} for node in from unit.root select - lib@(LibraryItem when num_deps(lib.parent, - lib.f_item.p_semantic_parent()) > n) or - sub@Subunit when num_deps(sub.parent, sub.p_semantic_parent()) > n + (lib@(LibraryItem when num_deps(lib.parent, + lib.f_item.p_semantic_parent()) > n) | + sub@Subunit when num_deps(sub.parent, sub.p_semantic_parent()) > n) ] diff --git a/lkql_checker/share/lkql/too_many_generic_dependencies.lkql b/lkql_checker/share/lkql/too_many_generic_dependencies.lkql index 4a646ccd5..eee9352a0 100644 --- a/lkql_checker/share/lkql/too_many_generic_dependencies.lkql +++ b/lkql_checker/share/lkql/too_many_generic_dependencies.lkql @@ -7,7 +7,7 @@ fun check_deps(node, n : int) = |" Return true if node has a chain of at least n generic units withed n == 0 or node is LibraryItem( - parent is unit@CompilationUnit + parent: unit@CompilationUnit when [x for x in concat( [[p for p in w.f_packages.children if p.p_referenced_decl() is GenericDecl].to_list diff --git a/lkql_checker/share/lkql/too_many_parents.lkql b/lkql_checker/share/lkql/too_many_parents.lkql index 8bf2efd87..461992d45 100644 --- a/lkql_checker/share/lkql/too_many_parents.lkql +++ b/lkql_checker/share/lkql/too_many_parents.lkql @@ -6,6 +6,8 @@ # This rule has the following parameter: n: Positive integer # specifying the maximal allowed number of parents/progenitors. +import stdlib + fun num_interfaces(n) = |" Return the number of interfaces for a SingleProtectedDecl, 0 otherwise |" since for all type declarations, super_types takes interfaces into @@ -15,10 +17,10 @@ fun num_interfaces(n) = @check(message="type has too many parents", remediation="MAJOR", category="Style", subcategory="Object Orientation") fun too_many_parents(node, n : int = 5) = - node is (TypeDecl(p_is_tagged_type() is true) or - TaskTypeDecl or ProtectedTypeDecl or SingleProtectedDecl) + node is (TypeDecl(p_is_tagged_type(): true) | + TaskTypeDecl | ProtectedTypeDecl | SingleProtectedDecl) when ({ val l = num_interfaces(node); - val st = super_types(node, max_depth=n - l + 1); + val st = stdlib.super_types(node, max_depth=n - l + 1); l + st.length > n }) diff --git a/lkql_checker/share/lkql/trivial_exception_handlers.lkql b/lkql_checker/share/lkql/trivial_exception_handlers.lkql index 499888ed8..0681e3eb5 100644 --- a/lkql_checker/share/lkql/trivial_exception_handlers.lkql +++ b/lkql_checker/share/lkql/trivial_exception_handlers.lkql @@ -6,9 +6,9 @@ category="Style", subcategory="Programming Practice") fun trivial_exception_handlers(node) = node is ExceptionHandler - when node.f_stmts[1] is RaiseStmt(f_exception_name is null) + when node.f_stmts[1] is RaiseStmt(f_exception_name: null) and { val handlers = node.parent.children; val handler = handlers[handlers.length]; handler.f_handled_exceptions[1] is not OthersDesignator or - handler.f_stmts[1] is RaiseStmt(f_exception_name is null)} + handler.f_stmts[1] is RaiseStmt(f_exception_name: null)} diff --git a/lkql_checker/share/lkql/unassigned_out_parameters.lkql b/lkql_checker/share/lkql/unassigned_out_parameters.lkql index 44665f320..22cb77508 100644 --- a/lkql_checker/share/lkql/unassigned_out_parameters.lkql +++ b/lkql_checker/share/lkql/unassigned_out_parameters.lkql @@ -25,27 +25,27 @@ fun param_matches(id, param, name, ignore_comp) = { val decl = id.p_referenced_decl(); (match decl - | ObjectDecl(f_renaming_clause is r@RenamingClause) => + | ObjectDecl(f_renaming_clause: r@RenamingClause) => stdlib.ultimate_alias( r.f_renamed_object, strip_component=not ignore_comp ) == param | * => decl == param and id.p_name_matches(name)) - and not (ignore_comp and id.parent is DottedName or CallExpr) + and not (ignore_comp and id.parent is (DottedName | CallExpr)) } # Return true if the list of stmts s contains any assignment to name as # defined above, which happens to match the p_is_write_reference() property. # param is the ParamDecl of name. fun check_stmts(param, name, s, ignore_comp) = - s is *(any children is id@Name + s is *(any children: id@Name when id.p_is_write_reference() and param_matches(id, param, name, ignore_comp)) # Return true if the exception handler h contains a raise statement, a call # to a No_Return procedure or an assignment to param as defined above. fun check_exception_handler(param, name, h, ignore_comp) = - (h.f_stmts is *(any children is RaiseStmt or + (h.f_stmts is *(any children: RaiseStmt | c@CallStmt when c.f_call.p_is_call() and c.f_call.p_referenced_decl(). p_has_aspect("No_Return"))) or @@ -55,7 +55,7 @@ fun enclosing_body_stmts(node) = match stdlib.enclosing_body(node) | null => null | NullSubpDecl => null - | p@* => p.f_stmts + | p => p.f_stmts @unit_check(help="OUT parameters do not get values in procedure bodies", category="Feature") @@ -63,10 +63,10 @@ fun unassigned_out_parameters(unit, ignore_component_assignments=false) = [ {message: "unassigned OUT parameter " & n.f_name.text, loc: n} for n in from unit.root # Look for out parameters of subprogram bodies only - select node@DefiningName(parent is DefiningNameList(parent is - ParamSpec(f_mode is ModeOut, - parent is ParamSpecList(parent is Params(parent is - SubpSpec(parent is SubpBody)))))) + select node@DefiningName(parent: DefiningNameList(parent: + ParamSpec(f_mode: ModeOut, + parent: ParamSpecList(parent: Params(parent: + SubpSpec(parent: SubpBody)))))) when { val f = enclosing_body_stmts(node); val decl = node.p_basic_decl(); diff --git a/lkql_checker/share/lkql/unavailable_body_calls.lkql b/lkql_checker/share/lkql/unavailable_body_calls.lkql index f994e7824..67022e6cf 100644 --- a/lkql_checker/share/lkql/unavailable_body_calls.lkql +++ b/lkql_checker/share/lkql/unavailable_body_calls.lkql @@ -10,5 +10,5 @@ fun unavailable_body_calls(node, indirect_calls = false) = node is Name when (indirect_calls and node.p_is_access_call()) or - node is BaseId(p_is_static_call() is true, - p_referenced_decl() is SubpDecl(p_body_part() is null)) + node is BaseId(p_is_static_call(): true, + p_referenced_decl(): SubpDecl(p_body_part(): null)) diff --git a/lkql_checker/share/lkql/unchecked_conversions_as_actuals.lkql b/lkql_checker/share/lkql/unchecked_conversions_as_actuals.lkql index 621d14a51..a80d184a3 100644 --- a/lkql_checker/share/lkql/unchecked_conversions_as_actuals.lkql +++ b/lkql_checker/share/lkql/unchecked_conversions_as_actuals.lkql @@ -8,11 +8,11 @@ import stdlib category="Style", subcategory="Programming Practice") fun unchecked_conversions_as_actuals(unit) = [ {message: "instance of Unchecked_Conversion as " & - (if n is CallExpr(any parent is CallStmt) + (if n is CallExpr(any parent: CallStmt) then "actual parameter" else "default parameter value"), loc: n} for n in from unit.root - select node@CallExpr(any parent is CallStmt or SubpSpec) + select node@CallExpr(any parent: CallStmt | SubpSpec) when stdlib.is_unchecked_conversion( stdlib.ultimate_subprogram_alias(node.p_referenced_decl()) )] diff --git a/lkql_checker/share/lkql/uncommented_begin.lkql b/lkql_checker/share/lkql/uncommented_begin.lkql index fdb2dc638..89be06043 100644 --- a/lkql_checker/share/lkql/uncommented_begin.lkql +++ b/lkql_checker/share/lkql/uncommented_begin.lkql @@ -11,10 +11,10 @@ fun uncommented_begin(unit) = [ {message: "mark BEGIN with -- " & n.parent.p_defining_name().text, loc: n.token_start().previous(exclude_trivia=true)} for n in from unit.root - select node@HandledStmts(parent is p@(PackageBody or SubpBody or - EntryBody or ProtectedBody or + select node@HandledStmts(parent: p@(PackageBody | SubpBody | + EntryBody | ProtectedBody | TaskBody)) - when p.f_decls is *(f_decls is l@*) + when p.f_decls is *(f_decls: l) when l[1] and not stdlib.find_comment(node.token_start().previous(exclude_trivia=true), p.p_defining_name().text) diff --git a/lkql_checker/share/lkql/uncommented_begin_in_package_bodies.lkql b/lkql_checker/share/lkql/uncommented_begin_in_package_bodies.lkql index 3fe36a646..9cee32db9 100644 --- a/lkql_checker/share/lkql/uncommented_begin_in_package_bodies.lkql +++ b/lkql_checker/share/lkql/uncommented_begin_in_package_bodies.lkql @@ -11,7 +11,7 @@ fun uncommented_begin_in_package_bodies(unit) = [ {message: "mark BEGIN with package name", loc: n.token_start().previous(exclude_trivia=true)} for n in from unit.root - select node@HandledStmts(parent is p@PackageBody(f_decls is *(f_decls is l@*))) + select node@HandledStmts(parent: p@PackageBody(f_decls: *(f_decls: l))) when l[1] and not stdlib.find_comment(node.token_start().previous(), p.f_package_name.text) diff --git a/lkql_checker/share/lkql/unconstrained_array_returns.lkql b/lkql_checker/share/lkql/unconstrained_array_returns.lkql index 11a606930..54420dd7f 100644 --- a/lkql_checker/share/lkql/unconstrained_array_returns.lkql +++ b/lkql_checker/share/lkql/unconstrained_array_returns.lkql @@ -15,11 +15,11 @@ fun unconstrained_array_type(type, except_string) = if type is SubtypeDecl then type.f_subtype.f_constraint is not Constraint and unconstrained_array_type(type.p_canonical_type(), except_string) - else if type is TypeDecl(f_type_def is DerivedTypeDef) + else if type is TypeDecl(f_type_def: DerivedTypeDef) then type.f_type_def.f_subtype_indication.f_constraint is not Constraint and unconstrained_array_type(type.p_base_type(), except_string) - else type is TypeDecl(p_is_array_type() is true, - f_type_def is ArrayTypeDef(f_indices is + else type is TypeDecl(p_is_array_type(): true, + f_type_def: ArrayTypeDef(f_indices: UnconstrainedArrayIndices)) when not (except_string and type.p_root_type().p_fully_qualified_name() @@ -28,13 +28,13 @@ fun unconstrained_array_type(type, except_string) = @check(message="function returns unconstrained array", follow_generic_instantiations=true, category="Feature") fun unconstrained_array_returns(node, except_string = false) = - node is (AbstractSubpDecl or SubpDecl or GenericSubpInternal or - BaseSubpBody(p_previous_part() is null) or - SubpBodyStub(p_previous_part() is null)) + node is (AbstractSubpDecl | SubpDecl | GenericSubpInternal | + BaseSubpBody(p_previous_part(): null) | + SubpBodyStub(p_previous_part(): null)) when (not stdlib.in_generic_template(node)) - and node.f_subp_spec is SubpSpec(f_subp_returns is - TypeExpr(p_designated_type_decl() is + and node.f_subp_spec is SubpSpec(f_subp_returns: + TypeExpr(p_designated_type_decl(): t@BaseTypeDecl when unconstrained_array_type(t, except_string))) diff --git a/lkql_checker/share/lkql/unconstrained_arrays.lkql b/lkql_checker/share/lkql/unconstrained_arrays.lkql index 3bfb9e5a8..f594579c0 100644 --- a/lkql_checker/share/lkql/unconstrained_arrays.lkql +++ b/lkql_checker/share/lkql/unconstrained_arrays.lkql @@ -2,5 +2,5 @@ @check(message="unconstrained array definition", category="Feature") fun unconstrained_arrays(node) = - node is ArrayTypeDef(f_indices is UnconstrainedArrayIndices, - all parent(depth=2) is not GenericFormalTypeDecl) + node is ArrayTypeDef(f_indices: UnconstrainedArrayIndices, + all parent(depth=2): not GenericFormalTypeDecl) diff --git a/lkql_checker/share/lkql/universal_ranges.lkql b/lkql_checker/share/lkql/universal_ranges.lkql index 62195d812..65ea78d2d 100644 --- a/lkql_checker/share/lkql/universal_ranges.lkql +++ b/lkql_checker/share/lkql/universal_ranges.lkql @@ -6,18 +6,18 @@ # In the context of a range constraint, a NumberDecl is always an int fun is_universal_int(i) = - i is IntLiteral or i is Name(p_referenced_decl() is NumberDecl) + i is IntLiteral or i is Name(p_referenced_decl(): NumberDecl) @check(message="range with universal integer bounds", category="SPARK") fun universal_ranges(node) = - node is ( + node is (( # index constraint or constrained array definition - CompositeConstraint(p_is_index_constraint() is true) + CompositeConstraint(p_is_index_constraint(): true) when node.f_constraints[1].f_constraint_expr - is r@BinOp(f_op is OpDoubleDot) + is r@BinOp(f_op: OpDoubleDot) when is_universal_int(r.f_right) and is_universal_int(r.f_left) - ) or ( + ) | ( # range of a "for of" loop - r@BinOp (parent is ForLoopSpec, f_op is OpDoubleDot) + r@BinOp (parent: ForLoopSpec, f_op: OpDoubleDot) when is_universal_int(r.f_right) and is_universal_int(r.f_left) - ) + )) diff --git a/lkql_checker/share/lkql/unnamed_blocks_and_loops.lkql b/lkql_checker/share/lkql/unnamed_blocks_and_loops.lkql index f7ecd9a32..8bab6c5cc 100644 --- a/lkql_checker/share/lkql/unnamed_blocks_and_loops.lkql +++ b/lkql_checker/share/lkql/unnamed_blocks_and_loops.lkql @@ -7,11 +7,11 @@ fun unnamed_blocks_and_loops(unit) = [ {message: "non-named " & (if n is BlockStmt then "block" - else (if n is BaseLoopStmt(any children is BaseLoopStmt) + else (if n is BaseLoopStmt(any children: BaseLoopStmt) then "nesting " else "nested ") & "loop") & " statement", loc: n} for n in from unit.root select node@CompositeStmt when (not node.parent is NamedStmt) - and node is BlockStmt or - BaseLoopStmt (any children is BaseLoopStmt) or - BaseLoopStmt (any parent is BaseLoopStmt)] + and node is (BlockStmt | + BaseLoopStmt (any children: BaseLoopStmt) | + BaseLoopStmt (any parent: BaseLoopStmt))] diff --git a/lkql_checker/share/lkql/unnamed_exits.lkql b/lkql_checker/share/lkql/unnamed_exits.lkql index f4437331d..6337c058c 100644 --- a/lkql_checker/share/lkql/unnamed_exits.lkql +++ b/lkql_checker/share/lkql/unnamed_exits.lkql @@ -3,5 +3,5 @@ @check(message="unnamed exit statement", remediation="EASY", category="Style", subcategory="Programming Practice") fun unnamed_exits(node) = - node is ExitStmt(f_loop_name is null) + node is ExitStmt(f_loop_name: null) when (from node through parent select first BaseLoopStmt)?.f_end_name is EndName diff --git a/lkql_checker/share/lkql/use_array_slices.lkql b/lkql_checker/share/lkql/use_array_slices.lkql index 5335528ed..a7b19240f 100644 --- a/lkql_checker/share/lkql/use_array_slices.lkql +++ b/lkql_checker/share/lkql/use_array_slices.lkql @@ -6,12 +6,12 @@ fun array_index(call, var) = call is CallExpr( - f_suffix is l@AssocList + f_suffix: l@AssocList when l.children_count == 1 and l[1].f_r_expr is id@Identifier when id.p_name_matches(var), # p_kind does not always work, in particular on e.g. Arr (X)(Y) so # perform this test last - p_kind() is "array_index") + p_kind(): "array_index") @check(message="FOR loop may be replaced by an array slice", category="Style", subcategory="Programming Practice") diff --git a/lkql_checker/share/lkql/use_case_statements.lkql b/lkql_checker/share/lkql/use_case_statements.lkql index 89631e5e8..d6a8a876c 100644 --- a/lkql_checker/share/lkql/use_case_statements.lkql +++ b/lkql_checker/share/lkql/use_case_statements.lkql @@ -11,14 +11,14 @@ import stdlib fun is_static_relation(expr) = - expr is RelationOp(f_right is Expr(p_is_static_expr() is true), - f_op is op@Op when stdlib.is_predefined_op(op)) + expr is RelationOp(f_right: Expr(p_is_static_expr(): true), + f_op: op@Op when stdlib.is_predefined_op(op)) fun check_alternatives(list, id) = |" Check that all alternatives are of the form: |" Id static-expr [x for x in list - if x.f_cond_expr is r@RelationOp(f_left is id2@(Identifier or DottedName)) + if x.f_cond_expr is r@RelationOp(f_left: id2@(Identifier | DottedName)) when is_static_relation(r) and id2.p_name_matches(id) ].length == list.length @@ -26,11 +26,11 @@ fun check_alternatives(list, id) = category="Style", subcategory="Programming Practice") fun use_case_statements(node) = node is IfStmt( - f_alternatives is l@ElsifStmtPartList when l[1], - f_cond_expr is r@RelationOp + f_alternatives: l@ElsifStmtPartList when l[1], + f_cond_expr: r@RelationOp when r.f_left is id@( (Identifier when id.p_expression_type().p_is_discrete_type()) - or (DottedName + | (DottedName when id.f_suffix is suffix@Name when suffix.p_referenced_decl() is ComponentDecl and suffix.p_expression_type().p_is_discrete_type())) diff --git a/lkql_checker/share/lkql/use_clauses.lkql b/lkql_checker/share/lkql/use_clauses.lkql index c6d8659ae..e6c3991cf 100644 --- a/lkql_checker/share/lkql/use_clauses.lkql +++ b/lkql_checker/share/lkql/use_clauses.lkql @@ -5,7 +5,7 @@ # declares operators in its visible part. fun is_operator(s) = - s is (BasicSubpDecl or BaseSubpBody) + s is (BasicSubpDecl | BaseSubpBody) when s.p_defining_name().p_is_operator_name() fun decls_not_only_operator(pkg) = diff --git a/lkql_checker/share/lkql/use_for_loops.lkql b/lkql_checker/share/lkql/use_for_loops.lkql index be67998b9..a1dd01139 100644 --- a/lkql_checker/share/lkql/use_for_loops.lkql +++ b/lkql_checker/share/lkql/use_for_loops.lkql @@ -19,18 +19,18 @@ import stdlib fun write_references(node, id) = |" Return all the write references to `id`, starting from `node` - from node select Identifier(p_name_matches(id) is true, - p_is_write_reference() is true) + from node select Identifier(p_name_matches(id): true, + p_is_write_reference(): true) fun no_write_reference(node, id) = |" Return true if no write reference to `id` is found, starting from `node` (from node select first - Identifier(p_name_matches(id) is true, - p_is_write_reference() is true)) == null + Identifier(p_name_matches(id): true, + p_is_write_reference(): true)) == null fun has_references(node, id) = |" Return true if any reference to `id` starting from `node` is found - (from node select first Identifier(p_name_matches(id) is true)) != null + (from node select first Identifier(p_name_matches(id): true)) != null fun exit_stmt(node) = |" Return the first exit statement referencing node (assumed to be a @@ -51,8 +51,8 @@ fun enclosing_scope(node) = { category="Style", subcategory="Programming Practice") fun use_for_loops(node, no_exit = false, no_function = false) = # Find while loops of the form: while Id ... loop - node is WhileLoopStmt(f_spec is WhileLoopSpec(f_expr is - rel@RelationOp(f_left is id@Identifier) + node is WhileLoopStmt(f_spec: WhileLoopSpec(f_expr: + rel@RelationOp(f_left: id@Identifier) when stdlib.is_predefined_op(rel.f_op))) when { val refs = write_references(node.f_stmts, id); @@ -60,12 +60,12 @@ fun use_for_loops(node, no_exit = false, no_function = false) = refs.length == 1 and # which is of the form: id := id +/- 1 refs[1].parent is - assign@AssignStmt(f_expr is - expr@BinOp(f_op is op@(OpPlus or OpMinus) + assign@AssignStmt(f_expr: + expr@BinOp(f_op: op@(OpPlus | OpMinus) when stdlib.is_predefined_op(op), - f_right is i@IntLiteral + f_right: i@IntLiteral when i.p_denoted_value() == 1, - f_left is Identifier(p_name_matches(id) is true))) + f_left: Identifier(p_name_matches(id): true))) # located at the very end of the loop when not assign.next_sibling() and assign.parent == node.f_stmts # and where id is declared in the same enclosing scope as the loop @@ -76,9 +76,9 @@ fun use_for_loops(node, no_exit = false, no_function = false) = and no_write_reference(decl.parent, id) # also check that there are no further references to id after the # loop. - and not node is *(any next_siblings is n@* + and not node is *(any next_siblings: n when has_references(n, id)) } and not (no_exit and exit_stmt(node)) and not (no_function and - from rel.f_right select first Name(p_is_call() is true)) + from rel.f_right select first Name(p_is_call(): true)) diff --git a/lkql_checker/share/lkql/use_for_of_loops.lkql b/lkql_checker/share/lkql/use_for_of_loops.lkql index 4a9b12a53..df9acf394 100644 --- a/lkql_checker/share/lkql/use_for_of_loops.lkql +++ b/lkql_checker/share/lkql/use_for_of_loops.lkql @@ -37,23 +37,23 @@ fun is_same_object(a, b) = fun use_for_of_loops(node, n : int = 1, ignore = false) = # Look for "for in 'Range" loops node is ForLoopStmt( - f_spec is spec@ForLoopSpec( - f_has_reverse is not ReversePresent, - f_loop_type is IterTypeIn, - f_iter_expr is attr@AttributeRef)) + f_spec: spec@ForLoopSpec( + f_has_reverse: not ReversePresent, + f_loop_type: IterTypeIn, + f_iter_expr: attr@AttributeRef)) when attr.f_attribute.p_name_is("Range") and attr.f_prefix.p_expression_type() is - iter_type@TypeDecl(p_is_array_type() is true) + iter_type@TypeDecl(p_is_array_type(): true) # where is a one dimension array. when num_indices(iter_type) == 1 and { val ids = (from node.f_stmts select - Identifier(p_name_matches(spec.f_var_decl.f_id.f_name) is true)); + Identifier(p_name_matches(spec.f_var_decl.f_id.f_name): true)); # Now check that all references to are of the form () not [f for f in ids if match f.parent - | ParamAssoc(parent is AssocList(parent is call@CallExpr)) => + | ParamAssoc(parent: AssocList(parent: call@CallExpr)) => not is_same_object(call.f_name, attr.f_prefix) | * => true] # Finally check that we have at least N references to diff --git a/lkql_checker/share/lkql/use_if_expressions.lkql b/lkql_checker/share/lkql/use_if_expressions.lkql index 3dbaaf60c..8ae6240d2 100644 --- a/lkql_checker/share/lkql/use_if_expressions.lkql +++ b/lkql_checker/share/lkql/use_if_expressions.lkql @@ -18,7 +18,7 @@ fun simple_return(l) = l.children_count == 1 and l[1] is ReturnStmt fun simple_assignment(l) = - l.children_count == 1 and l[1] is AssignStmt(f_dest is Name) + l.children_count == 1 and l[1] is AssignStmt(f_dest: Name) @check(message="IF statement may be replaced by an IF expression", category="Style", subcategory="Programming Practice") diff --git a/lkql_checker/share/lkql/use_memberships.lkql b/lkql_checker/share/lkql/use_memberships.lkql index c2b4b607e..03ff7a0a3 100644 --- a/lkql_checker/share/lkql/use_memberships.lkql +++ b/lkql_checker/share/lkql/use_memberships.lkql @@ -13,39 +13,39 @@ fun check_expr(expr, id, short_circuit) = # Strip parenthesis | ParenExpr => check_expr(expr.f_expr, id, short_circuit) # Check both "or" operands - | BinOp(f_op is OpOr or OpOrElse when short_circuit) => + | BinOp(f_op: OpOr | OpOrElse when short_circuit) => check_expr(expr.f_left, id, short_circuit) and check_expr(expr.f_right, id, short_circuit) # Allow X >= E1 and X <= E2 - | BinOp(f_op is (op@OpAnd when stdlib.is_predefined_op(op)) or + | BinOp(f_op: (op@OpAnd when stdlib.is_predefined_op(op)) | OpAndThen when short_circuit) => expr.f_left is RelationOp( - f_op is gte@OpGte, - f_left is Identifier(p_name_matches(id) is true)) when + f_op: gte@OpGte, + f_left: Identifier(p_name_matches(id): true)) when expr.f_right is RelationOp( - f_op is lte@OpLte, - f_left is Identifier(p_name_matches(id) is true)) when + f_op: lte@OpLte, + f_left: Identifier(p_name_matches(id): true)) when stdlib.is_predefined_op(gte) and stdlib.is_predefined_op(lte) # Allow X = C - | RelationOp(f_op is op@OpEq) => - expr.f_left is Name(p_name_matches(id) is true) and + | RelationOp(f_op: op@OpEq) => + expr.f_left is Name(p_name_matches(id): true) and stdlib.is_predefined_op(op) # Allow X in ... - | MembershipExpr(f_op is OpIn) => expr.f_expr.p_name_matches(id) + | MembershipExpr(f_op: OpIn) => expr.f_expr.p_name_matches(id) # Reject anything else | * => false @check(message="expression may be replaced by a membership test", category="Style", subcategory="Programming Practice") fun use_memberships(node, short_circuit = false) = - node is BinOp(parent is not Expr, - f_op is (op@OpOr when stdlib.is_predefined_op(op)) or + node is BinOp(parent: not Expr, + f_op: (op@OpOr when stdlib.is_predefined_op(op)) | OpOrElse when short_circuit) # Find a first variable used as LHS (id) and pass it to check_expr and match (from node select first - RelationOp(f_left is Identifier) - or MembershipExpr(f_expr is Identifier)) + (RelationOp(f_left: Identifier) + | MembershipExpr(f_expr: Identifier))) | r@RelationOp => check_expr(node, r.f_left, short_circuit) | m@MembershipExpr => check_expr(node, m.f_expr, short_circuit) | * => false diff --git a/lkql_checker/share/lkql/use_ranges.lkql b/lkql_checker/share/lkql/use_ranges.lkql index 2c9a58738..5b2fd0544 100644 --- a/lkql_checker/share/lkql/use_ranges.lkql +++ b/lkql_checker/share/lkql/use_ranges.lkql @@ -13,22 +13,22 @@ fun use_ranges(unit) = [ loc: n} for n in from unit.root select # Find 'Range in membership tests, for loop spec or case statements/expr - AttributeRef( - f_attribute is Identifier( - p_name_is("Range") is true), - parent is ForLoopSpec or - ExprAlternativesList or + (AttributeRef( + f_attribute: Identifier( + p_name_is("Range"): true), + parent: ForLoopSpec | + ExprAlternativesList | AlternativesList( - parent is CaseStmtAlternative or CaseExprAlternative), - f_prefix is Name( - p_referenced_decl() is BaseTypeDecl( - p_is_discrete_type() is true))) or + parent: CaseStmtAlternative | CaseExprAlternative), + f_prefix: Name( + p_referenced_decl(): BaseTypeDecl( + p_is_discrete_type(): true))) | # Find T'First .. T'Last - BinOp(f_op is OpDoubleDot, - f_left is AttributeRef( - f_attribute is Identifier(p_name_is("First") is true), - f_prefix is name@Name), - f_right is AttributeRef( - f_attribute is Identifier(p_name_is("Last") is true), - f_prefix is Name(p_name_matches(name) is true))) + BinOp(f_op: OpDoubleDot, + f_left: AttributeRef( + f_attribute: Identifier(p_name_is("First"): true), + f_prefix: name@Name), + f_right: AttributeRef( + f_attribute: Identifier(p_name_is("Last"): true), + f_prefix: Name(p_name_matches(name): true)))) ] diff --git a/lkql_checker/share/lkql/use_record_aggregates.lkql b/lkql_checker/share/lkql/use_record_aggregates.lkql index b20c8e478..3bb1181ea 100644 --- a/lkql_checker/share/lkql/use_record_aggregates.lkql +++ b/lkql_checker/share/lkql/use_record_aggregates.lkql @@ -6,25 +6,26 @@ fun assign_stmts(n, prefix) = |" Return all consecutive AssignStmt starting at n and following siblings |" when the destination is a DottedName whose prefix matches prefix. - if n is AssignStmt(f_dest is DottedName( - f_prefix is Name(p_name_matches(prefix) is true))) - then [n] & assign_stmts(n.next_sibling(), prefix) else [] + match n + | AssignStmt(f_dest: DottedName(f_prefix: Name(p_name_matches(prefix): true))) + => [n] & assign_stmts(n.next_sibling(), prefix) + | * => [] @check(message="component assignments may be replaced by an aggregate", category="Style", subcategory="Programming Practice") fun use_record_aggregates(node) = node is AssignStmt( - f_dest is DottedName( - f_prefix is prefix@Name, - f_suffix is Identifier( - p_referenced_decl() is ComponentDecl( - p_semantic_parent() is type@TypeDecl( - f_discriminants is null, - p_is_tagged_type() is false))))) + f_dest: DottedName( + f_prefix: prefix@Name, + f_suffix: Identifier( + p_referenced_decl(): ComponentDecl( + p_semantic_parent(): type@TypeDecl( + f_discriminants: null, + p_is_tagged_type(): false))))) # Only check for the first assignment in a row when node.previous_sibling() is not - AssignStmt(f_dest is DottedName( - f_prefix is Name(p_name_matches(prefix) is true))) and + AssignStmt(f_dest: DottedName( + f_prefix: Name(p_name_matches(prefix): true))) and { val num_comps = (from type.f_type_def select DefiningName).length; # More than 1 component @@ -32,10 +33,10 @@ fun use_record_aggregates(node) = # All components are assigned individually unique([s.f_dest.f_suffix.text for s in (from assign_stmts(node, prefix) select s@AssignStmt( - f_dest is DottedName( + f_dest: DottedName( # Check that the suffix is a ComponentDecl of the same # type. - f_suffix is Identifier(p_referenced_decl() is + f_suffix: Identifier(p_referenced_decl(): c2@ComponentDecl) when type == c2.p_semantic_parent())))]) .length == num_comps diff --git a/lkql_checker/share/lkql/use_simple_loops.lkql b/lkql_checker/share/lkql/use_simple_loops.lkql index 12c6cbfe8..ebbf92226 100644 --- a/lkql_checker/share/lkql/use_simple_loops.lkql +++ b/lkql_checker/share/lkql/use_simple_loops.lkql @@ -6,5 +6,5 @@ fun use_simple_loops(node) = # Find while loops whose condition is statically known to be True (= 1) node is WhileLoopStmt( - f_spec is WhileLoopSpec(f_expr is e@Expr(p_is_static_expr() is true) + f_spec: WhileLoopSpec(f_expr: e@Expr(p_is_static_expr(): true) when e.p_eval_as_int() == 1)) diff --git a/lkql_checker/share/lkql/variable_scoping.lkql b/lkql_checker/share/lkql/variable_scoping.lkql index 7980dff3f..1c4ace000 100644 --- a/lkql_checker/share/lkql/variable_scoping.lkql +++ b/lkql_checker/share/lkql/variable_scoping.lkql @@ -14,7 +14,7 @@ fun check_references(list, subp) = { # block with no enclosing loop and is part of subp (as opposed to a nested # subprogram). - block is BlockStmt(all parent is not BaseLoopStmt) and + block is BlockStmt(all parent: not BaseLoopStmt) and stdlib.enclosing_body(block) == subp and # Then check that no reference is outside this block apart from the @@ -39,11 +39,11 @@ fun variable_scoping(unit) = [ for n in from unit.root select node@DefiningName( - parent is DefiningNameList( - parent is decl@ObjectDecl( - f_default_expr is null, - f_renaming_clause is null, - parent is AdaNodeList( - parent is DeclarativePart(parent is subp@SubpBody))))) + parent: DefiningNameList( + parent: decl@ObjectDecl( + f_default_expr: null, + f_renaming_clause: null, + parent: AdaNodeList( + parent: DeclarativePart(parent: subp@SubpBody))))) when check_references(node.p_find_refs(subp), subp) ] diff --git a/lkql_checker/share/lkql/visible_components.lkql b/lkql_checker/share/lkql/visible_components.lkql index f41228f6f..e68b97996 100644 --- a/lkql_checker/share/lkql/visible_components.lkql +++ b/lkql_checker/share/lkql/visible_components.lkql @@ -20,11 +20,11 @@ fun has_visible_components(t) = @check(message="type defines publicly accessible components", category="Style", subcategory="Object Orientation") fun visible_components(node, tagged_only=false) = - node is TypeDecl(any parent(depth=2) is PublicPart( - parent is BasePackageDecl(any parent is LibraryItem( - f_item is PackageDecl or GenericDecl, - f_has_private is PrivateAbsent))), - all parent is not PrivatePart) + node is TypeDecl(any parent(depth=2): PublicPart( + parent: BasePackageDecl(any parent: LibraryItem( + f_item: PackageDecl | GenericDecl, + f_has_private: PrivateAbsent))), + all parent: not PrivatePart) when node.p_is_record_type() and ((not tagged_only) or node.p_is_tagged_type()) and has_visible_components(node.f_type_def) diff --git a/lkql_checker/share/lkql/volatile_objects_without_address_clauses.lkql b/lkql_checker/share/lkql/volatile_objects_without_address_clauses.lkql index c60cbf3b4..dc6644463 100644 --- a/lkql_checker/share/lkql/volatile_objects_without_address_clauses.lkql +++ b/lkql_checker/share/lkql/volatile_objects_without_address_clauses.lkql @@ -9,5 +9,5 @@ fun volatile_objects_without_address_clauses(node) = node is o@ObjectDecl when ( o.p_has_aspect("volatile") or o.f_type_expr.p_designated_type_decl() is - BaseTypeDecl(p_has_aspect("Volatile") is true) + BaseTypeDecl(p_has_aspect("Volatile"): true) ) and not o.p_has_aspect("Address") diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLContext.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLContext.java index abec3791d..99cd14b9f 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLContext.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLContext.java @@ -6,8 +6,10 @@ package com.adacore.lkql_jit; import com.adacore.libadalang.Libadalang; +import com.adacore.liblkqllang.Liblkqllang; import com.adacore.lkql_jit.built_ins.BuiltInFunctionValue; import com.adacore.lkql_jit.exception.LKQLRuntimeException; +import com.adacore.lkql_jit.nodes.LKQLNode; import com.adacore.lkql_jit.runtime.GlobalScope; import com.adacore.lkql_jit.utils.Constants; import com.adacore.lkql_jit.utils.LKQLConfigFileResult; @@ -20,6 +22,7 @@ import com.adacore.lkql_jit.utils.functions.StringUtils; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.source.Source; import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -35,6 +38,7 @@ * @author Hugo GUERRIER */ public final class LKQLContext { + private final LKQLLanguage language; // ----- Attributes ----- @@ -184,12 +188,13 @@ public final class LKQLContext { * @param env The environment. * @param global The initialized global values. */ - public LKQLContext(TruffleLanguage.Env env, GlobalScope global) { + public LKQLContext(TruffleLanguage.Env env, GlobalScope global, LKQLLanguage language) { this.env = env; this.global = global; this.specifiedSourceFiles = new ArrayList<>(); this.allSourceFiles = new ArrayList<>(); this.parsed = false; + this.language = language; } // ----- Destructors ----- @@ -794,9 +799,60 @@ public Object getRuleArg(String ruleName, String argName) { if (this.allRulesArgs == null) { this.allRulesArgs = new HashMap<>(); this.allRulesArgs.putAll(this.getRuleConfigFileResult().args()); - this.allRulesArgs.putAll( - ParsingUtils.parseRulesArgs( - this.getEnv().getOptions().get(LKQLLanguage.rulesArgs).split(";"))); + // Prepare the result + Map> res = new HashMap<>(); + + for (String ruleArgSource : + this.getEnv().getOptions().get(LKQLLanguage.rulesArgs).split(";")) { + // Verify that the rule is not empty + if (ruleArgSource.isEmpty() || ruleArgSource.isBlank()) continue; + + // Split the get the names and the value + final String[] valueSplit = ruleArgSource.split("="); + final String[] nameSplit = valueSplit[0].split("\\."); + + // Verify the rule argument syntax + if (valueSplit.length != 2 || nameSplit.length != 2) { + throw LKQLRuntimeException.fromMessage( + "Rule argument syntax error : '" + ruleArgSource + "'"); + } + + // Get the information from the rule argument source + final String ruleName1 = nameSplit[0].toLowerCase().trim(); + final String argName1 = nameSplit[1].toLowerCase().trim(); + final String valueSource = valueSplit[1].trim(); + + // Parse the value source with Liblkqllang + try (Liblkqllang.AnalysisContext analysisContext = + Liblkqllang.AnalysisContext.create()) { + // Parse the argument value source with Liblkqllang + final Liblkqllang.AnalysisUnit unit = + analysisContext.getUnitFromBuffer( + valueSource, + "rule_argument", + null, + Liblkqllang.GrammarRule.EXPR_RULE); + final Liblkqllang.LkqlNode root = unit.getRoot(); + final Source source = + Source.newBuilder(Constants.LKQL_ID, valueSource, "rule_argument") + .build(); + final LKQLNode node = language.translate(root, source); + + try { + // Add the argument in the result + Map ruleArgs = res.getOrDefault(ruleName1, new HashMap<>()); + ruleArgs.put(argName1, node.executeGeneric(null)); + res.put(ruleName1, ruleArgs); + } catch (Exception e) { + throw LKQLRuntimeException.fromMessage( + "The rule argument value generated an interpreter error: " + + valueSource); + } + } + } + + // Return the result + this.allRulesArgs.putAll(res); } Map ruleArgs = this.allRulesArgs.getOrDefault(ruleName, null); return ruleArgs == null ? null : ruleArgs.getOrDefault(argName, null); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLLanguage.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLLanguage.java index 849237319..3dc5023eb 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLLanguage.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLLanguage.java @@ -6,8 +6,11 @@ package com.adacore.lkql_jit; import com.adacore.liblkqllang.Liblkqllang; +import com.adacore.lkql_jit.built_ins.values.LKQLNamespace; import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.langkit_translator.LangkitTranslator; +import com.adacore.lkql_jit.langkit_translator.passes.FramingPass; +import com.adacore.lkql_jit.langkit_translator.passes.TranslationPass; +import com.adacore.lkql_jit.langkit_translator.passes.framing_utils.ScriptFrames; import com.adacore.lkql_jit.nodes.LKQLNode; import com.adacore.lkql_jit.nodes.TopLevelList; import com.adacore.lkql_jit.nodes.root_nodes.TopLevelRootNode; @@ -17,6 +20,7 @@ import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.Option; import com.oracle.truffle.api.TruffleLanguage; +import com.oracle.truffle.api.source.Source; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.util.List; @@ -40,6 +44,33 @@ dependentLanguages = {"regex"}) public final class LKQLLanguage extends TruffleLanguage { + /** + * This is the LKQL prelude. Those definitions are visible at the root of the LKQL context. This + * is where we put all global definitions that must be accessible in every context + */ + private static final String PRELUDE_SOURCE = + """ + selector children + |" Yields all the descendants of the given node + | AdaNode => rec(*this.children) + | * => () + + selector next_siblings + |" Yields all the next siblings of the given node + | AdaNode => rec(this.next_sibling()) + | * => () + + selector parent + |" Yields all the enclosing parents of the given node + | AdaNode => rec(this.parent) + | * => () + + selector prev_siblings + |" Yields all the previous siblings of the given node + | AdaNode => rec(this.previous_sibling()) + | * => () + """; + // ----- Static variables ----- /** The reference to the LKQL language. */ @@ -206,12 +237,14 @@ public final class LKQLLanguage extends TruffleLanguage { static final OptionKey diagnosticOutputMode = new OptionKey<>(DiagnosticOutputMode.PRETTY); + Liblkqllang.AnalysisContext lkqlAnalysisContext; + // ----- Constructors ----- /** A simple constructor for the library loading. */ public LKQLLanguage() { super(); - + this.lkqlAnalysisContext = Liblkqllang.AnalysisContext.create(); // Set the color support flag SUPPORT_COLOR = System.getenv("TERM") != null && System.console() != null; } @@ -250,7 +283,7 @@ protected LKQLContext createContext(Env env) { GlobalScope globalValues = new GlobalScope(); // Return the new context - return new LKQLContext(env, globalValues); + return new LKQLContext(env, globalValues, this); } /** @@ -299,13 +332,13 @@ protected CallTarget parse(ParsingRequest request) { final Liblkqllang.AnalysisUnit unit; TopLevelList result; - try (Liblkqllang.AnalysisContext analysisContext = Liblkqllang.AnalysisContext.create()) { + { if (request.getSource().getPath() == null) { unit = - analysisContext.getUnitFromBuffer( + lkqlAnalysisContext.getUnitFromBuffer( request.getSource().getCharacters().toString(), ""); } else { - unit = analysisContext.getUnitFromFile(request.getSource().getPath()); + unit = lkqlAnalysisContext.getUnitFromFile(request.getSource().getPath()); } // Verify the parsing result @@ -319,16 +352,11 @@ protected CallTarget parse(ParsingRequest request) { (Liblkqllang.TopLevelList) unit.getRoot(); // Translate the LKQL AST from Langkit to a Truffle AST - result = - (TopLevelList) - LangkitTranslator.translate(lkqlLangkitRoot, request.getSource()); + result = (TopLevelList) translate(lkqlLangkitRoot, request.getSource()); } - // Get the LKQL context - LKQLContext context = getContext(result); - // Print the Truffle AST if the JIT is in debug mode - if (context.isVerbose()) { + if (getContext(result).isVerbose()) { System.out.println( "=== Truffle AST <" + result.getLocation().getFileName() + "> :\n" + result); } @@ -336,4 +364,58 @@ protected CallTarget parse(ParsingRequest request) { // Return the call target return new TopLevelRootNode(result, this).getCallTarget(); } + + /** + * Translate the given source Langkit AST. + * + * @param lkqlLangkitRoot The LKQL Langkit AST to translate. + * @param source The Truffle source of the AST. + * @return The translated LKQL Truffle AST. + */ + public LKQLNode translate( + final Liblkqllang.LkqlNode lkqlLangkitRoot, final Source source, boolean isPrelude) { + + if (!isPrelude) { + var global = getContext(null).getGlobal(); + if (global.prelude == null) { + // Eval prelude + Source preludeSource = + Source.newBuilder(Constants.LKQL_ID, PRELUDE_SOURCE, "").build(); + var root = + lkqlAnalysisContext + .getUnitFromBuffer(PRELUDE_SOURCE, "") + .getRoot(); + var preludeRoot = (TopLevelList) translate(root, preludeSource, true); + var callTarget = new TopLevelRootNode(preludeRoot, this).getCallTarget(); + global.prelude = (LKQLNamespace) callTarget.call(); + var preludeMap = global.prelude.asMap(); + + var objects = new Object[preludeMap.size()]; + var i = 0; + for (var entry : preludeMap.entrySet()) { + global.preludeMap.put(entry.getKey(), i); + objects[i] = entry.getValue(); + i += 1; + } + global.preludeObjects = objects; + } + } + + // Do the framing pass to create the script frame descriptions + final FramingPass framingPass = new FramingPass(source); + lkqlLangkitRoot.accept(framingPass); + final ScriptFrames scriptFrames = + framingPass.getScriptFramesBuilder().build(CONTEXT_REFERENCE.get(null).getGlobal()); + + // Do the translation pass and return the result + final TranslationPass translationPass = new TranslationPass(source, scriptFrames); + + var res = lkqlLangkitRoot.accept(translationPass); + + return res; + } + + public LKQLNode translate(final Liblkqllang.LkqlNode lkqlLangkitRoot, final Source source) { + return translate(lkqlLangkitRoot, source, false); + } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java index 5d22da317..85ada0ff6 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/LKQLTypeSystem.java @@ -9,6 +9,7 @@ import com.adacore.lkql_jit.built_ins.values.*; import com.adacore.lkql_jit.built_ins.values.interfaces.Iterable; import com.adacore.lkql_jit.built_ins.values.interfaces.*; +import com.adacore.lkql_jit.built_ins.values.lists.BaseLKQLList; import com.adacore.lkql_jit.built_ins.values.lists.LKQLLazyList; import com.adacore.lkql_jit.built_ins.values.lists.LKQLList; import com.oracle.truffle.api.CompilerDirectives; @@ -35,6 +36,7 @@ LKQLTuple.class, LKQLList.class, LKQLLazyList.class, + BaseLKQLList.class, Indexable.class, Iterable.class, Libadalang.AdaNode.class, @@ -44,6 +46,7 @@ LKQLNamespace.class, LKQLObject.class, Nullish.class, + LKQLRecValue.class, LKQLValue.class, }) public abstract class LKQLTypeSystem { diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/BuiltInsHolder.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/BuiltInsHolder.java index df64cd329..e44a2ca1f 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/BuiltInsHolder.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/BuiltInsHolder.java @@ -40,15 +40,6 @@ public final class BuiltInsHolder { NodeCheckerFunction.getValue(), UnitCheckerFunction.getValue()); - /** The built-in selector list. */ - public final List builtInSelectors = - List.of( - ChildrenSelector.getInstance(), - ParentSelector.getInstance(), - NextSiblingsSelector.getInstance(), - PrevSiblingsSelector.getInstance(), - SuperTypesSelector.getInstance()); - /** The built-in method list. */ public final Map> builtInMethods = Map.ofEntries( diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/DocumentBuiltins.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/DocumentBuiltins.java index 9dd041553..22a56df8b 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/DocumentBuiltins.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/DocumentBuiltins.java @@ -43,23 +43,6 @@ public static String documentBuiltinsImpl(MaterializedFrame frame, FunCall call) writer.write("\n"); } - writer.write("Builtin selectors\n"); - writer.write("^^^^^^^^^^^^^^^^^\n"); - writer.write("\n"); - - for (var sel : BuiltInsHolder.get().builtInSelectors) { - writer.write(".. function:: "); - writer.write(sel.getName()); - writer.write("()"); - writer.write("\n\n"); - writer.withIndent( - () -> { - writer.write(sel.getValue().lkqlDocumentation()); - }); - writer.write("\n"); - writer.write("\n"); - } - writer.write("Builtin methods\n"); writer.write("^^^^^^^^^^^^^^^\n"); writer.write("\n"); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java index 3128c9bc5..5d5b6fc3b 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/functions/UnitCheckerFunction.java @@ -86,8 +86,6 @@ public Object executeGeneric(VirtualFrame frame) { try { this.applyUnitRule(frame, checker, unit, context, linesCache); } catch (LangkitException e) { - // TODO: Remove those clunky hardcoded names when getting rid of Ada - // implementation // Report LAL exception only in debug mode if (context.isCheckerDebug()) { context.getDiagnosticEmitter() @@ -100,8 +98,6 @@ public Object executeGeneric(VirtualFrame frame) { context); } } catch (LKQLRuntimeException e) { - // TODO: Remove those clunky hardcoded names when getting rid of Ada - // implementation context.getDiagnosticEmitter() .emitInternalError( checker.getName(), diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ChildrenSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ChildrenSelector.java deleted file mode 100644 index 480ddf80e..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ChildrenSelector.java +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.BuiltInSelectorValue; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.nodes.Identifier; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; -import com.adacore.lkql_jit.nodes.expressions.Unpack; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccess; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccessNodeGen; -import com.adacore.lkql_jit.nodes.expressions.literals.UnitLiteral; -import com.adacore.lkql_jit.nodes.patterns.UniversalPattern; -import com.adacore.lkql_jit.nodes.patterns.node_patterns.NodeKindPattern; - -/** - * This class represents the "children" built-in selector. - * - * @author Hugo GUERRIER - */ -public final class ChildrenSelector implements BuiltInSelector { - - // ----- Attributes ----- - - /** The only instance of the "children" built-in selector. */ - private static ChildrenSelector instance = null; - - /** The name of the selector. */ - public static final String NAME = "children"; - - /** The arms representing the "children" selector execution. */ - public final SelectorArm[] arms; - - // ----- Constructors ----- - - /** Private constructor. */ - private ChildrenSelector() { - this.arms = createArms(); - } - - /** - * Get the only instance of the built-in selector. - * - * @return The instance of the selector. - */ - public static ChildrenSelector getInstance() { - if (instance == null) { - instance = new ChildrenSelector(); - } - return instance; - } - - // ----- Override methods ----- - - /** - * @see BuiltInSelector#getName() - */ - @Override - public String getName() { - return NAME; - } - - /** - * @see BuiltInSelector#getValue() - */ - @Override - public LKQLSelector getValue() { - return new BuiltInSelectorValue( - NAME, "Yields all the descendants of the given node in the tree\n", this.arms); - } - - // ----- Class methods ----- - - /** - * Create the selector arms and return them. - * - * @return The selector arms. - */ - private static SelectorArm[] createArms() { - // Prepare the result - SelectorArm[] res = new SelectorArm[2]; - - // Create the children path - DotAccess toUnpack = - DotAccessNodeGen.create( - null, new Identifier(null, "children"), new ReadBuiltInThis()); - SelectorArm childrenPath = - new SelectorArm( - null, - new NodeKindPattern(null, "AdaNode"), - new SelectorExpr(null, SelectorExpr.Mode.REC, new Unpack(null, toUnpack))); - res[0] = childrenPath; - - // Create the universal path - SelectorArm universalPath = - new SelectorArm( - null, - new UniversalPattern(null), - new SelectorExpr(null, SelectorExpr.Mode.DEFAULT, new UnitLiteral(null))); - res[1] = universalPath; - - // Return the result - return res; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/NextSiblingsSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/NextSiblingsSelector.java deleted file mode 100644 index 8e72181c6..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/NextSiblingsSelector.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.BuiltInSelectorValue; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.nodes.Identifier; -import com.adacore.lkql_jit.nodes.arguments.Arg; -import com.adacore.lkql_jit.nodes.arguments.ArgList; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; -import com.adacore.lkql_jit.nodes.expressions.FunCall; -import com.adacore.lkql_jit.nodes.expressions.FunCallNodeGen; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccess; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccessNodeGen; -import com.adacore.lkql_jit.nodes.expressions.literals.UnitLiteral; -import com.adacore.lkql_jit.nodes.patterns.UniversalPattern; -import com.adacore.lkql_jit.nodes.patterns.node_patterns.NodeKindPattern; - -/** - * This class represents the "next_siblings" built-in selector. - * - * @author Hugo GUERRIER - */ -public final class NextSiblingsSelector implements BuiltInSelector { - - // ----- Attributes ----- - - /** The only instance of the "next_siblings" built-in selector. */ - private static NextSiblingsSelector instance = null; - - /** The name of the selector. */ - public static final String NAME = "next_siblings"; - - /** The arms representing the "next_siblings" selector execution. */ - public final SelectorArm[] arms; - - // ----- Constructors ----- - - /** Private constructor. */ - private NextSiblingsSelector() { - this.arms = createArms(); - } - - /** - * Get the only instance of the built-in selector. - * - * @return The instance of the selector. - */ - public static NextSiblingsSelector getInstance() { - if (instance == null) { - instance = new NextSiblingsSelector(); - } - return instance; - } - - // ----- Override methods ----- - - /** - * @see BuiltInSelector#getName() - */ - @Override - public String getName() { - return NAME; - } - - /** - * @see BuiltInSelector#getValue() - */ - @Override - public LKQLSelector getValue() { - return new BuiltInSelectorValue( - NAME, "Yields the siblings following the given node in the tree\n", this.arms); - } - - // ----- Class methods ----- - - /** - * Create the selector arms and return them. - * - * @return The selector arms. - */ - private static SelectorArm[] createArms() { - // Create the selector arms - SelectorArm[] res = new SelectorArm[2]; - - // Create the next sibling path - DotAccess propertyAccess = - DotAccessNodeGen.create( - null, new Identifier(null, "next_sibling"), new ReadBuiltInThis()); - FunCall funCall = - FunCallNodeGen.create( - null, false, null, new ArgList(null, new Arg[0]), propertyAccess); - SelectorArm nextSiblingPath = - new SelectorArm( - null, - new NodeKindPattern(null, "AdaNode"), - new SelectorExpr(null, SelectorExpr.Mode.REC, funCall)); - res[0] = nextSiblingPath; - - // Create the universal pattern - SelectorArm universalPath = - new SelectorArm( - null, - new UniversalPattern(null), - new SelectorExpr(null, SelectorExpr.Mode.DEFAULT, new UnitLiteral(null))); - res[1] = universalPath; - - // Return the result - return res; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ParentSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ParentSelector.java deleted file mode 100644 index df55c0c82..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ParentSelector.java +++ /dev/null @@ -1,108 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.BuiltInSelectorValue; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.nodes.Identifier; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccess; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccessNodeGen; -import com.adacore.lkql_jit.nodes.expressions.literals.UnitLiteral; -import com.adacore.lkql_jit.nodes.patterns.UniversalPattern; -import com.adacore.lkql_jit.nodes.patterns.node_patterns.NodeKindPattern; - -/** - * This class represents the "parent" built-in selector. - * - * @author Hugo GUERRIER - */ -public final class ParentSelector implements BuiltInSelector { - - // ----- Attributes ----- - - /** The only instance of the "parent" built-in selector. */ - private static ParentSelector instance = null; - - /** The name of the selector. */ - public static final String NAME = "parent"; - - /** The arms representing the "parent" selector execution. */ - public final SelectorArm[] arms; - - // ----- Constructors ----- - - /** Private constructor. */ - private ParentSelector() { - this.arms = this.createArms(); - } - - /** - * Get the only instance of the built-in selector. - * - * @return The instance of the selector. - */ - public static ParentSelector getInstance() { - if (instance == null) { - instance = new ParentSelector(); - } - return instance; - } - - // ----- Override methods ----- - - /** - * @see BuiltInSelector#getName() - */ - @Override - public String getName() { - return NAME; - } - - /** - * @see BuiltInSelector#getValue() - */ - @Override - public LKQLSelector getValue() { - return new BuiltInSelectorValue( - NAME, "Yields the parents (ancestors) of the given node in the tree\n", this.arms); - } - - // ----- Class methods ----- - - /** - * Create the selector arms and return them. - * - * @return The selector arms. - */ - private SelectorArm[] createArms() { - // Prepare the result - SelectorArm[] res = new SelectorArm[2]; - - // Create the children path - DotAccess toUnpack = - DotAccessNodeGen.create( - null, new Identifier(null, "parent"), new ReadBuiltInThis()); - SelectorArm parentPath = - new SelectorArm( - null, - new NodeKindPattern(null, "AdaNode"), - new SelectorExpr(null, SelectorExpr.Mode.REC, toUnpack)); - res[0] = parentPath; - - // Create the universal path - SelectorArm universalPath = - new SelectorArm( - null, - new UniversalPattern(null), - new SelectorExpr(null, SelectorExpr.Mode.DEFAULT, new UnitLiteral(null))); - res[1] = universalPath; - - // Return the result - return res; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/PrevSiblingsSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/PrevSiblingsSelector.java deleted file mode 100644 index 1f221f64f..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/PrevSiblingsSelector.java +++ /dev/null @@ -1,115 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.BuiltInSelectorValue; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.nodes.Identifier; -import com.adacore.lkql_jit.nodes.arguments.Arg; -import com.adacore.lkql_jit.nodes.arguments.ArgList; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; -import com.adacore.lkql_jit.nodes.expressions.FunCall; -import com.adacore.lkql_jit.nodes.expressions.FunCallNodeGen; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccess; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccessNodeGen; -import com.adacore.lkql_jit.nodes.expressions.literals.UnitLiteral; -import com.adacore.lkql_jit.nodes.patterns.UniversalPattern; -import com.adacore.lkql_jit.nodes.patterns.node_patterns.NodeKindPattern; - -/** - * This class represents the "previous_siblings" built-in selector. - * - * @author Hugo GUERRIER - */ -public final class PrevSiblingsSelector implements BuiltInSelector { - - // ----- Attributes ----- - - /** The only instance of the "previous_siblings" built-in selector. */ - private static PrevSiblingsSelector instance = null; - - /** The name of the selector. */ - public static final String NAME = "prev_siblings"; - - /** The arms representing the "previous_siblings" selector execution. */ - public final SelectorArm[] arms; - - // ----- Constructors ----- - - /** Private constructor. */ - private PrevSiblingsSelector() { - this.arms = createArms(); - } - - /** - * Get the only instance of the built-in selector. - * - * @return The instance of the selector. - */ - public static PrevSiblingsSelector getInstance() { - if (instance == null) { - instance = new PrevSiblingsSelector(); - } - return instance; - } - - // ----- Override methods ----- - - /** - * @see BuiltInSelector#getName() - */ - @Override - public String getName() { - return NAME; - } - - /** - * @see BuiltInSelector#getValue() - */ - @Override - public LKQLSelector getValue() { - return new BuiltInSelectorValue( - NAME, "Yields the siblings preceding the given node in the tree\n", this.arms); - } - - // ----- Class methods ----- - - /** - * Create the selector arms and return them. - * - * @return The selector arms. - */ - private static SelectorArm[] createArms() { - // Prepare the result - SelectorArm[] res = new SelectorArm[2]; - - // Create the previous path - DotAccess propertyAccess = - DotAccessNodeGen.create( - null, new Identifier(null, "previous_sibling"), new ReadBuiltInThis()); - FunCall funCall = - FunCallNodeGen.create( - null, false, null, new ArgList(null, new Arg[0]), propertyAccess); - SelectorArm prevSiblingPath = - new SelectorArm( - null, - new NodeKindPattern(null, "AdaNode"), - new SelectorExpr(null, SelectorExpr.Mode.REC, funCall)); - res[0] = prevSiblingPath; - - // Create the universal path - SelectorArm universalPath = - new SelectorArm( - null, - new UniversalPattern(null), - new SelectorExpr(null, SelectorExpr.Mode.DEFAULT, new UnitLiteral(null))); - res[1] = universalPath; - - // Return the result - return res; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java deleted file mode 100644 index c4800984a..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/ReadBuiltInThis.java +++ /dev/null @@ -1,44 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; -import com.adacore.lkql_jit.nodes.expressions.Expr; -import com.oracle.truffle.api.frame.VirtualFrame; - -/** - * This expression represents the "this" variable reading for the built-in selectors. - * - * @author Hugo GUERRIER - */ -public final class ReadBuiltInThis extends Expr { - - /** Create a new read "this" node. */ - public ReadBuiltInThis() { - super(null); - } - - /** - * Get the "this" variable that is the first argument of the frame. - * - * @see - * com.adacore.lkql_jit.nodes.LKQLNode#executeGeneric(com.oracle.truffle.api.frame.VirtualFrame) - */ - @Override - public Object executeGeneric(VirtualFrame frame) { - return ((LKQLDepthValue) frame.getArguments()[1]).value; - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return "BUILT_IN NODE"; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/SuperTypesSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/SuperTypesSelector.java deleted file mode 100644 index e86eb4c4b..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/selectors/SuperTypesSelector.java +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.built_ins.selectors; - -import com.adacore.lkql_jit.built_ins.BuiltInSelectorValue; -import com.adacore.lkql_jit.built_ins.values.LKQLSelector; -import com.adacore.lkql_jit.nodes.Identifier; -import com.adacore.lkql_jit.nodes.arguments.Arg; -import com.adacore.lkql_jit.nodes.arguments.ArgList; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; -import com.adacore.lkql_jit.nodes.expressions.FunCall; -import com.adacore.lkql_jit.nodes.expressions.FunCallNodeGen; -import com.adacore.lkql_jit.nodes.expressions.Unpack; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccess; -import com.adacore.lkql_jit.nodes.expressions.dot.DotAccessNodeGen; -import com.adacore.lkql_jit.nodes.expressions.literals.UnitLiteral; -import com.adacore.lkql_jit.nodes.patterns.UniversalPattern; -import com.adacore.lkql_jit.nodes.patterns.node_patterns.NodeKindPattern; - -/** - * This class represents the "super_types" built-in selector. - * - * @author Hugo GUERRIER - */ -public final class SuperTypesSelector implements BuiltInSelector { - - // ----- Attributes ----- - - /** The only instance of the "super_types" built-in selector. */ - private static SuperTypesSelector instance = null; - - /** The name of the selector. */ - public static final String NAME = "super_types"; - - /** The arms representing the "super_types" selector execution. */ - public final SelectorArm[] arms; - - // ----- Constructors ----- - - /** Private constructors. */ - private SuperTypesSelector() { - this.arms = createArms(); - } - - /** - * Get the only instance of the built-in selector. - * - * @return The instance of the selector. - */ - public static SuperTypesSelector getInstance() { - if (instance == null) { - instance = new SuperTypesSelector(); - } - return instance; - } - - // ----- Override methods ----- - - /** - * @see BuiltInSelector#getName() - */ - @Override - public String getName() { - return NAME; - } - - /** - * @see BuiltInSelector#getValue() - */ - @Override - public LKQLSelector getValue() { - return new BuiltInSelectorValue( - NAME, "Given a TypeDecl node, yields all the super types of the type\n", this.arms); - } - - // ----- Class methods ----- - - /** - * Create the selector arms and return them. - * - * @return The selector arms. - */ - private static SelectorArm[] createArms() { - // Create the arms - SelectorArm[] res = new SelectorArm[2]; - - // Create the base type path - DotAccess propertyAccess = - DotAccessNodeGen.create( - null, new Identifier(null, "p_base_types"), new ReadBuiltInThis()); - FunCall propertyCall = - FunCallNodeGen.create( - null, false, null, new ArgList(null, new Arg[0]), propertyAccess); - SelectorArm baseTypePath = - new SelectorArm( - null, - new NodeKindPattern(null, "BaseTypeDecl"), - new SelectorExpr( - null, SelectorExpr.Mode.REC, new Unpack(null, propertyCall))); - res[0] = baseTypePath; - - // Create the universal path - SelectorArm universalPath = - new SelectorArm( - null, - new UniversalPattern(null), - new SelectorExpr(null, SelectorExpr.Mode.DEFAULT, new UnitLiteral(null))); - res[1] = universalPath; - - // Return the result - return res; - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java index 33d72e84d..b395d700c 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLDepthValue.java @@ -35,10 +35,11 @@ public final class LKQLDepthValue extends BasicLKQLValue { public LKQLDepthValue(int depth, Object value) { this.depth = depth; this.value = value; + if (value instanceof LKQLDepthValue) { + assert false; + } } - // ----- Value methods ----- - /** Exported message to compare two LKQL depth nodes. */ @ExportMessage public static class IsIdenticalOrUndefined { diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLRecValue.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLRecValue.java new file mode 100644 index 000000000..359012f0e --- /dev/null +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLRecValue.java @@ -0,0 +1,21 @@ +// +// Copyright (C) 2005-2024, AdaCore +// SPDX-License-Identifier: GPL-3.0-or-later +// + +package com.adacore.lkql_jit.built_ins.values; + +import com.adacore.lkql_jit.built_ins.values.bases.BasicLKQLValue; + +public class LKQLRecValue extends BasicLKQLValue { + public final Object[] recurseVal; + public final Object[] resultVal; + + public int depth; + + public LKQLRecValue(Object[] recurseVal, Object[] resultVal) { + this.recurseVal = recurseVal; + this.resultVal = resultVal; + this.depth = -1; + } +} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLSelector.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLSelector.java index 7c5cf25df..307d9baca 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLSelector.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/LKQLSelector.java @@ -5,7 +5,6 @@ package com.adacore.lkql_jit.built_ins.values; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.built_ins.values.bases.BasicLKQLValue; import com.adacore.lkql_jit.built_ins.values.lists.LKQLSelectorList; import com.adacore.lkql_jit.nodes.root_nodes.SelectorRootNode; @@ -59,9 +58,9 @@ public LKQLSelector( // ----- Instance functions ----- - /** Execute the selector value on an ada node. */ - public LKQLSelectorList getList(Libadalang.AdaNode node) { - return this.getList(node, -1, -1, -1); + /** Execute the selector value. */ + public LKQLSelectorList getList(Object value) { + return this.getList(value, -1, -1, -1); } /** @@ -72,9 +71,8 @@ public LKQLSelectorList getList(Libadalang.AdaNode node) { * @param minDepth The minimal depth of the selector list. * @param depth The precise depth to get. */ - public LKQLSelectorList getList( - Libadalang.AdaNode node, int maxDepth, int minDepth, int depth) { - return new LKQLSelectorList(this.rootNode, this.closure, node, maxDepth, minDepth, depth); + public LKQLSelectorList getList(Object value, int maxDepth, int minDepth, int depth) { + return new LKQLSelectorList(this.rootNode, this.closure, value, maxDepth, minDepth, depth); } // ----- Value methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java index 6e142dfcd..29e7cc276 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLLazyList.java @@ -8,8 +8,11 @@ import com.adacore.lkql_jit.built_ins.values.iterators.LKQLIterator; import com.adacore.lkql_jit.built_ins.values.iterators.LKQLLazyListIterator; import com.adacore.lkql_jit.exception.utils.InvalidIndexException; +import com.adacore.lkql_jit.utils.Constants; +import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; import java.util.ArrayList; @@ -69,4 +72,12 @@ public LKQLIterator iterator() { public static int identityHashCode(LKQLLazyList receiver) { return System.identityHashCode(receiver); } + + @Override + @ExportMessage + public Object toDisplayString( + @SuppressWarnings("unused") final boolean allowSideEffect, + @CachedLibrary(limit = Constants.DISPATCHED_LIB_LIMIT) InteropLibrary elems) { + return "<" + LKQLTypesHelper.LKQL_LAZY_LIST + ">"; + } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java index ed29fd96f..32d4702c9 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/built_ins/values/lists/LKQLSelectorList.java @@ -5,10 +5,8 @@ package com.adacore.lkql_jit.built_ins.values.lists; -import com.adacore.libadalang.Libadalang; -import com.adacore.lkql_jit.LKQLTypeSystemGen; import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; -import com.adacore.lkql_jit.exception.LKQLRuntimeException; +import com.adacore.lkql_jit.built_ins.values.LKQLRecValue; import com.adacore.lkql_jit.exception.utils.InvalidIndexException; import com.adacore.lkql_jit.nodes.dispatchers.SelectorDispatcher; import com.adacore.lkql_jit.nodes.dispatchers.SelectorDispatcherNodeGen; @@ -59,7 +57,6 @@ public class LKQLSelectorList extends LKQLLazyList { * * @param rootNode The selector root node. * @param closure The closure for the root node execution. - * @param adaNode The ada node. * @param maxDepth The maximum depth of the returned nodes. * @param minDepth The minimum depth of the returned nodes. * @param depth The precise required depth of the returned nodes. @@ -68,7 +65,7 @@ public class LKQLSelectorList extends LKQLLazyList { public LKQLSelectorList( final SelectorRootNode rootNode, final Closure closure, - final Libadalang.AdaNode adaNode, + final Object value, final int maxDepth, final int minDepth, final int depth) { @@ -80,7 +77,7 @@ public LKQLSelectorList( this.maxDepth = maxDepth; this.minDepth = minDepth; this.exactDepth = depth; - this.recursList.add(new LKQLDepthValue(0, adaNode)); + this.recursList.add(new LKQLDepthValue(0, value)); } // ----- Lazy list required methods ----- @@ -90,102 +87,51 @@ public void computeItemAt(long n) { while (!(this.recursList.size() == 0) && (this.cache.size() - 1 < n || n == -1)) { // Get the first recurse item and execute the selector on it LKQLDepthValue nextNode = this.recursList.remove(0); - SelectorRootNode.SelectorCallResult result = + LKQLRecValue result = this.dispatcher.executeDispatch( this.rootNode, this.closure.getContent(), nextNode); - // If the result is a selector call result, do the needed operations - if (!LKQLTypeSystemGen.isNullish(result.result())) { - switch (result.mode()) { - case REC -> this.addRecursAndResult(result.result()); - case DEFAULT -> this.addResult(result.result()); - case SKIP -> this.addRecurs(result.result()); - } - } + addToRecurs(result.recurseVal, result.depth); + addToResult(result.resultVal, result.depth); } } /** Add the object to the result cache of the selector list. */ @CompilerDirectives.TruffleBoundary - private void addResult(Object toAdd) { - // If the object is just a node - if (toAdd instanceof LKQLDepthValue node) { - if (!this.alreadyVisited.contains(node)) { - this.addNodeResult(node); - } - } - - // If the object is an array of node - else if (toAdd instanceof LKQLDepthValue[] nodes) { - for (LKQLDepthValue node : nodes) { - if (!this.alreadyVisited.contains(node)) { - this.addNodeResult(node); - } - } - } else { - throw LKQLRuntimeException.shouldNotHappen("Should not happen"); + private void addToResult(Object[] toAdd, int depth) { + for (var val : toAdd) { + var depthVal = new LKQLDepthValue(depth, val); + this.addResult(depthVal); } } /** Add the object to the recursing list of the selector list. */ @CompilerDirectives.TruffleBoundary - private void addRecurs(Object toAdd) { - // If the object is just a node - if (toAdd instanceof LKQLDepthValue node) { - if (!this.alreadyVisited.contains(node)) { - this.recursList.add(node); - } - } - - // If the object is an array of node - else if (toAdd instanceof LKQLDepthValue[] nodes) { - for (LKQLDepthValue node : nodes) { - if (!this.alreadyVisited.contains(node)) { - this.recursList.add(node); - } - } - } - } - - /** Add the object to the result and the recursing list. */ - @CompilerDirectives.TruffleBoundary - private void addRecursAndResult(Object toAdd) { - // If the object is just a node - if (toAdd instanceof LKQLDepthValue node) { - if (!this.alreadyVisited.contains(node)) { - this.addNodeResult(node); - this.recursList.add(node); - } - } - - // If the object is an array of node - else if (toAdd instanceof LKQLDepthValue[] nodes) { - for (LKQLDepthValue node : nodes) { - if (!this.alreadyVisited.contains(node)) { - this.addNodeResult(node); - this.recursList.add(node); - } + private void addToRecurs(Object[] toAdd, int depth) { + for (var val : toAdd) { + var depthVal = new LKQLDepthValue(depth, val); + if (!this.alreadyVisited.contains(depthVal)) { + this.recursList.add(depthVal); + this.alreadyVisited.add(depthVal); } } } /** Add a node in the result and hashed cache with all verifications. */ @CompilerDirectives.TruffleBoundary - private void addNodeResult(LKQLDepthValue node) { + private void addResult(LKQLDepthValue value) { // If there is no defined depth if (this.exactDepth < 0) { - if ((this.maxDepth < 0 || node.depth <= this.maxDepth) - && (this.minDepth < 0 || node.depth >= this.minDepth)) { - this.cache.add(node); - this.alreadyVisited.add(node); + if ((this.maxDepth < 0 || value.depth <= this.maxDepth) + && (this.minDepth < 0 || value.depth >= this.minDepth)) { + this.cache.add(value); } } // Else, only get the wanted nodes else { - if (node.depth == this.exactDepth) { - this.cache.add(node); - this.alreadyVisited.add(node); + if (value.depth == this.exactDepth) { + this.cache.add(value); } } } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/LangkitTranslator.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/LangkitTranslator.java deleted file mode 100644 index d22cf4547..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/LangkitTranslator.java +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.langkit_translator; - -import com.adacore.liblkqllang.Liblkqllang; -import com.adacore.lkql_jit.langkit_translator.passes.FramingPass; -import com.adacore.lkql_jit.langkit_translator.passes.TranslationPass; -import com.adacore.lkql_jit.langkit_translator.passes.framing_utils.ScriptFrames; -import com.adacore.lkql_jit.nodes.LKQLNode; -import com.oracle.truffle.api.source.Source; - -/** - * This class is the top level class to translate a LKQL Langkit AST into a Truffle AST. - * - * @author Hugo GUERRIER - */ -public final class LangkitTranslator { - - /** - * Translate the given source Langkit AST. - * - * @param lkqlLangkitRoot The LKQL Langkit AST to translate. - * @param source The Truffle source of the AST. - * @return The translated LKQL Truffle AST. - */ - public static LKQLNode translate( - final Liblkqllang.LkqlNode lkqlLangkitRoot, final Source source) { - // Do the framing pass to create the script frame descriptions - final FramingPass framingPass = new FramingPass(source); - lkqlLangkitRoot.accept(framingPass); - final ScriptFrames scriptFrames = framingPass.getScriptFramesBuilder().build(); - - // Do the translation pass and return the result - final TranslationPass translationPass = new TranslationPass(source, scriptFrames); - return lkqlLangkitRoot.accept(translationPass); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java index d11f43f7f..add3c5630 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/FramingPass.java @@ -8,7 +8,6 @@ import com.adacore.liblkqllang.Liblkqllang; import com.adacore.lkql_jit.built_ins.BuiltInFunctionValue; import com.adacore.lkql_jit.built_ins.BuiltInsHolder; -import com.adacore.lkql_jit.built_ins.selectors.BuiltInSelector; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.exception.TranslatorException; import com.adacore.lkql_jit.langkit_translator.passes.framing_utils.ScriptFramesBuilder; @@ -132,11 +131,6 @@ public Void visit(Liblkqllang.TopLevelList topLevelList) { this.scriptFramesBuilder.addBuiltIn(function.getName()); } - // Add the built-in selectors - for (BuiltInSelector selector : BuiltInsHolder.get().builtInSelectors) { - this.scriptFramesBuilder.addBuiltIn(selector.getName()); - } - this.traverseChildren(topLevelList); this.scriptFramesBuilder.closeFrame(); return null; @@ -184,7 +178,7 @@ public Void visit(Liblkqllang.FunDecl funDecl) { public Void visit(Liblkqllang.SelectorArm selectorArm) { this.scriptFramesBuilder.openVirtualFrame(selectorArm); selectorArm.fPattern().accept(this); - selectorArm.fExprsList().accept(this); + selectorArm.fExpr().accept(this); this.scriptFramesBuilder.closeFrame(); return null; } @@ -273,7 +267,9 @@ public Void visit(Liblkqllang.BindingPattern bindingPattern) { // TODO: Enable the duplicate binding detection here // checkDuplicateBindings(symbol, bindingPattern.fBinding()); this.scriptFramesBuilder.addBinding(symbol); - bindingPattern.fValuePattern().accept(this); + if (!bindingPattern.fValuePattern().isNone()) { + bindingPattern.fValuePattern().accept(this); + } return null; } @@ -383,6 +379,12 @@ public Void visit(Liblkqllang.Query query) { return null; } + @Override + public Void visit(Liblkqllang.RecExpr recExpr) { + traverseChildren(recExpr); + return null; + } + /** * Create the frame description for a match arm. * @@ -496,6 +498,16 @@ public Void visit(Liblkqllang.SubBlockLiteral subBlockLiteral) { return null; } + @Override + public Void visit(Liblkqllang.UnpackAbsent unpackAbsent) { + return null; + } + + @Override + public Void visit(Liblkqllang.UnpackPresent unpackPresent) { + return null; + } + @Override public Void visit(Liblkqllang.SubBlockLiteralList subBlockLiteralList) { traverseChildren(subBlockLiteralList); @@ -652,12 +664,6 @@ public Void visit(Liblkqllang.ArithBinOp arithBinOp) { return null; } - @Override - public Void visit(Liblkqllang.Unpack unpack) { - traverseChildren(unpack); - return null; - } - @Override public Void visit(Liblkqllang.DotAccess dotAccess) { traverseChildren(dotAccess); @@ -892,36 +898,6 @@ public Void visit(Liblkqllang.FunCall funCall) { return null; } - @Override - public Void visit(Liblkqllang.SelectorExprModeDefault selectorExprModeDefault) { - traverseChildren(selectorExprModeDefault); - return null; - } - - @Override - public Void visit(Liblkqllang.SelectorExprModeRec selectorExprModeRec) { - traverseChildren(selectorExprModeRec); - return null; - } - - @Override - public Void visit(Liblkqllang.SelectorExprModeSkip selectorExprModeSkip) { - traverseChildren(selectorExprModeSkip); - return null; - } - - @Override - public Void visit(Liblkqllang.SelectorExpr selectorExpr) { - traverseChildren(selectorExpr); - return null; - } - - @Override - public Void visit(Liblkqllang.SelectorExprList selectorExprList) { - traverseChildren(selectorExprList); - return null; - } - @Override public Void visit(Liblkqllang.SelectorArmList selectorArmList) { traverseChildren(selectorArmList); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java index 37482690a..898512b54 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/TranslationPass.java @@ -17,9 +17,9 @@ import com.adacore.lkql_jit.nodes.arguments.ExprArg; import com.adacore.lkql_jit.nodes.arguments.NamedArg; import com.adacore.lkql_jit.nodes.declarations.*; +import com.adacore.lkql_jit.nodes.declarations.selector.RecExpr; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorDeclaration; -import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; import com.adacore.lkql_jit.nodes.expressions.*; import com.adacore.lkql_jit.nodes.expressions.block_expression.BlockBody; import com.adacore.lkql_jit.nodes.expressions.block_expression.BlockBodyDecl; @@ -256,6 +256,8 @@ else if (this.scriptFrames.isClosure(symbol)) { } else { return new ReadClosureUnsafe(location, slot, symbol); } + } else if (this.scriptFrames.isPrelude(symbol)) { + return new ReadPrelude(location, this.scriptFrames.getPrelude(symbol)); } // Finally look in the LKQL built-ins @@ -339,6 +341,16 @@ public LKQLNode visit(Liblkqllang.SubBlockLiteral subBlockLiteral) { return null; } + @Override + public LKQLNode visit(Liblkqllang.UnpackAbsent unpackAbsent) { + return null; + } + + @Override + public LKQLNode visit(Liblkqllang.UnpackPresent unpackPresent) { + return null; + } + @Override public LKQLNode visit(Liblkqllang.SubBlockLiteralList subBlockLiteralList) { return null; @@ -655,23 +667,6 @@ public LKQLNode visit(Liblkqllang.OpNot opNot) { return null; } - // --- Unpack node - - /** - * Visit an unpack node. - * - * @param unpack The unpack node from Langkit. - * @return The unpack node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.Unpack unpack) { - // Translate the unpack field - final Expr collectionExpr = (Expr) unpack.fCollectionExpr().accept(this); - - // Return the new unpack node - return new Unpack(loc(unpack), collectionExpr); - } - // --- Value declaration /** @@ -870,8 +865,11 @@ public LKQLNode visit(Liblkqllang.BindingPattern bindingPattern) { this.scriptFrames.declareBinding(name); final int slot = this.scriptFrames.getBinding(name); + ValuePattern pattern = null; // Visit the associated value pattern - final ValuePattern pattern = (ValuePattern) bindingPattern.fValuePattern().accept(this); + if (!bindingPattern.fValuePattern().isNone()) { + pattern = (ValuePattern) bindingPattern.fValuePattern().accept(this); + } // Return the result binding pattern node return new BindingPattern(loc(bindingPattern), slot, pattern); @@ -1082,6 +1080,20 @@ public LKQLNode visit(Liblkqllang.Query query) { return new Query(loc(query), queryKind, followGenerics, throughExpr, fromExpr, pattern); } + @Override + public LKQLNode visit(Liblkqllang.RecExpr recExpr) { + final boolean recurseHasUnpack = + recExpr.fRecurseUnpack() instanceof Liblkqllang.UnpackPresent; + final Expr recurseExpr = (Expr) recExpr.fRecurseExpr().accept(this); + + final boolean resultHasUnpack = + recExpr.fResultUnpack() instanceof Liblkqllang.UnpackPresent; + final Expr resultExpr = + recExpr.fResultExpr().isNone() ? null : (Expr) recExpr.fResultExpr().accept(this); + return new RecExpr( + loc(recExpr), recurseHasUnpack, recurseExpr, resultHasUnpack, resultExpr); + } + // --- Lists /** @@ -1443,51 +1455,6 @@ public LKQLNode visit(Liblkqllang.FunCall funCall) { // --- Selector declaration - @Override - public LKQLNode visit(Liblkqllang.SelectorExprModeDefault selectorExprModeDefault) { - return null; - } - - @Override - public LKQLNode visit(Liblkqllang.SelectorExprModeRec selectorExprModeRec) { - return null; - } - - @Override - public LKQLNode visit(Liblkqllang.SelectorExprModeSkip selectorExprModeSkip) { - return null; - } - - /** - * Visit a selector expression node. - * - * @param selectorExpr The selector expression node from Langkit. - * @return The selector expression node for Truffle. - */ - @Override - public LKQLNode visit(Liblkqllang.SelectorExpr selectorExpr) { - // Translate the selector expression fields - final Expr expr = (Expr) selectorExpr.fExpr().accept(this); - - // Get the expression mode - // TODO: Create specialized node for each mode - SelectorExpr.Mode mode = SelectorExpr.Mode.DEFAULT; - final Liblkqllang.SelectorExprMode modeNode = selectorExpr.fMode(); - if (modeNode instanceof Liblkqllang.SelectorExprModeRec) { - mode = SelectorExpr.Mode.REC; - } else if (modeNode instanceof Liblkqllang.SelectorExprModeSkip) { - mode = SelectorExpr.Mode.SKIP; - } - - // Create the new selector expression - return new SelectorExpr(loc(selectorExpr), mode, expr); - } - - @Override - public LKQLNode visit(Liblkqllang.SelectorExprList selectorExprList) { - return null; - } - /** * Visit a selector arm node. * @@ -1502,7 +1469,7 @@ public LKQLNode visit(Liblkqllang.SelectorArm selectorArm) { // Translate the selector arm fields // TODO: Question on why many expressions by arm final BasePattern pattern = (BasePattern) selectorArm.fPattern().accept(this); - final SelectorExpr expr = (SelectorExpr) selectorArm.fExprsList().getChild(0).accept(this); + final Expr expr = (Expr) selectorArm.fExpr().accept(this); // Exit the arm frame this.scriptFrames.exitFrame(); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFrames.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFrames.java index 22b400be7..051279854 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFrames.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFrames.java @@ -7,6 +7,7 @@ import com.adacore.liblkqllang.Liblkqllang; import com.adacore.lkql_jit.exception.TranslatorException; +import com.adacore.lkql_jit.runtime.GlobalScope; import com.adacore.lkql_jit.utils.ClosureDescriptor; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.FrameSlotKind; @@ -33,6 +34,8 @@ public final class ScriptFrames { /** Pointer to the current node frame. */ private AbstractNodeFrame current; + private final GlobalScope globalScope; + // ----- Constructors ----- /** @@ -40,8 +43,11 @@ public final class ScriptFrames { * * @param builtIns The built-in symbols. * @param root The root node frame of the script frames description. + * @param globalScope */ - public ScriptFrames(final List builtIns, final AbstractNodeFrame root) { + public ScriptFrames( + final List builtIns, final AbstractNodeFrame root, GlobalScope globalScope) { + this.globalScope = globalScope; this.builtIns = new HashMap<>(); for (int i = 0; i < builtIns.size(); i++) { this.builtIns.put(builtIns.get(i), i); @@ -117,6 +123,14 @@ public ClosureDescriptor getClosureDescriptor() { return ((NodeFrame) this.current).getClosureDescriptor(); } + public boolean isPrelude(final String symbol) { + return globalScope.preludeMap.containsKey(symbol); + } + + public int getPrelude(final String symbol) { + return globalScope.preludeMap.get(symbol); + } + // --- Symbol methods /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFramesBuilder.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFramesBuilder.java index 676ac6617..133cb4ccf 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFramesBuilder.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/langkit_translator/passes/framing_utils/ScriptFramesBuilder.java @@ -7,6 +7,7 @@ import com.adacore.liblkqllang.Liblkqllang; import com.adacore.lkql_jit.exception.TranslatorException; +import com.adacore.lkql_jit.runtime.GlobalScope; import java.util.ArrayList; import java.util.List; @@ -161,7 +162,7 @@ public void addParameter(final String symbol) { * * @return The script frames. */ - public ScriptFrames build() { + public ScriptFrames build(GlobalScope globalScope) { if (this.current != this.root) { throw new TranslatorException("Framing pass didn't close all opened frames"); } @@ -173,7 +174,7 @@ public ScriptFrames build() { } else { rootNodeFrame = this.root.build(null); } - return new ScriptFrames(this.builtIns, rootNodeFrame); + return new ScriptFrames(this.builtIns, rootNodeFrame, globalScope); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/RecExpr.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/RecExpr.java new file mode 100644 index 000000000..e4cbe4299 --- /dev/null +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/RecExpr.java @@ -0,0 +1,99 @@ +// +// Copyright (C) 2005-2024, AdaCore +// SPDX-License-Identifier: GPL-3.0-or-later +// + +package com.adacore.lkql_jit.nodes.declarations.selector; + +import com.adacore.lkql_jit.LKQLTypeSystemGen; +import com.adacore.lkql_jit.built_ins.values.LKQLRecValue; +import com.adacore.lkql_jit.built_ins.values.lists.BaseLKQLList; +import com.adacore.lkql_jit.exception.LKQLRuntimeException; +import com.adacore.lkql_jit.nodes.expressions.Expr; +import com.adacore.lkql_jit.utils.LKQLTypesHelper; +import com.adacore.lkql_jit.utils.source_location.SourceLocation; +import com.oracle.truffle.api.frame.VirtualFrame; + +public class RecExpr extends Expr { + + private final boolean recurseHasUnpack; + + @Child + @SuppressWarnings("FieldMayBeFinal") + private Expr recurseExpr; + + private final boolean resultHasUnpack; + + @Child + @SuppressWarnings("FieldMayBeFinal") + private Expr resultExpr; + + public RecExpr( + SourceLocation location, + boolean recurseHasUnpack, + Expr recurseExpr, + boolean resultHasUnpack, + Expr resultExpr) { + super(location); + this.recurseHasUnpack = recurseHasUnpack; + this.recurseExpr = recurseExpr; + this.resultHasUnpack = resultHasUnpack; + this.resultExpr = resultExpr; + } + + public Object executeGeneric(VirtualFrame frame) { + final var recurseExprVal = this.recurseExpr.executeGeneric(frame); + + Object[] recurseVal = null; + if (this.recurseHasUnpack) { + if (!LKQLTypeSystemGen.isBaseLKQLList(recurseExprVal)) { + throw LKQLRuntimeException.wrongType( + LKQLTypesHelper.LKQL_ITERABLE, + LKQLTypesHelper.fromJava(recurseExprVal), + this.recurseExpr); + } + BaseLKQLList i = (BaseLKQLList) recurseExprVal; + recurseVal = i.getContent(); + } else if (!LKQLTypeSystemGen.isNullish(recurseExprVal)) { + recurseVal = new Object[1]; + recurseVal[0] = recurseExprVal; + } else { + recurseVal = new Object[0]; + } + + // By default, if not specified, the result is the same as the recurse + // NOTE: we also need to propagate the unpack information if the recurse is unspecified + Object resultExprVal = null; + Boolean resultHasUnpack = this.resultHasUnpack; + if (this.resultExpr == null) { + resultExprVal = recurseExprVal; + resultHasUnpack = this.recurseHasUnpack; + } else { + resultExprVal = this.resultExpr.executeGeneric(frame); + } + + Object[] resultVal = null; + if (resultHasUnpack) { + if (!LKQLTypeSystemGen.isBaseLKQLList(resultExprVal)) { + throw LKQLRuntimeException.wrongType( + LKQLTypesHelper.LKQL_ITERABLE, + LKQLTypesHelper.fromJava(resultExprVal), + this.resultExpr); + } + BaseLKQLList i = (BaseLKQLList) resultExprVal; + resultVal = i.getContent(); + } else if (!LKQLTypeSystemGen.isNullish(resultExprVal)) { + resultVal = new Object[1]; + resultVal[0] = resultExprVal; + } else { + resultVal = new Object[0]; + } + + return new LKQLRecValue(recurseVal, resultVal); + } + + @Override + public String toString(int indentLevel) { + return null; + } +} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java index b95a431ec..ee01299cb 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorArm.java @@ -7,16 +7,14 @@ import com.adacore.lkql_jit.LKQLTypeSystemGen; import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; +import com.adacore.lkql_jit.built_ins.values.LKQLRecValue; import com.adacore.lkql_jit.exception.LKQLRuntimeException; import com.adacore.lkql_jit.nodes.LKQLNode; +import com.adacore.lkql_jit.nodes.expressions.Expr; import com.adacore.lkql_jit.nodes.patterns.BasePattern; -import com.adacore.lkql_jit.nodes.root_nodes.SelectorRootNode; import com.adacore.lkql_jit.utils.LKQLTypesHelper; import com.adacore.lkql_jit.utils.source_location.SourceLocation; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.UnexpectedResultException; -import java.util.ArrayList; -import java.util.List; /** * This node represents an arm for a selector declaration in the LKQL language. @@ -35,7 +33,7 @@ public final class SelectorArm extends LKQLNode { /** The expression to return if the arm is executed. */ @Child @SuppressWarnings("FieldMayBeFinal") - private SelectorExpr expr; + private Expr expr; // ----- Constructors ----- @@ -46,7 +44,7 @@ public final class SelectorArm extends LKQLNode { * @param pattern The pattern for the arm. * @param expr The expression to return. */ - public SelectorArm(SourceLocation location, BasePattern pattern, SelectorExpr expr) { + public SelectorArm(SourceLocation location, BasePattern pattern, Expr expr) { super(location); this.pattern = pattern; this.expr = expr; @@ -58,7 +56,7 @@ public BasePattern getPattern() { return pattern; } - public SelectorExpr getExpr() { + public Expr getExpr() { return expr; } @@ -80,50 +78,21 @@ public Object executeGeneric(VirtualFrame frame) { * @param node The node to match. * @return The result of the arm execution or null if the arm doesn't match. */ - public SelectorRootNode.SelectorCallResult executeArm(VirtualFrame frame, LKQLDepthValue node) { + public LKQLRecValue executeArm(VirtualFrame frame, LKQLDepthValue node) { if (this.pattern.executeValue(frame, node.value)) { - // Execute the selector expression - Object res = this.expr.executeGeneric(frame); - - // If the result of the expression is an array - if (res instanceof Object[] resList) { - List depthNodes = new ArrayList<>(resList.length); - for (Object obj : resList) { - // For each object of the array, verify that it is a node - try { - if (!LKQLTypeSystemGen.isNullish(obj)) { - depthNodes.add( - new LKQLDepthValue( - node.depth + 1, LKQLTypeSystemGen.expectAdaNode(obj))); - } - } - - // If it isn't a node, throw an exception - catch (UnexpectedResultException e) { - throw LKQLRuntimeException.wrongSelectorType( - LKQLTypesHelper.fromJava(obj), this.expr); - } - } - return new SelectorRootNode.SelectorCallResult( - this.expr.getMode(), depthNodes.toArray(new LKQLDepthValue[0])); + final var expr = this.expr.executeGeneric(frame); + + if (LKQLTypeSystemGen.isLKQLRecValue(expr)) { + LKQLRecValue val = LKQLTypeSystemGen.asLKQLRecValue(expr); + val.depth = node.depth + 1; + return val; + } else if (LKQLTypeSystemGen.isNullish(expr)) { + return new LKQLRecValue(new Object[0], new Object[0]); + } else { + throw LKQLRuntimeException.wrongType( + LKQLTypesHelper.LKQL_REC_VALUE, LKQLTypesHelper.fromJava(expr), this.expr); } - - // If the result of the expression is nullish - else if (LKQLTypeSystemGen.isNullish(res)) { - return new SelectorRootNode.SelectorCallResult(this.expr.getMode(), res); - } - - // If the result of the expression is a node - else if (LKQLTypeSystemGen.isAdaNode(res)) { - return new SelectorRootNode.SelectorCallResult( - this.expr.getMode(), - new LKQLDepthValue(node.depth + 1, LKQLTypeSystemGen.asAdaNode(res))); - } - - // Throw an exception - throw LKQLRuntimeException.wrongSelectorType(LKQLTypesHelper.fromJava(res), this.expr); } - // Return null if the arm hasn't been executed return null; } diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorExpr.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorExpr.java index 819993323..8f7fbe0ff 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorExpr.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/declarations/selector/SelectorExpr.java @@ -29,6 +29,8 @@ public final class SelectorExpr extends LKQLNode { @SuppressWarnings("FieldMayBeFinal") private Expr expr; + public final boolean hasUnpack; + // ----- Constructors ----- /** @@ -37,11 +39,13 @@ public final class SelectorExpr extends LKQLNode { * @param location The location of the node in the source. * @param mode The mode of the expression. * @param expr The expression. + * @param hasUnpack */ - public SelectorExpr(SourceLocation location, Mode mode, Expr expr) { + public SelectorExpr(SourceLocation location, Mode mode, Expr expr, boolean hasUnpack) { super(location); this.mode = mode; this.expr = expr; + this.hasUnpack = hasUnpack; } // ----- Getters ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java index 86f6f5808..1f001adc6 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/dispatchers/SelectorDispatcher.java @@ -6,6 +6,7 @@ package com.adacore.lkql_jit.nodes.dispatchers; import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; +import com.adacore.lkql_jit.built_ins.values.LKQLRecValue; import com.adacore.lkql_jit.nodes.root_nodes.SelectorRootNode; import com.adacore.lkql_jit.runtime.Cell; import com.oracle.truffle.api.dsl.Cached; @@ -22,7 +23,7 @@ public abstract class SelectorDispatcher extends Node { /** Function to execute the selector root node and get the result. */ - public abstract SelectorRootNode.SelectorCallResult executeDispatch( + public abstract LKQLRecValue executeDispatch( SelectorRootNode rootNode, Cell[] closure, LKQLDepthValue node); /** @@ -34,12 +35,12 @@ public abstract SelectorRootNode.SelectorCallResult executeDispatch( * @return The result of the selector call. */ @Specialization(guards = "rootNode.getRealCallTarget() == directCallNode.getCallTarget()") - protected static SelectorRootNode.SelectorCallResult executeCached( + protected static LKQLRecValue executeCached( SelectorRootNode rootNode, Cell[] closure, LKQLDepthValue node, @Cached("create(rootNode.getRealCallTarget())") DirectCallNode directCallNode) { - return (SelectorRootNode.SelectorCallResult) directCallNode.call(closure, node); + return (LKQLRecValue) directCallNode.call(closure, node); } /** @@ -51,13 +52,12 @@ protected static SelectorRootNode.SelectorCallResult executeCached( * @return The result of the selector call. */ @Specialization(replaces = "executeCached") - protected static SelectorRootNode.SelectorCallResult executeUncached( + protected static LKQLRecValue executeUncached( SelectorRootNode rootNode, Cell[] closure, LKQLDepthValue node, @Cached IndirectCallNode indirectCallNode) { - return (SelectorRootNode.SelectorCallResult) - indirectCallNode.call(rootNode.getRealCallTarget(), closure, node); + return (LKQLRecValue) indirectCallNode.call(rootNode.getRealCallTarget(), closure, node); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java index 940229f83..0ace2a683 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/FunCall.java @@ -5,7 +5,6 @@ package com.adacore.lkql_jit.nodes.expressions; -import com.adacore.libadalang.Libadalang; import com.adacore.lkql_jit.built_ins.BuiltInFunctionValue; import com.adacore.lkql_jit.built_ins.values.*; import com.adacore.lkql_jit.built_ins.values.interfaces.Nullish; @@ -27,7 +26,6 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.UnexpectedResultException; /** * This node represents a function call node in the LKQL language. @@ -212,17 +210,8 @@ protected LKQLSelectorList onSelector(VirtualFrame frame, LKQLSelector selectorV throw LKQLRuntimeException.selectorWithoutNode(this); } - // Get the node from the argument - Libadalang.AdaNode node; - try { - node = argList[0].getArgExpr().executeNode(frame); - } catch (UnexpectedResultException e) { - throw LKQLRuntimeException.wrongType( - LKQLTypesHelper.ADA_NODE, LKQLTypesHelper.fromJava(e.getResult()), argList[0]); - } - // Return the selector list value - return selectorValue.getList(node); + return selectorValue.getList(argList[0].getArgExpr().executeGeneric(frame)); } /** diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Unpack.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Unpack.java deleted file mode 100644 index 9c2ac38da..000000000 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/Unpack.java +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright (C) 2005-2024, AdaCore -// SPDX-License-Identifier: GPL-3.0-or-later -// - -package com.adacore.lkql_jit.nodes.expressions; - -import com.adacore.lkql_jit.LKQLTypeSystemGen; -import com.adacore.lkql_jit.utils.source_location.SourceLocation; -import com.oracle.truffle.api.frame.VirtualFrame; - -/** - * This node represents the unpack operation in the LKQL language. - * - * @author Hugo GUERRIER - */ -public final class Unpack extends Expr { - - // ----- Children ----- - - /** The collection to unpack. */ - @Child - @SuppressWarnings("FieldMayBeFinal") - private Expr expr; - - // ----- Constructors ----- - - /** - * Create a new unpack nod. - * - * @param location The location of the node in the source - * @param expr The collection expression to unpack - */ - public Unpack(SourceLocation location, Expr expr) { - super(location); - this.expr = expr; - } - - // ----- Execution methods ----- - - /** - * @see - * com.adacore.lkql_jit.nodes.LKQLNode#executeGeneric(com.oracle.truffle.api.frame.VirtualFrame) - */ - @Override - public Object executeGeneric(VirtualFrame frame) { - // Execute the collection expression - Object obj = this.expr.executeGeneric(frame); - - // If the result is a collection, copy it - if (LKQLTypeSystemGen.isIndexable(obj)) { - return LKQLTypeSystemGen.asIndexable(obj).getContent(); - } else { - return obj; - } - } - - // ----- Override methods ----- - - /** - * @see com.adacore.lkql_jit.nodes.LKQLNode#toString(int) - */ - @Override - public String toString(int indentLevel) { - return this.nodeRepresentation(indentLevel); - } -} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/value_read/ReadPrelude.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/value_read/ReadPrelude.java new file mode 100644 index 000000000..0503ff390 --- /dev/null +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/expressions/value_read/ReadPrelude.java @@ -0,0 +1,28 @@ +// +// Copyright (C) 2005-2024, AdaCore +// SPDX-License-Identifier: GPL-3.0-or-later +// + +package com.adacore.lkql_jit.nodes.expressions.value_read; + +import com.adacore.lkql_jit.LKQLLanguage; +import com.adacore.lkql_jit.utils.source_location.SourceLocation; +import com.oracle.truffle.api.frame.VirtualFrame; + +public class ReadPrelude extends BaseRead { + + public ReadPrelude(final SourceLocation location, final int slot) { + super(location, slot); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + return LKQLLanguage.getContext(this).getGlobal().preludeObjects[this.slot]; + } + + @Override + public String toString(int indentLevel) { + return this.nodeRepresentation( + indentLevel, new String[] {"slot"}, new Object[] {this.slot}); + } +} diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java index 5230d5a0d..dc050b4db 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/patterns/BindingPattern.java @@ -54,7 +54,7 @@ public boolean executeValue(VirtualFrame frame, Object value) { FrameUtils.writeLocal(frame, this.slot, value); // Execute the pattern with the binding done - return this.pattern.executeValue(frame, value); + return this.pattern == null || this.pattern.executeValue(frame, value); } // ----- Override methods ----- diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java index 825464501..1c56df671 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/nodes/root_nodes/SelectorRootNode.java @@ -6,7 +6,7 @@ package com.adacore.lkql_jit.nodes.root_nodes; import com.adacore.lkql_jit.built_ins.values.LKQLDepthValue; -import com.adacore.lkql_jit.built_ins.values.LKQLUnit; +import com.adacore.lkql_jit.built_ins.values.LKQLRecValue; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorArm; import com.adacore.lkql_jit.nodes.declarations.selector.SelectorExpr; import com.adacore.lkql_jit.utils.functions.FrameUtils; @@ -19,8 +19,7 @@ * * @author Hugo GUERRIER */ -public final class SelectorRootNode - extends MemoizedRootNode { +public final class SelectorRootNode extends MemoizedRootNode { // ----- Attributes ----- @@ -78,12 +77,14 @@ public Object execute(VirtualFrame frame) { // Initialize the frame this.initFrame(frame); - // Get the node and set it into the frame + // Get the depthVal and set it into the frame LKQLDepthValue value = (LKQLDepthValue) frame.getArguments()[1]; // Try memoization if (this.isMemoized) { - if (this.isMemoized(value)) return this.getMemoized(value); + if (this.isMemoized(value)) { + return this.getMemoized(value); + } } if (this.thisSlot > -1 && this.depthSlot > -1) { @@ -92,7 +93,7 @@ public Object execute(VirtualFrame frame) { } // Prepare the result - SelectorCallResult res = null; + LKQLRecValue res = null; // Try to match an arm, if there is none, set the result to unit for (SelectorArm arm : this.arms) { @@ -100,7 +101,7 @@ public Object execute(VirtualFrame frame) { if (res != null) break; } if (res == null) { - res = new SelectorCallResult(SelectorExpr.Mode.DEFAULT, LKQLUnit.INSTANCE); + res = new LKQLRecValue(new Object[0], new Object[0]); } // Do the memoization cache addition diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/runtime/GlobalScope.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/runtime/GlobalScope.java index 88c923c1b..53884a99c 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/runtime/GlobalScope.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/runtime/GlobalScope.java @@ -7,7 +7,7 @@ import com.adacore.lkql_jit.built_ins.BuiltInFunctionValue; import com.adacore.lkql_jit.built_ins.BuiltInsHolder; -import com.adacore.lkql_jit.built_ins.selectors.BuiltInSelector; +import com.adacore.lkql_jit.built_ins.values.LKQLNamespace; import com.adacore.lkql_jit.utils.checkers.BaseChecker; import com.oracle.truffle.api.CompilerDirectives; import java.util.HashMap; @@ -26,9 +26,14 @@ public final class GlobalScope { /** The defined LKQL rules. */ private final Map checkers; - /** The array containing the built-in functions and selectors. */ + /** The array containing the built-in functions . */ private final Object[] builtIns; + public LKQLNamespace prelude = null; + + public HashMap preludeMap = new HashMap<>(); + public Object[] preludeObjects = null; + /** The meta tables that contains built-in methods. */ private final Map> metaTables; @@ -57,12 +62,6 @@ public GlobalScope() { builtIns[i] = function; } - // Add the built-in selectors - for (int i = 0; i < builtInsHolder.builtInSelectors.size(); i++) { - BuiltInSelector selector = builtInsHolder.builtInSelectors.get(i); - builtIns[i + builtInsHolder.builtInFunctions.size()] = selector.getValue(); - } - // Add the built-in methods for (var entry : builtInsHolder.builtInMethods.entrySet()) { var methods = new HashMap(); diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/LKQLTypesHelper.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/LKQLTypesHelper.java index 582c3bd12..2ccf513fc 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/LKQLTypesHelper.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/LKQLTypesHelper.java @@ -71,6 +71,8 @@ public final class LKQLTypesHelper { /** The string representing the LKQL namespace type. */ public static final String LKQL_NAMESPACE = "Namespace"; + public static final String LKQL_REC_VALUE = "RecValue"; + /** The string representing the ada node type. */ public static final String ADA_NODE = "Node"; diff --git a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/ParsingUtils.java b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/ParsingUtils.java index 0493ae3a7..8eff6e498 100644 --- a/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/ParsingUtils.java +++ b/lkql_jit/language/src/main/java/com/adacore/lkql_jit/utils/functions/ParsingUtils.java @@ -5,14 +5,11 @@ package com.adacore.lkql_jit.utils.functions; -import com.adacore.liblkqllang.Liblkqllang; import com.adacore.lkql_jit.LKQLContext; import com.adacore.lkql_jit.LKQLTypeSystemGen; import com.adacore.lkql_jit.built_ins.values.LKQLNamespace; import com.adacore.lkql_jit.built_ins.values.LKQLObject; import com.adacore.lkql_jit.exception.LKQLRuntimeException; -import com.adacore.lkql_jit.langkit_translator.LangkitTranslator; -import com.adacore.lkql_jit.nodes.LKQLNode; import com.adacore.lkql_jit.utils.Constants; import com.adacore.lkql_jit.utils.LKQLConfigFileResult; import com.oracle.truffle.api.CallTarget; @@ -34,67 +31,6 @@ public class ParsingUtils { // ----- Rules arguments from command line ----- - /** - * Parse the command line rule arguments. - * - * @param argsSource The source of rule arguments to parse. - * @return The map containing the rules arguments. - */ - public static Map> parseRulesArgs(final String[] argsSource) { - // Prepare the result - Map> res = new HashMap<>(); - - for (String ruleArgSource : argsSource) { - // Verify that the rule is not empty - if (ruleArgSource.isEmpty() || ruleArgSource.isBlank()) continue; - - // Split the get the names and the value - final String[] valueSplit = ruleArgSource.split("="); - final String[] nameSplit = valueSplit[0].split("\\."); - - // Verify the rule argument syntax - if (valueSplit.length != 2 || nameSplit.length != 2) { - throw LKQLRuntimeException.fromMessage( - "Rule argument syntax error : '" + ruleArgSource + "'"); - } - - // Get the information from the rule argument source - final String ruleName = nameSplit[0].toLowerCase().trim(); - final String argName = nameSplit[1].toLowerCase().trim(); - final String valueSource = valueSplit[1].trim(); - - // Parse the value source with Liblkqllang - try (Liblkqllang.AnalysisContext analysisContext = - Liblkqllang.AnalysisContext.create()) { - // Parse the argument value source with Liblkqllang - final Liblkqllang.AnalysisUnit unit = - analysisContext.getUnitFromBuffer( - valueSource, - "rule_argument", - null, - Liblkqllang.GrammarRule.EXPR_RULE); - final Liblkqllang.LkqlNode root = unit.getRoot(); - final Source source = - Source.newBuilder(Constants.LKQL_ID, valueSource, "rule_argument").build(); - final LKQLNode node = LangkitTranslator.translate(root, source); - - try { - // Add the argument in the result - Map ruleArgs = res.getOrDefault(ruleName, new HashMap<>()); - ruleArgs.put(argName, node.executeGeneric(null)); - res.put(ruleName, ruleArgs); - } catch (Exception e) { - throw LKQLRuntimeException.fromMessage( - "The rule argument value generated an interpreter error: " - + valueSource); - } - } - } - - // Return the result - return res; - } - // ----- LKQL rule configuration file ----- /** diff --git a/testsuite/tests/checks/no_log_in_exception_handlers/no_log_in_exception_handlers.lkql b/testsuite/tests/checks/no_log_in_exception_handlers/no_log_in_exception_handlers.lkql index 5f2a71b61..c8f40e934 100644 --- a/testsuite/tests/checks/no_log_in_exception_handlers/no_log_in_exception_handlers.lkql +++ b/testsuite/tests/checks/no_log_in_exception_handlers/no_log_in_exception_handlers.lkql @@ -3,8 +3,8 @@ @check(message="no logging in exception handler") fun no_log_in_exception_handlers(node) = - node is ExceptionHandler(f_handled_exceptions is * - (any children(depth=1) is OthersDesignator)) + node is ExceptionHandler(f_handled_exceptions: * + (any children(depth=1): OthersDesignator)) when (from node.f_stmts select first n@Name when n.p_referenced_decl() is d@SubpDecl when match d.p_canonical_fully_qualified_name() diff --git a/testsuite/tests/checks/predefined_types/predefined_types.lkql b/testsuite/tests/checks/predefined_types/predefined_types.lkql index 24abec4b1..ac5527809 100644 --- a/testsuite/tests/checks/predefined_types/predefined_types.lkql +++ b/testsuite/tests/checks/predefined_types/predefined_types.lkql @@ -4,7 +4,7 @@ @check(message="reference to predefined type") fun predefined_types(node) = - node is Identifier(p_referenced_decl() is t@BaseTypeDecl) + node is Identifier(p_referenced_decl(): t@BaseTypeDecl) when match t.p_canonical_fully_qualified_name() | "^standard\.boolean$" => false | "^standard\.character$" => false diff --git a/testsuite/tests/interop/list_comp/test.out b/testsuite/tests/interop/list_comp/test.out index 9743dc3bf..f9479711b 100644 --- a/testsuite/tests/interop/list_comp/test.out +++ b/testsuite/tests/interop/list_comp/test.out @@ -1,5 +1,5 @@ === Lazy list interop messages: - toString(): [1, "Coucou", [4, 5]] + toString(): hasArrayElements(): true getArraySize(): 3 isBoolean(): true diff --git a/testsuite/tests/interop/selector/Main.java b/testsuite/tests/interop/selector/Main.java index fc76e4257..68243fe30 100644 --- a/testsuite/tests/interop/selector/Main.java +++ b/testsuite/tests/interop/selector/Main.java @@ -7,7 +7,7 @@ public class Main { val node = units()[1].root selector my_selector - | AdaNode => rec *this.children + | AdaNode => rec(*this.children) | * => () """; diff --git a/testsuite/tests/interpreter/call_selector/script.lkql b/testsuite/tests/interpreter/call_selector/script.lkql index 2f1f46724..0f2a2d842 100644 --- a/testsuite/tests/interpreter/call_selector/script.lkql +++ b/testsuite/tests/interpreter/call_selector/script.lkql @@ -1 +1 @@ -print(children((select ObjectDecl)[1])) \ No newline at end of file +print(children((select ObjectDecl)[1]).to_list) diff --git a/testsuite/tests/interpreter/call_selector/test.out b/testsuite/tests/interpreter/call_selector/test.out index eb32eb7cd..631a6af90 100644 --- a/testsuite/tests/interpreter/call_selector/test.out +++ b/testsuite/tests/interpreter/call_selector/test.out @@ -1 +1 @@ -[, , , , , , , , , , , , , , , , , , , , , , , , , ] +[, , , , , null, null, , , , , null, , , , , , , , , , null, , , , , , , , null, ] diff --git a/testsuite/tests/interpreter/complex_list_comprehension/script.lkql b/testsuite/tests/interpreter/complex_list_comprehension/script.lkql index fa5bf975c..d50032cdd 100644 --- a/testsuite/tests/interpreter/complex_list_comprehension/script.lkql +++ b/testsuite/tests/interpreter/complex_list_comprehension/script.lkql @@ -2,4 +2,4 @@ val subtypes = select SubtypeIndication val objects = select ObjectDecl print([ o.img & " " & st.img for o in objects, st in subtypes - if (o.img & " " & st.img).length != 64]) + if (o.img & " " & st.img).length != 64].to_list) diff --git a/testsuite/tests/interpreter/doc/test.out b/testsuite/tests/interpreter/doc/test.out index 06e339f05..755d75041 100644 --- a/testsuite/tests/interpreter/doc/test.out +++ b/testsuite/tests/interpreter/doc/test.out @@ -1,7 +1,6 @@ Built-in print function. Prints whatever is passed as an argument Given any object, return the documentation associated with it -Yields all the descendants of the given node in the tree - +Yields all the descendants of the given node This is the docstring This is the selector's docstring Pouet pouet pouet pouet diff --git a/testsuite/tests/interpreter/extended_paren_pattern/script.lkql b/testsuite/tests/interpreter/extended_paren_pattern/script.lkql index 6c1fffe5e..167aa78eb 100644 --- a/testsuite/tests/interpreter/extended_paren_pattern/script.lkql +++ b/testsuite/tests/interpreter/extended_paren_pattern/script.lkql @@ -1,2 +1,2 @@ -val decls = select b@(ObjectDecl or BaseTypeDecl)(f_aspects is not null) +val decls = select b@(ObjectDecl | BaseTypeDecl)(f_aspects: not null) print(decls) diff --git a/testsuite/tests/interpreter/full_pattern_binding_query_0/script.lkql b/testsuite/tests/interpreter/full_pattern_binding_query_0/script.lkql index 1b00c47ca..1a3ef2046 100644 --- a/testsuite/tests/interpreter/full_pattern_binding_query_0/script.lkql +++ b/testsuite/tests/interpreter/full_pattern_binding_query_0/script.lkql @@ -1,3 +1,3 @@ -val withAspect = select ObjectDecl(any cs @ children is AspectAssoc) +val withAspect = select ObjectDecl(any cs @ children: AspectAssoc) when cs.length == 1 print (withAspect) diff --git a/testsuite/tests/interpreter/full_pattern_query_0/script.lkql b/testsuite/tests/interpreter/full_pattern_query_0/script.lkql index 87194e4a8..c3d86da5c 100644 --- a/testsuite/tests/interpreter/full_pattern_query_0/script.lkql +++ b/testsuite/tests/interpreter/full_pattern_query_0/script.lkql @@ -1,2 +1,2 @@ -val withAspect = select ObjectDecl(any children is AspectAssoc) +val withAspect = select ObjectDecl(any children: AspectAssoc) print (withAspect) \ No newline at end of file diff --git a/testsuite/tests/interpreter/func_first_class/script.lkql b/testsuite/tests/interpreter/func_first_class/script.lkql index 77ab4925b..9df3abbb9 100644 --- a/testsuite/tests/interpreter/func_first_class/script.lkql +++ b/testsuite/tests/interpreter/func_first_class/script.lkql @@ -1,4 +1,4 @@ -fun map_fc(fn, coll) = [fn(el) for el in coll] +fun map_fc(fn, coll) = [fn(el) for el in coll].to_list print(map_fc((x) => x.text, select BasicDecl)) diff --git a/testsuite/tests/interpreter/iterators/script.lkql b/testsuite/tests/interpreter/iterators/script.lkql index c786bbecb..4f9134833 100644 --- a/testsuite/tests/interpreter/iterators/script.lkql +++ b/testsuite/tests/interpreter/iterators/script.lkql @@ -10,5 +10,5 @@ print("Evaluating itt up to index 2") print(itt[2]) print("Querying element 1, already computed") print(itt[1]) -print("Printing iterator will consume itt entirely") -print(itt) +print("Calling to_list will consume itt entirely") +print(itt.to_list) diff --git a/testsuite/tests/interpreter/iterators/test.out b/testsuite/tests/interpreter/iterators/test.out index 14d5c5155..591d22b77 100644 --- a/testsuite/tests/interpreter/iterators/test.out +++ b/testsuite/tests/interpreter/iterators/test.out @@ -4,7 +4,7 @@ In debug_id: 2 2 Querying element 1, already computed 1 -Printing iterator will consume itt entirely +Calling to_list will consume itt entirely In debug_id: 3 In debug_id: 4 In debug_id: 5 diff --git a/testsuite/tests/interpreter/list_literal_default_val/script.lkql b/testsuite/tests/interpreter/list_literal_default_val/script.lkql index f0a22f439..01de6c47d 100644 --- a/testsuite/tests/interpreter/list_literal_default_val/script.lkql +++ b/testsuite/tests/interpreter/list_literal_default_val/script.lkql @@ -1,4 +1,4 @@ fun woot(v = ["hello", "how", "are", "you"]) = [el.length for el in v] -print(woot()) \ No newline at end of file +print(woot().to_list) diff --git a/testsuite/tests/interpreter/list_neq/script.lkql b/testsuite/tests/interpreter/list_neq/script.lkql index 7ea4f151a..0ed4293d3 100644 --- a/testsuite/tests/interpreter/list_neq/script.lkql +++ b/testsuite/tests/interpreter/list_neq/script.lkql @@ -1,3 +1,3 @@ -val all = select randomName @ * +val all = select randomName val everything = select * print(all == everything) \ No newline at end of file diff --git a/testsuite/tests/interpreter/list_pattern/script.lkql b/testsuite/tests/interpreter/list_pattern/script.lkql index 9e8eda006..0dcaab1c0 100644 --- a/testsuite/tests/interpreter/list_pattern/script.lkql +++ b/testsuite/tests/interpreter/list_pattern/script.lkql @@ -3,9 +3,9 @@ fun test_list_patterns(lst) = img(lst) & " matches " & match lst | [1, 2, 3] => "[1, 2, 3]" - | [1, a@*, 3] => "[1, a@*, 3], with a = " & img(a) + | [1, a, 3] => "[1, a@*, 3], with a = " & img(a) | [11, 12, ...] => "[11, 12, ...]" - | [1, b@*, c@...] => "[1, b@*, c@...] with b = " & img(b) & " & c = " & img(c) + | [1, b, c@...] => "[1, b@*, c@...] with b = " & img(b) & " & c = " & img(c) | [...] => "[...]" | [..., 1, 2] => "Can never match" | * => "*" diff --git a/testsuite/tests/interpreter/node_pattern_data/script.lkql b/testsuite/tests/interpreter/node_pattern_data/script.lkql index 3be29b5b9..fb83c718d 100644 --- a/testsuite/tests/interpreter/node_pattern_data/script.lkql +++ b/testsuite/tests/interpreter/node_pattern_data/script.lkql @@ -1,2 +1,2 @@ -val result = select BaseTypeDecl(p_is_access_type() is true) +val result = select BaseTypeDecl(p_is_access_type(): true) print(result) \ No newline at end of file diff --git a/testsuite/tests/interpreter/not_pattern/script.lkql b/testsuite/tests/interpreter/not_pattern/script.lkql index b262c6c19..0da2cf1be 100644 --- a/testsuite/tests/interpreter/not_pattern/script.lkql +++ b/testsuite/tests/interpreter/not_pattern/script.lkql @@ -1,2 +1,2 @@ -val test = select not (ObjectDecl or CallExpr) -print (test) \ No newline at end of file +val test = select not (ObjectDecl | CallExpr) +print (test) diff --git a/testsuite/tests/interpreter/null_pattern/script.lkql b/testsuite/tests/interpreter/null_pattern/script.lkql index 4b65d3c58..2db50730d 100644 --- a/testsuite/tests/interpreter/null_pattern/script.lkql +++ b/testsuite/tests/interpreter/null_pattern/script.lkql @@ -1 +1 @@ -print(select ObjectDecl(f_default_expr is null)) \ No newline at end of file +print(select ObjectDecl(f_default_expr: null)) \ No newline at end of file diff --git a/testsuite/tests/interpreter/or_pattern/script.lkql b/testsuite/tests/interpreter/or_pattern/script.lkql index 209e85f97..a23bd99b6 100644 --- a/testsuite/tests/interpreter/or_pattern/script.lkql +++ b/testsuite/tests/interpreter/or_pattern/script.lkql @@ -1,2 +1,2 @@ -val test = select ObjectDecl or CallExpr -print (test) \ No newline at end of file +val test = select (ObjectDecl | CallExpr) +print (test) diff --git a/testsuite/tests/interpreter/parametrized_quantifier/script.lkql b/testsuite/tests/interpreter/parametrized_quantifier/script.lkql index a5fecb8c3..e895bdfcc 100644 --- a/testsuite/tests/interpreter/parametrized_quantifier/script.lkql +++ b/testsuite/tests/interpreter/parametrized_quantifier/script.lkql @@ -1,2 +1,2 @@ -val declWithAssoc = select *(any children(depth=3) is AspectAssoc) +val declWithAssoc = select *(any children(depth=3): AspectAssoc) print(declWithAssoc) \ No newline at end of file diff --git a/testsuite/tests/interpreter/parenthesized_pattern/script.lkql b/testsuite/tests/interpreter/parenthesized_pattern/script.lkql index f0838e28b..d02180bae 100644 --- a/testsuite/tests/interpreter/parenthesized_pattern/script.lkql +++ b/testsuite/tests/interpreter/parenthesized_pattern/script.lkql @@ -1,2 +1,2 @@ -val decls = select b@(ObjectDecl or BaseTypeDecl) when b.f_aspects != null -print(decls) \ No newline at end of file +val decls = select b@(ObjectDecl | BaseTypeDecl) when b.f_aspects != null +print(decls) diff --git a/testsuite/tests/interpreter/properties_returning_char/script.lkql b/testsuite/tests/interpreter/properties_returning_char/script.lkql index a11121a9c..d2f9c1f4c 100644 --- a/testsuite/tests/interpreter/properties_returning_char/script.lkql +++ b/testsuite/tests/interpreter/properties_returning_char/script.lkql @@ -2,4 +2,4 @@ # langkit. In that case, it will be the `kind` key of `RefResult` values in the # returned array. -print([a.p_denoted_value() for a in select CharLiteral]) +print([a.p_denoted_value() for a in select CharLiteral].to_list) diff --git a/testsuite/tests/interpreter/quantified_selector/script.lkql b/testsuite/tests/interpreter/quantified_selector/script.lkql index 0775d9d13..1e51f1fc7 100644 --- a/testsuite/tests/interpreter/quantified_selector/script.lkql +++ b/testsuite/tests/interpreter/quantified_selector/script.lkql @@ -1,2 +1,2 @@ -val result = select AdaNodeList(all children(depth=1) is ObjectDecl) -print(result) \ No newline at end of file +val result = select AdaNodeList(all children(depth=1): ObjectDecl) +print(result) diff --git a/testsuite/tests/interpreter/regex_pattern/script.lkql b/testsuite/tests/interpreter/regex_pattern/script.lkql index bb463e676..277a8bdf4 100644 --- a/testsuite/tests/interpreter/regex_pattern/script.lkql +++ b/testsuite/tests/interpreter/regex_pattern/script.lkql @@ -1,13 +1,13 @@ # Check that regex patterns can be applied to nodes directly # (Find all declarations starting with "F_" and then at least 5 characters) -val f_decls = select BasicDecl(p_defining_name() is "^F_.{5,}") +val f_decls = select BasicDecl(p_defining_name(): "^F_.{5,}") print(f_decls) # Check that LKQL doesn't crash when trying to regex-match null nodes # (f_aspects is null for more declarations) -val nulls = select BasicDecl(f_aspects is ".*") +val nulls = select BasicDecl(f_aspects: ".*") print(nulls) # Check that the pattern can be applied to string values -val fqns = select BasicDecl(p_fully_qualified_name() is "^.{15,25}$") +val fqns = select BasicDecl(p_fully_qualified_name(): "^.{15,25}$") print(fqns) \ No newline at end of file diff --git a/testsuite/tests/interpreter/simple_list_comprehension/script.lkql b/testsuite/tests/interpreter/simple_list_comprehension/script.lkql index be54f74d0..f3389999f 100644 --- a/testsuite/tests/interpreter/simple_list_comprehension/script.lkql +++ b/testsuite/tests/interpreter/simple_list_comprehension/script.lkql @@ -1,3 +1,3 @@ -val all = select p @ * -val decls = [a for a in all if a is ObjectDecl] -print(decls) \ No newline at end of file +val all = select p +val decls = [a for a in all if a is ObjectDecl].to_list +print(decls) diff --git a/testsuite/tests/interpreter/text_builtin/script.lkql b/testsuite/tests/interpreter/text_builtin/script.lkql index 599834a87..cdf283be3 100644 --- a/testsuite/tests/interpreter/text_builtin/script.lkql +++ b/testsuite/tests/interpreter/text_builtin/script.lkql @@ -1,2 +1,2 @@ -val texts = [bd.text for bd in select DefiningName] -print(texts) \ No newline at end of file +val texts = [bd.text for bd in select DefiningName].to_list +print(texts) diff --git a/testsuite/tests/interpreter/to_list/test.out b/testsuite/tests/interpreter/to_list/test.out index 46115b8fb..8951fba1b 100644 --- a/testsuite/tests/interpreter/to_list/test.out +++ b/testsuite/tests/interpreter/to_list/test.out @@ -1,3 +1,3 @@ [1, 2, 3, 4] [2, 4, 6, 8] -[, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ] +[, , null, , , , , , null, null, , , , , , , , , , , , , , , null, null, , , , , , , null, null, , , , , null, , , , null, , , , , , null, ] diff --git a/testsuite/tests/interpreter/tuple_pattern/script.lkql b/testsuite/tests/interpreter/tuple_pattern/script.lkql index 8d8f6a5c5..1c4673d27 100644 --- a/testsuite/tests/interpreter/tuple_pattern/script.lkql +++ b/testsuite/tests/interpreter/tuple_pattern/script.lkql @@ -5,7 +5,7 @@ fun test_match_tuple(i) = fun test_match_tuple_2(i) = match i - | (1, a@*, b@*, 4) => { print(a); print(b) } + | (1, a, b, 4) => { print(a); print(b) } test_match_tuple((1, 2, 3)) test_match_tuple((4, 5, 6)) diff --git a/testsuite/tests/interpreter/universal_pattern_query/script.lkql b/testsuite/tests/interpreter/universal_pattern_query/script.lkql index e236dfa8f..81d18f952 100644 --- a/testsuite/tests/interpreter/universal_pattern_query/script.lkql +++ b/testsuite/tests/interpreter/universal_pattern_query/script.lkql @@ -1,2 +1,2 @@ -val declParent = select *(any children(depth=1) is BasicDecl) +val declParent = select *(any children(depth=1): BasicDecl) print(declParent) \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_field_dot_access/script.lkql b/testsuite/tests/interpreter_errors/invalid_field_dot_access/script.lkql index 46b21861a..d08812537 100644 --- a/testsuite/tests/interpreter_errors/invalid_field_dot_access/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_field_dot_access/script.lkql @@ -1,2 +1,2 @@ -val p = select p @ * when p.f_nonExistingField is ObjectDecl +val p = select p when p.f_nonExistingField is ObjectDecl print (p) \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_field_dot_access/test.out b/testsuite/tests/interpreter_errors/invalid_field_dot_access/test.out index ede019b0a..fc2ad4e67 100644 --- a/testsuite/tests/interpreter_errors/invalid_field_dot_access/test.out +++ b/testsuite/tests/interpreter_errors/invalid_field_dot_access/test.out @@ -1,4 +1,4 @@ -script.lkql:1:29: error: No such field -1 | val p = select p @ * when p.f_nonExistingField is ObjectDecl - | ^^^^^^^^^^^^^^^^^^ +script.lkql:1:25: error: No such field +1 | val p = select p when p.f_nonExistingField is ObjectDecl + | ^^^^^^^^^^^^^^^^^^ diff --git a/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/script.lkql b/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/script.lkql index baaa7e3d1..a2ef024aa 100644 --- a/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/script.lkql @@ -1 +1 @@ -select p @ * when "Hello" is ObjectDecl \ No newline at end of file +select p when "Hello" is ObjectDecl \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/test.out b/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/test.out index aee6fd43f..3f4f0bf7e 100644 --- a/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/test.out +++ b/testsuite/tests/interpreter_errors/invalid_is_clause_left_operand/test.out @@ -1,4 +1,4 @@ -script.lkql:1:19: error: Type error: expected Node but got Str -1 | select p @ * when "Hello" is ObjectDecl - | ^^^^^^^ +script.lkql:1:15: error: Type error: expected Node but got Str +1 | select p when "Hello" is ObjectDecl + | ^^^^^^^ diff --git a/testsuite/tests/interpreter_errors/invalid_list_index/script.lkql b/testsuite/tests/interpreter_errors/invalid_list_index/script.lkql index a3e275fad..b0f33e940 100644 --- a/testsuite/tests/interpreter_errors/invalid_list_index/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_list_index/script.lkql @@ -1,2 +1,2 @@ -val p = select p @ * when true +val p = select p when true print (p[999999]) \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_regex/script.lkql b/testsuite/tests/interpreter_errors/invalid_regex/script.lkql index 5369a52d8..17b4c36bf 100644 --- a/testsuite/tests/interpreter_errors/invalid_regex/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_regex/script.lkql @@ -1,2 +1,2 @@ # Should show an error as the string below is not a valid regex -select BasicDecl(p_defining_name() is "*") \ No newline at end of file +select BasicDecl(p_defining_name(): "*") \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_regex/test.out b/testsuite/tests/interpreter_errors/invalid_regex/test.out index d2551a3c7..9f7f5406a 100644 --- a/testsuite/tests/interpreter_errors/invalid_regex/test.out +++ b/testsuite/tests/interpreter_errors/invalid_regex/test.out @@ -1,4 +1,4 @@ -script.lkql:2:39: error: Failed to compile regular expression: * -2 | select BasicDecl(p_defining_name() is "*") - | ^^^ +script.lkql:2:37: error: Failed to compile regular expression: * +2 | select BasicDecl(p_defining_name(): "*") + | ^^^ diff --git a/testsuite/tests/interpreter_errors/invalid_selector_binding/script.lkql b/testsuite/tests/interpreter_errors/invalid_selector_binding/script.lkql index f937f8cf1..0720bc6e0 100644 --- a/testsuite/tests/interpreter_errors/invalid_selector_binding/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_selector_binding/script.lkql @@ -1,4 +1,4 @@ -select AdaNode(any parent is n@AdaNode) +select AdaNode(any parent: n@AdaNode) when n # ^ This should be illegal, because is scoped to inside the quantified # selector call diff --git a/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/script.lkql b/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/script.lkql index 04e2a8de7..19a34cf61 100644 --- a/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/script.lkql +++ b/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/script.lkql @@ -1,2 +1,2 @@ -val p = select p @ * when "Hello" +val p = select p when "Hello" print (p) \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/test.out b/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/test.out index ae9abd66e..f81936aa6 100644 --- a/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/test.out +++ b/testsuite/tests/interpreter_errors/invalid_when_clause_return_type/test.out @@ -1,4 +1,4 @@ -script.lkql:1:27: error: Type error: expected Bool but got Str -1 | val p = select p @ * when "Hello" - | ^^^^^^^ +script.lkql:1:23: error: Type error: expected Bool but got Str +1 | val p = select p when "Hello" + | ^^^^^^^ diff --git a/testsuite/tests/interpreter_errors/selector_kind_error/script.lkql b/testsuite/tests/interpreter_errors/selector_kind_error/script.lkql index 889f58d80..1d965f092 100644 --- a/testsuite/tests/interpreter_errors/selector_kind_error/script.lkql +++ b/testsuite/tests/interpreter_errors/selector_kind_error/script.lkql @@ -1,4 +1,4 @@ selector badSelector | * => true -select *(any badSelector is *) \ No newline at end of file +select *(any badSelector: *) \ No newline at end of file diff --git a/testsuite/tests/interpreter_errors/selector_kind_error/test.out b/testsuite/tests/interpreter_errors/selector_kind_error/test.out index a801ffe32..b4a15d8ed 100644 --- a/testsuite/tests/interpreter_errors/selector_kind_error/test.out +++ b/testsuite/tests/interpreter_errors/selector_kind_error/test.out @@ -1,4 +1,4 @@ -script.lkql:2:12: error: Cannot use values of kind Bool in a selector +script.lkql:2:12: error: Type error: expected RecValue but got Bool 2 | | * => true | ^^^^ diff --git a/testsuite/tests/interpreter_errors/selector_unpack_wrong/script.lkql b/testsuite/tests/interpreter_errors/selector_unpack_wrong/script.lkql new file mode 100644 index 000000000..03961e3a3 --- /dev/null +++ b/testsuite/tests/interpreter_errors/selector_unpack_wrong/script.lkql @@ -0,0 +1,6 @@ +selector pparent + | AdaNode => rec(*this.parent, this) + | * => () + +# Access first element to evaluate selector call +pparent(select first AdaNode)[0] diff --git a/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.adb b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.adb new file mode 100644 index 000000000..e03b30c4e --- /dev/null +++ b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.adb @@ -0,0 +1,4 @@ +procedure Test is +begin + null; +end Test; diff --git a/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.out b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.out new file mode 100644 index 000000000..2172d8f9a --- /dev/null +++ b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.out @@ -0,0 +1,4 @@ +script.lkql:2:23: error: Type error: expected Iterable but got Node +2 | | AdaNode => rec(*this.parent, this) + | ^^^^^^^^^^^ + diff --git a/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.yaml b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.yaml new file mode 100644 index 000000000..c5e30112e --- /dev/null +++ b/testsuite/tests/interpreter_errors/selector_unpack_wrong/test.yaml @@ -0,0 +1,2 @@ +driver: 'interpreter' +project: 'default_project/default.gpr' diff --git a/testsuite/tests/miscellaneous/tokens/script.lkql b/testsuite/tests/miscellaneous/tokens/script.lkql index 91a3840dd..442746eae 100644 --- a/testsuite/tests/miscellaneous/tokens/script.lkql +++ b/testsuite/tests/miscellaneous/tokens/script.lkql @@ -1,3 +1,3 @@ -print([(a, a.start_line, a.start_column) for a in (select first AdaNode).tokens]) +print([(a, a.start_line, a.start_column) for a in (select first AdaNode).tokens].to_list) print((select first AdaNode).token_start().unit) print((select first AdaNode).unit.tokens) diff --git a/testsuite/tests/miscellaneous/traverse_instantiations/flag_ints.lkql b/testsuite/tests/miscellaneous/traverse_instantiations/flag_ints.lkql index 19aa4eb18..f546782da 100644 --- a/testsuite/tests/miscellaneous/traverse_instantiations/flag_ints.lkql +++ b/testsuite/tests/miscellaneous/traverse_instantiations/flag_ints.lkql @@ -1,6 +1,6 @@ @check(message="integer object decl", follow_generic_instantiations=true) fun int_obj_decl(node) = node is o @ ObjectDecl( - p_type_expression() is SubtypeIndication( - p_designated_type_decl() is t @ * when t == o.p_std_entity("Integer") + p_type_expression(): SubtypeIndication( + p_designated_type_decl(): t when t == o.p_std_entity("Integer") ) ) \ No newline at end of file diff --git a/testsuite/tests/parser/annotated_fun/input b/testsuite/tests/parser/annotated_fun/input index 539df58e3..559e45752 100644 --- a/testsuite/tests/parser/annotated_fun/input +++ b/testsuite/tests/parser/annotated_fun/input @@ -1,4 +1,4 @@ @check(custom_name="Implicit_Small") fun implicit_small() = - select t @ TypeDecl(any children is OrdinaryFixedPointDef) + select t @ TypeDecl(any children: OrdinaryFixedPointDef) when not t.p_has_aspect("Small") diff --git a/testsuite/tests/parser/annotated_fun/test.out b/testsuite/tests/parser/annotated_fun/test.out index 3ec900e2a..a6ee92822 100644 --- a/testsuite/tests/parser/annotated_fun/test.out +++ b/testsuite/tests/parser/annotated_fun/test.out @@ -19,6 +19,7 @@ FunDecl | |f_doc_node: | |f_body_expr: | | Query +| | |f_unpack_from: | | |f_from_expr: | | |f_through_expr: | | |f_query_kind: diff --git a/testsuite/tests/parser/fun_no_args/test.out b/testsuite/tests/parser/fun_no_args/test.out index 6727bfdcf..1ec636fda 100644 --- a/testsuite/tests/parser/fun_no_args/test.out +++ b/testsuite/tests/parser/fun_no_args/test.out @@ -9,6 +9,7 @@ FunDecl | |f_doc_node: | |f_body_expr: | | Query +| | |f_unpack_from: | | |f_from_expr: | | |f_through_expr: | | |f_query_kind: diff --git a/testsuite/tests/parser/fun_with_type_annotations/input b/testsuite/tests/parser/fun_with_type_annotations/input index 545776006..4247d728c 100644 --- a/testsuite/tests/parser/fun_with_type_annotations/input +++ b/testsuite/tests/parser/fun_with_type_annotations/input @@ -2,8 +2,8 @@ fun too_many_dependencies(max_deps : int) = select CompilationUnit( - any c @ children is Identifier(any parent(depth=2) is WithClause), - f_body is l @ LibraryItem when { + any c @ children: Identifier(any parent(depth=2): WithClause), + f_body: l @ LibraryItem when { val semanticParent = l.f_item?.p_semantic_parent(); val deps = [x for x in c if x.p_referenced_decl() != semanticParent]; deps.length > max_deps diff --git a/testsuite/tests/parser/fun_with_type_annotations/test.out b/testsuite/tests/parser/fun_with_type_annotations/test.out index 9fcb4f161..644a746c0 100644 --- a/testsuite/tests/parser/fun_with_type_annotations/test.out +++ b/testsuite/tests/parser/fun_with_type_annotations/test.out @@ -21,6 +21,7 @@ FunDecl | |f_doc_node: | |f_body_expr: | | Query +| | |f_unpack_from: | | |f_from_expr: | | |f_through_expr: | | |f_query_kind: diff --git a/testsuite/tests/parser/paren_or_pattern/input b/testsuite/tests/parser/paren_or_pattern/input index 4a53b1993..7815813a0 100644 --- a/testsuite/tests/parser/paren_or_pattern/input +++ b/testsuite/tests/parser/paren_or_pattern/input @@ -1,2 +1,2 @@ -select x@(A or B or C) -select (x@A) or (x@B) or (x@C) +select x@(A | B | C) +select (x@A | x@B | x@C) diff --git a/testsuite/tests/parser/paren_or_pattern/test.out b/testsuite/tests/parser/paren_or_pattern/test.out index 9950e2901..6816b9094 100644 --- a/testsuite/tests/parser/paren_or_pattern/test.out +++ b/testsuite/tests/parser/paren_or_pattern/test.out @@ -1,5 +1,6 @@ TopLevelList | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: @@ -27,15 +28,16 @@ TopLevelList | | | | | | |f_kind_name: | | | | | | | Identifier: C | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: | | QueryKindAll | |f_pattern: -| | OrPattern -| | |f_left: -| | | ParenPattern -| | | |f_pattern: +| | ParenPattern +| | |f_pattern: +| | | OrPattern +| | | |f_left: | | | | BindingPattern | | | | |f_binding: | | | | | Identifier: x @@ -43,11 +45,9 @@ TopLevelList | | | | | NodeKindPattern | | | | | |f_kind_name: | | | | | | Identifier: A -| | |f_right: -| | | OrPattern -| | | |f_left: -| | | | ParenPattern -| | | | |f_pattern: +| | | |f_right: +| | | | OrPattern +| | | | |f_left: | | | | | BindingPattern | | | | | |f_binding: | | | | | | Identifier: x @@ -55,9 +55,7 @@ TopLevelList | | | | | | NodeKindPattern | | | | | | |f_kind_name: | | | | | | | Identifier: B -| | | |f_right: -| | | | ParenPattern -| | | | |f_pattern: +| | | | |f_right: | | | | | BindingPattern | | | | | |f_binding: | | | | | | Identifier: x diff --git a/testsuite/tests/parser/query_0/test.out b/testsuite/tests/parser/query_0/test.out index c897514f5..f25cf4c33 100644 --- a/testsuite/tests/parser/query_0/test.out +++ b/testsuite/tests/parser/query_0/test.out @@ -1,4 +1,5 @@ Query +|f_unpack_from: |f_from_expr: |f_through_expr: |f_query_kind: diff --git a/testsuite/tests/parser/query_1/test.out b/testsuite/tests/parser/query_1/test.out index fe8893de7..6e19aec7c 100644 --- a/testsuite/tests/parser/query_1/test.out +++ b/testsuite/tests/parser/query_1/test.out @@ -5,6 +5,7 @@ ValDecl | Identifier: o |f_value: | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: diff --git a/testsuite/tests/parser/query_binding/test.out b/testsuite/tests/parser/query_binding/test.out index 4dc439b73..96212dcff 100644 --- a/testsuite/tests/parser/query_binding/test.out +++ b/testsuite/tests/parser/query_binding/test.out @@ -5,6 +5,7 @@ ValDecl | Identifier: o |f_value: | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: diff --git a/testsuite/tests/parser/query_full_pattern/input b/testsuite/tests/parser/query_full_pattern/input index 5761a9a66..42a6141b2 100644 --- a/testsuite/tests/parser/query_full_pattern/input +++ b/testsuite/tests/parser/query_full_pattern/input @@ -1,3 +1,3 @@ val declWihAspect = - select o @ ObjectDecl(any children is AspectAssoc) + select o @ ObjectDecl(any children: AspectAssoc) when o.identifier.length == 42 diff --git a/testsuite/tests/parser/query_full_pattern/test.out b/testsuite/tests/parser/query_full_pattern/test.out index b798c640b..23e51e56d 100644 --- a/testsuite/tests/parser/query_full_pattern/test.out +++ b/testsuite/tests/parser/query_full_pattern/test.out @@ -5,6 +5,7 @@ ValDecl | Identifier: declWihAspect |f_value: | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: diff --git a/testsuite/tests/parser/query_node_kind_only/test.out b/testsuite/tests/parser/query_node_kind_only/test.out index e890d531c..ee5109bc4 100644 --- a/testsuite/tests/parser/query_node_kind_only/test.out +++ b/testsuite/tests/parser/query_node_kind_only/test.out @@ -5,6 +5,7 @@ ValDecl | Identifier: o |f_value: | Query +| |f_unpack_from: | |f_from_expr: | |f_through_expr: | |f_query_kind: diff --git a/testsuite/tests/parser/query_quantified_selector/input b/testsuite/tests/parser/query_quantified_selector/input index f483e351c..f3f7992eb 100644 --- a/testsuite/tests/parser/query_quantified_selector/input +++ b/testsuite/tests/parser/query_quantified_selector/input @@ -1 +1 @@ -select o@ObjectDecl(all children is AspectAssoc) +select o@ObjectDecl(all children: AspectAssoc) diff --git a/testsuite/tests/parser/query_quantified_selector/test.out b/testsuite/tests/parser/query_quantified_selector/test.out index c5594de69..d4c2744ff 100644 --- a/testsuite/tests/parser/query_quantified_selector/test.out +++ b/testsuite/tests/parser/query_quantified_selector/test.out @@ -1,4 +1,5 @@ Query +|f_unpack_from: |f_from_expr: |f_through_expr: |f_query_kind: diff --git a/testsuite/tests/parser/selector/input b/testsuite/tests/parser/selector/input index b02a06d5a..d0978ab08 100644 --- a/testsuite/tests/parser/selector/input +++ b/testsuite/tests/parser/selector/input @@ -1,4 +1,4 @@ selector testSelector - | FirstNodeKind => skip it.field1 <> rec it.field2 - | SecondNodeKind(children is ThirdNodeKind) => it.field - | * => () + | FirstNodeKind => rec(*[it.field1, it.field2], ()) + | SecondNodeKind(children: ThirdNodeKind) => rec((), it.field) + | * => () diff --git a/testsuite/tests/parser/selector/test.out b/testsuite/tests/parser/selector/test.out index 9013d6df5..34e29b595 100644 --- a/testsuite/tests/parser/selector/test.out +++ b/testsuite/tests/parser/selector/test.out @@ -10,26 +10,28 @@ SelectorDecl | | | NodeKindPattern | | | |f_kind_name: | | | | Identifier: FirstNodeKind -| | |f_exprs_list: -| | | SelectorExprList -| | | | SelectorExpr -| | | | |f_mode: -| | | | | SelectorExprModeSkip -| | | | |f_expr: -| | | | | DotAccess -| | | | | |f_receiver: -| | | | | | Identifier: it -| | | | | |f_member: -| | | | | | Identifier: field1 -| | | | SelectorExpr -| | | | |f_mode: -| | | | | SelectorExprModeRec -| | | | |f_expr: -| | | | | DotAccess -| | | | | |f_receiver: -| | | | | | Identifier: it -| | | | | |f_member: -| | | | | | Identifier: field2 +| | |f_expr: +| | | RecExpr +| | | |f_recurse_unpack: +| | | | UnpackPresent +| | | |f_recurse_expr: +| | | | ListLiteral +| | | | |f_exprs: +| | | | | ExprList +| | | | | | DotAccess +| | | | | | |f_receiver: +| | | | | | | Identifier: it +| | | | | | |f_member: +| | | | | | | Identifier: field1 +| | | | | | DotAccess +| | | | | | |f_receiver: +| | | | | | | Identifier: it +| | | | | | |f_member: +| | | | | | | Identifier: field2 +| | | |f_result_unpack: +| | | | UnpackAbsent +| | | |f_result_expr: +| | | | UnitLiteral | | SelectorArm | | |f_pattern: | | | ExtendedNodePattern @@ -46,24 +48,22 @@ SelectorDecl | | | | | | NodeKindPattern | | | | | | |f_kind_name: | | | | | | | Identifier: ThirdNodeKind -| | |f_exprs_list: -| | | SelectorExprList -| | | | SelectorExpr -| | | | |f_mode: -| | | | | SelectorExprModeDefault -| | | | |f_expr: -| | | | | DotAccess -| | | | | |f_receiver: -| | | | | | Identifier: it -| | | | | |f_member: -| | | | | | Identifier: field +| | |f_expr: +| | | RecExpr +| | | |f_recurse_unpack: +| | | | UnpackAbsent +| | | |f_recurse_expr: +| | | | UnitLiteral +| | | |f_result_unpack: +| | | | UnpackAbsent +| | | |f_result_expr: +| | | | DotAccess +| | | | |f_receiver: +| | | | | Identifier: it +| | | | |f_member: +| | | | | Identifier: field | | SelectorArm | | |f_pattern: | | | UniversalPattern -| | |f_exprs_list: -| | | SelectorExprList -| | | | SelectorExpr -| | | | |f_mode: -| | | | | SelectorExprModeDefault -| | | | |f_expr: -| | | | | UnitLiteral +| | |f_expr: +| | | UnitLiteral diff --git a/testsuite/tests/parser/through_select/test.out b/testsuite/tests/parser/through_select/test.out index 2538ac10b..16c4c666e 100644 --- a/testsuite/tests/parser/through_select/test.out +++ b/testsuite/tests/parser/through_select/test.out @@ -1,4 +1,6 @@ Query +|f_unpack_from: +| UnpackAbsent |f_from_expr: | Identifier: a |f_through_expr: diff --git a/testsuite/tests/parser/universal_pattern/input b/testsuite/tests/parser/universal_pattern/input index f01b1f1fd..a859ee9e2 100644 --- a/testsuite/tests/parser/universal_pattern/input +++ b/testsuite/tests/parser/universal_pattern/input @@ -1 +1 @@ -select *(all children is BasicDecl) +select *(all children: BasicDecl) diff --git a/testsuite/tests/parser/universal_pattern/test.out b/testsuite/tests/parser/universal_pattern/test.out index 95397da9d..34bf16bd2 100644 --- a/testsuite/tests/parser/universal_pattern/test.out +++ b/testsuite/tests/parser/universal_pattern/test.out @@ -1,4 +1,5 @@ Query +|f_unpack_from: |f_from_expr: |f_through_expr: |f_query_kind: diff --git a/user_manual/generated/std.rst b/user_manual/generated/std.rst index 09a18b8c8..72a135d8c 100644 --- a/user_manual/generated/std.rst +++ b/user_manual/generated/std.rst @@ -72,34 +72,6 @@ Builtin functions Given a unit, apply all the unit checker on it -Builtin selectors -^^^^^^^^^^^^^^^^^ - -.. function:: children() - - Yields all the descendants of the given node in the tree - - -.. function:: parent() - - Yields the parents (ancestors) of the given node in the tree - - -.. function:: next_siblings() - - Yields the siblings following the given node in the tree - - -.. function:: prev_siblings() - - Yields the siblings preceding the given node in the tree - - -.. function:: super_types() - - Given a TypeDecl node, yields all the super types of the type - - Builtin methods ^^^^^^^^^^^^^^^ diff --git a/user_manual/generated/stdlib.rst b/user_manual/generated/stdlib.rst index 5af05ff94..508d7537c 100644 --- a/user_manual/generated/stdlib.rst +++ b/user_manual/generated/stdlib.rst @@ -269,3 +269,7 @@ Selectors Return all semantic parent nodes starting from a given node. +.. function:: super_types() + + Yields the chain of super types for the given type + diff --git a/user_manual/source/language_reference.rst b/user_manual/source/language_reference.rst index 17a2ed305..704f136b8 100644 --- a/user_manual/source/language_reference.rst +++ b/user_manual/source/language_reference.rst @@ -543,8 +543,8 @@ trigger the evaluation of the associated expression in the match arm. .. code-block:: lkql match nodes[1] - | ObjectDecl(p_has_aliased() is aliased @ *) => aliased - | ParamSpec(p_has_aliased() is aliased @ *) => aliased + | ObjectDecl(p_has_aliased(): aliased @ *) => aliased + | ParamSpec(p_has_aliased(): aliased @ *) => aliased | * => false .. note:: For the moment, there is no check that the matcher is complete. A @@ -651,7 +651,7 @@ Module .. lkql_doc_class:: Import LKQL has a very simple module system. Basically every file in LKQL is a module, -and you can import modules from other files with the ``import`` clause. +and you can import modules from other files with the ``import`` clause. .. code-block:: lkql @@ -696,7 +696,7 @@ declarations that have the aliased qualifier. .. code-block:: lkql - select ObjectDecl(p_has_aliased() is true) + select ObjectDecl(p_has_aliased(): true) # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Selector This will query every source file in the LKQL context, and filter according to @@ -706,7 +706,7 @@ the pattern. .. code-block:: lkql - val a = select ObjectDecl(p_has_aliased() is true) + val a = select ObjectDecl(p_has_aliased(): true) .. admonition:: todo @@ -734,7 +734,7 @@ chain. .. code-block:: lkql selector parent - | AdaNode => rec *this.parent + | AdaNode => rec(*this.parent, this) | * => () Query Expression @@ -811,11 +811,6 @@ Pattern .. raw:: html :file: ../../lkql/build/railroad-diagrams/pattern.svg -.. raw:: html - :file: ../../lkql/build/railroad-diagrams/filtered_pattern.svg - -.. raw:: html - :file: ../../lkql/build/railroad-diagrams/binding_pattern.svg Patterns are by far the most complex part of the query language subset, but at its core, the concept of a pattern is very simple: @@ -856,7 +851,6 @@ Nested Sub Patterns """"""""""""""""""" .. lkql_doc_class:: NodePatternDetail -.. lkql_doc_class:: DetailValue .. raw:: html :file: ../../lkql/build/railroad-diagrams/pattern_arg.svg @@ -873,7 +867,7 @@ match its results: .. code-block:: lkql - select Body(any children is ForLoopStmt) + select Body(any children: ForLoopStmt) The quantifier part (``any``) can be either ``any`` or ``all``, which will alter how the sub-pattern matches: @@ -896,7 +890,7 @@ construct in the introduction, and it's one of the simplest kind of patterns. .. code-block:: lkql - select ObjectDecl(p_default_val() is IntLiteral) + select ObjectDecl(p_default_val(): IntLiteral) Property Call Predicate """"""""""""""""""""""" @@ -907,7 +901,7 @@ this is denoted by the parentheses after the property name. .. code-block:: lkql - select BaseId(p_referenced_decl() is ObjectDecl) + select BaseId(p_referenced_decl(): ObjectDecl) Regular values patterns ^^^^^^^^^^^^^^^^^^^^^^^ @@ -1058,8 +1052,7 @@ Selector Declaration -------------------- .. lkql_doc_class:: SelectorDecl -.. lkql_doc_class:: SelectorExpr -.. lkql_doc_class:: SelectorExprMode +.. lkql_doc_class:: RecExpr .. lkql_doc_class:: SelectorArm .. lkql_doc_class:: Unpack @@ -1070,11 +1063,10 @@ Selector Declaration :file: ../../lkql/build/railroad-diagrams/selector_arm.svg .. raw:: html - :file: ../../lkql/build/railroad-diagrams/selector_expr.svg -Selectors are a special form of functions that return a lazy stream of node -values. They're at the basis of the query DSL of LKQL, allowing the easy -expression of traversal blueprints. +Selectors are a special form of functions that return a lazy stream of values. +They're at the basis of the query DSL of LKQL, allowing the easy expression of +traversal blueprints. For example, by default, the `Query expression`_ explores the tree via the default ``children`` selector. @@ -1102,30 +1094,42 @@ A selector is a recursive function. In the body of the selector, there is a binding from ``this`` to the current node. A selector has an implicit top level `Match expression`_ matching on ``this``. -.. note:: The principle of selectors is more general than nodes, but is for the - moment only usable with an ``this`` argument that is of type node. +In the branch of a selector, you can express whatever computation you want for +the current node. **There is a high-level requirement though, which is that the +expression returned by a selector branch must be a `RecExpr`, which can be +created via the call to the `rec` built-in operation.** + +The `rec` built-in operation looks like a function call. + +.. raw:: html + :file: ../../lkql/build/railroad-diagrams/selector_expr.svg + +It takes one or two expressions, which can be prefixed by the splat operator +`*`. -In the branch of a selector, you have three choices: +* The first expression represents what has to be added to the recurse list + (either an item, or a list of items, if prefixed by `*`). The recurse list is + the list of items on which the selector will be called next. Items are added + at the end of the list -* You can **recurse** via the ``rec`` keyword, on nodes reachable from ``this``. - The node or nodes you will recurse on via this keyword will both be "yielded" - by the selector, and explored further (ie. the selector will be called on - them) +* The second expression represents what has to be added to the result list + (either an item, or a list of items, if prefixed by `*`). The result list is + the list of items that will be yielded, piece-by-piece, to the user. -* You can **recurse but skip the node(s)**, via the ``skip`` keyword. This'll have - the same effect as ``rec``, except that it will not yield the node(s). +* You can pass only one expression, in which case it is used both for the + result list and for the recurse list. -* You can **return but not recurse**: This is the default action (requires no - keyword), and will yield the node(s), but not recurse on them. +.. attention:: Selectors calls are lazy, which means that their results are + computed on demand. When you first call a selector, nothing is computed. + Only by accessing its elements will you signify to LKQL that it has to + process the items -In ``rec`` or in the regular return branch, you can use the unpack operator, or -``*expr`` to "unpack" an expression, eg. return each of its values. Here is for -example how the ``super_types`` selector is expressed: +Here is for example how the ``super_types`` selector is expressed in Ada: .. code-block:: lkql selector super_types - | BaseTypeDecl => rec *this.p_base_types() + | BaseTypeDecl => rec(*this.p_base_types()) | * => () Built-in Selectors diff --git a/user_manual/source/lkql_checker.rst b/user_manual/source/lkql_checker.rst index 719ea4f74..ef17fce5f 100644 --- a/user_manual/source/lkql_checker.rst +++ b/user_manual/source/lkql_checker.rst @@ -89,8 +89,8 @@ Here is an example check: |" Will flag object declarations for which the type is the standard |" ``Integer`` type node is o @ ObjectDecl( - p_type_expression() is SubtypeIndication( - p_designated_type_decl() is t @ * when t == o.p_std_entity("Integer") + p_type_expression(): SubtypeIndication( + p_designated_type_decl(): t @ * when t == o.p_std_entity("Integer") ) ) diff --git a/utils/refactoring/pattern_arg_is_to_colon.py b/utils/refactoring/pattern_arg_is_to_colon.py new file mode 100644 index 000000000..5f6459bda --- /dev/null +++ b/utils/refactoring/pattern_arg_is_to_colon.py @@ -0,0 +1,15 @@ +import refactor +import liblkqllang as lkql +from refactor import Action, ActionKind + +class App(refactor.Refactor): + + def preprocess(self, unit): + for det in unit.root.findall(lkql.NodePatternDetail): + tok_is = refactor.first_with_pred(det.token_start, lambda t: t.kind == 'Is') + self.add_action(tok_is, Action(ActionKind.replace, ":")) + self.add_action(tok_is.previous, Action(ActionKind.replace, "")) + + +if __name__ == '__main__': + App.run() diff --git a/utils/refactoring/replace_or_patterns.py b/utils/refactoring/replace_or_patterns.py new file mode 100644 index 000000000..0f4701674 --- /dev/null +++ b/utils/refactoring/replace_or_patterns.py @@ -0,0 +1,22 @@ +import refactor +import liblkqllang as lkql +from refactor import Action, ActionKind + +class App(refactor.Refactor): + + def preprocess(self, unit): + for or_pat in unit.root.findall(lkql.OrPattern): + # Replace 'or' by '|' + or_tok = refactor.first_with_pred(or_pat.f_left.token_end, lambda t: t.kind == 'Or') + # Put parens around the OrPattern if needed + if not or_pat.parent.is_a(lkql.OrPattern, lkql.ParenPattern, + lkql.NodePatternSelector, + lkql.NodePatternField, + lkql.NodePatternProperty): + self.add_action(or_pat.token_start, Action(ActionKind.prepend, "(")) + self.add_action(or_pat.token_end, Action(ActionKind.append, ")")) + self.add_action(or_tok, Action(ActionKind.replace, "|")) + + +if __name__ == '__main__': + App.run() diff --git a/utils/refactoring/simplify_binding_patterns.py b/utils/refactoring/simplify_binding_patterns.py new file mode 100644 index 000000000..8222d3d88 --- /dev/null +++ b/utils/refactoring/simplify_binding_patterns.py @@ -0,0 +1,23 @@ +import refactor +import liblkqllang as lkql +from refactor import Action, ActionKind + +class App(refactor.Refactor): + + def preprocess(self, unit): + for binding_pat in unit.root.findall(lkql.BindingPattern): + # Remove every token from the @ token to the last whitespace after the '*' token + + if binding_pat.f_value_pattern and binding_pat.f_value_pattern.is_a(lkql.UniversalPattern): + cur_tok = refactor.first_with_pred(binding_pat.token_start, lambda t: t.kind == 'At') + if cur_tok.previous.kind == 'Whitespace': + cur_tok = cur_tok.previous + end_tok = binding_pat.token_end.next + + while cur_tok != end_tok: + self.add_action(cur_tok, Action(ActionKind.replace, "")) + cur_tok = cur_tok.next + + +if __name__ == '__main__': + App.run()