From 7c69dd84b9996d631cd0ad47bf97a496dec18b17 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 6 Sep 2017 13:11:35 -0700 Subject: [PATCH 1/3] Disable lookahead in isStartOfParameter/isStartOfType --- src/compiler/core.ts | 2 +- src/compiler/parser.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 20f757c3df8..a9138e0ab5c 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1283,7 +1283,7 @@ namespace ts { args[i] = arguments[i]; } - return t => reduceLeft<(t: T) => T, T>(args, (u, f) => f(u), t); + return t => reduceLeft(args, (u, f) => f(u), t); } else if (d) { return t => d(c(b(a(t)))); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 71c7d3aac49..e4847517252 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2237,7 +2237,14 @@ namespace ts { return token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern() || isModifierKind(token()) || - token() === SyntaxKind.AtToken || isStartOfType(); + token() === SyntaxKind.AtToken || + // a jsdoc parameter can start directly with a type, but shouldn't look ahead + // in order to avoid confusion between parenthesized types and arrow functions + // eg + // declare function f(cb: function(number): void): void; + // vs + // f((n) => console.log(n)); + isStartOfType(/*disableLookahead*/ true); } function parseParameter(): ParameterDeclaration { @@ -2698,7 +2705,7 @@ namespace ts { } } - function isStartOfType(): boolean { + function isStartOfType(disableLookahead?: boolean): boolean { switch (token()) { case SyntaxKind.AnyKeyword: case SyntaxKind.StringKeyword: @@ -2728,11 +2735,11 @@ namespace ts { case SyntaxKind.DotDotDotToken: return true; case SyntaxKind.MinusToken: - return lookAhead(nextTokenIsNumericLiteral); + return !disableLookahead && lookAhead(nextTokenIsNumericLiteral); case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return lookAhead(isStartOfParenthesizedOrFunctionType); + return !disableLookahead && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } From a5c2eac2ee533fa3e71a6be3e5d320107e2614e8 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Wed, 6 Sep 2017 15:54:14 -0700 Subject: [PATCH 2/3] Test:disable lookahead in isStartOfParameter --- src/compiler/parser.ts | 6 ------ ...arrowfunctionsOptionalArgsErrors2.errors.txt | 17 +++++++++++++---- .../fatarrowfunctionsOptionalArgsErrors2.js | 6 ++---- .../baselines/reference/parser512325.errors.txt | 17 +++++++++++++---- tests/baselines/reference/parser512325.js | 6 ++---- .../parserArrowFunctionExpression5.errors.txt | 15 +++++++++++++++ .../reference/parserArrowFunctionExpression5.js | 10 ++++++++++ .../parserArrowFunctionExpression5.ts | 5 +++++ 8 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 tests/baselines/reference/parserArrowFunctionExpression5.errors.txt create mode 100644 tests/baselines/reference/parserArrowFunctionExpression5.js create mode 100644 tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e4847517252..1740bad2d34 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2238,12 +2238,6 @@ namespace ts { isIdentifierOrPattern() || isModifierKind(token()) || token() === SyntaxKind.AtToken || - // a jsdoc parameter can start directly with a type, but shouldn't look ahead - // in order to avoid confusion between parenthesized types and arrow functions - // eg - // declare function f(cb: function(number): void): void; - // vs - // f((n) => console.log(n)); isStartOfType(/*disableLookahead*/ true); } diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt index 51db9c7391e..b435e7773f5 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.errors.txt @@ -1,7 +1,10 @@ -tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,15): error TS1003: Identifier expected. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2304: Cannot find name 'a'. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,12): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2304: Cannot find name 'b'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,16): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,19): error TS2304: Cannot find name 'c'. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,23): error TS1005: ';' expected. +tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,26): error TS2304: Cannot find name 'a'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,28): error TS2304: Cannot find name 'b'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(1,30): error TS2304: Cannot find name 'c'. tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(2,12): error TS2695: Left side of comma operator is unused and has no side effects. @@ -18,16 +21,22 @@ tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,17): error TS1005 tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts(4,20): error TS2304: Cannot find name 'a'. -==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (18 errors) ==== +==== tests/cases/compiler/fatarrowfunctionsOptionalArgsErrors2.ts (21 errors) ==== var tt1 = (a, (b, c)) => a+b+c; - ~ -!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'b'. ~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'c'. + ~~ +!!! error TS1005: ';' expected. + ~ +!!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'b'. ~ diff --git a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js index a1c68ea4476..b51003b62df 100644 --- a/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js +++ b/tests/baselines/reference/fatarrowfunctionsOptionalArgsErrors2.js @@ -5,10 +5,8 @@ var tt2 = ((a), b, c) => a+b+c; var tt3 = ((a)) => a; //// [fatarrowfunctionsOptionalArgsErrors2.js] -var tt1 = function (a, ) { - if ( === void 0) { = (b, c); } - return a + b + c; -}; +var tt1 = (a, (b, c)); +a + b + c; var tt2 = ((a), b, c); a + b + c; var tt3 = ((a)); diff --git a/tests/baselines/reference/parser512325.errors.txt b/tests/baselines/reference/parser512325.errors.txt index f54d9f2110a..e6a47fbf226 100644 --- a/tests/baselines/reference/parser512325.errors.txt +++ b/tests/baselines/reference/parser512325.errors.txt @@ -1,21 +1,30 @@ -tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,14): error TS1003: Identifier expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,11): error TS2304: Cannot find name 'a'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,11): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,15): error TS2304: Cannot find name 'b'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,15): error TS2695: Left side of comma operator is unused and has no side effects. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,18): error TS2304: Cannot find name 'c'. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,22): error TS1005: ';' expected. +tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,25): error TS2304: Cannot find name 'a'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,27): error TS2304: Cannot find name 'b'. tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts(1,29): error TS2304: Cannot find name 'c'. -==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts (6 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser512325.ts (9 errors) ==== var tt = (a, (b, c)) => a+b+c; - ~ -!!! error TS1003: Identifier expected. + ~ +!!! error TS2304: Cannot find name 'a'. + ~ +!!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'b'. ~ !!! error TS2695: Left side of comma operator is unused and has no side effects. ~ !!! error TS2304: Cannot find name 'c'. + ~~ +!!! error TS1005: ';' expected. + ~ +!!! error TS2304: Cannot find name 'a'. ~ !!! error TS2304: Cannot find name 'b'. ~ diff --git a/tests/baselines/reference/parser512325.js b/tests/baselines/reference/parser512325.js index 75af6b9f39a..14cbcddd86b 100644 --- a/tests/baselines/reference/parser512325.js +++ b/tests/baselines/reference/parser512325.js @@ -2,7 +2,5 @@ var tt = (a, (b, c)) => a+b+c; //// [parser512325.js] -var tt = function (a, ) { - if ( === void 0) { = (b, c); } - return a + b + c; -}; +var tt = (a, (b, c)); +a + b + c; diff --git a/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt b/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt new file mode 100644 index 00000000000..220c4d42279 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression5.errors.txt @@ -0,0 +1,15 @@ +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts(1,2): error TS2304: Cannot find name 'bar'. +tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts(1,6): error TS2304: Cannot find name 'x'. + + +==== tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts (2 errors) ==== + (bar(x, + ~~~ +!!! error TS2304: Cannot find name 'bar'. + ~ +!!! error TS2304: Cannot find name 'x'. + () => {}, + () => {} + ) + ) + \ No newline at end of file diff --git a/tests/baselines/reference/parserArrowFunctionExpression5.js b/tests/baselines/reference/parserArrowFunctionExpression5.js new file mode 100644 index 00000000000..b25d77a4b02 --- /dev/null +++ b/tests/baselines/reference/parserArrowFunctionExpression5.js @@ -0,0 +1,10 @@ +//// [parserArrowFunctionExpression5.ts] +(bar(x, + () => {}, + () => {} + ) +) + + +//// [parserArrowFunctionExpression5.js] +(bar(x, function () { }, function () { })); diff --git a/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts new file mode 100644 index 00000000000..d4ab2adefba --- /dev/null +++ b/tests/cases/conformance/parser/ecmascript5/ArrowFunctionExpressions/parserArrowFunctionExpression5.ts @@ -0,0 +1,5 @@ +(bar(x, + () => {}, + () => {} + ) +) From 90d9f3d4ba2b45c28fa3361725002f31c75d8403 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 7 Sep 2017 09:07:59 -0700 Subject: [PATCH 3/3] Rename isStartOfType parameter used by isStartOfParameter --- src/compiler/parser.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1740bad2d34..d25bb3efd50 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2238,7 +2238,7 @@ namespace ts { isIdentifierOrPattern() || isModifierKind(token()) || token() === SyntaxKind.AtToken || - isStartOfType(/*disableLookahead*/ true); + isStartOfType(/*inStartOfParameter*/ true); } function parseParameter(): ParameterDeclaration { @@ -2699,7 +2699,7 @@ namespace ts { } } - function isStartOfType(disableLookahead?: boolean): boolean { + function isStartOfType(inStartOfParameter?: boolean): boolean { switch (token()) { case SyntaxKind.AnyKeyword: case SyntaxKind.StringKeyword: @@ -2729,11 +2729,11 @@ namespace ts { case SyntaxKind.DotDotDotToken: return true; case SyntaxKind.MinusToken: - return !disableLookahead && lookAhead(nextTokenIsNumericLiteral); + return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case SyntaxKind.OpenParenToken: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. - return !disableLookahead && lookAhead(isStartOfParenthesizedOrFunctionType); + return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); }