Skip to content

Commit ea8904e

Browse files
authored
Propagate noDefaultLib comment into emitted declaration files (#23003)
1 parent d2d0f86 commit ea8904e

14 files changed

+276
-11
lines changed

src/compiler/emitter.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2473,14 +2473,18 @@ namespace ts {
24732473
}
24742474

24752475
function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) {
2476-
emitTripleSlashDirectives(node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
2476+
emitTripleSlashDirectives(node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []);
24772477
}
24782478

24792479
function emitTripleSlashDirectivesIfNeeded(node: SourceFile) {
2480-
if (node.isDeclarationFile) emitTripleSlashDirectives(node.referencedFiles, node.typeReferenceDirectives);
2480+
if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives);
24812481
}
24822482

2483-
function emitTripleSlashDirectives(files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>) {
2483+
function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray<FileReference>, types: ReadonlyArray<FileReference>) {
2484+
if (hasNoDefaultLib) {
2485+
write(`/// <reference no-default-lib="true"/>`);
2486+
writeLine();
2487+
}
24842488
if (currentSourceFile && currentSourceFile.moduleName) {
24852489
write(`/// <amd-module name="${currentSourceFile.moduleName}" />`);
24862490
writeLine();

src/compiler/factory.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2387,12 +2387,13 @@ namespace ts {
23872387

23882388
// Top-level nodes
23892389

2390-
export function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]) {
2390+
export function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean) {
23912391
if (
23922392
node.statements !== statements ||
23932393
(isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) ||
23942394
(referencedFiles !== undefined && node.referencedFiles !== referencedFiles) ||
2395-
(typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences)
2395+
(typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) ||
2396+
(hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib)
23962397
) {
23972398
const updated = <SourceFile>createSynthesizedNode(SyntaxKind.SourceFile);
23982399
updated.flags |= node.flags;
@@ -2404,11 +2405,11 @@ namespace ts {
24042405
updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile;
24052406
updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles;
24062407
updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences;
2408+
updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib;
24072409
if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies;
24082410
if (node.moduleName !== undefined) updated.moduleName = node.moduleName;
24092411
if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant;
24102412
if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies;
2411-
if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib;
24122413
if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion;
24132414
if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind;
24142415
if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator;

src/compiler/transformers/declarations.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,11 @@ namespace ts {
135135
if (node.kind === SyntaxKind.Bundle) {
136136
isBundledEmit = true;
137137
const refs = createMap<SourceFile>();
138+
let hasNoDefaultLib = false;
138139
const bundle = createBundle(map(node.sourceFiles,
139140
sourceFile => {
140141
if (sourceFile.isDeclarationFile || isSourceFileJavaScript(sourceFile)) return; // Omit declaration files from bundle results, too
142+
hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib;
141143
currentSourceFile = sourceFile;
142144
enclosingDeclaration = sourceFile;
143145
possibleImports = undefined;
@@ -154,16 +156,17 @@ namespace ts {
154156
[createModifier(SyntaxKind.DeclareKeyword)],
155157
createLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)),
156158
createModuleBlock(setTextRange(createNodeArray(filterCandidateImports(statements)), sourceFile.statements))
157-
)], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ []);
159+
)], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false);
158160
return newFile;
159161
}
160162
needsDeclare = true;
161163
const updated = visitNodes(sourceFile.statements, visitDeclarationStatements);
162-
return updateSourceFileNode(sourceFile, updated, /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ []);
164+
return updateSourceFileNode(sourceFile, updated, /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false);
163165
}
164166
));
165167
bundle.syntheticFileReferences = [];
166168
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
169+
bundle.hasNoDefaultLib = hasNoDefaultLib;
167170
const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath));
168171
const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath);
169172
refs.forEach(referenceVisitor);
@@ -191,7 +194,7 @@ namespace ts {
191194
if (isExternalModule(node) && !resultHasExternalModuleIndicator) {
192195
combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements);
193196
}
194-
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences());
197+
const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib);
195198
return updated;
196199

197200
function getFileReferencesForUsedTypeReferences() {

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2590,6 +2590,7 @@ namespace ts {
25902590
sourceFiles: ReadonlyArray<SourceFile>;
25912591
/* @internal */ syntheticFileReferences?: ReadonlyArray<FileReference>;
25922592
/* @internal */ syntheticTypeReferences?: ReadonlyArray<FileReference>;
2593+
/* @internal */ hasNoDefaultLib?: boolean;
25932594
}
25942595

25952596
export interface JsonSourceFile extends SourceFile {

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3714,7 +3714,7 @@ declare namespace ts {
37143714
function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment;
37153715
function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember;
37163716
function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember;
3717-
function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]): SourceFile;
3717+
function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean): SourceFile;
37183718
/**
37193719
* Creates a shallow, memberwise clone of a node for mutation.
37203720
*/

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3661,7 +3661,7 @@ declare namespace ts {
36613661
function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment;
36623662
function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember;
36633663
function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember;
3664-
function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]): SourceFile;
3664+
function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray<Statement>, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean): SourceFile;
36653665
/**
36663666
* Creates a shallow, memberwise clone of a node for mutation.
36673667
*/
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [tests/cases/compiler/declarationEmitBundlePreservesHasNoDefaultLibDirective.ts] ////
2+
3+
//// [extensions.ts]
4+
/// <reference no-default-lib="true"/>
5+
class Foo {
6+
public: string;
7+
}
8+
//// [core.ts]
9+
interface Array<T> {}
10+
interface Boolean {}
11+
interface Function {}
12+
interface IArguments {}
13+
interface Number {}
14+
interface Object {}
15+
interface RegExp {}
16+
interface String {}
17+
18+
19+
//// [mylib.js]
20+
/// <reference no-default-lib="true"/>
21+
var Foo = /** @class */ (function () {
22+
function Foo() {
23+
}
24+
return Foo;
25+
}());
26+
27+
28+
//// [mylib.d.ts]
29+
/// <reference no-default-lib="true"/>
30+
declare class Foo {
31+
public: string;
32+
}
33+
interface Array<T> {
34+
}
35+
interface Boolean {
36+
}
37+
interface Function {
38+
}
39+
interface IArguments {
40+
}
41+
interface Number {
42+
}
43+
interface Object {
44+
}
45+
interface RegExp {
46+
}
47+
interface String {
48+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/extensions.ts ===
2+
/// <reference no-default-lib="true"/>
3+
class Foo {
4+
>Foo : Symbol(Foo, Decl(extensions.ts, 0, 0))
5+
6+
public: string;
7+
>public : Symbol(Foo.public, Decl(extensions.ts, 1, 11))
8+
}
9+
=== tests/cases/compiler/core.ts ===
10+
interface Array<T> {}
11+
>Array : Symbol(Array, Decl(core.ts, 0, 0))
12+
>T : Symbol(T, Decl(core.ts, 0, 16))
13+
14+
interface Boolean {}
15+
>Boolean : Symbol(Boolean, Decl(core.ts, 0, 21))
16+
17+
interface Function {}
18+
>Function : Symbol(Function, Decl(core.ts, 1, 20))
19+
20+
interface IArguments {}
21+
>IArguments : Symbol(IArguments, Decl(core.ts, 2, 21))
22+
23+
interface Number {}
24+
>Number : Symbol(Number, Decl(core.ts, 3, 23))
25+
26+
interface Object {}
27+
>Object : Symbol(Object, Decl(core.ts, 4, 19))
28+
29+
interface RegExp {}
30+
>RegExp : Symbol(RegExp, Decl(core.ts, 5, 19))
31+
32+
interface String {}
33+
>String : Symbol(String, Decl(core.ts, 6, 19))
34+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
=== tests/cases/compiler/extensions.ts ===
2+
/// <reference no-default-lib="true"/>
3+
class Foo {
4+
>Foo : Foo
5+
6+
public: string;
7+
>public : string
8+
}
9+
=== tests/cases/compiler/core.ts ===
10+
interface Array<T> {}
11+
>Array : T[]
12+
>T : T
13+
14+
interface Boolean {}
15+
>Boolean : Boolean
16+
17+
interface Function {}
18+
>Function : Function
19+
20+
interface IArguments {}
21+
>IArguments : IArguments
22+
23+
interface Number {}
24+
>Number : Number
25+
26+
interface Object {}
27+
>Object : Object
28+
29+
interface RegExp {}
30+
>RegExp : RegExp
31+
32+
interface String {}
33+
>String : String
34+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
//// [declarationEmitPreservesHasNoDefaultLibDirective.ts]
2+
/// <reference no-default-lib="true"/>
3+
class Foo {
4+
public: string;
5+
}
6+
interface Array<T> {}
7+
interface Boolean {}
8+
interface Function {}
9+
interface IArguments {}
10+
interface Number {}
11+
interface Object {}
12+
interface RegExp {}
13+
interface String {}
14+
15+
16+
//// [declarationEmitPreservesHasNoDefaultLibDirective.js]
17+
/// <reference no-default-lib="true"/>
18+
var Foo = /** @class */ (function () {
19+
function Foo() {
20+
}
21+
return Foo;
22+
}());
23+
24+
25+
//// [declarationEmitPreservesHasNoDefaultLibDirective.d.ts]
26+
/// <reference no-default-lib="true"/>
27+
declare class Foo {
28+
public: string;
29+
}
30+
interface Array<T> {
31+
}
32+
interface Boolean {
33+
}
34+
interface Function {
35+
}
36+
interface IArguments {
37+
}
38+
interface Number {
39+
}
40+
interface Object {
41+
}
42+
interface RegExp {
43+
}
44+
interface String {
45+
}

0 commit comments

Comments
 (0)