From d5ac93c7f6533c098a3fb6b988d2b7b1c43d9d08 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 Jun 2019 16:33:16 -0700 Subject: [PATCH 1/6] Parse quoted constructors as constructors, not methods --- src/compiler/checker.ts | 3 --- src/compiler/diagnosticMessages.json | 4 ---- src/compiler/parser.ts | 22 +++++++++++++++++++ .../quotedConstructors.ts | 16 ++++++++++---- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a4ad3af7d9a35..9a5a3e1d9d475 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32053,9 +32053,6 @@ namespace ts { return grammarErrorAtPos(node, node.end - 1, ";".length, Diagnostics._0_expected, "{"); } } - else if (isClassLike(node.parent) && isStringLiteral(node.name) && node.name.text === "constructor" && (!compilerOptions.target || compilerOptions.target < ScriptTarget.ES5)) { - return grammarErrorOnNode(node.name, Diagnostics.Quoted_constructors_have_previously_been_interpreted_as_methods_which_is_incorrect_In_TypeScript_3_6_they_will_be_correctly_parsed_as_constructors_In_the_meantime_consider_using_constructor_to_write_a_constructor_or_constructor_to_write_a_method); - } if (checkGrammarForGenerator(node)) { return true; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index b209a878804db..59626445d33d3 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4995,10 +4995,6 @@ "category": "Error", "code": 18004 }, - "Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '[\"constructor\"]()' to write a method.": { - "category": "Error", - "code": 18005 - }, "Classes may not have a field named 'constructor'.": { "category": "Error", "code": 18006 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index c38e4f67fe287..d043a9d737255 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5650,9 +5650,24 @@ namespace ts { return finishNode(node); } + function tryParseStringConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined { + return tryParse(() => { + const stringLiteral = parseLiteralNode(); + if (isStringLiteral(stringLiteral) && stringLiteral.text === "constructor") { + node.kind = SyntaxKind.Constructor; + node.name = stringLiteral; + return parseConstructorDeclarationEnd(node); + } + }); + } + function parseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration { node.kind = SyntaxKind.Constructor; parseExpected(SyntaxKind.ConstructorKeyword); + return parseConstructorDeclarationEnd(node); + } + + function parseConstructorDeclarationEnd(node: ConstructorDeclaration): ConstructorDeclaration { fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); return finishNode(node); @@ -5861,6 +5876,13 @@ namespace ts { return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); } + if (token() === SyntaxKind.StringLiteral) { + const stringConstructor = tryParseStringConstructorDeclaration(node); + if (stringConstructor) { + return stringConstructor; + } + } + if (token() === SyntaxKind.ConstructorKeyword) { return parseConstructorDeclaration(node); } diff --git a/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts b/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts index 3ab45c72810cd..65071c4f84b22 100644 --- a/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts +++ b/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts @@ -1,17 +1,25 @@ class C { - "constructor"() {} // Error in 3.5 + "constructor"() { + console.log(this); + } } class D { - 'constructor'() {} // Error in 3.5 + 'constructor'() { + console.log(this); + } } class E { - ['constructor']() {} + ['constructor']() { + console.log(this); + } } new class { - "constructor"() {} // Error in 3.5 + "constructor"() { + console.log(this); + } }; var o = { "constructor"() {} }; From 3b26b45f18919014e7ebe43045f1c92a9ab26128 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 Jun 2019 16:47:05 -0700 Subject: [PATCH 2/6] Update baselines --- .../reference/quotedConstructors.errors.txt | 30 ---------- .../baselines/reference/quotedConstructors.js | 26 ++++++--- .../reference/quotedConstructors.symbols | 55 ++++++++++++++----- .../reference/quotedConstructors.types | 49 ++++++++++++++--- 4 files changed, 99 insertions(+), 61 deletions(-) delete mode 100644 tests/baselines/reference/quotedConstructors.errors.txt diff --git a/tests/baselines/reference/quotedConstructors.errors.txt b/tests/baselines/reference/quotedConstructors.errors.txt deleted file mode 100644 index 9e70452ff4062..0000000000000 --- a/tests/baselines/reference/quotedConstructors.errors.txt +++ /dev/null @@ -1,30 +0,0 @@ -tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts(2,5): error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. -tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts(6,5): error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. -tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts(14,5): error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. - - -==== tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts (3 errors) ==== - class C { - "constructor"() {} // Error in 3.5 - ~~~~~~~~~~~~~ -!!! error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. - } - - class D { - 'constructor'() {} // Error in 3.5 - ~~~~~~~~~~~~~ -!!! error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. - } - - class E { - ['constructor']() {} - } - - new class { - "constructor"() {} // Error in 3.5 - ~~~~~~~~~~~~~ -!!! error TS18005: Quoted constructors have previously been interpreted as methods, which is incorrect. In TypeScript 3.6, they will be correctly parsed as constructors. In the meantime, consider using 'constructor()' to write a constructor, or '["constructor"]()' to write a method. - }; - - var o = { "constructor"() {} }; - \ No newline at end of file diff --git a/tests/baselines/reference/quotedConstructors.js b/tests/baselines/reference/quotedConstructors.js index c9a662e6af526..672e1fd342282 100644 --- a/tests/baselines/reference/quotedConstructors.js +++ b/tests/baselines/reference/quotedConstructors.js @@ -1,18 +1,26 @@ //// [quotedConstructors.ts] class C { - "constructor"() {} // Error in 3.5 + "constructor"() { + console.log(this); + } } class D { - 'constructor'() {} // Error in 3.5 + 'constructor'() { + console.log(this); + } } class E { - ['constructor']() {} + ['constructor']() { + console.log(this); + } } new class { - "constructor"() {} // Error in 3.5 + "constructor"() { + console.log(this); + } }; var o = { "constructor"() {} }; @@ -21,26 +29,28 @@ var o = { "constructor"() {} }; //// [quotedConstructors.js] var C = /** @class */ (function () { function C() { + console.log(this); } - C.prototype["constructor"] = function () { }; // Error in 3.5 return C; }()); var D = /** @class */ (function () { function D() { + console.log(this); } - D.prototype['constructor'] = function () { }; // Error in 3.5 return D; }()); var E = /** @class */ (function () { function E() { } - E.prototype['constructor'] = function () { }; + E.prototype['constructor'] = function () { + console.log(this); + }; return E; }()); new /** @class */ (function () { function class_1() { + console.log(this); } - class_1.prototype["constructor"] = function () { }; // Error in 3.5 return class_1; }()); var o = { "constructor": function () { } }; diff --git a/tests/baselines/reference/quotedConstructors.symbols b/tests/baselines/reference/quotedConstructors.symbols index be68e48484754..4cb566d1a4bce 100644 --- a/tests/baselines/reference/quotedConstructors.symbols +++ b/tests/baselines/reference/quotedConstructors.symbols @@ -2,32 +2,59 @@ class C { >C : Symbol(C, Decl(quotedConstructors.ts, 0, 0)) - "constructor"() {} // Error in 3.5 + "constructor"() { >"constructor" : Symbol(C["constructor"], Decl(quotedConstructors.ts, 0, 9)) + + console.log(this); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol(C, Decl(quotedConstructors.ts, 0, 0)) + } } class D { ->D : Symbol(D, Decl(quotedConstructors.ts, 2, 1)) +>D : Symbol(D, Decl(quotedConstructors.ts, 4, 1)) + + 'constructor'() { +>'constructor' : Symbol(D['constructor'], Decl(quotedConstructors.ts, 6, 9)) - 'constructor'() {} // Error in 3.5 ->'constructor' : Symbol(D['constructor'], Decl(quotedConstructors.ts, 4, 9)) + console.log(this); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol(D, Decl(quotedConstructors.ts, 4, 1)) + } } class E { ->E : Symbol(E, Decl(quotedConstructors.ts, 6, 1)) - - ['constructor']() {} ->['constructor'] : Symbol(E['constructor'], Decl(quotedConstructors.ts, 8, 9)) ->'constructor' : Symbol(E['constructor'], Decl(quotedConstructors.ts, 8, 9)) +>E : Symbol(E, Decl(quotedConstructors.ts, 10, 1)) + + ['constructor']() { +>['constructor'] : Symbol(E['constructor'], Decl(quotedConstructors.ts, 12, 9)) +>'constructor' : Symbol(E['constructor'], Decl(quotedConstructors.ts, 12, 9)) + + console.log(this); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol(E, Decl(quotedConstructors.ts, 10, 1)) + } } new class { - "constructor"() {} // Error in 3.5 ->"constructor" : Symbol((Anonymous class)["constructor"], Decl(quotedConstructors.ts, 12, 11)) - + "constructor"() { +>"constructor" : Symbol((Anonymous class)["constructor"], Decl(quotedConstructors.ts, 18, 11)) + + console.log(this); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol((Anonymous class), Decl(quotedConstructors.ts, 18, 3)) + } }; var o = { "constructor"() {} }; ->o : Symbol(o, Decl(quotedConstructors.ts, 16, 3)) ->"constructor" : Symbol("constructor", Decl(quotedConstructors.ts, 16, 9)) +>o : Symbol(o, Decl(quotedConstructors.ts, 24, 3)) +>"constructor" : Symbol("constructor", Decl(quotedConstructors.ts, 24, 9)) diff --git a/tests/baselines/reference/quotedConstructors.types b/tests/baselines/reference/quotedConstructors.types index 907a2152a80ac..38ec02d030c60 100644 --- a/tests/baselines/reference/quotedConstructors.types +++ b/tests/baselines/reference/quotedConstructors.types @@ -2,32 +2,63 @@ class C { >C : C - "constructor"() {} // Error in 3.5 ->"constructor" : () => void + "constructor"() { +>"constructor" : error + + console.log(this); +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + } } class D { >D : D - 'constructor'() {} // Error in 3.5 ->'constructor' : () => void + 'constructor'() { +>'constructor' : error + + console.log(this); +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + } } class E { >E : E - ['constructor']() {} + ['constructor']() { >['constructor'] : () => void >'constructor' : "constructor" + + console.log(this); +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + } } new class { ->new class { "constructor"() {} // Error in 3.5} : (Anonymous class) ->class { "constructor"() {} // Error in 3.5} : typeof (Anonymous class) +>new class { "constructor"() { console.log(this); }} : (Anonymous class) +>class { "constructor"() { console.log(this); }} : typeof (Anonymous class) - "constructor"() {} // Error in 3.5 ->"constructor" : () => void + "constructor"() { +>"constructor" : error + console.log(this); +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + } }; var o = { "constructor"() {} }; From ca3c47473f375d306339bf714d406126e1cdc9b3 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 17 Jun 2019 16:58:58 -0700 Subject: [PATCH 3/6] Fix disambiguation between quoted constructor and property named constructor --- src/compiler/parser.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d043a9d737255..03b13f23b1255 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5653,7 +5653,10 @@ namespace ts { function tryParseStringConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined { return tryParse(() => { const stringLiteral = parseLiteralNode(); - if (isStringLiteral(stringLiteral) && stringLiteral.text === "constructor") { + if (isStringLiteral(stringLiteral) + && stringLiteral.text === "constructor" + && token() === SyntaxKind.OpenParenToken + ) { node.kind = SyntaxKind.Constructor; node.name = stringLiteral; return parseConstructorDeclarationEnd(node); From 10a5fbd3d66e9e933194bd8820c821dc2c641817 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 18 Jun 2019 15:40:57 -0700 Subject: [PATCH 4/6] Clean up parsing a bit --- src/compiler/parser.ts | 48 ++++++++----------- src/compiler/utilities.ts | 17 +++++++ src/services/utilities.ts | 17 ------- .../reference/quotedConstructors.symbols | 6 --- .../reference/quotedConstructors.types | 6 --- 5 files changed, 37 insertions(+), 57 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 03b13f23b1255..824a6c7c7aa23 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5650,32 +5650,28 @@ namespace ts { return finishNode(node); } - function tryParseStringConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined { + function parseConstructorName() { + if (token() === SyntaxKind.ConstructorKeyword) { + return parseExpected(SyntaxKind.ConstructorKeyword); + } + if (token() === SyntaxKind.StringLiteral + && stripQuotes(scanner.getTokenText()) === "constructor" + && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { + return parseLiteralNode(); + } + } + + function tryParseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration | undefined { return tryParse(() => { - const stringLiteral = parseLiteralNode(); - if (isStringLiteral(stringLiteral) - && stringLiteral.text === "constructor" - && token() === SyntaxKind.OpenParenToken - ) { + if (parseConstructorName()) { node.kind = SyntaxKind.Constructor; - node.name = stringLiteral; - return parseConstructorDeclarationEnd(node); + fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); + node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); + return finishNode(node); } }); } - function parseConstructorDeclaration(node: ConstructorDeclaration): ConstructorDeclaration { - node.kind = SyntaxKind.Constructor; - parseExpected(SyntaxKind.ConstructorKeyword); - return parseConstructorDeclarationEnd(node); - } - - function parseConstructorDeclarationEnd(node: ConstructorDeclaration): ConstructorDeclaration { - fillSignature(SyntaxKind.ColonToken, SignatureFlags.None, node); - node.body = parseFunctionBlockOrSemicolon(SignatureFlags.None, Diagnostics.or_expected); - return finishNode(node); - } - function parseMethodDeclaration(node: MethodDeclaration, asteriskToken: AsteriskToken, diagnosticMessage?: DiagnosticMessage): MethodDeclaration { node.kind = SyntaxKind.MethodDeclaration; node.asteriskToken = asteriskToken; @@ -5879,17 +5875,13 @@ namespace ts { return parseAccessorDeclaration(node, SyntaxKind.SetAccessor); } - if (token() === SyntaxKind.StringLiteral) { - const stringConstructor = tryParseStringConstructorDeclaration(node); - if (stringConstructor) { - return stringConstructor; + if (token() === SyntaxKind.ConstructorKeyword || token() === SyntaxKind.StringLiteral) { + const constructorDeclaration = tryParseConstructorDeclaration(node); + if (constructorDeclaration) { + return constructorDeclaration; } } - if (token() === SyntaxKind.ConstructorKeyword) { - return parseConstructorDeclaration(node); - } - if (isIndexSignature()) { return parseIndexSignatureDeclaration(node); } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 0ec81502cf799..1a8d5a4a8c611 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -3148,6 +3148,23 @@ namespace ts { return s.replace(escapedCharsRegExp, getReplacement); } + /** + * Strip off existed single quotes or double quotes from a given string + * + * @return non-quoted string + */ + export function stripQuotes(name: string) { + const length = name.length; + if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) { + return name.substring(1, length - 1); + } + return name; + } + + export function startsWithQuote(name: string): boolean { + return isSingleOrDoubleQuote(name.charCodeAt(0)); + } + function getReplacement(c: string, offset: number, input: string) { if (c.charCodeAt(0) === CharacterCodes.nullCharacter) { const lookAhead = input.charCodeAt(offset + c.length); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 5506b45d3808d..fa3da3def1c25 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1636,23 +1636,6 @@ namespace ts { return !!location.parent && isImportOrExportSpecifier(location.parent) && location.parent.propertyName === location; } - /** - * Strip off existed single quotes or double quotes from a given string - * - * @return non-quoted string - */ - export function stripQuotes(name: string) { - const length = name.length; - if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && startsWithQuote(name)) { - return name.substring(1, length - 1); - } - return name; - } - - export function startsWithQuote(name: string): boolean { - return isSingleOrDoubleQuote(name.charCodeAt(0)); - } - export function scriptKindIs(fileName: string, host: LanguageServiceHost, ...scriptKinds: ScriptKind[]): boolean { const scriptKind = getScriptKind(fileName, host); return some(scriptKinds, k => k === scriptKind); diff --git a/tests/baselines/reference/quotedConstructors.symbols b/tests/baselines/reference/quotedConstructors.symbols index 4cb566d1a4bce..c69edd126b24e 100644 --- a/tests/baselines/reference/quotedConstructors.symbols +++ b/tests/baselines/reference/quotedConstructors.symbols @@ -3,8 +3,6 @@ class C { >C : Symbol(C, Decl(quotedConstructors.ts, 0, 0)) "constructor"() { ->"constructor" : Symbol(C["constructor"], Decl(quotedConstructors.ts, 0, 9)) - console.log(this); >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) >console : Symbol(console, Decl(lib.dom.d.ts, --, --)) @@ -17,8 +15,6 @@ class D { >D : Symbol(D, Decl(quotedConstructors.ts, 4, 1)) 'constructor'() { ->'constructor' : Symbol(D['constructor'], Decl(quotedConstructors.ts, 6, 9)) - console.log(this); >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) >console : Symbol(console, Decl(lib.dom.d.ts, --, --)) @@ -44,8 +40,6 @@ class E { new class { "constructor"() { ->"constructor" : Symbol((Anonymous class)["constructor"], Decl(quotedConstructors.ts, 18, 11)) - console.log(this); >console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) >console : Symbol(console, Decl(lib.dom.d.ts, --, --)) diff --git a/tests/baselines/reference/quotedConstructors.types b/tests/baselines/reference/quotedConstructors.types index 38ec02d030c60..573c47683d7b9 100644 --- a/tests/baselines/reference/quotedConstructors.types +++ b/tests/baselines/reference/quotedConstructors.types @@ -3,8 +3,6 @@ class C { >C : C "constructor"() { ->"constructor" : error - console.log(this); >console.log(this) : void >console.log : (message?: any, ...optionalParams: any[]) => void @@ -18,8 +16,6 @@ class D { >D : D 'constructor'() { ->'constructor' : error - console.log(this); >console.log(this) : void >console.log : (message?: any, ...optionalParams: any[]) => void @@ -50,8 +46,6 @@ new class { >class { "constructor"() { console.log(this); }} : typeof (Anonymous class) "constructor"() { ->"constructor" : error - console.log(this); >console.log(this) : void >console.log : (message?: any, ...optionalParams: any[]) => void From 85bfd29513067e4c1e02b1a06ba4c67e15c2819c Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Mon, 24 Jun 2019 11:33:48 -0700 Subject: [PATCH 5/6] Support escapes in constructor name --- src/compiler/parser.ts | 9 +++++---- .../constructorDeclarations/quotedConstructors.ts | 6 ++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 824a6c7c7aa23..84174079209c3 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5654,10 +5654,11 @@ namespace ts { if (token() === SyntaxKind.ConstructorKeyword) { return parseExpected(SyntaxKind.ConstructorKeyword); } - if (token() === SyntaxKind.StringLiteral - && stripQuotes(scanner.getTokenText()) === "constructor" - && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { - return parseLiteralNode(); + if (token() === SyntaxKind.StringLiteral && lookAhead(nextToken) === SyntaxKind.OpenParenToken) { + return tryParse(() => { + const literalNode = parseLiteralNode(); + return literalNode.text === "constructor" ? literalNode : undefined; + }); } } diff --git a/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts b/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts index 65071c4f84b22..c03ce26cc2f6e 100644 --- a/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts +++ b/tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts @@ -23,3 +23,9 @@ new class { }; var o = { "constructor"() {} }; + +class F { + "\x63onstructor"() { + console.log(this); + } +} From 32a3751b0e68eaddc7f1208b28afb1fe64e49b78 Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 26 Jun 2019 10:45:14 -0700 Subject: [PATCH 6/6] Update baselines --- tests/baselines/reference/quotedConstructors.js | 12 ++++++++++++ .../baselines/reference/quotedConstructors.symbols | 12 ++++++++++++ tests/baselines/reference/quotedConstructors.types | 13 +++++++++++++ 3 files changed, 37 insertions(+) diff --git a/tests/baselines/reference/quotedConstructors.js b/tests/baselines/reference/quotedConstructors.js index 672e1fd342282..36b57718f0a49 100644 --- a/tests/baselines/reference/quotedConstructors.js +++ b/tests/baselines/reference/quotedConstructors.js @@ -24,6 +24,12 @@ new class { }; var o = { "constructor"() {} }; + +class F { + "\x63onstructor"() { + console.log(this); + } +} //// [quotedConstructors.js] @@ -54,3 +60,9 @@ new /** @class */ (function () { return class_1; }()); var o = { "constructor": function () { } }; +var F = /** @class */ (function () { + function F() { + console.log(this); + } + return F; +}()); diff --git a/tests/baselines/reference/quotedConstructors.symbols b/tests/baselines/reference/quotedConstructors.symbols index c69edd126b24e..a4476a25ae5e8 100644 --- a/tests/baselines/reference/quotedConstructors.symbols +++ b/tests/baselines/reference/quotedConstructors.symbols @@ -52,3 +52,15 @@ var o = { "constructor"() {} }; >o : Symbol(o, Decl(quotedConstructors.ts, 24, 3)) >"constructor" : Symbol("constructor", Decl(quotedConstructors.ts, 24, 9)) +class F { +>F : Symbol(F, Decl(quotedConstructors.ts, 24, 31)) + + "\x63onstructor"() { + console.log(this); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>this : Symbol(F, Decl(quotedConstructors.ts, 24, 31)) + } +} + diff --git a/tests/baselines/reference/quotedConstructors.types b/tests/baselines/reference/quotedConstructors.types index 573c47683d7b9..65be89ff815a9 100644 --- a/tests/baselines/reference/quotedConstructors.types +++ b/tests/baselines/reference/quotedConstructors.types @@ -60,3 +60,16 @@ var o = { "constructor"() {} }; >{ "constructor"() {} } : { "constructor"(): void; } >"constructor" : () => void +class F { +>F : F + + "\x63onstructor"() { + console.log(this); +>console.log(this) : void +>console.log : (message?: any, ...optionalParams: any[]) => void +>console : Console +>log : (message?: any, ...optionalParams: any[]) => void +>this : this + } +} +