diff --git a/JavaScript/JavaScript.sublime-syntax b/JavaScript/JavaScript.sublime-syntax index b056038c77..318b322fd1 100644 --- a/JavaScript/JavaScript.sublime-syntax +++ b/JavaScript/JavaScript.sublime-syntax @@ -91,6 +91,13 @@ variables: ) )) + dot_accessor: |- + (?x: # Match . and .?, but not .?( or .?[ + \. + (?! \? [\[(] ) + \?? + ) + contexts: main: - include: comments-top-level @@ -815,7 +822,7 @@ contexts: pop: true decorator-expression-end: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: - include: decorator-name @@ -850,14 +857,14 @@ contexts: left-expression-end: - include: expression-break - - include: property-access - - match: (?=`) push: literal-string-template - - match: (?=\() + - match: (?=(?:\.\?)?\() push: function-call-arguments + - include: property-access + - include: fallthrough - include: else-pop @@ -1078,7 +1085,7 @@ contexts: - match: in{{identifier_break}} scope: keyword.operator.js push: expression-begin - - match: '&&|\|\|' + - match: '&&|\|\||\?\?' scope: keyword.operator.logical.js push: expression-begin - match: '=(?![=>])' @@ -1235,7 +1242,7 @@ contexts: pop: true inherited-class-expression-end: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: - include: inherited-class-name @@ -1332,7 +1339,7 @@ contexts: - literal-variable-base expect-dot-accessor: - - match: '\.' + - match: '{{dot_accessor}}' scope: punctuation.accessor.js pop: true - include: else-pop @@ -1689,8 +1696,10 @@ contexts: push: expression function-call-arguments: - - match: \( - scope: punctuation.section.group.begin.js + - match: (\.\?)?(\() + captures: + 1: punctuation.accessor.js + 2: punctuation.section.group.begin.js set: - meta_scope: meta.group.js - match: \) @@ -1709,8 +1718,10 @@ contexts: - include: expression-list property-access: - - match: '\[' - scope: punctuation.section.brackets.begin.js + - match: (\.\?)?(\[) + captures: + 1: punctuation.accessor.js + 2: punctuation.section.brackets.begin.js push: - meta_scope: meta.brackets.js - match: '\]' @@ -1719,10 +1730,10 @@ contexts: - match: (?=\S) push: expression - - match: \. + - match: \.(?:\?)? scope: punctuation.accessor.js push: - - match: '(?={{identifier}}\s*\()' + - match: '(?={{identifier}}\s*(?:\.\?)?\()' set: - call-method-meta - function-call-arguments @@ -1796,13 +1807,13 @@ contexts: pop: true literal-call: - - match: (?={{identifier}}\s*\() + - match: (?={{identifier}}\s*(?:\.\?)?\() set: - call-function-meta - function-call-arguments - literal-variable - - match: (?={{identifier}}\s*(?:\.\s*{{identifier}}\s*)+\() + - match: (?={{identifier}}\s*(?:\.\s*{{identifier}}\s*)+(?:\.\?)?\() set: - call-method-meta - function-call-arguments @@ -1810,7 +1821,7 @@ contexts: - literal-variable call-path: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js push: object-property - include: else-pop @@ -1849,7 +1860,7 @@ contexts: scope: support.class.js pop: true - - match: (?={{identifier}}\s*\() + - match: (?={{identifier}}\s*(?:\.\?)?\() set: call-function-name - include: literal-variable-base @@ -1910,7 +1921,7 @@ contexts: - match: Array{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-array @@ -1921,7 +1932,7 @@ contexts: - match: ArrayBuffer{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-arraybuffer @@ -1932,7 +1943,7 @@ contexts: - match: Atomics{{identifier_break}} scope: support.constant.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-atomics @@ -1943,7 +1954,7 @@ contexts: - match: BigInt{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-bigint @@ -1954,7 +1965,7 @@ contexts: - match: Date{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-date @@ -1965,7 +1976,7 @@ contexts: - match: JSON{{identifier_break}} scope: support.constant.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-json @@ -1976,7 +1987,7 @@ contexts: - match: Math{{identifier_break}} scope: support.constant.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-math @@ -1987,7 +1998,7 @@ contexts: - match: Number{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-number @@ -1998,7 +2009,7 @@ contexts: - match: Object{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-object @@ -2009,7 +2020,7 @@ contexts: - match: Promise{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-promise @@ -2020,7 +2031,7 @@ contexts: - match: Proxy{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-proxy @@ -2031,7 +2042,7 @@ contexts: - match: Reflect{{identifier_break}} scope: support.constant.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-reflect @@ -2042,7 +2053,7 @@ contexts: - match: String{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-string @@ -2053,7 +2064,7 @@ contexts: - match: Symbol{{identifier_break}} scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-symbol @@ -2074,7 +2085,7 @@ contexts: ) scope: support.class.builtin.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-ecma-typedarray @@ -2183,7 +2194,7 @@ contexts: - match: console{{identifier_break}} scope: support.type.object.console.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: builtin-console-properties - include: else-pop @@ -2211,7 +2222,7 @@ contexts: - match: process{{identifier_break}} scope: support.constant.node.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-node-process @@ -2226,7 +2237,7 @@ contexts: - match: module{{identifier_break}} scope: support.constant.node.js set: - - match: \. + - match: '{{dot_accessor}}' scope: punctuation.accessor.js set: - include: support-property-node-module @@ -2273,7 +2284,7 @@ contexts: - include: support-property - - match: '(?={{identifier}}\s*\()' + - match: '(?={{identifier}}\s*(?:\.\?)?\()' set: call-method-name - include: object-property-base diff --git a/JavaScript/tests/syntax_test_js.js b/JavaScript/tests/syntax_test_js.js index 2911859409..90b8f69535 100644 --- a/JavaScript/tests/syntax_test_js.js +++ b/JavaScript/tests/syntax_test_js.js @@ -1944,3 +1944,29 @@ debugger; debugger [] // <- meta.sequence + + a ?? b; +// ^^ keyword.operator.logical + + a.?b.?c; +// ^^ punctuation.accessor +// ^ meta.property.object +// ^^ punctuation.accessor +// ^ meta.property.object + + a.?[propName]; +// ^^^^^^^^^^^^ meta.brackets +// ^^ punctuation.accessor +// ^ punctuation.section.brackets.begin + + a.?(); +// ^^^^^ meta.function-call +// ^ variable.function +// ^^^^ meta.group +// ^^ punctuation.accessor +// ^ punctuation.section.group.begin + + a.b.?(); +// ^^^^^^^ meta.function-call.method +// ^ variable.function +//