From c885ffbd2f80d601f33e00e109880fa7010b76a3 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 24 Jan 2018 20:29:54 -0800 Subject: [PATCH] Emit unqiue symbols with typeof if possible before issuing an error --- src/compiler/checker.ts | 3 +++ src/harness/typeWriter.ts | 2 +- .../indirectUniqueSymbolDeclarationEmit.js | 23 ++++++++++++++++++ ...ndirectUniqueSymbolDeclarationEmit.symbols | 20 ++++++++++++++++ .../indirectUniqueSymbolDeclarationEmit.types | 24 +++++++++++++++++++ .../indirectUniqueSymbolDeclarationEmit.ts | 8 +++++++ 6 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.js create mode 100644 tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.symbols create mode 100644 tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.types create mode 100644 tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f3658c645dbdc..a6005513009f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2858,6 +2858,9 @@ namespace ts { } if (type.flags & TypeFlags.UniqueESSymbol) { if (!(context.flags & NodeBuilderFlags.AllowUniqueESSymbolType)) { + if (isValueSymbolAccessible(type.symbol, context.enclosingDeclaration)) { + return createTypeQueryNode(symbolToName(type.symbol, context, SymbolFlags.Value, /*expectsIdentifier*/ false)); + } if (context.tracker.reportInaccessibleUniqueSymbolError) { context.tracker.reportInaccessibleUniqueSymbolError(); } diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index 17eda776bdaac..fc323babcd273 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -79,7 +79,7 @@ class TypeWriterWalker { // Workaround to ensure we output 'C' instead of 'typeof C' for base class expressions // let type = this.checker.getTypeAtLocation(node); const type = node.parent && ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent) && this.checker.getTypeAtLocation(node.parent) || this.checker.getTypeAtLocation(node); - const typeString = type ? this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation) : "No type information available!"; + const typeString = type ? this.checker.typeToString(type, node.parent, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.AllowUniqueESSymbolType) : "No type information available!"; return { line: lineAndCharacter.line, syntaxKind: node.kind, diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.js b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.js new file mode 100644 index 0000000000000..d3f312ae82ece --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.js @@ -0,0 +1,23 @@ +//// [indirectUniqueSymbolDeclarationEmit.ts] +export const x = Symbol(); +export const y = Symbol(); +declare function rand(): boolean; +export function f() { + return rand() ? x : y; +} + +//// [indirectUniqueSymbolDeclarationEmit.js] +"use strict"; +exports.__esModule = true; +exports.x = Symbol(); +exports.y = Symbol(); +function f() { + return rand() ? exports.x : exports.y; +} +exports.f = f; + + +//// [indirectUniqueSymbolDeclarationEmit.d.ts] +export declare const x: unique symbol; +export declare const y: unique symbol; +export declare function f(): typeof x | typeof y; diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.symbols b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.symbols new file mode 100644 index 0000000000000..9f205084ecb52 --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.symbols @@ -0,0 +1,20 @@ +=== tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts === +export const x = Symbol(); +>x : Symbol(x, Decl(indirectUniqueSymbolDeclarationEmit.ts, 0, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +export const y = Symbol(); +>y : Symbol(y, Decl(indirectUniqueSymbolDeclarationEmit.ts, 1, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --)) + +declare function rand(): boolean; +>rand : Symbol(rand, Decl(indirectUniqueSymbolDeclarationEmit.ts, 1, 26)) + +export function f() { +>f : Symbol(f, Decl(indirectUniqueSymbolDeclarationEmit.ts, 2, 33)) + + return rand() ? x : y; +>rand : Symbol(rand, Decl(indirectUniqueSymbolDeclarationEmit.ts, 1, 26)) +>x : Symbol(x, Decl(indirectUniqueSymbolDeclarationEmit.ts, 0, 12)) +>y : Symbol(y, Decl(indirectUniqueSymbolDeclarationEmit.ts, 1, 12)) +} diff --git a/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.types b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.types new file mode 100644 index 0000000000000..f50010d8f53a4 --- /dev/null +++ b/tests/baselines/reference/indirectUniqueSymbolDeclarationEmit.types @@ -0,0 +1,24 @@ +=== tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts === +export const x = Symbol(); +>x : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +export const y = Symbol(); +>y : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +declare function rand(): boolean; +>rand : () => boolean + +export function f() { +>f : () => unique symbol | unique symbol + + return rand() ? x : y; +>rand() ? x : y : unique symbol | unique symbol +>rand() : boolean +>rand : () => boolean +>x : unique symbol +>y : unique symbol +} diff --git a/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts b/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts new file mode 100644 index 0000000000000..5554c5d05c371 --- /dev/null +++ b/tests/cases/compiler/indirectUniqueSymbolDeclarationEmit.ts @@ -0,0 +1,8 @@ +// @lib: es6 +// @declaration: true +export const x = Symbol(); +export const y = Symbol(); +declare function rand(): boolean; +export function f() { + return rand() ? x : y; +} \ No newline at end of file