mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-27 22:39:59 -05:00
Source of project reference behave as if those files cannot be emitted.
This commit is contained in:
@@ -472,6 +472,33 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function recursiveCreateDirectory(directoryPath: string, sys: System) {
|
||||
const basePath = getDirectoryPath(directoryPath);
|
||||
const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
if (shouldCreateParent) {
|
||||
recursiveCreateDirectory(basePath, sys);
|
||||
}
|
||||
if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* patch writefile to create folder before writing the file
|
||||
*/
|
||||
/*@internal*/
|
||||
export function patchWriteFileEnsuringDirectory(sys: System) {
|
||||
// patch writefile to create folder before writing the file
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys);
|
||||
}
|
||||
originalWriteFile.call(sys, path, data, writeBom);
|
||||
};
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
interface NodeBuffer extends Uint8Array {
|
||||
write(str: string, offset?: number, length?: number, encoding?: string): number;
|
||||
@@ -1259,17 +1286,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
function recursiveCreateDirectory(directoryPath: string, sys: System) {
|
||||
const basePath = getDirectoryPath(directoryPath);
|
||||
const shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath);
|
||||
if (shouldCreateParent) {
|
||||
recursiveCreateDirectory(basePath, sys);
|
||||
}
|
||||
if (shouldCreateParent || !sys.directoryExists(directoryPath)) {
|
||||
sys.createDirectory(directoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
let sys: System | undefined;
|
||||
if (typeof ChakraHost !== "undefined") {
|
||||
sys = getChakraSystem();
|
||||
@@ -1281,14 +1297,7 @@ namespace ts {
|
||||
}
|
||||
if (sys) {
|
||||
// patch writefile to create folder before writing the file
|
||||
const originalWriteFile = sys.writeFile;
|
||||
sys.writeFile = (path, data, writeBom) => {
|
||||
const directoryPath = getDirectoryPath(normalizeSlashes(path));
|
||||
if (directoryPath && !sys!.directoryExists(directoryPath)) {
|
||||
recursiveCreateDirectory(directoryPath, sys!);
|
||||
}
|
||||
originalWriteFile.call(sys, path, data, writeBom);
|
||||
};
|
||||
patchWriteFileEnsuringDirectory(sys);
|
||||
}
|
||||
return sys!;
|
||||
})();
|
||||
|
||||
@@ -66,6 +66,8 @@ interface Array<T> {}`
|
||||
params.newLine,
|
||||
params.useWindowsStylePaths,
|
||||
params.environmentVariables);
|
||||
// Just like sys, patch the host to use writeFile
|
||||
patchWriteFileEnsuringDirectory(host);
|
||||
return host;
|
||||
}
|
||||
|
||||
@@ -990,6 +992,19 @@ interface Array<T> {}`
|
||||
}
|
||||
}
|
||||
|
||||
export type TestServerHostTrackingWrittenFiles = TestServerHost & { writtenFiles: Map<true>; };
|
||||
|
||||
export function changeToHostTrackingWrittenFiles(inputHost: TestServerHost) {
|
||||
const host = inputHost as TestServerHostTrackingWrittenFiles;
|
||||
const originalWriteFile = host.writeFile;
|
||||
host.writtenFiles = createMap<true>();
|
||||
host.writeFile = (fileName, content) => {
|
||||
originalWriteFile.call(host, fileName, content);
|
||||
const path = host.toFullPath(fileName);
|
||||
host.writtenFiles.set(path, true);
|
||||
};
|
||||
return host;
|
||||
}
|
||||
export const tsbuildProjectsLocation = "/user/username/projects";
|
||||
export function getTsBuildProjectFilePath(project: string, file: string) {
|
||||
return `${tsbuildProjectsLocation}/${project}/${file}`;
|
||||
|
||||
@@ -537,8 +537,11 @@ namespace ts.server {
|
||||
return this.projectService.getSourceFileLike(fileName, this);
|
||||
}
|
||||
|
||||
private shouldEmitFile(scriptInfo: ScriptInfo) {
|
||||
return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent();
|
||||
/*@internal*/
|
||||
shouldEmitFile(scriptInfo: ScriptInfo | undefined) {
|
||||
return scriptInfo &&
|
||||
!scriptInfo.isDynamicOrHasMixedContent() &&
|
||||
!this.program!.isSourceOfProjectReferenceRedirect(scriptInfo.path);
|
||||
}
|
||||
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[] {
|
||||
@@ -548,7 +551,7 @@ namespace ts.server {
|
||||
updateProjectIfDirty(this);
|
||||
this.builderState = BuilderState.create(this.program!, this.projectService.toCanonicalFileName, this.builderState);
|
||||
return mapDefined(BuilderState.getFilesAffectedBy(this.builderState, this.program!, scriptInfo.path, this.cancellationToken, data => this.projectService.host.createHash!(data)), // TODO: GH#18217
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)!) ? sourceFile.fileName : undefined);
|
||||
sourceFile => this.shouldEmitFile(this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1030,7 +1030,9 @@ namespace ts.server {
|
||||
|
||||
private getEmitOutput(args: protocol.FileRequestArgs): EmitOutput {
|
||||
const { file, project } = this.getFileAndProject(args);
|
||||
return project.getLanguageService().getEmitOutput(file);
|
||||
return project.shouldEmitFile(project.getScriptInfo(file)) ?
|
||||
project.getLanguageService().getEmitOutput(file) :
|
||||
{ emitSkipped: true, outputFiles: [] };
|
||||
}
|
||||
|
||||
private mapDefinitionInfo(definitions: ReadonlyArray<DefinitionInfo>, project: Project): ReadonlyArray<protocol.FileSpanWithContext> {
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
"unittests/tsserver/occurences.ts",
|
||||
"unittests/tsserver/openFile.ts",
|
||||
"unittests/tsserver/projectErrors.ts",
|
||||
"unittests/tsserver/projectReferenceCompileOnSave.ts",
|
||||
"unittests/tsserver/projectReferenceErrors.ts",
|
||||
"unittests/tsserver/projectReferences.ts",
|
||||
"unittests/tsserver/projects.ts",
|
||||
|
||||
@@ -2,18 +2,12 @@ namespace ts.tscWatch {
|
||||
import projectsLocation = TestFSWithWatch.tsbuildProjectsLocation;
|
||||
import getFilePathInProject = TestFSWithWatch.getTsBuildProjectFilePath;
|
||||
import getFileFromProject = TestFSWithWatch.getTsBuildProjectFile;
|
||||
type TsBuildWatchSystem = WatchedSystem & { writtenFiles: Map<true>; };
|
||||
type TsBuildWatchSystem = TestFSWithWatch.TestServerHostTrackingWrittenFiles;
|
||||
|
||||
function createTsBuildWatchSystem(fileOrFolderList: ReadonlyArray<TestFSWithWatch.FileOrFolderOrSymLink>, params?: TestFSWithWatch.TestServerHostCreationParameters) {
|
||||
const host = createWatchedSystem(fileOrFolderList, params) as TsBuildWatchSystem;
|
||||
const originalWriteFile = host.writeFile;
|
||||
host.writtenFiles = createMap<true>();
|
||||
host.writeFile = (fileName, content) => {
|
||||
originalWriteFile.call(host, fileName, content);
|
||||
const path = host.toFullPath(fileName);
|
||||
host.writtenFiles.set(path, true);
|
||||
};
|
||||
return host;
|
||||
return TestFSWithWatch.changeToHostTrackingWrittenFiles(
|
||||
createWatchedSystem(fileOrFolderList, params)
|
||||
);
|
||||
}
|
||||
|
||||
export function createSolutionBuilder(system: WatchedSystem, rootNames: ReadonlyArray<string>, defaultOptions?: BuildOptions) {
|
||||
|
||||
@@ -498,7 +498,7 @@ namespace ts.projectSystem {
|
||||
return protocolToLocation(str)(start);
|
||||
}
|
||||
|
||||
function protocolToLocation(text: string): (pos: number) => protocol.Location {
|
||||
export function protocolToLocation(text: string): (pos: number) => protocol.Location {
|
||||
const lineStarts = computeLineStarts(text);
|
||||
return pos => {
|
||||
const x = computeLineAndCharacterOfPosition(lineStarts, pos);
|
||||
|
||||
@@ -0,0 +1,410 @@
|
||||
namespace ts.projectSystem {
|
||||
describe("unittests:: tsserver:: with project references and compile on save", () => {
|
||||
const projectLocation = "/user/username/projects/myproject";
|
||||
const dependecyLocation = `${projectLocation}/dependency`;
|
||||
const usageLocation = `${projectLocation}/usage`;
|
||||
const dependencyTs: File = {
|
||||
path: `${dependecyLocation}/fns.ts`,
|
||||
content: `export function fn1() { }
|
||||
export function fn2() { }
|
||||
`
|
||||
};
|
||||
const dependencyConfig: File = {
|
||||
path: `${dependecyLocation}/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compilerOptions: { composite: true, declarationDir: "../decls" },
|
||||
compileOnSave: true
|
||||
})
|
||||
};
|
||||
const usageTs: File = {
|
||||
path: `${usageLocation}/usage.ts`,
|
||||
content: `import {
|
||||
fn1,
|
||||
fn2,
|
||||
} from '../decls/fns'
|
||||
fn1();
|
||||
fn2();
|
||||
`
|
||||
};
|
||||
const usageConfig: File = {
|
||||
path: `${usageLocation}/tsconfig.json`,
|
||||
content: JSON.stringify({
|
||||
compileOnSave: true,
|
||||
references: [{ path: "../dependency" }]
|
||||
})
|
||||
};
|
||||
|
||||
interface VerifySingleScenarioWorker extends VerifySingleScenario {
|
||||
withProject: boolean;
|
||||
}
|
||||
function verifySingleScenarioWorker({
|
||||
withProject, scenario, openFiles, requestArgs, change, expectedResult
|
||||
}: VerifySingleScenarioWorker) {
|
||||
it(scenario, () => {
|
||||
const host = TestFSWithWatch.changeToHostTrackingWrittenFiles(
|
||||
createServerHost([dependencyTs, dependencyConfig, usageTs, usageConfig, libFile])
|
||||
);
|
||||
const session = createSession(host);
|
||||
openFilesForSession(openFiles(), session);
|
||||
const reqArgs = requestArgs();
|
||||
const {
|
||||
expectedAffected,
|
||||
expectedEmit: { expectedEmitSuccess, expectedFiles },
|
||||
expectedEmitOutput
|
||||
} = expectedResult(withProject);
|
||||
|
||||
if (change) {
|
||||
session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
|
||||
command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
|
||||
arguments: { file: dependencyTs.path }
|
||||
});
|
||||
const { file, insertString } = change();
|
||||
if (session.getProjectService().openFiles.has(file.path)) {
|
||||
const toLocation = protocolToLocation(file.content);
|
||||
const location = toLocation(file.content.length);
|
||||
session.executeCommandSeq<protocol.ChangeRequest>({
|
||||
command: protocol.CommandTypes.Change,
|
||||
arguments: {
|
||||
file: file.path,
|
||||
...location,
|
||||
endLine: location.line,
|
||||
endOffset: location.offset,
|
||||
insertString
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
host.writeFile(file.path, `${file.content}${insertString}`);
|
||||
}
|
||||
host.writtenFiles.clear();
|
||||
}
|
||||
|
||||
const args = withProject ? reqArgs : { file: reqArgs.file };
|
||||
// Verify CompileOnSaveAffectedFileList
|
||||
const actualAffectedFiles = session.executeCommandSeq<protocol.CompileOnSaveAffectedFileListRequest>({
|
||||
command: protocol.CommandTypes.CompileOnSaveAffectedFileList,
|
||||
arguments: args
|
||||
}).response as protocol.CompileOnSaveAffectedFileListSingleProject[];
|
||||
assert.deepEqual(actualAffectedFiles, expectedAffected, "Affected files");
|
||||
|
||||
// Verify CompileOnSaveEmit
|
||||
const actualEmit = session.executeCommandSeq<protocol.CompileOnSaveEmitFileRequest>({
|
||||
command: protocol.CommandTypes.CompileOnSaveEmitFile,
|
||||
arguments: args
|
||||
}).response;
|
||||
assert.deepEqual(actualEmit, expectedEmitSuccess, "Emit files");
|
||||
assert.equal(host.writtenFiles.size, expectedFiles.length);
|
||||
for (const file of expectedFiles) {
|
||||
assert.equal(host.readFile(file.path), file.content, `Expected to write ${file.path}`);
|
||||
assert.isTrue(host.writtenFiles.has(file.path), `${file.path} is newly written`);
|
||||
}
|
||||
|
||||
// Verify EmitOutput
|
||||
const { exportedModulesFromDeclarationEmit: _1, ...actualEmitOutput } = session.executeCommandSeq<protocol.EmitOutputRequest>({
|
||||
command: protocol.CommandTypes.EmitOutput,
|
||||
arguments: args
|
||||
}).response as EmitOutput;
|
||||
assert.deepEqual(actualEmitOutput, expectedEmitOutput, "Emit output");
|
||||
});
|
||||
}
|
||||
|
||||
interface VerifySingleScenario {
|
||||
scenario: string;
|
||||
openFiles: () => readonly File[];
|
||||
requestArgs: () => protocol.FileRequestArgs;
|
||||
skipWithoutProject?: boolean;
|
||||
change?: () => SingleScenarioChange;
|
||||
expectedResult: GetSingleScenarioResult;
|
||||
}
|
||||
function verifySingleScenario(scenario: VerifySingleScenario) {
|
||||
if (!scenario.skipWithoutProject) {
|
||||
describe("without specifying project file", () => {
|
||||
verifySingleScenarioWorker({
|
||||
withProject: false,
|
||||
...scenario
|
||||
});
|
||||
});
|
||||
}
|
||||
describe("with specifying project file", () => {
|
||||
verifySingleScenarioWorker({
|
||||
withProject: true,
|
||||
...scenario
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
interface SingleScenarioExpectedEmit {
|
||||
expectedEmitSuccess: boolean;
|
||||
expectedFiles: readonly File[];
|
||||
}
|
||||
interface SingleScenarioResult {
|
||||
expectedAffected: protocol.CompileOnSaveAffectedFileListSingleProject[];
|
||||
expectedEmit: SingleScenarioExpectedEmit;
|
||||
expectedEmitOutput: EmitOutput;
|
||||
}
|
||||
type GetSingleScenarioResult = (withProject: boolean) => SingleScenarioResult;
|
||||
interface SingleScenarioChange {
|
||||
file: File;
|
||||
insertString: string;
|
||||
}
|
||||
interface ScenarioDetails {
|
||||
scenarioName: string;
|
||||
requestArgs: () => protocol.FileRequestArgs;
|
||||
skipWithoutProject?: boolean;
|
||||
initial: GetSingleScenarioResult;
|
||||
localChangeToDependency: GetSingleScenarioResult;
|
||||
localChangeToUsage: GetSingleScenarioResult;
|
||||
changeToDependency: GetSingleScenarioResult;
|
||||
changeToUsage: GetSingleScenarioResult;
|
||||
}
|
||||
interface VerifyScenario {
|
||||
openFiles: () => readonly File[];
|
||||
scenarios: readonly ScenarioDetails[];
|
||||
}
|
||||
|
||||
const localChange = "function fn3() { }";
|
||||
const change = `export ${localChange}`;
|
||||
const changeJs = `function fn3() { }
|
||||
exports.fn3 = fn3;`;
|
||||
const changeDts = "export declare function fn3(): void;";
|
||||
function verifyScenario({ openFiles, scenarios }: VerifyScenario) {
|
||||
for (const {
|
||||
scenarioName, requestArgs, skipWithoutProject, initial,
|
||||
localChangeToDependency, localChangeToUsage,
|
||||
changeToDependency, changeToUsage
|
||||
} of scenarios) {
|
||||
describe(scenarioName, () => {
|
||||
verifySingleScenario({
|
||||
scenario: "with initial file open",
|
||||
openFiles,
|
||||
requestArgs,
|
||||
skipWithoutProject,
|
||||
expectedResult: initial
|
||||
});
|
||||
|
||||
verifySingleScenario({
|
||||
scenario: "with local change to dependency",
|
||||
openFiles,
|
||||
requestArgs,
|
||||
skipWithoutProject,
|
||||
change: () => ({ file: dependencyTs, insertString: localChange }),
|
||||
expectedResult: localChangeToDependency
|
||||
});
|
||||
|
||||
verifySingleScenario({
|
||||
scenario: "with local change to usage",
|
||||
openFiles,
|
||||
requestArgs,
|
||||
skipWithoutProject,
|
||||
change: () => ({ file: usageTs, insertString: localChange }),
|
||||
expectedResult: localChangeToUsage
|
||||
});
|
||||
|
||||
verifySingleScenario({
|
||||
scenario: "with change to dependency",
|
||||
openFiles,
|
||||
requestArgs,
|
||||
skipWithoutProject,
|
||||
change: () => ({ file: dependencyTs, insertString: change }),
|
||||
expectedResult: changeToDependency
|
||||
});
|
||||
|
||||
verifySingleScenario({
|
||||
scenario: "with change to usage",
|
||||
openFiles,
|
||||
requestArgs,
|
||||
skipWithoutProject,
|
||||
change: () => ({ file: usageTs, insertString: change }),
|
||||
expectedResult: changeToUsage
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function expectedAffectedFiles(config: File, fileNames: File[]): protocol.CompileOnSaveAffectedFileListSingleProject {
|
||||
return {
|
||||
projectFileName: config.path,
|
||||
fileNames: fileNames.map(f => f.path),
|
||||
projectUsesOutFile: false
|
||||
};
|
||||
}
|
||||
|
||||
function expectedUsageEmit(appendJsText?: string): SingleScenarioExpectedEmit {
|
||||
const appendJs = appendJsText ? `${appendJsText}
|
||||
` : "";
|
||||
return {
|
||||
expectedEmitSuccess: true,
|
||||
expectedFiles: [{
|
||||
path: `${usageLocation}/usage.js`,
|
||||
content: `"use strict";
|
||||
exports.__esModule = true;
|
||||
var fns_1 = require("../decls/fns");
|
||||
fns_1.fn1();
|
||||
fns_1.fn2();
|
||||
${appendJs}`
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
function expectedEmitOutput({ expectedFiles }: SingleScenarioExpectedEmit): EmitOutput {
|
||||
return {
|
||||
outputFiles: expectedFiles.map(({ path, content }) => ({
|
||||
name: path,
|
||||
text: content,
|
||||
writeByteOrderMark: false
|
||||
})),
|
||||
emitSkipped: false
|
||||
};
|
||||
}
|
||||
|
||||
function expectedUsageEmitOutput(appendJsText?: string): EmitOutput {
|
||||
return expectedEmitOutput(expectedUsageEmit(appendJsText));
|
||||
}
|
||||
|
||||
function noEmit(): SingleScenarioExpectedEmit {
|
||||
return {
|
||||
expectedEmitSuccess: false,
|
||||
expectedFiles: emptyArray
|
||||
};
|
||||
}
|
||||
|
||||
function noEmitOutput(): EmitOutput {
|
||||
return {
|
||||
emitSkipped: true,
|
||||
outputFiles: []
|
||||
};
|
||||
}
|
||||
|
||||
function expectedDependencyEmit(appendJsText?: string, appendDtsText?: string): SingleScenarioExpectedEmit {
|
||||
const appendJs = appendJsText ? `${appendJsText}
|
||||
` : "";
|
||||
const appendDts = appendDtsText ? `${appendDtsText}
|
||||
` : "";
|
||||
return {
|
||||
expectedEmitSuccess: true,
|
||||
expectedFiles: [
|
||||
{
|
||||
path: `${dependecyLocation}/fns.js`,
|
||||
content: `"use strict";
|
||||
exports.__esModule = true;
|
||||
function fn1() { }
|
||||
exports.fn1 = fn1;
|
||||
function fn2() { }
|
||||
exports.fn2 = fn2;
|
||||
${appendJs}`
|
||||
},
|
||||
{
|
||||
path: `${projectLocation}/decls/fns.d.ts`,
|
||||
content: `export declare function fn1(): void;
|
||||
export declare function fn2(): void;
|
||||
${appendDts}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
function expectedDependencyEmitOutput(appendJsText?: string, appendDtsText?: string): EmitOutput {
|
||||
return expectedEmitOutput(expectedDependencyEmit(appendJsText, appendDtsText));
|
||||
}
|
||||
|
||||
function scenarioDetailsOfUsage(isDependencyOpen?: boolean): ScenarioDetails[] {
|
||||
return [
|
||||
{
|
||||
scenarioName: "Of usageTs",
|
||||
requestArgs: () => ({ file: usageTs.path, projectFileName: usageConfig.path }),
|
||||
initial: () => initialUsageTs(),
|
||||
// no change to usage so same as initial only usage file
|
||||
localChangeToDependency: () => initialUsageTs(),
|
||||
localChangeToUsage: () => initialUsageTs(localChange),
|
||||
changeToDependency: () => initialUsageTs(),
|
||||
changeToUsage: () => initialUsageTs(changeJs)
|
||||
},
|
||||
{
|
||||
scenarioName: "Of dependencyTs in usage project",
|
||||
requestArgs: () => ({ file: dependencyTs.path, projectFileName: usageConfig.path }),
|
||||
skipWithoutProject: !!isDependencyOpen,
|
||||
initial: () => initialDependencyTs(),
|
||||
localChangeToDependency: () => initialDependencyTs(/*noUsageFiles*/ true),
|
||||
localChangeToUsage: () => initialDependencyTs(/*noUsageFiles*/ true),
|
||||
changeToDependency: () => initialDependencyTs(),
|
||||
changeToUsage: () => initialDependencyTs(/*noUsageFiles*/ true)
|
||||
}
|
||||
];
|
||||
|
||||
function initialUsageTs(jsText?: string) {
|
||||
return {
|
||||
expectedAffected: [
|
||||
expectedAffectedFiles(usageConfig, [usageTs])
|
||||
],
|
||||
expectedEmit: expectedUsageEmit(jsText),
|
||||
expectedEmitOutput: expectedUsageEmitOutput(jsText)
|
||||
};
|
||||
}
|
||||
|
||||
function initialDependencyTs(noUsageFiles?: true) {
|
||||
return {
|
||||
expectedAffected: [
|
||||
expectedAffectedFiles(usageConfig, noUsageFiles ? [] : [usageTs])
|
||||
],
|
||||
expectedEmit: noEmit(),
|
||||
expectedEmitOutput: noEmitOutput()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function scenarioDetailsOfDependencyWhenOpen(): ScenarioDetails {
|
||||
return {
|
||||
scenarioName: "Of dependencyTs",
|
||||
requestArgs: () => ({ file: dependencyTs.path, projectFileName: dependencyConfig.path }),
|
||||
initial,
|
||||
localChangeToDependency: withProject => ({
|
||||
expectedAffected: withProject ?
|
||||
[
|
||||
expectedAffectedFiles(dependencyConfig, [dependencyTs])
|
||||
] :
|
||||
[
|
||||
expectedAffectedFiles(usageConfig, []),
|
||||
expectedAffectedFiles(dependencyConfig, [dependencyTs])
|
||||
],
|
||||
expectedEmit: expectedDependencyEmit(localChange),
|
||||
expectedEmitOutput: expectedDependencyEmitOutput(localChange)
|
||||
}),
|
||||
localChangeToUsage: withProject => initial(withProject, /*noUsageFiles*/ true),
|
||||
changeToDependency: withProject => initial(withProject, /*noUsageFiles*/ undefined, changeJs, changeDts),
|
||||
changeToUsage: withProject => initial(withProject, /*noUsageFiles*/ true)
|
||||
};
|
||||
|
||||
function initial(withProject: boolean, noUsageFiles?: true, appendJs?: string, appendDts?: string): SingleScenarioResult {
|
||||
return {
|
||||
expectedAffected: withProject ?
|
||||
[
|
||||
expectedAffectedFiles(dependencyConfig, [dependencyTs])
|
||||
] :
|
||||
[
|
||||
expectedAffectedFiles(usageConfig, noUsageFiles ? [] : [usageTs]),
|
||||
expectedAffectedFiles(dependencyConfig, [dependencyTs])
|
||||
],
|
||||
expectedEmit: expectedDependencyEmit(appendJs, appendDts),
|
||||
expectedEmitOutput: expectedDependencyEmitOutput(appendJs, appendDts)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
describe("when dependency project is not open", () => {
|
||||
verifyScenario({
|
||||
openFiles: () => [usageTs],
|
||||
scenarios: scenarioDetailsOfUsage()
|
||||
});
|
||||
});
|
||||
|
||||
describe("when the depedency file is open", () => {
|
||||
verifyScenario({
|
||||
openFiles: () => [usageTs, dependencyTs],
|
||||
scenarios: [
|
||||
...scenarioDetailsOfUsage(/*isDependencyOpen*/ true),
|
||||
scenarioDetailsOfDependencyWhenOpen(),
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -8463,7 +8463,6 @@ declare namespace ts.server {
|
||||
getGlobalProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getAllProjectErrors(): ReadonlyArray<Diagnostic>;
|
||||
getLanguageService(ensureSynchronized?: boolean): LanguageService;
|
||||
private shouldEmitFile;
|
||||
getCompileOnSaveAffectedFileList(scriptInfo: ScriptInfo): string[];
|
||||
/**
|
||||
* Returns true if emit was conducted
|
||||
|
||||
Reference in New Issue
Block a user