diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6524a69f13..d756f215ac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14764,49 +14764,43 @@ namespace ts { } } - // Static members may conflict with non-configurable non-writable built-in Function.prototype properties + // Static members may conflict with non-configurable non-writable built-in Function object properties // see https://github.com/microsoft/typescript/issues/442. function checkClassForStaticPropertyNameConflicts(node: ClassLikeDeclaration) { - const es5_descriptors: PropertyDescriptorMap = { - // see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 - // see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 - "name": { configurable: false, writable: false }, - "length": { configurable: false, writable: false }, - "prototype": { configurable: false, writable: false }, - - // see https://github.com/microsoft/typescript/issues/442 - "caller": { configurable: false, writable: false }, - "arguments": { configurable: false, writable: false } - }; - const post_es5_descriptors: PropertyDescriptorMap = { - // see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor - // see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances - "name": { configurable: true, writable: false }, - "length": { configurable: true, writable: false }, - "prototype": { configurable: false, writable: false }, - "caller": { configurable: false, writable: false }, - "arguments": { configurable: false, writable: false } - }; const message = Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1; const className = getSymbolOfNode(node).name; - for (const member of node.members) { - const isStatic = forEach(member.modifiers, (m: Modifier) => m.kind === SyntaxKind.StaticKeyword); - if (isStatic) { - const memberNameNode = member.name; - if (memberNameNode) { - const memberName = getPropertyNameForPropertyNameNode(memberNameNode); - let descriptor: PropertyDescriptor = undefined; - if (languageVersion <= ScriptTarget.ES5) { - descriptor = es5_descriptors.hasOwnProperty(memberName) ? es5_descriptors[memberName] : undefined; - } - else if (languageVersion > ScriptTarget.ES5) { - descriptor = post_es5_descriptors.hasOwnProperty(memberName) ? post_es5_descriptors[memberName] : undefined; - } - if (descriptor && descriptor.configurable === false && descriptor.writable === false) { + const isStatic = forEach(member.modifiers, (m: Modifier) => m.kind === SyntaxKind.StaticKeyword); + const isMethod = member.kind === SyntaxKind.MethodDeclaration; + const memberNameNode = member.name; + if (isStatic && memberNameNode) { + const memberName = getPropertyNameForPropertyNameNode(memberNameNode); + if (languageVersion <= ScriptTarget.ES5) { // ES3, ES5 + // see also http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 + // see also http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 + if (memberName === "prototype" || + memberName === "name" || + memberName === "length" || + memberName === "caller" || + memberName === "arguments" + ) { error(memberNameNode, message, memberName, className); } } + else { // ES6+ + // see also http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor + // see also http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances + if (memberName === "prototype") { + error(memberNameNode, message, memberName, className); + } + else if (( + memberName === "caller" || + memberName === "arguments" ) && + isMethod === false + ) { + error(memberNameNode, message, memberName, className); + } + } } } } diff --git a/tests/baselines/reference/staticPropertyNameConflictsEs6.errors.txt b/tests/baselines/reference/staticPropertyNameConflictsEs6.errors.txt index ef83151aa3..b73b01abbb 100644 --- a/tests/baselines/reference/staticPropertyNameConflictsEs6.errors.txt +++ b/tests/baselines/reference/staticPropertyNameConflictsEs6.errors.txt @@ -2,12 +2,10 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(31,12): error TS2300: Duplicate identifier 'prototype'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(31,12): error TS2699: Static property 'prototype' conflicts with built-in property 'Function.prototype' of constructor function 'StaticPrototypeFn'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(37,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCaller'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(42,12): error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(48,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArguments'. -tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts(53,12): error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. -==== tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts (7 errors) ==== +==== tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts (5 errors) ==== class StaticName { @@ -57,9 +55,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon } class StaticCallerFn { - static caller() {} // error - ~~~~~~ -!!! error TS2699: Static property 'caller' conflicts with built-in property 'Function.caller' of constructor function 'StaticCallerFn'. + static caller() {} // ok caller() {} // ok } @@ -72,9 +68,7 @@ tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameCon } class StaticArgumentsFn { - static arguments() {} // error - ~~~~~~~~~ -!!! error TS2699: Static property 'arguments' conflicts with built-in property 'Function.arguments' of constructor function 'StaticArgumentsFn'. + static arguments() {} // ok arguments() {} // ok } \ No newline at end of file diff --git a/tests/baselines/reference/staticPropertyNameConflictsEs6.js b/tests/baselines/reference/staticPropertyNameConflictsEs6.js index 48e8b7a063..8d96c73d4c 100644 --- a/tests/baselines/reference/staticPropertyNameConflictsEs6.js +++ b/tests/baselines/reference/staticPropertyNameConflictsEs6.js @@ -40,7 +40,7 @@ class StaticCaller { } class StaticCallerFn { - static caller() {} // error + static caller() {} // ok caller() {} // ok } @@ -51,7 +51,7 @@ class StaticArguments { } class StaticArgumentsFn { - static arguments() {} // error + static arguments() {} // ok arguments() {} // ok } @@ -78,12 +78,12 @@ class StaticPrototypeFn { class StaticCaller { } class StaticCallerFn { - static caller() { } // error + static caller() { } // ok caller() { } // ok } class StaticArguments { } class StaticArgumentsFn { - static arguments() { } // error + static arguments() { } // ok arguments() { } // ok } diff --git a/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts index 412833791b..01db0c2787 100644 --- a/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts +++ b/tests/cases/conformance/classes/propertyMemberDeclarations/staticPropertyNameConflictsEs6.ts @@ -40,7 +40,7 @@ class StaticCaller { } class StaticCallerFn { - static caller() {} // error + static caller() {} // ok caller() {} // ok } @@ -51,6 +51,6 @@ class StaticArguments { } class StaticArgumentsFn { - static arguments() {} // error + static arguments() {} // ok arguments() {} // ok }