84 lines
3.2 KiB
TypeScript
84 lines
3.2 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {PluginCompilerHost, TscPlugin} from '@bazel/typescript/internal/tsc_wrapped/plugin_api';
|
|
import * as ts from 'typescript';
|
|
|
|
import {SyntheticFilesCompilerHost} from './synthetic_files_compiler_host';
|
|
|
|
// Copied from tsc_wrapped/plugin_api.ts to avoid a runtime dependency on the
|
|
// @bazel/typescript package - it would be strange for non-Bazel users of
|
|
// Angular to fetch that package.
|
|
function createProxy<T>(delegate: T): T {
|
|
const proxy = Object.create(null);
|
|
for (const k of Object.keys(delegate)) {
|
|
proxy[k] = function() { return (delegate as any)[k].apply(delegate, arguments); };
|
|
}
|
|
return proxy;
|
|
}
|
|
|
|
export class NgTscPlugin implements TscPlugin {
|
|
constructor(private angularCompilerOptions: unknown) {}
|
|
|
|
wrapHost(inputFiles: string[], compilerHost: ts.CompilerHost) {
|
|
return new SyntheticFilesCompilerHost(inputFiles, compilerHost, (rootFiles: string[]) => {
|
|
// For demo purposes, assume that the first .ts rootFile is the only
|
|
// one that needs ngfactory.js/d.ts back-compat files produced.
|
|
const tsInputs = rootFiles.filter(f => f.endsWith('.ts') && !f.endsWith('.d.ts'));
|
|
const factoryPath: string = tsInputs[0].replace(/\.ts/, '.ngfactory.ts');
|
|
|
|
return {
|
|
factoryPath: (host: ts.CompilerHost) =>
|
|
ts.createSourceFile(factoryPath, 'contents', ts.ScriptTarget.ES5),
|
|
};
|
|
});
|
|
}
|
|
|
|
wrap(program: ts.Program, config: {}, host: ts.CompilerHost) {
|
|
const proxy = createProxy(program);
|
|
proxy.getSemanticDiagnostics = (sourceFile: ts.SourceFile) => {
|
|
const result: ts.Diagnostic[] = [...program.getSemanticDiagnostics(sourceFile)];
|
|
|
|
// For demo purposes, trigger a diagnostic when the sourcefile has a magic string
|
|
if (sourceFile.text.indexOf('diag') >= 0) {
|
|
const fake: ts.Diagnostic = {
|
|
file: sourceFile,
|
|
start: 0,
|
|
length: 3,
|
|
messageText: 'Example Angular Compiler Diagnostic',
|
|
category: ts.DiagnosticCategory.Error,
|
|
code: 12345,
|
|
// source is the name of the plugin.
|
|
source: 'ngtsc',
|
|
};
|
|
result.push(fake);
|
|
}
|
|
return result;
|
|
};
|
|
return proxy;
|
|
}
|
|
|
|
createTransformers(host: PluginCompilerHost) {
|
|
const afterDeclarations: Array<ts.TransformerFactory<ts.SourceFile|ts.Bundle>> =
|
|
[(context: ts.TransformationContext) => (sf: ts.SourceFile | ts.Bundle) => {
|
|
const visitor = (node: ts.Node): ts.Node => {
|
|
if (node.kind === ts.SyntaxKind.ClassDeclaration) {
|
|
const clz = node as ts.ClassDeclaration;
|
|
// For demo purposes, transform the class name in the .d.ts output
|
|
return ts.updateClassDeclaration(
|
|
clz, clz.decorators, node.modifiers, ts.createIdentifier('NEWNAME'),
|
|
clz.typeParameters, clz.heritageClauses, clz.members);
|
|
}
|
|
return ts.visitEachChild(node, visitor, context);
|
|
};
|
|
return visitor(sf) as ts.SourceFile;
|
|
}];
|
|
return {afterDeclarations};
|
|
}
|
|
}
|