From fe94a2180c4836cfaab18e2fd97e9befee45cc09 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 30 Oct 2020 16:16:23 -0700 Subject: [PATCH] Use same metho as importHelpers to add synthetic import --- src/compiler/moduleNameResolver.ts | 7 +-- src/compiler/program.ts | 57 ++++++++++--------- ...ImportSource-option-changed-incremental.js | 28 ++++----- .../jsxImportSource-option-changed-watch.js | 28 ++++----- 4 files changed, 58 insertions(+), 62 deletions(-) diff --git a/src/compiler/moduleNameResolver.ts b/src/compiler/moduleNameResolver.ts index 5928fb56486..fbd4f57a4a0 100644 --- a/src/compiler/moduleNameResolver.ts +++ b/src/compiler/moduleNameResolver.ts @@ -402,10 +402,8 @@ namespace ts { */ export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] { // Use explicit type list from tsconfig.json - // jsxImportSource, if present and in use, creates implicit imports - const implicitImport = getJSXRuntimeImport(getJSXImplicitImportBase(options), options); if (options.types) { - return [...options.types, ...(implicitImport ? [implicitImport] : [])]; + return options.types; } // Walk the primary type lookup locations @@ -436,9 +434,6 @@ namespace ts { } } } - if (implicitImport) { - result.push(implicitImport); - } return result; } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index bc358a42532..c6efe7c6b76 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1494,7 +1494,7 @@ namespace ts { } // try to verify results of module resolution for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) { - const moduleNames = getModuleNames(newSourceFile, options); + const moduleNames = getModuleNames(newSourceFile); const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFile); // ensure that module resolution results are still correct const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo); @@ -2201,6 +2201,15 @@ namespace ts { : b.kind === SyntaxKind.StringLiteral && a.text === b.text; } + function createSyntheticImport(text: string, file: SourceFile) { + const externalHelpersModuleReference = factory.createStringLiteral(text); + const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); + addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); + setParent(externalHelpersModuleReference, importDecl); + setParent(importDecl, file); + return externalHelpersModuleReference; + } + function collectExternalModuleReferences(file: SourceFile): void { if (file.imports) { return; @@ -2216,16 +2225,18 @@ namespace ts { // If we are importing helpers, we need to add a synthetic reference to resolve the // helpers library. - if (options.importHelpers - && (options.isolatedModules || isExternalModuleFile) + if ((options.isolatedModules || isExternalModuleFile) && !file.isDeclarationFile) { - // synthesize 'import "tslib"' declaration - const externalHelpersModuleReference = factory.createStringLiteral(externalHelpersModuleNameText); - const importDecl = factory.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined, externalHelpersModuleReference); - addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper); - setParent(externalHelpersModuleReference, importDecl); - setParent(importDecl, file); - imports = [externalHelpersModuleReference]; + if (options.importHelpers) { + // synthesize 'import "tslib"' declaration + imports = [createSyntheticImport(externalHelpersModuleNameText, file)]; + } + const jsxImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); + if (jsxImport) { + // synthesize `import "base/jsx-runtime"` declaration + imports ||= []; + imports.push(createSyntheticImport(jsxImport, file)); + } } for (const node of file.statements) { @@ -2840,16 +2851,11 @@ namespace ts { if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--; } else { - // Don't issue an error when auto-inclusion lookup fails for the jsxImportSource (at this point) - // It may be provided by an ambient module in the compilation, instead. - // A usage of a JSX tag later should report that the module couldn't be resolved if it is not supplied. - if (refFile || typeReferenceDirective !== getJSXRuntimeImport(getJSXImplicitImportBase(options), options)) { - fileProcessingDiagnostics.add(createRefFileDiagnostic( - refFile, - Diagnostics.Cannot_find_type_definition_file_for_0, - typeReferenceDirective - )); - } + fileProcessingDiagnostics.add(createRefFileDiagnostic( + refFile, + Diagnostics.Cannot_find_type_definition_file_for_0, + typeReferenceDirective + )); } if (saveResolution) { @@ -2896,9 +2902,9 @@ namespace ts { function processImportedModules(file: SourceFile) { collectExternalModuleReferences(file); - if (file.imports.length || file.moduleAugmentations.length || getJSXImplicitImportBase(options, file)) { + if (file.imports.length || file.moduleAugmentations.length) { // Because global augmentation doesn't have string literal name, we can check for global augmentation as such. - const moduleNames = getModuleNames(file, options); + const moduleNames = getModuleNames(file); const resolutions = resolveModuleNamesReusingOldState(moduleNames, file); Debug.assert(resolutions.length === moduleNames.length); for (let i = 0; i < moduleNames.length; i++) { @@ -3887,8 +3893,7 @@ namespace ts { } } - function getModuleNames(file: SourceFile, options: CompilerOptions): string[] { - const { imports, moduleAugmentations } = file; + function getModuleNames({ imports, moduleAugmentations }: SourceFile): string[] { const res = imports.map(i => i.text); for (const aug of moduleAugmentations) { if (aug.kind === SyntaxKind.StringLiteral) { @@ -3896,10 +3901,6 @@ namespace ts { } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. } - const jsxRuntimeImport = getJSXRuntimeImport(getJSXImplicitImportBase(options, file), options); - if (jsxRuntimeImport) { - res.push(jsxRuntimeImport); - } return res; } } diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js index e75b1813ec9..c4b9e292b48 100644 --- a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-incremental.js @@ -64,13 +64,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: @@ -98,15 +98,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/react/jsx-runtime/index.d.ts": { "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { @@ -156,13 +156,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preac Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: @@ -190,15 +190,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/preact/jsx-runtime/index.d.ts": { "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { diff --git a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js index 49bd165b3b1..9a2d68b431e 100644 --- a/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js +++ b/tests/baselines/reference/tscWatch/incremental/jsxImportSource-option-changed-watch.js @@ -69,13 +69,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"react Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/react/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: /users/username/projects/project/tsconfig.json: @@ -117,15 +117,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/react/jsx-runtime/index.d.ts": { "version": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-35656056833-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propA?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": { @@ -178,13 +178,13 @@ Program options: {"module":1,"jsx":4,"incremental":true,"jsxImportSource":"preac Program structureReused: Not Program files:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx Semantic diagnostics in builder refreshed for:: /a/lib/lib.d.ts -/users/username/projects/project/index.tsx /users/username/projects/project/node_modules/preact/jsx-runtime/index.d.ts +/users/username/projects/project/index.tsx WatchedFiles:: /users/username/projects/project/tsconfig.json: @@ -226,15 +226,15 @@ exports.App = App; "signature": "3858781397-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };", "affectsGlobalScope": true }, - "./index.tsx": { - "version": "-14760199789-export const App = () =>
;", - "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", - "affectsGlobalScope": false - }, "./node_modules/preact/jsx-runtime/index.d.ts": { "version": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "signature": "-17896129664-export namespace JSX {\n interface Element {}\n interface IntrinsicElements {\n div: {\n propB?: boolean;\n };\n }\n}\nexport function jsx(...args: any[]): void;\nexport function jsxs(...args: any[]): void;\nexport const Fragment: unique symbol;\n", "affectsGlobalScope": false + }, + "./index.tsx": { + "version": "-14760199789-export const App = () =>
;", + "signature": "-17269688391-export declare const App: () => import(\"react/jsx-runtime\").JSX.Element;\n", + "affectsGlobalScope": false } }, "options": {