angular-cn/packages/compiler-cli/test/compliance_old/prelink/bootstrap.ts

80 lines
2.8 KiB
TypeScript

/**
* @license
* Copyright Google LLC 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 {PluginObj, transformSync} from '@babel/core';
import * as ts from 'typescript';
import {needsLinking} from '../../../linker';
import {createEs2015LinkerPlugin} from '../../../linker/babel';
import {MockFileSystemNative} from '../../../src/ngtsc/file_system/testing';
import {MockLogger} from '../../../src/ngtsc/logging/testing';
import {compileFiles, CompileFn, setCompileFn} from '../mock_compile';
/**
* A function to compile the given code in two steps:
*
* - first compile the code in partial mode
* - then compile the partially compiled code using the linker
*
* This should produce the same output as the full AOT compilation
*/
const linkedCompile: CompileFn = (data, angularFiles, options) => {
if (options !== undefined && options.target !== undefined &&
options.target < ts.ScriptTarget.ES2015) {
pending('ES5 is not supported in the partial compilation tests');
throw new Error('ES5 is not supported in the partial compilation tests');
}
const compiledFiles = compileFiles(data, angularFiles, {...options, compilationMode: 'partial'});
const fileSystem = new MockFileSystemNative();
const logger = new MockLogger();
const linkerPlugin = createEs2015LinkerPlugin({
fileSystem,
logger,
// enableI18nLegacyMessageIdFormat defaults to false in `compileFiles`.
enableI18nLegacyMessageIdFormat: false,
...options,
});
const source =
compiledFiles
.map(file => applyLinker({path: file.fileName, source: file.source}, linkerPlugin))
.join('\n');
return {source};
};
/**
* Runs the provided code through the Babel linker plugin, if the file has the .js extension.
*
* @param file The absolute file path and its source to be transformed using the linker.
* @param linkerPlugin The linker plugin to apply.
* @returns The file's source content, which has been transformed using the linker if necessary.
*/
function applyLinker(file: {path: string; source: string}, linkerPlugin: PluginObj): string {
if (!file.path.endsWith('.js') || !needsLinking(file.path, file.source)) {
return file.source;
}
const result = transformSync(file.source, {
filename: file.path,
plugins: [linkerPlugin],
parserOpts: {sourceType: 'unambiguous'},
});
if (result === null) {
throw fail('Babel transform did not have output');
}
if (result.code == null) {
throw fail('Babel transform result does not have any code');
}
return result.code;
}
// Update the function that will do the compiling with this specialised version that
// runs the prelink and postlink parts of AOT compilation, to check it produces the
// same result as a normal full AOT compile.
setCompileFn(linkedCompile);