From 4edd218b89584baf2bbd109e4e02caa00b2068e7 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sat, 4 Sep 2021 18:46:41 +0200 Subject: [PATCH] feat(cdk/schematics): add migration for removed symbols Sets up a new migration that will log a message for symbols that have been removed from a specific module. --- src/cdk/schematics/ng-update/data/index.ts | 1 + .../ng-update/data/symbol-removal.ts | 22 ++++++++ .../ng-update/devkit-migration-rule.ts | 2 + .../ng-update/migrations/symbol-removal.ts | 50 +++++++++++++++++++ src/cdk/schematics/ng-update/upgrade-data.ts | 4 ++ .../schematics/ng-update/data/index.ts | 1 + .../ng-update/data/symbol-removal.ts | 29 +++++++++++ .../test-cases/misc/symbol-removal.spec.ts | 30 +++++++++++ .../test-cases/misc/symbol-removal_input.ts | 11 ++++ .../schematics/ng-update/upgrade-data.ts | 2 + 10 files changed, 152 insertions(+) create mode 100644 src/cdk/schematics/ng-update/data/symbol-removal.ts create mode 100644 src/cdk/schematics/ng-update/migrations/symbol-removal.ts create mode 100644 src/material/schematics/ng-update/data/symbol-removal.ts create mode 100644 src/material/schematics/ng-update/test-cases/misc/symbol-removal.spec.ts create mode 100644 src/material/schematics/ng-update/test-cases/misc/symbol-removal_input.ts diff --git a/src/cdk/schematics/ng-update/data/index.ts b/src/cdk/schematics/ng-update/data/index.ts index 2cd266995e42..a34dbf5df32b 100644 --- a/src/cdk/schematics/ng-update/data/index.ts +++ b/src/cdk/schematics/ng-update/data/index.ts @@ -15,3 +15,4 @@ export * from './input-names'; export * from './method-call-checks'; export * from './output-names'; export * from './property-names'; +export * from './symbol-removal'; diff --git a/src/cdk/schematics/ng-update/data/symbol-removal.ts b/src/cdk/schematics/ng-update/data/symbol-removal.ts new file mode 100644 index 000000000000..aa6d833910c6 --- /dev/null +++ b/src/cdk/schematics/ng-update/data/symbol-removal.ts @@ -0,0 +1,22 @@ +/** + * @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 {VersionChanges} from '../../update-tool/version-changes'; + +export interface SymbolRemovalUpgradeData { + /** Module that the symbol was removed from. */ + module: string; + + /** Name of the symbol being removed. */ + name: string; + + /** Message to log explaining why the symbol was removed. */ + message: string; +} + +export const symbolRemoval: VersionChanges = {}; diff --git a/src/cdk/schematics/ng-update/devkit-migration-rule.ts b/src/cdk/schematics/ng-update/devkit-migration-rule.ts index 967e6b524f09..0ce2648a7d7c 100644 --- a/src/cdk/schematics/ng-update/devkit-migration-rule.ts +++ b/src/cdk/schematics/ng-update/devkit-migration-rule.ts @@ -31,6 +31,7 @@ import {MiscTemplateMigration} from './migrations/misc-template'; import {OutputNamesMigration} from './migrations/output-names'; import {PropertyNamesMigration} from './migrations/property-names'; import {UpgradeData} from './upgrade-data'; +import {SymbolRemovalMigration} from './migrations/symbol-removal'; /** List of migrations which run for the CDK update. */ @@ -46,6 +47,7 @@ export const cdkMigrations: MigrationCtor[] = [ MiscTemplateMigration, OutputNamesMigration, PropertyNamesMigration, + SymbolRemovalMigration, ]; export type NullableDevkitMigration = MigrationCtor; diff --git a/src/cdk/schematics/ng-update/migrations/symbol-removal.ts b/src/cdk/schematics/ng-update/migrations/symbol-removal.ts new file mode 100644 index 000000000000..36f0ed4fbd73 --- /dev/null +++ b/src/cdk/schematics/ng-update/migrations/symbol-removal.ts @@ -0,0 +1,50 @@ +/** + * @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 * as ts from 'typescript'; +import {Migration} from '../../update-tool/migration'; +import {SymbolRemovalUpgradeData} from '../data'; +import {getVersionUpgradeData, UpgradeData} from '../upgrade-data'; + +/** Migration that flags imports for symbols that have been removed. */ +export class SymbolRemovalMigration extends Migration { + /** Change data that upgrades to the specified target version. */ + data: SymbolRemovalUpgradeData[] = getVersionUpgradeData(this, 'symbolRemoval'); + + // Only enable the migration rule if there is upgrade data. + enabled = this.data.length !== 0; + + override visitNode(node: ts.Node): void { + if (!ts.isImportDeclaration(node) || !ts.isStringLiteral(node.moduleSpecifier)) { + return; + } + + const namedBindings = node.importClause && node.importClause.namedBindings; + + if (!namedBindings || !ts.isNamedImports(namedBindings)) { + return; + } + + const moduleNameMatches = this.data.filter(entry => + (node.moduleSpecifier as ts.StringLiteral).text === entry.module); + + if (!moduleNameMatches.length) { + return; + } + + namedBindings.elements.forEach(element => { + const elementName = element.propertyName?.text || element.name.text; + + moduleNameMatches.forEach(match => { + if (match.name === elementName) { + this.createFailureAtNode(element, match.message); + } + }); + }); + } +} diff --git a/src/cdk/schematics/ng-update/upgrade-data.ts b/src/cdk/schematics/ng-update/upgrade-data.ts index 565d671c8239..829b86ed6a52 100644 --- a/src/cdk/schematics/ng-update/upgrade-data.ts +++ b/src/cdk/schematics/ng-update/upgrade-data.ts @@ -27,6 +27,8 @@ import { OutputNameUpgradeData, propertyNames, PropertyNameUpgradeData, + SymbolRemovalUpgradeData, + symbolRemoval, } from './data'; @@ -41,6 +43,7 @@ export const cdkUpgradeData: UpgradeData = { methodCallChecks, outputNames, propertyNames, + symbolRemoval, }; /** @@ -57,6 +60,7 @@ export interface UpgradeData { methodCallChecks: VersionChanges; outputNames: VersionChanges; propertyNames: VersionChanges; + symbolRemoval: VersionChanges; } /** diff --git a/src/material/schematics/ng-update/data/index.ts b/src/material/schematics/ng-update/data/index.ts index 2cd266995e42..a34dbf5df32b 100644 --- a/src/material/schematics/ng-update/data/index.ts +++ b/src/material/schematics/ng-update/data/index.ts @@ -15,3 +15,4 @@ export * from './input-names'; export * from './method-call-checks'; export * from './output-names'; export * from './property-names'; +export * from './symbol-removal'; diff --git a/src/material/schematics/ng-update/data/symbol-removal.ts b/src/material/schematics/ng-update/data/symbol-removal.ts new file mode 100644 index 000000000000..bf8c4ece6b60 --- /dev/null +++ b/src/material/schematics/ng-update/data/symbol-removal.ts @@ -0,0 +1,29 @@ +/** + * @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 {SymbolRemovalUpgradeData, TargetVersion, VersionChanges} from '@angular/cdk/schematics'; + +export const symbolRemoval: VersionChanges = { + [TargetVersion.V13]: [ + { + pr: 'https://github.com/angular/components/pull/23529', + changes: [ + 'CanColorCtor', + 'CanDisableRippleCtor', + 'CanDisableCtor', + 'CanUpdateErrorStateCtor', + 'HasInitializedCtor', + 'HasTabIndexCtor' + ].map(name => ({ + name, + module: '@angular/material/core', + message: `\`${name}\` is no longer necessary and has been removed.` + })) + } + ] +}; diff --git a/src/material/schematics/ng-update/test-cases/misc/symbol-removal.spec.ts b/src/material/schematics/ng-update/test-cases/misc/symbol-removal.spec.ts new file mode 100644 index 000000000000..cc43e3c9356e --- /dev/null +++ b/src/material/schematics/ng-update/test-cases/misc/symbol-removal.spec.ts @@ -0,0 +1,30 @@ +import {createTestCaseSetup, resolveBazelPath} from '@angular/cdk/schematics/testing'; +import {MIGRATION_PATH} from '../../../paths'; + +describe('symbol removal check', () => { + it('should report symbols that have been removed', async () => { + const {runFixers} = await createTestCaseSetup( + 'migration-v13', MIGRATION_PATH, + [resolveBazelPath(__dirname, './symbol-removal_input.ts')]); + + const {logOutput} = await runFixers(); + + expect(logOutput) + .not + .withContext('Expected check not to report symbols that have not been removed.') + .toContain('MatRipple'); + + expect(logOutput) + .not + .withContext('Expected check not to report symbols with the same name as a ' + + 'removed symbol, but from a different module.').toContain('HasInitializedCtor'); + + expect(logOutput) + .withContext('Expected check to report a removed symbol') + .toContain('@2:3 - `CanColorCtor` is no longer necessary and has been removed.'); + + expect(logOutput) + .withContext('Expected check to report a removed symbol that has been aliased') + .toContain('@3:3 - `CanDisableRippleCtor` is no longer necessary and has been removed.'); + }); +}); diff --git a/src/material/schematics/ng-update/test-cases/misc/symbol-removal_input.ts b/src/material/schematics/ng-update/test-cases/misc/symbol-removal_input.ts new file mode 100644 index 000000000000..a49943e3636c --- /dev/null +++ b/src/material/schematics/ng-update/test-cases/misc/symbol-removal_input.ts @@ -0,0 +1,11 @@ +import { + CanColorCtor, + CanDisableRippleCtor as DisableRippleCtorAlias, + MatRipple, +} from '@angular/material/core'; +import {HasInitializedCtor} from '@not-angular/material/core'; + +export declare const colorCtor: CanColorCtor; +export declare const disableRIppleCtor: DisableRippleCtorAlias; +export declare const ripple: MatRipple; +export declare const initCtor: HasInitializedCtor; diff --git a/src/material/schematics/ng-update/upgrade-data.ts b/src/material/schematics/ng-update/upgrade-data.ts index 58e8096f23de..5265d41fbb2f 100644 --- a/src/material/schematics/ng-update/upgrade-data.ts +++ b/src/material/schematics/ng-update/upgrade-data.ts @@ -17,6 +17,7 @@ import { methodCallChecks, outputNames, propertyNames, + symbolRemoval, } from './data'; /** Upgrade data that will be used for the Angular Material ng-update schematic. */ @@ -30,4 +31,5 @@ export const materialUpgradeData: UpgradeData = { methodCallChecks, outputNames, propertyNames, + symbolRemoval, };