Merge pull request #26564 from Microsoft/fix26497
Emit lib reference directives in declaration output
This commit is contained in:
commit
42c9208fd1
|
@ -140,7 +140,7 @@ function diagnosticFromJson(json, host) {
|
|||
category: json.category,
|
||||
code: json.code,
|
||||
source: json.source,
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(diagnosticRelatedInformationFromJson, host)
|
||||
relatedInformation: json.relatedInformation && json.relatedInformation.map(json => diagnosticRelatedInformationFromJson(json, host))
|
||||
});
|
||||
}
|
||||
exports.diagnosticFromJson = diagnosticFromJson;
|
||||
|
@ -169,7 +169,9 @@ function diagnosticRelatedInformationFromJson(json, host) {
|
|||
file: json.file && sourceFileFromJson(json.file, host),
|
||||
start: json.start,
|
||||
length: json.length,
|
||||
messageText: json.messageText
|
||||
messageText: json.messageText,
|
||||
category: json.category,
|
||||
code: json.code
|
||||
};
|
||||
}
|
||||
exports.diagnosticRelatedInformationFromJson = diagnosticRelatedInformationFromJson;
|
||||
|
|
|
@ -2593,14 +2593,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) {
|
||||
emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
|
||||
emitTripleSlashDirectives(!!node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || [], node.syntheticLibReferences || []);
|
||||
}
|
||||
|
||||
function emitTripleSlashDirectivesIfNeeded(node: SourceFile) {
|
||||
if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives);
|
||||
if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives, node.libReferenceDirectives);
|
||||
}
|
||||
|
||||
function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>) {
|
||||
function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>, libs: ReadonlyArray<FileReference>) {
|
||||
if (hasNoDefaultLib) {
|
||||
write(`/// <reference no-default-lib="true"/>`);
|
||||
writeLine();
|
||||
|
@ -2628,6 +2628,10 @@ namespace ts {
|
|||
write(`/// <reference types="${directive.fileName}" />`);
|
||||
writeLine();
|
||||
}
|
||||
for (const directive of libs) {
|
||||
write(`/// <reference lib="${directive.fileName}" />`);
|
||||
writeLine();
|
||||
}
|
||||
}
|
||||
|
||||
function emitSourceFileWorker(node: SourceFile) {
|
||||
|
|
|
@ -1237,6 +1237,7 @@ namespace ts {
|
|||
getSourceFile: program.getSourceFile,
|
||||
getSourceFileByPath: program.getSourceFileByPath,
|
||||
getSourceFiles: program.getSourceFiles,
|
||||
getLibFileFromReference: program.getLibFileFromReference,
|
||||
isSourceFileFromExternalLibrary,
|
||||
writeFile: writeFileCallback || (
|
||||
(fileName, data, writeByteOrderMark, onError, sourceFiles) => host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles)),
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ts {
|
|||
let needsScopeFixMarker = false;
|
||||
let resultHasScopeMarker = false;
|
||||
let enclosingDeclaration: Node;
|
||||
let necessaryTypeRefernces: Map<true> | undefined;
|
||||
let necessaryTypeReferences: Map<true> | undefined;
|
||||
let lateMarkedStatements: LateVisibilityPaintedStatement[] | undefined;
|
||||
let lateStatementReplacementMap: Map<VisitResult<LateVisibilityPaintedStatement>>;
|
||||
let suppressNewDiagnosticContexts: boolean;
|
||||
|
@ -53,6 +53,7 @@ namespace ts {
|
|||
|
||||
let currentSourceFile: SourceFile;
|
||||
let refs: Map<SourceFile>;
|
||||
let libs: Map<boolean>;
|
||||
const resolver = context.getEmitResolver();
|
||||
const options = context.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(options);
|
||||
|
@ -63,9 +64,9 @@ namespace ts {
|
|||
if (!typeReferenceDirectives) {
|
||||
return;
|
||||
}
|
||||
necessaryTypeRefernces = necessaryTypeRefernces || createMap<true>();
|
||||
necessaryTypeReferences = necessaryTypeReferences || createMap<true>();
|
||||
for (const ref of typeReferenceDirectives) {
|
||||
necessaryTypeRefernces.set(ref, true);
|
||||
necessaryTypeReferences.set(ref, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,6 +164,7 @@ namespace ts {
|
|||
if (node.kind === SyntaxKind.Bundle) {
|
||||
isBundledEmit = true;
|
||||
refs = createMap<SourceFile>();
|
||||
libs = createMap<boolean>();
|
||||
let hasNoDefaultLib = false;
|
||||
const bundle = createBundle(map(node.sourceFiles,
|
||||
sourceFile => {
|
||||
|
@ -177,6 +179,7 @@ namespace ts {
|
|||
needsScopeFixMarker = false;
|
||||
resultHasScopeMarker = false;
|
||||
collectReferences(sourceFile, refs);
|
||||
collectLibs(sourceFile, libs);
|
||||
if (isExternalModule(sourceFile)) {
|
||||
resultHasExternalModuleIndicator = false; // unused in external module bundle emit (all external modules are within module blocks, therefore are known to be modules)
|
||||
needsDeclare = false;
|
||||
|
@ -200,6 +203,7 @@ namespace ts {
|
|||
}));
|
||||
bundle.syntheticFileReferences = [];
|
||||
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
|
||||
bundle.syntheticLibReferences = getLibReferences();
|
||||
bundle.hasNoDefaultLib = hasNoDefaultLib;
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
|
||||
|
@ -219,8 +223,9 @@ namespace ts {
|
|||
suppressNewDiagnosticContexts = false;
|
||||
lateMarkedStatements = undefined;
|
||||
lateStatementReplacementMap = createMap();
|
||||
necessaryTypeRefernces = undefined;
|
||||
necessaryTypeReferences = undefined;
|
||||
refs = collectReferences(currentSourceFile, createMap());
|
||||
libs = collectLibs(currentSourceFile, createMap());
|
||||
const references: FileReference[] = [];
|
||||
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath!));
|
||||
const referenceVisitor = mapReferencesIntoArray(references, outputFilePath);
|
||||
|
@ -231,12 +236,16 @@ namespace ts {
|
|||
if (isExternalModule(node) && (!resultHasExternalModuleIndicator || (needsScopeFixMarker && !resultHasScopeMarker))) {
|
||||
combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements);
|
||||
}
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib);
|
||||
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
|
||||
updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
|
||||
return updated;
|
||||
|
||||
function getLibReferences() {
|
||||
return map(arrayFrom(libs.keys()), lib => ({ fileName: lib, pos: -1, end: -1 }));
|
||||
}
|
||||
|
||||
function getFileReferencesForUsedTypeReferences() {
|
||||
return necessaryTypeRefernces ? mapDefined(arrayFrom(necessaryTypeRefernces.keys()), getFileReferenceForTypeName) : [];
|
||||
return necessaryTypeReferences ? mapDefined(arrayFrom(necessaryTypeReferences.keys()), getFileReferenceForTypeName) : [];
|
||||
}
|
||||
|
||||
function getFileReferenceForTypeName(typeName: string): FileReference | undefined {
|
||||
|
@ -297,6 +306,16 @@ namespace ts {
|
|||
return ret;
|
||||
}
|
||||
|
||||
function collectLibs(sourceFile: SourceFile, ret: Map<boolean>) {
|
||||
forEach(sourceFile.libReferenceDirectives, ref => {
|
||||
const lib = host.getLibFileFromReference(ref);
|
||||
if (lib) {
|
||||
ret.set(ref.fileName.toLocaleLowerCase(), true);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function filterBindingPatternInitializers(name: BindingName) {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
return name;
|
||||
|
|
|
@ -2648,6 +2648,7 @@ namespace ts {
|
|||
sourceFiles: ReadonlyArray<SourceFile>;
|
||||
/* @internal */ syntheticFileReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ syntheticTypeReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ syntheticLibReferences?: ReadonlyArray<FileReference>;
|
||||
/* @internal */ hasNoDefaultLib?: boolean;
|
||||
}
|
||||
|
||||
|
@ -5074,6 +5075,7 @@ namespace ts {
|
|||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
getLibFileFromReference(ref: FileReference): SourceFile | undefined;
|
||||
|
||||
getCommonSourceDirectory(): string;
|
||||
getCanonicalFileName(fileName: string): string;
|
||||
|
|
25
tests/baselines/reference/libReferenceDeclarationEmit.js
Normal file
25
tests/baselines/reference/libReferenceDeclarationEmit.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
//// [tests/cases/conformance/declarationEmit/libReferenceDeclarationEmit.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
|
||||
//// [file2.ts]
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
|
||||
//// [file1.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//// [file2.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
|
||||
|
||||
//// [file1.d.ts]
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
//// [file2.d.ts]
|
||||
/// <reference lib="dom" />
|
||||
export {};
|
|
@ -0,0 +1,13 @@
|
|||
=== tests/cases/conformance/declarationEmit/file1.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
>elem : Symbol(elem, Decl(file1.ts, 1, 20))
|
||||
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
=== tests/cases/conformance/declarationEmit/file2.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
>elem : Symbol(elem, Decl(file2.ts, 2, 13))
|
||||
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
11
tests/baselines/reference/libReferenceDeclarationEmit.types
Normal file
11
tests/baselines/reference/libReferenceDeclarationEmit.types
Normal file
|
@ -0,0 +1,11 @@
|
|||
=== tests/cases/conformance/declarationEmit/file1.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
>elem : HTMLElement
|
||||
|
||||
=== tests/cases/conformance/declarationEmit/file2.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
>elem : HTMLElement
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
//// [tests/cases/conformance/declarationEmit/libReferenceDeclarationEmitBundle.ts] ////
|
||||
|
||||
//// [file1.ts]
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
|
||||
//// [file2.ts]
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
|
||||
//// [bundle.js]
|
||||
define("file1", ["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
});
|
||||
define("file2", ["require", "exports"], function (require, exports) {
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
});
|
||||
|
||||
|
||||
//// [bundle.d.ts]
|
||||
/// <reference lib="dom" />
|
||||
declare module "file1" {
|
||||
export const elem: HTMLElement;
|
||||
}
|
||||
declare module "file2" {
|
||||
export {};
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
=== tests/cases/conformance/declarationEmit/file1.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
>elem : Symbol(elem, Decl(file1.ts, 1, 20))
|
||||
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
=== tests/cases/conformance/declarationEmit/file2.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
>elem : Symbol(elem, Decl(file2.ts, 2, 13))
|
||||
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
=== tests/cases/conformance/declarationEmit/file1.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
>elem : HTMLElement
|
||||
|
||||
=== tests/cases/conformance/declarationEmit/file2.ts ===
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
||||
>elem : HTMLElement
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// @target: esnext
|
||||
// @module: commonjs
|
||||
// @lib: esnext
|
||||
// @declaration: true
|
||||
// @filename: file1.ts
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
|
||||
// @filename: file2.ts
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
|
@ -0,0 +1,13 @@
|
|||
// @target: esnext
|
||||
// @module: amd
|
||||
// @lib: esnext
|
||||
// @declaration: true
|
||||
// @outFile: bundle.js
|
||||
// @filename: file1.ts
|
||||
/// <reference lib="dom" />
|
||||
export declare const elem: HTMLElement;
|
||||
|
||||
// @filename: file2.ts
|
||||
/// <reference lib="dom" />
|
||||
export {}
|
||||
declare const elem: HTMLElement;
|
Loading…
Reference in a new issue