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

Impossible to define static 'length' function on class #9215

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
41 changes: 39 additions & 2 deletions src/compiler/checker.ts
Expand Up @@ -14217,14 +14217,14 @@ namespace ts {

function checkPropertyDeclaration(node: PropertyDeclaration) {
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name) || checkGrammarStaticPropertyOrMethodName(node);

checkVariableLikeDeclaration(node);
}

function checkMethodDeclaration(node: MethodDeclaration) {
// Grammar checking
checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name);
checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name) || checkGrammarStaticPropertyOrMethodName(node);

// Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
checkFunctionOrMethodDeclaration(node);
Expand All @@ -14236,6 +14236,36 @@ namespace ts {
}
}

function checkGrammarStaticPropertyOrMethodName(node: ClassElement) {
if (node.flags & ModifierFlags.Static) {
if (node.kind === SyntaxKind.PropertyDeclaration) {
return checkGrammarStaticMemberName(node, ((node as ClassElement).name as Identifier).text);
}
else if (node.kind === SyntaxKind.MethodDeclaration) {
if (languageVersion < ScriptTarget.ES6) {
return checkGrammarStaticMemberName(node, ((node as ClassElement).name as Identifier).text);
}
}
}

return false;
}

function checkGrammarStaticMemberName(node: Node, name: string) {
// see: https://github.com/Microsoft/TypeScript/issues/442
const forbiddenNames = ["length", "name", "arguments", "caller"];
if (forbiddenNames.indexOf(name) !== -1) {
if (languageVersion < ScriptTarget.ES6) {
return grammarErrorOnNode(node, Diagnostics._0_is_not_allowed_to_be_used_as_a_name_of_a_static_property_or_method_in_a_class_for_target_ES5, name);
}
else {
return grammarErrorOnNode(node, Diagnostics._0_is_not_allowed_to_be_used_as_a_name_of_a_static_property_in_a_class_for_target_ES6_and_higher, name);
}
}

return false;
}

function checkConstructorDeclaration(node: ConstructorDeclaration) {
// Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
checkSignatureDeclaration(node);
Expand Down Expand Up @@ -19714,6 +19744,13 @@ namespace ts {
if (computedPropertyName.expression.kind === SyntaxKind.BinaryExpression && (<BinaryExpression>computedPropertyName.expression).operatorToken.kind === SyntaxKind.CommaToken) {
return grammarErrorOnNode(computedPropertyName.expression, Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name);
}

if (computedPropertyName.expression.kind === SyntaxKind.StringLiteral) {
const member = computedPropertyName.parent.parent.parent;
if (member.flags & ModifierFlags.Static && member.kind === SyntaxKind.PropertyDeclaration) {
return checkGrammarStaticMemberName(computedPropertyName, (computedPropertyName.expression as StringLiteral).text);
}
}
}

function checkGrammarForGenerator(node: FunctionLikeDeclaration) {
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -1959,6 +1959,14 @@
"category": "Error",
"code": 2695
},
"'{0}' is not allowed to be used as a name of a static property or method in a class for target ES5.": {
"category": "Error",
"code": 2696
},
"'{0}' is not allowed to be used as a name of a static property in a class for target ES6 and higher.": {
"category": "Error",
"code": 2697
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
49 changes: 49 additions & 0 deletions tests/baselines/reference/checkGrammarStaticMemberName_es5.js
@@ -0,0 +1,49 @@
//// [checkGrammarStaticMemberName_es5.ts]

class static_property {
static length = 1;
static name = 1;
static arguments = 1;
static caller = 1;
static foo = {
["length"]: 1,
["name"]: 1,
["arguments"]: 1,
["caller"]: 1,
};
}

class static_method {
static length() { return 1; }
static name() { return 1; }
static arguments() { return 1; }
static caller() { return 1; }
}


//// [checkGrammarStaticMemberName_es5.js]
var static_property = (function () {
function static_property() {
}
return static_property;
}());
static_property.length = 1;
static_property.name = 1;
static_property.arguments = 1;
static_property.caller = 1;
static_property.foo = (_a = {},
_a["length"] = 1,
_a["name"] = 1,
_a["arguments"] = 1,
_a["caller"] = 1,
_a);
var static_method = (function () {
function static_method() {
}
static_method.length = function () { return 1; };
static_method.name = function () { return 1; };
static_method.arguments = function () { return 1; };
static_method.caller = function () { return 1; };
return static_method;
}());
var _a;
51 changes: 51 additions & 0 deletions tests/baselines/reference/checkGrammarStaticMemberName_es5.symbols
@@ -0,0 +1,51 @@
=== tests/cases/compiler/checkGrammarStaticMemberName_es5.ts ===

class static_property {
>static_property : Symbol(static_property, Decl(checkGrammarStaticMemberName_es5.ts, 0, 0))

static length = 1;
>length : Symbol(static_property.length, Decl(checkGrammarStaticMemberName_es5.ts, 1, 23))

static name = 1;
>name : Symbol(static_property.name, Decl(checkGrammarStaticMemberName_es5.ts, 2, 22))

static arguments = 1;
>arguments : Symbol(static_property.arguments, Decl(checkGrammarStaticMemberName_es5.ts, 3, 20))

static caller = 1;
>caller : Symbol(static_property.caller, Decl(checkGrammarStaticMemberName_es5.ts, 4, 25))

static foo = {
>foo : Symbol(static_property.foo, Decl(checkGrammarStaticMemberName_es5.ts, 5, 22))

["length"]: 1,
>"length" : Symbol(["length"], Decl(checkGrammarStaticMemberName_es5.ts, 6, 18))

["name"]: 1,
>"name" : Symbol(["name"], Decl(checkGrammarStaticMemberName_es5.ts, 7, 22))

["arguments"]: 1,
>"arguments" : Symbol(["arguments"], Decl(checkGrammarStaticMemberName_es5.ts, 8, 20))

["caller"]: 1,
>"caller" : Symbol(["caller"], Decl(checkGrammarStaticMemberName_es5.ts, 9, 25))

};
}

class static_method {
>static_method : Symbol(static_method, Decl(checkGrammarStaticMemberName_es5.ts, 12, 1))

static length() { return 1; }
>length : Symbol(static_method.length, Decl(checkGrammarStaticMemberName_es5.ts, 14, 21))

static name() { return 1; }
>name : Symbol(static_method.name, Decl(checkGrammarStaticMemberName_es5.ts, 15, 33))

static arguments() { return 1; }
>arguments : Symbol(static_method.arguments, Decl(checkGrammarStaticMemberName_es5.ts, 16, 31))

static caller() { return 1; }
>caller : Symbol(static_method.caller, Decl(checkGrammarStaticMemberName_es5.ts, 17, 36))
}

64 changes: 64 additions & 0 deletions tests/baselines/reference/checkGrammarStaticMemberName_es5.types
@@ -0,0 +1,64 @@
=== tests/cases/compiler/checkGrammarStaticMemberName_es5.ts ===

class static_property {
>static_property : static_property

static length = 1;
>length : number
>1 : 1

static name = 1;
>name : number
>1 : 1

static arguments = 1;
>arguments : number
>1 : 1

static caller = 1;
>caller : number
>1 : 1

static foo = {
>foo : { ["length"]: number; ["name"]: number; ["arguments"]: number; ["caller"]: number; }
>{ ["length"]: 1, ["name"]: 1, ["arguments"]: 1, ["caller"]: 1, } : { ["length"]: number; ["name"]: number; ["arguments"]: number; ["caller"]: number; }

["length"]: 1,
>"length" : "length"
>1 : 1

["name"]: 1,
>"name" : "name"
>1 : 1

["arguments"]: 1,
>"arguments" : "arguments"
>1 : 1

["caller"]: 1,
>"caller" : "caller"
>1 : 1

};
}

class static_method {
>static_method : static_method

static length() { return 1; }
>length : () => number
>1 : 1

static name() { return 1; }
>name : () => number
>1 : 1

static arguments() { return 1; }
>arguments : () => number
>1 : 1

static caller() { return 1; }
>caller : () => number
>1 : 1
}

42 changes: 42 additions & 0 deletions tests/baselines/reference/checkGrammarStaticMemberName_es6.js
@@ -0,0 +1,42 @@
//// [checkGrammarStaticMemberName_es6.ts]

class static_property {
static length = 1;
static name = 1;
static arguments = 1;
static caller = 1;
static foo = {
["length"]: 1,
["name"]: 1,
["arguments"]: 1,
["caller"]: 1,
};
}

class static_method {
static length() { return 1; }
static name() { return 1; }
static arguments() { return 1; }
static caller() { return 1; }
}


//// [checkGrammarStaticMemberName_es6.js]
class static_property {
}
static_property.length = 1;
static_property.name = 1;
static_property.arguments = 1;
static_property.caller = 1;
static_property.foo = {
["length"]: 1,
["name"]: 1,
["arguments"]: 1,
["caller"]: 1,
};
class static_method {
static length() { return 1; }
static name() { return 1; }
static arguments() { return 1; }
static caller() { return 1; }
}
51 changes: 51 additions & 0 deletions tests/baselines/reference/checkGrammarStaticMemberName_es6.symbols
@@ -0,0 +1,51 @@
=== tests/cases/compiler/checkGrammarStaticMemberName_es6.ts ===

class static_property {
>static_property : Symbol(static_property, Decl(checkGrammarStaticMemberName_es6.ts, 0, 0))

static length = 1;
>length : Symbol(static_property.length, Decl(checkGrammarStaticMemberName_es6.ts, 1, 23))

static name = 1;
>name : Symbol(static_property.name, Decl(checkGrammarStaticMemberName_es6.ts, 2, 22))

static arguments = 1;
>arguments : Symbol(static_property.arguments, Decl(checkGrammarStaticMemberName_es6.ts, 3, 20))

static caller = 1;
>caller : Symbol(static_property.caller, Decl(checkGrammarStaticMemberName_es6.ts, 4, 25))

static foo = {
>foo : Symbol(static_property.foo, Decl(checkGrammarStaticMemberName_es6.ts, 5, 22))

["length"]: 1,
>"length" : Symbol(["length"], Decl(checkGrammarStaticMemberName_es6.ts, 6, 18))

["name"]: 1,
>"name" : Symbol(["name"], Decl(checkGrammarStaticMemberName_es6.ts, 7, 22))

["arguments"]: 1,
>"arguments" : Symbol(["arguments"], Decl(checkGrammarStaticMemberName_es6.ts, 8, 20))

["caller"]: 1,
>"caller" : Symbol(["caller"], Decl(checkGrammarStaticMemberName_es6.ts, 9, 25))

};
}

class static_method {
>static_method : Symbol(static_method, Decl(checkGrammarStaticMemberName_es6.ts, 12, 1))

static length() { return 1; }
>length : Symbol(static_method.length, Decl(checkGrammarStaticMemberName_es6.ts, 14, 21))

static name() { return 1; }
>name : Symbol(static_method.name, Decl(checkGrammarStaticMemberName_es6.ts, 15, 33))

static arguments() { return 1; }
>arguments : Symbol(static_method.arguments, Decl(checkGrammarStaticMemberName_es6.ts, 16, 31))

static caller() { return 1; }
>caller : Symbol(static_method.caller, Decl(checkGrammarStaticMemberName_es6.ts, 17, 36))
}