Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiline arrow functions #25

Open
borela opened this issue Dec 1, 2017 · 11 comments
Open

Multiline arrow functions #25

borela opened this issue Dec 1, 2017 · 11 comments

Comments

@borela
Copy link
Owner

borela commented Dec 1, 2017

Currently, the following would not be highlighted as an arrow function:

let a = (
  param1,
  param2
) => {
 // Body
}

This limitation is from sublime itself as you can see here and here. The regex pattern in the syntax would work if multiline support is added to sublime syntax.

@Thom1729
Copy link

Thom1729 commented Dec 2, 2017

The argument list can't be distinguished from a parenthesized expression for two reasons. The lesser reason is the line-lookahead limitation. The greater reason is that the JavaScript syntax is not deterministic context-free. There is no way for Sublime's engine to correctly differentiate parenthesized expressions from arrow function parameter lists without implementing nondeterministic parsing.

On the other hand, once the syntax sees the =>, it should immediately recover from a wrong guess and correctly highlight the arrow function body as a block. This can be done now.

@borela
Copy link
Owner Author

borela commented Dec 2, 2017

I use lookaheads to predict arrow functions, if sublime allows multiline match it would correctly detect the arrow function but I know that's something hard for the sublime devs to implement in the engine for performance reasons.

I could still highlight the body once I find the =>, but the parameters would wrong, specially with destructuring:

({ 
  param1,
  param2
}) => {
 // The body would be correct but the paramters 
 // would be highlighted as an object literal inside parenthesis.
}

@Thom1729
Copy link

Thom1729 commented Dec 3, 2017

It's unfortunate that there's no perfect solution, but it's still a good idea to highlight the body correctly. This is what the core syntax does.

if sublime allows multiline match it would correctly detect the arrow function

This isn't quite true. Because of default arguments, you can have arbitrarily complicated expressions in a parameter list. A regular expression cannot handle this. I have to put the blame for this problem on the ECMAScript designers; in order for Sublime to parse this correctly, it would need nondeterminism.

@borela
Copy link
Owner Author

borela commented Dec 3, 2017

A regular expression cannot handle this. I have to put the blame for this problem on the ECMAScript designers; in order for Sublime to parse this correctly, it would need nondeterminism

Definitely agree, non determinism is what gave me headaches to approximate the syntax when combining it with flow and jsx.

This isn't quite true. Because of default arguments, you can have arbitrarily complicated expressions

To prevent this I use a look ahead with self balancing parenthesis and ignore everything inside them. It searches for (...) => to confirm that it is in fact an arrow function, you can put pretty much anything inside the parenthesis and it would still work.

For functions with a single parameter without parenthesis, I have a separate pattern.

What are the cases that I am missing?

@Thom1729
Copy link

Thom1729 commented Dec 3, 2017

It might actually be possible using subexpression calls, because those aren't deterministic context-free. The cases where I expect that particular expression to fail are parentheses in strings or comments. You'd need to implement those with regexps. The trickiest would be template strings with embedded expressions, which will require its own recursive subexpression call.

I'd be a little concerned about the performance of all of this, because Sublime would have to run this extremely complex recursive expression using the slow engine whenever it encountered a recursive expression. That may or may not be a problem in practice.

@borela
Copy link
Owner Author

borela commented Dec 3, 2017

I'll keep those cases in mind when testing the syntax. As for performance, it is still acceptable, the slowest PC I have access to is a core 2 duo and even when I use it, the key presses feel instantaneous.

@borela
Copy link
Owner Author

borela commented Jan 28, 2018

On the other hand, once the syntax sees the =>, it should immediately recover from a wrong guess and correctly highlight the arrow function body as a block. This can be done now.

Added in >= 3.0.0, multiline parameters for arrow functions still won't be highlighted correctly.

@Whoaa512
Copy link
Contributor

Whoaa512 commented Apr 3, 2019

@borela Sorry if there is something obvious that makes this difficult but is it possible to use multiple contexts to achieve the multi-line arrow function parsing?

Just saw this recently https://forum.sublimetext.com/t/syntax-for-multi-line-ifs-not-supported/36084

@borela
Copy link
Owner Author

borela commented Apr 4, 2019

@Whoaa512 The issue for arrow functions is that you need to check the pattern for the arrow functions first https://github.com/borela/naomi/blob/master/syntaxes/fjsx15/arrow-function.sublime-syntax#L143 it is not possible to render it as group and function at the same time.

I am really hoping something like treesitter or visual studio's(not vscode) syntax system gets incorporated in sublime, they are far more powerfull and can handle the most extraneous syntaxes out there.

@Thom1729
Copy link

Thom1729 commented Apr 4, 2019

I wrote a proposal to add nondeterministic parsing to Sublime. With this augmentation, Sublime's engine would be strictly more powerful than tree-sitter.

@borela
Copy link
Owner Author

borela commented Apr 4, 2019

@Thom1729 If that gets implemented I would definitely be happy too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants