Skip to content
This repository has been archived by the owner on Dec 15, 2022. It is now read-only.

Provide additional stop conditions for 'anonymous-classes-and-new' pattern #214

Merged
merged 9 commits into from
Nov 28, 2019
Merged

Provide additional stop conditions for 'anonymous-classes-and-new' pattern #214

merged 9 commits into from
Nov 28, 2019

Conversation

Vigilans
Copy link
Contributor

@Vigilans Vigilans commented Nov 27, 2019

Description of the Change

  • Dot should also end 'anonymous-classes-and-new', in order to propery highlight method call of temporary variable created by 'new'.

  • Question mark should also end 'anonymous-classes-and-new', in order to proper break out circumstances like new Random() ? true : false;

  • Right square brace should also end 'anonymous-classes-and-new', for circumstances like [new Random()].

  • Xor should also end anonymous-classes-and-new, for circumstances like new Integer(1) ^ new Integer(2).

Alternate Designs

Non was considered.

Having to enumerate these much punctuations made me think of proposing a general and simple regex to end new expression. But soon I found out that I couldn't find a way to tell when ) or ] is met, whether there will be a {} block next to it.

Benefits

  • The meaning of dot method call by variable and new-variable is consistent.
  • Every punctuation that could end a new expression is covered.

Possible Drawbacks

No obvious drawback.

Applicable Issues

Fix #213 -> dot
Fix #179 -> question mark
Fix #180 -> right square
Fix #192 -> xor

@Vigilans Vigilans changed the title Dot should also ends 'anonymous-classes-and-new' More punctuations to ends 'anonymous-classes-and-new' Nov 27, 2019
@Vigilans Vigilans changed the title More punctuations to ends 'anonymous-classes-and-new' More punctuations to end 'anonymous-classes-and-new' Nov 27, 2019
@@ -1755,6 +1768,41 @@ describe 'Java grammar', ->
expect(lines[7][19]).toEqual value: 'start', scopes: expected
expect(lines[8][19]).toEqual value: 'start', scopes: expected
expect(lines[9][19]).toEqual value: 'start', scopes: expected
expect(lines[10][19]).toEqual value: 'start', scopes: expected

# See issue https://github.com/atom/language-java/issues/180
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting is off.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same below.

expect(lines[8][1]).toEqual value: 'g', scopes: expected
expect(lines[9][1]).toEqual value: 'g', scopes: expected
expect(lines[10][1]).toEqual value: 'g', scopes: expected
expect(lines[15][3]).toEqual value: 'a', scopes: ['source.java', 'meta.class.java', 'meta.class.body.java', 'meta.method.java', 'meta.method.body.java', 'meta.definition.variable.java', 'variable.other.definition.java']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this test fail without your change?

Copy link
Contributor Author

@Vigilans Vigilans Nov 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #180, it will produce a nested scope like this for line[15][3]:

variable.other.definition.java
meta.definition.variable.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.function-call.java
meta.method.body.java
meta.method.java
meta.class.body.java
meta.class.java
source.java

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am well aware of the issue. I was only asking if you verified that the test fails without your changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. I test it by removing \\[ in the end regex, and it produces such failures:

image

@sadikovi
Copy link
Contributor

Please, enable edits from maintainers on your pull request.

@sadikovi sadikovi changed the title More punctuations to end 'anonymous-classes-and-new' Provide additional stop conditions for 'anonymous-classes-and-new' pattern Nov 28, 2019
@sadikovi
Copy link
Contributor

Merging to master, thanks!

@sadikovi sadikovi merged commit f8b9d68 into atom:master Nov 28, 2019
@Vigilans Vigilans deleted the vigilans/new-var-method branch November 28, 2019 07:50
sadikovi pushed a commit that referenced this pull request Mar 25, 2020
### Description of the Change

Similar to #212, it uses a two-scope pattern to distinguish `inner-class` block and `array-initializer` block. it is based on #214 to provide correct end regex for `inner-class` and `array-initializer`.

#### Detailed description

Conside how a syntax scope terminates:
```
new Class() <end of new expression>
            ^~~~~ terminate here
new Class[] <end of new expression>
            ^~~~~ terminate here
new Class() {} <end of new expression>
               ^~~~~ terminate here
new Class[] {} <end of new expression>
               ^~~~~ terminate here
```
Previous new-expr grammar handles following ways of termination:
* inner-class: `(?<!\\])\\s*({)`...`(})`
* parens (square): `[`...`]`
* parens (round): `(`...`)`
* parens (square + curly): `[`...`]`...`{`...`}`

The usage of `\s*` suffers from new-line and comment-in-between pattern, and this should be relaxed using a two-scope model.

Besides, `inner-class` and `array-initializer` do not share same syntax (`class-body` and `code`), so they should fall in different scope.

So, this PR:
* Differentiate `object-new` and `array-declaration` using two different scopes.
* Put `inner-class` and `array-initializer` in different scopes, with similar names.

### Alternate Designs

This PR repetitively uses the end regex of new expression:
```
'end': '(?=;|\\)|\\]|\\.|,|\\?|:|}|\\+|\\-|\\*|\\/(?!\\/|\\*)|%|!|&|\\||\\^|=)'
```
to determine when a scope terminates. It would be better if we could find a way to reduce its usage. 

One possible alternative is: match when inner end token reached (`)`, `]` or `}`), not the outer token that ends it (the complex end regex).

But just like #214, it is hard to tell when `)` or `]` is met, whether there will be a `{}` block next to it. I (maybe) tried such silly regexes (cannot remember them correctly):
* outer - `(?<=\\)`...`}`, inner: `{`...`(?=}`
   The problem with it: if there's no `}` after `)`, it won't ends, causing the whole `new-expr` scope won't ends.
   e.g. `A[] arr = new A[]{ new A(), new A() };` - the comma won't ends first `new A()` because inner scope eats until `}` is met.

### Benefits

* Can correctly highlight `array-initializer` when there's any distance of spaces between ']' and '{'.
* Can correctly highlight `array-initializer` when '{' is placed at new line or with a comment in between.
* Introduced a new scope `array-initializer`, in correspondence with `inner-class`.
* Patterns are more neat and uniform.

### Possible Drawbacks

* Undetected possible regression issues.

### Applicable Issues

Fix #172
Fix #199
Fix redhat-developer/vscode-java#728
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants