Merge pull request #25102 from Microsoft/declarationEmitWithNoEmitAndWatch

Mark the declarations visible correctly when emit is disabled but asked to emit declarations for watch mode
This commit is contained in:
Sheetal Nandi 2018-06-20 16:04:57 -07:00 committed by GitHub
commit 3eeb36bd22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 3 deletions

View file

@ -192,6 +192,11 @@ namespace ts {
// Setup and perform the transformation to retrieve declarations from the input files
const nonJsFiles = filter(sourceFiles, isSourceFileNotJavaScript);
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
if (emitOnlyDtsFiles && !compilerOptions.declaration) {
// Checker wont collect the linked aliases since thats only done when declaration is enabled.
// Do that here when emitting only dts files
nonJsFiles.forEach(collectLinkedAliases);
}
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false);
if (length(declarationTransform.diagnostics)) {
for (const diagnostic of declarationTransform.diagnostics!) {
@ -221,6 +226,20 @@ namespace ts {
declarationTransform.dispose();
}
function collectLinkedAliases(node: Node) {
if (isExportAssignment(node)) {
if (node.expression.kind === SyntaxKind.Identifier) {
resolver.collectLinkedAliases(node.expression as Identifier, /*setVisibility*/ true);
}
return;
}
else if (isExportSpecifier(node)) {
resolver.collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true);
return;
}
forEachChild(node, collectLinkedAliases);
}
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, bundleInfoPath: string | undefined, printer: Printer, mapRecorder: SourceMapWriter) {
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined;

View file

@ -3331,7 +3331,7 @@ namespace ts {
getNodeCheckFlags(node: Node): NodeCheckFlags;
isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean;
isLateBound(node: Declaration): node is LateBoundDeclaration;
collectLinkedAliases(node: Identifier): Node[] | undefined;
collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined;
isImplementationOfOverload(node: FunctionLike): boolean | undefined;
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;

View file

@ -571,7 +571,9 @@ interface Array<T> {}`
}
private addFileOrFolderInFolder(folder: FsFolder, fileOrDirectory: FsFile | FsFolder | FsSymLink, ignoreWatch?: boolean) {
insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path)));
if (!this.fs.has(fileOrDirectory.path)) {
insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path)));
}
folder.modifiedTime = this.now();
this.fs.set(fileOrDirectory.path, fileOrDirectory);

View file

@ -1218,6 +1218,58 @@ namespace ts.tscWatch {
checkWatchedFiles(host, files.map(f => f.path));
}
});
it("updates errors correctly when declaration emit is disabled in compiler options", () => {
const currentDirectory = "/user/username/projects/myproject";
const aFile: File = {
path: `${currentDirectory}/a.ts`,
content: `import test from './b';
test(4, 5);`
};
const bFileContent = `function test(x: number, y: number) {
return x + y / 5;
}
export default test;`;
const bFile: File = {
path: `${currentDirectory}/b.ts`,
content: bFileContent
};
const tsconfigFile: File = {
path: `${currentDirectory}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: {
module: "commonjs",
noEmit: true,
strict: true,
}
})
};
const files = [aFile, bFile, libFile, tsconfigFile];
const host = createWatchedSystem(files, { currentDirectory });
const watch = createWatchOfConfigFile("tsconfig.json", host);
checkOutputErrorsInitial(host, emptyArray);
changeParameterType("x", "string", [
getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("4"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "4", "string")
]);
changeParameterType("y", "string", [
getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.indexOf("5"), 1, Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1, "5", "string"),
getDiagnosticOfFileFromProgram(watch(), bFile.path, bFile.content.indexOf("y /"), 1, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type)
]);
function changeParameterType(parameterName: string, toType: string, expectedErrors: ReadonlyArray<Diagnostic>) {
const newContent = bFileContent.replace(new RegExp(`${parameterName}\: [a-z]*`), `${parameterName}: ${toType}`);
verifyErrorsWithBFileContents(newContent, expectedErrors);
verifyErrorsWithBFileContents(bFileContent, emptyArray);
}
function verifyErrorsWithBFileContents(content: string, expectedErrors: ReadonlyArray<Diagnostic>) {
host.writeFile(bFile.path, content);
host.runQueuedTimeoutCallbacks();
checkOutputErrorsIncremental(host, expectedErrors);
}
});
});
describe("tsc-watch emit with outFile or out setting", () => {

View file

@ -2915,7 +2915,7 @@ declare namespace ts {
getNodeCheckFlags(node: Node): NodeCheckFlags;
isDeclarationVisible(node: Declaration | AnyImportSyntax): boolean;
isLateBound(node: Declaration): node is LateBoundDeclaration;
collectLinkedAliases(node: Identifier): Node[] | undefined;
collectLinkedAliases(node: Identifier, setVisibility?: boolean): Node[] | undefined;
isImplementationOfOverload(node: FunctionLike): boolean | undefined;
isRequiredInitializedParameter(node: ParameterDeclaration): boolean;
isOptionalUninitializedParameterProperty(node: ParameterDeclaration): boolean;