(
  (comment)* @doc
  .
  (method_definition
    name: (property_identifier) @name) @definition.method
  (#not-eq? @name "constructor")
  (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
  (#select-adjacent! @doc @definition.method)
)

(
  (comment)* @doc
  .
  [
    (class
      name: (_) @name)
    (class_declaration
      name: (_) @name)
  ] @definition.class
  (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
  (#select-adjacent! @doc @definition.class)
)

(
  (comment)* @doc
  .
  [
    (function_expression
      name: (identifier) @name)
    (function_declaration
      name: (identifier) @name)
    (generator_function
      name: (identifier) @name)
    (generator_function_declaration
      name: (identifier) @name)
  ] @definition.function
  (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
  (#select-adjacent! @doc @definition.function)
)

(
  (comment)* @doc
  .
  (lexical_declaration
    (variable_declarator
      name: (identifier) @name
      value: [(arrow_function) (function_expression)]) @definition.function)
  (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
  (#select-adjacent! @doc @definition.function)
)

(
  (comment)* @doc
  .
  (variable_declaration
    (variable_declarator
      name: (identifier) @name
      value: [(arrow_function) (function_expression)]) @definition.function)
  (#strip! @doc "^[\\s\\*/]+|^[\\s\\*/]$")
  (#select-adjacent! @doc @definition.function)
)

(assignment_expression
  left: [
    (identifier) @name
  ]
  right: [(arrow_function) (function_expression)]
) @definition.function

(pair
  key: (property_identifier) @name
  value: [(arrow_function) (function_expression)]) @definition.function

(lexical_declaration
  (variable_declarator
    name: (identifier) @name)) @definition.variable

(variable_declaration
  (variable_declarator
    name: (identifier) @name)) @definition.variable

(formal_parameters
  (identifier) @name) @definition.parameter

(
  (call_expression
    function: (identifier) @name) @reference.call
  (#not-match? @name "^(require)$")
)

(new_expression
  constructor: (_) @name) @reference.class

(import_statement
  source: (string
    (string_fragment) @name)) @reference.module

(import_clause
  (identifier) @name) @reference.import

(namespace_import
  (identifier) @name) @reference.import

(import_specifier
  name: (identifier) @name) @reference.import

(import_specifier
  alias: (identifier) @name) @reference.import

(export_statement
  source: (string
    (string_fragment) @name)) @reference.module

[
  (binary_expression left: (identifier) @name)
  (binary_expression right: (identifier) @name)
  (unary_expression (identifier) @name)
  (return_statement (identifier) @name)
  (array (identifier) @name)
  (arguments (identifier) @name)
  (variable_declarator value: (identifier) @name)
  (assignment_expression right: (identifier) @name)
  (pair value: (identifier) @name)
  (await_expression (identifier) @name)
  (yield_expression (identifier) @name)
  (subscript_expression object: (identifier) @name)
  (shorthand_property_identifier) @name
  (ternary_expression condition: (identifier) @name)
  (ternary_expression consequence: (identifier) @name)
  (ternary_expression alternative: (identifier) @name)
  (template_substitution (identifier) @name)
] @reference.variable

(export_statement value: (assignment_expression left: (identifier) @name right: ([
 (number)
 (string)
 (identifier)
 (undefined)
 (null)
 (new_expression)
 (binary_expression)
 (call_expression)
]))) @definition.constant
