mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
Improve robustness of lib builder.
This commit is contained in:
parent
2cf3a89f63
commit
765f229357
7 changed files with 102 additions and 12 deletions
|
@ -75,14 +75,24 @@ export function checkDiagnostics(project: Project, onlyFor?: string[]) {
|
|||
})
|
||||
.map(diagnostic => diagnostic.compilerObject);
|
||||
|
||||
logDiagnostics(diagnostics);
|
||||
|
||||
if (diagnostics.length) {
|
||||
console.log(
|
||||
ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticHost)
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function createDeclarationError(
|
||||
msg: string,
|
||||
declaration: ImportDeclaration | ExportDeclaration
|
||||
): Error {
|
||||
return new Error(
|
||||
`${msg}\n` +
|
||||
` In: "${declaration.getSourceFile().getFilePath()}"\n` +
|
||||
` Text: "${declaration.getText()}"`
|
||||
);
|
||||
}
|
||||
|
||||
export interface FlattenNamespaceOptions {
|
||||
customSources?: { [sourceFilePath: string]: string };
|
||||
debug?: boolean;
|
||||
|
@ -151,7 +161,12 @@ export function flattenNamespace({
|
|||
}
|
||||
|
||||
sourceFile.getExportDeclarations().forEach(exportDeclaration => {
|
||||
processSourceFile(exportDeclaration.getModuleSpecifierSourceFileOrThrow());
|
||||
const exportedSourceFile = exportDeclaration.getModuleSpecifierSourceFile();
|
||||
if (exportedSourceFile) {
|
||||
processSourceFile(exportedSourceFile);
|
||||
} else {
|
||||
throw createDeclarationError("Missing source file.", exportDeclaration);
|
||||
}
|
||||
exportDeclaration.remove();
|
||||
});
|
||||
|
||||
|
@ -254,9 +269,19 @@ export function loadFiles(project: Project, filePaths: string[]) {
|
|||
}
|
||||
}
|
||||
|
||||
/** Log diagnostics to the console with colour. */
|
||||
export function logDiagnostics(diagnostics: ts.Diagnostic[]): void {
|
||||
if (diagnostics.length) {
|
||||
console.log(
|
||||
ts.formatDiagnosticsWithColorAndContext(diagnostics, formatDiagnosticHost)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export interface NamespaceSourceFileOptions {
|
||||
debug?: boolean;
|
||||
namespace?: string;
|
||||
namespaces: Set<string>;
|
||||
rootPath: string;
|
||||
sourceFileMap: Map<SourceFile, string>;
|
||||
}
|
||||
|
@ -267,7 +292,13 @@ export interface NamespaceSourceFileOptions {
|
|||
*/
|
||||
export function namespaceSourceFile(
|
||||
sourceFile: SourceFile,
|
||||
{ debug, namespace, rootPath, sourceFileMap }: NamespaceSourceFileOptions
|
||||
{
|
||||
debug,
|
||||
namespace,
|
||||
namespaces,
|
||||
rootPath,
|
||||
sourceFileMap
|
||||
}: NamespaceSourceFileOptions
|
||||
): string {
|
||||
if (sourceFileMap.has(sourceFile)) {
|
||||
return "";
|
||||
|
@ -300,22 +331,42 @@ export function namespaceSourceFile(
|
|||
|
||||
const output = sourceFile
|
||||
.getImportDeclarations()
|
||||
.filter(declaration => {
|
||||
const dsf = declaration.getModuleSpecifierSourceFile();
|
||||
if (dsf == null) {
|
||||
try {
|
||||
const namespaceName = declaration
|
||||
.getNamespaceImportOrThrow()
|
||||
.getText();
|
||||
if (!namespaces.has(namespaceName)) {
|
||||
throw createDeclarationError(
|
||||
"Already defined source file under different namespace.",
|
||||
declaration
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
throw createDeclarationError(
|
||||
"Unsupported import clause.",
|
||||
declaration
|
||||
);
|
||||
}
|
||||
declaration.remove();
|
||||
}
|
||||
return dsf;
|
||||
})
|
||||
.map(declaration => {
|
||||
if (
|
||||
declaration.getNamedImports().length ||
|
||||
!declaration.getNamespaceImport()
|
||||
) {
|
||||
throw new Error(
|
||||
"Unsupported import clause.\n" +
|
||||
` In: "${declaration.getSourceFile().getFilePath()}"\n` +
|
||||
` Text: "${declaration.getText()}"`
|
||||
);
|
||||
throw createDeclarationError("Unsupported import clause.", declaration);
|
||||
}
|
||||
const text = namespaceSourceFile(
|
||||
declaration.getModuleSpecifierSourceFileOrThrow(),
|
||||
{
|
||||
debug,
|
||||
namespace: declaration.getNamespaceImportOrThrow().getText(),
|
||||
namespaces,
|
||||
rootPath,
|
||||
sourceFileMap
|
||||
}
|
||||
|
@ -328,6 +379,8 @@ export function namespaceSourceFile(
|
|||
.getExportDeclarations()
|
||||
.forEach(declaration => declaration.remove());
|
||||
|
||||
namespaces.add(namespace);
|
||||
|
||||
return `${output}
|
||||
${globalNamespaceText || ""}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
getSourceComment,
|
||||
loadDtsFiles,
|
||||
loadFiles,
|
||||
logDiagnostics,
|
||||
namespaceSourceFile,
|
||||
normalizeSlashes
|
||||
} from "./ast_util";
|
||||
|
@ -222,6 +223,7 @@ export function mergeGlobal({
|
|||
// declaration source file into a namespace that exists within the merged
|
||||
// namespace
|
||||
const importDeclarations = sourceFile.getImportDeclarations();
|
||||
const namespaces = new Set<string>();
|
||||
for (const declaration of importDeclarations) {
|
||||
const declarationSourceFile = declaration.getModuleSpecifierSourceFile();
|
||||
if (
|
||||
|
@ -241,6 +243,7 @@ export function mergeGlobal({
|
|||
namespaceSourceFile(dtsSourceFile, {
|
||||
debug,
|
||||
namespace: declaration.getNamespaceImportOrThrow().getText(),
|
||||
namespaces,
|
||||
rootPath: basePath,
|
||||
sourceFileMap
|
||||
})
|
||||
|
@ -308,6 +311,14 @@ export function main({
|
|||
// emit the project, which will be only the declaration files
|
||||
const inputEmitResult = inputProject.emitToMemory();
|
||||
|
||||
const inputDiagnostics = inputEmitResult
|
||||
.getDiagnostics()
|
||||
.map(d => d.compilerObject);
|
||||
logDiagnostics(inputDiagnostics);
|
||||
if (inputDiagnostics.length) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// the declaration project will be the target for the emitted files from
|
||||
// the input project, these will be used to transfer information over to
|
||||
// the final library file
|
||||
|
|
|
@ -128,7 +128,10 @@ test(function buildLibraryMerge() {
|
|||
});
|
||||
|
||||
assert(targetSourceFile.getNamespace("moduleC") != null);
|
||||
assertEqual(targetSourceFile.getNamespaces().length, 1);
|
||||
assert(targetSourceFile.getNamespace("moduleD") != null);
|
||||
assert(targetSourceFile.getNamespace("moduleE") != null);
|
||||
assert(targetSourceFile.getNamespace("moduleF") != null);
|
||||
assertEqual(targetSourceFile.getNamespaces().length, 4);
|
||||
assert(targetSourceFile.getInterface("FooBar") != null);
|
||||
assertEqual(targetSourceFile.getInterfaces().length, 1);
|
||||
const variableDeclarations = targetSourceFile.getVariableDeclarations();
|
||||
|
@ -138,7 +141,15 @@ test(function buildLibraryMerge() {
|
|||
variableDeclarations[2].getType().getText(),
|
||||
`typeof moduleC.qat`
|
||||
);
|
||||
assertEqual(variableDeclarations.length, 3);
|
||||
assertEqual(
|
||||
variableDeclarations[3].getType().getText(),
|
||||
`typeof moduleE.process`
|
||||
);
|
||||
assertEqual(
|
||||
variableDeclarations[4].getType().getText(),
|
||||
`typeof moduleD.reprocess`
|
||||
);
|
||||
assertEqual(variableDeclarations.length, 5);
|
||||
});
|
||||
|
||||
// TODO author unit tests for `ast_util.ts`
|
||||
|
|
4
tools/ts_library_builder/testdata/globals.ts
vendored
4
tools/ts_library_builder/testdata/globals.ts
vendored
|
@ -1,6 +1,10 @@
|
|||
import * as moduleC from "./moduleC";
|
||||
import * as moduleD from "./moduleD";
|
||||
import * as moduleE from "./moduleE";
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const foobarbaz: any = {};
|
||||
foobarbaz.bar = new moduleC.Bar();
|
||||
foobarbaz.qat = moduleC.qat;
|
||||
foobarbaz.process = moduleE.process;
|
||||
foobarbaz.reprocess = moduleD.reprocess;
|
||||
|
|
5
tools/ts_library_builder/testdata/moduleD.ts
vendored
Normal file
5
tools/ts_library_builder/testdata/moduleD.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import * as moduleF from "./moduleF";
|
||||
|
||||
export function reprocess(value: typeof moduleF.key) {
|
||||
console.log(value);
|
||||
}
|
5
tools/ts_library_builder/testdata/moduleE.ts
vendored
Normal file
5
tools/ts_library_builder/testdata/moduleE.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
import * as moduleF from "./moduleF";
|
||||
|
||||
export function process(value: typeof moduleF.key) {
|
||||
console.log(value);
|
||||
}
|
1
tools/ts_library_builder/testdata/moduleF.ts
vendored
Normal file
1
tools/ts_library_builder/testdata/moduleF.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
export const key = "value";
|
Loading…
Add table
Reference in a new issue