diff --git a/packages/compiler-cli/src/ngtsc/core/BUILD.bazel b/packages/compiler-cli/src/ngtsc/core/BUILD.bazel index d1d151c0246..0f348a408b2 100644 --- a/packages/compiler-cli/src/ngtsc/core/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/core/BUILD.bazel @@ -31,7 +31,6 @@ ts_library( "//packages/compiler-cli/src/ngtsc/scope", "//packages/compiler-cli/src/ngtsc/shims", "//packages/compiler-cli/src/ngtsc/shims:api", - "//packages/compiler-cli/src/ngtsc/switch", "//packages/compiler-cli/src/ngtsc/transform", "//packages/compiler-cli/src/ngtsc/typecheck", "//packages/compiler-cli/src/ngtsc/typecheck/api", diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index 98c1be35191..f8b101166b1 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -25,7 +25,6 @@ import {DeclarationNode, isNamedClassDeclaration, TypeScriptReflectionHost} from import {AdapterResourceLoader} from '../../resource'; import {ComponentScopeReader, LocalModuleScopeRegistry, MetadataDtsModuleScopeResolver, TypeCheckScopeRegistry} from '../../scope'; import {generatedFactoryTransform} from '../../shims'; -import {ivySwitchTransform} from '../../switch'; import {aliasTransformFactory, CompilationMode, declarationTransformFactory, DecoratorHandler, DtsTransformRegistry, ivyTransformFactory, TraitCompiler} from '../../transform'; import {TemplateTypeCheckerImpl} from '../../typecheck'; import {OptimizeFor, TemplateTypeChecker, TypeCheckingConfig} from '../../typecheck/api'; @@ -647,7 +646,6 @@ export class NgCompiler { before.push( generatedFactoryTransform(this.adapter.factoryTracker.sourceInfo, importRewriter)); } - before.push(ivySwitchTransform); return {transformers: {before, afterDeclarations} as ts.CustomTransformers}; } diff --git a/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel b/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel deleted file mode 100644 index 7ceb4ad96ee..00000000000 --- a/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel +++ /dev/null @@ -1,14 +0,0 @@ -load("//tools:defaults.bzl", "ts_library") - -package(default_visibility = ["//visibility:public"]) - -ts_library( - name = "switch", - srcs = ["index.ts"] + glob([ - "src/**/*.ts", - ]), - deps = [ - "//packages/compiler", - "@npm//typescript", - ], -) diff --git a/packages/compiler-cli/src/ngtsc/switch/index.ts b/packages/compiler-cli/src/ngtsc/switch/index.ts deleted file mode 100644 index 1733176e359..00000000000 --- a/packages/compiler-cli/src/ngtsc/switch/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @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 - */ - -export {ivySwitchTransform} from './src/switch'; diff --git a/packages/compiler-cli/src/ngtsc/switch/src/switch.ts b/packages/compiler-cli/src/ngtsc/switch/src/switch.ts deleted file mode 100644 index 985bf676e80..00000000000 --- a/packages/compiler-cli/src/ngtsc/switch/src/switch.ts +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @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 ts from 'typescript'; - -const IVY_SWITCH_PRE_SUFFIX = '__PRE_R3__'; -const IVY_SWITCH_POST_SUFFIX = '__POST_R3__'; - -export function ivySwitchTransform(_: ts.TransformationContext): ts.Transformer { - return flipIvySwitchInFile; -} - -function flipIvySwitchInFile(sf: ts.SourceFile): ts.SourceFile { - // To replace the statements array, it must be copied. This only needs to happen if a statement - // must actually be replaced within the array, so the newStatements array is lazily initialized. - let newStatements: ts.Statement[]|undefined = undefined; - - // Iterate over the statements in the file. - for (let i = 0; i < sf.statements.length; i++) { - const statement = sf.statements[i]; - - // Skip over everything that isn't a variable statement. - if (!ts.isVariableStatement(statement) || !hasIvySwitches(statement)) { - continue; - } - - // This statement needs to be replaced. Check if the newStatements array needs to be lazily - // initialized to a copy of the original statements. - if (newStatements === undefined) { - newStatements = [...sf.statements]; - } - - // Flip any switches in the VariableStatement. If there were any, a new statement will be - // returned; otherwise the old statement will be. - newStatements[i] = flipIvySwitchesInVariableStatement(statement, sf.statements); - } - - // Only update the statements in the SourceFile if any have changed. - if (newStatements !== undefined) { - return ts.updateSourceFileNode(sf, newStatements); - } - return sf; -} - -/** - * Look for the ts.Identifier of a ts.Declaration with this name. - * - * The real identifier is needed (rather than fabricating one) as TypeScript decides how to - * reference this identifier based on information stored against its node in the AST, which a - * synthetic node would not have. In particular, since the post-switch variable is often exported, - * TypeScript needs to know this so it can write `exports.VAR` instead of just `VAR` when emitting - * code. - * - * Only variable, function, and class declarations are currently searched. - */ -function findPostSwitchIdentifier( - statements: ReadonlyArray, name: string): ts.Identifier|null { - for (const stmt of statements) { - if (ts.isVariableStatement(stmt)) { - const decl = stmt.declarationList.declarations.find( - decl => ts.isIdentifier(decl.name) && decl.name.text === name); - if (decl !== undefined) { - return decl.name as ts.Identifier; - } - } else if (ts.isFunctionDeclaration(stmt) || ts.isClassDeclaration(stmt)) { - if (stmt.name !== undefined && ts.isIdentifier(stmt.name) && stmt.name.text === name) { - return stmt.name; - } - } - } - return null; -} - -/** - * Flip any Ivy switches which are discovered in the given ts.VariableStatement. - */ -function flipIvySwitchesInVariableStatement( - stmt: ts.VariableStatement, statements: ReadonlyArray): ts.VariableStatement { - // Build a new list of variable declarations. Specific declarations that are initialized to a - // pre-switch identifier will be replaced with a declaration initialized to the post-switch - // identifier. - const newDeclarations = [...stmt.declarationList.declarations]; - for (let i = 0; i < newDeclarations.length; i++) { - const decl = newDeclarations[i]; - - // Skip declarations that aren't initialized to an identifier. - if (decl.initializer === undefined || !ts.isIdentifier(decl.initializer)) { - continue; - } - - // Skip declarations that aren't Ivy switches. - if (!decl.initializer.text.endsWith(IVY_SWITCH_PRE_SUFFIX)) { - continue; - } - - // Determine the name of the post-switch variable. - const postSwitchName = - decl.initializer.text.replace(IVY_SWITCH_PRE_SUFFIX, IVY_SWITCH_POST_SUFFIX); - - // Find the post-switch variable identifier. If one can't be found, it's an error. This is - // reported as a thrown error and not a diagnostic as transformers cannot output diagnostics. - const newIdentifier = findPostSwitchIdentifier(statements, postSwitchName); - if (newIdentifier === null) { - throw new Error(`Unable to find identifier ${postSwitchName} in ${ - stmt.getSourceFile().fileName} for the Ivy switch.`); - } - - newDeclarations[i] = ts.updateVariableDeclaration( - /* node */ decl, - /* name */ decl.name, - /* type */ decl.type, - /* initializer */ newIdentifier); - } - - const newDeclList = ts.updateVariableDeclarationList( - /* declarationList */ stmt.declarationList, - /* declarations */ newDeclarations); - - const newStmt = ts.updateVariableStatement( - /* statement */ stmt, - /* modifiers */ stmt.modifiers, - /* declarationList */ newDeclList); - - return newStmt; -} - -/** - * Check whether the given VariableStatement has any Ivy switch variables. - */ -function hasIvySwitches(stmt: ts.VariableStatement) { - return stmt.declarationList.declarations.some( - decl => decl.initializer !== undefined && ts.isIdentifier(decl.initializer) && - decl.initializer.text.endsWith(IVY_SWITCH_PRE_SUFFIX)); -} diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 2ff3f0b9b9d..b3f3a415200 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -6254,37 +6254,6 @@ function allTests(os: string) { }); }); - describe('ivy switch mode', () => { - it('should allow for symbols to be renamed when they use a SWITCH_IVY naming mechanism', - () => { - env.write('test.ts', ` -export const FooCmp__POST_R3__ = 1; -export const FooCmp__PRE_R3__ = 2; -export const FooCmp = FooCmp__PRE_R3__;`); - env.driveMain(); - - const source = env.getContents('test.js'); - expect(source).toContain(`export var FooCmp = FooCmp__POST_R3__`); - expect(source).not.toContain(`export var FooCmp = FooCmp__PRE_R3__`); - }); - - it('should allow for SWITCH_IVY naming even even if it occurs outside of core', () => { - const content = ` -export const Foo__POST_R3__ = 1; -export const Foo__PRE_R3__ = 2; -export const Foo = Foo__PRE_R3__; -`; - env.write('test_outside_angular_core.ts', content); - env.write( - 'test_inside_angular_core.ts', content + '\nexport const ITS_JUST_ANGULAR = true;'); - env.driveMain(); - - const sourceTestOutsideAngularCore = env.getContents('test_outside_angular_core.js'); - const sourceTestInsideAngularCore = env.getContents('test_inside_angular_core.js'); - expect(sourceTestInsideAngularCore).toContain(sourceTestOutsideAngularCore); - }); - }); - describe('NgModule export aliasing', () => { it('should use an alias to import a directive from a deep dependency', () => { env.tsconfig({'_useHostForImportGeneration': true});