From 7fd602e59432287ab0d1748ddd709d0ac382cdf5 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 26 Mar 2018 13:02:09 -0700 Subject: [PATCH 1/2] Fix #22866: Condition checking for name collision of generated variable names on emit happening --- src/compiler/checker.ts | 14 ++- ...dCompilerDeclarationsWithNoEmit.errors.txt | 56 +++++++++++ ...rvedCompilerDeclarationsWithNoEmit.symbols | 87 ++++++++++++++++ ...servedCompilerDeclarationsWithNoEmit.types | 98 +++++++++++++++++++ ...dReservedCompilerDeclarationsWithNoEmit.ts | 53 ++++++++++ 5 files changed, 303 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.errors.txt create mode 100644 tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.symbols create mode 100644 tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.types create mode 100644 tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65807b5347b..c12ebdb4764 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21900,7 +21900,7 @@ namespace ts { function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((node).body)) { + if (languageVersion >= ScriptTarget.ES2015 || compilerOptions.noEmit || !hasRestParameter(node) || node.flags & NodeFlags.Ambient || nodeIsMissing((node).body)) { return; } @@ -21941,13 +21941,13 @@ namespace ts { } function checkCollisionWithCapturedThisVariable(node: Node, name: Identifier): void { - if (needCollisionCheckForIdentifier(node, name, "_this")) { + if (languageVersion <= ScriptTarget.ES5 && !compilerOptions.noEmit && needCollisionCheckForIdentifier(node, name, "_this")) { potentialThisCollisions.push(node); } } function checkCollisionWithCapturedNewTargetVariable(node: Node, name: Identifier): void { - if (needCollisionCheckForIdentifier(node, name, "_newTarget")) { + if (languageVersion <= ScriptTarget.ES5 &&!compilerOptions.noEmit && needCollisionCheckForIdentifier(node, name, "_newTarget")) { potentialNewTargetCollisions.push(node); } } @@ -21984,6 +21984,10 @@ namespace ts { } function checkCollisionWithCapturedSuperVariable(node: Node, name: Identifier) { + if (languageVersion >= ScriptTarget.ES2015 || compilerOptions.noEmit) { + return; + } + if (!needCollisionCheckForIdentifier(node, name, "_super")) { return; } @@ -22008,7 +22012,7 @@ namespace ts { function checkCollisionWithRequireExportsInGeneratedCode(node: Node, name: Identifier) { // No need to check for require or exports for ES6 modules and later - if (modulekind >= ModuleKind.ES2015) { + if (modulekind >= ModuleKind.ES2015 || compilerOptions.noEmit) { return; } @@ -22031,7 +22035,7 @@ namespace ts { } function checkCollisionWithGlobalPromiseInGeneratedCode(node: Node, name: Identifier): void { - if (languageVersion >= ScriptTarget.ES2017 || !needCollisionCheckForIdentifier(node, name, "Promise")) { + if (languageVersion >= ScriptTarget.ES2017 || compilerOptions.noEmit || !needCollisionCheckForIdentifier(node, name, "Promise")) { return; } diff --git a/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.errors.txt b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.errors.txt new file mode 100644 index 00000000000..55e4e20e960 --- /dev/null +++ b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.errors.txt @@ -0,0 +1,56 @@ +tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts(23,13): error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. + + +==== tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts (1 errors) ==== + // Shadowed captured this and super + class Base { } + class C extends Base { + constructor() { + super(); + } + + foo() { + let _this = this; + + () => { + _this; + }; + } + + bar() { + let _super = this; + } + } + + + /// shadowed arguments + function f1(arguments, ...a) { + ~~~~~~~~~ +!!! error TS1215: Invalid use of 'arguments'. Modules are automatically in strict mode. + } + + class C2 extends Base { + constructor() { + super(); + var _newTarget = ""; + var t = new.target; + var y = _newTarget; + } + } + + + // Shadowed Promise + var Promise = null; + async function f4() { + return 0; + } + + + // shadowed require + var require = 0; + + // shadowed exports + var exports = 0; + + + export { }; \ No newline at end of file diff --git a/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.symbols b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.symbols new file mode 100644 index 00000000000..66d2d2a338e --- /dev/null +++ b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.symbols @@ -0,0 +1,87 @@ +=== tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts === +// Shadowed captured this and super +class Base { } +>Base : Symbol(Base, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 0, 0)) + +class C extends Base { +>C : Symbol(C, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 1, 14)) +>Base : Symbol(Base, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 0, 0)) + + constructor() { + super(); +>super : Symbol(Base, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 0, 0)) + } + + foo() { +>foo : Symbol(C.foo, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 5, 5)) + + let _this = this; +>_this : Symbol(_this, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 8, 11)) +>this : Symbol(C, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 1, 14)) + + () => { + _this; +>_this : Symbol(_this, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 8, 11)) + + }; + } + + bar() { +>bar : Symbol(C.bar, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 13, 5)) + + let _super = this; +>_super : Symbol(_super, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 16, 11)) +>this : Symbol(C, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 1, 14)) + } +} + + +/// shadowed arguments +function f1(arguments, ...a) { +>f1 : Symbol(f1, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 18, 1)) +>arguments : Symbol(arguments, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 22, 12)) +>a : Symbol(a, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 22, 22)) +} + +class C2 extends Base { +>C2 : Symbol(C2, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 23, 1)) +>Base : Symbol(Base, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 0, 0)) + + constructor() { + super(); +>super : Symbol(Base, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 0, 0)) + + var _newTarget = ""; +>_newTarget : Symbol(_newTarget, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 28, 11)) + + var t = new.target; +>t : Symbol(t, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 29, 11)) + + var y = _newTarget; +>y : Symbol(y, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 30, 11)) +>_newTarget : Symbol(_newTarget, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 28, 11)) + } +} + + +// Shadowed Promise +var Promise = null; +>Promise : Symbol(Promise, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 36, 3)) + +async function f4() { +>f4 : Symbol(f4, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 36, 19)) + + return 0; +} + + +// shadowed require +var require = 0; +>require : Symbol(require, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 43, 3)) + +// shadowed exports +var exports = 0; +>exports : Symbol(exports, Decl(shadowedReservedCompilerDeclarationsWithNoEmit.ts, 46, 3)) + + +export { }; diff --git a/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.types b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.types new file mode 100644 index 00000000000..2b6b63f0dcd --- /dev/null +++ b/tests/baselines/reference/shadowedReservedCompilerDeclarationsWithNoEmit.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts === +// Shadowed captured this and super +class Base { } +>Base : Base + +class C extends Base { +>C : C +>Base : Base + + constructor() { + super(); +>super() : void +>super : typeof Base + } + + foo() { +>foo : () => void + + let _this = this; +>_this : this +>this : this + + () => { +>() => { _this; } : () => void + + _this; +>_this : this + + }; + } + + bar() { +>bar : () => void + + let _super = this; +>_super : this +>this : this + } +} + + +/// shadowed arguments +function f1(arguments, ...a) { +>f1 : (arguments: any, ...a: any[]) => void +>arguments : any +>a : any[] +} + +class C2 extends Base { +>C2 : C2 +>Base : Base + + constructor() { + super(); +>super() : void +>super : typeof Base + + var _newTarget = ""; +>_newTarget : string +>"" : "" + + var t = new.target; +>t : typeof C2 +>new.target : typeof C2 +>target : any + + var y = _newTarget; +>y : string +>_newTarget : string + } +} + + +// Shadowed Promise +var Promise = null; +>Promise : any +>null : null + +async function f4() { +>f4 : () => Promise + + return 0; +>0 : 0 +} + + +// shadowed require +var require = 0; +>require : number +>0 : 0 + +// shadowed exports +var exports = 0; +>exports : number +>0 : 0 + + +export { }; diff --git a/tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts b/tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts new file mode 100644 index 00000000000..d12ebad67ca --- /dev/null +++ b/tests/cases/compiler/shadowedReservedCompilerDeclarationsWithNoEmit.ts @@ -0,0 +1,53 @@ +// @target: es5 +// @noemit: true + +// Shadowed captured this and super +class Base { } +class C extends Base { + constructor() { + super(); + } + + foo() { + let _this = this; + + () => { + _this; + }; + } + + bar() { + let _super = this; + } +} + + +/// shadowed arguments +function f1(arguments, ...a) { +} + +class C2 extends Base { + constructor() { + super(); + var _newTarget = ""; + var t = new.target; + var y = _newTarget; + } +} + + +// Shadowed Promise +var Promise = null; +async function f4() { + return 0; +} + + +// shadowed require +var require = 0; + +// shadowed exports +var exports = 0; + + +export { }; \ No newline at end of file From 2483719e6ebd5ce49e8cee759101d6ae4ea6fd19 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Mon, 26 Mar 2018 13:49:57 -0700 Subject: [PATCH 2/2] Fix lint issues --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c12ebdb4764..f41433b0d33 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21947,7 +21947,7 @@ namespace ts { } function checkCollisionWithCapturedNewTargetVariable(node: Node, name: Identifier): void { - if (languageVersion <= ScriptTarget.ES5 &&!compilerOptions.noEmit && needCollisionCheckForIdentifier(node, name, "_newTarget")) { + if (languageVersion <= ScriptTarget.ES5 && !compilerOptions.noEmit && needCollisionCheckForIdentifier(node, name, "_newTarget")) { potentialNewTargetCollisions.push(node); } } @@ -21984,7 +21984,7 @@ namespace ts { } function checkCollisionWithCapturedSuperVariable(node: Node, name: Identifier) { - if (languageVersion >= ScriptTarget.ES2015 || compilerOptions.noEmit) { + if (languageVersion >= ScriptTarget.ES2015 || compilerOptions.noEmit) { return; }