fix defaults on type annotated arrow function params - fixes #2493

This commit is contained in:
Sebastian McKenzie 2015-11-05 09:49:03 +00:00
parent 2b6f78df83
commit 779675610f
4 changed files with 462 additions and 10 deletions

View File

@ -93,16 +93,20 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
} }
let failOnShorthandAssign; let failOnShorthandAssign;
if (!refShorthandDefaultPos) { if (refShorthandDefaultPos) {
failOnShorthandAssign = false;
} else {
refShorthandDefaultPos = { start: 0 }; refShorthandDefaultPos = { start: 0 };
failOnShorthandAssign = true; failOnShorthandAssign = true;
} else {
failOnShorthandAssign = false;
} }
let startPos = this.state.start, startLoc = this.state.startLoc;
let startPos = this.state.start;
let startLoc = this.state.startLoc;
if (this.match(tt.parenL) || this.match(tt.name)) { if (this.match(tt.parenL) || this.match(tt.name)) {
this.state.potentialArrowAt = this.state.start; this.state.potentialArrowAt = this.state.start;
} }
let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos); let left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
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) {
@ -110,7 +114,9 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
node.operator = this.state.value; node.operator = this.state.value;
node.left = this.match(tt.eq) ? this.toAssignable(left) : left; node.left = this.match(tt.eq) ? this.toAssignable(left) : left;
refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
this.checkLVal(left); this.checkLVal(left);
if (left.extra && left.extra.parenthesized) { if (left.extra && left.extra.parenthesized) {
let errorMsg; let errorMsg;
if (left.type === "ObjectPattern") { if (left.type === "ObjectPattern") {
@ -122,12 +128,14 @@ pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`); this.raise(left.start, `You're trying to assign to a parenthesized expression, eg. instead of ${errorMsg}`);
} }
} }
this.next(); this.next();
node.right = this.parseMaybeAssign(noIn); node.right = this.parseMaybeAssign(noIn);
return this.finishNode(node, "AssignmentExpression"); return this.finishNode(node, "AssignmentExpression");
} else if (failOnShorthandAssign && refShorthandDefaultPos.start) { } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
this.unexpected(refShorthandDefaultPos.start); this.unexpected(refShorthandDefaultPos.start);
} }
return left; return left;
}; };
@ -506,12 +514,13 @@ pp.parseParenExpression = function () {
pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow, isAsync) { pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow, isAsync) {
startPos = startPos || this.state.start; startPos = startPos || this.state.start;
startLoc = startLoc || this.state.startLoc; startLoc = startLoc || this.state.startLoc;
let val; let val;
this.next(); this.next();
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, innerParenStart, optionalCommaStart; let refShorthandDefaultPos = { start: 0 }, spreadStart, optionalCommaStart;
while (!this.match(tt.parenR)) { while (!this.match(tt.parenR)) {
if (first) { if (first) {
first = false; first = false;
@ -529,9 +538,6 @@ 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 {
if (this.match(tt.parenL) && !innerParenStart) {
innerParenStart = this.state.start;
}
exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem)); exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
} }
} }
@ -541,7 +547,10 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow
this.expect(tt.parenR); this.expect(tt.parenR);
if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) { if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
if (innerParenStart) this.unexpected(innerParenStart); for (let param of exprList) {
if (param.extra && param.extra.parenthesized) this.unexpected(param.extra.parenStart);
}
return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, isAsync); return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, isAsync);
} }
@ -564,7 +573,11 @@ pp.parseParenAndDistinguishExpression = function (startPos, startLoc, canBeArrow
} else { } else {
val = exprList[0]; val = exprList[0];
} }
this.addExtra(val, "parenthesized", true); this.addExtra(val, "parenthesized", true);
this.addExtra(val, "parenStart", startPos);
return val; return val;
}; };

View File

@ -762,6 +762,16 @@ export default function (instance) {
return node.expression; return node.expression;
} }
instance.extend("toAssignable", function (inner) {
return function (node) {
if (node.type === "TypeCastExpression") {
return typeCastToParameter(node);
} else {
return inner.apply(this, arguments);
}
};
});
// turn type casts that we found in function parameter head into type annotated params // turn type casts that we found in function parameter head into type annotated params
instance.extend("toAssignableList", function (inner) { instance.extend("toAssignableList", function (inner) {
return function (exprList, isBinding) { return function (exprList, isBinding) {
@ -807,6 +817,14 @@ export default function (instance) {
}; };
}); });
instance.extend("checkLVal", function (inner) {
return function (node) {
if (node.type !== "TypeCastExpression") {
return inner.apply(this, arguments);
}
};
});
// parse class property type annotations // parse class property type annotations
instance.extend("parseClassProperty", function (inner) { instance.extend("parseClassProperty", function (inner) {
return function (node) { return function (node) {

View File

@ -0,0 +1,5 @@
let hello = (greeting:string = ' world') : string => {
console.log('hello' + greeting);
};
hello();

View File

@ -0,0 +1,416 @@
{
"type": "File",
"start": 0,
"end": 102,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 8
}
},
"program": {
"type": "Program",
"start": 0,
"end": 102,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 5,
"column": 8
}
},
"sourceType": "module",
"body": [
{
"type": "VariableDeclaration",
"start": 0,
"end": 92,
"loc": {
"start": {
"line": 1,
"column": 0
},
"end": {
"line": 3,
"column": 2
}
},
"declarations": [
{
"type": "VariableDeclarator",
"start": 4,
"end": 91,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 3,
"column": 1
}
},
"id": {
"type": "Identifier",
"start": 4,
"end": 9,
"loc": {
"start": {
"line": 1,
"column": 4
},
"end": {
"line": 1,
"column": 9
}
},
"name": "hello"
},
"init": {
"type": "ArrowFunctionExpression",
"start": 12,
"end": 91,
"loc": {
"start": {
"line": 1,
"column": 12
},
"end": {
"line": 3,
"column": 1
}
},
"id": null,
"generator": false,
"expression": false,
"async": false,
"params": [
{
"type": "AssignmentPattern",
"start": 13,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 13
},
"end": {
"line": 1,
"column": 39
}
},
"left": {
"type": "Identifier",
"start": 13,
"end": 21,
"loc": {
"start": {
"line": 1,
"column": 13
},
"end": {
"line": 1,
"column": 21
}
},
"name": "greeting",
"typeAnnotation": {
"type": "TypeAnnotation",
"start": 21,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 21
},
"end": {
"line": 1,
"column": 28
}
},
"typeAnnotation": {
"type": "StringTypeAnnotation",
"start": 22,
"end": 28,
"loc": {
"start": {
"line": 1,
"column": 22
},
"end": {
"line": 1,
"column": 28
}
}
}
}
},
"right": {
"type": "StringLiteral",
"start": 31,
"end": 39,
"loc": {
"start": {
"line": 1,
"column": 31
},
"end": {
"line": 1,
"column": 39
}
},
"extra": {
"rawValue": " world",
"raw": "' world'"
},
"value": " world"
},
"extra": {
"parenthesized": true,
"parenStart": 12
}
}
],
"body": {
"type": "BlockStatement",
"start": 53,
"end": 91,
"loc": {
"start": {
"line": 1,
"column": 53
},
"end": {
"line": 3,
"column": 1
}
},
"body": [
{
"type": "ExpressionStatement",
"start": 57,
"end": 89,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 34
}
},
"expression": {
"type": "CallExpression",
"start": 57,
"end": 88,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 33
}
},
"callee": {
"type": "MemberExpression",
"start": 57,
"end": 68,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 13
}
},
"object": {
"type": "Identifier",
"start": 57,
"end": 64,
"loc": {
"start": {
"line": 2,
"column": 2
},
"end": {
"line": 2,
"column": 9
}
},
"name": "console"
},
"property": {
"type": "Identifier",
"start": 65,
"end": 68,
"loc": {
"start": {
"line": 2,
"column": 10
},
"end": {
"line": 2,
"column": 13
}
},
"name": "log"
},
"computed": false
},
"arguments": [
{
"type": "BinaryExpression",
"start": 69,
"end": 87,
"loc": {
"start": {
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 32
}
},
"left": {
"type": "StringLiteral",
"start": 69,
"end": 76,
"loc": {
"start": {
"line": 2,
"column": 14
},
"end": {
"line": 2,
"column": 21
}
},
"extra": {
"rawValue": "hello",
"raw": "'hello'"
},
"value": "hello"
},
"operator": "+",
"right": {
"type": "Identifier",
"start": 79,
"end": 87,
"loc": {
"start": {
"line": 2,
"column": 24
},
"end": {
"line": 2,
"column": 32
}
},
"name": "greeting"
}
}
]
}
}
],
"directives": []
},
"returnType": {
"type": "TypeAnnotation",
"start": 41,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 41
},
"end": {
"line": 1,
"column": 49
}
},
"typeAnnotation": {
"type": "StringTypeAnnotation",
"start": 43,
"end": 49,
"loc": {
"start": {
"line": 1,
"column": 43
},
"end": {
"line": 1,
"column": 49
}
}
}
}
}
}
],
"kind": "let"
},
{
"type": "ExpressionStatement",
"start": 94,
"end": 102,
"loc": {
"start": {
"line": 5,
"column": 0
},
"end": {
"line": 5,
"column": 8
}
},
"expression": {
"type": "CallExpression",
"start": 94,
"end": 101,
"loc": {
"start": {
"line": 5,
"column": 0
},
"end": {
"line": 5,
"column": 7
}
},
"callee": {
"type": "Identifier",
"start": 94,
"end": 99,
"loc": {
"start": {
"line": 5,
"column": 0
},
"end": {
"line": 5,
"column": 5
}
},
"name": "hello"
},
"arguments": []
}
}
],
"directives": []
}
}