Fix support for flow optional parameters in arrow functions T7096
This overwrites the conditional handling in babylon for flow to support optional parameters in arrow functions.
This commit is contained in:
parent
b926e401c6
commit
e6c11a0673
@ -88,7 +88,7 @@ pp.parseExpression = function (noIn, refShorthandDefaultPos) {
|
|||||||
// Parse an assignment expression. This includes applications of
|
// Parse an assignment expression. This includes applications of
|
||||||
// operators like `+=`.
|
// operators like `+=`.
|
||||||
|
|
||||||
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
|
pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse, refNeedsArrowPos) {
|
||||||
if (this.match(tt._yield) && this.state.inGenerator) {
|
if (this.match(tt._yield) && this.state.inGenerator) {
|
||||||
return this.parseYield();
|
return this.parseYield();
|
||||||
}
|
}
|
||||||
@ -108,7 +108,7 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
|
|||||||
this.state.potentialArrowAt = this.state.start;
|
this.state.potentialArrowAt = this.state.start;
|
||||||
}
|
}
|
||||||
|
|
||||||
let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
|
let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos, refNeedsArrowPos);
|
||||||
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
|
if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc);
|
||||||
if (this.state.type.isAssign) {
|
if (this.state.type.isAssign) {
|
||||||
let node = this.startNodeAt(startPos, startLoc);
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
@ -142,10 +142,15 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
|
|||||||
|
|
||||||
// Parse a ternary conditional (`?:`) operator.
|
// Parse a ternary conditional (`?:`) operator.
|
||||||
|
|
||||||
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
|
pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos, refNeedsArrowPos) {
|
||||||
let startPos = this.state.start, startLoc = this.state.startLoc;
|
let startPos = this.state.start, startLoc = this.state.startLoc;
|
||||||
let expr = this.parseExprOps(noIn, refShorthandDefaultPos);
|
let expr = this.parseExprOps(noIn, refShorthandDefaultPos);
|
||||||
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
|
||||||
|
|
||||||
|
return this.parseConditional(expr, noIn, startPos, startLoc, refNeedsArrowPos);
|
||||||
|
};
|
||||||
|
|
||||||
|
pp.parseConditional = function (expr, noIn, startPos, startLoc) {
|
||||||
if (this.eat(tt.question)) {
|
if (this.eat(tt.question)) {
|
||||||
let node = this.startNodeAt(startPos, startLoc);
|
let node = this.startNodeAt(startPos, startLoc);
|
||||||
node.test = expr;
|
node.test = expr;
|
||||||
@ -541,6 +546,7 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow
|
|||||||
let innerStartPos = this.state.start, innerStartLoc = this.state.startLoc;
|
let innerStartPos = this.state.start, innerStartLoc = this.state.startLoc;
|
||||||
let exprList = [], first = true;
|
let exprList = [], first = true;
|
||||||
let refShorthandDefaultPos = { start: 0 }, spreadStart, optionalCommaStart;
|
let refShorthandDefaultPos = { start: 0 }, spreadStart, optionalCommaStart;
|
||||||
|
let refNeedsArrowPos = { start: 0 };
|
||||||
while (!this.match(tt.parenR)) {
|
while (!this.match(tt.parenR)) {
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
@ -558,7 +564,7 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow
|
|||||||
exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartLoc, spreadNodeStartPos));
|
exprList.push(this.parseParenItem(this.parseRest(), spreadNodeStartLoc, spreadNodeStartPos));
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
|
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem, refNeedsArrowPos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -584,6 +590,7 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow
|
|||||||
if (optionalCommaStart && !allowOptionalCommaStart) this.unexpected(optionalCommaStart);
|
if (optionalCommaStart && !allowOptionalCommaStart) this.unexpected(optionalCommaStart);
|
||||||
if (spreadStart) this.unexpected(spreadStart);
|
if (spreadStart) this.unexpected(spreadStart);
|
||||||
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
|
if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
|
||||||
|
if (refNeedsArrowPos.start) this.unexpected(refNeedsArrowPos.start);
|
||||||
|
|
||||||
if (exprList.length > 1) {
|
if (exprList.length > 1) {
|
||||||
val = this.startNodeAt(innerStartPos, innerStartLoc);
|
val = this.startNodeAt(innerStartPos, innerStartLoc);
|
||||||
|
|||||||
@ -717,9 +717,30 @@ export default function (instance) {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
instance.extend("parseConditional", function (inner) {
|
||||||
|
return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) {
|
||||||
|
const state = this.state.clone();
|
||||||
|
try {
|
||||||
|
return inner.call(this, expr, noIn, startPos, startLoc);
|
||||||
|
} catch (err) {
|
||||||
|
if (refNeedsArrowPos && err instanceof SyntaxError) {
|
||||||
|
this.state = state;
|
||||||
|
refNeedsArrowPos.start = this.state.start;
|
||||||
|
return expr;
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
instance.extend("parseParenItem", function () {
|
instance.extend("parseParenItem", function () {
|
||||||
return function (node, startLoc, startPos, forceArrow?) {
|
return function (node, startLoc, startPos, forceArrow?) {
|
||||||
let canBeArrow = this.state.potentialArrowAt = startPos;
|
let canBeArrow = this.state.potentialArrowAt = startPos;
|
||||||
|
if (this.eat(tt.question)) {
|
||||||
|
node.optional = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.match(tt.colon)) {
|
if (this.match(tt.colon)) {
|
||||||
let typeCastNode = this.startNodeAt(startLoc, startPos);
|
let typeCastNode = this.startNodeAt(startLoc, startPos);
|
||||||
typeCastNode.expression = node;
|
typeCastNode.expression = node;
|
||||||
|
|||||||
1
test/fixtures/flow/optional-type/1/actual.js
vendored
Normal file
1
test/fixtures/flow/optional-type/1/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
const f = (x?) => {}
|
||||||
138
test/fixtures/flow/optional-type/1/expected.json
vendored
Normal file
138
test/fixtures/flow/optional-type/1/expected.json
vendored
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start": 0,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start": 0,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceType": "module",
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"start": 0,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclarator",
|
||||||
|
"start": 6,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 6
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 6,
|
||||||
|
"end": 7,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 6
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "f"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"type": "ArrowFunctionExpression",
|
||||||
|
"start": 10,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 10
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": null,
|
||||||
|
"generator": false,
|
||||||
|
"expression": false,
|
||||||
|
"async": false,
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 11,
|
||||||
|
"end": 12,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 11
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "x",
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"type": "BlockStatement",
|
||||||
|
"start": 18,
|
||||||
|
"end": 20,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 18
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 20
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"body": [],
|
||||||
|
"directives": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "const"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": []
|
||||||
|
}
|
||||||
|
}
|
||||||
1
test/fixtures/flow/optional-type/2/actual.js
vendored
Normal file
1
test/fixtures/flow/optional-type/2/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
const f = (x?)
|
||||||
3
test/fixtures/flow/optional-type/2/options.json
vendored
Normal file
3
test/fixtures/flow/optional-type/2/options.json
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Unexpected token (1:12)"
|
||||||
|
}
|
||||||
1
test/fixtures/flow/optional-type/3/actual.js
vendored
Normal file
1
test/fixtures/flow/optional-type/3/actual.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
const f = (x?, y?:Object = {}) => {}
|
||||||
233
test/fixtures/flow/optional-type/3/expected.json
vendored
Normal file
233
test/fixtures/flow/optional-type/3/expected.json
vendored
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
{
|
||||||
|
"type": "File",
|
||||||
|
"start": 0,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"program": {
|
||||||
|
"type": "Program",
|
||||||
|
"start": 0,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sourceType": "module",
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"start": 0,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 0
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"declarations": [
|
||||||
|
{
|
||||||
|
"type": "VariableDeclarator",
|
||||||
|
"start": 6,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 6
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 6,
|
||||||
|
"end": 7,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 6
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 7
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "f"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"type": "ArrowFunctionExpression",
|
||||||
|
"start": 10,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 10
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": null,
|
||||||
|
"generator": false,
|
||||||
|
"expression": false,
|
||||||
|
"async": false,
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 11,
|
||||||
|
"end": 12,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 11
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "x",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "AssignmentPattern",
|
||||||
|
"start": 15,
|
||||||
|
"end": 29,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 15
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 29
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"left": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 15,
|
||||||
|
"end": 16,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 15
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 16
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "y",
|
||||||
|
"optional": true,
|
||||||
|
"typeAnnotation": {
|
||||||
|
"type": "TypeAnnotation",
|
||||||
|
"start": 17,
|
||||||
|
"end": 24,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 17
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typeAnnotation": {
|
||||||
|
"type": "GenericTypeAnnotation",
|
||||||
|
"start": 18,
|
||||||
|
"end": 24,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 18
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typeParameters": null,
|
||||||
|
"id": {
|
||||||
|
"type": "Identifier",
|
||||||
|
"start": 18,
|
||||||
|
"end": 24,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 18
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "Object"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"type": "ObjectExpression",
|
||||||
|
"start": 27,
|
||||||
|
"end": 29,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 27
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 29
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"body": {
|
||||||
|
"type": "BlockStatement",
|
||||||
|
"start": 34,
|
||||||
|
"end": 36,
|
||||||
|
"loc": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 34
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"column": 36
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"body": [],
|
||||||
|
"directives": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"kind": "const"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": []
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user