This commit is contained in:
Paul Gauthier 2025-03-12 14:14:13 -07:00
parent f55099e969
commit e69bad57e4
24 changed files with 829 additions and 0 deletions

View file

@ -0,0 +1,5 @@
(function_declarator
declarator: (identifier) @name) @definition.function
(call_expression
function: (identifier) @name) @reference.call

View file

@ -0,0 +1,9 @@
(struct_specifier name: (type_identifier) @name body:(_)) @definition.class
(declaration type: (union_specifier name: (type_identifier) @name)) @definition.class
(function_declarator declarator: (identifier) @name) @definition.function
(type_definition declarator: (type_identifier) @name) @definition.type
(enum_specifier name: (type_identifier) @name) @definition.type

View file

@ -0,0 +1,16 @@
; Definitions
(intent_def
(intent) @name) @definition.intent
(slot_def
(slot) @name) @definition.slot
(alias_def
(alias) @name) @definition.alias
; References
(slot_ref
(slot) @name) @reference.slot
(alias_ref
(alias) @name) @reference.alias

View file

@ -0,0 +1,122 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Function Definitions ;;;;;;;;;;;;;;;;;;;;;;;
(defun_header
function_name: (sym_lit) @name) @definition.function
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Function Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; Basically, we consider every list literal with symbol as the
;;; first element to be a call to a function named by that element.
;;; But we must exclude some cases. Note, tree-sitter @ignore
;;; cases only work if they are declared before the cases
;;; we want to include.
;; Exclude lambda lists for function definitions
;; For example:
;;
;; (defun my-func (arg1 arg2) ...)
;;
;; do not treat (arg1 arg2) as a call of function arg1
;;
(defun_header
lambda_list: (list_lit . [(sym_lit) (package_lit)] @ignore))
;; Similar to the above, but for
;;
;; (defmethod m ((type1 param1) (type2 param2)) ...)
;;
;; where list literals having symbol as their first element
;; are nested inside the lambda list.
(defun_header
lambda_list: (list_lit (list_lit . [(sym_lit) (package_lit)] @ignore)))
;;
;; (let ((var ...) (var2 ...)) ...)
;;
;; - exclude var, var2
;; - the same for let*, flet, labels, macrolet, symbol-macrolet
(list_lit . [(sym_lit) (package_lit)] @name
. (list_lit (list_lit . [(sym_lit) (package_lit)] @ignore))
(#match? @name
"(?i)^(cl:)?(let|let\\*|flet|labels|macrolet|symbol-macrolet)$")
)
;; TODO:
;; - exclude also:
;; - (defclass name (parent parent2)
;; ((slot1 ...)
;; (slot2 ...))
;; exclude the parent, slot1, slot2
;; - (flet ((func-1 (param1 param2))) ...)
;; - we already exclude func-1, but param1 is still recognized
;; as a function call - exclude it too
;; - the same for labels
;; - the same macrolet
;; - what else?
;; (that's a non-goal to completely support all macros
;; and special operators, but every one we support
;; makes the solution a little bit better)
;; - (flet ((func-1 (param1 param2))) ...)
;; - instead of simply excluding it, as we do today,
;; tag func-1 as @local.definition.function (I suppose)
;; - the same for labels, macrolet
;; - @local.scope for let, let*, flet, labels, macrolet
;; - I guess the whole span of the scope text,
;; till the closing paren, should be tagged as @local.scope;
;; Hopefully, combined with @local.definition.function
;; within the scope, the usual @reference.call within
;; that scope will refer to the local definition,
;; and there will be no need to use @local.reference.call
;; (which is more difficult to implement).
;; - When implementing, remember the scope rules differences
;; of let vs let*, flet vs labels.
;; Include all other cases - list literal with symbol as the
;; first element
(list_lit . [(sym_lit) (package_lit)] @name) @reference.call
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; classes
(list_lit . [(sym_lit) (package_lit)] @ignore
. [(sym_lit) (package_lit)] @name
(#match? @ignore "(?i)^(cl:)?defclass$")
) @definition.class
(list_lit . [(sym_lit) (package_lit)] @ignore
. (quoting_lit [(sym_lit) (package_lit)] @name)
(#match? @ignore "(?i)^(cl:)?make-instance$")
) @reference.class
;;; TODO:
;; - @reference.class for base classes
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; TODO:
;; - Symbols referenced in defpackage
;;
;; (defpackage ...
;; (:export (symbol-a :symbol-b #:symbol-c "SYMBOL-D")))
;;
;; The goal is to allow quick navigation from the API
;; overview in the form of defpackage, to the definition
;; where user can read parameters, docstring, etc.
;; - The @name must not include the colon, or sharpsign colon, quotes,
;; just symbol-a, symbol-b, symbol-c, sybmol-d
;; - Downcase the names specified as string literals?
;; ("SYMBOL-D" -> symbol-d)
;; - We don't know if the exported symbol is a function, variable,
;; class or something else. The official doc
;; (https://tree-sitter.github.io/tree-sitter/code-navigation-systems)
;; does not even suggest a tag for variable reference.
;; (Although in practice, the `tree-sitter tags` command
;; allows any @reference.* and @definition.* tags)
;; Probably it's better to just use @reference.call for all
;; the symbols in the :export clause.
;;
;; - The same for the export function call:
;;
;; (export '(symbol-a :symbol-b #:symbol-c "SYMBOL-D"))

View file

@ -0,0 +1,15 @@
(struct_specifier name: (type_identifier) @name body:(_)) @definition.class
(declaration type: (union_specifier name: (type_identifier) @name)) @definition.class
(function_declarator declarator: (identifier) @name) @definition.function
(function_declarator declarator: (field_identifier) @name) @definition.function
(function_declarator declarator: (qualified_identifier scope: (namespace_identifier) @local.scope name: (identifier) @name)) @definition.method
(type_definition declarator: (type_identifier) @name) @definition.type
(enum_specifier name: (type_identifier) @name) @definition.type
(class_specifier name: (type_identifier) @name) @definition.class

View file

@ -0,0 +1,26 @@
(module_def (module_declaration (module_fqn) @name)) @definition.module
(struct_declaration (struct) . (identifier) @name) @definition.class
(interface_declaration (interface) . (identifier) @name) @definition.interface
(enum_declaration (enum) . (identifier) @name) @definition.type
(class_declaration (class) . (identifier) @name) @definition.class
(constructor (this) @name) @definition.method
(destructor (this) @name) @definition.method
(postblit (this) @name) @definition.method
(manifest_declarator . (identifier) @name) @definition.type
(function_declaration (identifier) @name) @definition.function
(union_declaration (union) . (identifier) @name) @definition.type
(anonymous_enum_declaration (enum_member . (identifier) @name)) @definition.constant
(enum_declaration (enum_member . (identifier) @name)) @definition.constant
(call_expression (identifier) @name) @reference.call
(call_expression (type (template_instance (identifier) @name))) @reference.call
(parameter (type (identifier) @name) @reference.class (identifier))
(variable_declaration (type (identifier) @name) @reference.class (declarator))

View file

@ -0,0 +1,92 @@
(class_definition
name: (identifier) @name) @definition.class
(method_signature
(function_signature)) @definition.method
(type_alias
(type_identifier) @name) @definition.type
(method_signature
(getter_signature
name: (identifier) @name)) @definition.method
(method_signature
(setter_signature
name: (identifier) @name)) @definition.method
(method_signature
(function_signature
name: (identifier) @name)) @definition.method
(method_signature
(factory_constructor_signature
(identifier) @name)) @definition.method
(method_signature
(constructor_signature
name: (identifier) @name)) @definition.method
(method_signature
(operator_signature)) @definition.method
(method_signature) @definition.method
(mixin_declaration
(mixin)
(identifier) @name) @definition.mixin
(extension_declaration
name: (identifier) @name) @definition.extension
(new_expression
(type_identifier) @name) @reference.class
(enum_declaration
name: (identifier) @name) @definition.enum
(function_signature
name: (identifier) @name) @definition.function
(initialized_variable_definition
name: (identifier)
value: (identifier) @name
value: (selector
"!"?
(argument_part
(arguments
(argument)*))?)?) @reference.class
(assignment_expression
left: (assignable_expression
(identifier)
(unconditional_assignable_selector
"."
(identifier) @name))) @reference.call
(assignment_expression
left: (assignable_expression
(identifier)
(conditional_assignable_selector
"?."
(identifier) @name))) @reference.call
((identifier) @name
(selector
"!"?
(conditional_assignable_selector
"?." (identifier) @name)?
(unconditional_assignable_selector
"."? (identifier) @name)?
(argument_part
(arguments
(argument)*))?)*
(cascade_section
(cascade_selector
(identifier)) @name
(argument_part
(arguments
(argument)*))?)?) @reference.call

View file

@ -0,0 +1,5 @@
;; defun/defsubst
(function_definition name: (symbol) @name) @definition.function
;; Treat macros as function definitions for the sake of TAGS.
(macro_definition name: (symbol) @name) @definition.function

View file

@ -0,0 +1,54 @@
; Definitions
; * modules and protocols
(call
target: (identifier) @ignore
(arguments (alias) @name)
(#any-of? @ignore "defmodule" "defprotocol")) @definition.module
; * functions/macros
(call
target: (identifier) @ignore
(arguments
[
; zero-arity functions with no parentheses
(identifier) @name
; regular function clause
(call target: (identifier) @name)
; function clause with a guard clause
(binary_operator
left: (call target: (identifier) @name)
operator: "when")
])
(#any-of? @ignore "def" "defp" "defdelegate" "defguard" "defguardp" "defmacro" "defmacrop" "defn" "defnp")) @definition.function
; References
; ignore calls to kernel/special-forms keywords
(call
target: (identifier) @ignore
(#any-of? @ignore "def" "defp" "defdelegate" "defguard" "defguardp" "defmacro" "defmacrop" "defn" "defnp" "defmodule" "defprotocol" "defimpl" "defstruct" "defexception" "defoverridable" "alias" "case" "cond" "else" "for" "if" "import" "quote" "raise" "receive" "require" "reraise" "super" "throw" "try" "unless" "unquote" "unquote_splicing" "use" "with"))
; ignore module attributes
(unary_operator
operator: "@"
operand: (call
target: (identifier) @ignore))
; * function call
(call
target: [
; local
(identifier) @name
; remote
(dot
right: (identifier) @name)
]) @reference.call
; * pipe into function call
(binary_operator
operator: "|>"
right: (identifier) @name) @reference.call
; * modules
(alias) @name @reference.module

View file

@ -0,0 +1,19 @@
(value_declaration (function_declaration_left (lower_case_identifier) @name)) @definition.function
(function_call_expr (value_expr (value_qid) @name)) @reference.function
(exposed_value (lower_case_identifier) @name) @reference.function
(type_annotation ((lower_case_identifier) @name) (colon)) @reference.function
(type_declaration ((upper_case_identifier) @name) ) @definition.type
(type_ref (upper_case_qid (upper_case_identifier) @name)) @reference.type
(exposed_type (upper_case_identifier) @name) @reference.type
(type_declaration (union_variant (upper_case_identifier) @name)) @definition.union
(value_expr (upper_case_qid (upper_case_identifier) @name)) @reference.union
(module_declaration
(upper_case_qid (upper_case_identifier)) @name
) @definition.module

View file

@ -0,0 +1,41 @@
; Modules
(module) @name @reference.module
(import alias: (identifier) @name) @reference.module
(remote_type_identifier
module: (identifier) @name) @reference.module
((field_access
record: (identifier) @name)
(#is-not? local)) @reference.module
; Functions
(function
name: (identifier) @name) @definition.function
(external_function
name: (identifier) @name) @definition.function
(unqualified_import (identifier) @name) @reference.function
((function_call
function: (identifier) @name) @reference.function
(#is-not? local))
((field_access
record: (identifier) @ignore
field: (label) @name)
(#is-not? local)) @reference.function
((binary_expression
operator: "|>"
right: (identifier) @name)
(#is-not? local)) @reference.function
; Types
(type_definition
(type_name
name: (type_identifier) @name)) @definition.type
(type_definition
(data_constructors
(data_constructor
name: (constructor_name) @name))) @definition.constructor
(external_type
(type_name
name: (type_identifier) @name)) @definition.type
(type_identifier) @name @reference.type
(constructor_name) @name @reference.constructor

View file

@ -0,0 +1,42 @@
(
(comment)* @doc
.
(function_declaration
name: (identifier) @name) @definition.function
(#strip! @doc "^//\\s*")
(#set-adjacent! @doc @definition.function)
)
(
(comment)* @doc
.
(method_declaration
name: (field_identifier) @name) @definition.method
(#strip! @doc "^//\\s*")
(#set-adjacent! @doc @definition.method)
)
(call_expression
function: [
(identifier) @name
(parenthesized_expression (identifier) @name)
(selector_expression field: (field_identifier) @name)
(parenthesized_expression (selector_expression field: (field_identifier) @name))
]) @reference.call
(type_spec
name: (type_identifier) @name) @definition.type
(type_identifier) @name @reference.type
(package_clause "package" (package_identifier) @name)
(type_declaration (type_spec name: (type_identifier) @name type: (interface_type)))
(type_declaration (type_spec name: (type_identifier) @name type: (struct_type)))
(import_declaration (import_spec) @name)
(var_declaration (var_spec name: (identifier) @name))
(const_declaration (const_spec name: (identifier) @name))

View file

@ -0,0 +1,20 @@
(class_declaration
name: (identifier) @name) @definition.class
(method_declaration
name: (identifier) @name) @definition.method
(method_invocation
name: (identifier) @name
arguments: (argument_list) @reference.call)
(interface_declaration
name: (identifier) @name) @definition.interface
(type_list
(type_identifier) @name) @reference.implementation
(object_creation_expression
type: (type_identifier) @name) @reference.class
(superclass (type_identifier) @name) @reference.class

View file

@ -0,0 +1,34 @@
(function_declaration
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
]) @definition.function
(function_declaration
name: (method_index_expression
method: (identifier) @name)) @definition.method
(assignment_statement
(variable_list .
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
])
(expression_list .
value: (function_definition))) @definition.function
(table_constructor
(field
name: (identifier) @name
value: (function_definition))) @definition.function
(function_call
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
(method_index_expression
method: (identifier) @name)
]) @reference.call

View file

@ -0,0 +1,39 @@
;Class definitions @definition.class
;Function definitions @definition.function
;Interface definitions @definition.interface
;Method definitions @definition.method
;Module definitions @definition.module
;Function/method calls @reference.call
;Class reference @reference.class
;Interface implementation @reference.implementation
(
(identifier) @reference.class
(#match? @reference.class "^_*[A-Z][a-zA-Z0-9_]*$")
)
(class_definition (identifier) @name) @definition.class
(actor_definition (identifier) @name) @definition.class
(primitive_definition (identifier) @name) @definition.class
(struct_definition (identifier) @name) @definition.class
(type_alias (identifier) @name) @definition.class
(trait_definition (identifier) @name) @definition.interface
(interface_definition (identifier) @name) @definition.interface
(constructor (identifier) @name) @definition.method
(method (identifier) @name) @definition.method
(behavior (identifier) @name) @definition.method
(class_definition (type) @name) @reference.implementation
(actor_definition (type) @name) @reference.implementation
(primitive_definition (type) @name) @reference.implementation
(struct_definition (type) @name) @reference.implementation
(type_alias (type) @name) @reference.implementation
; calls - not catching all possible call cases of callees for capturing the method name
(call_expression callee: [(identifier) (ffi_identifier)] @name) @reference.call
(call_expression callee: (generic_expression [(identifier) (ffi_identifier)] @name)) @reference.call
(call_expression callee: (member_expression (identifier) @name .)) @reference.call
(call_expression callee: (member_expression (generic_expression [(identifier) (ffi_identifier)] @name) .)) @reference.call
; TODO: add more possible callee expressions
(call_expression) @reference.call

View file

@ -0,0 +1,5 @@
(property
(key) @name) @definition.property
(substitution
(key) @name) @reference.property

View file

@ -0,0 +1,14 @@
(module (expression_statement (assignment left: (identifier) @name) @definition.constant))
(class_definition
name: (identifier) @name) @definition.class
(function_definition
name: (identifier) @name) @definition.function
(call
function: [
(identifier) @name
(attribute
attribute: (identifier) @name)
]) @reference.call

View file

@ -0,0 +1,21 @@
(binary_operator
lhs: (identifier) @name
operator: "<-"
rhs: (function_definition)
) @definition.function
(binary_operator
lhs: (identifier) @name
operator: "="
rhs: (function_definition)
) @definition.function
(call
function: (identifier) @name
) @reference.call
(call
function: (namespace_operator
rhs: (identifier) @name
)
) @reference.call

View file

@ -0,0 +1,12 @@
(list
.
(symbol) @reference._define
(#match? @reference._define "^(define|define/contract)$")
.
(list
.
(symbol) @name) @definition.function)
(list
.
(symbol) @reference.call)

View file

@ -0,0 +1,64 @@
; Method definitions
(
(comment)* @doc
.
[
(method
name: (_) @name) @definition.method
(singleton_method
name: (_) @name) @definition.method
]
(#strip! @doc "^#\\s*")
(#select-adjacent! @doc @definition.method)
)
(alias
name: (_) @name) @definition.method
(setter
(identifier) @ignore)
; Class definitions
(
(comment)* @doc
.
[
(class
name: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.class
(singleton_class
value: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.class
]
(#strip! @doc "^#\\s*")
(#select-adjacent! @doc @definition.class)
)
; Module definitions
(
(module
name: [
(constant) @name
(scope_resolution
name: (_) @name)
]) @definition.module
)
; Calls
(call method: (identifier) @name) @reference.call
(
[(identifier) (constant)] @name @reference.call
(#is-not? local)
(#not-match? @name "^(lambda|load|require|require_relative|__FILE__|__LINE__)$")
)

View file

@ -0,0 +1,60 @@
; ADT definitions
(struct_item
name: (type_identifier) @name) @definition.class
(enum_item
name: (type_identifier) @name) @definition.class
(union_item
name: (type_identifier) @name) @definition.class
; type aliases
(type_item
name: (type_identifier) @name) @definition.class
; method definitions
(declaration_list
(function_item
name: (identifier) @name) @definition.method)
; function definitions
(function_item
name: (identifier) @name) @definition.function
; trait definitions
(trait_item
name: (type_identifier) @name) @definition.interface
; module definitions
(mod_item
name: (identifier) @name) @definition.module
; macro definitions
(macro_definition
name: (identifier) @name) @definition.macro
; references
(call_expression
function: (identifier) @name) @reference.call
(call_expression
function: (field_expression
field: (field_identifier) @name)) @reference.call
(macro_invocation
macro: (identifier) @name) @reference.call
; implementations
(impl_item
trait: (type_identifier) @name) @reference.implementation
(impl_item
type: (type_identifier) @name
!trait) @reference.implementation

View file

@ -0,0 +1,43 @@
;; Method and Function declarations
(contract_declaration (_
(function_definition
name: (identifier) @name) @definition.method))
(source_file
(function_definition
name: (identifier) @name) @definition.function)
;; Contract, struct, enum and interface declarations
(contract_declaration
name: (identifier) @name) @definition.class
(interface_declaration
name: (identifier) @name) @definition.interface
(library_declaration
name: (identifier) @name) @definition.interface
(struct_declaration name: (identifier) @name) @definition.class
(enum_declaration name: (identifier) @name) @definition.class
(event_definition name: (identifier) @name) @definition.class
;; Function calls
(call_expression (expression (identifier)) @name ) @reference.call
(call_expression
(expression (member_expression
property: (_) @name ))) @reference.call
;; Log emit
(emit_statement name: (_) @name) @reference.class
;; Inheritance
(inheritance_specifier
ancestor: (user_defined_type (_) @name . )) @reference.class
;; Imports ( note that unknown is not standardised )
(import_directive
import_name: (_) @name ) @reference.unknown

View file

@ -0,0 +1,51 @@
(class_declaration
name: (type_identifier) @name) @definition.class
(protocol_declaration
name: (type_identifier) @name) @definition.interface
(class_declaration
(class_body
[
(function_declaration
name: (simple_identifier) @name
)
(subscript_declaration
(parameter (simple_identifier) @name)
)
(init_declaration "init" @name)
(deinit_declaration "deinit" @name)
]
)
) @definition.method
(protocol_declaration
(protocol_body
[
(protocol_function_declaration
name: (simple_identifier) @name
)
(subscript_declaration
(parameter (simple_identifier) @name)
)
(init_declaration "init" @name)
]
)
) @definition.method
(class_declaration
(class_body
[
(property_declaration
(pattern (simple_identifier) @name)
)
]
)
) @definition.property
(property_declaration
(pattern (simple_identifier) @name)
) @definition.property
(function_declaration
name: (simple_identifier) @name) @definition.function

View file

@ -0,0 +1,20 @@
(assignment
key: "LABEL"
(value
(content) @name)) @definition.label
(assignment
key: "GOTO"
(value
(content) @name)) @reference.label
(assignment
key: "ENV"
(env_var) @name) @definition.variable
(match
key: "ENV"
(env_var) @name) @reference.variable
(var_sub
(env_var) @name) @reference.variable