diff --git a/JSX (Outer).YAML-tmPreferences b/JSX (Outer).YAML-tmPreferences
deleted file mode 100644
index d1e3052..0000000
--- a/JSX (Outer).YAML-tmPreferences
+++ /dev/null
@@ -1,16 +0,0 @@
-# [PackageDev] target_format: plist, ext: tmPreferences
-name: JSX 2
-scope: source.js
-settings:
- # The indent patterns can't be limited to meta.jsx.js. Otherwise they wouldn't
- # work for the outer most tag since it would fall outside of that scope.
- # They're also not limited with '- string - comment' since you may be writing
- # JSX in your documentation or template strings.
- decreaseIndentPattern: >-
- (?x)
- ^\s*[^>]+>$
- | ^\s*/>$
- increaseIndentPattern: >-
- (?x)
- ^\s*<[^/>]+>$
- | ^\s*<[^/>\s]+$
diff --git a/JSX (Outer).tmPreferences b/JSX (Outer).tmPreferences
deleted file mode 100644
index 788984b..0000000
--- a/JSX (Outer).tmPreferences
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
- name
- JSX 2
- scope
- source.js
- settings
-
- decreaseIndentPattern
- (?x)
- ^\s*</[^>]+>$
- | ^\s*/>$
- increaseIndentPattern
- (?x)
- ^\s*<[^/>]+>$
- | ^\s*<[^/>\s]+$
-
-
-
diff --git a/JavaScript (Babel).sublime-syntax b/JavaScript (Babel).sublime-syntax
index 8ff7a69..08cc8c1 100644
--- a/JavaScript (Babel).sublime-syntax
+++ b/JavaScript (Babel).sublime-syntax
@@ -1,11 +1,186 @@
%YAML 1.2
---
+name: JavaScript (Babel)
+file_extensions:
+ - js
+ - jsx
+ - es6
+ - babel
+scope: source.js
+variables:
+ left_expression_end_lookahead: (?!\s*[.\[\(])
+ identifier_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{identifier_escape}})
+ method_lookahead: |-
+ (?x)(?=
+ (?: get|set|async ){{identifier_break}}(?!\s*:)
+ | \*
+ | {{property_name}} \s* (?:\(|<)
+ )
+ function_call_lookahead: (?={{identifier_name}}\s*(?:{{dot_accessor}})?\()
+ dec_exponent: '[Ee](?:[-+]|(?![-+])){{dec_digit}}*'
+ dollar_only_identifier: (?:\${{identifier_break}})
+ arrow_func_lookahead: |-
+ (?x)(?:
+ \s*(async\s*)?
+ (?:
+ {{non_reserved_identifier}}
+ |\( (?: [^()]|\([^()]*\) )* \)
+ )
+ (?:
+ \s*:
+ \s*{{non_reserved_identifier}}
+ )?
+ \s*=>
+ )
+ func_lookahead: |-
+ (?x:
+ (?:async{{identifier_break}}{{nothing}})?
+ function{{identifier_break}}
+ )
+ jsx_identifier_break: (?!{{jsx_identifier_part}})
+ identifier_start: (?:[_$\p{L}\p{Nl}]|{{identifier_escape}})
+ constant_identifier: (?:[[:upper:]]{{identifier_part}}*{{identifier_break}})
+ modifier: (?:static{{identifier_break}})
+ identifier_escape: (?:\\u(?:\h{4}|\{\h+\}))
+ 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}}
+ function_assignment_lookahead: |-
+ (?x:(?=
+ \s* = \s*
+ {{either_func_lookahead}}
+ ))
+ identifier_break: (?!{{identifier_part}})
+ jsdoc_block_tag: \@[^\n\t\f\v *@]+
+ binding_pattern_lookahead: (?:{{identifier_name}}|\[|\{)
+ non_reserved_identifier: (?:(?!{{reserved_word}}){{identifier_name}})
+ jsx_identifier: '{{identifier_start}}{{jsx_identifier_part}}*{{jsx_identifier_break}}'
+ oct_digit: '[0-7_]'
+ bin_digit: '[01_]'
+ property_name: >-
+ (?x:
+ {{identifier_name}}
+ | [0-9]+
+ | '(?:[^\\']|\\.)*'
+ | "(?:[^\\"]|\\.)*"
+ | \[ .* \]
+ )
+ line_ending_ahead: (?={{nothing}}(?:/\*{{block_comment_contents}})?$)
+ block_comment_contents: (?:(?:[^*]|\*(?!/))*)
+ identifier_name: (?:{{identifier_start}}{{identifier_part}}*{{identifier_break}})
+ nothing: (?x:(?:\s+|{{block_comment}})*)
+ jsx_identifier_part: (?:{{identifier_part}}|-)
+ hex_digit: '[\h_]'
+ dec_digit: '[0-9_]'
+ class_element_name: |-
+ (?x:
+ \+?
+ (?:
+ \*?
+ {{property_name}}
+ | \#{{non_reserved_identifier}}
+ )
+ )
+ block_comment: (?:/\*{{block_comment_contents}}\*/)
+ either_func_lookahead: (?:{{func_lookahead}}|{{arrow_func_lookahead}})
+ dec_integer: (?:0|[1-9]{{dec_digit}}*)
+ dollar_identifier: (?:(\$){{identifier_part}}*{{identifier_break}})
+ line_continuation_lookahead: >-
+ (?x:(?=
+ (?! \+\+ | -- )
+ (?=
+ != |
+ [-+*/%><=&|^\[(;,.:?] |
+ (?:in|instanceof){{identifier_break}}
+ )
+ ))
+ dot_accessor: (?:\??\.)
first_line_match: ^#!\s*/.*\b(node|js)\b
+version: 2
contexts:
- support-property-ecma-reflect:
- - match: (?:apply|construct|defineProperty|deleteProperty|get|getOwnPropertyDescriptor|getPrototypeOf|has|isExtensible|ownKeys|preventExtensions|set|setPrototypeOf){{identifier_break}}
- scope: support.function.builtin.js
+ branch-possible-bare-arrow-function:
+ - meta_include_prototype: false
+ - match: ''
+ push:
+ - detect-bare-arrow
+ - literal-variable
+
+ import-string-or-items:
+ - include: literal-string
+ - match: (?=\S)
+ set:
+ - import-export-from
+ - import-list
+ - import-export-alias
+ - import-item
+
+ flow-type-object-contents:
+ - include: comma-separator
+ - match: ;
+ scope: punctuation.separator.semicolon.js
+ - match: '{{method_lookahead}}'
+ push: method-declaration
+ - match: \+
+ scope: storage.modifier.variance.js
+ - match: '{{non_reserved_identifier}}'
+ scope: meta.object-literal.key.js
+ push: flow-type-object-value
+ - match: \[
+ scope: punctuation.section.brackets.begin.js
+ push:
+ - flow-type-object-value
+ - flow-type-object-indexer-type
+ - flow-type-object-indexer-label
+
+ export-extended:
+ - include: flow-type-export-type
+
+ - include: variable-declaration
+ - include: class
+ - include: regular-function
+
+ - match: default{{identifier_break}}
+ scope: keyword.control.import-export.js
+ set:
+ - include: class
+ - include: regular-function
+ - match: (?=\S)
+ set: expression-statement
+
+ - match: (?=\S)
+ set:
+ - expect-semicolon
+ - import-export-from
+ - export-list
+ - import-export-alias
+ - export-item
+
+ else-pop:
+ - match: (?=\S)
+ pop: true
+
+ variable-binding-array-destructuring:
+ - match: \[
+ scope: punctuation.section.brackets.begin.js
+ set:
+ - meta_scope: meta.binding.destructuring.sequence.js
+ - match: \]
+ scope: punctuation.section.brackets.end.js
+ pop: true
+ - include: variable-binding-spread
+ - include: variable-binding-list
+
+ jsx-expect-tag-end:
+ - meta_content_scope: meta.tag.js
+ - match: '>'
+ scope: meta.tag.js punctuation.definition.tag.end.js
pop: true
+ - include: else-pop
for-condition-contents:
# This could be either type of for loop.
@@ -28,137 +203,157 @@ contexts:
- expression-end-no-in
- expression-begin
- prototype:
- - include: comments
+ immediately-pop:
+ - match: ''
+ pop: true
- postfix-operators:
- - match: --
- scope: keyword.operator.arithmetic.js
- - match: \+\+
- scope: keyword.operator.arithmetic.js
+ flow-type-function:
+ - match: \(
+ scope: punctuation.section.grouping.begin.js
+ set:
+ - meta_scope: meta.group.js
+ - match: \)
+ scope: punctuation.section.grouping.end.js
+ pop: true
+ - include: flow-type-list
- class-body-contents:
- - meta_scope: meta.block.js
+ object-literal-contents:
+ - meta_scope: meta.mapping.js
- match: \}
scope: punctuation.section.block.end.js
pop: true
- - match: \;
- scope: punctuation.terminator.statement.js
-
- - include: decorator
+ - match: \.\.\.
+ scope: keyword.operator.spread.js
+ push: expression-no-comma
- - match: constructor{{identifier_break}}
- scope: entity.name.function.constructor.js
+ - match: >-
+ (?x)(?=
+ {{property_name}}\s*:\s*
+ {{either_func_lookahead}}
+ )
push:
- - function-meta
- - function-declaration-expect-body
- - function-declaration-meta
- - function-declaration-expect-parameters
-
- - match: static{{identifier_break}}
- scope: storage.modifier.js
- push: class-field
-
- - match: (?={{class_element_name}})
- push: class-field
-
- decorator-expression-begin:
- - include: decorator-name
- - include: expression-begin
-
- function-parameter-binding-name:
- - match: '{{non_reserved_identifier}}'
- scope: meta.binding.name.js variable.parameter.function.js
- - match: '{{identifier}}'
- scope: invalid.illegal.identifier.js meta.binding.name.js variable.parameter.function.js
+ - object-literal-meta-key
+ - method-name
- import-list:
- - match: ','
- scope: punctuation.separator.comma.js
- push:
- - import-export-alias
- - import-item
- - include: else-pop
+ - match: (?=\*)
+ push: method-declaration
- jsx-tag-attributes:
- - meta_content_scope: meta.tag.attributes.js
+ - match: (?=(?:get|set|async){{identifier_break}})
+ branch_point: prefixed-object-literal-method
+ branch:
+ - prefixed-object-literal-method
+ - object-literal-element
- - match: '>'
- scope: punctuation.definition.tag.end.js
- set: jsx-body
+ - match: (?={{property_name}})
+ push: object-literal-element
- - match: /
- scope: punctuation.definition.tag.end.js
- set: jsx-expect-tag-end
+ - include: comma-separator
- - include: jsx-interpolation
+ - match: ':'
+ scope: punctuation.separator.key-value.js
+ push: expression-no-comma
- - match: '{{jsx_identifier}}'
- scope: entity.other.attribute-name.js
+ # If there's any garbage, parse it as an expression
+ # so that close braces won't break things.
+ - match: (?=\S)
+ push: expression-no-comma
- - match: '='
- scope: punctuation.separator.key-value.js
- push: jsx-attribute-value
+ tagged-template:
+ - include: literal-string-template-custom-comments
+ - include: literal-string-template-custom-tags
+ - include: styled-components
- for-await:
- - match: await{{identifier_break}}
- scope: keyword.control.flow.await.js
+ - match: '{{identifier_name}}(?=\s*`)'
+ scope: variable.function.tagged-template.js
pop: true
- - include: else-pop
- 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: true
- - match: (?:isFinite|isInteger|isNaN|isSafeInteger|NaN|parseFloat|parseInt){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
-
- class-meta:
+ parenthesized-arrow-function-fallback:
- meta_include_prototype: false
- - meta_scope: meta.class.js
- - include: immediately-pop
-
- arrow-function-expect-arrow:
- - match: =>
- scope: storage.type.function.arrow.js
- pop: true
- - include: else-pop
-
- 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
+ - match: ''
+ push:
+ - immediately-pop-2
+ - arrow-function-declaration
- support-variable-dom:
- - match: XMLHttpRequest{{identifier_break}}
- scope: support.class.dom.js
- pop: true
- - match: (?:document|window|navigator){{identifier_break}}
- scope: support.type.object.dom.js
- pop: true
- - match: (?:clearTimeout|setTimeout){{identifier_break}}
- scope: support.function.dom.js
- pop: true
+ 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: |-
+ (?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
- immediately-pop:
- - match: ''
- pop: true
+ inherited-class-expression-end:
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ push:
+ - include: inherited-class-name
+ - include: object-property
- import-meta:
- - meta_include_prototype: false
- - meta_scope: meta.import.js
- - include: immediately-pop
+ - include: left-expression-end
flow-type-operators:
- match: \|(?!\})
@@ -168,7 +363,7 @@ contexts:
scope: keyword.operator.type.intersection.js
push: flow-type-begin
- match: =>
- scope: storage.type.function.arrow.js
+ scope: keyword.declaration.function.arrow.js
push: flow-type-begin
- match: \?
scope: storage.modifier.maybe.js
@@ -182,129 +377,66 @@ contexts:
- match: '%checks{{identifier_break}}'
scope: storage.modifier.checks.js
- initializer:
- - match: '='
- scope: keyword.operator.assignment.js
- set: expression-no-comma
- - include: else-pop
-
- flow-type-declare:
- - match: declare{{identifier_break}}(?=\s*(?:type|class|function|var|let|const|opaque|export|module){{identifier_break}})
- scope: storage.type.js
- set:
- - match: opaque{{identifier_break}}
- scope: storage.modifier.js
- pop: true
- - match: module{{identifier_break}}
- scope: storage.type.js
- set:
- - flow-type-module-meta
- - flow-type-module-body
- - flow-type-module-name
- - match: export{{identifier_break}}
- scope: storage.type.js
- set: flow-type-declare-export
- - include: else-pop
-
- block-scope:
- - include: block
- - include: else-pop
-
- 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: constant.numeric.float.decimal.js
- captures:
- 1: punctuation.separator.decimal.js
- 2: punctuation.separator.decimal.js
- pop: true
-
- # integers
- - match: 0{{dec_digit}}+{{identifier_break}}
- scope: constant.numeric.integer.octal.js invalid.deprecated.numeric.octal.js
- pop: true
+ import-brace:
+ - include: flow-type-import-type
- - match: (0[Xx]){{hex_digit}}*(n)?{{identifier_break}}
- scope: constant.numeric.integer.hexadecimal.js
- captures:
- 1: punctuation.definition.numeric.base.js
- 2: storage.type.numeric.js
+ - meta_scope: meta.block.js
+ - include: comma-separator
+ - match: \}
+ scope: punctuation.section.block.end.js
pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.other.readwrite.js
+ push: import-export-alias
+ - match: \*
+ scope: constant.other.js
+ push: import-export-alias
+ - include: else-pop
- - match: (0[Oo]){{oct_digit}}*(n)?{{identifier_break}}
- scope: constant.numeric.integer.octal.js
- captures:
- 1: punctuation.definition.numeric.base.js
- 2: storage.type.numeric.js
- pop: true
+ function-parameter-binding-object-alias:
+ - match: ':'
+ scope: punctuation.separator.key-value.js
+ set: function-parameter-binding-pattern
+ - include: else-pop
- - match: (0[Bb]){{bin_digit}}*(n)?{{identifier_break}}
- scope: constant.numeric.integer.binary.js
- captures:
- 1: punctuation.definition.numeric.base.js
- 2: storage.type.numeric.js
- pop: true
+ main:
+ - include: comments-top-level
- - match: '{{dec_integer}}(n|(?!\.)){{identifier_break}}'
- scope: constant.numeric.integer.decimal.js
- captures:
- 1: storage.type.numeric.js
- pop: true
+ - match: \)|\}|\]
+ scope: invalid.illegal.stray-bracket-end.js
+ # Don't pop or embedding could break.
- # illegal numbers
- - match: 0[Xx]{{identifier_part}}+
- scope: invalid.illegal.numeric.hexadecimal.js
- pop: true
+ - include: statements
- - match: 0[Bb]{{identifier_part}}+
- scope: invalid.illegal.numeric.binary.js
- pop: true
+ comma-separator:
+ - match: ','
+ scope: punctuation.separator.comma.js
- - match: 0{{identifier_part}}+
- scope: invalid.illegal.numeric.octal.js
- pop: true
+ function-parameter-binding-pattern:
+ - match: ''
+ set:
+ - - include: flow-type-annotation-optional
+ - - include: function-parameter-binding-name
+ - include: function-parameter-binding-array-destructuring
+ - include: function-parameter-binding-object-destructuring
+ - include: else-pop
- - match: '[1-9]{{identifier_part}}+(?:\.{{identifier_part}}*)?'
- scope: invalid.illegal.numeric.decimal.js
+ function-parameter-binding-object-key:
+ - match: '{{identifier_name}}(?=\s*:)'
pop: true
-
- variable-binding-object-alias:
- - match: ':'
- scope: punctuation.separator.key-value.js
- set: variable-binding-pattern
+ - include: literal-string
+ - include: computed-property-name
+ - include: function-parameter-binding-name
- include: else-pop
- literal-variable-base:
- - match: '{{dollar_only_identifier}}'
- scope: variable.other.dollar.only.js punctuation.dollar.js
- pop: true
- - match: '{{dollar_identifier}}'
- scope: variable.other.dollar.js
- captures:
- 1: punctuation.dollar.js
- pop: true
- - match: '{{constant_identifier}}'
- scope: variable.other.constant.js
- pop: true
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
- pop: true
- - match: (#)({{identifier}})
- captures:
- 1: punctuation.definition.variable.js
- 2: variable.other.readwrite.js
- pop: true
+ method-declaration-expect-asterisk:
+ - match: \*
+ scope: keyword.generator.asterisk.js
+ - include: else-pop
- support-property-ecma-atomics:
- - match: (?:and|add|compareExchange|exchange|isLockFree|load|or|store|sub|wait|wake|xor){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
+ expect-parenthesized-expression:
+ - include: parenthesized-expression
+ - include: else-pop
parenthesized-expression:
- match: \(
@@ -319,623 +451,498 @@ contexts:
- match: (?=\S)
push: expression
- catch-meta:
- - meta_include_prototype: false
- - meta_scope: meta.catch.js
+ flow-type-module-meta:
+ - meta_scope: meta.module.js
- include: immediately-pop
- support-property-ecma-typedarray:
- - match: (?:BYTES_PER_ELEMENT){{identifier_break}}
- scope: support.constant.builtin.js
+ statement:
+ - include: flow-type-declare
+ - include: flow-type-alias
+
+ - match: \;
+ scope: punctuation.terminator.statement.empty.js
pop: true
- for-of-rest:
- - match: (?:of|in){{identifier_break}}
- scope: keyword.operator.word.js
- set: expression
-
- class-field-rest:
- - match: ','
- scope: punctuation.separator.js
- push:
- - initializer
- - field-name
- - include: else-pop
+ - include: import-statement-or-import-meta
+ - include: export-statement
+ - include: conditional
+ - include: block
+ - include: label
+ - include: variable-declaration
- support-property-ecma-bigint:
- - match: (?:asUintN|asIntN){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
+ - match: break{{identifier_break}}
+ scope: keyword.control.flow.break.js
+ set:
+ - expect-semicolon
+ - expect-label
- constructor-body-expect-class-begin:
- - match: (?={{identifier}}\s*\()
+ - match: continue{{identifier_break}}
+ scope: keyword.control.flow.continue.js
set:
- - include: support
- - match: '{{dollar_only_identifier}}'
- scope: variable.type.dollar.only.js punctuation.dollar.js
- pop: true
- - match: '{{dollar_identifier}}'
- scope: variable.type.dollar.js
- captures:
- 1: punctuation.dollar.js
- pop: true
- - match: '{{identifier}}'
- scope: variable.type.js
- pop: true
- - include: else-pop
+ - expect-semicolon
+ - expect-label
- - include: expression-begin
+ - match: debugger{{identifier_break}}
+ scope: keyword.control.flow.debugger.js
+ set: expect-semicolon
- variable-binding-pattern:
- - match: ''
- set:
- - - include: flow-type-annotation
- - - include: variable-binding-name
- - include: variable-binding-array-destructuring
- - include: variable-binding-object-destructuring
- - include: else-pop
+ - match: return{{identifier_break}}
+ scope: keyword.control.flow.return.js
+ set: restricted-production
- statements:
- - match: \)|\}|\]
- scope: invalid.illegal.stray-bracket-end.js
- pop: true
+ - match: throw{{identifier_break}}
+ scope: keyword.control.flow.throw.js
+ set: restricted-production
- - match: (?=\S)
- push: statement
+ - include: class
+ - include: regular-function
- literal-string:
- - match: "'"
- scope: punctuation.definition.string.begin.js
- set:
- - meta_include_prototype: false
- - meta_scope: meta.string.js string.quoted.single.js
- - match: \'
- scope: punctuation.definition.string.end.js
- pop: true
- - match: \n
- scope: invalid.illegal.newline.js
- pop: true
- - include: string-content
- - match: '"'
- scope: punctuation.definition.string.begin.js
- set:
- - meta_include_prototype: false
- - meta_scope: meta.string.js string.quoted.double.js
- - match: \"
- scope: punctuation.definition.string.end.js
- pop: true
- - match: \n
- scope: invalid.illegal.newline.js
- pop: true
- - include: string-content
+ - include: decorator
- finally-meta:
- - meta_include_prototype: false
- - meta_scope: meta.finally.js
- - include: immediately-pop
+ - include: expression-statement
- flow-type-module-body:
- - match: \{
- scope: punctuation.section.block.begin.js
- set: flow-type-module-contents
+ variable-binding-object-key:
+ - match: '{{identifier_name}}(?=\s*:)'
+ pop: true
+ - include: literal-string
+ - include: computed-property-name
+ - include: variable-binding-name
- include: else-pop
- flow-type-generic-arguments:
- - match: <
- scope: punctuation.section.generic.begin.js
- set:
- - meta_scope: meta.generic.js
- - match: '>'
- scope: punctuation.section.generic.end.js
- pop: true
- - include: flow-type-list
+ function-declaration-expect-function-keyword:
+ - match: function{{identifier_break}}
+ scope: keyword.declaration.function.js
+ pop: true
- include: else-pop
- function-or-class-declaration:
- - match: (?=class{{identifier_break}})
- set: class
-
- - match: (?={{func_lookahead}})
- set: function-declaration
-
- class-field:
- - match: \+
- scope: storage.modifier.variance.js
-
- - match: '{{method_lookahead}}'
- set: method-declaration
-
- - match: |-
- (?x)(?=
- \#? {{identifier}}
- \s* = \s*
- {{either_func_lookahead}}
- )
- set:
- - function-initializer
- - flow-type-annotation-optional
- - function-name-meta
- - field-name
-
- - match: (?={{property_name}})
+ function-block:
+ - match: \{
+ scope: punctuation.section.block.begin.js
set:
- - field-initializer-or-method-declaration
- - flow-type-annotation-optional
- - field-name
+ - meta_scope: meta.block.js
+ - match: \}
+ scope: punctuation.section.block.end.js
+ pop: true
+ - include: statements
- - match: (?=#{{identifier}})
+ class-extends:
+ - match: extends{{identifier_break}}
+ scope: storage.modifier.extends.js
set:
- - class-field-rest
- - initializer
- - flow-type-annotation-optional
- - field-name
-
+ - flow-type-generic-arguments
+ - inherited-class-expression-end
+ - inherited-class-expression-begin
- include: else-pop
- jsx-tag-name:
- - match: ''
- set:
- - - clear_scopes: 1
- - meta_scope: meta.tag.name.js
- - include: immediately-pop
- - jsx-tag-name-component
-
- flow-type-declare-export:
- - match: default{{identifier_break}}
- scope: keyword.control.import-export.js
- set: flow-type
+ detect-parenthesized-arrow:
+ - match: (?==>)
+ fail: parenthesized-arrow-function
- match: (?=\S)
- pop: true
-
- tagged-template:
- - include: literal-string-template-custom-comments
- - include: literal-string-template-custom-tags
- - include: styled-components
+ pop: 2
- - match: '{{identifier}}(?=\s*`)'
- scope: variable.function.tagged-template.js
+ expect-case-colon:
+ - match: ':'
+ scope: punctuation.separator.js
pop: true
-
- call-path:
- - match: '{{dot_accessor}}'
- scope: punctuation.accessor.js
- push: object-property
- include: else-pop
- for-condition:
- - match: \(
- scope: punctuation.section.group.js
- set:
- - for-condition-end
- - for-condition-contents
- - include: else-pop
+ support-property-ecma-array:
+ - match: (?:from|isArray|of){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
- 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
+ expression-list:
+ - include: expression-break
+ - include: comma-separator
+ - match: (?=\S)
+ push: expression-no-comma
+
+ builtin-console-properties:
+ - match: (?:warn|info|log|error|time|timeEnd|assert|count|dir|group|groupCollapsed|groupEnd|profile|profileEnd|table|trace|timeStamp){{identifier_break}}
+ scope: support.function.console.js
pop: true
- - 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: support.function.node.js
+ - include: object-property
+
+ flow-type-object-indexer-type:
+ - match: \]
+ scope: punctuation.section.brackets.end.js
pop: true
+ - include: flow-type-list
- block:
+ export-item:
- match: \{
scope: punctuation.section.block.begin.js
- set:
- - meta_scope: meta.block.js
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
- - include: statements
-
- flow-type-utility:
- - match: |-
- (?x) (?:
- Class|Function|
- \$(?:
- Keys|Values|ReadOnly|Exact|Diff|Rest|PropertyType|ElementType|
- ObjMap|TupleMap|Call|Supertype|Subtype
- )
- ){{identifier_break}}
- scope: support.type.utility.js
- pop: true
-
- support-property-ecma-math:
- - match: (?:E|LN10|LN2|LOG10E|LOG2E|PI|SQRT1_2|SQRT2){{identifier_break}}
- scope: support.constant.builtin.js
+ set: export-brace
+ - match: '{{non_reserved_identifier}}'
+ scope: variable.other.readwrite.js
pop: true
- - 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: support.function.builtin.js
+ - match: \*
+ scope: constant.other.js
pop: true
+ - include: else-pop
- function-declaration:
+ ternary-operator-expect-colon:
+ - match: ':'
+ scope: keyword.operator.ternary.js
+ set: expression-no-comma
+ - include: else-pop
+
+ variable-binding-pattern:
- match: ''
set:
- - function-meta
- - function-declaration-expect-body
- - function-declaration-meta
- - flow-type-annotation
- - function-declaration-expect-parameters
- - flow-type-generic-parameters
- - function-declaration-expect-name
- - function-declaration-expect-generator-star
- - function-declaration-expect-function-keyword
- - function-declaration-expect-async
+ - - include: flow-type-annotation
+ - - include: variable-binding-name
+ - include: variable-binding-array-destructuring
+ - include: variable-binding-object-destructuring
+ - include: else-pop
- support-property-ecma-string:
- - match: (?:fromCharCode|fromCodePoint|raw){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
+ do-while-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.do-while.js
+ - include: immediately-pop
- await-expression:
- - match: await{{identifier_break}}
- scope: keyword.control.flow.await.js
+ 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
- literal-string-template-custom-comments: []
- left-expression-end:
- - include: expression-break
+ computed-property-name:
+ - match: \[
+ scope: punctuation.section.brackets.begin.js
+ set:
+ - match: \]
+ scope: punctuation.section.brackets.end.js
+ pop: true
+ - match: (?=\S)
+ push: expression
- - match: (?=`)
- push: literal-string-template
+ styled-component-end:
+ - match: \.
+ scope: punctuation.accessor.dot.js
+ push: styled-component-begin
- - match: (?=(?:\.\?)?\()
- push: function-call-arguments
+ - match: (?=`)
+ set:
+ - match: '`'
+ scope: string.quoted.other.js punctuation.definition.string.begin.js
+ push:
+ - - meta_include_prototype: false
+ - meta_scope: meta.string.js string.quoted.other.js
+ - match: '`'
+ scope: punctuation.definition.string.end.js
+ pop: true
+ - include: immediately-pop
+ - - clear_scopes: 1
+ - include: immediately-pop
+ - - match: ''
+ set: scope:source.js.css
+ with_prototype:
+ - match: (?=`)
+ pop: true
+ - match: \$\{
+ scope: punctuation.section.interpolation.begin.js
+ push:
+ - clear_scopes: 1
+ - meta_scope: meta.interpolation.js
+ - meta_content_scope: source.js.embedded.expression
+ - match: \}
+ scope: punctuation.section.interpolation.end.js
+ pop: true
+ - match: (?=\S)
+ push: expression
+ - include: string-content
+ - include: else-pop
+ - include: expression-end
- - include: property-access
+ regexp-complete:
+ - match: /
+ scope: punctuation.definition.string.begin.js
+ set: regexp
- - include: fallthrough
+ expression-statement:
+ - match: (?=\S)
+ set:
+ - expect-semicolon
+ - expression-statement-end
+ - expression-begin
+ function-declaration-expect-parameters:
+ - include: function-declaration-parameters
- include: else-pop
- string-content:
- - match: \\\n
- scope: constant.character.escape.newline.js
- - match: \\(?:x\h\h|u\h\h\h\h|.)
- scope: constant.character.escape.js
-
- decorator:
- - match: '@'
- scope: punctuation.definition.annotation.js
- push:
- - decorator-meta
- - decorator-expression-end
- - decorator-expression-begin
-
- flow-type-object:
- - match: \{\|
- scope: punctuation.section.block.begin.js
+ function-call-arguments:
+ - match: ({{dot_accessor}})?(\()
+ captures:
+ 1: punctuation.accessor.js
+ 2: punctuation.section.group.begin.js
set:
- - meta_scope: meta.type.object.exact.js
- - match: \|\}
- scope: punctuation.section.block.end.js
+ - meta_scope: meta.group.js
+ - match: \)
+ scope: punctuation.section.group.end.js
pop: true
- - include: flow-type-object-contents
+ - include: expression-list
- - match: \{
- scope: punctuation.section.block.begin.js
- set:
- - meta_scope: meta.type.object.js
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
- - include: flow-type-object-contents
+ inherited-class-expression-begin:
+ - include: inherited-class-name
+ - include: expression-begin
- export-extended:
- - include: flow-type-export-type
+ for-await:
+ - match: await{{identifier_break}}
+ scope: keyword.control.flow.await.js
+ pop: true
+ - include: else-pop
- - include: variable-declaration
- - include: function-or-class-declaration
+ function-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.function.js
+ - include: immediately-pop
- - match: default{{identifier_break}}
- scope: keyword.control.import-export.js
+ flow-type-alias:
+ - match: (?=type{{identifier_break}})
set:
- - include: function-or-class-declaration
- - match: (?=\S)
- set: expression-statement
+ - - match: (?={{non_reserved_identifier}})
+ set:
+ - - meta_scope: meta.declaration.type.js
+ - match: ''
+ pop: true
+ - flow-type-alias-initializer
+ - flow-type-generic-parameters
+ - - match: '{{non_reserved_identifier}}'
+ scope: entity.name.type.js
+ pop: true
+ - - include: else-pop
- - match: (?=\S)
- set:
- - expect-semicolon
- - import-export-from
- - export-list
- - import-export-alias
- - export-item
+ - match: (?=\S)
+ set: [expression-statement, expression-end]
+ - - match: type{{identifier_break}}(?=\s*(?:$|{{non_reserved_identifier}}))
+ scope: keyword.declaration.js
+ set:
+ - meta_scope: meta.declaration.type.js
+ - include: else-pop
+ - include: expression-begin
- call-function-name:
- - match: '{{dollar_only_identifier}}'
- scope: variable.function.js variable.other.dollar.only.js punctuation.dollar.js
+ with-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.with.js
+ - include: immediately-pop
+
+ flow-type-primitive:
+ - match: boolean{{identifier_break}}
+ scope: support.type.primitive.boolean.js
pop: true
- - match: '{{identifier}}'
- scope: variable.function.js
+
+ - match: number{{identifier_break}}
+ scope: support.type.primitive.number.js
pop: true
- - include: else-pop
- import-meta-expression:
- - match: import{{identifier_break}}
- scope: keyword.import.js
- set: import-expression-end
+ - match: string{{identifier_break}}
+ scope: support.type.primitive.string.js
+ pop: true
- function-declaration-expect-async:
- - match: async{{identifier_break}}
- scope: storage.type.js
+ - match: null{{identifier_break}}
+ scope: support.type.primitive.null.js
pop: true
- - include: else-pop
- flow-type-literal:
- - match: true{{identifier_break}}
- scope: constant.language.boolean.true.js
+ - match: void{{identifier_break}}
+ scope: support.type.primitive.void.js
pop: true
- - match: false{{identifier_break}}
- scope: constant.language.boolean.false.js
+
+ import-statement-or-import-meta:
+ - match: (?=import{{identifier_break}})
+ branch_point: import-statement
+ branch:
+ - import-statement
+ - expression-statement
+
+ expression-end:
+ - include: postfix-operators
+ - include: binary-operators
+ - include: ternary-operator
+
+ - include: left-expression-end
+
+ catch-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.catch.js
+ - include: immediately-pop
+
+ 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: true
- - match: (?=\d)
- set:
- - - match: '{{identifier_part}}+'
- scope: invalid.illegal.js
- - include: immediately-pop
- - literal-number
- - match: (?=['"])
- set: literal-string
- support-property-ecma-proxy:
- - match: revocable{{identifier_break}}
- scope: support.function.builtin.js
+ # 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: true
- import-export:
- - match: import{{identifier_break}}(?!{{nothing}}[.(])
- scope: keyword.control.import-export.js
- set:
- - meta_scope: meta.import.js
- - match: (?=[.(]) # Recovery for import expressions
- set:
- - expression-statement-end
- - import-expression-end
- - match: (?=\S)
- set:
- - import-meta
- - expect-semicolon
- - import-string-or-items
+ - 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: true
- - match: export{{identifier_break}}
- scope: keyword.control.import-export.js
- set:
- - export-meta
- - export-extended
+ - 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: true
- 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.logical.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: |-
- (?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)
- <= | # relational left-to-right both
- >= | # relational left-to-right both
- < | # relational left-to-right both
- > # relational left-to-right both
- scope: keyword.operator.relational.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
+ - 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: true
- inherited-class-expression-end:
- - match: '{{dot_accessor}}'
- scope: punctuation.accessor.js
- push:
- - include: inherited-class-name
- - include: object-property
+ - match: ({{dec_integer}})(n|(?!\.)){{identifier_break}}
+ scope: meta.number.integer.decimal.js
+ captures:
+ 1: constant.numeric.value.js
+ 2: constant.numeric.suffix.js
+ pop: true
- - include: left-expression-end
+ # illegal numbers
+ - match: 0[Xx]{{identifier_part}}+
+ scope: invalid.illegal.numeric.hexadecimal.js
+ pop: true
- call-method-meta:
- - meta_include_prototype: false
- - meta_scope: meta.function-call.method.js
- - include: else-pop
+ - match: 0[Bb]{{identifier_part}}+
+ scope: invalid.illegal.numeric.binary.js
+ pop: true
- switch-meta:
+ - match: 0{{identifier_part}}+
+ scope: invalid.illegal.numeric.octal.js
+ pop: true
+
+ - match: '[1-9]{{identifier_part}}+(?:\.{{identifier_part}}*)?'
+ scope: invalid.illegal.numeric.decimal.js
+ pop: true
+
+ object-literal:
+ - match: \{
+ scope: punctuation.section.block.begin.js
+ set: object-literal-contents
+
+ conditional-meta:
- meta_include_prototype: false
- - meta_scope: meta.switch.js
+ - meta_scope: meta.conditional.js
- include: immediately-pop
- import-string-or-items:
- - include: literal-string
- - match: (?=\S)
+ variable-declaration:
+ - match: (?:const|let|var){{identifier_break}}
+ scope: keyword.declaration.js
set:
- - import-export-from
- - import-list
+ - expect-semicolon
+ - variable-binding-list-top
+ - variable-binding-top
+
+ export-list:
+ - match: ','
+ scope: punctuation.separator.comma.js
+ push:
- import-export-alias
- - import-item
+ - export-item
+ - include: else-pop
- flow-type-meta:
- - meta_scope: meta.flow-type.js
+ for-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.for.js
- include: immediately-pop
- literal-string-template-custom-lookahead: []
- expression-end-no-in:
- - match: (?=in{{identifier_break}})
- pop: true
- - include: expression-end
-
- regexp:
- - meta_include_prototype: false
- - meta_scope: meta.string.js string.regexp.js
- - match: /
- scope: punctuation.definition.string.end.js
+ flow-type-declare:
+ - match: declare{{identifier_break}}(?=\s*(?:type|class|function|var|let|const|opaque|export|module){{identifier_break}})
+ scope: keyword.declaration.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: (?=/)
+ - match: opaque{{identifier_break}}
+ scope: storage.modifier.js
pop: true
- - include: scope:source.regexp.js
-
- comments-top-level:
- - match: ^(#!).*$\n?
- scope: comment.line.shebang.js
- captures:
- 1: punctuation.definition.comment.js
+ - match: module{{identifier_break}}
+ scope: keyword.declaration.js
+ set:
+ - flow-type-module-meta
+ - flow-type-module-body
+ - flow-type-module-name
+ - match: export{{identifier_break}}
+ scope: keyword.declaration.js
+ set: flow-type-declare-export
+ - include: else-pop
- arrow-function-expect-body:
- - include: function-block
+ detect-bare-arrow:
+ - match: (?==>)
+ fail: bare-arrow-function
- match: (?=\S)
- set:
- - block-meta
- - expression-no-comma
+ pop: 2
- method-name:
- - match: '{{dollar_identifier}}'
- scope: meta.mapping.key.dollar.js entity.name.function.js
- captures:
- 1: punctuation.dollar.js
- pop: true
- - match: '{{identifier}}'
- scope: entity.name.function.js
- pop: true
- - 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: true
- - match: \n
- scope: invalid.illegal.newline.js
- pop: true
- - include: string-content
- - match: '"'
- scope: punctuation.definition.string.begin.js
+ flow-type-tuple:
+ - match: \[
+ scope: punctuation.section.brackets.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: true
- - match: \n
- scope: invalid.illegal.newline.js
+ - meta_scope: meta.sequence.js
+ - match: \]
+ scope: punctuation.section.brackets.end.js
pop: true
- - include: string-content
-
- - match: (?=\[)
- push: computed-property-name
+ - include: flow-type-list
+ variable-binding-list:
+ - include: comma-separator
+ - match: (?={{binding_pattern_lookahead}})
+ push:
+ - initializer
+ - variable-binding-pattern
- include: else-pop
- support-property-node-module:
- - match: (?:children|exports|filename|id|loaded|parent|paths){{identifier_break}}
- scope: support.constant.node.js
- pop: true
- - match: require{{identifier_break}}
- scope: support.function.node.js
+ flow-type-existential:
+ - match: \*
+ scope: constant.language.type.existential.js
pop: true
- flow-type-pragma:
- - match: (//)\s*(?=@)
- scope: comment.line.double-slash.pragma.js
- captures:
- 1: punctuation.definition.comment.js
- push:
- - meta_include_prototype: false
- - match: (@)(flow)
- captures:
- 1: punctuation.definition.pragma.js
- 2: support.function.pragma.js
- pop: true
- - include: else-pop
-
- class-body:
- - match: \{
- scope: punctuation.section.block.begin.js
- set: class-body-contents
+ expression-no-comma:
+ - meta_include_prototype: false
+ - match: ''
+ set: [expression-end-no-comma, expression-begin]
+ variable-binding-top:
+ - match: (?={{binding_pattern_lookahead}})
+ set:
+ - initializer
+ - variable-binding-pattern
- include: else-pop
- constructor-body-expect-class-end:
- - include: property-access
- - include: else-pop
-
- jsx-tag-name-component:
- - match: '{{jsx_identifier}}'
- scope: entity.name.tag.js
+ flow-type:
+ - match: ''
set:
- - match: '[:.]'
- scope: punctuation.accessor.js
- set: jsx-tag-name
- - include: else-pop
- - include: else-pop
+ - flow-type-end
+ - flow-type-begin
- variable-binding-top:
- - include: function-assignment
- - match: (?={{binding_pattern_lookahead}})
+ class-field:
+ - match: ''
set:
- initializer
- - variable-binding-pattern
- - include: else-pop
-
- function-meta:
- - meta_include_prototype: false
- - meta_scope: meta.function.js
- - include: immediately-pop
+ - flow-type-annotation-optional
+ - class-field-check
+ - field-name
flow-type-object-value:
- match: (\?)?(:)
@@ -945,382 +952,236 @@ contexts:
set: flow-type
- include: else-pop
- do-while-meta:
- - meta_include_prototype: false
- - meta_scope: meta.do-while.js
- - include: immediately-pop
+ for-oldstyle-rest:
+ - match: (?=\))
+ pop: true
+ - match: ;
+ scope: punctuation.separator.expression.js
+ - match: (?=\S)
+ push: expression
- try-meta:
- - meta_include_prototype: false
- - meta_scope: meta.try.js
- - include: immediately-pop
+ 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: true
+ - match: (?:isFinite|isInteger|isNaN|isSafeInteger|NaN|parseFloat|parseInt){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
- conditional:
- - match: switch{{identifier_break}}
- scope: keyword.control.conditional.switch.js
- set:
- - switch-meta
- - switch-block
- - expect-parenthesized-expression
+ 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: true
+ - 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: support.function.node.js
+ pop: true
- - match: do{{identifier_break}}
- scope: keyword.control.loop.do-while.js
- set:
- - do-while-meta
- - do-while-condition
- - block-scope
+ switch-block-contents:
+ - meta_scope: meta.block.js
- - match: for{{identifier_break}}
- scope: keyword.control.loop.for.js
- set:
- - for-meta
- - block-scope
- - for-condition
- - for-await
+ - match: \}
+ scope: punctuation.section.block.end.js
+ pop: true
- - match: while{{identifier_break}}
- scope: keyword.control.loop.while.js
- set:
- - while-meta
- - block-scope
- - expect-parenthesized-expression
+ - match: case{{identifier_break}}
+ scope: keyword.control.conditional.case.js
+ push:
+ - expect-case-colon
+ - expression
- - match: with{{identifier_break}}
- scope: keyword.control.import.with.js
- set:
- - with-meta
- - block-scope
- - expect-parenthesized-expression
+ - match: default{{identifier_break}}
+ scope: keyword.control.conditional.default.js
+ push:
+ - expect-case-colon
- - match: if{{identifier_break}}
- scope: keyword.control.conditional.if.js
- set:
- - conditional-meta
- - block-scope
- - expect-parenthesized-expression
+ - include: statements
- - match: else\s+if{{identifier_break}}
- scope: keyword.control.conditional.elseif.js
- set:
- - conditional-meta
- - block-scope
- - expect-parenthesized-expression
+ support-property-ecma-promise:
+ - match: (?:all|race|reject|resolve|allSettled|any){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
- - match: else{{identifier_break}}
- scope: keyword.control.conditional.else.js
- set:
- - conditional-meta
- - block-scope
+ class-body-contents:
+ - meta_scope: meta.block.js
- - match: try{{identifier_break}}
- scope: keyword.control.exception.try.js
- set:
- - try-meta
- - block-scope
+ - match: \}
+ scope: punctuation.section.block.end.js
+ pop: true
- - match: finally{{identifier_break}}
- scope: keyword.control.exception.finally.js
- set:
- - finally-meta
- - block-scope
+ - match: \;
+ scope: punctuation.terminator.statement.js
- - match: catch{{identifier_break}}
- scope: keyword.control.exception.catch.js
- set:
- - catch-meta
- - block-scope
- - expect-parenthesized-expression
+ - include: decorator
- function-name-meta:
+ - match: constructor{{identifier_break}}
+ scope: entity.name.function.constructor.js
+ push:
+ - function-meta
+ - function-declaration-expect-body
+ - function-declaration-expect-parameters
+
+ - include: class-element-modifiers
+
+ - match: |-
+ (?x)(?=
+ \#? {{identifier_name}}
+ \s* = \s*
+ {{either_func_lookahead}}
+ )
+ push:
+ - initializer
+ - function-name-meta
+ - literal-variable-base
+
+ - match: (?=(?:get|set|async){{identifier_break}})
+ branch_point: prefixed-method
+ branch:
+ - prefixed-method
+ - class-element
+
+ - match: (?=\*)
+ push: method-declaration
+
+ - match: (?={{class_element_name}})
+ push: class-element
+
+ regular-function:
+ - match: (?={{func_lookahead}})
+ set: function-declaration
+
+ class-name:
+ - match: '{{non_reserved_identifier}}'
+ scope: entity.name.class.js
+ set: flow-type-generic-parameters
+ - include: else-pop
+
+ switch-meta:
- meta_include_prototype: false
- - meta_scope: entity.name.function.js
+ - meta_scope: meta.switch.js
- include: immediately-pop
- flow-type-generic-parameters:
- - match: <
- scope: punctuation.section.generic.begin.js
+ object-property:
+ - include: support-property
+
+ - match: (?=\#?{{identifier_name}}{{function_assignment_lookahead}})
set:
- - meta_scope: meta.generic.declaration.js
- - match: '>'
- scope: punctuation.section.generic.end.js
- pop: true
- - include: comma-separator
- - match: \+
- scope: storage.modifier.variance.js
- - match: '{{identifier}}'
- scope: variable.parameter.type.js
- push:
- - - match: '='
- scope: keyword.operator.assignment.js
- set: flow-type
- - include: else-pop
- - flow-type-annotation
+ - function-name-meta
+ - object-property-base
+
+ - match: (?=#?{{identifier_name}}\s*(?:{{dot_accessor}})?\()
+ set: call-method-name
+
+ - include: object-property-base
- include: else-pop
- function-parameter-binding-spread:
- - match: \.\.\.
- scope: keyword.operator.spread.js
- push: function-parameter-binding-pattern
+ comments-top-level:
+ - match: ^(#!).*$\n?
+ scope: comment.line.shebang.js
+ captures:
+ 1: punctuation.definition.comment.js
- expression-break:
- - match: (?=[;})\]])
+ expression-end-no-in:
+ - match: (?=in{{identifier_break}})
pop: true
+ - include: expression-end
- comma-separator:
- - match: ','
- scope: punctuation.separator.comma.js
-
- variable-binding-list-top:
- - match: '{{line_ending_ahead}}'
- set:
- - match: '{{line_continuation_lookahead}}'
- set: variable-binding-top
- - include: else-pop
- - match: ','
- scope: punctuation.separator.comma.js
- push: variable-binding-top
+ expect-semicolon:
+ - match: \;
+ scope: punctuation.terminator.statement.js
+ pop: true
- include: else-pop
jsx-interpolation:
- - match: '{'
- scope: punctuation.definition.interpolation.begin.js
- push:
- - - meta_scope: meta.interpolation.js
- - meta_content_scope: source.js.embedded.jsx
- - match: '}'
- scope: punctuation.definition.interpolation.end.js
- pop: true
- - expression
-
- flow-type-special:
- - match: any{{identifier_break}}
- scope: support.type.any.js
- pop: true
+ - match: (?={/\*)
+ branch_point: jsx-interpolation-comment
+ branch:
+ - jsx-interpolation-comment
+ - jsx-interpolation-plain
+ - match: (?={)
+ push: jsx-interpolation-plain
- - match: mixed{{identifier_break}}
- scope: support.type.mixed.js
- pop: true
+ switch-block:
+ - match: \{
+ scope: punctuation.section.block.begin.js
+ set: switch-block-contents
+ - include: else-pop
- variable-declaration:
- - match: (?:const|let|var){{identifier_break}}
- scope: storage.type.js
- set:
- - expect-semicolon
- - variable-binding-list-top
- - variable-binding-top
+ decorator-expression-begin:
+ - include: decorator-name
+ - include: expression-begin
- flow-type-function:
- - match: \(
- scope: punctuation.section.grouping.begin.js
+ literal-string-template-custom-tags: []
+ arrow-function-expect-body:
+ - include: function-block
+ - match: (?=\S)
set:
- - meta_scope: meta.group.js
- - match: \)
- scope: punctuation.section.grouping.end.js
- pop: true
- - include: flow-type-list
-
- flow-type-class:
- - match: '{{identifier}}'
- scope: variable.other.class.js
- pop: true
+ - block-meta
+ - expression-no-comma
- styled-components:
- - match: (?=(?:styled|css|createGlobalStyle|injectGlobal|keyframes){{identifier_break}})
- set:
- - styled-component-end
- - styled-component-begin
- support-property-ecma-arraybuffer:
- - match: isView{{identifier_break}}
+ support-property-ecma-reflect:
+ - match: (?:apply|construct|defineProperty|deleteProperty|get|getOwnPropertyDescriptor|getPrototypeOf|has|isExtensible|ownKeys|preventExtensions|set|setPrototypeOf){{identifier_break}}
scope: support.function.builtin.js
pop: true
- object-literal-meta-key:
- - meta_scope: meta.mapping.key.js
- - include: else-pop
+ flow-type-meta:
+ - meta_scope: meta.flow-type.js
+ - include: immediately-pop
- expression-statement-end:
- - match: '{{line_ending_ahead}}'
- set:
- - match: '{{line_continuation_lookahead}}'
- set: expression-statement-end
+ flow-type-pragma:
+ - match: (//)\s*(?=@)
+ scope: comment.line.double-slash.pragma.js
+ captures:
+ 1: punctuation.definition.comment.js
+ push:
+ - meta_include_prototype: false
+ - match: (@)(flow)
+ captures:
+ 1: punctuation.definition.pragma.js
+ 2: support.function.pragma.js
+ pop: true
- include: else-pop
- - include: expression-end
- import-export-from:
- - match: from{{identifier_break}}
- scope: keyword.control.import-export.js
- set: literal-string
+ call-function-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.function-call.js
- include: else-pop
- function-declaration-parameters:
- - match: \(
- scope: punctuation.section.group.begin.js
+ jsx-tag-name:
+ - match: ''
set:
- - match: \)
- scope: punctuation.section.group.end.js
- pop: true
- - include: function-parameter-binding-list
-
- styled-component-end:
- - match: \.
- scope: punctuation.accessor.dot.js
- push: styled-component-begin
+ - - clear_scopes: 1
+ - meta_scope: meta.tag.name.js
+ - include: immediately-pop
+ - jsx-tag-name-component
- - match: (?=`)
+ styled-components:
+ - match: (?=(?:styled|css|createGlobalStyle|injectGlobal|keyframes){{identifier_break}})
set:
- - match: '`'
- scope: punctuation.definition.string.begin.js
- push:
- - - meta_include_prototype: false
- - meta_scope: meta.string.js string.quoted.other.js
- - match: '`'
- scope: punctuation.definition.string.end.js
- pop: true
- - include: immediately-pop
- - - clear_scopes: 1
- - include: immediately-pop
- - - match: ''
- set: scope:source.js.css
- with_prototype:
- - match: (?=`)
- pop: true
- - match: \$\{
- scope: punctuation.section.interpolation.begin.js
- push:
- - clear_scopes: 1
- - meta_scope: meta.interpolation.js
- - meta_content_scope: source.js.embedded.expression
- - match: \}
- scope: punctuation.section.interpolation.end.js
- pop: true
- - match: (?=\S)
- push: expression
- - include: string-content
- - include: else-pop
- - include: expression-end
-
- expect-semicolon:
- - match: \;
- scope: punctuation.terminator.statement.js
- pop: true
- - include: else-pop
-
- support-property-ecma-json:
- - match: (?:parse|stringify){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
-
- import-brace:
- - include: flow-type-import-type
-
- - meta_scope: meta.block.js
- - include: comma-separator
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
- push: import-export-alias
- - match: \*
- scope: constant.other.js
- push: import-export-alias
- - include: else-pop
-
- support:
- - include: support-variable-ecma
- - include: support-variable-console
- - include: support-variable-dom
- - include: support-variable-node
-
- class-name:
- - match: '{{non_reserved_identifier}}'
- scope: entity.name.class.js
- set: flow-type-generic-parameters
- - include: else-pop
-
- variable-binding-object-destructuring:
- - match: \{
+ - styled-component-end
+ - styled-component-begin
+ flow-type-object:
+ - match: \{\|
scope: punctuation.section.block.begin.js
set:
- - meta_scope: meta.binding.destructuring.mapping.js
- - match: \}
+ - meta_scope: meta.type.object.exact.js
+ - match: \|\}
scope: punctuation.section.block.end.js
pop: true
- - include: variable-binding-spread
- - match: (?={{identifier}}|\[|'|")
- push:
- - initializer
- - variable-binding-object-alias
- - object-literal-meta-key
- - variable-binding-object-key
- - include: comma-separator
-
- function-declaration-meta-no-clear:
- - meta_include_prototype: false
- - meta_scope: meta.function.declaration.js
- - include: immediately-pop
-
- field-initializer-or-method-declaration:
- - match: (?=\()
- set:
- - function-meta
- - function-declaration-expect-body
- - function-declaration-meta
- - function-declaration-expect-parameters
- - match: (?=\S)
- set:
- - class-field-rest
- - initializer
-
- function-parameter-binding-array-destructuring:
- - match: \[
- scope: punctuation.section.brackets.begin.js
- set:
- - meta_scope: meta.binding.destructuring.sequence.js
- - match: \]
- scope: punctuation.section.brackets.end.js
- pop: true
- - include: function-parameter-binding-list
+ - include: flow-type-object-contents
- import-export-alias:
- - match: as{{identifier_break}}
- scope: keyword.control.import-export.js
+ - match: \{
+ scope: punctuation.section.block.begin.js
set:
- - match: default{{identifier_break}}
- scope: keyword.control.import-export.js
- pop: true
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
+ - meta_scope: meta.type.object.js
+ - match: \}
+ scope: punctuation.section.block.end.js
pop: true
- - include: else-pop
- - include: else-pop
-
- decorator-expression-end:
- - match: '{{dot_accessor}}'
- scope: punctuation.accessor.js
- push:
- - include: decorator-name
- - include: object-property
-
- - include: left-expression-end
-
- for-oldstyle-rest:
- - match: (?=\))
- pop: true
- - match: ;
- scope: punctuation.separator.expression.js
- - match: (?=\S)
- push: expression
+ - include: flow-type-object-contents
- switch-block:
- - match: \{
- scope: punctuation.section.block.begin.js
- set: switch-block-contents
+ constructor-body-expect-class-end:
+ - include: property-access
- include: else-pop
- support-property:
- - include: support-property-ecma
-
jsx-body:
- meta_include_prototype: false
@@ -1343,319 +1204,244 @@ contexts:
- include: jsx-html-escapes
- include: jsx-interpolation
- function-declaration-expect-generator-star:
- - match: \*
- scope: keyword.generator.asterisk.js
- pop: true
- - include: else-pop
-
- comments:
- - include: flow-type-pragma
+ import-statement:
+ - match: import{{identifier_break}}
+ scope: keyword.control.import-export.js
+ set:
+ - import-meta
+ - expect-semicolon
+ - import-string-or-items
+ - import-check-branch
- - match: /\*\*(?!/)
- scope: punctuation.definition.comment.begin.js
- push:
- - meta_include_prototype: false
- - meta_scope: comment.block.documentation.js
- - match: \*/
- scope: punctuation.definition.comment.end.js
- pop: true
- - match: ^\s*(\*)(?!/)
- captures:
- 1: punctuation.definition.comment.js
- - match: /\*
- scope: punctuation.definition.comment.begin.js
- push:
- - meta_include_prototype: false
- - meta_scope: comment.block.js
- - match: \*/
- scope: punctuation.definition.comment.end.js
- pop: true
- - match: //
- scope: punctuation.definition.comment.js
- push:
- - meta_include_prototype: false
- - meta_scope: comment.line.double-slash.js
- - match: \n
- pop: true
+ 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
- function-declaration-expect-function-keyword:
- - match: function{{identifier_break}}
- scope: storage.type.function.js
- pop: true
+ jsx-tag-name-component:
+ - match: '{{jsx_identifier}}'
+ scope: entity.name.tag.js
+ set:
+ - match: '[:.]'
+ scope: punctuation.accessor.js
+ set: jsx-tag-name
+ - include: else-pop
- include: else-pop
- with-meta:
+ expression:
- meta_include_prototype: false
- - meta_scope: meta.with.js
- - include: immediately-pop
-
- function-declaration-expect-parameters:
- - include: function-declaration-parameters
- - include: else-pop
+ - match: ''
+ set: [expression-end, expression-begin]
- object-literal-expect-colon:
- - match: ':'
- scope: punctuation.separator.key-value.js
- - include: else-pop
+ array-literal:
+ - match: \[
+ scope: punctuation.section.brackets.begin.js
+ set:
+ - meta_scope: meta.sequence.js
+ - match: \]
+ scope: punctuation.section.brackets.end.js
+ pop: true
+ - include: expression-list
- while-meta:
+ bare-arrow-function-fallback:
- meta_include_prototype: false
- - meta_scope: meta.while.js
- - include: immediately-pop
-
- inherited-class-expression-begin:
- - include: inherited-class-name
- - include: expression-begin
+ - match: ''
+ push:
+ - immediately-pop-2
+ - arrow-function-declaration
- main:
- - include: comments-top-level
+ export-statement:
+ - match: export{{identifier_break}}
+ scope: keyword.control.import-export.js
+ set:
+ - export-meta
+ - export-extended
- - match: \)|\}|\]
- scope: invalid.illegal.stray-bracket-end.js
- # Don't pop or embedding could break.
+ literal-variable:
+ - include: special-identifier
+ - include: support
- - include: statements
+ - match: (?={{identifier_name}}{{function_assignment_lookahead}})
+ set:
+ - function-name-meta
+ - literal-variable-base
- export-meta:
- - meta_include_prototype: false
- - meta_scope: meta.export.js
- - include: immediately-pop
+ - match: '{{constant_identifier}}(?=\s*(?:{{dot_accessor}}|\[))'
+ scope: support.class.js
+ pop: true
- expression-end:
- - include: postfix-operators
- - include: binary-operators
- - include: ternary-operator
+ - match: '{{function_call_lookahead}}'
+ set: call-function-name
- - include: left-expression-end
+ - include: literal-variable-base
- flow-type-object-indexer-type:
- - match: \]
- scope: punctuation.section.brackets.end.js
- pop: true
- - include: flow-type-list
+ jsdoc-comment:
+ - meta_include_prototype: false
+ - meta_scope: comment.block.documentation.js
+ - match: \*/
+ scope: punctuation.definition.comment.end.js
+ pop: 1
+ # 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
- flow-type-annotation:
- - match: ':'
- scope: punctuation.separator.type.js
+ import-expression-end:
+ - match: (?=\()
+ set: function-call-arguments
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
set:
- - flow-type-meta
- - flow-type
- - match: (?!\s*(?:$|:|//|/\*))
- pop: true
+ - match: meta{{identifier_break}}
+ scope: variable.language.import.js
+ pop: true
+ - include: object-property
+ - include: else-pop
+ function-parameter-binding-object-destructuring:
+ - match: \{
+ scope: punctuation.section.block.begin.js
+ set:
+ - meta_scope: meta.binding.destructuring.mapping.js
+ - match: ','
+ scope: punctuation.separator.parameter.function.js
+ - match: \}
+ scope: punctuation.section.block.end.js
+ pop: true
+ - include: function-parameter-binding-spread
+ - match: (?={{identifier_start}}|\[|'|")
+ push:
+ - initializer
+ - function-parameter-binding-object-alias
+ - object-literal-meta-key
+ - function-parameter-binding-object-key
- restricted-production:
- - meta_include_prototype: false
- - match: '{{line_ending_ahead}}'
+ support-variable-dom:
+ - match: XMLHttpRequest{{identifier_break}}
+ scope: support.class.dom.js
+ pop: true
+ - match: (?:document|window|navigator){{identifier_break}}
+ scope: support.type.object.dom.js
+ pop: true
+ - match: (?:clearTimeout|setTimeout){{identifier_break}}
+ scope: support.function.dom.js
pop: true
- - match: ''
- set: expression-statement
- support-property-ecma-array:
- - match: (?:from|isArray|of){{identifier_break}}
- scope: support.function.builtin.js
+ flow-type-module-name:
+ - include: literal-string
+ - match: '{{non_reserved_identifier}}'
+ scope: entity.name.module.js
pop: true
+ - include: else-pop
- expression-statement:
- - match: (?=\S)
- set:
- - expect-semicolon
- - expression-statement-end
- - expression-begin
+ object-literal-meta-key:
+ - meta_scope: meta.mapping.key.js string.unquoted.js
+ - include: else-pop
- variable-binding-name:
- - match: (?={{non_reserved_identifier}})
+ class-element-modifier:
+ - match: '{{modifier}}'
+ scope: storage.modifier.js
set:
- - meta_scope: meta.binding.name.js
- - include: literal-variable
-
- object-literal-contents:
- - meta_scope: meta.mapping.js
-
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
+ - match: (?={{class_element_name}}|\*)
+ pop: true
+ - match: (?=\S)
+ fail: class-element-modifier
+ 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
- push: expression-no-comma
-
- - match: >-
- (?x)(?=
- {{property_name}}\s*:
- (?: {{either_func_lookahead}} )
- )
- push:
- - either-function-declaration
- - function-declaration-meta-no-clear
- - object-literal-expect-colon
- - object-literal-meta-key
- - method-name
-
- - match: '{{method_lookahead}}'
- push: method-declaration
-
- - match: '{{identifier}}(?=\s*(?:[},]|$|//|/\*))'
- scope: variable.other.readwrite.js
-
- - match: (?=\[)
- push:
- - object-literal-meta-key
- - computed-property-name
-
- - match: (?=\"|')
- push:
- - object-literal-meta-key
- - literal-string
-
- - match: (?=[-+]?(?:\.[0-9]|0[bxo]|\d))
- push:
- - object-literal-meta-key
- - literal-number
-
- # - include: bare-property-name
- - match: (?={{identifier}})
- push:
- - object-literal-meta-key
- - bare-property-name
-
- - include: comma-separator
- - match: ':'
- scope: punctuation.separator.key-value.js
- push: expression-no-comma
+ - match: \+|\-
+ scope: keyword.operator.arithmetic.js
+ - match: (?:delete|typeof|void){{identifier_break}}
+ scope: keyword.operator.js
- # In case we're inside a destructured arrow function parameter that we
- # misidentified as an object literal.
- - match: '='
- scope: keyword.operator.assignment.js
- push: expression-no-comma
+ import-export-from:
+ - match: from{{identifier_break}}
+ scope: keyword.control.import-export.js
+ set: literal-string
+ - include: else-pop
- jsx-tag-attributes-top:
- - meta_scope: meta.tag.js
- - match: /
- scope: punctuation.definition.tag.begin.js
+ ternary-operator:
+ - match: \?(?=[^.]|\.[0-9])
+ scope: keyword.operator.ternary.js
set:
- - - meta_scope: invalid.illegal.unmatched-tag.js
- - include: immediately-pop
- - jsx-expect-tag-end
- - jsx-tag-name
+ - ternary-operator-expect-colon
+ - expression-no-comma
- - match: (?=\S)
- set:
- - jsx-tag-attributes
- - jsx-tag-name
-
- variable-binding-list:
- - include: comma-separator
- - match: (?={{binding_pattern_lookahead}})
- push:
- - initializer
- - variable-binding-pattern
- - include: else-pop
-
- label:
- - match: ({{identifier}})\s*(:)
- captures:
- 1: entity.name.label.js
- 2: punctuation.separator.js
-
- new-target:
- - match: \.
- scope: punctuation.accessor.dot.js
+ import-export-alias:
+ - match: as{{identifier_break}}
+ scope: keyword.control.import-export.js
set:
- - match: target{{identifier_break}}
- scope: variable.language.target.js
+ - match: default{{identifier_break}}
+ scope: keyword.control.import-export.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.other.readwrite.js
pop: true
- include: else-pop
-
- include: else-pop
- statement:
- - include: flow-type-declare
- - include: flow-type-alias
-
- - match: \;
- scope: punctuation.terminator.statement.empty.js
- pop: true
-
- - include: import-export
- - include: conditional
- - include: block
- - include: label
- - include: variable-declaration
-
- - 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: function-or-class-declaration
-
- - include: decorator
-
- - include: expression-statement
-
- variable-binding-array-destructuring:
- - match: \[
- scope: punctuation.section.brackets.begin.js
+ literal-string:
+ - match: "'"
+ scope: punctuation.definition.string.begin.js
set:
- - meta_scope: meta.binding.destructuring.sequence.js
- - match: \]
- scope: punctuation.section.brackets.end.js
+ - meta_include_prototype: false
+ - meta_scope: meta.string.js string.quoted.single.js
+ - match: \'
+ scope: punctuation.definition.string.end.js
pop: true
- - include: variable-binding-spread
- - include: variable-binding-list
-
- builtin-console-properties:
- - match: (?:warn|info|log|error|time|timeEnd|assert|count|dir|group|groupCollapsed|groupEnd|profile|profileEnd|table|trace|timeStamp){{identifier_break}}
- scope: support.function.console.js
- pop: true
- - include: object-property
-
- yield-expression:
- - match: yield{{identifier_break}}
- scope: keyword.control.flow.yield.js
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - include: string-content
+ - match: '"'
+ scope: punctuation.definition.string.begin.js
set:
- - match: $
+ - meta_include_prototype: false
+ - meta_scope: meta.string.js string.quoted.double.js
+ - match: \"
+ scope: punctuation.definition.string.end.js
pop: true
- - match: \*
- scope: keyword.generator.asterisk.js
- set: expression-begin
- - match: (?=\S)
- set: expression-begin
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - include: string-content
- bare-property-name:
- - match: '{{identifier}}'
- scope: string.unquoted.js
- pop: true
- expression:
- - meta_include_prototype: false
+ class-element:
- match: ''
- set: [expression-end, expression-begin]
+ pop: true
+ branch_point: class-field
+ branch:
+ - class-field
+ - method-declaration
- conditional-meta:
- - meta_include_prototype: false
- - meta_scope: meta.conditional.js
- - include: immediately-pop
+ method-declaration:
+ - match: ''
+ set:
+ - function-meta
+ - function-declaration-expect-body
+ - flow-type-annotation
+ - function-declaration-expect-parameters
+ - flow-type-generic-parameters
+ - method-name
+ - method-declaration-expect-asterisk
jsx-attribute-value:
- include: jsx-tag
@@ -1682,714 +1468,1231 @@ contexts:
- include: else-pop
- call-function-meta:
- - meta_include_prototype: false
- - meta_scope: meta.function-call.js
- - include: else-pop
-
- function-parameter-binding-object-alias:
- - match: ':'
- scope: punctuation.separator.key-value.js
- set: function-parameter-binding-pattern
+ function-declaration-expect-name:
+ - match: '{{non_reserved_identifier}}'
+ scope: entity.name.function.js
+ pop: true
- include: else-pop
- literal-string-template-custom-tags: []
- function-parameter-binding-list:
- - match: ','
- scope: punctuation.separator.parameter.function.js
- - include: function-parameter-binding-spread
- - match: (?={{binding_pattern_lookahead}})
- push:
- - initializer
- - function-parameter-binding-pattern
- - include: else-pop
+ yield-expression:
+ - match: yield{{identifier_break}}
+ scope: keyword.control.flow.yield.js
+ set:
+ - match: $
+ pop: true
+ - match: \*
+ scope: keyword.generator.asterisk.js
+ set: expression-begin
+ - match: (?=\S)
+ set: expression-begin
- arrow-function-declaration:
- - meta_include_prototype: false
- - match: ''
+ async-arrow-function:
+ - match: async{{identifier_break}}
+ scope: keyword.declaration.async.js
set:
- function-meta
- arrow-function-expect-body
- - function-declaration-meta
- - arrow-function-expect-arrow
+ - arrow-function-expect-arrow-or-fail-async
- arrow-function-expect-parameters
- - function-declaration-expect-async
-
- function-call-arguments:
- - match: (\.\?)?(\()
- captures:
- 1: punctuation.accessor.js
- 2: punctuation.section.group.begin.js
- set:
- - meta_scope: meta.group.js
- - match: \)
- scope: punctuation.section.group.end.js
- pop: true
- - include: expression-list
- export-list:
- - match: ','
- scope: punctuation.separator.comma.js
- push:
- - import-export-alias
- - export-item
- - include: else-pop
+ support-property-ecma-bigint:
+ - match: (?:asUintN|asIntN){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
- constructor-body-expect-arguments:
- - include: function-call-arguments
+ variable-binding-object-alias:
+ - match: ':'
+ scope: punctuation.separator.key-value.js
+ set: variable-binding-pattern
- include: else-pop
- fallthrough:
- # If an arrow function has the ( and ) on different lines, we won't have matched
- - match: =>
- scope: storage.type.function.arrow.js
- push:
- - function-meta
- - arrow-function-expect-body
-
- function-declaration-identifiers-expect-class:
- - match: prototype{{identifier_break}}
- scope: support.constant.prototype.js
- pop: true
- - include: language-identifiers
- - match: '{{dollar_only_identifier}}'
- scope: support.class.dollar.only.js punctuation.dollar.js
- pop: true
- - match: '{{dollar_identifier}}'
- scope: support.class.dollar.js
- captures:
- 1: punctuation.dollar.js
- pop: true
- - match: '{{identifier}}'
- scope: support.class.js
+ statements:
+ - match: \)|\}|\]
+ scope: invalid.illegal.stray-bracket-end.js
pop: true
- - include: else-pop
- import-item:
- - include: flow-type-import-type
+ - match: (?=\S)
+ push: statement
- - match: \{
- scope: punctuation.section.block.begin.js
- set: import-brace
- - match: '{{non_reserved_identifier}}'
- scope: variable.other.readwrite.js
+ export-brace:
+ - meta_scope: meta.block.js
+ - include: comma-separator
+ - match: \}
+ scope: punctuation.section.block.end.js
pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.other.readwrite.js
+ push: import-export-alias
- match: \*
scope: constant.other.js
- pop: true
+ push: import-export-alias
- include: else-pop
- flow-type-typeof:
- - match: typeof{{identifier_break}}
- scope: keyword.operator.js
- set:
- - left-expression-end
- - expression-begin
+ block-scope:
+ - include: block
+ - include: else-pop
- function-parameter-binding-object-destructuring:
- - match: \{
- scope: punctuation.section.block.begin.js
- set:
- - meta_scope: meta.binding.destructuring.mapping.js
- - match: ','
- scope: punctuation.separator.parameter.function.js
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
- - include: function-parameter-binding-spread
- - match: (?={{identifier}}|\[|'|")
- push:
- - initializer
- - function-parameter-binding-object-alias
- - object-literal-meta-key
- - function-parameter-binding-object-key
-
- block-meta:
- - meta_include_prototype: false
- - meta_scope: meta.block.js
- - include: immediately-pop
-
- function-declaration-meta:
- - meta_include_prototype: false
- - meta_scope: meta.function.declaration.js
- - clear_scopes: 1
- - include: immediately-pop
-
- method-declaration-expect-prefix:
- - match: \*
- scope: keyword.generator.asterisk.js
- - match: (?:get|set){{identifier_break}}(?!\s*\()
- scope: storage.type.accessor.js
- - include: else-pop
-
- support-variable-console:
- # https://console.spec.whatwg.org/
- - match: console{{identifier_break}}
- scope: support.type.object.console.js
+ 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
- flow-type-object-contents:
- - include: comma-separator
- - match: ;
- scope: punctuation.separator.semicolon.js
- - match: '{{method_lookahead}}'
- push: method-declaration
- - match: \+
- scope: storage.modifier.variance.js
- - match: '{{identifier}}'
- scope: meta.object-literal.key.js
- push: flow-type-object-value
- - match: \[
- scope: punctuation.section.brackets.begin.js
- push:
- - flow-type-object-value
- - flow-type-object-indexer-type
- - flow-type-object-indexer-label
+ call-method-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.function-call.method.js
+ - include: else-pop
- expression-begin:
- - match: (?=`)
+ literal-call:
+ - match: (?={{identifier_name}}\s*(?:{{dot_accessor}})?\()
set:
- - include: literal-string-template-custom-comments
- - include: literal-string-template-custom-lookahead
- - include: literal-string-template
-
- - include: jsx-tag
-
- - include: expression-break
-
- - include: yield-expression
- - include: await-expression
+ - call-function-meta
+ - function-call-arguments
+ - literal-variable
- - include: regexp-complete
- - include: literal-string
- - include: tagged-template
- - include: literal-string-template
- - include: constructor
- - include: literal-number
- - include: prefix-operators
- - include: import-meta-expression
+ - match: (?={{identifier_name}}\s*(?:{{dot_accessor}}\s*#?{{identifier_name}}\s*)+(?:{{dot_accessor}})?\()
+ set:
+ - call-method-meta
+ - function-call-arguments
+ - call-path
+ - literal-variable
- - include: class
- - include: constants
- - include: function-assignment
- - include: either-function-declaration
- - include: object-literal
+ prefixed-object-literal-method:
+ - match: (?:get|set){{identifier_break}}
+ scope: storage.type.accessor.js
+ set:
+ - meta_scope: meta.function.js
+ - match: (?={{class_element_name}})
+ set: method-declaration
+ - match: (?=\S)
+ fail: prefixed-object-literal-method
+ - match: (?:async){{identifier_break}}
+ scope: keyword.declaration.async.js
+ set:
+ - meta_scope: meta.function.js
+ - match: (?=\*|{{class_element_name}})
+ set: method-declaration
+ - match: (?=\S)
+ fail: prefixed-object-literal-method
- - include: parenthesized-expression
- - include: array-literal
+ inherited-class-name:
+ - match: '{{non_reserved_identifier}}{{left_expression_end_lookahead}}'
+ scope: entity.other.inherited-class.js
+ pop: true
- - include: literal-call
- - include: literal-variable
+ import-check-branch:
+ - match: (?=[.(]) # Recovery for import expressions
+ fail: import-statement
+ - include: else-pop
+ arrow-function-expect-arrow:
+ - match: =>
+ scope: keyword.declaration.function.arrow.js
+ pop: true
- include: else-pop
- flow-type-begin:
- - include: flow-type-existential
- - include: flow-type-literal
- - include: flow-type-special
- - include: flow-type-primitive
- - include: flow-type-utility
- - include: flow-type-typeof
- - include: flow-type-class
- - include: flow-type-function
- - include: flow-type-tuple
- - include: flow-type-object
+ 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: true
+ - match: '{{dollar_identifier}}'
+ scope: variable.type.dollar.js
+ captures:
+ 1: punctuation.dollar.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.type.js
+ pop: true
+ - include: else-pop
- - include: else-pop
+ - include: expression-begin
- flow-type-object-indexer-label:
- - match: ({{identifier}})\s*(:)
- captures:
- 1: meta.object-literal.key.js
- 2: punctuation.separator.key-value.js
+ styled-component-begin:
+ - match: '{{non_reserved_identifier}}(?=\s*\()'
+ scope: variable.function.js
pop: true
- - include: else-pop
- function-parameter-binding-object-key:
- - match: '{{identifier}}(?=\s*:)'
+ - match: '{{non_reserved_identifier}}(?=\s*`)'
+ scope: variable.function.tagged-template.js
pop: true
- - include: literal-string
- - include: computed-property-name
- - include: function-parameter-binding-name
- - include: else-pop
- expression-list:
- - include: expression-break
- - include: comma-separator
- - match: (?=\S)
- push: expression-no-comma
+ - match: '{{non_reserved_identifier}}'
+ scope: variable.other.readwrite.js
+ pop: true
- method-declaration:
- - match: ''
- set:
- - function-meta
- - function-declaration-expect-body
- - function-declaration-meta
- - flow-type-annotation
- - function-declaration-expect-parameters
- - flow-type-generic-parameters
- - method-name
- - method-declaration-expect-prefix
- - function-declaration-expect-async
+ - include: else-pop
+ decorator:
+ - match: '@'
+ scope: punctuation.definition.annotation.js
+ push:
+ - decorator-meta
+ - decorator-expression-end
+ - decorator-expression-begin
- literal-string-template:
- - match: '`'
- scope: punctuation.definition.string.begin.js
+ flow-type-generic-arguments:
+ - match: <
+ scope: punctuation.section.generic.begin.js
set:
- - meta_include_prototype: false
- - meta_scope: meta.string.js string.quoted.other.js
- - match: '`'
- scope: punctuation.definition.string.end.js
+ - meta_scope: meta.generic.js
+ - match: '>'
+ scope: punctuation.section.generic.end.js
pop: true
- - match: \$\{
- scope: punctuation.section.interpolation.begin.js
- push:
- - clear_scopes: 1
- - meta_scope: meta.interpolation.js
- - meta_content_scope: source.js.embedded
- - match: \}
- scope: punctuation.section.interpolation.end.js
- pop: true
- - match: (?=\S)
- push: expression
- - include: string-content
+ - include: flow-type-list
+ - include: else-pop
- switch-block-contents:
- - meta_scope: meta.block.js
+ prefixed-method:
+ - match: (?:get|set){{identifier_break}}
+ scope: storage.type.accessor.js
+ set:
+ - meta_scope: meta.function.js
+ - match: (?={{class_element_name}})
+ set: method-declaration
+ - match: (?=\S)
+ fail: prefixed-method
+ - match: (?:async){{identifier_break}}
+ scope: keyword.declaration.async.js
+ set:
+ - meta_scope: meta.function.js
+ - match: (?=\*|{{class_element_name}})
+ set: method-declaration
+ - match: (?=\S)
+ fail: prefixed-method
- - match: \}
- scope: punctuation.section.block.end.js
+ expression-end-no-comma:
+ - match: (?=,)
pop: true
+ - include: expression-end
- - match: case{{identifier_break}}
- scope: keyword.control.conditional.case.js
- push:
- - expect-case-colon
- - expression
+ support:
+ - include: support-variable-ecma
+ - include: support-variable-console
+ - include: support-variable-dom
+ - include: support-variable-node
- - match: default{{identifier_break}}
- scope: keyword.control.conditional.default.js
- push:
- - expect-case-colon
+ literal-string-template-custom-comments: []
+ export-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.export.js
+ - include: immediately-pop
- - include: statements
+ jsx-tag-attributes:
+ - meta_scope: meta.tag.attributes.js
- flow-type-alias:
- - match: (?=type{{identifier_break}})
- set:
- - - match: (?={{identifier}})
- set:
- - - meta_scope: meta.declaration.type.js
- - match: ''
- pop: true
- - flow-type-alias-initializer
- - flow-type-generic-parameters
- - - match: '{{identifier}}'
- scope: entity.name.type.js
- pop: true
- - - include: else-pop
+ - match: '>'
+ scope: punctuation.definition.tag.end.js
+ set: jsx-body
- - match: (?=\S)
- set: [expression-statement, expression-end]
- - - match: type{{identifier_break}}(?=\s*(?:$|{{identifier}}))
- scope: storage.type.js
- set:
- - meta_scope: meta.declaration.type.js
- - include: else-pop
- - include: expression-begin
+ - match: /
+ scope: punctuation.definition.tag.end.js
+ set: jsx-expect-tag-end
- ternary-operator-expect-colon:
- - match: ':'
- scope: keyword.operator.ternary.js
- set: expression-no-comma
- - include: else-pop
+ - include: jsx-interpolation
- array-literal:
- - match: \[
- scope: punctuation.section.brackets.begin.js
+ - match: '{{jsx_identifier}}'
+ scope: entity.other.attribute-name.js
+
+ - match: '='
+ scope: punctuation.separator.key-value.js
+ push: jsx-attribute-value
+
+ variable-binding-object-destructuring:
+ - match: \{
+ scope: punctuation.section.block.begin.js
set:
- - meta_scope: meta.sequence.js
- - match: \]
- scope: punctuation.section.brackets.end.js
+ - meta_scope: meta.binding.destructuring.mapping.js
+ - match: \}
+ scope: punctuation.section.block.end.js
pop: true
- - include: expression-list
+ - include: variable-binding-spread
+ - match: (?={{identifier_start}}|\[|'|")
+ push:
+ - initializer
+ - variable-binding-object-alias
+ - object-literal-meta-key
+ - variable-binding-object-key
+ - include: comma-separator
- export-brace:
- - meta_scope: meta.block.js
- - include: comma-separator
- - match: \}
- scope: punctuation.section.block.end.js
+ flow-type-utility:
+ - match: |-
+ (?x) (?:
+ Class|Function|
+ \$(?:
+ Keys|Values|ReadOnly|Exact|Diff|Rest|PropertyType|ElementType|
+ ObjMap|TupleMap|Call|Supertype|Subtype
+ )
+ ){{identifier_break}}
+ scope: support.type.utility.js
pop: true
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
- push: import-export-alias
- - match: \*
- scope: constant.other.js
- push: import-export-alias
+
+ flow-type-annotation:
+ - match: ':'
+ scope: punctuation.separator.type.js
+ set:
+ - flow-type-meta
+ - flow-type
+ - match: (?!\s*(?:$|:|//|/\*))
+ pop: true
+
+ class-field-check:
+ - match: (?=\()
+ fail: class-field
- include: else-pop
- flow-type-export-type:
- - match: type{{identifier_break}}(?=\s*\{)
- scope: storage.type.js
- set: export-item
- - include: flow-type-alias
+ expression-statement-end:
+ - match: '{{line_ending_ahead}}'
+ set:
+ - match: '{{line_continuation_lookahead}}'
+ set: expression-statement-end
+ - include: else-pop
+ - include: expression-end
- function-declaration-expect-name:
- - match: '{{non_reserved_identifier}}'
- scope: entity.name.function.js
+ support-property-ecma:
+ - match: constructor{{identifier_break}}
+ scope: variable.language.constructor.js
+ pop: true
+ - match: prototype{{identifier_break}}
+ scope: support.constant.prototype.js
pop: true
- - include: else-pop
- function-declaration-expect-body:
- - include: function-block
- - include: else-pop
+ - match: (?:hasOwnProperty|isPrototypeOf|propertyIsEnumerable|toLocaleString|toString|valueOf){{identifier_break}}
+ scope: support.function.js
+ pop: true
- do-while-condition:
- - match: while{{identifier_break}}
- scope: keyword.control.loop.while.js
- set: parenthesized-expression
- - include: else-pop
+ # Annex B
+ - match: __proto__{{identifier_break}}
+ scope: invalid.deprecated.js variable.language.prototype.js
+ pop: true
+ - match: (?:__defineGetter__|__defineSetter__|__lookupGetter__){{identifier_break}}
+ scope: invalid.deprecated.js support.function.js
+ pop: true
- computed-property-name:
+ function-parameter-binding-array-destructuring:
- match: \[
scope: punctuation.section.brackets.begin.js
set:
+ - meta_scope: meta.binding.destructuring.sequence.js
- match: \]
scope: punctuation.section.brackets.end.js
pop: true
- - match: (?=\S)
- push: expression
-
- jsx-meta:
- - meta_scope: meta.jsx.js
- - include: immediately-pop
+ - include: function-parameter-binding-list
- object-literal:
- - match: \{
- scope: punctuation.section.block.begin.js
- set: object-literal-contents
+ 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: true
+ - include: function-declaration-parameters
+ - include: else-pop
- flow-type-primitive:
- - match: boolean{{identifier_break}}
- scope: support.type.primitive.boolean.js
+ call-method-name:
+ - include: support-property
+ - match: '{{identifier_name}}'
+ scope: variable.function.js
pop: true
-
- - match: number{{identifier_break}}
- scope: support.type.primitive.number.js
+ - match: (#){{identifier_name}}
+ scope: variable.function.js
+ captures:
+ 1: punctuation.definition.js
pop: true
+ - include: else-pop
- - match: string{{identifier_break}}
- scope: support.type.primitive.string.js
+ call-function-name:
+ - match: '{{dollar_only_identifier}}'
+ scope: variable.function.js variable.other.dollar.only.js punctuation.dollar.js
pop: true
-
- - match: null{{identifier_break}}
- scope: support.type.primitive.null.js
+ - match: '{{identifier_name}}'
+ scope: variable.function.js
pop: true
+ - include: else-pop
- - match: void{{identifier_break}}
- scope: support.type.primitive.void.js
- pop: true
+ object-property-name:
+ - match: (?=\[)
+ set: computed-property-name
- 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: support.function.builtin.js
- pop: true
+ - include: literal-string
+ - include: literal-number
- flow-type-existential:
- - match: \*
- scope: constant.language.type.existential.js
+ - match: '{{identifier_name}}'
pop: true
- expression-end-no-comma:
- - match: (?=,)
- pop: true
- - include: expression-end
+ - include: else-pop
- literal-variable:
- - include: language-identifiers
- - include: support
+ block-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.block.js
+ - include: immediately-pop
- - match: '{{constant_identifier}}(?=\s*[\[.])'
- scope: support.class.js
- pop: true
+ arrow-function-declaration:
+ - meta_include_prototype: false
+ - match: ''
+ set:
+ - function-meta
+ - arrow-function-expect-body
+ - arrow-function-expect-arrow
+ - arrow-function-expect-parameters
- - match: (?={{identifier}}\s*(?:\.\?)?\()
- set: call-function-name
+ function-declaration:
+ - match: ''
+ set:
+ - function-meta
+ - function-declaration-expect-body
+ - flow-type-annotation
+ - function-declaration-expect-parameters
+ - flow-type-generic-parameters
+ - function-declaration-expect-name
+ - function-declaration-expect-generator-star
+ - function-declaration-expect-function-keyword
+ - function-declaration-expect-async
- - include: literal-variable-base
+ literal-string-template:
+ - match: '`'
+ scope: punctuation.definition.string.begin.js
+ set:
+ - meta_include_prototype: false
+ - meta_scope: meta.string.js string.quoted.other.js
+ - match: '`'
+ scope: punctuation.definition.string.end.js
+ pop: true
+ - match: \$\{
+ scope: punctuation.section.interpolation.begin.js
+ push:
+ - clear_scopes: 1
+ - meta_scope: meta.interpolation.js
+ - meta_content_scope: source.js.embedded
+ - match: \}
+ scope: punctuation.section.interpolation.end.js
+ pop: true
+ - match: (?=\S)
+ push: expression
+ - include: string-content
- arrow-function-expect-parameters:
- - match: '{{identifier}}'
- scope: variable.parameter.function.js
- pop: true
- - include: function-declaration-parameters
+ variable-binding-list-top:
+ - match: '{{line_ending_ahead}}'
+ set:
+ - match: '{{line_continuation_lookahead}}'
+ set: variable-binding-top
+ - include: else-pop
+ - match: ','
+ scope: punctuation.separator.comma.js
+ push: variable-binding-top
- include: else-pop
- else-pop:
+ object-literal-element:
+ - match: '{{identifier_name}}(?=\s*(?:[},]|$|//|/\*))'
+ scope: variable.other.readwrite.js
+ pop: true
- match: (?=\S)
pop: true
+ branch_point: object-literal-property
+ branch:
+ - object-literal-property
+ - method-declaration
- support-property-ecma-symbol:
- - match: (?:asyncIterator|hasInstance|isConcatSpreadable|iterator|match|replace|search|species|split|toPrimitive|toStringTag|unscopeables){{identifier_break}}
- scope: support.constant.builtin.js
- pop: true
- - match: (?:for|keyFor){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
+ conditional:
+ - match: switch{{identifier_break}}
+ scope: keyword.control.conditional.switch.js
+ set:
+ - switch-meta
+ - switch-block
+ - expect-parenthesized-expression
- literal-call:
- - match: (?={{identifier}}\s*(?:\.\?)?\()
+ - match: do{{identifier_break}}
+ scope: keyword.control.loop.do-while.js
set:
- - call-function-meta
- - function-call-arguments
- - literal-variable
+ - do-while-meta
+ - do-while-condition
+ - statement
- - match: (?={{identifier}}\s*(?:\.\s*{{identifier}}\s*)+(?:\.\?)?\()
+ - match: for{{identifier_break}}
+ scope: keyword.control.loop.for.js
set:
- - call-method-meta
- - function-call-arguments
- - call-path
- - literal-variable
+ - for-meta
+ - block-scope
+ - for-condition
+ - for-await
- class:
- - match: class{{identifier_break}}
- scope: storage.type.class.js
+ - match: while{{identifier_break}}
+ scope: keyword.control.loop.while.js
set:
- - class-meta
- - class-body
- - class-extends
- - class-name
+ - while-meta
+ - block-scope
+ - expect-parenthesized-expression
- inherited-class-name:
- - match: '{{non_reserved_identifier}}{{left_expression_end_lookahead}}'
- scope: entity.other.inherited-class.js
- pop: true
+ - match: with{{identifier_break}}
+ scope: keyword.control.import.with.js
+ set:
+ - with-meta
+ - block-scope
+ - expect-parenthesized-expression
- flow-type-alias-initializer:
- - match: '='
- scope: keyword.operator.assignment.js
+ - match: if{{identifier_break}}
+ scope: keyword.control.conditional.if.js
set:
- - flow-type-meta
- - flow-type
- - include: else-pop
- support-variable-node:
- - match: global{{identifier_break}}
- scope: support.type.object.node.js
- pop: true
+ - conditional-meta
+ - statement
+ - expect-parenthesized-expression
- - match: Buffer{{identifier_break}}
- scope: support.class.node.js
- pop: true
+ - match: else\s+if{{identifier_break}}
+ scope: keyword.control.conditional.elseif.js
+ set:
+ - conditional-meta
+ - statement
+ - expect-parenthesized-expression
- - match: process{{identifier_break}}
- scope: support.constant.node.js
+ - match: else{{identifier_break}}
+ scope: keyword.control.conditional.else.js
set:
- - match: '{{dot_accessor}}'
- scope: punctuation.accessor.js
- set:
- - include: support-property-node-process
- - include: object-property
- - include: else-pop
- - include: else-pop
+ - conditional-meta
+ - statement
- # Module-level variables
- - match: (?:__dirname|__filename|exports){{identifier_break}}
- scope: support.constant.node.js
- pop: true
- - match: module{{identifier_break}}
- scope: support.constant.node.js
+ - match: try{{identifier_break}}
+ scope: keyword.control.exception.try.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: support.function.node.js
- pop: true
+ - try-meta
+ - block-scope
- expect-parenthesized-expression:
- - include: parenthesized-expression
- - include: else-pop
+ - match: finally{{identifier_break}}
+ scope: keyword.control.exception.finally.js
+ set:
+ - finally-meta
+ - block-scope
- flow-type-module-name:
- - include: literal-string
- - match: '{{identifier}}'
- scope: entity.name.module.js
- pop: true
- - include: else-pop
+ - match: catch{{identifier_break}}
+ scope: keyword.control.exception.catch.js
+ set:
+ - catch-meta
+ - block-scope
+ - expect-parenthesized-expression
- for-meta:
- - meta_include_prototype: false
- - meta_scope: meta.for.js
- - include: immediately-pop
+ postfix-operators:
+ - match: --
+ scope: keyword.operator.arithmetic.js
+ - match: \+\+
+ scope: keyword.operator.arithmetic.js
- field-name:
- - match: '{{dollar_identifier}}'
- scope: meta.mapping.key.dollar.js variable.other.readwrite.js
- captures:
- 1: punctuation.dollar.js
- pop: true
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
- pop: true
- - 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: true
- - match: \n
- scope: invalid.illegal.newline.js
- pop: true
- - include: string-content
- - match: '"'
- scope: punctuation.definition.string.begin.js
+ block:
+ - match: \{
+ scope: punctuation.section.block.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: true
- - match: \n
- scope: invalid.illegal.newline.js
+ - meta_scope: meta.block.js
+ - match: \}
+ scope: punctuation.section.block.end.js
pop: true
- - include: string-content
- - match: (#)({{identifier}})
- captures:
- 1: punctuation.definition.variable.js
- 2: variable.other.readwrite.js
-
- - match: (?=\[)
- push: computed-property-name
-
- - include: else-pop
+ - include: statements
- object-property-base:
- - match: '{{dollar_only_identifier}}'
- scope: meta.property.object.dollar.only.js punctuation.dollar.js
+ special-name:
+ - match: true{{identifier_break}}
+ scope: constant.language.boolean.true.js
pop: true
- - match: '{{dollar_identifier}}'
- scope: meta.property.object.dollar.js
- captures:
- 1: punctuation.dollar.js
+ - match: false{{identifier_break}}
+ scope: constant.language.boolean.false.js
pop: true
- - match: '{{identifier}}'
- scope: meta.property.object.js
+ - match: null{{identifier_break}}
+ scope: constant.language.null.js
pop: true
- - match: '{{identifier_part}}+{{identifier_break}}'
- scope: invalid.illegal.illegal-identifier.js
+ - match: super{{identifier_break}}
+ scope: variable.language.super.js
pop: true
- - match: (#)({{identifier}})
- captures:
- 1: punctuation.definition.variable.js
- 2: meta.property.object.js
+ - match: this{{identifier_break}}
+ scope: variable.language.this.js
pop: true
- function-initializer:
- - meta_scope: meta.function.declaration.js
- - match: '='
- scope: keyword.operator.assignment.js
- set:
- - meta_content_scope: meta.function.declaration.js
- - include: expression-no-comma
+ flow-type-begin:
+ - include: flow-type-existential
+ - include: flow-type-literal
+ - include: flow-type-special
+ - include: flow-type-primitive
+ - include: flow-type-utility
+ - include: flow-type-typeof
+ - include: flow-type-class
+ - include: flow-type-function
+ - include: flow-type-tuple
+ - include: flow-type-object
- include: else-pop
- flow-type-annotation-optional:
- - match: \?(?=:)
- scope: storage.modifier.optional.js
- - include: flow-type-annotation
-
- flow-type-module-contents:
- - match: \}
- scope: punctuation.section.block.end.js
+ support-property-ecma-json:
+ - match: (?:parse|stringify){{identifier_break}}
+ scope: support.function.builtin.js
pop: true
- - include: main
-
- jsx-html-escapes:
- - match: (&)#?[[:alnum:]]+(;)
- scope: constant.character.escape.js
- captures:
- 1: punctuation.definition.entity.js
- 2: punctuation.definition.entity.js
-
- 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: true
- - match: (?=\S)
- push: expression
-
- - match: \.(?:\?)?
- scope: punctuation.accessor.js
- push:
- - match: (?={{identifier}}\s*(?:\.\?)?\()
- set:
- - call-method-meta
- - function-call-arguments
- - call-path
- - object-property
- - include: object-property
- language-identifiers:
- - match: arguments{{identifier_break}}
- scope: variable.language.arguments.js
- pop: true
- - match: super{{identifier_break}}
- scope: variable.language.super.js
- pop: true
- - match: this{{identifier_break}}
- scope: variable.language.this.js
- pop: true
- - match: globalThis{{identifier_break}}
- scope: variable.language.global.js
+ support-property-ecma-atomics:
+ - match: (?:and|add|compareExchange|exchange|isLockFree|load|or|store|sub|wait|wake|xor){{identifier_break}}
+ scope: support.function.builtin.js
pop: true
- # These three are ordinary variables, not literals!
- - match: undefined{{identifier_break}}
- scope: constant.language.undefined.js
- pop: true
- - match: NaN{{identifier_break}}
- scope: constant.language.nan.js
- pop: true
- - match: Infinity{{identifier_break}}
- scope: constant.language.infinity.js
+ expression-break:
+ - match: (?=[;})\]])
pop: true
- function-declaration-identifiers:
- - match: (?={{identifier}}\s*\.)
- push:
- - expect-dot-accessor
- - function-declaration-identifiers-expect-class
- - match: prototype{{identifier_break}}
- scope: support.constant.prototype.js
+ 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: support.function.builtin.js
pop: true
- - match: (?=#?{{identifier}})
- set:
- - function-name-meta
- - literal-variable-base
- export-item:
+ flow-type-generic-parameters:
+ - match: <
+ scope: punctuation.section.generic.begin.js
+ set:
+ - meta_scope: meta.generic.declaration.js
+ - match: '>'
+ scope: punctuation.section.generic.end.js
+ pop: true
+ - include: comma-separator
+ - match: \+
+ scope: storage.modifier.variance.js
+ - match: '{{non_reserved_identifier}}'
+ scope: variable.parameter.type.js
+ push:
+ - - match: '='
+ scope: keyword.operator.assignment.js
+ set: flow-type
+ - include: else-pop
+ - flow-type-annotation
+ - include: else-pop
+
+ expression-begin:
+ - include: jsx-tag
+
+ - match: (?=`)
+ set:
+ - include: literal-string-template-custom-comments
+ - include: literal-string-template-custom-lookahead
+ - include: literal-string-template
+
+ - include: expression-break
+
+ - include: yield-expression
+ - include: await-expression
+
+ - include: regexp-complete
+ - include: literal-string
+ - include: tagged-template
+ - 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: true
+
+ - 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}}(?:\(|{{identifier_start}}))
+ pop: true
+ branch_point: async-arrow-function
+ branch:
+ - async-arrow-function
+ - literal-variable
+
+ - include: literal-call
+
+ - match: (?={{identifier_start}})
+ pop: true
+ branch_point: bare-arrow-function
+ branch:
+ - branch-possible-bare-arrow-function
+ - bare-arrow-function-fallback
+
+ - match: (?=\()
+ pop: true
+ branch_point: parenthesized-arrow-function
+ branch:
+ - branch-possible-parenthesized-arrow-function
+ - parenthesized-arrow-function-fallback
+
+ - include: array-literal
+
+ - include: literal-private-variable
+
+ - include: else-pop
+
+ support-property-node-module:
+ - match: (?:children|exports|filename|id|loaded|parent|paths){{identifier_break}}
+ scope: support.constant.node.js
+ pop: true
+ - match: require{{identifier_break}}
+ scope: support.function.node.js
+ pop: true
+
+ flow-type-end:
+ - include: flow-type-operators
+ - match: (?=<)
+ push: flow-type-generic-arguments
+ - include: else-pop
+
+ flow-type-annotation-optional:
+ - match: \?(?=:)
+ scope: storage.modifier.optional.js
+ - include: flow-type-annotation
+
+ flow-type-literal:
+ - match: true{{identifier_break}}
+ scope: constant.language.boolean.true.js
+ pop: true
+ - match: false{{identifier_break}}
+ scope: constant.language.boolean.false.js
+ pop: true
+ - match: (?=\d)
+ set:
+ - - match: '{{identifier_part}}+'
+ scope: invalid.illegal.js
+ - include: immediately-pop
+ - literal-number
+ - match: (?=['"])
+ set: literal-string
+
+ function-declaration-expect-async:
+ - match: async{{identifier_break}}
+ scope: keyword.declaration.async.js
+ pop: true
+ - include: else-pop
+
+ jsx-meta:
+ - meta_scope: meta.jsx.js
+ - include: immediately-pop
+
+ function-declaration-expect-body:
+ - include: function-block
+ - include: else-pop
+
+ support-property-ecma-date:
+ - match: (?:now|parse|UTC){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
+
+ object-property-base:
+ - match: '{{dollar_only_identifier}}'
+ scope: meta.property.object.dollar.only.js punctuation.dollar.js
+ pop: true
+ - match: '{{dollar_identifier}}'
+ scope: meta.property.object.dollar.js
+ captures:
+ 1: punctuation.dollar.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: meta.property.object.js
+ pop: true
+ - match: '{{identifier_part}}+{{identifier_break}}'
+ scope: invalid.illegal.illegal-identifier.js
+ pop: true
+ - match: (#)({{identifier_name}})
+ captures:
+ 1: punctuation.definition.variable.js
+ 2: meta.property.object.js
+ pop: true
+
+ class-body:
+ - match: \{
+ scope: punctuation.section.block.begin.js
+ set: class-body-contents
+
+ - include: else-pop
+
+ jsdoc-block-tag:
+ - match: '{{jsdoc_block_tag}}'
+ scope: entity.other.attribute-name.documentation.js
+ pop: 1
+ - match: (?=\S)|$
+ pop: 1
+
+ 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: true
+ - include: scope:source.regexp.js
+
+ literal-private-variable:
+ - match: (#)({{identifier_name}})
+ captures:
+ 1: punctuation.definition.variable.js
+ 2: variable.other.readwrite.js
+ pop: true
+
+ support-property-ecma-string:
+ - match: (?:fromCharCode|fromCodePoint|raw){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
+
+ flow-type-class:
+ - match: '{{non_reserved_identifier}}'
+ scope: variable.other.class.js
+ pop: true
+
+ decorator-name:
+ - match: '{{identifier_name}}{{left_expression_end_lookahead}}'
+ scope: variable.annotation.js
+ pop: true
+
+ variable-binding-spread:
+ - match: \.\.\.
+ scope: keyword.operator.spread.js
+ push: variable-binding-pattern
+
+ finally-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.finally.js
+ - include: immediately-pop
+
+ new-target:
+ - match: \.
+ scope: punctuation.accessor.dot.js
+ set:
+ - match: target{{identifier_break}}
+ scope: variable.language.target.js
+ pop: true
+ - include: else-pop
+
+ - include: else-pop
+
+ while-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.while.js
+ - include: immediately-pop
+
+ left-expression-end:
+ - include: expression-break
+
+ - match: (?=`)
+ push: literal-string-template
+
+ - match: (?=(?:{{dot_accessor}})?\()
+ push: function-call-arguments
+
+ - include: property-access
+
+ - include: else-pop
+
+ class:
+ - match: class{{identifier_break}}
+ scope: keyword.declaration.class.js
+ set:
+ - class-meta
+ - class-body
+ - class-extends
+ - class-name
+
+ flow-type-special:
+ - match: any{{identifier_break}}
+ scope: support.type.any.js
+ pop: true
+
+ - match: mixed{{identifier_break}}
+ scope: support.type.mixed.js
+ pop: true
+
+ branch-possible-parenthesized-arrow-function:
+ - meta_include_prototype: false
+ - match: ''
+ push:
+ - detect-parenthesized-arrow
+ - parenthesized-expression
+
+ flow-type-import-type:
+ - match: type{{identifier_break}}
+ scope: keyword.declaration.js
+
+ - match: typeof{{identifier_break}}
+ scope: keyword.operator.js
+
+ function-name-meta:
+ - meta_include_prototype: false
+ - meta_scope: entity.name.function.js
+ - include: immediately-pop
+
+ flow-type-export-type:
+ - match: type{{identifier_break}}(?=\s*\{)
+ scope: keyword.declaration.js
+ set: export-item
+ - include: flow-type-alias
+
+ 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: true
+ - include: function-parameter-binding-list
+
+ support-property-ecma-math:
+ - match: (?:E|LN10|LN2|LOG10E|LOG2E|PI|SQRT1_2|SQRT2){{identifier_break}}
+ scope: support.constant.builtin.js
+ pop: true
+ - 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: support.function.builtin.js
+ pop: true
+
+ class-element-modifiers:
+ - match: (?={{modifier}})
+ branch_point: class-element-modifier
+ branch:
+ - class-element-modifier
+ - class-element
+
+ flow-type-typeof:
+ - match: typeof{{identifier_break}}
+ scope: keyword.operator.js
+ set:
+ - left-expression-end
+ - expression-begin
+
+ prototype:
+ - include: comments
+
+ await-expression:
+ - match: await{{identifier_break}}
+ scope: keyword.control.flow.await.js
+
+ object-literal-property:
+ - match: ''
+ set:
+ - object-literal-property-check
+ - object-literal-meta-key
+ - object-property-name
+
+ decorator-expression-end:
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ push:
+ - include: decorator-name
+ - include: object-property
+
+ - include: left-expression-end
+
+ string-content:
+ - match: \\\n
+ scope: constant.character.escape.newline.js
+ - match: \\(?:x\h\h|u\h\h\h\h|.)
+ scope: constant.character.escape.js
+
+ restricted-production:
+ - meta_include_prototype: false
+ - match: '{{line_ending_ahead}}'
+ pop: true
+ - match: ''
+ set: expression-statement
+
+ support-property-ecma-typedarray:
+ - match: (?:BYTES_PER_ELEMENT){{identifier_break}}
+ scope: support.constant.builtin.js
+ pop: true
+
+ variable-binding-name:
+ - match: (?={{non_reserved_identifier}})
+ set:
+ - - meta_scope: meta.binding.name.js
+ - include: immediately-pop
+ - literal-variable
+
+ immediately-pop-2:
+ - meta_include_prototype: false
+ - match: ''
+ pop: 2
+
+ support-property:
+ - include: support-property-ecma
+
+ jsx-tag-attributes-top:
+ - meta_scope: meta.tag.js
+ - match: /
+ scope: punctuation.definition.tag.begin.js
+ set:
+ - - meta_scope: invalid.illegal.unmatched-tag.js
+ - include: immediately-pop
+ - jsx-expect-tag-end
+ - jsx-tag-name
+
+ - match: (?=\S)
+ set:
+ - jsx-tag-attributes
+ - jsx-tag-name
+
+ initializer:
+ - match: '='
+ scope: keyword.operator.assignment.js
+ set: expression-no-comma
+ - include: else-pop
+
+ field-name:
+ - match: '{{dollar_identifier}}'
+ scope: meta.mapping.key.dollar.js variable.other.readwrite.js
+ captures:
+ 1: punctuation.dollar.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.other.readwrite.js
+ pop: true
+ - 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: true
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - 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: true
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - include: string-content
+ - match: (#)({{identifier_name}})
+ captures:
+ 1: punctuation.definition.variable.js
+ 2: variable.other.readwrite.js
+
+ - match: (?=\[)
+ push: computed-property-name
+
+ - include: else-pop
+
+ comments:
+ - include: flow-type-pragma
+
+ - match: /\*\*(?!/)
+ scope: punctuation.definition.comment.begin.js
+ push:
+ - jsdoc-comment
+ - jsdoc-block-tag
+ - match: /\*
+ scope: punctuation.definition.comment.begin.js
+ push:
+ - meta_include_prototype: false
+ - meta_scope: comment.block.js
+ - match: \*/
+ scope: punctuation.definition.comment.end.js
+ pop: true
+ - match: //
+ scope: punctuation.definition.comment.js
+ push:
+ - meta_include_prototype: false
+ - meta_scope: comment.line.double-slash.js
+ - match: \n
+ pop: true
+
+ decorator-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.annotation.js
+ - include: immediately-pop
+
+ class-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.class.js
+ - include: immediately-pop
+
+ special-identifier:
+ # These are ordinary identifiers, not reserved words
+ - match: arguments{{identifier_break}}
+ scope: variable.language.arguments.js
+ pop: true
+ - match: globalThis{{identifier_break}}
+ scope: variable.language.global.js
+ pop: true
+ - match: undefined{{identifier_break}}
+ scope: constant.language.undefined.js
+ pop: true
+ - match: NaN{{identifier_break}}
+ scope: constant.language.nan.js
+ pop: true
+ - match: Infinity{{identifier_break}}
+ scope: constant.language.infinity.js
+ pop: true
+
+ try-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.try.js
+ - include: immediately-pop
+
+ support-variable-node:
+ - match: global{{identifier_break}}
+ scope: support.type.object.node.js
+ pop: true
+
+ - match: Buffer{{identifier_break}}
+ scope: support.class.node.js
+ pop: true
+
+ - 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: true
+ - 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: support.function.node.js
+ pop: true
+
+ import-list:
+ - match: ','
+ scope: punctuation.separator.comma.js
+ push:
+ - import-export-alias
+ - import-item
+ - include: else-pop
+
+ expect-label:
+ - meta_include_prototype: false
+ - match: (?={{nothing}}{{identifier_name}})
+ set:
+ - match: '{{non_reserved_identifier}}'
+ scope: variable.label.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: invalid.illegal.identifier.js variable.label.js
+ pop: true
+ - include: else-pop
+ - include: immediately-pop
+
+ for-of-rest:
+ - match: (?:of|in){{identifier_break}}
+ scope: keyword.operator.word.js
+ set: expression
+
+ import-meta:
+ - meta_include_prototype: false
+ - meta_scope: meta.import.js
+ - include: immediately-pop
+
+ method-name:
+ - match: '{{dollar_identifier}}'
+ scope: meta.mapping.key.dollar.js entity.name.function.js
+ captures:
+ 1: punctuation.dollar.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: entity.name.function.js
+ pop: true
+ - match: (#){{identifier_name}}
+ scope: entity.name.function.js
+ captures:
+ 1: punctuation.definition.js
+ pop: true
+ - 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: true
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - 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: true
+ - match: \n
+ scope: invalid.illegal.newline.js
+ pop: true
+ - include: string-content
+
+ - match: (?=\[)
+ push: computed-property-name
+
+ - include: else-pop
+
+ flow-type-declare-export:
+ - match: default{{identifier_break}}
+ scope: keyword.control.import-export.js
+ set: flow-type
+ - match: (?=\S)
+ pop: true
+
+ for-condition-end:
+ - meta_scope: meta.group.js
+
+ - match: \)
+ scope: punctuation.section.group.js
+ pop: true
+
+ support-property-ecma-arraybuffer:
+ - match: isView{{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
+
+ import-item:
+ - include: flow-type-import-type
+
- match: \{
scope: punctuation.section.block.begin.js
- set: export-brace
+ set: import-brace
- match: '{{non_reserved_identifier}}'
scope: variable.other.readwrite.js
pop: true
@@ -2398,36 +2701,153 @@ contexts:
pop: true
- include: else-pop
- function-parameter-binding-pattern:
- - match: ''
+ property-access:
+ - match: ({{dot_accessor}})?(\[)
+ 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: true
+ - match: (?=\S)
+ push: expression
+
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ push:
+ - match: (?={{identifier_name}}\s*(?:{{dot_accessor}})?\()
+ set:
+ - call-method-meta
+ - function-call-arguments
+ - call-path
+ - object-property
+ - include: object-property
+
+ arrow-function-expect-arrow-or-fail-async:
+ - match: =>
+ scope: keyword.declaration.function.arrow.js
+ pop: true
+ - match: (?=\S)
+ fail: async-arrow-function
+
+ jsx-tag:
+ - match: <
+ scope: punctuation.definition.tag.begin.js
set:
- - - include: flow-type-annotation-optional
- - - include: function-parameter-binding-name
- - include: function-parameter-binding-array-destructuring
- - include: function-parameter-binding-object-destructuring
- - include: else-pop
+ - jsx-meta
+ - jsx-tag-attributes-top
- flow-type-end:
- - include: flow-type-operators
- - match: (?=<)
- push: flow-type-generic-arguments
+ function-parameter-binding-spread:
+ - match: \.\.\.
+ scope: keyword.operator.spread.js
+ push: function-parameter
+
+ flow-type-alias-initializer:
+ - match: '='
+ scope: keyword.operator.assignment.js
+ set:
+ - flow-type-meta
+ - flow-type
+ - include: else-pop
+ constructor-body-expect-arguments:
+ - include: function-call-arguments
- include: else-pop
- function-block:
+ flow-type-module-body:
- match: \{
scope: punctuation.section.block.begin.js
+ set: flow-type-module-contents
+ - include: else-pop
+
+ function-parameter-binding-name:
+ - 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
+
+ do-while-condition:
+ - match: while{{identifier_break}}
+ scope: keyword.control.loop.while.js
+ set: parenthesized-expression
+ - include: else-pop
+
+ flow-type-list:
+ - include: comma-separator
+ - match: (?=\S)
+ push: flow-type
+
+ support-property-ecma-symbol:
+ - match: (?:asyncIterator|hasInstance|isConcatSpreadable|iterator|match|replace|search|species|split|toPrimitive|toStringTag|unscopeables){{identifier_break}}
+ scope: support.constant.builtin.js
+ pop: true
+ - match: (?:for|keyFor){{identifier_break}}
+ scope: support.function.builtin.js
+ pop: true
+
+ import-meta-expression:
+ - match: import{{identifier_break}}
+ scope: keyword.import.js
+ set: import-expression-end
+
+ literal-variable-base:
+ - match: '{{dollar_only_identifier}}'
+ scope: variable.other.dollar.only.js punctuation.dollar.js
+ pop: true
+ - match: '{{dollar_identifier}}'
+ scope: variable.other.dollar.js
+ captures:
+ 1: punctuation.dollar.js
+ pop: true
+ - match: '{{constant_identifier}}'
+ scope: variable.other.constant.js
+ pop: true
+ - match: '{{identifier_name}}'
+ scope: variable.other.readwrite.js
+ pop: true
+ - include: literal-private-variable
+
+ flow-type-module-contents:
+ - match: \}
+ scope: punctuation.section.block.end.js
+ pop: true
+ - include: main
+
+ jsx-interpolation-plain:
+ - match: '{'
+ scope: punctuation.definition.interpolation.begin.js
set:
- - meta_scope: meta.block.js
- - match: \}
- scope: punctuation.section.block.end.js
- pop: true
- - include: statements
+ - - meta_scope: meta.interpolation.js
+ - meta_content_scope: source.js.embedded.jsx
+ - match: '}'
+ scope: punctuation.definition.interpolation.end.js
+ pop: true
+ - expression
- support-property-ecma-date:
- - match: (?:now|parse|UTC){{identifier_break}}
+ function-declaration-expect-generator-star:
+ - match: \*
+ scope: keyword.declaration.generator.js
+ pop: true
+ - include: else-pop
+
+ support-property-ecma-proxy:
+ - match: revocable{{identifier_break}}
scope: support.function.builtin.js
pop: true
+ label:
+ - match: ({{identifier_name}})\s*(:)
+ captures:
+ 1: entity.name.label.js
+ 2: punctuation.separator.js
+
+ function-parameter:
+ - match: ''
+ set:
+ - initializer
+ - function-parameter-binding-pattern
+
support-variable-ecma:
- match: Array{{identifier_break}}
scope: support.class.builtin.js
@@ -2524,446 +2944,151 @@ contexts:
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: true
- - match: (?:Eval|Range|Reference|Syntax|Type|URI)?Error{{identifier_break}}
- scope: support.class.builtin.js
- pop: true
-
- - match: (?:eval|isFinite|isNaN|parseFloat|parseInt|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent){{identifier_break}}
- scope: support.function.js
- pop: true
-
- flow-type-module-meta:
- - meta_scope: meta.module.js
- - include: immediately-pop
-
- variable-binding-spread:
- - match: \.\.\.
- scope: keyword.operator.spread.js
- push: variable-binding-pattern
-
- constants:
- - match: true{{identifier_break}}
- scope: constant.language.boolean.true.js
- pop: true
- - match: false{{identifier_break}}
- scope: constant.language.boolean.false.js
- pop: true
- - match: null{{identifier_break}}
- scope: constant.language.null.js
- pop: true
-
- variable-binding-object-key:
- - match: '{{identifier}}(?=\s*:)'
- pop: true
- - include: literal-string
- - include: computed-property-name
- - include: variable-binding-name
- - include: else-pop
-
- flow-type:
- - match: ''
- set:
- - flow-type-end
- - flow-type-begin
-
- flow-type-list:
- - include: comma-separator
- - match: (?=\S)
- push: flow-type
-
- for-condition-end:
- - meta_scope: meta.group.js
-
- - match: \)
- scope: punctuation.section.group.js
- pop: true
-
- expression-no-comma:
- - meta_include_prototype: false
- - match: ''
- set: [expression-end-no-comma, expression-begin]
-
- regexp-complete:
- - match: /
- scope: punctuation.definition.string.begin.js
- set: regexp
-
- jsx-expect-tag-end:
- - meta_content_scope: meta.tag.js
- - match: '>'
- scope: meta.tag.js punctuation.definition.tag.end.js
- pop: true
- - include: else-pop
-
- expect-label:
- - meta_include_prototype: false
- - match: (?={{nothing}}{{identifier}})
- set:
- - match: '{{non_reserved_identifier}}'
- scope: variable.label.js
- pop: true
- - match: '{{identifier}}'
- scope: invalid.illegal.identifier.js variable.label.js
- pop: true
- - include: else-pop
- - include: immediately-pop
-
- function-assignment:
- - match: |-
- (?x)(?=
- (?:{{identifier}} \s* \. \s*)*
- {{identifier}}
- \s* = \s*
- {{either_func_lookahead}}
- )
- set:
- - function-initializer
- - function-declaration-identifiers
-
- support-property-ecma-promise:
- - match: (?:all|race|reject|resolve|allSettled|any){{identifier_break}}
- scope: support.function.builtin.js
- pop: true
-
- constructor-meta:
- - meta_include_prototype: false
- - meta_scope: meta.function-call.constructor.js
- - include: immediately-pop
-
- class-extends:
- - match: extends{{identifier_break}}
- scope: storage.modifier.extends.js
- set:
- - flow-type-generic-arguments
- - inherited-class-expression-end
- - inherited-class-expression-begin
- - include: else-pop
-
- expect-dot-accessor:
- - match: '{{dot_accessor}}'
- scope: punctuation.accessor.js
- pop: true
- - include: else-pop
-
- styled-component-begin:
- - match: '{{identifier}}(?=\s*\()'
- scope: variable.function.js
- pop: true
-
- - match: '{{identifier}}(?=\s*`)'
- scope: variable.function.tagged-template.js
- pop: true
-
- - match: '{{identifier}}'
- scope: variable.other.readwrite.js
- pop: true
-
- - include: else-pop
- jsx-tag:
- - match: <
- scope: punctuation.definition.tag.begin.js
- set:
- - jsx-meta
- - jsx-tag-attributes-top
-
- flow-type-import-type:
- - match: type{{identifier_break}}
- scope: storage.type.js
-
- - match: typeof{{identifier_break}}
- scope: keyword.operator.js
-
- 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
+ - include: object-property
+ - include: else-pop
+ - include: else-pop
- ternary-operator:
- - match: \?
- scope: keyword.operator.ternary.js
+ - match: Promise{{identifier_break}}
+ scope: support.class.builtin.js
set:
- - ternary-operator-expect-colon
- - expression-no-comma
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ set:
+ - include: support-property-ecma-promise
+ - include: object-property
+ - include: else-pop
+ - include: else-pop
- call-method-name:
- - include: support-property
- - match: '{{identifier}}'
- scope: variable.function.js
- pop: true
- - 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
- expect-case-colon:
- - match: ':'
- scope: punctuation.separator.js
- pop: true
- - 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
- either-function-declaration:
- - match: (?={{func_lookahead}})
- set: function-declaration
- - match: (?={{arrow_func_lookahead}})
- set: arrow-function-declaration
+ - 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
- flow-type-tuple:
- - match: \[
- scope: punctuation.section.brackets.begin.js
+ - match: Symbol{{identifier_break}}
+ scope: support.class.builtin.js
set:
- - meta_scope: meta.sequence.js
- - match: \]
- scope: punctuation.section.brackets.end.js
- pop: true
- - include: flow-type-list
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ set:
+ - include: support-property-ecma-symbol
+ - include: object-property
+ - include: else-pop
+ - include: else-pop
- support-property-ecma:
- - match: constructor{{identifier_break}}
- scope: variable.language.constructor.js
+ - 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: true
- - match: prototype{{identifier_break}}
- scope: support.constant.prototype.js
+ - match: (?:Eval|Range|Reference|Syntax|Type|URI)?Error{{identifier_break}}
+ scope: support.class.builtin.js
pop: true
- - match: (?:hasOwnProperty|isPrototypeOf|propertyIsEnumerable|toLocaleString|toString|valueOf){{identifier_break}}
+ - match: (?:eval|isFinite|isNaN|parseFloat|parseInt|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent){{identifier_break}}
scope: support.function.js
pop: true
- # Annex B
- - match: __proto__{{identifier_break}}
- scope: invalid.deprecated.js variable.language.prototype.js
- pop: true
- - match: (?:__defineGetter__|__defineSetter__|__lookupGetter__){{identifier_break}}
- scope: invalid.deprecated.js support.function.js
- pop: true
-
- import-expression-end:
- - match: (?=\()
- set: function-call-arguments
- - match: \.
- scope: punctuation.accessor.js
+ jsx-interpolation-comment:
+ - match: ({)(/\*)
+ captures:
+ 1: punctuation.definition.interpolation.begin.js
+ 2: punctuation.definition.comment.begin.js
set:
- - match: meta{{identifier_break}}
- scope: variable.language.import.js
+ - meta_include_prototype: false
+ - meta_scope: meta.interpolation.js comment.block.js
+ - match: (\*/)(})
+ captures:
+ 1: punctuation.definition.comment.end.js
+ 2: punctuation.definition.interpolation.end.js
pop: true
- - include: object-property
- - include: else-pop
- object-property:
- - match: |-
- (?x)(?=
- {{identifier}}
- \s* = \s*
- {{either_func_lookahead}}
- )
- set:
- - function-initializer
- - function-name-meta
- - object-property-base
+ - match: (?=\*/)
+ fail: jsx-interpolation-comment
- - include: support-property
+ literal-string-template-custom-lookahead: []
+ jsx-html-escapes:
+ - match: (&)#?[[:alnum:]]+(;)
+ scope: constant.character.escape.js
+ captures:
+ 1: punctuation.definition.entity.js
+ 2: punctuation.definition.entity.js
- - match: (?={{identifier}}\s*(?:\.\?)?\()
- set: call-method-name
+ call-path:
+ - match: '{{dot_accessor}}'
+ scope: punctuation.accessor.js
+ push: object-property
+ - include: else-pop
- - include: object-property-base
+ for-condition:
+ - match: \(
+ scope: punctuation.section.group.js
+ set:
+ - for-condition-end
+ - for-condition-contents
- include: else-pop
- decorator-name:
- - match: '{{identifier}}{{left_expression_end_lookahead}}'
- scope: variable.annotation.js
+ flow-type-object-indexer-label:
+ - match: ({{non_reserved_identifier}})\s*(:)
+ captures:
+ 1: meta.object-literal.key.js
+ 2: punctuation.separator.key-value.js
pop: true
+ - include: else-pop
- decorator-meta:
+ object-literal-property-check:
+ - match: (?=\()
+ fail: object-literal-property
+ - include: else-pop
+
+ constructor-meta:
- meta_include_prototype: false
- - meta_scope: meta.annotation.js
+ - meta_scope: meta.function-call.constructor.js
- include: immediately-pop
-scope: source.js
-variables:
- block_comment: (?:/\*{{block_comment_contents}}\*/)
- non_reserved_identifier: (?:(?!{{reserved_word}}){{identifier}})
- dot_accessor: |-
- (?x: # Match . and .?, but not .?( or .?[
- \.
- (?! \? [\[(] )
- \??
- )
- line_continuation_lookahead: >-
- (?x:(?=
- (?! \+\+ | -- )
- (?=
- != |
- [-+*/%><=&|^\[(;,.:?] |
- (?:in|instanceof){{identifier_break}}
- )
- ))
- oct_digit: '[0-7_]'
- identifier_escape: (?:\\u(?:\h{4}|\{\h+\}))
- jsx_identifier_part: (?:{{identifier_part}}|-)
- jsx_identifier_break: (?!{{jsx_identifier_part}})
- jsx_identifier: '{{identifier_start}}{{jsx_identifier_part}}*{{jsx_identifier_break}}'
- identifier_start: (?:[_$\p{L}\p{Nl}]|{{identifier_escape}})
- identifier_break: (?!{{identifier_part}})
- either_func_lookahead: (?:{{func_lookahead}}|{{arrow_func_lookahead}})
- hex_digit: '[\h_]'
- line_ending_ahead: (?={{nothing}}(?:/\*{{block_comment_contents}})?$)
- block_comment_contents: (?:(?:[^*]|\*(?!/))*)
- bin_digit: '[01_]'
- property_name: >-
- (?x:
- {{identifier}}
- | '(?:[^\\']|\\.)*'
- | "(?:[^\\"]|\\.)*"
- | \[ .* \]
- )
- left_expression_end_lookahead: (?!\s*[.\[\(])
- class_element_name: |-
- (?x:
- \+?
- (?:
- \*?
- {{property_name}}
- | \#{{identifier}}
- )
- )
- dec_exponent: (?:[Ee](?:[-+]|(?![-+])){{dec_digit}}*)
- dollar_identifier: (?:(\$){{identifier_part}}*{{identifier_break}})
- dollar_only_identifier: (?:\${{identifier_break}})
- arrow_func_lookahead: |-
- (?x)(?:
- \s*(async\s*)?
- (?:
- {{identifier}}
- |\( (?: [^()]|\([^()]*\) )* \)
- )
- (?:
- \s*:
- \s*{{identifier}}
- )?
- \s*=>
- )
- constant_identifier: (?:[[:upper:]]{{identifier_part}}*{{identifier_break}})
- 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}}
- binding_pattern_lookahead: (?:{{identifier}}|\[|\{)
- identifier: (?:{{identifier_start}}{{identifier_part}}*{{identifier_break}})
- func_lookahead: |-
- (?x:
- \s*
- (?:async{{identifier_break}}{{nothing}})?
- function{{identifier_break}}
- )
- method_lookahead: |-
- (?x)(?=
- (?: get|set|async ){{identifier_break}}(?!\s*:)
- | \*
- | {{property_name}} \s* (?:\(|<)
- )
- dec_digit: '[0-9_]'
- identifier_part: (?:[_$\p{L}\p{Nl}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\x{200C}\x{200D}]|{{identifier_escape}})
- nothing: (?x:(?:\s+|{{block_comment}})*)
- dec_integer: (?:0|[1-9]{{dec_digit}}*)
-file_extensions:
- - js
- - jsx
- - es6
- - babel
-name: JavaScript (Babel)
diff --git a/build/build.py b/build/build.py
index 3a69265..e755803 100644
--- a/build/build.py
+++ b/build/build.py
@@ -42,7 +42,7 @@ def run(self):
print("Building tests…")
sublime.run_command('build_js_custom_tests', {
'syntax_path': str(syntax_path),
- 'suites': ['base', 'flow', 'jsx', 'string_object_keys'],
+ 'suites': ['js', 'flow', 'jsx', 'string_object_keys'],
'destination_directory': str(test_directory),
})
print('Done.')
diff --git a/messages.json b/messages.json
index fba5c35..dfe5045 100644
--- a/messages.json
+++ b/messages.json
@@ -5,5 +5,6 @@
"7.1.0": "messages/7.1.0.txt",
"7.1.1": "messages/7.1.0.txt",
"8.0.0": "messages/8.0.0.txt",
- "10.0.0": "messages/10.0.0.txt"
+ "10.0.0": "messages/10.0.0.txt",
+ "11.0.0": "messages/11.0.0.txt"
}
diff --git a/messages/11.0.0.txt b/messages/11.0.0.txt
new file mode 100644
index 0000000..0096a16
--- /dev/null
+++ b/messages/11.0.0.txt
@@ -0,0 +1,7 @@
+babel-sublime
+-------------
+
+Version 11 features significantly improved highlighting using new features from Sublime Text 4. Highlights include:
+
+- Recognition of multiline arrow function parameter lists. (#340)
+- Better commenting in JSX. (#390)
diff --git a/support/JavaScript Indent.tmPreferences b/support/Indentation Rules.tmPreferences
similarity index 83%
rename from support/JavaScript Indent.tmPreferences
rename to support/Indentation Rules.tmPreferences
index b5122ed..6acdd2a 100644
--- a/support/JavaScript Indent.tmPreferences
+++ b/support/Indentation Rules.tmPreferences
@@ -1,17 +1,14 @@
- name
- JavaScript Indent
scope
- source.js
+ source.js, source.ts, source.jsx, source.tsx
settings
decreaseIndentPattern
^(.*\*/)?\s*\}.*$
increaseIndentPattern
^.*\{[^}"']*$
-
bracketIndentNextLinePattern
(?x)
^ \s* \b(if|while|else)\b [^;]* $
diff --git a/support/JavaScript (Babel).sublime-settings b/support/JavaScript (Babel).sublime-settings
new file mode 100644
index 0000000..d9ced3f
--- /dev/null
+++ b/support/JavaScript (Babel).sublime-settings
@@ -0,0 +1,3 @@
+{
+ "word_separators": "./\\()\"'-:,.;<>~!@#%^&*|+=[]{}`~?",
+}
diff --git a/support/Indexed Symbols.tmPreferences b/support/Symbol List - Exports.tmPreferences
similarity index 61%
rename from support/Indexed Symbols.tmPreferences
rename to support/Symbol List - Exports.tmPreferences
index 9cec1c6..a3d10e8 100644
--- a/support/Indexed Symbols.tmPreferences
+++ b/support/Symbol List - Exports.tmPreferences
@@ -2,7 +2,9 @@
scope
- source.js meta.function.declaration.js entity.name.function.js, source.js meta.class.js entity.name.class.js
+
+ meta.export.js meta.binding.name - meta.export.js meta.function meta.binding.name
+
settings
showInIndexedSymbolList
diff --git a/support/Symbol List Function.tmPreferences b/support/Symbol List Function.tmPreferences
deleted file mode 100644
index 442f40b..0000000
--- a/support/Symbol List Function.tmPreferences
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- name
- Symbol List Function
- scope
- source.js meta.function.declaration, source.js entity.name.class
- settings
-
- showInSymbolList
- 1
- symbolTransformation
- s/\s+/ /g;
-
-
-
diff --git a/support/Symbol List Banned.tmPreferences b/support/Symbol List.tmPreferences
similarity index 58%
rename from support/Symbol List Banned.tmPreferences
rename to support/Symbol List.tmPreferences
index 8ed3f14..befd761 100644
--- a/support/Symbol List Banned.tmPreferences
+++ b/support/Symbol List.tmPreferences
@@ -1,16 +1,16 @@
- name
- Symbol List Banned
scope
- source.js meta.function.anonymous
+
+ entity.name.interface.js
+
settings
- showInIndexedSymbolList
- 0
showInSymbolList
- 0
+ 1
+ showInIndexedSymbolList
+ 1
diff --git a/tests/syntax_test_flow.js b/tests/syntax_test_flow.js
index bdb7dbf..95b435f 100644
--- a/tests/syntax_test_flow.js
+++ b/tests/syntax_test_flow.js
@@ -31,28 +31,28 @@
/* Literal types */
const x:true;
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^ meta.flow-type
// ^ punctuation.separator.type
// ^^^^ constant.language.boolean.true
const x:42;
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^ meta.flow-type
// ^ punctuation.separator.type
-// ^^ constant.numeric.integer.decimal
+// ^^ meta.number.integer.decimal constant.numeric
const x:"foo";
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^^ meta.flow-type
// ^ punctuation.separator.type
// ^^^^^ string.quoted.double
const x:'bar';
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^^ meta.flow-type
// ^ punctuation.separator.type
@@ -99,7 +99,7 @@
const x: typeof 42;
// ^^^^^^^^^^^ meta.flow-type
// ^^^^^^ keyword.operator
-// ^^ constant.numeric.integer.decimal
+// ^^ meta.number.integer.decimal constant.numeric
const x: number %checks;
// ^^^^^^^^^^^^^^^^ meta.flow-type
@@ -190,7 +190,7 @@
/* Variables */
var x : number;
-// ^^^ storage.type
+// ^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^^^^ meta.flow-type
// ^ punctuation.separator.type
@@ -198,7 +198,7 @@
// ^ punctuation.terminator.statement
let x : number;
-// ^^^ storage.type
+// ^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^^^^ meta.flow-type
// ^ punctuation.separator.type
@@ -206,7 +206,7 @@
// ^ punctuation.terminator.statement
const x : number;
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration
// ^ meta.binding.name variable.other.readwrite
// ^^^^^^^^ meta.flow-type
// ^ punctuation.separator.type
@@ -221,13 +221,13 @@
/* Functions */
function f() : number {}
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^ entity.name.function
// ^^^^^^^^ meta.flow-type
// ^^ meta.block
function f() : number {}
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^ entity.name.function
// ^^^^^^ meta.generic.declaration
// ^ punctuation.section.generic.begin
@@ -260,7 +260,7 @@ function f(
class MyClass {
foo() : number {}
-// ^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^ meta.flow-type
// ^ punctuation.separator.type
// ^^^^^^ support.type.primitive.number
@@ -293,12 +293,12 @@ class MyClass {
// ^ punctuation.separator.type
// ^^^^^^ support.type.primitive.number
// ^ keyword.operator.assignment
-// ^^ constant.numeric.integer.decimal
+// ^^ meta.number.integer.decimal constant.numeric
}
class MyClass {}
// ^^^^^^^^^^^^^^^^^^^^^^^ meta.class
-// ^^^^^ storage.type.class
+// ^^^^^ keyword.declaration.class
// ^^^^^^^ entity.name.class
// ^^^^^^ meta.generic.declaration
// ^ punctuation.section.generic.begin
@@ -316,14 +316,14 @@ class MyClass {
type MyType = number;
// ^^^^^^^^^^^^^^^^^^^^ meta.declaration.type - meta.declaration.type meta.declaration.type
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^^^^ entity.name.type
// ^ keyword.operator.assignment
// ^^^^^^ support.type.primitive.number
type MyType = number;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.declaration.type
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^^^^ entity.name.type
// ^^^^^^ meta.generic.declaration
// ^ punctuation.section.generic.begin
@@ -338,16 +338,16 @@ class MyClass {
// ^^^^ variable.other.readwrite - storage
type = function() {};
-// ^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^ entity.name.function variable.other.readwrite - storage
+// ^^^^^^^^^^^^^ meta.function
type
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
/foo/g;
// ^ keyword.operator.arithmetic - string
type
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
foo;
// ^^^ meta.declaration.type entity.name.type
@@ -359,7 +359,7 @@ class MyClass {
(42 : number);
// ^^^^^^^^^^^^^ meta.group
// ^ punctuation.section.group
-// ^^ constant.numeric.integer.decimal
+// ^^ meta.number.integer.decimal constant.numeric
// ^^^^^^^^ meta.flow-type
// ^ punctuation.separator.type
// ^^^^^^ support.type.primitive.number
@@ -374,19 +374,19 @@ class MyClass {
/* Imports/exports */
import { type Foo } from 'bar';
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^ variable.other.readwrite
import type Foo from 'bar';
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^ variable.other.readwrite
export type { Foo };
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^ variable.other.readwrite
export type Foo = bar;
-// ^^^^ storage.type
+// ^^^^ keyword.declaration
// ^^^ entity.name.type
import typeof React from 'React';
diff --git a/tests/syntax_test_js.js b/tests/syntax_test_js.js
index da5af8b..1484563 100644
--- a/tests/syntax_test_js.js
+++ b/tests/syntax_test_js.js
@@ -1,233 +1,5 @@
// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
-import TheirClass from "./mypath";
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
-// ^ keyword.control.import-export
-// ^ keyword.control.import-export
-
-import {identifier, otherIdentifier} from "somewhere";
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import
-// ^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
-// ^ punctuation.section.block.begin
-// ^ punctuation.section.block.end
-// ^ meta.import meta.block variable.other.readwrite
-
-import thing, {identifier as otherIdentifier}, * as otherName from "otherplace";
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import
-// ^ keyword.control.import-export
-// ^ variable.other.readwrite
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
-// ^ variable.other.readwrite
-// ^ keyword.control.import-export
-// ^ variable.other.readwrite
-// ^ constant.other.js
-// ^ keyword.control.import-export
-
-import 'module';
-// ^^^^^^^^^^^^^ meta.import
-
-// Better highlighting while typing.
-import
-import;
-// <- keyword.control.import-export
-
-import;/**/
-// ^ - meta.import
-
-export { name1, name2 as name3 };
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
-// ^ punctuation.separator.comma
-// ^^ keyword.control.import-export
-
-export let name1, name2;
-//^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^ storage.type
-// ^ punctuation.separator.comma
-
-export var name3;
-//^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^ storage.type
-
-export const name1 = 5;
-//^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^^^ storage.type
-// ^ keyword.operator.assignment
-
-export let foo = 123 // No semicolon
-export function bar() {}
-// <- keyword.control.import-export
-
-export function foo() {};
-//^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^^^ meta.function.declaration
-// ^ punctuation.terminator.statement.empty
-
-export function* foo() {};
-//^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^ meta.function.declaration
-// ^ punctuation.terminator.statement.empty
-
-export async function foo() {};
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
-// ^ punctuation.terminator.statement.empty
-
-export class Foo {};
-//^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^ meta.class
-// ^ punctuation.terminator.statement.empty
-
-export default expression;
-//^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^ keyword.control.import-export
-
-export default function (a) { };
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^ meta.function.declaration.js
-// ^ punctuation.terminator.statement.empty - meta.export
-
-export default function* (a) { };
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^^ meta.function.declaration.js
-// ^ punctuation.terminator.statement.empty - meta.export
-
-export default function name1(b) { }
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^ keyword.control.import-export
-// ^ storage.type
-// ^ entity.name.function
-
-export default class Foo {};
-//^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^ meta.class
-// ^ punctuation.terminator.statement.empty
-
-export default +function (a) { };
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^^^^ keyword.control.import-export
-// ^^^^^^^ keyword.control.import-export
-// ^^^^^^^^^^^^ meta.function.declaration.js
-
-export { name1 as default };
-//^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^^^^^ meta.block
-// ^ keyword.control.import-export
-// ^ keyword.control.import-export
-
-export * from "./othermod";
-//^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^ constant.other
-// ^ keyword.control.import-export
-
-export { name1, name2 } from "./othermod";
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^ meta.block
-// ^ punctuation.section.block.begin
-// ^ punctuation.section.block.end
-// ^ keyword.control.import-export
-
-export { import1 as name1, import2 as name2, nameN } from "./othermod";
-//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
-//^ keyword.control.import-export
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
-// ^ keyword.control.import-export
-// ^ keyword.control.import-export
-// ^ keyword.control.import-export
-
-// Better highlighting while typing.
-export
-export;
-// <- keyword.control.import-export
-
-export;/**/
-// ^ - meta.export
-
-import * as
- alias from "module";
-// ^^^^^^^^^^^^^^^^^^^^^ meta.import.js
-
-import { member as
- alias } from "module";
-// ^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
-
-import { * as
- alias } from "module";
-// ^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
-
-export { member as
- alias } from "module";
-// ^^^^^^^^^^^^^^^^^^^^^^^ meta.export.js
-
-export { member as
- default } from "module";
-// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export.js
-
-let from;
-// ^^^^ variable.other.readwrite.js
-
-import from from "./othermod";
-// ^^^^ variable.other.readwrite.js
-
-import { from } from "./othermod";
-// ^^^^ variable.other.readwrite.js
-
-export from from "./othermod";
-// ^^^^ variable.other.readwrite.js
-
-export { from } from "./othermod";
-// ^^^^ variable.other.readwrite.js
-
-export default$
-// ^^^^^^^^ - keyword
-;
-
-let x = import.meta;
-// ^^^^^^^^^^^ - meta.import
-// ^^^^^^ keyword.import
-// ^ punctuation.accessor
-// ^^^^ variable.language.import
-
- import.meta;
-// ^^^^^^^^^^^ - meta.import
-// ^^^^^^ keyword.import
-// ^ punctuation.accessor
-// ^^^^ variable.language.import
-
- import
- .meta;
-// ^^^^^ - meta.import
-// ^ punctuation.accessor
-// ^^^^ variable.language.import
-
- import('foo');
-// ^^^^^^ keyword.import
-// ^^^^^^^ meta.group
-
- import
- ('foo');
-// ^^^^^^^ meta.group
-
// This object literal is technically broken since foo() does not have a
// method body, but we include it here to ensure that highlighting is not
// broken as the user is typing
@@ -246,26 +18,23 @@ someFunction({
function foo() {
// ^^^^^^^^^^^^^^^^ meta.function - meta.function meta.function
-// ^^^^^^^^^^^^^^ meta.function.declaration
-// ^^^^^^^^ storage.type.function
+// ^^^^^^^^ keyword.declaration.function
// ^^^ entity.name.function
-// ^^ - meta.function.declaration
}
// ^ meta.function meta.block
var bar = function() {
-// ^^^ storage.type
-// ^^^^^^^^^^^^^^^^^^ meta.function - meta.function meta.function
-// ^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^ keyword.declaration
// ^^^ entity.name.function variable.other.readwrite
-// ^^^^^^^^ storage.type.function
+// ^^^^^^^^^^^^ meta.function - meta.function meta.function
+// ^^^^^^^^ keyword.declaration.function
}
baz = function*()
-// ^^^^^^^^^^^^^^^^^ meta.function.declaration - meta.function meta.function
// ^^^ entity.name.function variable.other.readwrite
-// ^^^^^^^^ storage.type.function
-// ^ keyword.generator.asterisk
+// ^^^^^^^^^^^ meta.function - meta.function meta.function
+// ^^^^^^^^ keyword.declaration.function
+// ^ keyword.declaration.generator
{
}
@@ -276,17 +45,11 @@ someFunction({
// Better highlighting when typing
function
function() {}
-// <- storage.type.function - entity.name.function
+// <- keyword.declaration.function - entity.name.function
function foo(){}/**/
// ^ - meta.function
-if (true)
-// <- keyword.control.conditional.if
-{
- bar()
-}
-
// This is a comment function() { }
// <- punctuation.definition.comment
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ comment.line.double-slash
@@ -307,7 +70,7 @@ if (true)
x --> y;
//^^ keyword.operator.arithmetic.js
-// ^ keyword.operator.relational.js
+// ^ keyword.operator.comparison.js
#! /usr/bin/env node
// <- comment.line.shebang punctuation.definition.comment
@@ -351,9 +114,12 @@ not_a_comment;
"// /* not a comment"() {},
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -comment() {}
-// ^ - meta.function.declaration meta.function.declaration
});
+1
+ /* Block Comment */
+// ^^^^^^^^^^^^^^^^^^^ comment.block
+
{
let _$Foobar1Ù𝓩ʷªאξ‿ᛮↂ〩;
// ^^^^^^^^^^^^^^^^^^^ variable.other.readwrite
@@ -399,7 +165,7 @@ not_a_comment;
var str = '\':';
var str2 = NaN;
-// <- storage.type
+// <- keyword.declaration
// ^ variable.other.readwrite
// ^ keyword.operator.assignment
// ^^^ constant.language.nan
@@ -462,11 +228,15 @@ var obj = {
// ^^^^^^^^^^^^^^ meta.string string.quoted.double
$keyFunc: function() {
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
- // <- meta.mapping.key.dollar entity.name.function punctuation.dollar
- // <- meta.mapping.key.dollar entity.name.function - punctuation.dollar
+// ^^^^^^^^ meta.mapping.key.dollar entity.name.function
+// ^ punctuation.dollar
+// ^^^^^^^ - punctuation.dollar
+// ^^^^^^^^^^^^ meta.function
},
+ class: null, // Keys are IdentifierNames, not merely Identifiers
+// ^^^^^ meta.mapping.key
+
[true==false ? 'one' : 'two']: false,
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key
// ^ punctuation.section.brackets.begin
@@ -489,75 +259,81 @@ var obj = {
// ^^^^^ constant.language.boolean.false
objKey: new function() {
-// ^^^^^^^^ storage.type.function
+// ^^^^^^^^ keyword.declaration.function
this.foo = baz;
// ^^^^ variable.language.this
// ^ punctuation.accessor
// ^^^ meta.property
}(),
+ objKey: new/**/function() {}(),
+// ^^^^^^^^ keyword.declaration.function
+
objKey: new class Foo {
-// ^^^^^ storage.type.class
+// ^^^^^ keyword.declaration.class
get baz() {}
// ^^^ storage.type.accessor
// ^^^ entity.name.function
}(),
funcKey: function() {
-// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^ meta.mapping.key entity.name.function
+// ^^^^^^^^^^^^ meta.function
},
func2Key: function func2Key() {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^ meta.mapping.key entity.name.function
+// ^^^^^^^^^^^^^^^^^^^^^ meta.function
},
funcKeyArrow: () => {
-// ^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^^^^^ meta.mapping.key entity.name.function
+// ^^^^^^^ meta.function
},
"funcStringKey": function funcStringKey()
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double
// ^^^^^^^^^^^^^ entity.name.function
+// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
{ },
'funcStringKey': function() {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single
// ^^^^^^^^^^^^^ entity.name.function
+// ^^^^^^^^^^^^ meta.function
},
'funcStringKeyArrow': () => {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.single
// ^^^^^^^^^^^^^^^^^^ entity.name.function
+// ^^^^^^^ meta.function
},
"func\\String2KeyArrow": (foo) => {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^^^^^^^^^ meta.mapping.key meta.string string.quoted.double
// ^^^^^^^^^^^^^^^^^^^^^ entity.name.function
// ^^ constant.character.escape
},
+ f: function(){} + 1,
+// ^ keyword.operator.arithmetic
+
key: 'str' + (true ? 'true' : 'false'),
// ^^^^ constant.language.boolean.true
qux()
-// ^^^^^ meta.function.declaration
+// ^^^^^ meta.function
// ^^^ entity.name.function
{},
'funcStringMethod'() {
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^^ entity.name.function
},
'funcStringMethodWithSameLineColon'() { var foo = { name: 'jeff' }; },
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ entity.name.function
"key (": true,
@@ -573,7 +349,7 @@ var obj = {
// ^^^^^^ variable.other.readwrite
*baz(){
-// ^^^^^^ meta.function.declaration
+// ^^^^^^ meta.function
// ^ keyword.generator.asterisk
// ^^^ entity.name.function
}
@@ -600,6 +376,16 @@ var obj = {
get: 42,
// ^^^ meta.mapping.key
+
+ async() {}
+// ^^^^^^^^^^ meta.function
+// ^^^^^ entity.name.function
+// ^^ meta.function.parameters
+// ^ punctuation.section.group.begin
+// ^ punctuation.section.group.end
+// ^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
}
// <- meta.mapping - meta.block
@@ -640,8 +426,8 @@ function x() {}
// <- meta.brackets.js
var $ = function(baz) {
-// ^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.dollar.only punctuation.dollar
+// ^^^^^^^^^^^^^ meta.function
}
$()
@@ -657,295 +443,12 @@ baz = "";
// ^^ meta.string string.quoted.double
var qux = 100;
-// <- storage.type
+// <- keyword.declaration
// ^ variable.other.readwrite
// ^ constant.numeric
-{}/**/
-//^ - meta.block
-
-if (Infinity > qux) {
-// <- meta.conditional.js keyword.control.conditional.if
-// ^^^^^^^^^^^^^^^ meta.conditional
-// ^^^^^^^^ constant.language.infinity
- a;
-// ^ meta.conditional meta.block
-}
-// <- meta.conditional meta.block
-
-if (foo bar)
- baz = "test"
-
-if(false){}/**/
-// ^ - meta.conditional
-
-do {
-// <- meta.do-while keyword.control.loop.do-while
-// ^ meta.block
- qux += 1
-// ^^^^^^^^ meta.do-while meta.block
-} while(qux < 20);
-// <- meta.block
-// ^^^^^^^^^^^^^^ meta.do-while - meta.block
-// ^^^^ keyword.control.loop.while
-// ^^^^^^^^ meta.group
-
-do // Incomplete statement
- 42;
-// ^^ constant.numeric - meta.do-while
-
-do {} while (false)/**/
-// <- meta.do-while keyword.control.loop.do-while
-//^^^^^^^^^^^^^^^^^ meta.do-while.js
-// ^^ - meta.do-while
-// ^^^^^ keyword.control.loop.while.js
-
-for (var i = 0; i < 10; i++) {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^^^^^^^^^^^^^^^^^^^^ meta.group
-// ^^^ storage.type.js
-// ^ meta.block
- i += 1;
-// ^^^^^^^ meta.for meta.block
-}
-// <- meta.block
-
- for (; x in list;) {}
-// ^^^^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^^^^ meta.group
-// ^ punctuation.separator.expression
-// ^^ keyword.operator
-// ^ punctuation.separator.expression
-
- for (a[x in list];;) {}
-// ^^^^^^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^^^^^^ meta.group
-// ^^^^^^^^^^^ meta.brackets
-// ^^ keyword.operator
-// ^ punctuation.separator.expression
-// ^ punctuation.separator.expression
-
- for (;function () {}/a/g;) {}
-// ^ keyword.operator
-
- for (const x in list) {}
-// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^^^^^^^ meta.group
-// ^^^^^ storage.type
-// ^^ keyword.operator.word
-
- for (const x of list) {}
-// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^^^^^^^ meta.group
-// ^^^^^ storage.type
-// ^^ keyword.operator.word
-
- for (x in list) {}
-// ^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^ meta.group
-// ^^ keyword.operator.word
-
- for (x of list) {}
-// ^^^^^^^^^^^^^^^^^^ meta.for
-// ^^^ keyword.control.loop.for
-// ^^^^^^^^^^^ meta.group
-// ^^ keyword.operator.word
-
- for await (const x of list) {}
-// ^^^ keyword.control.loop.for
-// ^^^^^ keyword.control.flow.await
-
-for
- 42;
-// ^^ constant.numeric - meta.for
-
-for(;;){}/**/
-// ^ - meta.for
-
-while (true)
-// ^^^^^^^^^ meta.while
-// ^^^^ meta.group
-{
-// <- meta.block
- x = yield;
-// ^^^^^ keyword.control.flow.yield
-
- x = yield * 42;
-// ^^^^^ keyword.control.flow.yield
-// ^ keyword.generator.asterisk
-
- x = yield
- function f() {}
- [];
-// ^^ meta.sequence - meta.brackets
-
-
- x = yield*
- function f() {}
- [];
-// ^^ meta.brackets - meta.sequence
-
- y = await 42;
-// ^^^^^ keyword.control.flow.await
-
- y = yield await 42;
-// ^^^^^ keyword.control.flow.yield
-// ^^^^^ keyword.control.flow.await
-
- yield (parenthesized_expression);
-// ^^^^^ keyword.control.flow.yield
-
- yield `template`;
-// ^^^^^ keyword.control.flow.yield
-
- break;
-// ^^^^^ keyword.control.flow.break
-
- break foo;
-// ^^^^^ keyword.control.flow.break
-// ^^^ variable.label
-
- break
- foo;
-// ^^^ variable.other.readwrite - variable.label
-
- break/**/foo;
-// ^^^ variable.label - variable.other.readwrite
-
- break/*
- */foo;
-// ^^^ variable.other.readwrite - variable.label
-
- break function;
-// ^^^^^^^^ invalid.illegal.identifier variable.label
-
- continue;
-// ^^^^^^^^ keyword.control.flow.continue
-
- continue foo;
-// ^^^^^^^^ keyword.control.flow.continue
-// ^^^ variable.label
-
- continue
- foo;
-// ^^^ variable.other.readwrite - variable.label
-
- continue/**/foo;
-// ^^^ variable.label - variable.other.readwrite
-
- continue/*
- */ foo;
-// ^^^ variable.other.readwrite - variable.label
-
- goto;
-// ^^^^ variable.other.readwrite - keyword
-}
-// <- meta.block
-
-while // Incomplete statement
- 42;
-// ^^ constant.numeric - meta.while
-
-while(false){}/**/
-// ^ - meta.while
-
-with (undefined) {
-// <- keyword.control.import.with
-//^^^^^^^^^^ meta.with
-// ^^^^^^^^^ constant.language.undefined
- return;
-// ^^^^^^ meta.with.js meta.block.js keyword.control.flow.return
-}
-
-with // Incomplete statement
- 42;
-// ^^ constant.numeric - meta.while
-
-with(false){}/**/
-// ^ - meta.with
-
-switch ($foo) {
-// <- meta.switch.js keyword.control.conditional.switch
-// ^^^^^^^^^^^^ meta.switch
-//^^^^ keyword.control.conditional.switch
-// ^^^^ meta.group
-// ^ meta.block punctuation.section.block.begin
- case foo:
- // ^ meta.switch meta.block keyword.control.conditional.case
- // ^ - punctuation.separator.key-value
- qux = 1;
- break;
- // ^ keyword.control.flow.break
- case "baz":
- // ^ keyword.control.conditional.case
- // ^ - punctuation.separator.key-value string
- qux = 2;
- break;
- // ^ keyword.control.flow.break
- default:
- // ^ meta.switch meta.block keyword.control.conditional.default
- // ^ - punctuation.separator.key-value
- qux = 3;
-
- case$
-// ^^^^^ - keyword
- ;
-
- default$
-// ^^^^^^^^ - keyword
- ;
-
- case 0: {}
- case 1:
-// ^^^^ keyword.control.conditional.case
-}
-// <- meta.block punctuation.section.block.end
-
-try {
-// <- meta.try keyword.control.exception.try
-// ^^ meta.try
-// ^ meta.block
- foobar = qux.bar();
-// ^^^^^^^^^^^^^^^^^^^ meta.try meta.block
-} catch (e) {
-// <- meta.block
-//^^^^^^^^^^^^ meta.catch
-//^^^^^ keyword.control.exception.catch
-// ^ meta.group
-// ^ meta.block
- foobar = 0
-// ^^^^^^^^^^ meta.catch meta.block
-} finally {
-// <- meta.block
-//^^^^^^^^^^ meta.finally
-//^^^^^^^ keyword.control.exception.finally
-// ^ meta.block
- foobar += 1
-// ^^^^^^^^^^^ meta.finally meta.block
-}
-// <- meta.block
-
-switch // Incomplete statement
- 42;
-// ^^ constant.numeric - meta.switch
-
-switch(x){}/**/
-// ^^ - meta.switch
-
-try{}/**/
-// ^ - meta.try
-catch{}/**/
-// ^ - meta.catch
-finally{}/**/
-// ^ - meta.finally
-
class MyClass extends TheirClass {
-// <- storage.type.class
+// <- keyword.declaration.class
// ^^^^^^^ entity.name.class
// ^^^^^^^ storage.modifier.extends
// ^^^^^^^^^^ entity.other.inherited-class
@@ -982,18 +485,18 @@ class MyClass extends TheirClass {
// ^^ constant.numeric
f = a => b;
-// ^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^ meta.function
// ^ variable.parameter.function
g = function() {};
-// ^^^^^^^^^^^^^^^^^ meta.function
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
#h = function() {};
-// ^^^^^^^^^^^^^^^^^^ meta.function
// ^ punctuation.definition.variable
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
static x = 42;
// ^^^^^^ storage.modifier.js
@@ -1030,32 +533,17 @@ class MyClass extends TheirClass {
// ^^ constant.numeric
static f = a => b;
-// ^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^ meta.function
// ^ variable.parameter.function
static g = function() {};
-// ^^^^^^^^^^^^^^^^^ meta.function
// ^ entity.name.function variable.other.readwrite
-
- a, 'b' = 50, "c", [d] = 100, #e;
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-
- static a, 'b' = 50, "c", [d] = 100, #e;
-// ^^^^^^ storage.modifier.js
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
-// ^ variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
foo // You thought I was a field...
() { return '...but was a method all along!'; }
-// ^^ meta.class.js meta.block.js meta.function.declaration.js
+// ^^ meta.class meta.block meta.function
someMethod() {
return #e * 2;
@@ -1068,8 +556,13 @@ class MyClass extends TheirClass {
// ^^^^ meta.property.object
}
+ #privateMethod() {}
+// ^^^^^^^^^^^^^^^^^^^ meta.function
+// ^^^^^^^^^^^^^^ entity.name.function.js
+// ^ punctuation.definition.js
+
constructor(el)
-// ^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^ meta.function
// ^ entity.name.function.constructor
{
// ^ meta.class meta.block meta.function meta.block punctuation.section.block
@@ -1079,7 +572,7 @@ class MyClass extends TheirClass {
// ^ meta.class meta.block meta.function meta.block punctuation.section.block
get foo()
-// ^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^ meta.function
// <- storage.type.accessor
// ^ entity.name.function
{
@@ -1088,18 +581,18 @@ class MyClass extends TheirClass {
static foo(baz) {
// ^^^^^^ storage.modifier
-// ^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^ meta.function
// ^^^ entity.name.function
}
qux()
-// ^^^^^ meta.function.declaration
+// ^^^^^ meta.function
{ }
// ^ meta.class meta.block meta.block punctuation.section.block.begin
get bar () {
-// ^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^ meta.function
// ^ meta.class meta.block meta.block punctuation.section.block.begin
// <- storage.type.accessor
// ^ entity.name.function
@@ -1107,20 +600,20 @@ class MyClass extends TheirClass {
}
baz() { return null }
-// ^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^ meta.function
// <- entity.name.function
get() { return "foobar"; }
-// ^^^^^ meta.function.declaration.js
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^ entity.name.function.js - storage.type.accessor
set (value) { return value; }
-// ^^^^^^^^^^^ meta.function.declaration.js
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^ variable.parameter.function.js
// ^^^ entity.name.function.js - storage.type.accessor
set abc(value1, value2) { return value1 + value2; }
-// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration.js
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^ storage.type.accessor - entity.name.function.js
// ^^^ entity.name.function.js
// ^^^^^^ variable.parameter.function.js
@@ -1154,19 +647,23 @@ class MyClass extends TheirClass {
// ^^^ entity.name.function
['foo']() {}
-// ^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^ meta.function
static ['foo']() {}
-// ^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^ meta.function
async foo() {}
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration.async
*foo() {}
// ^ keyword.generator.asterisk
+ async *foo() {}
+// ^^^^^ keyword.declaration.async
+// ^ keyword.generator.asterisk
+
static async foo() {}
-// ^^^^^ storage.type
+// ^^^^^ keyword.declaration.async
}
// <- meta.block punctuation.section.block.end
@@ -1208,79 +705,100 @@ class Foo extends getSomeClass() {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class
// ^^^^^^^ storage.modifier.extends
// ^^^^^^^^ meta.class meta.class
-// ^^^^^ storage.type.class
+// ^^^^^ keyword.declaration.class
// Better highlighting while typing.
class
class
-// <- storage.type.class - entity.name.class
+// <- keyword.declaration.class - entity.name.class
class{}/**/
// ^ - meta.class
- () => {}
+ () => {};
// ^^^^^^^^ meta.function - meta.function meta.function
-// ^^^^^ meta.function.declaration
+// ^^ meta.function.parameters
// ^ punctuation.section.group.begin
// ^ punctuation.section.group.end
-// ^^ storage.type.function.arrow
+// ^^ keyword.declaration.function.arrow
// ^^ meta.block
// ^ punctuation.section.block
// ^ punctuation.section.block
- @foo class Foo {}
-// ^^^^ meta.annotation
-// ^ punctuation.definition.annotation
-// ^^^ variable.annotation
-// ^^^^^ storage.type.class
+ () => {};
+// ^^^^^ meta.function
+// ^ punctuation.section.group.begin
+// ^ punctuation.section.group.end
+// ^ meta.block punctuation.section.block.begin
+// ^ meta.block punctuation.section.block.end
+
+ (foo, bar = 42)
+// ^^^^^^^^^^^^^^^ meta.function.parameters
+// ^^^ meta.binding.name
+// ^^^ meta.binding.name
+ => 42;
+// ^^^^^ meta.function
+// ^^ keyword.declaration.function.arrow
+
+ foo
+// ^^^ meta.function.parameters variable.parameter.function
+ => 42;
+// ^^^^^ meta.function
+// ^^ keyword.declaration.function.arrow
+
+ async x => y;
+// ^^^^^^^^^^^^ meta.function
+// ^^^^^ keyword.declaration.async
+// ^ meta.function.parameters variable.parameter.function
+// ^^ keyword.declaration.function.arrow
+// ^ variable.other.readwrite
- @foo.bar class Foo {}
-// ^^^^^^^^ meta.annotation
-// ^ punctuation.definition.annotation
-// ^^^ variable.other.readwrite - variable.annotation
-// ^^^ variable.annotation
-// ^^^^^ storage.type.class
+ async (x) => y;
+// ^^^^^^^^^^^^^^ meta.function
+// ^^^^^ keyword.declaration.async
+// ^^^ meta.function.parameters
+// ^ variable.parameter.function
+// ^^ keyword.declaration.function.arrow
+// ^ variable.other.readwrite
- @(whatever) class Foo {}
-// ^^^^^^^^^^^ meta.annotation
-// ^ punctuation.definition.annotation
-// ^^^^^^^^^^ meta.group
-// ^^^^^ storage.type.class
+ async => {};
+// ^^^^^^^^^^^ meta.function
+// ^^^^^ meta.function.parameters variable.parameter.function
+// ^^ keyword.declaration.function.arrow
+
+ async;
+// ^^^^^ variable.other.readwrite
-() => {}
-// <- meta.function.declaration punctuation.section.group.begin
- // <- meta.function.declaration punctuation.section.group.end
-//^^^ meta.function.declaration
-// ^ meta.block punctuation.section.block.begin
-// ^ meta.block punctuation.section.block.end
+ async ();
+// ^^^^^ variable.function
const test = ({a, b, c=()=>({active:false}) }) => {};
// ^ entity.name.function
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.binding.destructuring
// ^ punctuation.section.block.begin
// ^ variable.parameter
// ^ variable.parameter
// ^ variable.parameter
-// ^^^^ meta.function.declaration meta.function.declaration
+// ^^^^ meta.function meta.function
+// ^^ meta.function meta.function.parameters
// ^ punctuation.section.group.begin
// ^ punctuation.section.group.end
// ^^^^^^^^^^^^^^^^ meta.group
// ^ constant.language
// ^ punctuation.section.block.end
-// We can't currently detect this properly, but we need to consume => properly
([a,
b]) => { return x; }
// ^^^^^^^^^^^^^^^^ meta.function
-// ^^ storage.type.function.arrow
+// ^^ keyword.declaration.function.arrow
// ^^^^^^ meta.block keyword.control.flow
(
()
=> { return; }
-// ^^ storage.type.function.arrow
+// ^^ keyword.declaration.function.arrow
// ^^^^^^^^^^^ meta.block - meta.mapping
// ^^^^^^ keyword.control.flow
);
@@ -1289,42 +807,40 @@ const test = ({a, b, c=()=>({active:false}) }) => {};
a = {},
// ^ keyword.operator.assignment
// ^^ punctuation.section.block
-// ^ punctuation.separator.comma - keyword.operator.comma
+// ^ punctuation.separator.parameter - keyword.operator.comma
b,
-// ^ punctuation.separator.comma - keyword.operator.comma
+// ^ punctuation.separator.parameter - keyword.operator.comma
}) => null;
-// ^^ storage.type.function.arrow
+// ^^ keyword.declaration.function.arrow
MyClass.foo = function() {}
-// ^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ support.class
// ^ entity.name.function
+// ^^^^^^^^^^^^^ meta.function
MyClass.foo = () => {}
-// ^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ support.class
// ^ entity.name.function
+// ^^^^^^^^ meta.function
xhr.onload = function() {}
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
-// <- support.class.js
// ^ entity.name.function
+// ^^^^^^^^^^^^^ meta.function
xhr.onload = () => {}
-// ^^^^^^^^^^^^^^^ meta.function.declaration
-// <- support.class.js
// ^ entity.name.function
+// ^^^^^^^^ meta.function
var simpleArrow = foo => bar;
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function
-// ^ variable.parameter.function
-// ^ storage.type.function.arrow
+// ^^^^^^^^^^ meta.function
+// ^^^ variable.parameter.function
+// ^^ keyword.declaration.function.arrow
var Proto = () => {
-// ^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function
-// ^ storage.type.function.arrow
+// ^^^^^^^ meta.function
+// ^ keyword.declaration.function.arrow
this._var = 1;
}
@@ -1332,16 +848,16 @@ var notAFunc = function$;
// ^^^^^^^^ - entity.name.function
Proto.prototype.getVar = () => this._var;
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^ meta.function
// ^ support.class
// ^ support.constant.prototype
// ^ entity.name.function
-// ^ storage.type.function.arrow
+// ^ keyword.declaration.function.arrow
Class3.prototype = function() {
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ support.class
// ^ support.constant.prototype
+// ^^^^^^^^^^^^ meta.function
}
Proto.prototype.attr
@@ -1351,9 +867,9 @@ Proto.prototype.attr
Proto.prototype = {
funcName: function() {
-// ^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^^^^^^^^ entity.name.function
// ^ punctuation.separator.key-value
+// ^^^^^^^^^^^^ meta.function
}
}
@@ -1363,14 +879,20 @@ sources.DOM
.status()
// ^ meta.function-call.method variable.function
+ foo.#bar();
+// ^^^^^^^^^^ meta.function-call.method.js
+// ^^^^ variable.function.js
+// ^ punctuation.definition.js
+// ^^ meta.group.js
+
return new Promise(resolve => preferenceObject.set({value}, resolve));
// ^ meta.function-call.constructor punctuation.section.group.end
var anotherSingle = function(){a = param => param; return param2 => param2 * a}
-// ^ meta.function.declaration variable.parameter.function
+// ^ meta.function variable.parameter.function
// ^ meta.block meta.block variable.other.readwrite
// ^ meta.block punctuation.terminator.statement
-// ^ meta.function.declaration variable.parameter.function
+// ^ meta.function variable.parameter.function
// ^ meta.block meta.block variable.other.readwrite
// ^ meta.block punctuation.section.block.end
@@ -1381,17 +903,17 @@ var foo = ~{a:function(){}.a()}
// ^ keyword.operator.bitwise
// ^ punctuation.section.block.begin
// ^^^^^^^^^^^^^^^^^^^^ meta.mapping
-// ^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^ meta.function
// ^ entity.name.function
// ^ punctuation.separator.key-value
-// ^^^^^^^^ storage.type.function
+// ^^^^^^^^ keyword.declaration.function
// ^ punctuation.section.group.begin
// ^ punctuation.section.group.end
// ^ meta.block punctuation.section.block.begin
// ^ meta.block punctuation.section.block.end
// ^ meta.mapping
-// ^^^ meta.function.declaration
-// ^ entity.name.function
+// ^^^ - meta.function
+// ^ variable.function - entity.name.function
// ^ punctuation.section.group.begin
// ^ punctuation.section.group.end
// ^ punctuation.section.block.end
@@ -1420,10 +942,10 @@ var instance = new Constructor(param1, param2)
// ^ punctuation.section.group.end
var obj = new function() {}();
-// ^^^^^^^^ storage.type
+// ^^^^^^^^ keyword.declaration.function
var obj2 = new class Foo{}();
-// ^^^^^ storage.type.class
+// ^^^^^ keyword.declaration.class
this.func()
// <- variable.language.this
@@ -1655,16 +1177,16 @@ var re = /^\/[^/]+/;
// ^ meta.brackets keyword.operator.comma - meta.sequence - punctuation
define(['common'], function(common) {
-// ^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^ meta.function
var namedFunc = function() {
-// ^ meta.function.declaration
+// ^ meta.function
}
});
new FooBar(function(){
-// ^ meta.function.declaration
+// ^ meta.function
var namedFunc2 = function() {
-// ^ meta.function.declaration
+// ^ meta.function
}
})
@@ -1684,7 +1206,7 @@ new FooBar(function(){
{
// <- meta.block punctuation.section.block.begin
let foo = 1;
-// ^^^ meta.block storage.type
+// ^^^ meta.block keyword.declaration
// ^^^ variable.other.readwrite
}
// <- meta.block punctuation.section.block.end
@@ -1695,7 +1217,7 @@ var test =
var arrowFuncBraceNextLine = () => /* comments! */
// ^ entity.name.function
-// ^^ storage.type.function
+// ^^ keyword.declaration.function
// ^^^^^^^^^^^^^^^ comment
{
foo.bar();
@@ -1736,11 +1258,11 @@ $varname.method()
// ^ variable.other.dollar
$.fn.new_plugin = function() {}
-// <- support.class.dollar.only punctuation.dollar
+// <- variable.other.dollar.only punctuation.dollar
$var.fn.name = () => {}
-// <- support.class.dollar punctuation.dollar - support.class.dollar.only
-// ^ support.class.dollar - punctuation.dollar
+// <- variable.other.dollar punctuation.dollar - variable.other.dollar.only
+// ^ variable.other.dollar - punctuation.dollar
someFunction(() => [() => 'X']);
// ^ punctuation.section.brackets.end
@@ -1799,8 +1321,14 @@ return/*
//^^^^^^ meta.block - meta.mapping
const abc = new Set
-if (true) {};
-// <- keyword.control.conditional
+
+ const x =
+ const y = 1; // Better highlighting while typing.
+// ^^^^^ keyword.declaration
+
+ let x =
+ const y = 1; // Better highlighting while typing.
+// ^^^^^ keyword.declaration
var o = {
a,
@@ -1834,8 +1362,8 @@ var str = `Hello, ${name}!`;
function yy (a, b) {
// ^^^^^^^^^^^^^^^^^ meta.function
-// ^^^^^^^^^^^^^^^ meta.function.declaration
// ^^ entity.name.function
+// ^^^^^^ meta.function.parameters
// ^ punctuation.section.group.begin
// ^ variable.parameter.function
// ^ punctuation.separator.parameter.function
@@ -1848,80 +1376,88 @@ function yy (a, b) {
// Integers
123_456_789_0n;
-// ^^^^^^^^^^^^^^ constant.numeric.integer.decimal
-// ^ storage.type.numeric
+// ^^^^^^^^^^^^^ meta.number.integer.decimal.js constant.numeric.value.js
+// ^ meta.number.integer.decimal.js constant.numeric.suffix.js
0;
-// ^ constant.numeric.integer.decimal
+// ^ meta.number.integer.decimal.js constant.numeric.value.js
123 .foo;
-// ^^^ constant.numeric.integer.decimal
+// ^^^ meta.number.integer.decimal.js constant.numeric.value.js
// ^ punctuation.accessor
// ^^^ meta.property.object
+123;
// ^ keyword.operator.arithmetic
-// ^^^ constant.numeric.integer.decimal - keyword
+// ^^^ meta.number.integer.decimal.js constant.numeric.value.js - keyword
-123;
// ^ keyword.operator.arithmetic
-// ^^^ constant.numeric.integer.decimal - keyword
+// ^^^ meta.number.integer.decimal.js constant.numeric.value.js - keyword
+ 123;
// ^ keyword.operator.arithmetic
+// ^ - keyword - constant
+// ^^^ meta.number.integer.decimal.js constant.numeric.value.js - keyword
123xyz;
// ^^^^^^ invalid.illegal.numeric.decimal
0123456789;
-// ^^^^^^^^^^ constant.numeric.integer.octal invalid.deprecated.numeric.octal
+// ^ meta.number.integer.octal.js constant.numeric.base.js invalid.deprecated.numeric.octal.js
+// ^^^^^^^^^ meta.number.integer.octal.js constant.numeric.value.js invalid.deprecated.numeric.octal.js
0123456789xyz;
// ^^^^^^^^^^^^^ invalid.illegal.numeric.octal
0123456789.xyz;
-// ^^^^^^^^^^ invalid.deprecated.numeric.octal
+// ^ meta.number.integer.octal.js constant.numeric.base.js invalid.deprecated.numeric.octal.js
+// ^^^^^^^^^ meta.number.integer.octal.js constant.numeric.value.js invalid.deprecated.numeric.octal.js
// ^ punctuation.accessor
// ^^^ meta.property.object
0123456789.123;
-// ^^^^^^^^^^ invalid.deprecated.numeric.octal
-// ^ punctuation.accessor
+// ^ meta.number.integer.octal.js constant.numeric.base.js invalid.deprecated.numeric.octal.js
+// ^^^^^^^^^ meta.number.integer.octal.js constant.numeric.value.js invalid.deprecated.numeric.octal.js
+// ^ punctuation.accessor.js
// ^^^ invalid.illegal.illegal-identifier
0b0110_1001_1001_0110n;
-// ^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.integer.binary
-// ^^ punctuation.definition.numeric.base
-// ^ storage.type.numeric
+// ^^ meta.number.integer.binary.js constant.numeric.base.js
+// ^^^^^^^^^^^^^^^^^^^ meta.number.integer.binary.js constant.numeric.value.js
+// ^ meta.number.integer.binary.js constant.numeric.suffix.js
0o0123_4567n;
-// ^^^^^^^^^^^^ constant.numeric.integer.octal
-// ^^ punctuation.definition.numeric.base
-// ^ storage.type.numeric
+// ^^ meta.number.integer.octal.js constant.numeric.base.js
+// ^^^^^^^^^ meta.number.integer.octal.js constant.numeric.value.js
+// ^ meta.number.integer.octal.js constant.numeric.suffix.js
0x01_23_45_67_89_ab_CD_efn;
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.integer.hexadecimal
-// ^^ punctuation.definition.numeric.base
-// ^ storage.type.numeric
+// ^^ meta.number.integer.hexadecimal.js constant.numeric.base.js
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.number.integer.hexadecimal.js constant.numeric.value.js
+// ^ meta.number.integer.hexadecimal.js constant.numeric.suffix.js
0B0; 0O0; 0X0;
-// ^^^ constant.numeric.integer.binary
-// ^^ punctuation.definition.numeric.base
-// ^^^ constant.numeric.integer.octal
-// ^^ punctuation.definition.numeric.base
-// ^^^ constant.numeric.integer.hexadecimal
-// ^^ punctuation.definition.numeric.base
+// ^^ meta.number.integer.binary.js constant.numeric.base.js
+// ^ meta.number.integer.binary.js constant.numeric.value.js
+// ^ punctuation.terminator.statement.js
+// ^^ meta.number.integer.octal.js constant.numeric.base.js
+// ^ meta.number.integer.octal.js constant.numeric.value.js
+// ^ punctuation.terminator.statement.js
+// ^^ meta.number.integer.hexadecimal.js constant.numeric.base.js
+// ^ meta.number.integer.hexadecimal.js constant.numeric.value.js
+// ^ punctuation.terminator.statement.js
0b1.foo;
// ^^^^^^^ - invalid
-// ^^^ constant.numeric.integer.binary
-// ^^ punctuation.definition.numeric.base
+// ^^ meta.number.integer.binary.js constant.numeric.base.js
+// ^ meta.number.integer.binary.js constant.numeric.value.js
// ^ punctuation.accessor
// ^^^ meta.property.object
0b1.0;
-// ^^^ constant.numeric.integer.binary
-// ^^ punctuation.definition.numeric.base
+// ^^ meta.number.integer.binary.js constant.numeric.base.js
+// ^ meta.number.integer.binary.js constant.numeric.value.js
// ^ punctuation.accessor
// ^ invalid.illegal.illegal-identifier
@@ -1932,25 +1468,27 @@ function yy (a, b) {
// Floats
1_234_567_890.123_456_789_0;
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant.numeric.float.decimal
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.number.float.decimal.js constant.numeric.value.js
+// ^ punctuation.separator.decimal.js
.123_456_789_0;
-// ^^^^^^^^^^^^^^ constant.numeric.float.decimal
+// ^^^^^^^^^^^^^^ meta.number.float.decimal.js constant.numeric.value.js
// ^ punctuation.separator.decimal
12345e6_7_8;
-// ^^^^^^^^^^^ constant.numeric.float.decimal
+// ^^^^^^^^^^^ meta.number.float.decimal.js constant.numeric.value.js
123.456e+789;
-// ^^^^^^^^^^^^ constant.numeric.float.decimal
+// ^^^^^^^^^^^^ meta.number.float.decimal.js constant.numeric.value.js
// ^ punctuation.separator.decimal
.123E-7_8_9;
-// ^^^^^^^^^^^ constant.numeric.float.decimal
+// ^^^^^^^^^^^ meta.number.float.decimal.js constant.numeric.value.js
// ^ punctuation.separator.decimal
0123.45;
-// ^^^^ constant.numeric.integer.octal invalid.deprecated.numeric.octal
+// ^ meta.number.integer.octal.js constant.numeric.base.js invalid.deprecated.numeric.octal.js
+// ^^^ meta.number.integer.octal.js constant.numeric.value.js invalid.deprecated.numeric.octal.js
// ^ punctuation.accessor
// ^^ invalid.illegal - constant.numeric
@@ -1961,7 +1499,7 @@ function yy (a, b) {
// ^^^^^^ invalid.illegal.numeric.decimal
123..foo;
-// ^^^^ constant.numeric.float.decimal
+// ^^^^ meta.number.float.decimal.js constant.numeric.value.js
// ^ punctuation.accessor
// ^^^ meta.property.object
@@ -1975,25 +1513,39 @@ debugger
a ?? b;
// ^^ keyword.operator.logical
- a.?b.?c;
+ a &&= b;
+// ^^^ keyword.operator.assignment.augmented
+
+ a ||= b;
+// ^^^ keyword.operator.assignment.augmented
+
+ a ??= b;
+// ^^^ keyword.operator.assignment.augmented
+
+ a ?.5 : .7;
+// ^ keyword.operator.ternary
+// ^^ constant.numeric
+// ^ keyword.operator.ternary
+
+ a?.b?.c;
// ^^ punctuation.accessor
// ^ meta.property.object
// ^^ punctuation.accessor
// ^ meta.property.object
- a.?[propName];
+ a?.[propName];
// ^^^^^^^^^^^^ meta.brackets
// ^^ punctuation.accessor
// ^ punctuation.section.brackets.begin
- a.?();
+ a?.();
// ^^^^^ meta.function-call
// ^ variable.function
// ^^^^ meta.group
// ^^ punctuation.accessor
// ^ punctuation.section.group.begin
- a.b.?();
+ a.b?.();
// ^^^^^^^ meta.function-call.method
// ^ variable.function
//
diff --git a/tests/syntax_test_js_bindings.js b/tests/syntax_test_js_bindings.js
index 29c4c9f..7db4f38 100644
--- a/tests/syntax_test_js_bindings.js
+++ b/tests/syntax_test_js_bindings.js
@@ -26,7 +26,7 @@ const [ x, [a, b], z] = value;
const [ x = 42, y = [a, b, c] ] = value;
// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.binding.destructuring.sequence
// ^ keyword.operator.assignment
-// ^^ meta.binding.destructuring.sequence.js constant.numeric.integer.decimal.js
+// ^^ meta.binding.destructuring.sequence.js meta.number.integer.decimal.js constant.numeric.value.js
// ^ keyword.operator.assignment
// ^^^^^^^^^ meta.sequence
// ^ variable.other.readwrite - meta.binding.name
@@ -57,7 +57,7 @@ const x;
// ^ meta.binding.name variable.other.readwrite
let
-// <- storage.type
+// <- keyword.declaration
w
// <- meta.binding.name variable.other.readwrite
,
@@ -82,7 +82,7 @@ let;
const
const x = 0;
-// <- storage.type
+// <- keyword.declaration
// Function parameters
@@ -105,7 +105,7 @@ function f ([ x, [a, b], z]) {}
function f ([ x = 42, y = [a, b, c] ]) {}
// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.binding.destructuring.sequence
// ^ keyword.operator.assignment
-// ^^ meta.binding.destructuring.sequence.js constant.numeric.integer.decimal.js
+// ^^ meta.function meta.binding.destructuring.sequence meta.number.integer.decimal constant.numeric.value
// ^ keyword.operator.assignment
// ^^^^^^^^^ meta.sequence
// ^ variable.other.readwrite - meta.binding.name
@@ -142,7 +142,7 @@ function f (new) {}
// ^^^ invalid.illegal.identifier meta.binding.name variable.parameter.function
let f = ([ x, y, ...z, ]) => {};
-// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^ meta.binding.destructuring.sequence
// ^ meta.binding.name variable.parameter.function
// ^ punctuation.separator.parameter
@@ -153,26 +153,26 @@ let f = ([ x, y, ...z, ]) => {};
// ^ punctuation.separator.parameter
let f = ([ x, [a, b], z]) => {};
-// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^ meta.binding.destructuring.sequence
// ^^^^^^ meta.binding.destructuring.sequence meta.binding.destructuring.sequence
// ^ meta.binding.name variable.parameter.function
// ^ meta.binding.name variable.parameter.function
let f = ([ x = 42, y = [a, b, c] ]) => {};
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.binding.destructuring.sequence
// ^ keyword.operator.assignment
-// ^^ meta.binding.destructuring.sequence.js constant.numeric.integer.decimal.js
+// ^^ meta.binding.destructuring.sequence.js meta.number.integer.decimal.js constant.numeric.value.js
// ^ keyword.operator.assignment
// ^^^^^^^^^ meta.sequence
// ^ variable.other.readwrite - meta.binding.name
let f = ({ a, b: c, ...d }) => {};
-// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
// ^^^^^^^^^^^^^^^^^ meta.binding.destructuring.mapping
// ^ meta.mapping.key meta.binding.name variable.parameter.function
// ^ punctuation.separator.parameter
@@ -195,12 +195,12 @@ let f = ({ 'a': x, "b": y, [c]: z }) => {};
// ^ meta.binding.name variable.parameter.function
let f = (a, ...rest) => {};
-// ^^^^^^^^^^^^^^^^ meta.function.declaration
// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^^^^^^ meta.function
// ^ meta.binding.name variable.parameter.function
// ^^^ keyword.operator.spread
// ^^^^ meta.binding.name variable.parameter.function
let f = (new) => {};
-// ^^^^^^^^^^^^^^^ meta.function
+// ^^^^^^^^^^^ meta.function
// ^^^ invalid.illegal.identifier meta.binding.name variable.parameter.function
diff --git a/tests/syntax_test_js_class.js b/tests/syntax_test_js_class.js
new file mode 100644
index 0000000..8a6a47a
--- /dev/null
+++ b/tests/syntax_test_js_class.js
@@ -0,0 +1,320 @@
+// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
+
+class MyClass extends TheirClass {
+// <- keyword.declaration.class
+// ^^^^^^^ entity.name.class
+// ^^^^^^^ storage.modifier.extends
+// ^^^^^^^^^^ entity.other.inherited-class
+// ^ meta.block punctuation.section.block.begin
+
+ x = 42;
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ 'y' = 42;
+// ^^^ meta.string string.quoted.single
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ "z" = 42;
+// ^^^ meta.string string.quoted.double
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ [w] = 42;
+// ^ punctuation.section.brackets.begin
+// ^ variable.other.readwrite
+// ^ punctuation.section.brackets.end
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ #v = 42;
+// ^ punctuation.definition.variable
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ f = a => b;
+// ^ entity.name.function variable.other.readwrite
+// ^^^^^^ meta.function
+// ^ variable.parameter.function
+
+ g = function() {};
+// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
+
+ #h = function() {};
+// ^ punctuation.definition.variable
+// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
+
+ class = null;
+// ^^^^^ variable.other.readwrite
+
+ static x = 42;
+// ^^^^^^ storage.modifier.js
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ static 'y' = 42;
+// ^^^^^^ storage.modifier.js
+// ^^^ meta.string string.quoted.single
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ static "z" = 42;
+// ^^^^^^ storage.modifier.js
+// ^^^ meta.string string.quoted.double
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ static [w] = 42;
+// ^^^^^^ storage.modifier.js
+// ^ punctuation.section.brackets.begin
+// ^ variable.other.readwrite
+// ^ punctuation.section.brackets.end
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ static #v = 42;
+// ^ punctuation.definition.variable
+// ^ variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^^ constant.numeric
+
+ static f = a => b;
+// ^ entity.name.function variable.other.readwrite
+// ^^^^^^ meta.function
+// ^ variable.parameter.function
+
+ static g = function() {};
+// ^ entity.name.function variable.other.readwrite
+// ^^^^^^^^^^^^^ meta.function
+
+ static = 42;
+// ^^^^^^ variable.other.readwrite
+
+ static() {}
+// ^^^^^^^^^^^ meta.function
+// ^^^^^^ entity.name.function
+
+ foo // You thought I was a field...
+ () { return '...but was a method all along!'; }
+// ^^ meta.class meta.block meta.function
+
+ someMethod() {
+ return #e * 2;
+// ^ punctuation.definition.variable
+// ^ variable.other.readwrite
+// ^ keyword.operator.arithmetic
+
+ for (const param of this.#data.get('value')) {}
+// ^ punctuation.definition.variable
+// ^^^^ meta.property.object
+ }
+
+ #privateMethod() {}
+// ^^^^^^^^^^^^^^^^^^^ meta.function
+// ^^^^^^^^^^^^^^ entity.name.function.js
+// ^ punctuation.definition.js
+
+ constructor(el)
+// ^^^^^^^^^^^^^^^ meta.function
+ // ^ entity.name.function.constructor
+ {
+// ^ meta.class meta.block meta.function meta.block punctuation.section.block
+ $.foo = "";
+ super(el);
+ }
+// ^ meta.class meta.block meta.function meta.block punctuation.section.block
+
+ get foo()
+// ^^^^^^^^^ meta.function
+ // <- storage.type.accessor
+ // ^ entity.name.function
+ {
+ return this._foo;
+ }
+
+ get *foo()
+
+ static foo(baz) {
+// ^^^^^^ storage.modifier
+// ^^^^^^^^^^ meta.function
+ // ^^^ entity.name.function
+
+ }
+
+ qux()
+// ^^^^^ meta.function
+ { }
+// ^ meta.class meta.block meta.block punctuation.section.block.begin
+
+ get bar () {
+// ^^^^^^^^^^^^ meta.function
+// ^ meta.class meta.block meta.block punctuation.section.block.begin
+ // <- storage.type.accessor
+ // ^ entity.name.function
+ return false;
+ }
+
+ baz() { return null }
+// ^^^^^^^^^^^^^^^^^^^^^ meta.function
+ // <- entity.name.function
+
+ get() { return "foobar"; }
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
+// ^^^ entity.name.function.js - storage.type.accessor
+
+ set (value) { return value; }
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
+// ^^^^^ variable.parameter.function.js
+// ^^^ entity.name.function.js - storage.type.accessor
+
+ set abc(value1, value2) { return value1 + value2; }
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function
+// ^^^ storage.type.accessor - entity.name.function.js
+// ^^^ entity.name.function.js
+// ^^^^^^ variable.parameter.function.js
+// ^ punctuation.separator.parameter.function.js
+// ^^^^^^ variable.parameter.function.js
+
+ static$
+// ^^^^^^^ - storage
+ () {};
+
+ constructor$() {}
+// ^^^^^^^^^^^^ entity.name.function - entity.name.function.constructor
+
+ @foo bar() {}
+// ^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^ variable.annotation
+// ^^^ entity.name.function
+
+ @foo.bar bar() {}
+// ^^^^^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^ variable.other.readwrite - variable.annotation
+// ^^^ variable.annotation
+// ^^^ entity.name.function
+
+ @(whatever) bar() {}
+// ^^^^^^^^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^^^^^^^^ meta.group
+// ^^^ entity.name.function
+
+ ['foo']() {}
+// ^^^^^^^^^^^^ meta.function
+
+ static ['foo']() {}
+// ^^^^^^^^^^^^ meta.function
+
+ async foo() {}
+// ^^^^^ keyword.declaration.async
+
+ *foo() {}
+// ^ keyword.generator.asterisk
+
+ async *foo() {}
+// ^^^^^ keyword.declaration.async
+// ^ keyword.generator.asterisk
+
+ static *foo() {}
+// ^^^^^^ storage.modifier
+// ^ keyword.generator.asterisk
+// ^^^ entity.name.function
+
+ static async foo() {}
+// ^^^^^^ storage.modifier
+// ^^^^^ keyword.declaration.async
+
+ async() {}
+// ^^^^^^^^^^ meta.function
+// ^^^^^ entity.name.function
+// ^^ meta.function.parameters
+// ^ punctuation.section.group.begin
+// ^ punctuation.section.group.end
+// ^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+
+ static async() {}
+// ^^^^^^ storage.modifier
+// ^^^^^ entity.name.function
+}
+// <- meta.block punctuation.section.block.end
+
+class Foo extends React.Component {
+// ^^^^^ - entity.other.inherited-class
+// ^^^^^^^^^ entity.other.inherited-class
+ constructor()
+ {}
+
+ [foo.bar](arg) {
+// ^^^ variable.other
+// ^^^ meta.property
+// ^^^ variable.parameter
+ return this.a;
+ }
+}
+
+class Foo extends (Foo).Bar {}
+// ^^^ entity.other.inherited-class
+
+class Foo extends Bar
+// ^^^ entity.other.inherited-class
+ .baz {}
+// ^^^^^^^ meta.class
+// ^ punctuation.accessor
+// ^^^ entity.other.inherited-class
+
+class Foo extends
+// ^^^^^^^ storage.modifier.extends
+Bar {}
+
+class Foo extends getSomeClass() {}
+// ^^^^^^^^^^^^ meta.function-call variable.function - entity.other.inherited-class
+
+ (class extends Bar {});
+// ^^^^^^^ storage.modifier.extends - entity.name.class
+
+ (class extends class {} {});
+// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.class
+// ^^^^^^^ storage.modifier.extends
+// ^^^^^^^^ meta.class meta.class
+// ^^^^^ keyword.declaration.class
+
+// Better highlighting while typing.
+class
+class
+// <- keyword.declaration.class - entity.name.class
+
+class{}/**/
+// ^ - meta.class
+
+ @foo class Foo {}
+// ^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^ variable.annotation
+// ^^^^^ keyword.declaration.class
+
+ @foo.bar class Foo {}
+// ^^^^^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^ variable.other.readwrite - variable.annotation
+// ^^^ variable.annotation
+// ^^^^^ keyword.declaration.class
+
+ @(whatever) class Foo {}
+// ^^^^^^^^^^^ meta.annotation
+// ^ punctuation.definition.annotation
+// ^^^^^^^^^^ meta.group
+// ^^^^^ keyword.declaration.class
diff --git a/tests/syntax_test_js_control.js b/tests/syntax_test_js_control.js
new file mode 100644
index 0000000..2cff94c
--- /dev/null
+++ b/tests/syntax_test_js_control.js
@@ -0,0 +1,365 @@
+// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
+
+ if ( true ) { } ;
+// ^^^^^^^^^^^^^^^ meta.conditional
+// ^^ keyword.control.conditional.if
+// ^^^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^ - meta.conditional
+// ^ punctuation.terminator.statement.empty
+
+ if ( true ) null ;
+// ^^^^^^^^^^^^^^^^^^ meta.conditional
+// ^^ keyword.control.conditional.if
+// ^^^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^^^^ constant.language.null
+// ^ punctuation.terminator.statement - punctuation.terminator.statement.empty
+// ^ - meta.conditional
+
+ if (true) {}/**/
+// ^^^^ - meta.conditional
+
+ if (true) ;
+// ^^^^^^^^^^ meta.conditional
+// ^ punctuation.terminator.statement.empty
+
+ if (true) ;
+ else { } ;
+// ^^^^^^^^ meta.conditional
+// ^^^^ keyword.control.conditional.else
+// ^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^ - meta.conditional
+// ^ punctuation.terminator.statement.empty
+
+ else if (true) { } ;
+// ^^^^^^^^^^^^^^^^^^ meta.conditional
+// ^^^^^^^ keyword.control.conditional.elseif
+// ^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^^^ - meta.conditional
+// ^ punctuation.terminator.statement.empty
+
+ do { } while ( true ) ;
+// ^^^^^^^^^^^^^^^^^^^^^ meta.do-while
+// ^^ keyword.control.loop.do-while
+// ^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^^^^^ keyword.control.loop.while
+// ^^^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^ - meta.do-while
+// ^ punctuation.terminator.statement.empty
+
+ do 42 ; while ( true ) ;
+// ^^^^^^^^^^^^^^^^^^^^^^ meta.do-while
+// ^^ keyword.control.loop.do-while
+// ^^ meta.number.integer.decimal constant.numeric.value
+// ^ punctuation.terminator.statement
+// ^^^^^ keyword.control.loop.while
+// ^^^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^ punctuation.terminator.statement.empty
+
+ do {} while (false)/**/
+// ^ - meta.do-while
+
+ for (var i = 0; i < 10; i++) { } ;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.group
+// ^ punctuation.section.group
+// ^^^ storage.type
+// ^ meta.binding.name variable.other.readwrite
+// ^ keyword.operator.assignment
+// ^ meta.number.integer.decimal constant.numeric.value
+// ^ punctuation.separator.expression
+// ^ variable.other.readwrite
+// ^ keyword.operator.comparison
+// ^^ meta.number.integer.decimal constant.numeric.value
+// ^ punctuation.separator.expression
+// ^ variable.other.readwrite
+// ^^ keyword.operator.arithmetic
+// ^ punctuation.section.group
+// ^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^ - meta.for
+// ^ punctuation.terminator.statement.empty
+
+ for (;;) 42;
+// ^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^ meta.group
+// ^ punctuation.section.group
+// ^^ punctuation.separator.expression
+// ^ punctuation.section.group
+// ^^ meta.number.integer.decimal constant.numeric.value
+// ^ punctuation.terminator.statement - punctuation.terminator.statement.empty
+// ^ - meta.for
+
+ for (; x in list;) {}
+// ^^^^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^^^^ meta.group
+// ^ punctuation.separator.expression
+// ^^ keyword.operator
+// ^ punctuation.separator.expression
+
+ for (a[x in list];;) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^^^^^^ meta.group
+// ^^^^^^^^^^^ meta.brackets
+// ^^ keyword.operator
+// ^ punctuation.separator.expression
+// ^ punctuation.separator.expression
+
+ for (;function () {}/a/g;) {}
+// ^ keyword.operator
+
+ for (const x in list) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^^^^^^^ meta.group
+// ^^^^^ storage.type
+// ^^ keyword.operator.word
+
+ for (const x of list) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^^^^^^^ meta.group
+// ^^^^^ storage.type
+// ^^ keyword.operator.word
+
+ for (x in list) {}
+// ^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^ meta.group
+// ^^ keyword.operator.word
+
+ for (x of list) {}
+// ^^^^^^^^^^^^^^^^^^ meta.for
+// ^^^ keyword.control.loop.for
+// ^^^^^^^^^^^ meta.group
+// ^^ keyword.operator.word
+
+ for await (const x of list) {}
+// ^^^ keyword.control.loop.for
+// ^^^^^ keyword.control.flow.await
+
+for
+ 42;
+// ^^ constant.numeric - meta.for
+
+for(;;){}/**/
+// ^ - meta.for
+
+{}/**/
+//^ - meta.block
+
+while (true)
+// ^^^^^^^^^ meta.while
+// ^^^^ meta.group
+{
+// <- meta.block
+ x = yield;
+// ^^^^^ keyword.control.flow.yield
+
+ x = yield * 42;
+// ^^^^^ keyword.control.flow.yield
+// ^ keyword.generator.asterisk
+
+ x = yield
+ function f() {}
+ [];
+// ^^ meta.sequence - meta.brackets
+
+
+ x = yield*
+ function f() {}
+ [];
+// ^^ meta.brackets - meta.sequence
+
+ y = await 42;
+// ^^^^^ keyword.control.flow.await
+
+ y = yield await 42;
+// ^^^^^ keyword.control.flow.yield
+// ^^^^^ keyword.control.flow.await
+
+ yield (parenthesized_expression);
+// ^^^^^ keyword.control.flow.yield
+
+ yield `template`;
+// ^^^^^ keyword.control.flow.yield
+
+ break;
+// ^^^^^ keyword.control.flow.break
+
+ break foo;
+// ^^^^^ keyword.control.flow.break
+// ^^^ variable.label
+
+ break
+ foo;
+// ^^^ variable.other.readwrite - variable.label
+
+ break/**/foo;
+// ^^^ variable.label - variable.other.readwrite
+
+ break/*
+ */foo;
+// ^^^ variable.other.readwrite - variable.label
+
+ break function;
+// ^^^^^^^^ invalid.illegal.identifier variable.label
+
+ continue;
+// ^^^^^^^^ keyword.control.flow.continue
+
+ continue foo;
+// ^^^^^^^^ keyword.control.flow.continue
+// ^^^ variable.label
+
+ continue
+ foo;
+// ^^^ variable.other.readwrite - variable.label
+
+ continue/**/foo;
+// ^^^ variable.label - variable.other.readwrite
+
+ continue/*
+ */ foo;
+// ^^^ variable.other.readwrite - variable.label
+
+ goto;
+// ^^^^ variable.other.readwrite - keyword
+}
+// <- meta.block
+
+ while (true) 42 ;
+// ^^^^^^^^^^^^^ meta.while
+// ^^^^^ keyword.control.loop.while
+// ^^^^^^ meta.group
+// ^ punctuation.section.group.begin
+// ^^^^ constant.language.boolean.true
+// ^ punctuation.section.group.end
+// ^^ meta.number.integer.decimal constant.numeric.value
+// ^ punctuation.terminator.statement - punctuation.terminator.statement.empty
+
+while // Incomplete statement
+ 42;
+// ^^ constant.numeric - meta.while
+
+while(false){}/**/
+// ^ - meta.while
+
+with (undefined) {
+// <- keyword.control.import.with
+//^^^^^^^^^^ meta.with
+// ^^^^^^^^^ constant.language.undefined
+ return;
+// ^^^^^^ meta.with.js meta.block.js keyword.control.flow.return
+}
+
+with // Incomplete statement
+ 42;
+// ^^ constant.numeric - meta.while
+
+with(false){}/**/
+// ^ - meta.with
+
+switch ($foo) {
+// <- meta.switch.js keyword.control.conditional.switch
+// ^^^^^^^^^^^^ meta.switch
+//^^^^ keyword.control.conditional.switch
+// ^^^^ meta.group
+// ^ meta.block punctuation.section.block.begin
+ case foo:
+ // ^ meta.switch meta.block keyword.control.conditional.case
+ // ^ - punctuation.separator.key-value
+ qux = 1;
+ break;
+ // ^ keyword.control.flow.break
+ case "baz":
+ // ^ keyword.control.conditional.case
+ // ^ - punctuation.separator.key-value string
+ qux = 2;
+ break;
+ // ^ keyword.control.flow.break
+ default:
+ // ^ meta.switch meta.block keyword.control.conditional.default
+ // ^ - punctuation.separator.key-value
+ qux = 3;
+
+ case$
+// ^^^^^ - keyword
+ ;
+
+ default$
+// ^^^^^^^^ - keyword
+ ;
+
+ case 0: {}
+ case 1:
+// ^^^^ keyword.control.conditional.case
+}
+// <- meta.block punctuation.section.block.end
+
+try {
+// <- meta.try keyword.control.exception.try
+// ^^ meta.try
+// ^ meta.block
+ foobar = qux.bar();
+// ^^^^^^^^^^^^^^^^^^^ meta.try meta.block
+} catch (e) {
+// <- meta.block
+//^^^^^^^^^^^^ meta.catch
+//^^^^^ keyword.control.exception.catch
+// ^ meta.group
+// ^ meta.block
+ foobar = 0
+// ^^^^^^^^^^ meta.catch meta.block
+} finally {
+// <- meta.block
+//^^^^^^^^^^ meta.finally
+//^^^^^^^ keyword.control.exception.finally
+// ^ meta.block
+ foobar += 1
+// ^^^^^^^^^^^ meta.finally meta.block
+}
+// <- meta.block
+
+switch // Incomplete statement
+ 42;
+// ^^ constant.numeric - meta.switch
+
+switch(x){}/**/
+// ^^ - meta.switch
+
+try{}/**/
+// ^ - meta.try
+catch{}/**/
+// ^ - meta.catch
+finally{}/**/
+// ^ - meta.finally
diff --git a/tests/syntax_test_js_import_export.js b/tests/syntax_test_js_import_export.js
new file mode 100644
index 0000000..04b8b8f
--- /dev/null
+++ b/tests/syntax_test_js_import_export.js
@@ -0,0 +1,231 @@
+// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
+
+import TheirClass from "./mypath";
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
+// ^ keyword.control.import-export
+// ^ keyword.control.import-export
+
+import {identifier, otherIdentifier} from "somewhere";
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import
+// ^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^ meta.import meta.block variable.other.readwrite
+
+import thing, {identifier as otherIdentifier}, * as otherName from "otherplace";
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.import
+// ^ keyword.control.import-export
+// ^ variable.other.readwrite
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
+// ^ variable.other.readwrite
+// ^ keyword.control.import-export
+// ^ variable.other.readwrite
+// ^ constant.other.js
+// ^ keyword.control.import-export
+
+import 'module';
+// ^^^^^^^^^^^^^ meta.import
+
+// Better highlighting while typing.
+import
+import;
+// <- keyword.control.import-export
+
+import;/**/
+// ^ - meta.import
+
+export { name1, name2 as name3 };
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
+// ^ punctuation.separator.comma
+// ^^ keyword.control.import-export
+
+export let name1, name2;
+//^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^ keyword.declaration
+// ^ punctuation.separator.comma
+
+export var name3;
+//^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^ keyword.declaration
+
+export const name1 = 5;
+//^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^^^ keyword.declaration
+// ^ keyword.operator.assignment
+
+export let foo = 123 // No semicolon
+export function bar() {}
+// <- keyword.control.import-export
+
+export function foo() {};
+//^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^ meta.function
+// ^ punctuation.terminator.statement.empty
+
+export function* foo() {};
+//^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^ meta.function
+// ^ punctuation.terminator.statement.empty
+
+export async function foo() {};
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.function
+// ^ punctuation.terminator.statement.empty
+
+export class Foo {};
+//^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^ meta.class
+// ^ punctuation.terminator.statement.empty
+
+export default expression;
+//^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^ keyword.control.import-export
+
+export default function (a) { };
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^ meta.function
+// ^ punctuation.terminator.statement.empty - meta.export
+
+export default function* (a) { };
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^ meta.function
+// ^ punctuation.terminator.statement.empty - meta.export
+
+export default function name1(b) { }
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^ keyword.control.import-export
+// ^^^^^^^^ keyword.declaration.function
+// ^ entity.name.function
+
+export default class Foo {};
+//^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^ meta.class
+// ^ punctuation.terminator.statement.empty
+
+export default +function (a) { };
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^^^^ keyword.control.import-export
+// ^^^^^^^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^ meta.function
+
+export { name1 as default };
+//^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^^^ meta.block
+// ^ keyword.control.import-export
+// ^ keyword.control.import-export
+
+export * from "./othermod";
+//^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^ constant.other
+// ^ keyword.control.import-export
+
+export { name1, name2 } from "./othermod";
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^ meta.block
+// ^ punctuation.section.block.begin
+// ^ punctuation.section.block.end
+// ^ keyword.control.import-export
+
+export { import1 as name1, import2 as name2, nameN } from "./othermod";
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export
+//^ keyword.control.import-export
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.block
+// ^ keyword.control.import-export
+// ^ keyword.control.import-export
+// ^ keyword.control.import-export
+
+// Better highlighting while typing.
+export
+export;
+// <- keyword.control.import-export
+
+export;/**/
+// ^ - meta.export
+
+import * as
+ alias from "module";
+// ^^^^^^^^^^^^^^^^^^^^^ meta.import.js
+
+import { member as
+ alias } from "module";
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
+
+import { * as
+ alias } from "module";
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.import.js
+
+export { member as
+ alias } from "module";
+// ^^^^^^^^^^^^^^^^^^^^^^^ meta.export.js
+
+export { member as
+ default } from "module";
+// ^^^^^^^^^^^^^^^^^^^^^^^^^ meta.export.js
+
+let from;
+// ^^^^ variable.other.readwrite.js
+
+import from from "./othermod";
+// ^^^^ variable.other.readwrite.js
+
+import { from } from "./othermod";
+// ^^^^ variable.other.readwrite.js
+
+export from from "./othermod";
+// ^^^^ variable.other.readwrite.js
+
+export { from } from "./othermod";
+// ^^^^ variable.other.readwrite.js
+
+export default$
+// ^^^^^^^^ - keyword
+;
+
+let x = import.meta;
+// ^^^^^^^^^^^ - meta.import
+// ^^^^^^ keyword.import
+// ^ punctuation.accessor
+// ^^^^ variable.language.import
+
+ import.meta;
+// ^^^^^^^^^^^ - meta.import
+// ^^^^^^ keyword.import
+// ^ punctuation.accessor
+// ^^^^ variable.language.import
+
+ import
+// ^^^^^^ - meta.import
+ .meta;
+// ^^^^^ - meta.import
+// ^ punctuation.accessor
+// ^^^^ variable.language.import
+
+ import('foo');
+// ^^^^^^ keyword.import
+// ^^^^^^^ meta.group
+
+ import
+// ^^^^^^ - meta.import
+ ('foo');
+// ^^^^^^^ meta.group
diff --git a/tests/syntax_test_js_jsdoc.js b/tests/syntax_test_js_jsdoc.js
new file mode 100644
index 0000000..629e3b6
--- /dev/null
+++ b/tests/syntax_test_js_jsdoc.js
@@ -0,0 +1,42 @@
+// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
+
+ /**@a*/
+// ^^^ punctuation.definition.comment.begin
+// ^^ entity.other.attribute-name.documentation
+// ^^ punctuation.definition.comment.end - entity.other.attribute-name.documentation
+// ^^^^^^^ comment.block.documentation.js
+
+/** @a b */
+// ^^ entity.other.attribute-name.documentation
+// ^ - entity.other.attribute-name.documentation
+// ^^ punctuation.definition.comment.end
+
+/** @a@b */
+// ^^ entity.other.attribute-name.documentation
+// ^^ - entity.other.attribute-name.documentation
+
+/**
+ * @a b
+// ^^ entity.other.attribute-name.documentation
+// ^ comment.block.documentation
+*/
+// <- punctuation.definition.comment.end
+
+/**
+ * First line
+ * @a @b c */
+// ^^ entity.other.attribute-name.documentation
+// ^^ - entity.other.attribute-name.documentation
+// ^^^^ comment.block.documentation
+// ^^^^ - comment.block.documentation comment.block.documentation
+// ^^ comment.block.documentation punctuation.definition.comment.end
+
+/**
+
+ @a */
+//^^ - entity.other.attribute-name.documentation
+// ^^ punctuation.definition.comment.end
+
+/*@a */
+//^^ - entity.other.attribute-name.documentation
+// ^^ punctuation.definition.comment.end
diff --git a/tests/syntax_test_jsx.js b/tests/syntax_test_jsx.jsx
similarity index 78%
rename from tests/syntax_test_jsx.js
rename to tests/syntax_test_jsx.jsx
index 8d6dda2..43733ab 100644
--- a/tests/syntax_test_jsx.js
+++ b/tests/syntax_test_jsx.jsx
@@ -1,4 +1,5 @@
// SYNTAX TEST "Packages/Babel/JavaScript (Babel).sublime-syntax"
+
;
// ^^^^^^^ meta.jsx meta.tag
// ^ punctuation.definition.tag.begin
@@ -42,9 +43,9 @@
// ^^^^^^^^^^^ meta.jsx
// ^^^^^ - meta.jsx
-// ^ keyword.operator.relational
+// ^ keyword.operator.comparison
// ^^^ variable
-// ^ keyword.operator.relational
+// ^ keyword.operator.comparison
0;
<>Hello!>;
@@ -60,9 +61,9 @@
// ^^^^^ - meta.jsx
-// ^ keyword.operator.relational
+// ^ keyword.operator.comparison
// ^^^ variable
-// ^ keyword.operator.relational
+// ^ keyword.operator.comparison
0;
;
@@ -70,7 +71,7 @@
+
+ {/* foo */}
+// ^^^^^^^^^^^ meta.jsx meta.interpolation comment.block - source.embedded
+// ^ punctuation.definition.interpolation.begin
+// ^^ punctuation.definition.comment.begin
+// ^^ punctuation.definition.comment.end
+// ^ punctuation.definition.interpolation.end
+
+ {/* foo */ bar}
+// ^^^^^^^^^^^^^^^ meta.jsx meta.interpolation
+// ^^^^^^^^^^^^^ source.js.embedded
+// ^ punctuation.definition.interpolation.begin - comment
+// ^^ punctuation.definition.comment.begin
+// ^^ punctuation.definition.comment.end
+// ^^^^^ - comment
+// ^^^ meta.jsx meta.interpolation variable.other.readwrite
+// ^ punctuation.definition.interpolation.end
+
+;
+
+ ;
+// ^^^^^ entity.name.tag