%YAML 1.2 --- # Derived from JavaScript Next: https://github.com/Benvie/JavaScriptNext.tmLanguage name: JavaScript scope: source.js version: 2 file_extensions: - js - mjs - cjs - htc first_line_match: |- (?xi: ^ \#! .* \b(?:node|js|bun|osascript\s+-l\s+JavaScript)\b # shebang | ^ \s* // .*? -\*- .*? \b(?:js|javascript)\b .*? -\*- # editorconfig ) variables: shebang_lang: \b(?:node|js|bun|osascript\s+-l\s+JavaScript)\b bin_digit: '[01_]' oct_digit: '[0-7_]' dec_digit: '[0-9_]' hex_digit: '[\h_]' dec_integer: (?:0|[1-9]{{dec_digit}}*) dec_exponent: '[Ee](?:[-+]|(?![-+])){{dec_digit}}*' identifier_escape: (?:\\u(?:\h{4}|\{\h+\})) identifier_start: (?:[_$\p{L}\p{Nl}]|{{identifier_escape}}) identifier_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{identifier_escape}}) identifier_break: (?!{{identifier_part}}) identifier_name: (?:{{identifier_start}}{{identifier_part}}*{{identifier_break}}) constant_identifier: (?:[[:upper:]]{{identifier_part}}*{{identifier_break}}) dollar_only_identifier: (?:\${{identifier_break}}) dollar_identifier: '(?:(\$){{identifier_part}}*{{identifier_break}})' block_comment_contents: (?:(?:[^*]|\*(?!/))*) block_comment: (?:/\*{{block_comment_contents}}\*/) nothing: (?:(?:\s|{{block_comment}})*) line_ending_ahead: (?={{nothing}}(?:/\*{{block_comment_contents}}|//.*)?$) # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar reserved_word: |- (?x: break|case|catch|class|const|continue|debugger|default|delete|do|else| export|extends|finally|for|function|if|import|in|instanceof|new|return| super|switch|this|throw|try|typeof|var|void|while|with|yield| enum| null|true|false ){{identifier_break}} non_reserved_identifier: (?:(?!{{reserved_word}}){{identifier_name}}) possible_arrow_function_begin: (?:\(|{{identifier_start}}) either_func_lookahead: (?:{{func_lookahead}}|{{arrow_func_lookahead}}) binding_pattern_lookahead: (?:{{identifier_name}}|\[|\{) left_expression_end_lookahead: (?!\s*[.\[\(]) dot_accessor: (?:\??\.) property_name: >- (?x: {{identifier_name}} | [0-9]+ | '(?:[^\\']|\\.)*' | "(?:[^\\"]|\\.)*" | \[ .* \] ) class_element_name: |- (?x: {{property_name}} | \#{{identifier_name}} ) modifier: (?:(?:static|accessor){{identifier_break}}) # Newline not permitted between `async` and `function`. func_lookahead: |- (?x: (?:async{{identifier_break}}{{nothing}})? function{{identifier_break}} ) arrow_func_lookahead: |- (?x: (?:async\s*)? (?: {{identifier_name}} | \( ( [^()] | \( [^()]* \) )* \) ) \s* => ) function_call_after_lookahead: (?=\s*(?:\?\.\s*)?\() function_assignment_lookahead: |- (?x:(?= \s* = \s* {{either_func_lookahead}} )) # '@' followed by a pattern like \S but excluding literal '*' and '@'. jsdoc_block_tag: \@[^\n\t\f\v *@]+ contexts: main: - meta_include_prototype: false # don't match comments before shebang - match: '' push: [script, shebang] script: - match: '\)|\}|\]' scope: invalid.illegal.stray-bracket-end.js # Don't pop or embedding could break. - include: statements prototype: - include: comments comments: - include: line-comments - include: block-comments block-comments: # empty block comments - match: /\*\*+/ scope: comment.block.empty.js punctuation.definition.comment.js # documentation block comments - match: /\*\*+ scope: punctuation.definition.comment.begin.js push: - jsdoc-comment-body - jsdoc-block-tag # normal block comments - match: /\* scope: punctuation.definition.comment.begin.js push: block-comment-body block-comment-end: - match: \*+/ scope: punctuation.definition.comment.end.js pop: 1 block-comment-body: - meta_include_prototype: false - meta_scope: comment.block.js - include: block-comment-end - match: ^\s*(\*)(?!/) captures: 1: punctuation.definition.comment.js jsdoc-comment-body: - meta_include_prototype: false - meta_scope: comment.block.documentation.js - include: block-comment-end # JSDoc "block" tags (i.e. @param) are only accepted at the beginning of the documentation # line so directly after the '/**' or after the '*' marker on the next lines. - match: ^\s*(\*)(?!/) captures: 1: punctuation.definition.comment.js push: jsdoc-block-tag jsdoc-block-tag: - match: '{{jsdoc_block_tag}}' scope: entity.other.attribute-name.documentation.js pop: 1 - match: (?=\S)|$ pop: 1 line-comments: - match: /{4,} scope: punctuation.definition.comment.js push: line-comment-other-body - match: /{3} scope: punctuation.definition.comment.js push: line-comment-triple-slash-body - match: /{2} scope: punctuation.definition.comment.js push: line-comment-double-slash-body line-comment-end: - match: (//+)?\n captures: 1: punctuation.definition.comment.js pop: 1 line-comment-double-slash-body: - meta_include_prototype: false - meta_scope: comment.line.double-slash.js - include: line-comment-end line-comment-triple-slash-body: - meta_include_prototype: false - meta_scope: comment.line.triple-slash.js - include: line-comment-end line-comment-other-body: - meta_include_prototype: false - meta_scope: comment.line.other.js - include: line-comment-end shebang: - meta_include_prototype: false - match: ^\#! scope: punctuation.definition.comment.js set: shebang-body - match: ^|(?=\S) # Note: Ensure to highlight shebang if the syntax is embedded. pop: 1 shebang-body: - meta_include_prototype: false - meta_scope: comment.line.shebang.js # Note: Keep sync with first_line_match! - match: '{{shebang_lang}}' scope: constant.language.shebang.js - match: \n pop: 1 else-pop: - match: (?=\S) pop: 1 else-pop-2: - match: (?=\S) pop: 2 immediately-pop: - meta_include_prototype: false - match: '' pop: 1 immediately-pop-2: - meta_include_prototype: false - match: '' pop: 2 comma-separator: - match: ',' scope: punctuation.separator.comma.js import-statement-or-import-meta: - match: (?=import{{identifier_break}}) branch_point: import-statement branch: - import-statement - expression-statement import-statement: - match: import{{identifier_break}} scope: keyword.control.import-export.js set: - import-meta - expect-semicolon - import-export-assert - import-string-or-items - import-check-branch import-check-branch: - match: (?=[.(]) # Recovery for import expressions fail: import-statement - include: else-pop import-meta: - meta_include_prototype: false - meta_scope: meta.import.js - include: immediately-pop import-export-alias: - match: as{{identifier_break}} scope: keyword.control.import-export.js set: import-export-name - include: else-pop import-export-name: - match: default{{identifier_break}} scope: keyword.control.import-export.js pop: 1 - match: '{{identifier_name}}' scope: variable.other.readwrite.js pop: 1 - include: literal-string - include: else-pop import-export-from: - match: 'from{{identifier_break}}' scope: keyword.control.import-export.js set: import-export-from-name - include: else-pop import-export-from-name: - include: literal-string - include: else-pop import-string-or-items: - include: literal-string - match: (?=\S) set: - import-export-from - import-list - import-export-item import-list: - match: ',' scope: punctuation.separator.comma.js push: import-export-item - include: else-pop import-export-item: - match: '\{' scope: punctuation.section.block.begin.js set: import-export-brace - match: '{{non_reserved_identifier}}' scope: variable.other.readwrite.js pop: 1 - match: '\*' scope: constant.other.wildcard.asterisk.js set: import-export-alias - include: else-pop import-export-brace: - meta_scope: meta.block.js - include: comma-separator - match: '\}' scope: punctuation.section.block.end.js pop: 1 - match: (?={{identifier_start}}|'|") push: - import-export-alias - import-export-name - match: '\*' scope: constant.other.wildcard.asterisk.js push: import-export-alias - include: else-pop import-export-assert: - match: (?:assert|with){{identifier_break}} scope: keyword.control.import-export.js set: import-export-object - include: else-pop import-export-object: - include: object-literal - include: else-pop export-statement: - match: export{{identifier_break}} scope: keyword.control.import-export.js set: - export-meta - export-body export-meta: - meta_include_prototype: false - meta_scope: meta.export.js - include: immediately-pop export-body: - include: declaration - match: default{{identifier_break}} scope: keyword.control.import-export.js set: export-default - match: (?=\S) set: - expect-semicolon - import-export-assert - import-export-from - import-export-item export-default: - include: declaration - include: expression-statement statements: - match: '\)|\}|\]' scope: invalid.illegal.stray-bracket-end.js pop: 1 - match: (?=\S) push: statement statement: - match: \; scope: punctuation.terminator.statement.empty.js pop: 1 - include: declaration - include: import-statement-or-import-meta - include: export-statement - include: conditional - include: block - include: label - match: break{{identifier_break}} scope: keyword.control.flow.break.js set: - expect-semicolon - expect-label - match: continue{{identifier_break}} scope: keyword.control.flow.continue.js set: - expect-semicolon - expect-label - match: debugger{{identifier_break}} scope: keyword.control.flow.debugger.js set: expect-semicolon - match: return{{identifier_break}} scope: keyword.control.flow.return.js set: restricted-production - match: throw{{identifier_break}} scope: keyword.control.flow.throw.js set: restricted-production - include: decorator - include: expression-statement declaration: - include: variable-declaration - include: using-declaration - include: class - include: regular-function expect-semicolon: - match: \; scope: punctuation.terminator.statement.js pop: 1 - include: else-pop expect-label: - meta_include_prototype: false - match: '(?={{nothing}}{{identifier_name}})' set: - match: '{{non_reserved_identifier}}' scope: variable.label.js pop: 1 - match: '{{identifier_name}}' scope: invalid.illegal.identifier.js variable.label.js pop: 1 - include: else-pop - include: immediately-pop block: - match: '\{' scope: punctuation.section.block.begin.js set: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.end.js pop: 1 - include: statements variable-binding-pattern: - include: variable-binding-name - include: variable-binding-array-destructuring - include: variable-binding-object-destructuring - include: else-pop variable-binding-name: - match: (?={{non_reserved_identifier}}) set: - - meta_scope: meta.binding.name.js - include: immediately-pop - literal-variable variable-binding-array-destructuring: - match: '\[' scope: punctuation.section.sequence.begin.js set: - meta_scope: meta.binding.destructuring.sequence.js - match: '\]' scope: punctuation.section.sequence.end.js pop: 1 - include: variable-binding-spread - include: variable-binding-list variable-binding-object-destructuring: - match: '\{' scope: punctuation.section.mapping.begin.js set: - meta_scope: meta.binding.destructuring.mapping.js - match: '\}' scope: punctuation.section.mapping.end.js pop: 1 - include: variable-binding-spread - match: (?={{identifier_start}}|\[|'|") push: - initializer - variable-binding-object-alias - object-literal-meta-key - variable-binding-object-key - include: comma-separator variable-binding-object-alias: - match: ':' scope: punctuation.separator.key-value.js set: variable-binding-pattern - include: else-pop variable-binding-object-key: - match: '{{identifier_name}}(?=\s*:)' pop: 1 - include: literal-string - include: computed-property-name - include: variable-binding-name - include: else-pop variable-binding-spread: - match: '\.\.\.' scope: keyword.operator.spread.js push: variable-binding-pattern variable-binding-list: - include: comma-separator - match: (?={{binding_pattern_lookahead}}) push: - initializer - variable-binding-pattern - include: else-pop variable-binding-top: - match: (?={{binding_pattern_lookahead}}) set: - initializer - variable-binding-pattern - include: else-pop variable-binding-list-top: - match: ',' scope: punctuation.separator.comma.js push: variable-binding-top - include: else-pop variable-declaration: - match: (?:const|let|var){{identifier_break}} scope: keyword.declaration.js set: - expect-semicolon - variable-binding-list-top - variable-binding-top using-declaration: - include: plain-using-declaration - match: (?=await{{identifier_break}}) branch_point: await-using-declaration branch: - await-using-declaration - expression-statement pop: 1 plain-using-declaration: - match: using{{identifier_break}}(?={{nothing}}{{non_reserved_identifier}}) scope: keyword.declaration.js set: - expect-semicolon - variable-binding-list-top - variable-binding-top await-using-declaration: - match: await{{identifier_break}} scope: keyword.declaration.js set: - include: using-declaration - match: (?=\S) fail: await-using-declaration function-parameter-binding-pattern: - include: function-parameter-binding-name - include: function-parameter-binding-array-destructuring - include: function-parameter-binding-object-destructuring - include: else-pop function-parameter-binding-name: - match: '{{dollar_identifier}}' scope: meta.binding.name.js variable.parameter.function.js captures: 1: punctuation.dollar.js - match: '{{non_reserved_identifier}}' scope: meta.binding.name.js variable.parameter.function.js - match: '{{identifier_name}}' scope: invalid.illegal.identifier.js meta.binding.name.js variable.parameter.function.js function-parameter-binding-array-destructuring: - match: '\[' scope: punctuation.section.sequence.begin.js set: - meta_scope: meta.binding.destructuring.sequence.js - match: '\]' scope: punctuation.section.sequence.end.js pop: 1 - include: function-parameter-binding-list function-parameter-binding-object-destructuring: - match: '\{' scope: punctuation.section.mapping.begin.js set: - meta_scope: meta.binding.destructuring.mapping.js - match: ',' scope: punctuation.separator.parameter.function.js - match: '\}' scope: punctuation.section.mapping.end.js pop: 1 - include: function-parameter-binding-spread - match: (?={{identifier_start}}|\[|'|") push: - initializer - function-parameter-binding-object-alias - object-literal-meta-key - function-parameter-binding-object-key function-parameter-binding-object-alias: - match: ':' scope: punctuation.separator.key-value.js set: function-parameter-binding-pattern - include: else-pop function-parameter-binding-object-key: - match: '{{identifier_name}}(?=\s*:)' pop: 1 - include: literal-string - include: computed-property-name - include: function-parameter-binding-name - include: else-pop function-parameter-binding-spread: - match: '\.\.\.' scope: keyword.operator.spread.js push: function-parameter function-parameter-binding-list: - match: ',' scope: punctuation.separator.parameter.function.js - include: function-parameter-binding-spread - match: (?={{binding_pattern_lookahead}}) push: function-parameter - include: else-pop function-parameter: - match: '' set: - initializer - function-parameter-binding-pattern initializer: - match: '=' scope: keyword.operator.assignment.js set: expression-no-comma - include: else-pop expression-statement: - match: (?=\S) set: - expect-semicolon - expression-statement-end - expression-begin expression-statement-end: - match: '{{line_ending_ahead}}' branch_point: expression-statement-continuation branch: - expression-statement-continuation - expression-statement-pop - include: expression-end expression-statement-continuation: - match: (?=\+\+|--) fail: expression-statement-continuation - match: |- (?x) (?= != | [-+*/%><=&|^\[(;,.:?] | (?:in|instanceof){{identifier_break}} ) pop: 1 - match: (?=\S) fail: expression-statement-continuation expression-statement-pop: # Consume only comments (ignore patterns from inheriting syntaxes) and # pop `expression-statement-end` at the same text point the previous branch # fails at in order to prevent ST's syntax engine to lock up. # see: https://github.com/sublimehq/sublime_text/issues/5853 - meta_include_prototype: false - include: comments - include: else-pop-2 restricted-production: - meta_include_prototype: false - match: '{{line_ending_ahead}}' pop: 1 - match: '' set: expression-statement expect-case-colon: - match: ':' scope: punctuation.separator.js pop: 1 - include: else-pop conditional: - match: switch{{identifier_break}} scope: keyword.control.conditional.switch.js set: - switch-meta - switch-block - expect-parenthesized-expression - match: do{{identifier_break}} scope: keyword.control.loop.do-while.js set: - do-while-meta - do-while-condition - statement - match: for{{identifier_break}} scope: keyword.control.loop.for.js set: - for-meta - block-scope - for-condition - for-await - match: while{{identifier_break}} scope: keyword.control.loop.while.js set: - while-meta - block-scope - expect-parenthesized-expression - match: with{{identifier_break}} scope: keyword.control.import.with.js set: - with-meta - block-scope - expect-parenthesized-expression - match: if{{identifier_break}} scope: keyword.control.conditional.if.js set: - conditional-meta - statement - expect-parenthesized-expression - match: else\s+if{{identifier_break}} scope: keyword.control.conditional.elseif.js set: - conditional-meta - statement - expect-parenthesized-expression - match: else{{identifier_break}} scope: keyword.control.conditional.else.js set: - conditional-meta - statement - match: try{{identifier_break}} scope: keyword.control.exception.try.js set: - try-meta - block-scope - match: finally{{identifier_break}} scope: keyword.control.exception.finally.js set: - finally-meta - block-scope - match: catch{{identifier_break}} scope: keyword.control.exception.catch.js set: - catch-meta - block-scope - catch-binding expect-parenthesized-expression: - include: parenthesized-expression - include: else-pop switch-meta: - meta_include_prototype: false - meta_scope: meta.switch.js - include: immediately-pop do-while-meta: - meta_include_prototype: false - meta_scope: meta.do-while.js - include: immediately-pop for-meta: - meta_include_prototype: false - meta_scope: meta.for.js - include: immediately-pop while-meta: - meta_include_prototype: false - meta_scope: meta.while.js - include: immediately-pop with-meta: - meta_include_prototype: false - meta_scope: meta.with.js - include: immediately-pop conditional-meta: - meta_include_prototype: false - meta_scope: meta.conditional.js - include: immediately-pop try-meta: - meta_include_prototype: false - meta_scope: meta.try.js - include: immediately-pop finally-meta: - meta_include_prototype: false - meta_scope: meta.finally.js - include: immediately-pop catch-meta: - meta_include_prototype: false - meta_scope: meta.catch.js - include: immediately-pop for-await: - match: await{{identifier_break}} scope: keyword.control.flow.await.js pop: 1 - include: else-pop for-condition: - match: '\(' scope: punctuation.section.group.begin.js set: - for-condition-end - for-condition-contents - include: else-pop for-condition-end: - meta_scope: meta.group.js - match: '\)' scope: punctuation.section.group.end.js pop: 1 for-condition-contents: - match: '' branch_point: for-in-of branch: - for-in-of - for-oldstyle pop: 1 for-in-of: - match: '' set: - expression - for-in-of-word - for-in-of-declaration for-in-of-declaration: - match: (?:const|let|var){{identifier_break}} scope: keyword.declaration.js set: for-in-of-binding - match: |- (?x: (?! # [lookahead ≠ using of] using{{identifier_break}}{{nothing}} of{{identifier_break}} ) (?= # await [no LineTerminator here] using [no LineTerminator here] ForBinding (?:await{{identifier_break}}{{nothing}})? using{{identifier_break}}{{nothing}} {{non_reserved_identifier}} ) ) scope: keyword.declaration.js set: - match: await{{identifier_break}} scope: keyword.declaration.js - match: using{{identifier_break}} scope: keyword.declaration.js set: for-in-of-binding - match: (?=\S) set: - left-expression-end - expression-begin for-in-of-binding: - include: variable-binding-name - include: variable-binding-array-destructuring - include: variable-binding-object-destructuring - match: (?=\S) fail: for-in-of for-in-of-word: - match: (?:of|in){{identifier_break}} scope: keyword.operator.word.js pop: 1 - match: (?=\S) fail: for-in-of for-oldstyle: - match: '' set: - for-oldstyle-rest - for-oldstyle-first for-oldstyle-first: - match: (?:const|let|var){{identifier_break}} scope: keyword.declaration.js set: - variable-binding-list-top - variable-binding-top - match: (?=\S) set: expression for-oldstyle-rest: - match: (?=\)) pop: 1 - match: ; scope: punctuation.separator.expression.js - match: (?=\S) push: expression block-scope: - include: block - include: else-pop block-meta: - meta_include_prototype: false - meta_scope: meta.block.js - include: immediately-pop switch-block: - match: '\{' scope: punctuation.section.block.begin.js set: switch-block-contents - include: else-pop switch-block-contents: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.end.js pop: 1 - match: case{{identifier_break}} scope: keyword.control.conditional.case.js push: - expect-case-colon - expression - match: default{{identifier_break}} scope: keyword.control.conditional.default.js push: - expect-case-colon - include: statements do-while-condition: - match: while{{identifier_break}} scope: keyword.control.loop.while.js set: parenthesized-expression - include: else-pop catch-binding: - match: \( scope: punctuation.section.group.begin.js set: - catch-binding-end - variable-binding-pattern - include: else-pop catch-binding-end: - meta_scope: meta.group.js - match: \) scope: punctuation.section.group.end.js pop: 1 decorator: - match: '@' scope: punctuation.definition.annotation.js push: - decorator-meta - decorator-expression-end - decorator-expression-begin decorator-meta: - meta_include_prototype: false - meta_scope: meta.annotation.js - include: immediately-pop decorator-name: - match: '{{identifier_name}}(?!\s*[.\(`])' scope: variable.annotation.js pop: 1 decorator-expression-end: - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: - include: decorator-name - include: object-property - match: (?=`) push: literal-string-template - match: (?={{function_call_after_lookahead}}) push: function-call-arguments - match: '{{line_ending_ahead}}' branch_point: decorator-expression-continuation branch: - decorator-expression-continuation - decorator-expression-pop - include: else-pop decorator-expression-continuation: - match: (?=[.`(]) pop: 1 - match: (?=\S) fail: decorator-expression-continuation decorator-expression-pop: # Consume only comments (ignore patterns from inheriting syntaxes) # and clear `meta.annotation` scope so it looks like the comment not being # part of the annotation anymore. # Pop `decorator-expression-end` at the same text point the previous branch # fails at in order to prevent ST's syntax engine to lock up. # see: https://github.com/sublimehq/sublime_text/issues/5853 - clear_scopes: 1 - meta_include_prototype: false - include: comments - include: else-pop-2 decorator-expression-begin: - include: decorator-name - include: parenthesized-expression - include: expression-begin expression-break: - match: (?=[;})\]]) pop: 1 expression: - meta_include_prototype: false - match: '' set: [ expression-end, expression-begin ] expression-no-comma: - meta_include_prototype: false - match: '' set: [ expression-end-no-comma, expression-begin ] expression-list: - include: expression-break - include: comma-separator - match: (?=\S) push: expression-no-comma left-expression-end: - include: expression-break - match: (?=`) push: literal-string-template - match: '{{function_call_after_lookahead}}' push: function-call-arguments - include: property-access - include: else-pop expression-end: - include: postfix-operators - include: binary-operators - include: ternary-operator - include: left-expression-end expression-end-no-comma: - match: (?=,) pop: 1 - include: expression-end expression-end-no-in: - match: (?=in{{identifier_break}}) pop: 1 - include: expression-end expression-begin: - include: expression-break - include: yield-expression - include: await-expression - include: regexp-complete - include: literal-string - include: literal-string-template - include: constructor - include: literal-number - include: prefix-operators - include: import-meta-expression - include: class - include: special-name - include: regular-function - match: (?={{reserved_word}}) pop: 1 - match: (?={{identifier_name}}{{function_assignment_lookahead}}) set: - function-name-meta - literal-variable - include: object-literal # Newline not allowed between `async` and parameters. - match: (?=async{{identifier_break}}{{nothing}}{{possible_arrow_function_begin}}) pop: 1 branch_point: async-arrow-function branch: - async-arrow-function - literal-variable - match: (?={{possible_arrow_function_begin}}) pop: 1 branch_point: arrow-function branch: - branch-possible-arrow-function - arrow-function-declaration - include: array-literal - include: literal-private-variable - include: else-pop async-arrow-function: - match: async{{identifier_break}} scope: keyword.declaration.async.js set: - function-meta - arrow-function-expect-body - arrow-function-expect-arrow-or-fail-async - arrow-function-expect-parameters arrow-function-expect-arrow-or-fail-async: - match: '=>' scope: keyword.declaration.function.arrow.js pop: 1 - match: (?=\S) fail: async-arrow-function branch-possible-arrow-function: - meta_include_prototype: false - match: (?=\() set: - detect-arrow - parenthesized-expression - match: (?={{identifier_start}}) set: - detect-arrow - literal-variable detect-arrow: - match: (?==>) fail: arrow-function - include: else-pop literal-string: - include: literal-double-quoted-string - include: literal-single-quoted-string literal-double-quoted-string: - match: \" scope: punctuation.definition.string.begin.js set: literal-double-quoted-string-content literal-double-quoted-string-content: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.double.js - match: \" scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content literal-single-quoted-string: - match: \' scope: punctuation.definition.string.begin.js set: literal-single-quoted-string-content literal-single-quoted-string-content: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.single.js - match: \' scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content literal-string-template: - match: \` scope: punctuation.definition.string.begin.js set: literal-string-template-content literal-string-template-content: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.other.js - match: \` scope: punctuation.definition.string.end.js pop: 1 - include: string-interpolations - include: string-content string-content: - match: \\\n scope: constant.character.escape.newline.js - match: \\(?:x\h\h|u\h\h\h\h|.) scope: constant.character.escape.js string-interpolations: - match: \$\{ scope: punctuation.section.interpolation.begin.js push: string-interpolation-content string-interpolation-content: - clear_scopes: 1 - meta_scope: meta.interpolation.js - meta_content_scope: source.js.embedded - match: \} scope: punctuation.section.interpolation.end.js pop: 1 - match: (?=\S) push: expression regexp-complete: - match: '/' scope: punctuation.definition.string.begin.js set: regexp regexp: - meta_include_prototype: false - meta_scope: meta.string.js string.regexp.js - match: "/" scope: punctuation.definition.string.end.js set: - meta_include_prototype: false - meta_content_scope: meta.string.js string.regexp.js - match: '[gimyus]' scope: keyword.other.js - match: '[A-Za-z0-9]' # Ignore unknown flags for future-compatibility - include: immediately-pop - match: '(?=.|\n)' push: - meta_include_prototype: false - match: '(?=/)' pop: 1 - include: scope:source.regexp.js constructor: - match: new{{identifier_break}} scope: keyword.operator.word.new.js set: - match: (?=\s*\.) set: new-target - match: (?=\s*\S) set: - constructor-meta - constructor-body-expect-arguments - constructor-body-expect-class-end - constructor-body-expect-class-begin constructor-meta: - meta_include_prototype: false - meta_scope: meta.function-call.constructor.js - include: immediately-pop constructor-body-expect-arguments: - include: function-call-arguments - include: else-pop constructor-body-expect-class-end: - include: property-access - include: else-pop constructor-body-expect-class-begin: - match: (?={{non_reserved_identifier}}\s*\() set: - include: support - match: '{{dollar_only_identifier}}' scope: variable.type.dollar.only.js punctuation.dollar.js pop: 1 - match: '{{dollar_identifier}}' scope: variable.type.dollar.js captures: 1: punctuation.dollar.js pop: 1 - match: '{{identifier_name}}' scope: variable.type.js pop: 1 - include: else-pop - include: expression-begin new-target: - match: \. scope: punctuation.accessor.dot.js set: - match: target{{identifier_break}} scope: variable.language.target.js pop: 1 - include: else-pop - include: else-pop prefix-operators: - match: '~' scope: keyword.operator.bitwise.js - match: '!(?!=)' scope: keyword.operator.logical.js - match: '--' scope: keyword.operator.arithmetic.js - match: '\+\+' scope: keyword.operator.arithmetic.js - match: \.\.\. scope: keyword.operator.spread.js - match: \+|\- scope: keyword.operator.arithmetic.js - match: (?:delete|typeof|void){{identifier_break}} scope: keyword.operator.js binary-operators: - match: instanceof{{identifier_break}} scope: keyword.operator.js push: expression-begin - match: in{{identifier_break}} scope: keyword.operator.js push: expression-begin - match: '=(?![=>])' scope: keyword.operator.assignment.js push: expression-begin - match: |- (?x) %= | # assignment right-to-left both &= | # assignment right-to-left both \*= | # assignment right-to-left both \+= | # assignment right-to-left both -= | # assignment right-to-left both /= | # assignment right-to-left both \^= | # assignment right-to-left both \|= | # assignment right-to-left both <<= | # assignment right-to-left both >>= | # assignment right-to-left both >>>= | # assignment right-to-left both &&= | \|\|= | \?\?= scope: keyword.operator.assignment.augmented.js push: expression-begin - match: '&&|\|\|' scope: keyword.operator.logical.js push: expression-begin - match: \?\? scope: keyword.operator.null-coalescing.js push: expression-begin - match: |- (?x) << | # bitwise-shift left-to-right both >>> | # bitwise-shift left-to-right both >> | # bitwise-shift left-to-right both & | # bitwise-and left-to-right both \^ | # bitwise-xor left-to-right both \| # bitwise-or left-to-right both scope: keyword.operator.bitwise.js push: expression-begin - match: |- (?x) <= | # comparison left-to-right both >= | # comparison left-to-right both < | # comparison left-to-right both > # comparison left-to-right both scope: keyword.operator.comparison.js push: expression-begin - match: |- (?x) === | # equality left-to-right both !== | # equality left-to-right both == | # equality left-to-right both != # equality left-to-right both scope: keyword.operator.comparison.js push: expression-begin - match: |- (?x) / | # division left-to-right both % | # modulus left-to-right both \* | # multiplication left-to-right both \+ | # addition left-to-right both - # subtraction left-to-right both scope: keyword.operator.arithmetic.js push: expression-begin - match: ',' scope: keyword.operator.comma.js # Comma operator, not punctuation. push: expression-begin ternary-operator: - match: '\?(?=[^.]|\.[0-9])' scope: keyword.operator.ternary.js set: - ternary-operator-expect-colon - expression-no-comma ternary-operator-expect-colon: - match: ':' scope: keyword.operator.ternary.js set: expression-no-comma - include: else-pop postfix-operators: - match: '--' scope: keyword.operator.arithmetic.js - match: '\+\+' scope: keyword.operator.arithmetic.js yield-expression: - match: yield{{identifier_break}} scope: keyword.control.flow.yield.js set: - match: $ pop: 1 - match: \* scope: keyword.generator.asterisk.js set: expression-begin - match: (?=\S) set: expression-begin await-expression: - match: await{{identifier_break}} scope: keyword.control.flow.await.js class: - match: class{{identifier_break}} scope: keyword.declaration.class.js set: - class-meta - class-body - class-extends - class-name class-meta: - meta_include_prototype: false - meta_scope: meta.class.js - include: immediately-pop class-body: - match: '\{' scope: punctuation.section.block.begin.js set: class-body-contents - include: else-pop class-body-contents: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.end.js pop: 1 - match: \; scope: punctuation.terminator.statement.empty.js - include: decorator - match: constructor{{identifier_break}} scope: entity.name.function.constructor.js push: - function-meta - function-declaration-expect-body - function-declaration-expect-parameters - match: (?=static{{identifier_break}}) branch_point: static-block branch: - static-block - class-element - match: (?=\S) push: class-element static-block: - match: static{{identifier_break}} scope: storage.modifier.js set: - include: block - match: (?=\S) fail: static-block class-extends: - match: extends{{identifier_break}} scope: storage.modifier.extends.js set: - inherited-class-expression-end - inherited-class-expression-begin - include: else-pop inherited-class-name: - match: '{{non_reserved_identifier}}{{left_expression_end_lookahead}}' scope: entity.other.inherited-class.js pop: 1 inherited-class-expression-end: - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: - include: inherited-class-name - include: object-property - include: left-expression-end inherited-class-expression-begin: - include: inherited-class-name - include: expression-begin class-name: - match: '{{non_reserved_identifier}}' scope: entity.name.class.js pop: 1 - include: else-pop class-element: - meta_include_prototype: false - match: (?=\*) set: method-declaration - match: '' pop: 1 branch_point: class-field branch: - class-field - method-declaration class-field: - meta_include_prototype: false - match: '' set: - expect-semicolon - initializer - class-field-check - field-name - class-element-modifiers class-field-check: - match: (?=\() fail: class-field - include: else-pop class-element-modifiers: - match: (?={{modifier}}) branch_point: class-element-modifier branch: - - match: '{{modifier}}' scope: storage.modifier.js set: - match: (?={{class_element_name}}|\*) pop: 1 - match: (?=\S) fail: class-element-modifier - immediately-pop-2 - include: else-pop special-name: - match: true{{identifier_break}} scope: constant.language.boolean.true.js pop: 1 - match: false{{identifier_break}} scope: constant.language.boolean.false.js pop: 1 - match: null{{identifier_break}} scope: constant.language.null.js pop: 1 - match: super{{identifier_break}} scope: variable.language.super.js pop: 1 - match: this{{identifier_break}} scope: variable.language.this.js pop: 1 function-name-meta: - meta_include_prototype: false - meta_scope: entity.name.function.js - include: immediately-pop regular-function: - match: (?={{func_lookahead}}) set: function-declaration function-declaration: - meta_include_prototype: false - match: '' set: - function-meta - function-declaration-expect-body - function-declaration-expect-parameters - function-declaration-expect-name - function-declaration-expect-generator-star - function-declaration-expect-function-keyword - function-declaration-expect-async function-declaration-expect-body: - include: function-block - include: else-pop function-meta: - meta_include_prototype: false - meta_scope: meta.function.js - include: immediately-pop function-declaration-expect-parameters: - include: function-declaration-parameters - include: else-pop function-declaration-expect-name: - match: '{{non_reserved_identifier}}' scope: entity.name.function.js pop: 1 - include: else-pop function-declaration-expect-generator-star: - match: \* scope: keyword.declaration.generator.js pop: 1 - include: else-pop function-declaration-expect-function-keyword: - match: function{{identifier_break}} scope: keyword.declaration.function.js pop: 1 - include: else-pop function-declaration-expect-async: - match: 'async{{identifier_break}}' scope: keyword.declaration.async.js pop: 1 - include: else-pop arrow-function-declaration: - meta_include_prototype: false - match: '' set: - function-meta - arrow-function-expect-body - arrow-function-expect-arrow - arrow-function-expect-parameters arrow-function-expect-body: - include: function-block - match: (?=\S) set: - block-meta - expression-no-comma arrow-function-expect-arrow: - match: '=>' scope: keyword.declaration.function.arrow.js pop: 1 - include: else-pop arrow-function-expect-parameters: - match: (?={{identifier_start}}) set: - clear_scopes: 1 - meta_scope: meta.function.parameters.js - match: '{{identifier_name}}' scope: variable.parameter.function.js pop: 1 - include: function-declaration-parameters - include: else-pop function-block: - match: '\{' scope: punctuation.section.block.begin.js set: - meta_scope: meta.block.js - match: '\}' scope: punctuation.section.block.end.js pop: 1 - include: statements function-declaration-parameters: - match: \( scope: punctuation.section.group.begin.js set: - clear_scopes: 1 - meta_scope: meta.function.parameters.js - match: \) scope: punctuation.section.group.end.js pop: 1 - include: function-parameter-binding-list label: - match: '({{identifier_name}})\s*(:)' captures: 1: entity.name.label.js 2: punctuation.separator.js object-literal: - match: '\{' scope: punctuation.section.mapping.begin.js set: object-literal-contents object-literal-contents: - meta_scope: meta.mapping.js - match: '\}' scope: punctuation.section.mapping.end.js pop: 1 - match: \.\.\. scope: keyword.operator.spread.js push: expression-no-comma - match: >- (?x)(?= {{property_name}}\s*:\s* {{either_func_lookahead}} ) push: - object-literal-meta-key - method-name - match: (?=\*) push: method-declaration - match: (?={{property_name}}) push: object-literal-element - include: comma-separator - match: ':' scope: punctuation.separator.key-value.js push: expression-no-comma # If there's any garbage, parse it as an expression # so that close braces won't break things. - match: (?=\S) push: expression-no-comma object-literal-element: - match: '{{identifier_name}}(?=\s*(?:[},]|$|//|/\*))' scope: variable.other.readwrite.js pop: 1 - match: (?=\S) pop: 1 branch_point: object-literal-property branch: - object-literal-property - method-declaration object-literal-property: - match: '' set: - object-literal-property-check - object-literal-meta-key - object-property-name object-property-name: - include: computed-property-name - include: literal-string - include: literal-number - match: (?:get|set|async){{identifier_break}} pop: 2 set: - match: (?=\*|{{class_element_name}}) fail: object-literal-property - include: else-pop - match: '{{identifier_name}}' pop: 1 - include: else-pop object-literal-property-check: - match: (?=\() fail: object-literal-property - include: else-pop computed-property-name: - match: \[ scope: punctuation.section.brackets.begin.js set: - meta_scope: meta.brackets.js - match: \] scope: punctuation.section.brackets.end.js pop: 1 - match: (?=\S) push: expression object-literal-meta-key: - meta_include_prototype: false - meta_scope: meta.mapping.key.js - include: else-pop method-name: - match: '{{dollar_identifier}}' scope: meta.mapping.key.dollar.js entity.name.function.js captures: 1: punctuation.dollar.js pop: 1 - match: '{{identifier_name}}' scope: entity.name.function.js pop: 1 - match: '(#){{identifier_name}}' scope: entity.name.function.js captures: 1: punctuation.definition.js pop: 1 - match: "'" scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.single.js - meta_content_scope: entity.name.function.js - match: \' scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content - match: '"' scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.double.js - meta_content_scope: entity.name.function.js - match: \" scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content - include: computed-property-name - include: else-pop field-name: - match: |- (?x)(?= \#? {{identifier_name}} {{nothing}} = {{nothing}} {{either_func_lookahead}} ) set: - function-name-meta - literal-variable-base - match: (?:get|set|async){{identifier_break}} scope: variable.other.readwrite.js set: - match: (?=\*|{{class_element_name}}) fail: class-field - include: else-pop - include: literal-variable-base - match: "'" scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.single.js - meta_content_scope: variable.other.readwrite.js - match: \' scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content - match: '"' scope: punctuation.definition.string.begin.js set: - meta_include_prototype: false - meta_scope: meta.string.js string.quoted.double.js - meta_content_scope: variable.other.readwrite.js - match: \" scope: punctuation.definition.string.end.js pop: 1 - match: \n scope: invalid.illegal.newline.js pop: 1 - include: string-content - include: computed-property-name - include: else-pop method-declaration: - meta_include_prototype: false - match: '' set: - function-meta - function-declaration-expect-body - function-declaration-expect-parameters - method-name - method-declaration-expect-asterisk - method-declaration-prefix - class-element-modifiers method-declaration-expect-asterisk: - match: \* scope: keyword.generator.asterisk.js - include: else-pop method-declaration-prefix: - match: (?=(?:get|set|async){{identifier_break}}) pop: 1 branch_point: method-declaration-prefix branch: - - match: (?:get|set){{identifier_break}} scope: storage.type.accessor.js set: method-declaration-prefix-check - match: (?:async){{identifier_break}} scope: keyword.declaration.async.js set: method-declaration-prefix-check - immediately-pop - include: else-pop method-declaration-prefix-check: - match: (?=\*|{{class_element_name}}) pop: 1 - match: (?=\S) fail: method-declaration-prefix parenthesized-expression: - match: \( scope: punctuation.section.group.begin.js set: - meta_scope: meta.group.js - match: \) scope: punctuation.section.group.end.js pop: 1 - match: (?=\S) push: expression function-call-arguments: - meta_content_scope: meta.function-call.js - match: '\?\.' scope: punctuation.accessor.js - match: \( scope: punctuation.section.group.begin.js set: - meta_scope: meta.function-call.arguments.js meta.group.js - match: \) scope: punctuation.section.group.end.js pop: 1 - include: expression-list array-literal: - match: '\[' scope: punctuation.section.sequence.begin.js set: - meta_scope: meta.sequence.js - match: '\]' scope: punctuation.section.sequence.end.js pop: 1 - include: expression-list property-access: - match: (\?\.)?(\[) captures: 1: punctuation.accessor.js 2: punctuation.section.brackets.begin.js push: - meta_scope: meta.brackets.js - match: '\]' scope: punctuation.section.brackets.end.js pop: 1 - match: (?=\S) push: expression - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: object-property literal-number: # floats - match: |- (?x: # 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1 | 1e1, 1e-1 {{dec_integer}} (?: (\.) {{dec_digit}}* (?:{{dec_exponent}})? | {{dec_exponent}} ) # .1, .1e1, .1e-1 | (\.) {{dec_digit}}+ (?:{{dec_exponent}})? ){{identifier_break}} scope: meta.number.float.decimal.js constant.numeric.value.js captures: 1: punctuation.separator.decimal.js 2: punctuation.separator.decimal.js pop: 1 # integers - match: (0)({{dec_digit}}+){{identifier_break}} scope: meta.number.integer.octal.js captures: 1: constant.numeric.base.js invalid.deprecated.numeric.octal.js 2: constant.numeric.value.js invalid.deprecated.numeric.octal.js pop: 1 - match: (0[Xx])({{hex_digit}}*)(n)?{{identifier_break}} scope: meta.number.integer.hexadecimal.js captures: 1: constant.numeric.base.js 2: constant.numeric.value.js 3: constant.numeric.suffix.js pop: 1 - match: (0[Oo])({{oct_digit}}*)(n)?{{identifier_break}} scope: meta.number.integer.octal.js captures: 1: constant.numeric.base.js 2: constant.numeric.value.js 3: constant.numeric.suffix.js pop: 1 - match: (0[Bb])({{bin_digit}}*)(n)?{{identifier_break}} scope: meta.number.integer.binary.js captures: 1: constant.numeric.base.js 2: constant.numeric.value.js 3: constant.numeric.suffix.js pop: 1 - match: ({{dec_integer}})(n|(?!\.)){{identifier_break}} scope: meta.number.integer.decimal.js captures: 1: constant.numeric.value.js 2: constant.numeric.suffix.js pop: 1 # illegal numbers - match: 0[Xx]{{identifier_part}}+ scope: invalid.illegal.numeric.hexadecimal.js pop: 1 - match: 0[Bb]{{identifier_part}}+ scope: invalid.illegal.numeric.binary.js pop: 1 - match: 0{{identifier_part}}+ scope: invalid.illegal.numeric.octal.js pop: 1 - match: '[1-9]{{identifier_part}}+(?:\.{{identifier_part}}*)?' scope: invalid.illegal.numeric.decimal.js pop: 1 literal-variable: - include: special-identifier - include: support - match: '(?={{identifier_name}}{{function_assignment_lookahead}})' set: - function-name-meta - literal-variable-base - match: '{{identifier_name}}(?={{nothing}}`)' scope: variable.function.tagged-template.js pop: 1 - match: '{{constant_identifier}}(?=\s*(?:{{dot_accessor}}|\[))' scope: support.class.js pop: 1 # If we don't capture the trailing space here, # it'll get eaten by the arrow function detection. - match: '({{dollar_only_identifier}}){{nothing}}{{function_call_after_lookahead}}' scope: meta.function-call.js captures: 1: variable.function.js variable.other.dollar.only.js punctuation.dollar.js pop: 1 - match: '({{identifier_name}}){{nothing}}{{function_call_after_lookahead}}' scope: meta.function-call.js captures: 1: variable.function.js pop: 1 - include: literal-variable-base literal-variable-base: - match: '{{dollar_only_identifier}}' scope: variable.other.dollar.only.js punctuation.dollar.js pop: 1 - match: '{{dollar_identifier}}' scope: variable.other.dollar.js captures: 1: punctuation.dollar.js pop: 1 - match: '{{constant_identifier}}' scope: variable.other.constant.js pop: 1 - match: '{{identifier_name}}' scope: variable.other.readwrite.js pop: 1 - include: literal-private-variable literal-private-variable: - match: (#)({{identifier_name}}) captures: 1: punctuation.definition.variable.js 2: variable.other.readwrite.js pop: 1 special-identifier: # These are ordinary identifiers, not reserved words - match: arguments{{identifier_break}} scope: variable.language.arguments.js pop: 1 - match: globalThis{{identifier_break}} scope: variable.language.global.js pop: 1 - match: undefined{{identifier_break}} scope: constant.language.undefined.js pop: 1 - match: NaN{{identifier_break}} scope: constant.language.nan.js pop: 1 - match: Infinity{{identifier_break}} scope: constant.language.infinity.js pop: 1 support: - include: support-variable-ecma - include: support-variable-console - include: support-variable-dom - include: support-variable-node support-variable-ecma: - match: Array{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-array - include: object-property - include: else-pop - include: else-pop - match: ArrayBuffer{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-arraybuffer - include: object-property - include: else-pop - include: else-pop - match: Atomics{{identifier_break}} scope: support.constant.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-atomics - include: object-property - include: else-pop - include: else-pop - match: BigInt{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-bigint - include: object-property - include: else-pop - include: else-pop - match: Date{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-date - include: object-property - include: else-pop - include: else-pop - match: JSON{{identifier_break}} scope: support.constant.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-json - include: object-property - include: else-pop - include: else-pop - match: Math{{identifier_break}} scope: support.constant.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-math - include: object-property - include: else-pop - include: else-pop - match: Number{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-number - include: object-property - include: else-pop - include: else-pop - match: Object{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-object - include: object-property - include: else-pop - include: else-pop - match: Promise{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-promise - include: object-property - include: else-pop - include: else-pop - match: Proxy{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-proxy - include: object-property - include: else-pop - include: else-pop - match: Reflect{{identifier_break}} scope: support.constant.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-reflect - include: object-property - include: else-pop - include: else-pop - match: String{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-string - include: object-property - include: else-pop - include: else-pop - match: Symbol{{identifier_break}} scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-symbol - include: object-property - include: else-pop - include: else-pop - match: |- (?x: (?: BigInt64| BigUint64| Float(?:32|64)| Int(?:8|16|32)| Uint(?:8|16|32|32Clamped) ) Array{{identifier_break}} ) scope: support.class.builtin.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-typedarray - include: object-property - include: else-pop - include: else-pop # Classes with no constructor properties - match: (?:Boolean|DataView|Function|Map|RegExp|Set|WeakMap|WeakSet){{identifier_break}} scope: support.class.builtin.js pop: 1 - match: (?:Eval|Range|Reference|Syntax|Type|URI)?Error{{identifier_break}} scope: support.class.builtin.js pop: 1 - match: (?:eval|isFinite|isNaN|parseFloat|parseInt|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent){{identifier_break}} scope: meta.function-call.js support.function.js pop: 1 support-property-ecma-array: - match: (?:from|isArray|of){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-arraybuffer: - match: isView{{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-atomics: - match: (?:and|add|compareExchange|exchange|isLockFree|load|or|store|sub|wait|wake|xor){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-bigint: - match: (?:asUintN|asIntN){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-date: - match: (?:now|parse|UTC){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-json: - match: (?:parse|stringify){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-math: - match: (?:E|LN10|LN2|LOG10E|LOG2E|PI|SQRT1_2|SQRT2){{identifier_break}} scope: support.constant.builtin.js pop: 1 - match: (?:abs|acos|acosh|asin|asin|atan|atanh|atan2|cbrt|ceil|clz32|cos|cosh|exp|expm1|floor|fround|hypot|imul|log|log1p|log10|log2|max|min|pow|random|round|sign|sin|sinh|sqrt|tan|tanh|trunc){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-number: - match: (?:EPSILON|MAX_SAFE_INTEGER|MAX_VALUE|MIN_SAFE_INTEGER|MIN_VALUE|NEGATIVE_INFINITY|POSITIVE_INFINITY){{identifier_break}} scope: support.constant.builtin.js pop: 1 - match: (?:isFinite|isInteger|isNaN|isSafeInteger|NaN|parseFloat|parseInt){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-object: - match: (?:assign|create|defineProperties|defineProperty|entries|freeze|fromEntries|getOwnPropertyDescriptors?|getOwnPropertyNames|getOwnPropertySymbols|getPrototypeOf|is|isExtensible|isFrozen|isSealed|keys|preventExtensions|seal|setPrototypeOf|values){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-promise: - match: (?:all|race|reject|resolve|allSettled|any){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-proxy: - match: revocable{{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-reflect: - match: (?:apply|construct|defineProperty|deleteProperty|get|getOwnPropertyDescriptor|getPrototypeOf|has|isExtensible|ownKeys|preventExtensions|set|setPrototypeOf){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-string: - match: (?:fromCharCode|fromCodePoint|raw){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-symbol: - match: (?:asyncDispose|asyncIterator|dispose|hasInstance|isConcatSpreadable|iterator|match|replace|search|species|split|toPrimitive|toStringTag|unscopeables){{identifier_break}} scope: support.constant.builtin.js pop: 1 - match: (?:for|keyFor){{identifier_break}} scope: meta.function-call.js support.function.builtin.js pop: 1 support-property-ecma-typedarray: - match: (?:BYTES_PER_ELEMENT){{identifier_break}} scope: support.constant.builtin.js pop: 1 support-variable-console: # https://console.spec.whatwg.org/ - match: console{{identifier_break}} scope: support.type.object.console.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: builtin-console-properties - include: else-pop support-variable-dom: - match: XMLHttpRequest{{identifier_break}} scope: support.class.dom.js pop: 1 - match: (?:document|window|navigator){{identifier_break}} scope: support.type.object.dom.js pop: 1 - match: (?:clearTimeout|clearInterval|setTimeout|setInterval){{identifier_break}} scope: meta.function-call.js support.function.dom.js pop: 1 support-variable-node: - match: global{{identifier_break}} scope: support.type.object.node.js pop: 1 - match: Buffer{{identifier_break}} scope: support.class.node.js pop: 1 - match: process{{identifier_break}} scope: support.constant.node.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-node-process - include: object-property - include: else-pop - include: else-pop # Module-level variables - match: (?:__dirname|__filename|exports){{identifier_break}} scope: support.constant.node.js pop: 1 - match: module{{identifier_break}} scope: support.constant.node.js set: - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-node-module - include: object-property - include: else-pop - include: else-pop - match: require{{identifier_break}} scope: meta.function-call.js support.function.node.js pop: 1 support-property-node-process: - match: (?:arch|argv|argv0|channel|config|connected|debugPort|env|execArgv|execPath|exitCode|mainModule|noDeprecation|pid|platform|ppid|release|stderr|stdin|stdout|throwDeprecation|title|traceDeprecation|version|versions){{identifier_break}} scope: support.constant.node.js pop: 1 - match: (?:abort|chdir|cpuUsage|cwd|disconnect|dlopen|emitWarning|exit|getegid|geteuid|getgit|getgroups|getuid|hasUncaughtExceptionCaptureCallback|hrtime|initGroups|kill|memoryUsage|nextTick|send|setegid|seteuid|setgid|setgroups|setuid|hasUncaughtExceptionCaptureCallback|umask|uptime){{identifier_break}} scope: meta.function-call.js support.function.node.js pop: 1 support-property-node-module: - match: (?:children|exports|filename|id|loaded|parent|paths){{identifier_break}} scope: support.constant.node.js pop: 1 - match: require{{identifier_break}} scope: meta.function-call.js support.function.node.js pop: 1 builtin-console-properties: - match: (?:warn|info|log|error|time|timeEnd|assert|count|dir|group|groupCollapsed|groupEnd|profile|profileEnd|table|trace|timeStamp){{identifier_break}} scope: meta.function-call.js support.function.console.js pop: 1 - include: object-property object-property: - include: support-property - match: (?=\#?{{identifier_name}}{{function_assignment_lookahead}}) set: - function-name-meta - object-property-base - match: '(?=#?{{identifier_name}}{{function_call_after_lookahead}})' set: call-method-name - match: '{{identifier_name}}(?={{nothing}}`)' scope: variable.function.tagged-template.js pop: 1 - include: object-property-base - include: else-pop call-method-name: - include: support-property - match: '(#)?{{identifier_name}}' scope: meta.function-call.js variable.function.js captures: 1: punctuation.definition.js pop: 1 - include: else-pop object-property-base: - match: '{{dollar_only_identifier}}' scope: meta.property.object.dollar.only.js punctuation.dollar.js pop: 1 - match: '{{dollar_identifier}}' scope: meta.property.object.dollar.js captures: 1: punctuation.dollar.js pop: 1 - match: '{{identifier_name}}' scope: meta.property.object.js pop: 1 - match: '{{identifier_part}}+{{identifier_break}}' scope: invalid.illegal.illegal-identifier.js pop: 1 - match: (#)({{identifier_name}}) captures: 1: punctuation.definition.variable.js 2: meta.property.object.js pop: 1 support-property: - include: support-property-ecma support-property-ecma: - match: constructor{{identifier_break}} scope: variable.language.constructor.js pop: 1 - match: prototype{{identifier_break}} scope: support.constant.prototype.js pop: 1 - match: (?:hasOwnProperty|isPrototypeOf|propertyIsEnumerable|toLocaleString|toString|valueOf){{identifier_break}} scope: meta.function-call.js support.function.js pop: 1 # Annex B - match: __proto__{{identifier_break}} scope: invalid.deprecated.js variable.language.prototype.js pop: 1 - match: (?:__defineGetter__|__defineSetter__|__lookupGetter__){{identifier_break}} scope: invalid.deprecated.js meta.function-call.js support.function.js pop: 1 import-meta-expression: - match: import{{identifier_break}} scope: keyword.import.js set: import-expression-end import-expression-end: - match: (?=\() set: function-call-arguments - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - match: meta{{identifier_break}} scope: variable.language.import.js pop: 1 - include: object-property - include: else-pop