From ded7beed3241714373536ae7d76450d0b3ee2a5f Mon Sep 17 00:00:00 2001 From: JoostK Date: Fri, 30 Oct 2020 23:04:09 +0100 Subject: [PATCH] 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 --- .../test/compliance/mock_compile/index.ts | 20 ++++++--- .../test/compliance/prelink/BUILD.bazel | 8 ++++ .../test/compliance/prelink/bootstrap.ts | 43 +++++++++++++++++-- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/packages/compiler-cli/test/compliance/mock_compile/index.ts b/packages/compiler-cli/test/compliance/mock_compile/index.ts index 4c56d03741..95c50391ea 100644 --- a/packages/compiler-cli/test/compliance/mock_compile/index.ts +++ b/packages/compiler-cli/test/compliance/mock_compile/index.ts @@ -196,10 +196,10 @@ function buildMatcher(pieces: (string|RegExp)[]): {regexp: RegExp, groups: Map entry.fileName); @@ -217,8 +217,18 @@ export function doCompile( }, mockCompilerHost); program.emit(); - const source = - scripts.map(script => mockCompilerHost.readFile(script.replace(/\.ts$/, '.js'))).join('\n'); + return scripts.map(script => { + 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}; } diff --git a/packages/compiler-cli/test/compliance/prelink/BUILD.bazel b/packages/compiler-cli/test/compliance/prelink/BUILD.bazel index c0e657d274..d4a988f8e8 100644 --- a/packages/compiler-cli/test/compliance/prelink/BUILD.bazel +++ b/packages/compiler-cli/test/compliance/prelink/BUILD.bazel @@ -6,7 +6,15 @@ ts_library( srcs = ["bootstrap.ts"], deps = [ "//packages:types", + "//packages/compiler-cli/linker/babel", "//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", ], ) diff --git a/packages/compiler-cli/test/compliance/prelink/bootstrap.ts b/packages/compiler-cli/test/compliance/prelink/bootstrap.ts index 38d8efa990..527d6e881f 100644 --- a/packages/compiler-cli/test/compliance/prelink/bootstrap.ts +++ b/packages/compiler-cli/test/compliance/prelink/bootstrap.ts @@ -5,7 +5,10 @@ * 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 {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: @@ -16,11 +19,43 @@ import {CompileFn, doCompile, setCompileFn} from '../mock_compile'; * This should produce the same output as the full AOT compilation */ const linkedCompile: CompileFn = (data, angularFiles, options) => { - const result = doCompile(data, angularFiles, {...options, compilationMode: 'partial'}); - // TODO: additional post linking - return result; + const compiledFiles = compileFiles(data, angularFiles, {...options, compilationMode: 'partial'}); + + 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 // runs the prelink and postlink parts of AOT compilation, to check it produces the // same result as a normal full AOT compile.