# [PackageDev] target_format: plist, ext: hidden-tmLanguage
name: Find Refs
scopeName: text.find-refs
uuid: de594c8b-2688-48c1-bc73-b5c935e408b8

patterns:
  - include: '#filename'
  - include: '#header'
  - include: '#footer'
  - include: '#reference'
  - include: '#line-with-match'
  
repository:
  filename:
    match: ^([^ ].*:)$
    captures:
      '1': {name: entity.name.filename.find-refs}
  footer:
    name: text.find-refs
    match: '^[0-9]+ matches in [0-9+] files\s*$'
  header:
    name: text.find-refs
    match: ^References to .*$

  line-with-match:
    begin: '^ +([0-9]+):'
    end: $
    beginCaptures:
      '1': {name: constant.numeric.line-number.match.find-refs }
    patterns:
    - include: '#single-line-ts'
  single-line-ts:
    name: meta.ts.find-refs
    patterns:
    - include: '#expression'
  # The remainder of this file is a copy of the TypeScript
  # grammar, but with end patterns augmented so that they
  # always stay within a single line (since this grammar
  # is for single-line referenes into TypeScript files)
  var-expr:
    name: meta.var.expr.ts
    begin: (?<!\()\s*\b(var|let|const(?!\s+enum))\s+([a-zA-Z_$][\w$]*) 
    beginCaptures:
      '1': { name: storage.type.ts }
      '2': { name: variable.ts }
    end: '$|(?=[;=\}\{])|(?<=\})'
    patterns:
    - include: '#type-annotation'

  control-statement:
    name: keyword.control.ts
    match: \b(break|catch|continue|declare|do|else|finally|for|if|return|switch|throw|try|while)\b

  switch-case: 
    name: case.expr.ts
    begin: '\b(case|default)\b'
    beginCaptures:
      '1': { name: keyword.control.ts }
    end: ':'  
    patterns:
    - include: '#expression'

  declaration:
    name: meta.declaration.ts
    patterns:
     - include: '#function-declaration'
     - include: '#object-declaration'
     - include: '#type-declaration'
     - include: '#enum-declaration'

  type-declaration:
    name: meta.type.declaration.ts
    begin: \b(type)\b\s+([a-zA-Z_$][\w$]*)\s*=\s*
    beginCaptures:
      '1': { name: keyword.other.ts }
      '2': { name: storage.type.ts }
    end: $|(?=[,);>]|var|type|function|class|interface)
    patterns:
      - include: '#type'

  enum-declaration:
    name: meta.enum.declaration.ts
    match: (?:\b(const)\s+)?\b(enum)\s+([a-zA-Z_$][\w$]*)
    captures:
      '1': { name: storage.modifier.ts}
      '2': { name: storage.type.ts }
      '3': { name: entity.name.class.ts }

  object-declaration:
    name: meta.declaration.object.ts
    begin: '\b(?:(export)\s+)?\b(class|interface)\b(?:\s+([a-zA-Z_$][\w$]*))'
    beginCaptures:
      '1': { name: storage.modifier.ts }
      '2': { name: storage.type.ts }
      '3': { name: entity.name.class.ts }
    end: $|(?=\})
    endCaptures:
      '1': { name: brace.curly.ts }
    patterns:
    - include: '#type-parameters'
    - include: '#object-heritage'
    - include: '#object-body'
    - include: '#comment'

  object-heritage:
    name: meta.object.heritage.ts
    match: (?:\b(extends|implements)\b|,)(?:\s+([a-zA-Z_$][.\w$]*))
    captures:
       '1': { name: storage.modifier.ts }
       '2': { name: storage.type.ts } 

  object-body:
    name: meta.object.body.ts
    begin: \{
    end: $|(?=\})
    patterns:
    - include: '#comment'
    - include: '#field-declaration'
    - include: '#method-declaration'
    - include: '#indexer-declaration'
    - include: '#type-annotation'
    - include: '#variable-initializer'
    - include: '#access-modifier'
    - include: '#static-modifier'
    - include: '#property-accessor'

  object-type:
    name: meta.object.type.ts
    begin: \{
    end: $|\}
    patterns:
    - include: '#comment'
    - include: '#field-declaration'
    - include: '#method-declaration-no-body'
    - include: '#indexer-declaration'
    - include: '#type-annotation'

  field-declaration:
    name: meta.field.declaration.ts
    match: '\b([a-zA-Z_$][\w$]*)\s*(\?\s*)?(?=(=|:))'
    captures:
      '1': { name: variable.ts }
      '2': { name: keyword.operator.ts }

  method-declaration:
    name: meta.method.declaration.ts
    begin: '\b(?:(get|set)\s+)?\[?([a-zA-Z_$][\.\w$]*)\s*\]?\s*(\??)\s*(?=\()'
    beginCaptures:
      '1': { name: storage.type.property.ts }
      '2': { name: entity.name.function.ts }
      '3': { name: keyword.operator.ts }
    end: '$|\}|[;,]'
    patterns:
    - include: '#comment'
    - include: '#function-parameters'
    - include: '#type-annotation'
    - include: '#decl-block'

  method-declaration-no-body:
    name: meta.method.declaration.ts
    begin: '\b(?:(get|set)\s+)?\[?([a-zA-Z_$][\.\w$]*)\s*\]?\s*(\??)\s*(?=\()'
    beginCaptures:
      '1': { name: storage.type.property.ts }
      '2': { name: entity.name.function.ts }
      '3': { name: keyword.operator.ts }
    end: '$|(?=\})|[;,]'
    patterns:
    - include: '#comment'
    - include: '#function-parameters'
    - include: '#type-annotation'
    - include: '#decl-block'

  indexer-declaration:
    name: meta.indexer.declaration.ts
    begin: \[
    end: \]\s*(\?\s*)?|$
    endCaptures:
      '1': { name: keyword.operator.ts }
    patterns:
    - include: '#type-annotation'
    - include: '#indexer-parameter'
    - include: '#expression'

  indexer-parameter:
    name: meta.indexer.parameter.ts
    match: ([a-zA-Z_$][\w$]*)(?=\:)
    captures:
      '1': { name: variable.parameter.ts}
      
  function-declaration:
    name: meta.function.ts
    begin: \b(function)\b(?:\s+([a-zA-Z_$][\w$]*))?\s*
    beginCaptures:
      '1': { name: storage.type.function.ts }
      '2': { name: entity.name.function.ts }
    end: $|(?=\}|;)
    patterns:
    - include: '#comment'
    - include: '#type-parameters'
    - include: '#function-parameters'
    - include: '#return-type'
    - include: '#decl-block'

  block:
    name: meta.block.ts
    begin: \{
    end: $|\}
    patterns:
    - include: '#expression'
    - include: '#object-member'

  decl-block:
    name: meta.decl.block.ts
    begin: \{
    end: $|(?=\})
    patterns:
    - include: '#expression'

  function-parameters:
    name: meta.function-parameters.ts
    begin: \(
    end: $|\)
    patterns:
      - include: '#comment'
      - include: '#parameter-name'
      - include: '#type-annotation'
      - include: '#variable-initializer'

  function-type-parameters:
    name: meta.function.type.ts
    begin: \(
    end: $|\)
    patterns:
    - include: '#comment'
    - include: '#parameter-name'
    - include: '#type-annotation'
    - include: '#variable-initializer'

  parameter-name:
    name: parameter.name.ts
    match: '(?:\s*\b(public|private)\b\s+)?(\.\.\.)?\s*([a-zA-Z_$][\w$]*)\s*(\??)'
    captures:
      '1': { name: storage.modifier.ts }
      '2': { name: keyword.operator.ts }
      '3': { name: variable.parameter.ts }
      '4': { name: keyword.operator.ts }

  return-type:
    name: meta.return.type.ts
    begin: '(?<=\)):'
    end: $|(?=\{|;|//)
    patterns:
    - include: '#type'

  type-annotation:
    name: meta.type.annotation.ts
    begin: ":"
    end: (?=[,);}\[\]])|(?==[^>])|(?<=[a-z]|>)\s*(?=\{|$|//)
    patterns:
      - include: '#type'
      - include: '#comment'

  type:
    name: meta.type.ts
    patterns:
    - include: '#type-name'
    - include: '#type-parameters'
    - include: '#type-union'
    - include: '#object-type'
    - include: '#function-type-parameters'
    - include: '#function-type-return-type'

  function-type-return-type:
    name: meta.function.type.return.ts
    begin: '=>'
    end: $|(?=[,\){]|//)
    patterns:
    - include: '#type'

  type-union:
    name: meta.type.union.ts
    begin: '(\|)'
    beginCaptures:
      '1': { name: keyword.operator.ts }
    end: '$|([a-zA-Z_$][.\w$]*)'
    endCaptures:
      '1': { name: storage.type.ts }
    patterns:
    - include: '#comment'

  type-name:
    name: storage.type.ts
    match: '[a-zA-Z_$][.\w$]*'

  type-parameters:
    name: meta.type.parameters.ts
    begin: '<'
    end: '$|(?=var|type|function|class|interface)|>'  
    patterns:
    - name: keyword.other.ts
      match: '\b(extends)\b'
    - include: '#comment'
    - include: '#type'

  variable-initializer:
    begin: (=)
    beginCaptures:
      '1': { name: keyword.operator.ts }
    end: $|(?=[,);=])
    patterns:
      - include: '#expression'  

  expression:
    name: meta.expression.ts
    patterns:
    - include: '#string'
    - include: '#regex'
    - include: '#template'
    - include: '#comment'
    - include: '#literal'
    - include: '#paren-expression'
    - include: '#var-expr'
    - include: '#declaration'
    - include: '#cast'
    - include: '#new-expr'
    - include: '#block'
    - include: '#expression-operator'
    - include: '#relational-operator'
    - include: '#arithmetic-operator'
    - include: '#logic-operator'
    - include: '#assignment-operator'
    - include: '#storage-keyword'
    - include: '#control-statement'
    - include: '#switch-case'
    - include: '#for-in-simple'

  for-in-simple:
    name: forin.expr.ts
    match: (?<=\()\s*\b(var|let)\s+([a-zA-Z_$][\w$]*)\s+(in)\b
    captures:
      '1': { name: storage.type.ts }
      '3': { name: keyword.operator.ts }

  cast:
    name: cast.expr.ts
    match: '<\s*([a-zA-Z_$][.\w$]*)\s*(?:<([a-zA-Z_$][.\w$]*)>)?\s*(\[\])*\s*>'
    captures:
       '1': { name: storage.type.ts }
       '2': { name: storage.type.ts }
  
  new-expr:
    name: new.expr.ts
    match: '\b(new)\b\s*([a-zA-Z_$][.\w$]*)'
    captures:
       '1': { name: keyword.operator.ts }
       '2': { name: storage.type.ts }
     
  # TODO: object members with quoted or numric lhs
  object-member:
    name: meta.object.member.ts
    begin: '[a-zA-Z_$][\w$]*\s*:'
    end: $|(?=,|\})
    patterns:
    - include: '#expression'

  expression-operator:
    name: keyword.operator.ts
    match: =>|\b(delete|export|import|in|instanceof|module|new|typeof|void)\b

  arithmetic-operator:
    name: keyword.operator.ts
    match: \*|/|\-\-|\-|\+\+|\+|%

  relational-operator:
    name: keyword.operator.ts
    match: ===|==|=|!=|!==|<=|>=|<>|<|>

  assignment-operator:
    name: keyword.operator.ts
    match: <<=|>>=|>>>=|\*=|(?<!\()/=|%=|\+=|\-=|&=|\^=

  logic-operator:
    name: keyword.operator.ts
    match: \!|&|~|\||&&|\|\|

  storage-keyword:
    name: storage.type.ts
    match: \b(number|boolean|string)\b

  paren-expression:
    begin: \(
    beginCaptures:
      '0': {name: brace.paren.ts }
    end: $|\)
    endCaptures:
      '0': {name: brace.paren.ts }
    patterns:
    - include: '#expression'

  qstring-double:
    name: string.double.ts
    begin: '"'
    end: '"|(?=$)'
    patterns:
    - include: '#string-character-escape'

  qstring-single:
    name: string.single.ts
    begin: "'"
    end: "'|(?=$)"
    patterns:
    - include: '#string-character-escape'

  regex:
    name: string.regex.ts
    begin: (?<=[=(:,\[]|^|return|&&|\|\||!)\s*(/)(?![/*+{}?])
    end: $|(/)[igm]*
    patterns:
    - name: constant.character.escape.ts
      match: \\.
    - name: constant.character.class.ts
      match: \[(\\\]|[^\]])*\]

  string:
    name: string.ts
    patterns:
    - include: '#qstring-single'
    - include: '#qstring-double'

  template:
    name: meta.template.ts
    begin: '`'
    beginCaptures:
      '0': { name: string.template.ts}
    end: '$|`'
    endCaptures:
      '0': { name: string.template.ts}
    patterns:
     - include: '#template-substitution-element'
     - include: '#template-string-contents'

  template-string-contents:
    name: string.template.ts
    begin: '.*?'
    end: $|(?=(\$\{|`))
    patterns:
    - include: '#string-character-escape'

  string-character-escape:
    name: constant.character.escape
    match: \\(x\h{2}|[0-2][0-7]{,2}|3[0-6][0-7]?|37[0-7]?|[4-7][0-7]?|.|$)

  template-substitution-element:
    name: template.element.ts
    begin: \$\{
    beginCaptures:
      '0': {name: keyword.operator.ts}
    end: $|\}
    endCaptures:
      '0': {name: keyword.operator.ts}
    patterns:
      - include: '#expression'

  comment:
    name: comment.ts
    patterns:
    - include: '#comment-block-doc'
    - include: '#comment-block'
    - include: '#comment-line'

  comment-block-doc:
    name: comment.block.documentation.ts
    begin: /\*\*(?!/)
    end: $|\*/

  comment-block:
    name: comment.block.ts
    begin: /\*
    end: $|\*/

  comment-line:
    name: comment.line.ts
    match: (//).*$\n?

  literal:
    name: literal.ts
    patterns:
    - include: '#numeric-literal'
    - include: '#boolean-literal'
    - include: '#null-literal'
    - include: '#undefined-literal'
    - include: '#array-literal'

  array-literal:
    name: meta.array.literal.ts
    begin: \[
    beginCaptures:
      '0': { name: brace.square.ts }
    end: $|\]
    endCaptures:
      '0': { name: brace.square.ts }
    patterns:
    - include: '#expression'

  numeric-literal:
    name: constant.numeric.ts 
    match: \b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?))\b

  boolean-literal:
    name: constant.language.boolean.ts
    match: \b(false|true)\b

  null-literal:
    name: constant.language.null.ts
    match: \b(null)\b

  undefined-literal:
    name: constant.language.ts
    match: \b(undefined)\b

  access-modifier:
    name: storage.modifier.ts
    match: \b(public|protected|private)\b
    
  static-modifier:
    name: keyword.other.ts
    match: \b(static)\b

  property-accessor:
    name: storage.type.property.ts
    match: \b(get|set)\b



    
  
