Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emit grammar error on quoted constructors and class fields named “constructor” #31119

Merged
merged 7 commits into from May 1, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/compiler/checker.ts
Expand Up @@ -31468,6 +31468,9 @@ 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;
}
Expand Down
6 changes: 5 additions & 1 deletion src/compiler/diagnosticMessages.json
Expand Up @@ -2959,7 +2959,7 @@
"category": "Error",
"code": 4104
},

"The current host does not support the '{0}' option.": {
"category": "Error",
"code": 5001
Expand Down Expand Up @@ -4954,5 +4954,9 @@
"No value exists in scope for the shorthand property '{0}'. Either declare one or provide an initializer." :{
"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": 96000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use a normal code here; it's fine to introduce a gap in the sequence later

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was confused about why 18004 was way down here. Now I see that's the latest of an earlier sequence.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to 18005

}
}
30 changes: 30 additions & 0 deletions tests/baselines/reference/quotedConstructors.errors.txt
@@ -0,0 +1,30 @@
tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts(2,5): error TS96000: 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 TS96000: 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 TS96000: 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 TS96000: 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 TS96000: 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 TS96000: 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"() {} };

46 changes: 46 additions & 0 deletions tests/baselines/reference/quotedConstructors.js
@@ -0,0 +1,46 @@
//// [quotedConstructors.ts]
class C {
"constructor"() {} // Error in 3.5
}

class D {
'constructor'() {} // Error in 3.5
}

class E {
['constructor']() {}
}

new class {
"constructor"() {} // Error in 3.5
};

var o = { "constructor"() {} };


//// [quotedConstructors.js]
var C = /** @class */ (function () {
function C() {
}
C.prototype["constructor"] = function () { }; // Error in 3.5
return C;
}());
var D = /** @class */ (function () {
function D() {
}
D.prototype['constructor'] = function () { }; // Error in 3.5
return D;
}());
var E = /** @class */ (function () {
function E() {
}
E.prototype['constructor'] = function () { };
return E;
}());
new /** @class */ (function () {
function class_1() {
}
class_1.prototype["constructor"] = function () { }; // Error in 3.5
return class_1;
}());
var o = { "constructor": function () { } };
33 changes: 33 additions & 0 deletions tests/baselines/reference/quotedConstructors.symbols
@@ -0,0 +1,33 @@
=== tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts ===
class C {
>C : Symbol(C, Decl(quotedConstructors.ts, 0, 0))

"constructor"() {} // Error in 3.5
>"constructor" : Symbol(C["constructor"], Decl(quotedConstructors.ts, 0, 9))
}

class D {
>D : Symbol(D, Decl(quotedConstructors.ts, 2, 1))

'constructor'() {} // Error in 3.5
>'constructor' : Symbol(D['constructor'], Decl(quotedConstructors.ts, 4, 9))
}

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))
}

new class {
"constructor"() {} // Error in 3.5
>"constructor" : Symbol((Anonymous class)["constructor"], Decl(quotedConstructors.ts, 12, 11))

};

var o = { "constructor"() {} };
>o : Symbol(o, Decl(quotedConstructors.ts, 16, 3))
>"constructor" : Symbol("constructor", Decl(quotedConstructors.ts, 16, 9))

37 changes: 37 additions & 0 deletions tests/baselines/reference/quotedConstructors.types
@@ -0,0 +1,37 @@
=== tests/cases/conformance/classes/constructorDeclarations/quotedConstructors.ts ===
class C {
>C : C

"constructor"() {} // Error in 3.5
>"constructor" : () => void
}

class D {
>D : D

'constructor'() {} // Error in 3.5
>'constructor' : () => void
}

class E {
>E : E

['constructor']() {}
>['constructor'] : () => void
>'constructor' : "constructor"
}

new class {
>new class { "constructor"() {} // Error in 3.5} : (Anonymous class)
>class { "constructor"() {} // Error in 3.5} : typeof (Anonymous class)

"constructor"() {} // Error in 3.5
>"constructor" : () => void

};

var o = { "constructor"() {} };
>o : { "constructor"(): void; }
>{ "constructor"() {} } : { "constructor"(): void; }
>"constructor" : () => void

@@ -0,0 +1,17 @@
class C {
"constructor"() {} // Error in 3.5
}

class D {
'constructor'() {} // Error in 3.5
}

class E {
['constructor']() {}
}

new class {
"constructor"() {} // Error in 3.5
};

var o = { "constructor"() {} };