Skip to content
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
2 changes: 1 addition & 1 deletion src/compiler/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1134,7 +1134,7 @@ namespace ts {
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string): boolean {
const resolutionToFile = getResolvedModule(oldSourceFile!, moduleName);
const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName);
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
if (resolutionToFile && resolvedFile) {
// In the old program, we resolved to an ambient module that was in the same
// place as we expected to find an actual module file.
// We actually need to return 'false' here even though this seems like a 'true' case
Expand Down
3 changes: 3 additions & 0 deletions src/server/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,9 @@ namespace ts.server {
);
const elapsed = timestamp() - start;
this.writeLog(`Finishing updateGraphWorker: Project: ${this.getProjectName()} Version: ${this.getProjectVersion()} structureChanged: ${hasNewProgram} Elapsed: ${elapsed}ms`);
if (this.program !== oldProgram) {
this.print();
}
return hasNewProgram;
}

Expand Down
84 changes: 84 additions & 0 deletions src/testRunner/unittests/tsserver/projectErrors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,90 @@ namespace ts.projectSystem {
session.clearMessages();
}
});

it("Correct errors when resolution resolves to file that has same ambient module and is also module", () => {
const projectRootPath = "/users/username/projects/myproject";
const aFile: File = {
path: `${projectRootPath}/src/a.ts`,
content: `import * as myModule from "@custom/plugin";
function foo() {
// hello
}`
};
const config: File = {
path: `${projectRootPath}/tsconfig.json`,
content: JSON.stringify({ include: ["src"] })
};
const plugin: File = {
path: `${projectRootPath}/node_modules/@custom/plugin/index.d.ts`,
content: `import './proposed';
declare module '@custom/plugin' {
export const version: string;
}`
};
const pluginProposed: File = {
path: `${projectRootPath}/node_modules/@custom/plugin/proposed.d.ts`,
content: `declare module '@custom/plugin' {
export const bar = 10;
}`
};
const files = [libFile, aFile, config, plugin, pluginProposed];
const host = createServerHost(files);
const session = createSession(host, { canUseEvents: true });
const service = session.getProjectService();
openFilesForSession([aFile], session);

checkNumberOfProjects(service, { configuredProjects: 1 });
session.clearMessages();
checkErrors();

session.executeCommandSeq<protocol.ChangeRequest>({
command: protocol.CommandTypes.Change,
arguments: {
file: aFile.path,
line: 3,
offset: 8,
endLine: 3,
endOffset: 8,
insertString: "o"
}
});
checkErrors();

function checkErrors() {
host.checkTimeoutQueueLength(0);
const expectedSequenceId = session.getNextSeq();
session.executeCommandSeq<protocol.GeterrRequest>({
command: server.CommandNames.Geterr,
arguments: {
delay: 0,
files: [aFile.path],
}
});

host.checkTimeoutQueueLengthAndRun(1);

checkErrorMessage(session, "syntaxDiag", { file: aFile.path, diagnostics: [] }, /*isMostRecent*/ true);
session.clearMessages();

host.runQueuedImmediateCallbacks(1);

checkErrorMessage(session, "semanticDiag", { file: aFile.path, diagnostics: [] });
session.clearMessages();

host.runQueuedImmediateCallbacks(1);

checkErrorMessage(session, "suggestionDiag", {
file: aFile.path,
diagnostics: [
createDiagnostic({ line: 1, offset: 1 }, { line: 1, offset: 44 }, Diagnostics._0_is_declared_but_its_value_is_never_read, ["myModule"], "suggestion", /*reportsUnnecessary*/ true),
createDiagnostic({ line: 2, offset: 10 }, { line: 2, offset: 13 }, Diagnostics._0_is_declared_but_its_value_is_never_read, ["foo"], "suggestion", /*reportsUnnecessary*/ true)
],
});
checkCompleteEvent(session, 2, expectedSequenceId);
session.clearMessages();
}
});
});

describe("unittests:: tsserver:: Project Errors for Configure file diagnostics events", () => {
Expand Down