diff --git a/runtime/queries/awk/locals.scm b/runtime/queries/awk/locals.scm new file mode 100644 index 00000000..786a47f7 --- /dev/null +++ b/runtime/queries/awk/locals.scm @@ -0,0 +1,18 @@ +; Scopes + +(func_def) @local.scope + +; Definitions + +; awk has no local declarations; extra params are the idiom for locals. +(func_def + (param_list + (identifier) @local.definition.variable.parameter)) + +; References + +(identifier) @local.reference + +; Function names in call position are not variable references. +(func_call + name: (identifier) @_) diff --git a/runtime/queries/bash/locals.scm b/runtime/queries/bash/locals.scm new file mode 100644 index 00000000..fce52e9a --- /dev/null +++ b/runtime/queries/bash/locals.scm @@ -0,0 +1,22 @@ +; Scopes + +[ + (function_definition) + (subshell) +] @local.scope + +; Definitions + +(variable_assignment + name: (variable_name) @local.definition.variable) + +; `local`/`declare`/`export x` etc. bind a bare name. +(declaration_command + (variable_name) @local.definition.variable) + +(for_statement + variable: (variable_name) @local.definition.variable) + +; References + +(variable_name) @local.reference diff --git a/runtime/queries/c-sharp/locals.scm b/runtime/queries/c-sharp/locals.scm new file mode 100644 index 00000000..dfb04606 --- /dev/null +++ b/runtime/queries/c-sharp/locals.scm @@ -0,0 +1,37 @@ +; Scopes + +[ + (method_declaration) + (local_function_statement) + (constructor_declaration) + (destructor_declaration) + (operator_declaration) + (lambda_expression) + (anonymous_method_expression) + (block) +] @local.scope + +; Definitions + +(parameter + name: (identifier) @local.definition.variable.parameter) + +(variable_declarator + name: (identifier) @local.definition.variable) + +(foreach_statement + left: (identifier) @local.definition.variable) + +; References + +(identifier) @local.reference + +; Discards: identifiers that look like references but aren't variables. + +; `obj.Member` — the member name is not a local. +(member_access_expression + name: (identifier) @_) + +; Named argument `f(name: value)`. +(argument + name: (identifier) @_) diff --git a/runtime/queries/c/locals.scm b/runtime/queries/c/locals.scm index eddf00d7..b0b90fbb 100644 --- a/runtime/queries/c/locals.scm +++ b/runtime/queries/c/locals.scm @@ -37,3 +37,8 @@ ;; References (identifier) @local.reference + +; A call's function name is not a variable reference; keep its class +; even when a same-named local is in scope. +(call_expression + function: (identifier) @_) diff --git a/runtime/queries/clarity/locals.scm b/runtime/queries/clarity/locals.scm new file mode 100644 index 00000000..62208f00 --- /dev/null +++ b/runtime/queries/clarity/locals.scm @@ -0,0 +1,35 @@ +; Scopes + +[ + (function_definition) + (let_expression) +] @local.scope + +; Definitions + +; `function_parameter` is `name: (identifier) type: (parameter_type)`. +(function_parameter + (identifier) @local.definition.variable.parameter) + +; `local_binding` in a `let` is `name: (identifier) value: (_)`; anchor the name. +(let_expression + (local_binding + . (identifier) @local.definition.variable)) + +; References + +(identifier) @local.reference + +; The function name in a signature is a definition site, not a reference. +(function_signature + (identifier) @_) + +; Operators in call forms are function names, not variable references. +(contract_function_call + operator: (identifier) @_) + +; Tuple keys are field names, not variable references. +(tuple_lit + key: (identifier) @_) +(tuple_type + key: (identifier) @_) diff --git a/runtime/queries/crystal/locals.scm b/runtime/queries/crystal/locals.scm index b44fd3a0..4534b2dc 100644 --- a/runtime/queries/crystal/locals.scm +++ b/runtime/queries/crystal/locals.scm @@ -12,3 +12,9 @@ lhs: (identifier) @local.definition.variable) (identifier) @local.reference + +; Call/keyword-argument names look like identifiers but aren't variable refs. +(call + method: (identifier) @_) +(named_expr + name: (identifier) @_) diff --git a/runtime/queries/d/locals.scm b/runtime/queries/d/locals.scm new file mode 100644 index 00000000..b8990117 --- /dev/null +++ b/runtime/queries/d/locals.scm @@ -0,0 +1,47 @@ +; Scopes + +[ + (function_body) + (function_literal) + (block_statement) + (foreach_statement) + (for_statement) +] @local.scope + +; Definitions + +; In a `parameter`, the type is wrapped in a `(type)` node while the variable +; name is a direct `identifier` child, so this matches only the name. +(parameter + (identifier) @local.definition.variable.parameter) + +; `Type name = …;` — declarator's first child is the name; the initializer is +; nested under expression nodes, so anchor to the first child. +(variable_declaration + (declarator + . (identifier) @local.definition.variable)) +; `auto name = …;` +(auto_declaration + variable: (identifier) @local.definition.variable) + +; `foreach (name; range)` — like parameters, the optional type is a `(type)` +; node and the loop variable is the trailing direct identifier. +(foreach_type + (identifier) @local.definition.variable) + +; `catch (Exception e)` — type is wrapped, the bound name is a direct identifier. +(catch_statement + (identifier) @local.definition.variable) + +; References + +(identifier) @local.reference + +; Discards: identifiers that look like references but aren't variables. + +; `expr.member` — the trailing member name is not a local. +(property_expression + (identifier) @_ .) +; Named argument `foo(name: value)`. +(named_argument + (identifier) @_) diff --git a/runtime/queries/dart/locals.scm b/runtime/queries/dart/locals.scm index 15a81f78..d4e81fcf 100644 --- a/runtime/queries/dart/locals.scm +++ b/runtime/queries/dart/locals.scm @@ -2,7 +2,10 @@ ;------- [ + (function_body) + (function_expression_body) (block) + (for_statement) (try_statement) (catch_clause) (finally_clause) @@ -11,10 +14,23 @@ ; Definitions ;------------ -(class_definition - body: (_) @local.definition.type) +(formal_parameter + name: (identifier) @local.definition.variable.parameter) + +; for-in / C-style loop variable. +(for_loop_parts + name: (identifier) @local.definition.variable) + +(initialized_variable_definition + name: (identifier) @local.definition.variable) ; References ;------------ (identifier) @local.reference + +; Member access selectors carry plain identifiers that are not local references. +(unconditional_assignable_selector + (identifier) @_) +(conditional_assignable_selector + (identifier) @_) diff --git a/runtime/queries/elisp/locals.scm b/runtime/queries/elisp/locals.scm new file mode 100644 index 00000000..5afc1996 --- /dev/null +++ b/runtime/queries/elisp/locals.scm @@ -0,0 +1,40 @@ +; Scopes + +[ + (function_definition) + (macro_definition) +] @local.scope + +; `lambda`/`let`/`let*` are `special_form`s; the leading keyword is an anonymous +; token, so scope on the specific form rather than all special forms. +(special_form + . + ["lambda" "let" "let*"]) @local.scope + +; Definitions + +(function_definition + parameters: (list (symbol) @local.definition.variable.parameter)) +(macro_definition + parameters: (list (symbol) @local.definition.variable.parameter)) + +; (lambda (a b) ...) +(special_form + . + "lambda" + . + (list (symbol) @local.definition.variable.parameter)) + +; (let ((x v) (y w)) ...) / let* — each binding's first symbol +(special_form + . + ["let" "let*"] + . + (list + (list + . + (symbol) @local.definition.variable))) + +; References + +(symbol) @local.reference diff --git a/runtime/queries/elixir/locals.scm b/runtime/queries/elixir/locals.scm new file mode 100644 index 00000000..348bc216 --- /dev/null +++ b/runtime/queries/elixir/locals.scm @@ -0,0 +1,25 @@ +; Elixir is macro-heavy and `def`/`defp` are ordinary `call`s, so a general +; def/scope story can't be expressed without guessing. The one unambiguous +; binding form is the anonymous function `fn ... -> ... end`. + +; Scopes + +(anonymous_function) @local.scope + +; Definitions + +; `fn x, y -> ... end`: plain identifiers in the clause head are parameters. +; (Destructuring patterns are intentionally left to highlights.scm.) +(stab_clause + left: (arguments + (identifier) @local.definition.variable.parameter)) + +; `fn x when guard -> ... end`: the head is wrapped in a `when` binary_operator. +(stab_clause + left: (binary_operator + left: (arguments + (identifier) @local.definition.variable.parameter))) + +; References + +(identifier) @local.reference diff --git a/runtime/queries/elm/locals.scm b/runtime/queries/elm/locals.scm index 63d31ba5..08af4775 100644 --- a/runtime/queries/elm/locals.scm +++ b/runtime/queries/elm/locals.scm @@ -1,3 +1,4 @@ +; Scopes (value_declaration) @local.scope (type_alias_declaration) @local.scope (type_declaration) @local.scope @@ -5,10 +6,28 @@ (port_annotation) @local.scope (infix_declaration) @local.scope (let_in_expr) @local.scope +(anonymous_function_expr) @local.scope +(case_of_branch) @local.scope -(function_declaration_left (lower_pattern (lower_case_identifier)) @local.definition.function) -(function_declaration_left (lower_case_identifier) @local.definition.function) +; Definitions +; The lower_case_identifier child (not the pattern field) is the function name. +(function_declaration_left + (lower_case_identifier) @local.definition.function) +; `lower_pattern` is the leaf binding node in every pattern position (function +; params, lambda params, case branches, let/top-level destructuring) at any +; nesting depth, so a single rule covers names inside tuple/list/cons/record +; patterns too. +(lower_pattern (lower_case_identifier) @local.definition.variable) -(value_expr(value_qid(upper_case_identifier)) @local.reference) -(value_expr(value_qid(lower_case_identifier)) @local.reference) +; Function and lambda parameters: re-capture with the parameter class. Placed +; after the broad `variable` rule so parameters win the `variable.parameter` +; highlight. +(function_declaration_left + pattern: (_ (lower_case_identifier) @local.definition.variable.parameter)) +(anonymous_function_expr + param: (pattern (_ (lower_case_identifier)) @local.definition.variable.parameter)) + +; References +(value_expr (value_qid (upper_case_identifier)) @local.reference) +(value_expr (value_qid (lower_case_identifier)) @local.reference) (type_ref (upper_case_qid) @local.reference) diff --git a/runtime/queries/fennel/locals.scm b/runtime/queries/fennel/locals.scm new file mode 100644 index 00000000..4e4140a7 --- /dev/null +++ b/runtime/queries/fennel/locals.scm @@ -0,0 +1,50 @@ +; Scopes + +[ + (fn_form) + (lambda_form) + (hashfn_form) + (let_form) + (each_form) + (for_form) + (collect_form) + (icollect_form) + (fcollect_form) + (accumulate_form) + (faccumulate_form) +] @local.scope + +; Definitions + +; Function parameters; rest_binding covers the trailing `& rest` form. +(sequence_arguments + (symbol_binding) @local.definition.variable.parameter) +(sequence_arguments + (rest_binding + rhs: (symbol_binding) @local.definition.variable.parameter)) + +; (let [x ...] ...) +(let_vars + (binding_pair + lhs: (symbol_binding) @local.definition.variable)) + +; (local x ...) / (var x ...) / (global x ...) +[ + (local_form) + (var_form) + (global_form) +] + (binding_pair + lhs: (symbol_binding) @local.definition.variable) + +; Loop bindings +(iter_body + binding: (symbol_binding) @local.definition.variable) +(for_iter_body + index: (symbol_binding) @local.definition.variable) +(accumulator_pair + accumulator_binding: (symbol_binding) @local.definition.variable) + +; References + +(symbol) @local.reference diff --git a/runtime/queries/fish/locals.scm b/runtime/queries/fish/locals.scm new file mode 100644 index 00000000..6357f297 --- /dev/null +++ b/runtime/queries/fish/locals.scm @@ -0,0 +1,14 @@ +; Scopes + +(function_definition) @local.scope + +; Definitions + +; `set`/`read` bindings aren't a dedicated node (the name is an untyped `word` +; argument), so only the for-loop variable is reliably a definition. +(for_statement + variable: (variable_name) @local.definition.variable) + +; References + +(variable_name) @local.reference diff --git a/runtime/queries/fsharp/locals.scm b/runtime/queries/fsharp/locals.scm index b9b0cf1e..9b79b979 100644 --- a/runtime/queries/fsharp/locals.scm +++ b/runtime/queries/fsharp/locals.scm @@ -4,18 +4,36 @@ (namespace) (named_module) (function_or_value_defn) + (fun_expression) + (for_expression) + (match_expression) + (rule) ] @local.scope (function_declaration_left . - ((_) @local.definition.function) - ((argument_patterns - [ - (_ (identifier) @local.definition.variable.parameter) - (_ (_ (identifier) @local.definition.variable.parameter)) - (_ (_ (_ (identifier) @local.definition.variable.parameter))) - (_ (_ (_ (_ (identifier) @local.definition.variable.parameter)))) - (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter))))) - (_ (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter)))))) - ]) - )) + ((_) @local.definition.function)) + +; Parameters live in `argument_patterns`, which appears under function +; declarations, lambdas (`fun_expression`) and property accessors alike. The +; identifier can sit several pattern wrappers deep (paren/typed/tuple/as), so +; match it at any of those depths. +(argument_patterns + [ + (_ (identifier) @local.definition.variable.parameter) + (_ (_ (identifier) @local.definition.variable.parameter)) + (_ (_ (_ (identifier) @local.definition.variable.parameter))) + (_ (_ (_ (_ (identifier) @local.definition.variable.parameter)))) + (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter))))) + (_ (_ (_ (_ (_ (_ (identifier) @local.definition.variable.parameter)))))) + ]) + +; `for i in ...` loop variable. +(for_expression + (identifier) @local.definition.variable) + +; The `field` of `a.b` is member access, not a value reference. +(dot_expression + field: (long_identifier_or_op (identifier) @_)) +(dot_expression + field: (long_identifier_or_op (long_identifier (identifier) @_))) diff --git a/runtime/queries/go/locals.scm b/runtime/queries/go/locals.scm index 6830e91d..ff0d2046 100644 --- a/runtime/queries/go/locals.scm +++ b/runtime/queries/go/locals.scm @@ -3,6 +3,7 @@ [ (function_declaration) (method_declaration) + (func_literal) (type_declaration) (block) ] @local.scope @@ -16,6 +17,19 @@ (const_spec name: (identifier) @local.definition.constant)) +(var_spec + name: (identifier) @local.definition.variable) + +(short_var_declaration + left: (expression_list (identifier) @local.definition.variable)) + +(range_clause + left: (expression_list (identifier) @local.definition.variable)) + +; Bound identifier of `switch v := x.(type)`. +(type_switch_statement + alias: (expression_list (identifier) @local.definition.variable)) + ; References (identifier) @local.reference diff --git a/runtime/queries/haxe/locals.scm b/runtime/queries/haxe/locals.scm index bc58c10d..66b33d4f 100644 --- a/runtime/queries/haxe/locals.scm +++ b/runtime/queries/haxe/locals.scm @@ -1,7 +1,10 @@ ; Scopes [ (block) + (class_declaration) + (interface_declaration) (function_declaration) + (switch_expression) ] @local.scope ; Definitions @@ -9,4 +12,17 @@ (variable_declaration name: (identifier) @local.definition.variable) ; References -(block (identifier)) @local.reference +(identifier) @local.reference + +; The `member` side of `a.b` is field access, not a variable reference. +(member_expression + member: (identifier) @_) +; A bare-identifier callee is a function/method name, not a variable reference +; (matches the `@function` baseline in highlights.scm). +(call_expression + object: (identifier) @_) +; Type names are type references, not value references. +(type + type_name: (identifier) @_) +(type + built_in: (identifier) @_) diff --git a/runtime/queries/hdl/locals.scm b/runtime/queries/hdl/locals.scm new file mode 100644 index 00000000..94d66aba --- /dev/null +++ b/runtime/queries/hdl/locals.scm @@ -0,0 +1,22 @@ +; Scopes + +(chip_definition) @local.scope + +; Definitions + +; A chip's IN/OUT/CLOCKED pins are the signals visible inside its PARTS body. +(in_section + input_pin_name: (identifier) @local.definition.variable.parameter) +(out_section + output_pin_name: (identifier) @local.definition.variable.parameter) +(clocked_body + (identifier) @local.definition.variable.parameter) + +; References + +; In `part_pin=chip_pin`, the chip_pin is a signal in the enclosing chip's scope. +(connection + chip_pin: (identifier) @local.reference) +(connection + chip_pin: (bus_identifier + (identifier) @local.reference)) diff --git a/runtime/queries/java/locals.scm b/runtime/queries/java/locals.scm new file mode 100644 index 00000000..b65352d7 --- /dev/null +++ b/runtime/queries/java/locals.scm @@ -0,0 +1,49 @@ +; Scopes + +[ + (method_declaration) + (constructor_declaration) + (compact_constructor_declaration) + (lambda_expression) + (for_statement) + (enhanced_for_statement) + (block) +] @local.scope + +; Definitions + +(formal_parameter + name: (identifier) @local.definition.variable.parameter) +; `Type... name` — the name lives in a variable_declarator child, not a `name:` field. +(spread_parameter + (variable_declarator + name: (identifier) @local.definition.variable.parameter)) +(catch_formal_parameter + name: (identifier) @local.definition.variable.parameter) +; Lambda params: `x -> …` (single bare identifier) and `(x, y) -> …` (inferred). +(lambda_expression + parameters: (identifier) @local.definition.variable.parameter) +(inferred_parameters + (identifier) @local.definition.variable.parameter) + +(local_variable_declaration + (variable_declarator + name: (identifier) @local.definition.variable)) +(enhanced_for_statement + name: (identifier) @local.definition.variable) + +; References + +(identifier) @local.reference + +; Discards: identifiers that look like references but aren't variables. + +; `obj.method(…)` — the method name is not a variable. +(method_invocation + name: (identifier) @_) +; `obj.field` — the field name is not a local. +(field_access + field: (identifier) @_) +; `Outer.name` qualified access. +(scoped_identifier + name: (identifier) @_) diff --git a/runtime/queries/julia/locals.scm b/runtime/queries/julia/locals.scm index d3a434d0..dd424490 100644 --- a/runtime/queries/julia/locals.scm +++ b/runtime/queries/julia/locals.scm @@ -33,7 +33,20 @@ ; ---------- (identifier) @local.reference - + +; A call's function name, field member access, and keyword-argument names are +; not variable references; cancel resolution so they keep their highlights.scm +; class even when a same-named local is in scope. +(call_expression + . (identifier) @_) +(field_expression + (_) + (identifier) @_) +(call_expression + (argument_list + (assignment + . (identifier) @_))) + ; ------ ; Scopes ; ------ diff --git a/runtime/queries/kotlin/locals.scm b/runtime/queries/kotlin/locals.scm index 2080cddd..cd007683 100644 --- a/runtime/queries/kotlin/locals.scm +++ b/runtime/queries/kotlin/locals.scm @@ -3,6 +3,12 @@ (class_declaration) (function_declaration) (lambda_literal) + ; `fun(x) { … }` expression form: has its own parameters and body. + (anonymous_function) + (control_structure_body) + (when_entry) + ; for/while loop variables are declared on the statement, not in its body. + (for_statement) ] @local.scope ; Definitions @@ -17,7 +23,16 @@ (variable_declaration (simple_identifier) @local.definition.variable.parameter))) +; Loop and local `val`/`var` bindings; defined so inner references resolve and +; shadow correctly. +(variable_declaration + (simple_identifier) @local.definition.variable) + ; References (simple_identifier) @local.reference (type_identifier) @local.reference (interpolated_identifier) @local.reference + +; Member access after `.` is not a local reference. +(navigation_suffix + (simple_identifier) @_) diff --git a/runtime/queries/lua/locals.scm b/runtime/queries/lua/locals.scm new file mode 100644 index 00000000..3fc9a18a --- /dev/null +++ b/runtime/queries/lua/locals.scm @@ -0,0 +1,53 @@ +; Scopes + +[ + (chunk) + (function_declaration) + (function_definition) + (do_statement) + (while_statement) + (repeat_statement) + (if_statement) + (for_statement) +] @local.scope + +; Definitions + +(parameters + (identifier) @local.definition.variable.parameter) + +; `self` in a method is an implicit parameter. +(parameters + (identifier) @local.definition.variable.builtin + (#eq? @local.definition.variable.builtin "self")) + +(for_numeric_clause + name: (identifier) @local.definition.variable) + +(for_generic_clause + (variable_list + (variable + (identifier) @local.definition.variable))) + +; `local x, y = ...` +(variable_declaration + (assignment_statement + (variable_list + (variable + (identifier) @local.definition.variable)))) +(variable_declaration + (variable_list + (variable + (identifier) @local.definition.variable))) + +; References + +(identifier) @local.reference + +; Field/member names are not variable references. +(dot_index_expression + field: (identifier) @_) +(method_index_expression + method: (identifier) @_) +(field + name: (identifier) @_) diff --git a/runtime/queries/matlab/locals.scm b/runtime/queries/matlab/locals.scm index 882d9818..718a33d6 100644 --- a/runtime/queries/matlab/locals.scm +++ b/runtime/queries/matlab/locals.scm @@ -4,3 +4,10 @@ (lambda (arguments (identifier) @local.definition.variable.parameter)) @local.scope (identifier) @local.reference + +; A call's function name and a field member name are not variable references; +; cancel resolution so a same-named local doesn't capture them. +(function_call + name: (identifier) @_) +(field_expression + field: (identifier) @_) diff --git a/runtime/queries/openscad/locals.scm b/runtime/queries/openscad/locals.scm new file mode 100644 index 00000000..13808607 --- /dev/null +++ b/runtime/queries/openscad/locals.scm @@ -0,0 +1,39 @@ +; Scopes + +[ + (function_item) + (function_lit) + (module_item) + (let_expression) + (let_block) + (assign_block) + (for_block) + (intersection_for_block) + (list_comprehension) +] @local.scope + +; Definitions + +; Parameters: a bare `identifier`, or `name = default` via an `assignment`. +(parameters + (parameter + (identifier) @local.definition.variable.parameter)) +(parameters + (parameter + (assignment + name: (identifier) @local.definition.variable.parameter))) + +; let(x = ...) / assign(x = ...) / for(x = ...) bindings +(assignments + (assignment + name: (identifier) @local.definition.variable)) + +; References + +(identifier) @local.reference + +; Call targets are function/module names, not variable references. +(function_call + name: (identifier) @_) +(module_call + name: (identifier) @_) diff --git a/runtime/queries/pascal/locals.scm b/runtime/queries/pascal/locals.scm new file mode 100644 index 00000000..87c96947 --- /dev/null +++ b/runtime/queries/pascal/locals.scm @@ -0,0 +1,26 @@ +; Scopes + +[ + (declProc) + (block) +] @local.scope + +; Definitions + +(declArg + name: (identifier) @local.definition.variable.parameter) + +(declVar + name: (identifier) @local.definition.variable) + +; References + +(identifier) @local.reference + +; The rhs of `a.b` is a member access, not a variable reference. +(exprDot + rhs: (identifier) @_) + +; Procedure/function names in call position are not variable references. +(exprCall + entity: (identifier) @_) diff --git a/runtime/queries/php-only/locals.scm b/runtime/queries/php-only/locals.scm new file mode 100644 index 00000000..f89f618e --- /dev/null +++ b/runtime/queries/php-only/locals.scm @@ -0,0 +1,24 @@ +; Scopes + +[ + (function_definition) + (method_declaration) + (anonymous_function) + (arrow_function) + (compound_statement) +] @local.scope + +; Definitions + +; PHP variables are `variable_name` ($foo); parameters share that node type so +; references match by text including the leading `$`. +(simple_parameter + name: (variable_name) @local.definition.variable.parameter) +(variadic_parameter + name: (variable_name) @local.definition.variable.parameter) +(property_promotion_parameter + name: (variable_name) @local.definition.variable.parameter) + +; References + +(variable_name) @local.reference diff --git a/runtime/queries/php/locals.scm b/runtime/queries/php/locals.scm new file mode 100644 index 00000000..f89f618e --- /dev/null +++ b/runtime/queries/php/locals.scm @@ -0,0 +1,24 @@ +; Scopes + +[ + (function_definition) + (method_declaration) + (anonymous_function) + (arrow_function) + (compound_statement) +] @local.scope + +; Definitions + +; PHP variables are `variable_name` ($foo); parameters share that node type so +; references match by text including the leading `$`. +(simple_parameter + name: (variable_name) @local.definition.variable.parameter) +(variadic_parameter + name: (variable_name) @local.definition.variable.parameter) +(property_promotion_parameter + name: (variable_name) @local.definition.variable.parameter) + +; References + +(variable_name) @local.reference diff --git a/runtime/queries/ruby/locals.scm b/runtime/queries/ruby/locals.scm index 2da5401b..76d4b0c1 100644 --- a/runtime/queries/ruby/locals.scm +++ b/runtime/queries/ruby/locals.scm @@ -1,4 +1,12 @@ -((method) @local.scope +; Method, class, module and singleton-class bodies don't see locals from the +; enclosing scope in Ruby, so they must not inherit. +([ + (method) + (singleton_method) + (class) + (module) + (singleton_class) +] @local.scope (#set! local.scope-inherits false)) [ @@ -18,3 +26,8 @@ (optional_parameter name: (identifier) @local.definition.variable.parameter) (identifier) @local.reference + +; A method-call name is not a variable reference (the grammar only forms `call` +; when it's syntactically a call), so a same-named local must not capture it. +(call + method: (identifier) @_) diff --git a/runtime/queries/scala/locals.scm b/runtime/queries/scala/locals.scm index 60368f6c..635bc522 100644 --- a/runtime/queries/scala/locals.scm +++ b/runtime/queries/scala/locals.scm @@ -1,14 +1,46 @@ -(template_body) @local.scope -(lambda_expression) @local.scope +; Scopes +[ + (template_body) + (function_definition) + (lambda_expression) + (for_expression) + (block) + (case_clause) +] @local.scope -(function_declaration - name: (identifier) @local.definition.function) @local.scope +; Definitions (function_definition - name: (identifier) @local.definition.function) + name: (identifier) @local.definition.function) +; `def`/method and `class`/constructor parameters; baseline highlight is plain +; `variable`, so the parameter class is what makes these distinct. (parameter name: (identifier) @local.definition.variable.parameter) +(class_parameter + name: (identifier) @local.definition.variable.parameter) + +; Lambda parameters: `(x: Int) => …` (bindings) and bare `x => …`. +(bindings + (binding + name: (identifier) @local.definition.variable.parameter)) +(lambda_expression + parameters: (identifier) @local.definition.variable.parameter) + +(type_parameters + name: (identifier) @local.definition.type.parameter) + +; Local `val`/`var` bindings; defined so inner references resolve and shadow. +(val_definition + pattern: (identifier) @local.definition.variable) +(var_definition + pattern: (identifier) @local.definition.variable) + +; References (identifier) @local.reference + +; Member access after `.` is a field/method name, not a local reference. +(field_expression + field: (identifier) @_) diff --git a/runtime/queries/scheme/locals.scm b/runtime/queries/scheme/locals.scm new file mode 100644 index 00000000..b2f5e52c --- /dev/null +++ b/runtime/queries/scheme/locals.scm @@ -0,0 +1,73 @@ +; Everything in Scheme is `(list (symbol) ...)`, so scopes and definitions are +; gated by `#eq?`/`#any-of?` predicates on the leading symbol of a form. + +; Scopes + +(list + . + (symbol) @_f + (#any-of? @_f + "lambda" "λ" "case-lambda" + "let" "let*" "letrec" "letrec*" "let-values" "let*-values" + "let-syntax" "letrec-syntax" + "do")) @local.scope + +; A `(define (f args...) ...)` form is also a scope for its parameters. +(list + . + (symbol) @_f + . + (list) + (#eq? @_f "define")) @local.scope + +; Definitions + +; (lambda (a b c) ...) and (define (f a b c) ...) parameters +(list + . + (symbol) @_f + . + (list + (symbol) @local.definition.variable.parameter) + (#any-of? @_f "lambda" "λ")) + +(list + . + (symbol) @_f + . + (list + . + (symbol) ; function name, not a parameter + (symbol) @local.definition.variable.parameter) + (#eq? @_f "define")) + +; (let ((x v) (y w)) ...) and friends: each binding's first symbol +(list + . + (symbol) @_f + . + (list + (list + . + (symbol) @local.definition.variable)) + (#any-of? @_f + "let" "let*" "letrec" "letrec*" "let-values" "let*-values" + "let-syntax" "letrec-syntax" "do")) + +; (define name value) +(list + . + (symbol) @_f + . + (symbol) @local.definition.variable + (#eq? @_f "define")) + +; References + +(symbol) @local.reference + +; The leading symbol of a form is a keyword/operator/call target, not a +; variable reference; cancel resolution there. +(list + . + (symbol) @_) diff --git a/runtime/queries/sourcepawn/locals.scm b/runtime/queries/sourcepawn/locals.scm new file mode 100644 index 00000000..1fe65774 --- /dev/null +++ b/runtime/queries/sourcepawn/locals.scm @@ -0,0 +1,35 @@ +; Scopes + +[ + (function_definition) + (function_declaration) + (block) +] @local.scope + +; Definitions + +(parameter_declaration + name: (identifier) @local.definition.variable.parameter) + +(variable_declaration + name: (identifier) @local.definition.variable) +(old_variable_declaration + name: (identifier) @local.definition.variable) + +; References + +(identifier) @local.reference + +; Member/field names are not variable references. +(field_access + field: (identifier) @_) +(scope_access + field: (identifier) @_) + +; Function names in call position are not variable references. +(call_expression + function: (identifier) @_) + +; Named argument labels are not variable references. +(named_arg + arg_name: (identifier) @_) diff --git a/runtime/queries/swift/locals.scm b/runtime/queries/swift/locals.scm index 597748c1..ae3391a8 100644 --- a/runtime/queries/swift/locals.scm +++ b/runtime/queries/swift/locals.scm @@ -2,6 +2,11 @@ (import_declaration (identifier) @local.definition.namespace) (function_declaration name: (simple_identifier) @local.definition.function) +; Parameters: the `name` field is the in-body binding (external_name is the +; call-site label, handled as a discard below). +(parameter name: (simple_identifier) @local.definition.variable.parameter) +(lambda_parameter name: (simple_identifier) @local.definition.variable.parameter) + ; Scopes [ (for_statement) @@ -17,3 +22,10 @@ (protocol_declaration) (lambda_literal) ] @local.scope + +(simple_identifier) @local.reference + +; Discards: identifiers that look like references but aren't variable uses. +(call_expression (simple_identifier) @_) ; foo() call name +(navigation_suffix (simple_identifier) @_) ; .bar member/method name +(parameter external_name: (simple_identifier) @_) ; call-site argument label diff --git a/runtime/queries/vala/locals.scm b/runtime/queries/vala/locals.scm new file mode 100644 index 00000000..87e61dec --- /dev/null +++ b/runtime/queries/vala/locals.scm @@ -0,0 +1,46 @@ +; Scopes + +[ + (method_declaration) + (creation_method_declaration) + (constructor_declaration) + (destructor_declaration) + (local_function_declaration) + (lambda_expression) + (block) + (for_statement) + (foreach_statement) +] @local.scope + +; Definitions + +(parameter + (identifier) @local.definition.variable.parameter) + +(lambda_expression + (identifier) @local.definition.variable.parameter) + +; `foreach (Type x in ...)` — the identifier after the element type. +(foreach_statement + . + (type) + . + (identifier) @local.definition.variable) + +; `Type x = ...;` — first identifier of each assignment in a local declaration. +(local_declaration + (assignment + . + (identifier) @local.definition.variable)) + +; References + +(identifier) @local.reference + +; In `a.b`, `b` is a member access rather than a variable reference. A bare name +; is a single-child member_access_expression, so only discard the trailing +; identifier when it follows a receiver expression. +(member_access_expression + (_) + . + (identifier) @_) diff --git a/runtime/queries/vhdl/locals.scm b/runtime/queries/vhdl/locals.scm new file mode 100644 index 00000000..4f89896f --- /dev/null +++ b/runtime/queries/vhdl/locals.scm @@ -0,0 +1,34 @@ +; Scopes + +[ + (subprogram_definition) + (process_statement) +] @local.scope + +; Definitions + +; Subprogram parameters: each interface declaration's identifier_list holds the +; parameter name(s), reachable regardless of the constant:/generic: field label. +(parameter_list_specification + (interface_list + (_ + (identifier_list + (identifier) @local.definition.variable.parameter)))) + +; Locally declared signals/variables/constants. +(signal_declaration + (identifier_list + (identifier) @local.definition.variable)) +(variable_declaration + (identifier_list + (identifier) @local.definition.variable)) +(constant_declaration + (identifier_list + (identifier) @local.definition.constant)) + +; References + +; A use of a name is `(name (identifier) ...)`; the base identifier may resolve. +; Member identifiers live inside (selection ...) and are excluded by this shape. +(name + (identifier) @local.reference)