Distinguish between ternary's : and arrow fn's return type (#573)

* Distinguish between ternary's : and arrow fn's return type

* Correctly parse nested arrow functions inside conditional expressions

Defer the conversion of arrow function parameters to assignable nodes so that
it is possible to use the (invalid) ast to get the exact position of the (wrong)
arrow functions.

* Check params of arrow fns w/ type params or w/o return type

* Fix also async functions

* Add test from prettier

https://github.com/prettier/prettier/issues/2194

* Don't check arrow params if they are valid at the first attemp

* Use state instead of relying on the "noArrowParamsConversion" parameter

* Remove noArrowParamsConversion
This commit is contained in:
Nicolò Ribaudo
2017-06-27 21:44:56 +02:00
committed by Henry Zhu
parent 39447b1cca
commit a9a55fbd3f
15 changed files with 6840 additions and 10 deletions

View File

@@ -0,0 +1,4 @@
// This can be parsed in two ways:
// a ? b : (c => ((d): e => f))
// a ? ((b): c => d) : (e => f)
a ? (b) : c => (d) : e => f;

View File

@@ -0,0 +1,3 @@
{
"throws": "Ambiguous expression: wrap the arrow functions in parentheses to disambiguate. (4:4)"
}

View File

@@ -0,0 +1,2 @@
// Function which looks like a return type
a ? (b) : (c => d) => e;

View File

@@ -0,0 +1,3 @@
{
"throws": "Invalid left-hand side in arrow function parameters (2:11)"
}

View File

@@ -0,0 +1,2 @@
// Invalid LHS parameter after type parameters
a ? <T>(b => c) : d => (e) : f => g;

View File

@@ -0,0 +1,3 @@
{
"throws": "Invalid left-hand side in arrow function parameters (2:8)"
}

View File

@@ -0,0 +1,2 @@
// Invalid LHS parameter after type parameters
a ? (b => c) => (e) : f => g;

View File

@@ -0,0 +1,3 @@
{
"throws": "Invalid left-hand side in arrow function parameters (2:5)"
}

View File

@@ -0,0 +1,2 @@
// Invalid LHS parameter
a ? async (b => c) => (d) : f => g;

View File

@@ -0,0 +1,3 @@
{
"throws": "Invalid left-hand side in arrow function parameters (2:11)"
}

View File

@@ -0,0 +1,44 @@
// Valid lhs value inside parentheses
a ? (b) : c => d; // a ? b : (c => d)
a ? (b) : c => d : e; // a ? ((b): c => d) : e
a ? (b) : (c) : d => e; // a ? b : ((c): d => e)
// Nested arrow function inside parentheses
a ? (b = (c) => d) : e => f; // a ? (b = (c) => d) : (e => f)
a ? (b = (c) => d) : e => f : g; // a ? ((b = (c) => d): e => f) : g
// Nested conditional expressions
b ? c ? (d) : e => (f) : g : h; // b ? (c ? ((d): e => f) : g) : h
a ? b ? c ? (d) : e => (f) : g : h; // a ? (b ? (c ? d : (e => f)) : g) : h
a ? b ? (c) : (d) : (e) => f : g; // a ? (b ? c : ((d): e => f)) : g
// Multiple arrow functions
a ? (b) : c => d : (e) : f => g; // a ? ((b): c => d) : ((e): f => g)
// Multiple nested arrow functions (<T> is needed to avoid ambiguities)
a ? (b) : c => (d) : e => f : g; // a ? ((b): c => ((d): e => f)) : g
a ? (b) : c => <T>(d) : e => f; // a ? b : (c => (<T>(d): e => f))
a ? <T>(b) : c => (d) : e => f; // a ? (<T>(b): c => d) : (e => f)
// Invalid lhs value inside parentheses
a ? (b => c) : d => e; // a ? (b => c) : (d => e)
a ? b ? (c => d) : e => f : g; // a ? (b ? (c => d) : (e => f)) : g
// Invalid lhs value inside parentheses inside arrow function
a ? (b) : c => (d => e) : f => g; // a ? ((b): c => (d => e)) : (f => g)
a ? b ? (c => d) : e => (f => g) : h => i; // a ? (b ? (c => d) : (e => (f => g))) : (h => i)
// Function as type annotation
a ? (b) : (c => d) => e : f; // a ? ((b): (c => d) => e) : f
// Async functions or calls
a ? async (b) : c => d; // a ? (async(b)) : (c => d)
a ? async (b) : c => d : e; // a ? (async (b): c => d) : e
a ? async (b => c) : d => e; // a ? (async(b => c)) : (d => e)
a ? async (b) => (c => d) : e => f; // a ? (async (b) => c => d) : (e => f)
// https://github.com/prettier/prettier/issues/2194
let icecream = what == "cone"
? p => (!!p ? `here's your ${p} cone` : `just the empty cone for you`)
: p => `here's your ${p} ${what}`;

File diff suppressed because it is too large Load Diff