Skip to content

Add assumeChangesOnlyAffectDirectDependencies as a option to skip checking and generating .d.ts files for files indirectly importing affected file #35711

New issue

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

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

Already on GitHub? # to your account

Merged
merged 6 commits into from
Jan 3, 2020
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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/compiler/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ namespace ts {
return;
}

forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, (state, path) => handleDtsMayChangeOf(state, path, cancellationToken, computeHash));
if (!state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To someone unfamiliar with the builder, it's not clear how adding this simple check does what it says in the description. Where are the direct dependencies handled if not in the call below? At what point is the list expanded to include indirect dependencies?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getAffectedFiles handle the direct dependency and the below function handles indirect ones.

forEachReferencingModulesOfExportOfAffectedFile(state, affectedFile, (state, path) => handleDtsMayChangeOf(state, path, cancellationToken, computeHash));
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions src/compiler/commandLineParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ namespace ts {
description: Diagnostics.Enable_incremental_compilation,
transpileOptionValue: undefined
},
{
name: "assumeChangesOnlyAffectDirectDependencies",
type: "boolean",
affectsSemanticDiagnostics: true,
affectsEmit: true,
category: Diagnostics.Advanced_Options,
description: Diagnostics.Have_recompiles_in_incremental_and_watch_assume_that_changes_within_a_file_will_only_affect_files_directly_depending_on_it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is probably a very ignorant question, but does this apply only within projects or across projects as well? Clearly we can't get everything into the name, but it might be nice to provide more details in the description (or in a a comment, if we'd prefer to keep the switch mysterious and little-used).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Builder is not used across projects but within single program.

},
{
name: "locale",
type: "string",
Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -4366,6 +4366,10 @@
"category": "Message",
"code": 6383
},
"Have recompiles in '--incremental' and '--watch' assume that changes within a file will only affect files directly depending on it.": {
"category": "Message",
"code": 6384
},

"The expected type comes from property '{0}' which is declared here on type '{1}'": {
"category": "Message",
Expand Down
1 change: 1 addition & 0 deletions src/compiler/tsbuildPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace ts {
/*@internal*/ listFiles?: boolean;
/*@internal*/ pretty?: boolean;
incremental?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;

traceResolution?: boolean;
/* @internal */ diagnostics?: boolean;
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5070,6 +5070,7 @@ namespace ts {
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;
noLib?: boolean;
noResolve?: boolean;
out?: string;
Expand Down
12 changes: 12 additions & 0 deletions src/testRunner/unittests/tscWatch/emitAndErrorUpdates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ namespace ts.tscWatch {
subScenario: `config with --isolatedModules and --declaration/${input.subScenario}`,
configFile: () => changeCompilerOptions(input, { isolatedModules: true, declaration: true })
});

verifyEmitAndErrorUpdatesWorker({
...input,
subScenario: `config with --assumeChangesOnlyAffectDirectDependencies/${input.subScenario}`,
configFile: () => changeCompilerOptions(input, { assumeChangesOnlyAffectDirectDependencies: true })
});

verifyEmitAndErrorUpdatesWorker({
...input,
subScenario: `config with --assumeChangesOnlyAffectDirectDependencies and --declaration/${input.subScenario}`,
configFile: () => changeCompilerOptions(input, { assumeChangesOnlyAffectDirectDependencies: true, declaration: true })
});
}

describe("deep import changes", () => {
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,7 @@ declare namespace ts {
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;
noLib?: boolean;
noResolve?: boolean;
out?: string;
Expand Down Expand Up @@ -4779,6 +4780,7 @@ declare namespace ts {
force?: boolean;
verbose?: boolean;
incremental?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;
traceResolution?: boolean;
[option: string]: CompilerOptionsValue | undefined;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2673,6 +2673,7 @@ declare namespace ts {
noUnusedLocals?: boolean;
noUnusedParameters?: boolean;
noImplicitUseStrict?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;
noLib?: boolean;
noResolve?: boolean;
out?: string;
Expand Down Expand Up @@ -4779,6 +4780,7 @@ declare namespace ts {
force?: boolean;
verbose?: boolean;
incremental?: boolean;
assumeChangesOnlyAffectDirectDependencies?: boolean;
traceResolution?: boolean;
[option: string]: CompilerOptionsValue | undefined;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"assumeChangesOnlyAffectDirectDependencies": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/a/lib/tsc.js --w
//// [/user/username/projects/myproject/a.ts]
import {B} from './b';
declare var console: any;
let b = new B();
console.log(b.c.d);

//// [/user/username/projects/myproject/b.ts]
import {C} from './c';
export class B
{
c = new C();
}

//// [/user/username/projects/myproject/c.ts]
export class C
{
d = 1;
}

//// [/user/username/projects/myproject/tsconfig.json]
{"compilerOptions":{"assumeChangesOnlyAffectDirectDependencies":true,"declaration":true}}

//// [/a/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }

//// [/user/username/projects/myproject/c.js]
"use strict";
exports.__esModule = true;
var C = /** @class */ (function () {
function C() {
this.d = 1;
}
return C;
}());
exports.C = C;


//// [/user/username/projects/myproject/c.d.ts]
export declare class C {
d: number;
}


//// [/user/username/projects/myproject/b.js]
"use strict";
exports.__esModule = true;
var c_1 = require("./c");
var B = /** @class */ (function () {
function B() {
this.c = new c_1.C();
}
return B;
}());
exports.B = B;


//// [/user/username/projects/myproject/b.d.ts]
import { C } from './c';
export declare class B {
c: C;
}


//// [/user/username/projects/myproject/a.js]
"use strict";
exports.__esModule = true;
var b_1 = require("./b");
var b = new b_1.B();
console.log(b.c.d);


//// [/user/username/projects/myproject/a.d.ts]
export {};



Output::
>> Screen clear
12:00:25 AM - Starting compilation in watch mode...



12:00:38 AM - Found 0 errors. Watching for file changes.


Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts","/user/username/projects/myproject/c.ts"]
Program options: {"assumeChangesOnlyAffectDirectDependencies":true,"declaration":true,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/c.ts
/user/username/projects/myproject/b.ts
/user/username/projects/myproject/a.ts

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

WatchedFiles::
/user/username/projects/myproject/tsconfig.json:
{"pollingInterval":250}
/user/username/projects/myproject/a.ts:
{"pollingInterval":250}
/user/username/projects/myproject/b.ts:
{"pollingInterval":250}
/user/username/projects/myproject/c.ts:
{"pollingInterval":250}
/a/lib/lib.d.ts:
{"pollingInterval":250}

FsWatches::

FsWatchesRecursive::
/user/username/projects/myproject/node_modules/@types:
{"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
/user/username/projects/myproject:
{"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}

exitCode:: ExitStatus.undefined

Change:: Rename property d to d2 of class C

//// [/user/username/projects/myproject/c.ts]
export class C
{
d2 = 1;
}

//// [/user/username/projects/myproject/c.js]
"use strict";
exports.__esModule = true;
var C = /** @class */ (function () {
function C() {
this.d2 = 1;
}
return C;
}());
exports.C = C;


//// [/user/username/projects/myproject/c.d.ts]
export declare class C {
d2: number;
}


//// [/user/username/projects/myproject/b.js] file written with same contents
//// [/user/username/projects/myproject/b.d.ts] file written with same contents

Output::
>> Screen clear
12:00:42 AM - File change detected. Starting incremental compilation...



12:00:55 AM - Found 0 errors. Watching for file changes.


Program root files: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts","/user/username/projects/myproject/c.ts"]
Program options: {"assumeChangesOnlyAffectDirectDependencies":true,"declaration":true,"watch":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/c.ts
/user/username/projects/myproject/b.ts
/user/username/projects/myproject/a.ts

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

WatchedFiles::
/user/username/projects/myproject/tsconfig.json:
{"pollingInterval":250}
/user/username/projects/myproject/a.ts:
{"pollingInterval":250}
/user/username/projects/myproject/b.ts:
{"pollingInterval":250}
/user/username/projects/myproject/c.ts:
{"pollingInterval":250}
/a/lib/lib.d.ts:
{"pollingInterval":250}

FsWatches::

FsWatchesRecursive::
/user/username/projects/myproject/node_modules/@types:
{"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}
/user/username/projects/myproject:
{"fallbackPollingInterval":500,"fallbackOptions":{"watchFile":"PriorityPollingInterval"}}

exitCode:: ExitStatus.undefined
Loading