Skip to content

Commit

Permalink
[JavaScript] Use branching for method detection, take two (#2417)
Browse files Browse the repository at this point in the history
* [JavaScript] Use branching to tell class fields from methods.
* [JavaScript] Use branching for methods/properties in object literals.
  • Loading branch information
Thom1729 authored Jul 21, 2020
1 parent 8262c6b commit 3ee86e4
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 95 deletions.
173 changes: 105 additions & 68 deletions JavaScript/JavaScript.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ variables:
property_name: >-
(?x:
{{identifier}}
| [0-9]+
| '(?:[^\\']|\\.)*'
| "(?:[^\\"]|\\.)*"
| \[ .* \]
)
class_element_name: |-
(?x:
\*?
{{property_name}}
| \#{{identifier}}
)
Expand All @@ -83,13 +83,6 @@ variables:
=>
)
method_lookahead: |-
(?x:(?=
(?: get|set|async ){{identifier_break}}(?!\s*:)
| \*
| {{property_name}} \s* \(
))
line_continuation_lookahead: >-
(?x:(?=
(?! \+\+ | -- )
Expand Down Expand Up @@ -1270,10 +1263,29 @@ contexts:

- match: static{{identifier_break}}
scope: storage.modifier.js
push: class-field

- match: |-
(?x)(?=
\#? {{identifier}}
\s* = \s*
{{either_func_lookahead}}
)
push:
- function-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-field
push: class-element

class-extends:
- match: extends{{identifier_break}}
Expand Down Expand Up @@ -1307,47 +1319,61 @@ contexts:
pop: true
- include: else-pop

class-field:
- match: '{{method_lookahead}}'
set: method-declaration
class-element:
- match: ''
pop: true
branch_point: class-field
branch:
- class-field
- method-declaration

- match: |-
(?x)(?=
\#? {{identifier}}
\s* = \s*
{{either_func_lookahead}}
)
prefixed-method:
- match: (?:get|set){{identifier_break}}
scope: storage.type.accessor.js
set:
- function-initializer
- function-name-meta
- literal-variable-base
- match: (?=#?{{property_name}})
- meta_scope: meta.function.declaration.js
- match: (?={{class_element_name}})
set: method-declaration
- match: (?=\S)
fail: prefixed-method
- match: (?:async){{identifier_break}}
scope: storage.type.js
set:
- field-initializer-or-method-declaration
- field-name
- meta_scope: meta.function.declaration.js
- match: (?=\*|{{class_element_name}})
set: method-declaration
- match: (?=\S)
fail: prefixed-method

- include: else-pop
prefixed-object-literal-method:
- match: (?:get|set){{identifier_break}}
scope: storage.type.accessor.js
set:
- meta_scope: meta.function.declaration.js
- match: (?={{class_element_name}})
set: method-declaration
- match: (?=\S)
fail: prefixed-object-literal-method
- match: (?:async){{identifier_break}}
scope: storage.type.js
set:
- meta_scope: meta.function.declaration.js
- match: (?=\*|{{class_element_name}})
set: method-declaration
- match: (?=\S)
fail: prefixed-object-literal-method

class-field-rest:
- match: ','
scope: punctuation.separator.js
push:
class-field:
- match: ''
set:
- initializer
- class-field-check
- field-name
- include: else-pop

field-initializer-or-method-declaration:
class-field-check:
- match: (?=\()
set:
- function-meta
- function-declaration-expect-body
- function-declaration-meta
- function-declaration-expect-parameters
- match: (?=\S)
set:
- class-field-rest
- initializer
fail: class-field
- include: else-pop

constants:
- match: true{{identifier_break}}
Expand Down Expand Up @@ -1565,48 +1591,59 @@ contexts:
- object-literal-meta-key
- method-name
- match: '{{method_lookahead}}'
- match: (?=\*)
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
- match: (?=(?:get|set|async){{identifier_break}})
branch_point: prefixed-object-literal-method
branch:
- prefixed-object-literal-method
- object-literal-element

# - include: bare-property-name
- match: (?={{identifier}})
push:
- object-literal-meta-key
- bare-property-name
- match: (?={{property_name}})
push: object-literal-element

- include: comma-separator

- match: ':'
scope: punctuation.separator.key-value.js
push: expression-no-comma

# 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
object-literal-element:
- match: ''
pop: true
branch_point: object-literal-property
branch:
- object-literal-property
- method-declaration

object-literal-property:
- match: ''
set:
- object-literal-property-check
- object-literal-meta-key
- object-property-name

object-property-name:
- match: (?=\[)
set: computed-property-name

- include: literal-string
- include: literal-number

bare-property-name:
- match: '{{identifier}}'
pop: true

- include: else-pop

object-literal-property-check:
- match: (?=\()
fail: object-literal-property
- include: else-pop

computed-property-name:
- match: \[
scope: punctuation.section.brackets.begin.js
Expand Down
20 changes: 9 additions & 11 deletions JavaScript/TypeScript.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -371,21 +371,19 @@ contexts:
- match: (?:private|public|protected|readonly|abstract|declare){{identifier_break}}
scope: storage.modifier.js

field-initializer-or-method-declaration:
- match: (?=\(|<)
set:
- function-meta
- function-declaration-expect-body
- function-declaration-meta
- ts-type-annotation
- function-declaration-expect-parameters
- ts-type-parameter-list
- match: (?=\S)
class-field:
- match: ''
set:
- class-field-rest
- initializer
- ts-type-annotation
- ts-type-annotation-optional
- class-field-check
- field-name

class-field-check:
- match: (?=[(<])
fail: class-field
- include: else-pop

method-declaration:
- meta_include_prototype: false
Expand Down
19 changes: 4 additions & 15 deletions JavaScript/tests/syntax_test_js.js
Original file line number Diff line number Diff line change
Expand Up @@ -1044,21 +1044,6 @@ class MyClass extends TheirClass {
// ^^^^^^^^^^^^^^^^^ 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

foo // You thought I was a field...
() { return '...but was a method all along!'; }
// ^^ meta.class.js meta.block.js meta.function.declaration.js
Expand Down Expand Up @@ -1171,6 +1156,10 @@ class MyClass extends TheirClass {
*foo() {}
// ^ keyword.generator.asterisk

async *foo() {}
// ^^^^^ storage.type
// ^ keyword.generator.asterisk

static async foo() {}
// ^^^^^ storage.type
}
Expand Down
10 changes: 9 additions & 1 deletion JavaScript/tests/syntax_test_typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,14 @@
// ^ punctuation.separator.type
// ^^^ meta.type support.type.any
// ^^ meta.function meta.block

foo<T>(): any {}
// ^^^^^^^^^^^^^ meta.function.declaration
// ^^^ entity.name.function
// ^^^ meta.generic
// ^ punctuation.separator.type
// ^^^ meta.type support.type.any
// ^^ meta.function meta.block
}

abstract class Foo {
Expand Down Expand Up @@ -687,4 +695,4 @@ let x: import ( "foo" ) . Bar ;
// ^^^^^ meta.string string.quoted.double
// ^ punctuation.section.group.end
// ^ punctuation.separator.accessor
// ^^^ support.class
// ^^^ support.class

0 comments on commit 3ee86e4

Please sign in to comment.