test(compiler-cli): run the linker transform in the compliance test's prelink target (#39518)

In PR #38938 an additional Bazel target was introduced for the compliance
tests, as preparation to run the compliance tests in partial compilation
mode and then apply the linker transform. The linker plugin itself was
not available at the time but has since been implemented, so this commit
updates the prelink target of the compliance tests to apply the linker
transform using the Babel plugin.

Actually emitting partial compilations to be transformed will be done in
follow-up work.

PR Close #39518
This commit is contained in:
JoostK 2020-10-30 23:04:09 +01:00 committed by Joey Perrott
parent 4eda87c86c
commit ded7beed32
3 changed files with 62 additions and 9 deletions

View File

@ -196,10 +196,10 @@ function buildMatcher(pieces: (string|RegExp)[]): {regexp: RegExp, groups: Map<s
}; };
} }
export function doCompile( export function compileFiles(
data: MockDirectory, angularFiles: MockData, options: NgCompilerOptions = {}): { data: MockDirectory, angularFiles: MockData, options: NgCompilerOptions = {}): {
source: string, fileName: string; source: string,
} { }[] {
setFileSystem(new NodeJSFileSystem()); setFileSystem(new NodeJSFileSystem());
const testFiles = toMockFileArray(data); const testFiles = toMockFileArray(data);
const scripts = testFiles.map(entry => entry.fileName); const scripts = testFiles.map(entry => entry.fileName);
@ -217,8 +217,18 @@ export function doCompile(
}, },
mockCompilerHost); mockCompilerHost);
program.emit(); program.emit();
const source = return scripts.map(script => {
scripts.map(script => mockCompilerHost.readFile(script.replace(/\.ts$/, '.js'))).join('\n'); const fileName = script.replace(/\.ts$/, '.js');
const source = mockCompilerHost.readFile(fileName);
return {fileName, source};
});
}
function doCompile(data: MockDirectory, angularFiles: MockData, options: NgCompilerOptions = {}): {
source: string,
} {
const scripts = compileFiles(data, angularFiles, options);
const source = scripts.map(script => script.source).join('\n');
return {source}; return {source};
} }

View File

@ -6,7 +6,15 @@ ts_library(
srcs = ["bootstrap.ts"], srcs = ["bootstrap.ts"],
deps = [ deps = [
"//packages:types", "//packages:types",
"//packages/compiler-cli/linker/babel",
"//packages/compiler-cli/test/compliance/mock_compile", "//packages/compiler-cli/test/compliance/mock_compile",
"@npm//@babel/core",
"@npm//@babel/generator",
"@npm//@babel/template",
"@npm//@babel/types",
"@npm//@types/babel__core",
"@npm//@types/babel__generator",
"@npm//@types/babel__template",
], ],
) )

View File

@ -5,7 +5,10 @@
* Use of this source code is governed by an MIT-style license that can be * 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 * found in the LICENSE file at https://angular.io/license
*/ */
import {CompileFn, doCompile, setCompileFn} from '../mock_compile'; import {PluginObj, transformSync} from '@babel/core';
import {createEs2015LinkerPlugin} from '../../../linker/babel';
import {compileFiles, CompileFn, setCompileFn} from '../mock_compile';
/** /**
* A function to compile the given code in two steps: * A function to compile the given code in two steps:
@ -16,11 +19,43 @@ import {CompileFn, doCompile, setCompileFn} from '../mock_compile';
* This should produce the same output as the full AOT compilation * This should produce the same output as the full AOT compilation
*/ */
const linkedCompile: CompileFn = (data, angularFiles, options) => { const linkedCompile: CompileFn = (data, angularFiles, options) => {
const result = doCompile(data, angularFiles, {...options, compilationMode: 'partial'}); const compiledFiles = compileFiles(data, angularFiles, {...options, compilationMode: 'partial'});
// TODO: additional post linking
return result; const linkerPlugin = createEs2015LinkerPlugin({
enableI18nLegacyMessageIdFormat: options?.enableI18nLegacyMessageIdFormat,
i18nNormalizeLineEndingsInICUs: options?.i18nNormalizeLineEndingsInICUs,
});
const source = compiledFiles.map(file => applyLinker(file, linkerPlugin)).join('\n');
return {source};
}; };
/**
* Runs the provided code through the Babel linker plugin, if the file has the .js extension.
*
* @param file The file name 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: {fileName: string; source: string}, linkerPlugin: PluginObj): string {
if (!file.fileName.endsWith('.js')) {
return file.source;
}
const result = transformSync(file.source, {
filename: file.fileName,
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 // 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 // runs the prelink and postlink parts of AOT compilation, to check it produces the
// same result as a normal full AOT compile. // same result as a normal full AOT compile.