Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enables passing --declaration, --emitDeclarationOnly, --declarationMap, --soureMap and --inlineSourceMap to tsc --build #51241

Merged
merged 12 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
635 changes: 355 additions & 280 deletions src/compiler/builder.ts

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/compiler/builderState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ namespace ts {
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>, disableUseFileVersionAsSignature?: boolean): BuilderState {
const fileInfos = new Map<Path, FileInfo>();
const options = newProgram.getCompilerOptions();
const referencedMap = options.module !== ModuleKind.None && !outFile(options) ?
const isOutFile = outFile(options);
const referencedMap = options.module !== ModuleKind.None && !isOutFile ?
createManyToManyPathMap() : undefined;
const exportedModulesMap = referencedMap ? createManyToManyPathMap() : undefined;
const useOldState = canReuseOldState(referencedMap, oldState);
Expand Down Expand Up @@ -299,7 +300,8 @@ namespace ts {
fileInfos.set(sourceFile.resolvedPath, {
version,
signature,
affectsGlobalScope: isFileAffectingGlobalScope(sourceFile) || undefined,
// No need to calculate affectsGlobalScope with --out since its not used at all
affectsGlobalScope: !isOutFile ? isFileAffectingGlobalScope(sourceFile) || undefined : undefined,
impliedFormat: sourceFile.impliedNodeFormat
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/builderStatePublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ namespace ts {
name: string;
writeByteOrderMark: boolean;
text: string;
/* @internal */ buildInfo?: BuildInfo
/* @internal */ data?: WriteFileCallbackData;
}
}
231 changes: 113 additions & 118 deletions src/compiler/commandLineParser.ts

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -5426,6 +5426,10 @@
"category": "Message",
"code": 6405
},
"Project '{0}' is out of date because buildinfo file '{1}' indicates there is change in compilerOptions": {
"category": "Message",
"code": 6406
},

"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
Expand Down
72 changes: 39 additions & 33 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ namespace ts {
/*@internal*/
export function getFirstProjectOutput(configFile: ParsedCommandLine, ignoreCase: boolean): string {
if (outFile(configFile.options)) {
const { jsFilePath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false);
return Debug.checkDefined(jsFilePath, `project ${configFile.options.configFilePath} expected to have at least one output`);
const { jsFilePath, declarationFilePath } = getOutputPathsForBundle(configFile.options, /*forceDtsPaths*/ false);
return Debug.checkDefined(jsFilePath || declarationFilePath, `project ${configFile.options.configFilePath} expected to have at least one output`);
}

const getCommonSourceDirectory = memoize(() => getCommonSourceDirectoryOfConfig(configFile, ignoreCase));
Expand All @@ -278,7 +278,7 @@ namespace ts {

/*@internal*/
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, { scriptTransformers, declarationTransformers }: EmitTransformers, emitOnlyDtsFiles?: boolean, onlyBuildInfo?: boolean, forceDtsEmit?: boolean): EmitResult {
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile | undefined, { scriptTransformers, declarationTransformers }: EmitTransformers, emitOnly?: boolean | EmitOnly, onlyBuildInfo?: boolean, forceDtsEmit?: boolean): EmitResult {
const compilerOptions = host.getCompilerOptions();
const sourceMapDataList: SourceMapEmitResult[] | undefined = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
const emittedFilesList: string[] | undefined = compilerOptions.listEmittedFiles ? [] : undefined;
Expand Down Expand Up @@ -331,7 +331,7 @@ namespace ts {
tracing?.pop();

if (!emitSkipped && emittedFilesList) {
if (!emitOnlyDtsFiles) {
if (!emitOnly) {
if (jsFilePath) {
emittedFilesList.push(jsFilePath);
}
Expand All @@ -342,11 +342,13 @@ namespace ts {
emittedFilesList.push(buildInfoPath);
}
}
if (declarationFilePath) {
emittedFilesList.push(declarationFilePath);
}
if (declarationMapPath) {
emittedFilesList.push(declarationMapPath);
if (emitOnly !== EmitOnly.Js) {
if (declarationFilePath) {
emittedFilesList.push(declarationFilePath);
}
if (declarationMapPath) {
emittedFilesList.push(declarationMapPath);
}
}
}

Expand All @@ -358,13 +360,11 @@ namespace ts {
function emitBuildInfo(bundle: BundleBuildInfo | undefined, buildInfoPath: string | undefined) {
// Write build information if applicable
if (!buildInfoPath || targetSourceFile || emitSkipped) return;
const program = host.getProgramBuildInfo();
if (host.isEmitBlocked(buildInfoPath)) {
emitSkipped = true;
return;
}
const version = ts.version; // Extracted into a const so the form is stable between namespace and module
const buildInfo: BuildInfo = { bundle, program, version };
const buildInfo = host.getBuildInfo(bundle) || createBuildInfo(/*program*/ undefined, bundle);
// Pass buildinfo as additional data to avoid having to reparse
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
}
Expand All @@ -374,7 +374,7 @@ namespace ts {
jsFilePath: string | undefined,
sourceMapFilePath: string | undefined,
relativeToBuildInfo: (path: string) => string) {
if (!sourceFileOrBundle || emitOnlyDtsFiles || !jsFilePath) {
if (!sourceFileOrBundle || emitOnly || !jsFilePath) {
return;
}

Expand Down Expand Up @@ -424,16 +424,16 @@ namespace ts {
declarationFilePath: string | undefined,
declarationMapPath: string | undefined,
relativeToBuildInfo: (path: string) => string) {
if (!sourceFileOrBundle) return;
if (!sourceFileOrBundle || emitOnly === EmitOnly.Js) return;
if (!declarationFilePath) {
if (emitOnlyDtsFiles || compilerOptions.emitDeclarationOnly) emitSkipped = true;
if (emitOnly || compilerOptions.emitDeclarationOnly) emitSkipped = true;
return;
}
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
const filesForEmit = forceDtsEmit ? sourceFiles : filter(sourceFiles, isSourceFileNotJson);
// Setup and perform the transformation to retrieve declarations from the input files
const inputListOrBundle = outFile(compilerOptions) ? [factory.createBundle(filesForEmit, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : filesForEmit;
if (emitOnlyDtsFiles && !getEmitDeclarations(compilerOptions)) {
if (emitOnly && !getEmitDeclarations(compilerOptions)) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
// Do that here when emitting only dts files
filesForEmit.forEach(collectLinkedAliases);
Expand Down Expand Up @@ -646,6 +646,12 @@ namespace ts {
}
}

/*@internal*/
export function createBuildInfo(program: ProgramBuildInfo | undefined, bundle: BundleBuildInfo | undefined): BuildInfo {
const version = ts.version; // Extracted into a const so the form is stable between namespace and module
return { bundle, program, version };
}

/*@internal*/
export function getBuildInfoText(buildInfo: BuildInfo) {
return JSON.stringify(buildInfo);
Expand Down Expand Up @@ -822,21 +828,7 @@ namespace ts {
if (sourceMapText === text) return;
break;
case buildInfoPath:
const newBuildInfo = data!.buildInfo!;
newBuildInfo.program = buildInfo.program;
if (newBuildInfo.program && changedDtsText !== undefined && config.options.composite) {
// Update the output signature
(newBuildInfo.program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, createHash, changedDtsData);
}
// Update sourceFileInfo
const { js, dts, sourceFiles } = buildInfo.bundle!;
newBuildInfo.bundle!.js!.sources = js!.sources;
if (dts) {
newBuildInfo.bundle!.dts!.sources = dts.sources;
}
newBuildInfo.bundle!.sourceFiles = sourceFiles;
outputFiles.push({ name, text: getBuildInfoText(newBuildInfo), writeByteOrderMark, buildInfo: newBuildInfo });
return;
break;
case declarationFilePath:
if (declarationText === text) return;
changedDtsText = text;
Expand All @@ -848,13 +840,27 @@ namespace ts {
default:
Debug.fail(`Unexpected path: ${name}`);
}
outputFiles.push({ name, text, writeByteOrderMark });
outputFiles.push({ name, text, writeByteOrderMark, data });
},
isEmitBlocked: returnFalse,
readFile: f => host.readFile(f),
fileExists: f => host.fileExists(f),
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
getProgramBuildInfo: returnUndefined,
getBuildInfo: bundle => {
const program = buildInfo.program;
if (program && changedDtsText !== undefined && config.options.composite) {
// Update the output signature
(program as ProgramBundleEmitBuildInfo).outSignature = computeSignature(changedDtsText, createHash, changedDtsData);
}
// Update sourceFileInfo
const { js, dts, sourceFiles } = buildInfo.bundle!;
bundle!.js!.sources = js!.sources;
if (dts) {
bundle!.dts!.sources = dts.sources;
}
bundle!.sourceFiles = sourceFiles;
return createBuildInfo(program, bundle);
},
getSourceFileFromReference: returnUndefined,
redirectTargetsMap: createMultiMap(),
getFileIncludeReasons: notImplemented,
Expand Down
12 changes: 6 additions & 6 deletions src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1967,7 +1967,7 @@ namespace ts {
return host.fileExists(f);
},
useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(),
getProgramBuildInfo: () => program.getProgramBuildInfo && program.getProgramBuildInfo(),
getBuildInfo: bundle => program.getBuildInfo?.(bundle),
getSourceFileFromReference: (file, ref) => program.getSourceFileFromReference(file, ref),
redirectTargetsMap,
getFileIncludeReasons: program.getFileIncludeReasons,
Expand Down Expand Up @@ -2058,9 +2058,9 @@ namespace ts {
return typeChecker || (typeChecker = createTypeChecker(program));
}

function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnlyDtsFiles?: boolean, transformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
function emit(sourceFile?: SourceFile, writeFileCallback?: WriteFileCallback, cancellationToken?: CancellationToken, emitOnly?: boolean | EmitOnly, transformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
tracing?.push(tracing.Phase.Emit, "emit", { path: sourceFile?.path }, /*separateBeginAndEnd*/ true);
const result = runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers, forceDtsEmit));
const result = runWithCancellationToken(() => emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnly, transformers, forceDtsEmit));
tracing?.pop();
return result;
}
Expand All @@ -2069,7 +2069,7 @@ namespace ts {
return hasEmitBlockingDiagnostics.has(toPath(emitFileName));
}

function emitWorker(program: Program, sourceFile: SourceFile | undefined, writeFileCallback: WriteFileCallback | undefined, cancellationToken: CancellationToken | undefined, emitOnlyDtsFiles?: boolean, customTransformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
function emitWorker(program: Program, sourceFile: SourceFile | undefined, writeFileCallback: WriteFileCallback | undefined, cancellationToken: CancellationToken | undefined, emitOnly?: boolean | EmitOnly, customTransformers?: CustomTransformers, forceDtsEmit?: boolean): EmitResult {
if (!forceDtsEmit) {
const result = handleNoEmitOptions(program, sourceFile, writeFileCallback, cancellationToken);
if (result) return result;
Expand All @@ -2091,8 +2091,8 @@ namespace ts {
emitResolver,
getEmitHost(writeFileCallback),
sourceFile,
getTransformers(options, customTransformers, emitOnlyDtsFiles),
emitOnlyDtsFiles,
getTransformers(options, customTransformers, emitOnly),
emitOnly,
/*onlyBuildInfo*/ false,
forceDtsEmit
);
Expand Down
5 changes: 3 additions & 2 deletions src/compiler/sourcemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,10 @@ namespace ts {
}

// Sometimes tools can see the following line as a source mapping url comment, so we mangle it a bit (the [M])
const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
export const sourceMapCommentRegExpDontCareLineStart = /\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;
export const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)\r?\n?$/;

const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;
export const whitespaceOrMapCommentRegExp = /^\s*(\/\/[@#] .*)?$/;

export interface LineInfo {
getLineCount(): number;
Expand Down
8 changes: 4 additions & 4 deletions src/compiler/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,15 @@ namespace ts {

export const noTransformers: EmitTransformers = { scriptTransformers: emptyArray, declarationTransformers: emptyArray };

export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean): EmitTransformers {
export function getTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnly?: boolean | EmitOnly): EmitTransformers {
return {
scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnlyDtsFiles),
scriptTransformers: getScriptTransformers(compilerOptions, customTransformers, emitOnly),
declarationTransformers: getDeclarationTransformers(customTransformers),
};
}

function getScriptTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnlyDtsFiles?: boolean) {
if (emitOnlyDtsFiles) return emptyArray;
function getScriptTransformers(compilerOptions: CompilerOptions, customTransformers?: CustomTransformers, emitOnly?: boolean | EmitOnly) {
if (emitOnly) return emptyArray;

const languageVersion = getEmitScriptTarget(compilerOptions);
const moduleKind = getEmitModuleKind(compilerOptions);
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/tsbuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace ts {
OutOfDateWithSelf,
OutOfDateWithUpstream,
OutOfDateBuildInfo,
OutOfDateOptions,
UpstreamOutOfDate,
UpstreamBlocked,
ComputingUpstream,
Expand Down Expand Up @@ -116,7 +117,7 @@ namespace ts {
* Buildinfo indicates that build is out of date
*/
export interface OutOfDateBuildInfo {
type: UpToDateStatusType.OutOfDateBuildInfo,
type: UpToDateStatusType.OutOfDateBuildInfo | UpToDateStatusType.OutOfDateOptions,
buildInfoFile: string;
}

Expand Down
Loading