feat(core): add undecorated classes migration schematic (#31650)
Introduces a new migration schematic that follows the given migration plan: https://hackmd.io/@alx/S1XKqMZeS. First case: The schematic detects decorated directives which inherit a constructor. The migration ensures that all base classes until the class with the explicit constructor are properly decorated with "@Directive()" or "@Component". In case one of these classes is not decorated, the schematic adds the abstract "@Directive()" decorator automatically. Second case: The schematic detects undecorated declarations and copies the inherited "@Directive()", "@Component" or "@Pipe" decorator to the undecorated derived class. This involves non-trivial import rewriting, identifier aliasing and AOT metadata serializing (as decorators are not always part of source files) PR Close #31650
This commit is contained in:

committed by
Kara Erickson

parent
5064dc75ac
commit
024c31da25
@ -15,6 +15,7 @@ export type CallExpressionDecorator = ts.Decorator & {
|
||||
|
||||
export interface NgDecorator {
|
||||
name: string;
|
||||
moduleName: string;
|
||||
node: CallExpressionDecorator;
|
||||
importNode: ts.ImportDeclaration;
|
||||
}
|
||||
@ -30,6 +31,7 @@ export function getAngularDecorators(
|
||||
.map(({node, importData}) => ({
|
||||
node: node as CallExpressionDecorator,
|
||||
name: importData !.name,
|
||||
moduleName: importData !.importModule,
|
||||
importNode: importData !.node
|
||||
}));
|
||||
}
|
||||
|
@ -30,3 +30,8 @@ export function findParentClassDeclaration(node: ts.Node): ts.ClassDeclaration|n
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/** Checks whether the given class declaration has an explicit constructor or not. */
|
||||
export function hasExplicitConstructor(node: ts.ClassDeclaration): boolean {
|
||||
return node.members.some(ts.isConstructorDeclaration);
|
||||
}
|
||||
|
20
packages/core/schematics/utils/typescript/symbol.ts
Normal file
20
packages/core/schematics/utils/typescript/symbol.ts
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. 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';
|
||||
|
||||
export function getValueSymbolOfDeclaration(node: ts.Node, typeChecker: ts.TypeChecker): ts.Symbol|
|
||||
undefined {
|
||||
let symbol = typeChecker.getSymbolAtLocation(node);
|
||||
|
||||
while (symbol && symbol.flags & ts.SymbolFlags.Alias) {
|
||||
symbol = typeChecker.getAliasedSymbol(symbol);
|
||||
}
|
||||
|
||||
return symbol;
|
||||
}
|
Reference in New Issue
Block a user