Let builder find out from imports/typereference directives if file references have changed.

This is needed to ensure that the ambient module addition takes effect
Fixes #15632
This commit is contained in:
Sheetal Nandi 2017-10-04 17:29:06 -07:00
parent 8b2a219dd4
commit bf4ca30bc3
4 changed files with 146 additions and 8 deletions

View File

@ -77,8 +77,8 @@ namespace ts {
*/
onUpdateSourceFile(program: Program, sourceFile: SourceFile): void;
/**
* Called when source file has not changed but has some of the resolutions invalidated
* If returned true, builder will mark the file as changed (noting that something associated with file has changed)
* Called when source file has not changed
* If returned true, builder will mark the file as changed (noting that something associated with file has changed eg. module resolution)
*/
onUpdateSourceFileWithSameVersion(program: Program, sourceFile: SourceFile): boolean;
/**
@ -161,8 +161,7 @@ namespace ts {
existingInfo.version = sourceFile.version;
emitHandler.onUpdateSourceFile(program, sourceFile);
}
else if (program.hasInvalidatedResolution(sourceFile.path) &&
emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) {
registerChangedFile(sourceFile.path, sourceFile.fileName);
}
}

View File

@ -663,8 +663,7 @@ namespace ts {
dropDiagnosticsProducingTypeChecker,
getSourceFileFromReference,
sourceFileToPackageName,
redirectTargetsSet,
hasInvalidatedResolution
redirectTargetsSet
};
verifyCompilerOptions();

View File

@ -2525,8 +2525,6 @@ namespace ts {
/* @internal */ sourceFileToPackageName: Map<string>;
/** Set of all source files that some other source file redirects to. */
/* @internal */ redirectTargetsSet: Map<true>;
/** Returns true when file in the program had invalidated resolution at the time of program creation. */
/* @internal */ hasInvalidatedResolution: HasInvalidatedResolution;
}
/* @internal */

View File

@ -1655,5 +1655,147 @@ namespace ts.tscWatch {
assert.isTrue(fileExistsCalledForBar, "'fileExists' should be called.");
checkOutputDoesNotContain(host, [barNotFound]);
});
it("works when module resolution changes to ambient module", () => {
const root = {
path: "/a/b/foo.ts",
content: `import * as fs from "fs";`
};
const packageJson = {
path: "/a/b/node_modules/@types/node/package.json",
content: `
{
"main": ""
}
`
};
const nodeType = {
path: "/a/b/node_modules/@types/node/index.d.ts",
content: `
declare module "fs" {
export interface Stats {
isFile(): boolean;
isDirectory(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
dev: number;
ino: number;
mode: number;
nlink: number;
uid: number;
gid: number;
rdev: number;
size: number;
blksize: number;
blocks: number;
atimeMs: number;
mtimeMs: number;
ctimeMs: number;
birthtimeMs: number;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
}
}`
};
const files = [root, libFile];
const filesWithNodeType = files.concat(packageJson, nodeType);
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
createWatchModeWithoutConfigFile([root.path], host, { });
const fsNotFound = `foo.ts(1,21): error TS2307: Cannot find module 'fs'.\n`;
checkOutputContains(host, [fsNotFound]);
host.clearOutput();
host.reloadFS(filesWithNodeType);
host.runQueuedTimeoutCallbacks();
checkOutputDoesNotContain(host, [fsNotFound]);
});
it("works when included file with ambient module changes", () => {
const root = {
path: "/a/b/foo.ts",
content: `
import * as fs from "fs";
import * as u from "url";
`
};
const file = {
path: "/a/b/bar.d.ts",
content: `
declare module "url" {
export interface Url {
href?: string;
protocol?: string;
auth?: string;
hostname?: string;
port?: string;
host?: string;
pathname?: string;
search?: string;
query?: string | any;
slashes?: boolean;
hash?: string;
path?: string;
}
}
`
};
const fileContentWithFS = `
declare module "fs" {
export interface Stats {
isFile(): boolean;
isDirectory(): boolean;
isBlockDevice(): boolean;
isCharacterDevice(): boolean;
isSymbolicLink(): boolean;
isFIFO(): boolean;
isSocket(): boolean;
dev: number;
ino: number;
mode: number;
nlink: number;
uid: number;
gid: number;
rdev: number;
size: number;
blksize: number;
blocks: number;
atimeMs: number;
mtimeMs: number;
ctimeMs: number;
birthtimeMs: number;
atime: Date;
mtime: Date;
ctime: Date;
birthtime: Date;
}
}
`;
const files = [root, file, libFile];
const host = createWatchedSystem(files, { currentDirectory: "/a/b" });
createWatchModeWithoutConfigFile([root.path, file.path], host, {});
const fsNotFound = `foo.ts(2,21): error TS2307: Cannot find module 'fs'.\n`;
checkOutputContains(host, [fsNotFound]);
host.clearOutput();
file.content += fileContentWithFS;
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
checkOutputDoesNotContain(host, [fsNotFound]);
});
});
}