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

Skip typechecking file when generating declaraiton to get d.ts signature for incremental build #58592

Merged
merged 7 commits into from
May 21, 2024
26 changes: 13 additions & 13 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2428,10 +2428,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return visitEachChild(node, markAsSynthetic, /*context*/ undefined);
}

function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken, forceDtsEmit?: boolean) {
// Ensure we have all the type information in place for this file so that all the
// emitter questions of this resolver will return the right information.
getDiagnostics(sourceFile, cancellationToken);
getDiagnostics(sourceFile, cancellationToken, forceDtsEmit);
sheetalkamat marked this conversation as resolved.
Show resolved Hide resolved
return emitResolver;
}

Expand Down Expand Up @@ -47483,10 +47483,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
tracing?.pop();
}

function checkSourceFile(node: SourceFile) {
function checkSourceFile(node: SourceFile, forceDtsEmit: boolean | undefined) {
tracing?.push(tracing.Phase.Check, "checkSourceFile", { path: node.path }, /*separateBeginAndEnd*/ true);
performance.mark("beforeCheck");
checkSourceFileWorker(node);
checkSourceFileWorker(node, forceDtsEmit);
performance.mark("afterCheck");
performance.measure("Check", "beforeCheck", "afterCheck");
tracing?.pop();
Expand All @@ -47511,10 +47511,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

// Fully type check a source file and collect the relevant diagnostics.
function checkSourceFileWorker(node: SourceFile) {
function checkSourceFileWorker(node: SourceFile, forceDtsEmit: boolean | undefined) {
const links = getNodeLinks(node);
if (!(links.flags & NodeCheckFlags.TypeChecked)) {
if (skipTypeChecking(node, compilerOptions, host)) {
if (forceDtsEmit || skipTypeChecking(node, compilerOptions, host)) {
return;
}

Expand Down Expand Up @@ -47578,13 +47578,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}

function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken): Diagnostic[] {
function getDiagnostics(sourceFile: SourceFile, ct: CancellationToken, forceDtsEmit?: boolean): Diagnostic[] {
sheetalkamat marked this conversation as resolved.
Show resolved Hide resolved
try {
// Record the cancellation token so it can be checked later on during checkSourceElement.
// Do this in a finally block so we can ensure that it gets reset back to nothing after
// this call is done.
cancellationToken = ct;
return getDiagnosticsWorker(sourceFile);
return getDiagnosticsWorker(sourceFile, forceDtsEmit);
}
finally {
cancellationToken = undefined;
Expand All @@ -47599,7 +47599,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
deferredDiagnosticsCallbacks = [];
}

function checkSourceFileWithEagerDiagnostics(sourceFile: SourceFile) {
function checkSourceFileWithEagerDiagnostics(sourceFile: SourceFile, forceDtsEmit?: boolean) {
ensurePendingDiagnosticWorkComplete();
// then setup diagnostics for immediate invocation (as we are about to collect them, and
// this avoids the overhead of longer-lived callbacks we don't need to allocate)
Expand All @@ -47608,11 +47608,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// thus much more likely retaining the same union ordering as before we had lazy diagnostics)
const oldAddLazyDiagnostics = addLazyDiagnostic;
addLazyDiagnostic = cb => cb();
checkSourceFile(sourceFile);
checkSourceFile(sourceFile, forceDtsEmit);
addLazyDiagnostic = oldAddLazyDiagnostics;
}

function getDiagnosticsWorker(sourceFile: SourceFile): Diagnostic[] {
function getDiagnosticsWorker(sourceFile: SourceFile, forceDtsEmit: boolean | undefined): Diagnostic[] {
if (sourceFile) {
ensurePendingDiagnosticWorkComplete();
// Some global diagnostics are deferred until they are needed and
Expand All @@ -47621,7 +47621,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
const previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length;

checkSourceFileWithEagerDiagnostics(sourceFile);
checkSourceFileWithEagerDiagnostics(sourceFile, forceDtsEmit);

const semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName);
const currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics();
Expand All @@ -47642,7 +47642,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

// Global diagnostics are always added when a file is not provided to
// getDiagnostics
forEach(host.getSourceFiles(), checkSourceFileWithEagerDiagnostics);
forEach(host.getSourceFiles(), sourceFile => checkSourceFileWithEagerDiagnostics(sourceFile, forceDtsEmit));
return diagnostics.getDiagnostics();
}

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2870,7 +2870,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
// This is because in the -out scenario all files need to be emitted, and therefore all
// files need to be type checked. And the way to specify that all files need to be type
// checked is to not pass the file to getEmitResolver.
const emitResolver = getTypeChecker().getEmitResolver(options.outFile ? undefined : sourceFile, cancellationToken);
const emitResolver = getTypeChecker().getEmitResolver(options.outFile ? undefined : sourceFile, cancellationToken, forceDtsEmit);

performance.mark("beforeEmit");

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5264,7 +5264,7 @@ export interface TypeChecker {
// Should not be called directly. Should only be accessed through the Program instance.
/** @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
/** @internal */ getGlobalDiagnostics(): Diagnostic[];
/** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken): EmitResolver;
/** @internal */ getEmitResolver(sourceFile?: SourceFile, cancellationToken?: CancellationToken, forceDts?: boolean): EmitResolver;

/** @internal */ getNodeCount(): number;
/** @internal */ getIdentifierCount(): number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ Output::


//// [/user/username/projects/demo/lib/core/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../../../a/lib/lib.d.ts","../../animals/animal.ts","../../animals/dog.ts","../../animals/index.ts","../../core/utilities.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedFormat":1},{"version":"-9289341318-export type Size = \"small\" | \"medium\" | \"large\";\nexport default interface Animal {\n size: Size;\n}\n","impliedFormat":1},{"version":"-18870194049-import Animal from '.';\nimport { makeRandomName } from '../core/utilities';\n\nexport interface Dog extends Animal {\n woof(): void;\n name: string;\n}\n\nexport function createDog(): Dog {\n return ({\n size: \"medium\",\n woof: function(this: Dog) {\n console.log(`${ this.name } says \"Woof\"!`);\n },\n name: makeRandomName()\n });\n}\n","signature":"6032048049-import Animal from '.';\nexport interface Dog extends Animal {\n woof(): void;\n name: string;\n}\nexport declare function createDog(): Dog;\n","impliedFormat":1},{"version":"-7220553464-import Animal from './animal';\n\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n","signature":"1096904574-import Animal from './animal';\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n","impliedFormat":1},{"version":"-11321611519-\nimport * as A from '../animals';\nexport function makeRandomName() {\n return \"Bob!?! \";\n}\n\nexport function lastElementOf<T>(arr: T[]): T | undefined {\n if (arr.length === 0) return undefined;\n return arr[arr.length - 1];\n}\n","signature":"-11345568166-export declare function makeRandomName(): string;\nexport declare function lastElementOf<T>(arr: T[]): T | undefined;\n","impliedFormat":1}],"root":[5],"options":{"composite":true,"declaration":true,"module":1,"noFallthroughCasesInSwitch":true,"noImplicitReturns":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","rootDir":"../../core","strict":true,"target":1},"fileIdsList":[[4,5],[2,3],[4]],"referencedMap":[[3,1],[4,2],[5,3]],"semanticDiagnosticsPerFile":[1,2,3,4,[5,[{"file":"../../core/utilities.ts","start":1,"length":32,"messageText":"'A' is declared but its value is never read.","category":1,"code":6133,"reportsUnnecessary":true}]]],"affectedFilesPendingEmit":[2,3,4,5],"emitSignatures":[2,3,4,5]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../../../../../../a/lib/lib.d.ts","../../animals/animal.ts","../../animals/dog.ts","../../animals/index.ts","../../core/utilities.ts"],"fileInfos":[{"version":"3858781397-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }\ninterface ReadonlyArray<T> {}\ndeclare const console: { log(msg: any): void; };","affectsGlobalScope":true,"impliedFormat":1},{"version":"-9289341318-export type Size = \"small\" | \"medium\" | \"large\";\nexport default interface Animal {\n size: Size;\n}\n","impliedFormat":1},{"version":"-18870194049-import Animal from '.';\nimport { makeRandomName } from '../core/utilities';\n\nexport interface Dog extends Animal {\n woof(): void;\n name: string;\n}\n\nexport function createDog(): Dog {\n return ({\n size: \"medium\",\n woof: function(this: Dog) {\n console.log(`${ this.name } says \"Woof\"!`);\n },\n name: makeRandomName()\n });\n}\n","signature":"6032048049-import Animal from '.';\nexport interface Dog extends Animal {\n woof(): void;\n name: string;\n}\nexport declare function createDog(): Dog;\n","impliedFormat":1},{"version":"-7220553464-import Animal from './animal';\n\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n","signature":"2198076214-export default Animal;\nexport { createDog, Dog };\n","impliedFormat":1},{"version":"-11321611519-\nimport * as A from '../animals';\nexport function makeRandomName() {\n return \"Bob!?! \";\n}\n\nexport function lastElementOf<T>(arr: T[]): T | undefined {\n if (arr.length === 0) return undefined;\n return arr[arr.length - 1];\n}\n","signature":"-11345568166-export declare function makeRandomName(): string;\nexport declare function lastElementOf<T>(arr: T[]): T | undefined;\n","impliedFormat":1}],"root":[5],"options":{"composite":true,"declaration":true,"module":1,"noFallthroughCasesInSwitch":true,"noImplicitReturns":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./","rootDir":"../../core","strict":true,"target":1},"fileIdsList":[[4,5],[2,3],[4]],"referencedMap":[[3,1],[4,2],[5,3]],"semanticDiagnosticsPerFile":[1,2,3,4,[5,[{"file":"../../core/utilities.ts","start":1,"length":32,"messageText":"'A' is declared but its value is never read.","category":1,"code":6133,"reportsUnnecessary":true}]]],"affectedFilesPendingEmit":[2,3,4,5],"emitSignatures":[2,3,4,5]},"version":"FakeTSVersion"}

//// [/user/username/projects/demo/lib/core/tsconfig.tsbuildinfo.readable.baseline.txt]
{
Expand Down Expand Up @@ -615,11 +615,11 @@ Output::
"../../animals/index.ts": {
"original": {
"version": "-7220553464-import Animal from './animal';\n\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n",
"signature": "1096904574-import Animal from './animal';\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n",
"signature": "2198076214-export default Animal;\nexport { createDog, Dog };\n",
sheetalkamat marked this conversation as resolved.
Show resolved Hide resolved
"impliedFormat": 1
},
"version": "-7220553464-import Animal from './animal';\n\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n",
"signature": "1096904574-import Animal from './animal';\nexport default Animal;\nimport { createDog, Dog } from './dog';\nexport { createDog, Dog };\n",
"signature": "2198076214-export default Animal;\nexport { createDog, Dog };\n",
"impliedFormat": "commonjs"
},
"../../core/utilities.ts": {
Expand Down Expand Up @@ -711,7 +711,7 @@ Output::
]
},
"version": "FakeTSVersion",
"size": 2812
"size": 2739
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Operation ws cancelled:: true


//// [/user/username/projects/myproject/tsconfig.tsbuildinfo]
{"program":{"fileNames":["../../../../a/lib/lib.d.ts","./c.ts","./b.ts","./a.ts","./d.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true,"impliedFormat":1},{"version":"840271342-export class C {\n d = 1;\n}export function foo() {}","signature":"-6977846840-export declare class C {\n d: number;\n}\n","impliedFormat":1},{"version":"-6441446591-import {C} from './c';\nexport class B {\n c = new C();\n}","signature":"-165097315-import { C } from './c';\nexport declare class B {\n c: C;\n}\n","impliedFormat":1},{"version":"4878398349-import {B} from './b';\ndeclare var console: any;\nlet b = new B();\nconsole.log(b.c.d);","signature":"-3531856636-export {};\n","impliedFormat":1},{"version":"-7804761415-export class D { }","signature":"-8611429667-export declare class D {\n}\n","impliedFormat":1}],"root":[[2,5]],"options":{"declaration":true},"fileIdsList":[[3],[2]],"referencedMap":[[4,1],[3,2]],"semanticDiagnosticsPerFile":[1,4,3,5],"changeFileSet":[2]},"version":"FakeTSVersion"}
{"program":{"fileNames":["../../../../a/lib/lib.d.ts","./c.ts","./b.ts","./a.ts","./d.ts"],"fileInfos":[{"version":"-7698705165-/// <reference no-default-lib=\"true\"/>\ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array<T> { length: number; [n: number]: T; }","affectsGlobalScope":true,"impliedFormat":1},{"version":"840271342-export class C {\n d = 1;\n}export function foo() {}","signature":"-6977846840-export declare class C {\n d: number;\n}\n","impliedFormat":1},{"version":"-6441446591-import {C} from './c';\nexport class B {\n c = new C();\n}","signature":"-165097315-import { C } from './c';\nexport declare class B {\n c: C;\n}\n","impliedFormat":1},{"version":"4878398349-import {B} from './b';\ndeclare var console: any;\nlet b = new B();\nconsole.log(b.c.d);","signature":"-3531856636-export {};\n","impliedFormat":1},{"version":"-7804761415-export class D { }","signature":"-8611429667-export declare class D {\n}\n","impliedFormat":1}],"root":[[2,5]],"options":{"declaration":true},"fileIdsList":[[3],[2]],"referencedMap":[[4,1],[3,2]],"semanticDiagnosticsPerFile":[1,3,5],"affectedFilesPendingEmit":[[4],2],"changeFileSet":[2]},"version":"FakeTSVersion"}

//// [/user/username/projects/myproject/tsconfig.tsbuildinfo.readable.baseline.txt]
{
Expand Down Expand Up @@ -373,16 +373,27 @@ Operation ws cancelled:: true
},
"semanticDiagnosticsPerFile": [
"../../../../a/lib/lib.d.ts",
"./a.ts",
"./b.ts",
"./d.ts"
],
"affectedFilesPendingEmit": [
sheetalkamat marked this conversation as resolved.
Show resolved Hide resolved
[
[
"./a.ts"
],
"Dts"
],
[
"./c.ts",
"Js | Dts"
]
],
"changeFileSet": [
"./c.ts"
]
},
"version": "FakeTSVersion",
"size": 1366
"size": 1399
}


Expand All @@ -407,8 +418,12 @@ Program files::

Semantic diagnostics in builder refreshed for::
/user/username/projects/myproject/c.ts
/user/username/projects/myproject/a.ts

No shapes updated in the builder::
Shape signatures in builder refreshed for::
/user/username/projects/myproject/c.ts (computed .d.ts)
/user/username/projects/myproject/b.ts (computed .d.ts)
/user/username/projects/myproject/a.ts (used version)

exitCode:: ExitStatus.undefined

Expand Down
Loading