From 086e2c75df76ce92920060f15b0f64e030ad6229 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 2 Jul 2019 13:57:29 -0700 Subject: [PATCH 1/3] Retarget to es6 and fix the resulting bugs --- src/compiler/core.ts | 11 +++++++++++ src/compiler/program.ts | 5 ++++- src/compiler/transformers/declarations.ts | 12 ++++++++---- src/harness/fourslash.ts | 3 ++- src/tsconfig-base.json | 3 ++- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index f1511b79c126b..b111483112fb7 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -1386,6 +1386,17 @@ namespace ts { return keys; } + export function getAllKeys(obj: object): string[] { + const result: string[] = []; + do { + const names = Object.getOwnPropertyNames(obj); + for (const name of names) { + pushIfUnique(result, name); + } + } while (obj = Object.getPrototypeOf(obj)); + return result; + } + export function getOwnValues(sparseArray: T[]): T[] { const values: T[] = []; for (const key in sparseArray) { diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 889d24549e55c..f22a750def710 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -815,7 +815,10 @@ namespace ts { let mapFromFileToProjectReferenceRedirects: Map | undefined; const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); - const structuralIsReused = tryReuseStructureFromOldProgram(); + // We set `structuralIsReused` to `undefined` because `tryReuseStructureFromOldProgram` calls `tryReuseStructureFromOldProgram` which checks + // `structuralIsReused`, which would be a TDZ violation if it was not set in advance to `undefined`. + let structuralIsReused: StructureIsReused | undefined; + structuralIsReused = tryReuseStructureFromOldProgram(); if (structuralIsReused !== StructureIsReused.Completely) { processingDefaultLibFiles = []; processingOtherFiles = []; diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index bb939f7d4f1f1..8fd294ef02452 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -83,6 +83,7 @@ namespace ts { let currentSourceFile: SourceFile; let refs: Map; let libs: Map; + let emittedImports: readonly AnyImportSyntax[] | undefined; // must be declared in container so it can be `undefined` while transformer's first pass const resolver = context.getEmitResolver(); const options = context.getCompilerOptions(); const newLine = getNewLineCharacter(options); @@ -279,7 +280,7 @@ namespace ts { const statements = visitNodes(node.statements, visitDeclarationStatements); let combinedStatements = setTextRange(createNodeArray(transformAndReplaceLatePaintedStatements(statements)), node.statements); refs.forEach(referenceVisitor); - const emittedImports = filter(combinedStatements, isAnyImportSyntax); + emittedImports = filter(combinedStatements, isAnyImportSyntax); if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) { combinedStatements = setTextRange(createNodeArray([...combinedStatements, createEmptyExports()]), combinedStatements); } @@ -736,6 +737,12 @@ namespace ts { } const oldDiag = getSymbolAccessibilityDiagnostic; + // Setup diagnostic-related flags before first potential `cleanup` call, otherwise + // We'd see a TDZ violation ar runtime + const canProdiceDiagnostic = canProduceDiagnostics(input); + const oldWithinObjectLiteralType = suppressNewDiagnosticContexts; + let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === SyntaxKind.TypeLiteral || input.kind === SyntaxKind.MappedType) && input.parent.kind !== SyntaxKind.TypeAliasDeclaration); + // Emit methods which are private as properties with no type information if (isMethodDeclaration(input) || isMethodSignature(input)) { if (hasModifier(input, ModifierFlags.Private)) { @@ -744,7 +751,6 @@ namespace ts { } } - const canProdiceDiagnostic = canProduceDiagnostics(input); if (canProdiceDiagnostic && !suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input as DeclarationDiagnosticProducing); } @@ -753,8 +759,6 @@ namespace ts { checkEntityNameVisibility(input.exprName, enclosingDeclaration); } - const oldWithinObjectLiteralType = suppressNewDiagnosticContexts; - let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === SyntaxKind.TypeLiteral || input.kind === SyntaxKind.MappedType) && input.parent.kind !== SyntaxKind.TypeAliasDeclaration); if (shouldEnterSuppressNewDiagnosticsContextContext) { // We stop making new diagnostic contexts within object literal types. Unless it's an object type on the RHS of a type alias declaration. Then we do. suppressNewDiagnosticContexts = true; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c26b059ced8e5..4a006f5b915b4 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -344,7 +344,8 @@ namespace FourSlash { "getDocumentHighlights", ]; const proxy = {} as ts.LanguageService; - for (const k in ls) { + const keys = ts.getAllKeys(ls); + for (const k of keys) { const key = k as keyof typeof ls; if (cacheableMembers.indexOf(key) === -1) { proxy[key] = (...args: any[]) => (ls[key] as Function)(...args); diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 4d83436a5385a..9886993ac7a82 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -2,7 +2,8 @@ "compilerOptions": { "pretty": true, "lib": ["es2015.iterable", "es5"], - "target": "es5", + "moduleResolution": "node", + "target": "es6", "rootDir": ".", "declaration": true, From b9827470c101e1cb2fa84cbfd7848a8854211343 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Tue, 2 Jul 2019 14:52:50 -0700 Subject: [PATCH 2/3] Set target back to es5 --- src/tsconfig-base.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 9886993ac7a82..4d83436a5385a 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -2,8 +2,7 @@ "compilerOptions": { "pretty": true, "lib": ["es2015.iterable", "es5"], - "moduleResolution": "node", - "target": "es6", + "target": "es5", "rootDir": ".", "declaration": true, From 170aa05cb5bed6eaee48dad17a5690c23c13cf2a Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 1 Aug 2019 13:52:33 -0700 Subject: [PATCH 3/3] Fix typos in declaration emitter --- src/compiler/transformers/declarations.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 8fd294ef02452..6dfc909b93abd 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -738,8 +738,8 @@ namespace ts { const oldDiag = getSymbolAccessibilityDiagnostic; // Setup diagnostic-related flags before first potential `cleanup` call, otherwise - // We'd see a TDZ violation ar runtime - const canProdiceDiagnostic = canProduceDiagnostics(input); + // We'd see a TDZ violation at runtime + const canProduceDiagnostic = canProduceDiagnostics(input); const oldWithinObjectLiteralType = suppressNewDiagnosticContexts; let shouldEnterSuppressNewDiagnosticsContextContext = ((input.kind === SyntaxKind.TypeLiteral || input.kind === SyntaxKind.MappedType) && input.parent.kind !== SyntaxKind.TypeAliasDeclaration); @@ -751,7 +751,7 @@ namespace ts { } } - if (canProdiceDiagnostic && !suppressNewDiagnosticContexts) { + if (canProduceDiagnostic && !suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(input as DeclarationDiagnosticProducing); } @@ -913,13 +913,13 @@ namespace ts { return cleanup(visitEachChild(input, visitDeclarationSubtree, context)); function cleanup(returnValue: T | undefined): T | undefined { - if (returnValue && canProdiceDiagnostic && hasDynamicName(input as Declaration)) { + if (returnValue && canProduceDiagnostic && hasDynamicName(input as Declaration)) { checkName(input as DeclarationDiagnosticProducing); } if (isEnclosingDeclaration(input)) { enclosingDeclaration = previousEnclosingDeclaration; } - if (canProdiceDiagnostic && !suppressNewDiagnosticContexts) { + if (canProduceDiagnostic && !suppressNewDiagnosticContexts) { getSymbolAccessibilityDiagnostic = oldDiag; } if (shouldEnterSuppressNewDiagnosticsContextContext) {