From 336df751eab01595e451b0de6e5c9ecf551083b0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 24 Aug 2017 15:53:09 -0700 Subject: [PATCH] Fix issue #16803 do not error on getters/setters (#18031) --- src/compiler/checker.ts | 17 ++++++++++----- src/compiler/core.ts | 4 ++++ .../exportEqualsClassNoRedeclarationError.js | 19 +++++++++++++++++ ...ortEqualsClassNoRedeclarationError.symbols | 17 +++++++++++++++ ...xportEqualsClassNoRedeclarationError.types | 18 ++++++++++++++++ ...rtEqualsClassRedeclarationError.errors.txt | 21 +++++++++++++++++++ .../exportEqualsClassRedeclarationError.js | 21 +++++++++++++++++++ .../exportEqualsClassNoRedeclarationError.ts | 10 +++++++++ .../exportEqualsClassRedeclarationError.ts | 11 ++++++++++ 9 files changed, 133 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/exportEqualsClassNoRedeclarationError.js create mode 100644 tests/baselines/reference/exportEqualsClassNoRedeclarationError.symbols create mode 100644 tests/baselines/reference/exportEqualsClassNoRedeclarationError.types create mode 100644 tests/baselines/reference/exportEqualsClassRedeclarationError.errors.txt create mode 100644 tests/baselines/reference/exportEqualsClassRedeclarationError.js create mode 100644 tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts create mode 100644 tests/cases/compiler/exportEqualsClassRedeclarationError.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 24a9a868c4..21db77b5e3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -497,6 +497,8 @@ namespace ts { const builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); + const isNotOverloadAndNotAccessor = and(isNotOverload, isNotAccessor); + initializeTypeChecker(); return checker; @@ -22257,7 +22259,7 @@ namespace ts { if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) { return; } - const exportedDeclarationsCount = countWhere(declarations, isNotOverload); + const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor); if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) { // it is legal to merge type alias with other values // so count should be either 1 (just type alias) or 2 (type alias + merged value) @@ -22273,11 +22275,16 @@ namespace ts { }); links.exportsChecked = true; } + } - function isNotOverload(declaration: Declaration): boolean { - return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) || - !!(declaration as FunctionDeclaration).body; - } + function isNotAccessor(declaration: Declaration): boolean { + // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks + return !isAccessor(declaration); + } + + function isNotOverload(declaration: Declaration): boolean { + return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) || + !!(declaration as FunctionDeclaration).body; } function checkSourceElement(node: Node): void { diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6eb17f1fb7..f94ac9a75c 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -2626,4 +2626,8 @@ namespace ts { export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } + + export function and(f: (arg: T) => boolean, g: (arg: T) => boolean) { + return (arg: T) => f(arg) && g(arg); + } } diff --git a/tests/baselines/reference/exportEqualsClassNoRedeclarationError.js b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.js new file mode 100644 index 0000000000..834d10a48d --- /dev/null +++ b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.js @@ -0,0 +1,19 @@ +//// [exportEqualsClassNoRedeclarationError.ts] +class SomeClass { + static get someProp(): number { + return 0; + } + + static set someProp(value: number) {} +} +export = SomeClass; + +//// [exportEqualsClassNoRedeclarationError.js] +"use strict"; +class SomeClass { + static get someProp() { + return 0; + } + static set someProp(value) { } +} +module.exports = SomeClass; diff --git a/tests/baselines/reference/exportEqualsClassNoRedeclarationError.symbols b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.symbols new file mode 100644 index 0000000000..386efa1bda --- /dev/null +++ b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts === +class SomeClass { +>SomeClass : Symbol(SomeClass, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 0)) + + static get someProp(): number { +>someProp : Symbol(SomeClass.someProp, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 17), Decl(exportEqualsClassNoRedeclarationError.ts, 3, 5)) + + return 0; + } + + static set someProp(value: number) {} +>someProp : Symbol(SomeClass.someProp, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 17), Decl(exportEqualsClassNoRedeclarationError.ts, 3, 5)) +>value : Symbol(value, Decl(exportEqualsClassNoRedeclarationError.ts, 5, 24)) +} +export = SomeClass; +>SomeClass : Symbol(SomeClass, Decl(exportEqualsClassNoRedeclarationError.ts, 0, 0)) + diff --git a/tests/baselines/reference/exportEqualsClassNoRedeclarationError.types b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.types new file mode 100644 index 0000000000..cba7b57a4e --- /dev/null +++ b/tests/baselines/reference/exportEqualsClassNoRedeclarationError.types @@ -0,0 +1,18 @@ +=== tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts === +class SomeClass { +>SomeClass : SomeClass + + static get someProp(): number { +>someProp : number + + return 0; +>0 : 0 + } + + static set someProp(value: number) {} +>someProp : number +>value : number +} +export = SomeClass; +>SomeClass : SomeClass + diff --git a/tests/baselines/reference/exportEqualsClassRedeclarationError.errors.txt b/tests/baselines/reference/exportEqualsClassRedeclarationError.errors.txt new file mode 100644 index 0000000000..4eccf0cc1c --- /dev/null +++ b/tests/baselines/reference/exportEqualsClassRedeclarationError.errors.txt @@ -0,0 +1,21 @@ +tests/cases/compiler/exportEqualsClassRedeclarationError.ts(2,16): error TS2300: Duplicate identifier 'someProp'. +tests/cases/compiler/exportEqualsClassRedeclarationError.ts(6,16): error TS2300: Duplicate identifier 'someProp'. +tests/cases/compiler/exportEqualsClassRedeclarationError.ts(7,16): error TS2300: Duplicate identifier 'someProp'. + + +==== tests/cases/compiler/exportEqualsClassRedeclarationError.ts (3 errors) ==== + class SomeClass { + static get someProp(): number { + ~~~~~~~~ +!!! error TS2300: Duplicate identifier 'someProp'. + return 0; + } + + static set someProp(value: number) {} + ~~~~~~~~ +!!! error TS2300: Duplicate identifier 'someProp'. + static set someProp(value: number) {} + ~~~~~~~~ +!!! error TS2300: Duplicate identifier 'someProp'. + } + export = SomeClass; \ No newline at end of file diff --git a/tests/baselines/reference/exportEqualsClassRedeclarationError.js b/tests/baselines/reference/exportEqualsClassRedeclarationError.js new file mode 100644 index 0000000000..f0134c4662 --- /dev/null +++ b/tests/baselines/reference/exportEqualsClassRedeclarationError.js @@ -0,0 +1,21 @@ +//// [exportEqualsClassRedeclarationError.ts] +class SomeClass { + static get someProp(): number { + return 0; + } + + static set someProp(value: number) {} + static set someProp(value: number) {} +} +export = SomeClass; + +//// [exportEqualsClassRedeclarationError.js] +"use strict"; +class SomeClass { + static get someProp() { + return 0; + } + static set someProp(value) { } + static set someProp(value) { } +} +module.exports = SomeClass; diff --git a/tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts b/tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts new file mode 100644 index 0000000000..0e5c582411 --- /dev/null +++ b/tests/cases/compiler/exportEqualsClassNoRedeclarationError.ts @@ -0,0 +1,10 @@ +// @target: es6 +// @module: commonjs +class SomeClass { + static get someProp(): number { + return 0; + } + + static set someProp(value: number) {} +} +export = SomeClass; \ No newline at end of file diff --git a/tests/cases/compiler/exportEqualsClassRedeclarationError.ts b/tests/cases/compiler/exportEqualsClassRedeclarationError.ts new file mode 100644 index 0000000000..237aca399f --- /dev/null +++ b/tests/cases/compiler/exportEqualsClassRedeclarationError.ts @@ -0,0 +1,11 @@ +// @target: es6 +// @module: commonjs +class SomeClass { + static get someProp(): number { + return 0; + } + + static set someProp(value: number) {} + static set someProp(value: number) {} +} +export = SomeClass; \ No newline at end of file