diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 6fca3d897ac..23a74c8f1b7 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2473,14 +2473,18 @@ namespace ts { } function emitSyntheticTripleSlashReferencesIfNeeded(node: Bundle) { - emitTripleSlashDirectives(node.syntheticFileReferences || [], node.syntheticTypeReferences || []); + emitTripleSlashDirectives(node.hasNoDefaultLib, node.syntheticFileReferences || [], node.syntheticTypeReferences || []); } function emitTripleSlashDirectivesIfNeeded(node: SourceFile) { - if (node.isDeclarationFile) emitTripleSlashDirectives(node.referencedFiles, node.typeReferenceDirectives); + if (node.isDeclarationFile) emitTripleSlashDirectives(node.hasNoDefaultLib, node.referencedFiles, node.typeReferenceDirectives); } - function emitTripleSlashDirectives(files: ReadonlyArray, types: ReadonlyArray) { + function emitTripleSlashDirectives(hasNoDefaultLib: boolean, files: ReadonlyArray, types: ReadonlyArray) { + if (hasNoDefaultLib) { + write(`/// `); + writeLine(); + } if (currentSourceFile && currentSourceFile.moduleName) { write(`/// `); writeLine(); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index c64ce44dc6d..1b951c5b0b7 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -2387,12 +2387,13 @@ namespace ts { // Top-level nodes - export function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]) { + export function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean) { if ( node.statements !== statements || (isDeclarationFile !== undefined && node.isDeclarationFile !== isDeclarationFile) || (referencedFiles !== undefined && node.referencedFiles !== referencedFiles) || - (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) + (typeReferences !== undefined && node.typeReferenceDirectives !== typeReferences) || + (hasNoDefaultLib !== undefined && node.hasNoDefaultLib !== hasNoDefaultLib) ) { const updated = createSynthesizedNode(SyntaxKind.SourceFile); updated.flags |= node.flags; @@ -2404,11 +2405,11 @@ namespace ts { updated.isDeclarationFile = isDeclarationFile === undefined ? node.isDeclarationFile : isDeclarationFile; updated.referencedFiles = referencedFiles === undefined ? node.referencedFiles : referencedFiles; updated.typeReferenceDirectives = typeReferences === undefined ? node.typeReferenceDirectives : typeReferences; + updated.hasNoDefaultLib = hasNoDefaultLib === undefined ? node.hasNoDefaultLib : hasNoDefaultLib; if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; if (node.moduleName !== undefined) updated.moduleName = node.moduleName; if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; - if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib; if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 83128b9acb4..a7ecab0b4fe 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -135,9 +135,11 @@ namespace ts { if (node.kind === SyntaxKind.Bundle) { isBundledEmit = true; const refs = createMap(); + let hasNoDefaultLib = false; const bundle = createBundle(map(node.sourceFiles, sourceFile => { if (sourceFile.isDeclarationFile || isSourceFileJavaScript(sourceFile)) return; // Omit declaration files from bundle results, too + hasNoDefaultLib = hasNoDefaultLib || sourceFile.hasNoDefaultLib; currentSourceFile = sourceFile; enclosingDeclaration = sourceFile; possibleImports = undefined; @@ -154,16 +156,17 @@ namespace ts { [createModifier(SyntaxKind.DeclareKeyword)], createLiteral(getResolvedExternalModuleName(context.getEmitHost(), sourceFile)), createModuleBlock(setTextRange(createNodeArray(filterCandidateImports(statements)), sourceFile.statements)) - )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ []); + )], /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false); return newFile; } needsDeclare = true; const updated = visitNodes(sourceFile.statements, visitDeclarationStatements); - return updateSourceFileNode(sourceFile, updated, /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ []); + return updateSourceFileNode(sourceFile, updated, /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false); } )); bundle.syntheticFileReferences = []; bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences(); + bundle.hasNoDefaultLib = hasNoDefaultLib; const outputFilePath = getDirectoryPath(normalizeSlashes(getOutputPathsFor(node, host, /*forceDtsPaths*/ true).declarationFilePath)); const referenceVisitor = mapReferencesIntoArray(bundle.syntheticFileReferences as FileReference[], outputFilePath); refs.forEach(referenceVisitor); @@ -191,7 +194,7 @@ namespace ts { if (isExternalModule(node) && !resultHasExternalModuleIndicator) { combinedStatements = setTextRange(createNodeArray([...combinedStatements, createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([]), /*moduleSpecifier*/ undefined)]), combinedStatements); } - const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences()); + const updated = updateSourceFileNode(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib); return updated; function getFileReferencesForUsedTypeReferences() { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 801d44e2012..83b3dde7aa7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2590,6 +2590,7 @@ namespace ts { sourceFiles: ReadonlyArray; /* @internal */ syntheticFileReferences?: ReadonlyArray; /* @internal */ syntheticTypeReferences?: ReadonlyArray; + /* @internal */ hasNoDefaultLib?: boolean; } export interface JsonSourceFile extends SourceFile { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 10d6f31408b..b859f9f1876 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3714,7 +3714,7 @@ declare namespace ts { function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; - function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]): SourceFile; + function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean): SourceFile; /** * Creates a shallow, memberwise clone of a node for mutation. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 26b942f6d81..d9381742cc3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3661,7 +3661,7 @@ declare namespace ts { function updateSpreadAssignment(node: SpreadAssignment, expression: Expression): SpreadAssignment; function createEnumMember(name: string | PropertyName, initializer?: Expression): EnumMember; function updateEnumMember(node: EnumMember, name: PropertyName, initializer: Expression | undefined): EnumMember; - function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"]): SourceFile; + function updateSourceFileNode(node: SourceFile, statements: ReadonlyArray, isDeclarationFile?: boolean, referencedFiles?: SourceFile["referencedFiles"], typeReferences?: SourceFile["typeReferenceDirectives"], hasNoDefaultLib?: boolean): SourceFile; /** * Creates a shallow, memberwise clone of a node for mutation. */ diff --git a/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.js b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.js new file mode 100644 index 00000000000..94e9f627e93 --- /dev/null +++ b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.js @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/declarationEmitBundlePreservesHasNoDefaultLibDirective.ts] //// + +//// [extensions.ts] +/// +class Foo { + public: string; +} +//// [core.ts] +interface Array {} +interface Boolean {} +interface Function {} +interface IArguments {} +interface Number {} +interface Object {} +interface RegExp {} +interface String {} + + +//// [mylib.js] +/// +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); + + +//// [mylib.d.ts] +/// +declare class Foo { + public: string; +} +interface Array { +} +interface Boolean { +} +interface Function { +} +interface IArguments { +} +interface Number { +} +interface Object { +} +interface RegExp { +} +interface String { +} diff --git a/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.symbols b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.symbols new file mode 100644 index 00000000000..3819cefebcb --- /dev/null +++ b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/extensions.ts === +/// +class Foo { +>Foo : Symbol(Foo, Decl(extensions.ts, 0, 0)) + + public: string; +>public : Symbol(Foo.public, Decl(extensions.ts, 1, 11)) +} +=== tests/cases/compiler/core.ts === +interface Array {} +>Array : Symbol(Array, Decl(core.ts, 0, 0)) +>T : Symbol(T, Decl(core.ts, 0, 16)) + +interface Boolean {} +>Boolean : Symbol(Boolean, Decl(core.ts, 0, 21)) + +interface Function {} +>Function : Symbol(Function, Decl(core.ts, 1, 20)) + +interface IArguments {} +>IArguments : Symbol(IArguments, Decl(core.ts, 2, 21)) + +interface Number {} +>Number : Symbol(Number, Decl(core.ts, 3, 23)) + +interface Object {} +>Object : Symbol(Object, Decl(core.ts, 4, 19)) + +interface RegExp {} +>RegExp : Symbol(RegExp, Decl(core.ts, 5, 19)) + +interface String {} +>String : Symbol(String, Decl(core.ts, 6, 19)) + diff --git a/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.types b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.types new file mode 100644 index 00000000000..3b5f0685ce9 --- /dev/null +++ b/tests/baselines/reference/declarationEmitBundlePreservesHasNoDefaultLibDirective.types @@ -0,0 +1,34 @@ +=== tests/cases/compiler/extensions.ts === +/// +class Foo { +>Foo : Foo + + public: string; +>public : string +} +=== tests/cases/compiler/core.ts === +interface Array {} +>Array : T[] +>T : T + +interface Boolean {} +>Boolean : Boolean + +interface Function {} +>Function : Function + +interface IArguments {} +>IArguments : IArguments + +interface Number {} +>Number : Number + +interface Object {} +>Object : Object + +interface RegExp {} +>RegExp : RegExp + +interface String {} +>String : String + diff --git a/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.js b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.js new file mode 100644 index 00000000000..b71b5ed3ded --- /dev/null +++ b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.js @@ -0,0 +1,45 @@ +//// [declarationEmitPreservesHasNoDefaultLibDirective.ts] +/// +class Foo { + public: string; +} +interface Array {} +interface Boolean {} +interface Function {} +interface IArguments {} +interface Number {} +interface Object {} +interface RegExp {} +interface String {} + + +//// [declarationEmitPreservesHasNoDefaultLibDirective.js] +/// +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); + + +//// [declarationEmitPreservesHasNoDefaultLibDirective.d.ts] +/// +declare class Foo { + public: string; +} +interface Array { +} +interface Boolean { +} +interface Function { +} +interface IArguments { +} +interface Number { +} +interface Object { +} +interface RegExp { +} +interface String { +} diff --git a/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.symbols b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.symbols new file mode 100644 index 00000000000..d271cb33a73 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.symbols @@ -0,0 +1,33 @@ +=== tests/cases/compiler/declarationEmitPreservesHasNoDefaultLibDirective.ts === +/// +class Foo { +>Foo : Symbol(Foo, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 0, 0)) + + public: string; +>public : Symbol(Foo.public, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 1, 11)) +} +interface Array {} +>Array : Symbol(Array, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 3, 1)) +>T : Symbol(T, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 4, 16)) + +interface Boolean {} +>Boolean : Symbol(Boolean, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 4, 21)) + +interface Function {} +>Function : Symbol(Function, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 5, 20)) + +interface IArguments {} +>IArguments : Symbol(IArguments, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 6, 21)) + +interface Number {} +>Number : Symbol(Number, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 7, 23)) + +interface Object {} +>Object : Symbol(Object, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 8, 19)) + +interface RegExp {} +>RegExp : Symbol(RegExp, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 9, 19)) + +interface String {} +>String : Symbol(String, Decl(declarationEmitPreservesHasNoDefaultLibDirective.ts, 10, 19)) + diff --git a/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.types b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.types new file mode 100644 index 00000000000..723cc766795 --- /dev/null +++ b/tests/baselines/reference/declarationEmitPreservesHasNoDefaultLibDirective.types @@ -0,0 +1,33 @@ +=== tests/cases/compiler/declarationEmitPreservesHasNoDefaultLibDirective.ts === +/// +class Foo { +>Foo : Foo + + public: string; +>public : string +} +interface Array {} +>Array : T[] +>T : T + +interface Boolean {} +>Boolean : Boolean + +interface Function {} +>Function : Function + +interface IArguments {} +>IArguments : IArguments + +interface Number {} +>Number : Number + +interface Object {} +>Object : Object + +interface RegExp {} +>RegExp : RegExp + +interface String {} +>String : String + diff --git a/tests/cases/compiler/declarationEmitBundlePreservesHasNoDefaultLibDirective.ts b/tests/cases/compiler/declarationEmitBundlePreservesHasNoDefaultLibDirective.ts new file mode 100644 index 00000000000..79ebb3c9387 --- /dev/null +++ b/tests/cases/compiler/declarationEmitBundlePreservesHasNoDefaultLibDirective.ts @@ -0,0 +1,16 @@ +// @declaration: true +// @outFile: mylib.js +// @filename: extensions.ts +/// +class Foo { + public: string; +} +// @filename: core.ts +interface Array {} +interface Boolean {} +interface Function {} +interface IArguments {} +interface Number {} +interface Object {} +interface RegExp {} +interface String {} diff --git a/tests/cases/compiler/declarationEmitPreservesHasNoDefaultLibDirective.ts b/tests/cases/compiler/declarationEmitPreservesHasNoDefaultLibDirective.ts new file mode 100644 index 00000000000..8cb0e82b048 --- /dev/null +++ b/tests/cases/compiler/declarationEmitPreservesHasNoDefaultLibDirective.ts @@ -0,0 +1,13 @@ +// @declaration: true +/// +class Foo { + public: string; +} +interface Array {} +interface Boolean {} +interface Function {} +interface IArguments {} +interface Number {} +interface Object {} +interface RegExp {} +interface String {}