refactor(ivy): use ClassDeclaration
in more ReflectionHost
methods (#29209)
PR Close #29209
This commit is contained in:

committed by
Miško Hevery

parent
bb6a3632f6
commit
2790352d04
@ -8,4 +8,5 @@
|
||||
|
||||
export * from './src/host';
|
||||
export {typeNodeToValueExpr} from './src/type_to_value';
|
||||
export {TypeScriptReflectionHost, filterToMembersWithDecorator, reflectIdentifierOfDeclaration, reflectNameOfDeclaration, reflectObjectLiteral, reflectTypeEntityToDeclaration} from './src/typescript';
|
||||
export {TypeScriptReflectionHost, filterToMembersWithDecorator, reflectIdentifierOfDeclaration, reflectNameOfDeclaration, reflectObjectLiteral, reflectTypeEntityToDeclaration} from './src/typescript';
|
||||
export {isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration} from './src/util';
|
||||
|
@ -362,16 +362,13 @@ export interface ReflectionHost {
|
||||
* Examine a declaration which should be of a class, and return metadata about the members of the
|
||||
* class.
|
||||
*
|
||||
* @param declaration a TypeScript `ts.Declaration` node representing the class over which to
|
||||
* reflect. If the source is in ES6 format, this will be a `ts.ClassDeclaration` node. If the
|
||||
* source is in ES5 format, this might be a `ts.VariableDeclaration` as classes in ES5 are
|
||||
* represented as the result of an IIFE execution.
|
||||
* @param clazz a `ClassDeclaration` representing the class over which to reflect.
|
||||
*
|
||||
* @returns an array of `ClassMember` metadata representing the members of the class.
|
||||
*
|
||||
* @throws if `declaration` does not resolve to a class declaration.
|
||||
*/
|
||||
getMembersOfClass(clazz: ts.Declaration): ClassMember[];
|
||||
getMembersOfClass(clazz: ClassDeclaration): ClassMember[];
|
||||
|
||||
/**
|
||||
* Reflect over the constructor of a class and return metadata about its parameters.
|
||||
@ -379,16 +376,13 @@ export interface ReflectionHost {
|
||||
* This method only looks at the constructor of a class directly and not at any inherited
|
||||
* constructors.
|
||||
*
|
||||
* @param declaration a TypeScript `ts.Declaration` node representing the class over which to
|
||||
* reflect. If the source is in ES6 format, this will be a `ts.ClassDeclaration` node. If the
|
||||
* source is in ES5 format, this might be a `ts.VariableDeclaration` as classes in ES5 are
|
||||
* represented as the result of an IIFE execution.
|
||||
* @param clazz a `ClassDeclaration` representing the class over which to reflect.
|
||||
*
|
||||
* @returns an array of `Parameter` metadata representing the parameters of the constructor, if
|
||||
* a constructor exists. If the constructor exists and has 0 parameters, this array will be empty.
|
||||
* If the class has no constructor, this method returns `null`.
|
||||
*/
|
||||
getConstructorParameters(declaration: ts.Declaration): CtorParameter[]|null;
|
||||
getConstructorParameters(clazz: ClassDeclaration): CtorParameter[]|null;
|
||||
|
||||
/**
|
||||
* Reflect over a function and return metadata about its parameters and body.
|
||||
@ -478,17 +472,21 @@ export interface ReflectionHost {
|
||||
isClass(node: ts.Node): node is ClassDeclaration;
|
||||
|
||||
/**
|
||||
* Determines whether the given declaration has a base class.
|
||||
* Determines whether the given declaration, which should be a class, has a base class.
|
||||
*
|
||||
* @param clazz a `ClassDeclaration` representing the class over which to reflect.
|
||||
*/
|
||||
hasBaseClass(node: ts.Declaration): boolean;
|
||||
hasBaseClass(clazz: ClassDeclaration): boolean;
|
||||
|
||||
/**
|
||||
* Get the number of generic type parameters of a given class.
|
||||
*
|
||||
* @param clazz a `ClassDeclaration` representing the class over which to reflect.
|
||||
*
|
||||
* @returns the number of type parameters of the class, if known, or `null` if the declaration
|
||||
* is not a class or has an unknown number of type parameters.
|
||||
*/
|
||||
getGenericArityOfClass(clazz: ts.Declaration): number|null;
|
||||
getGenericArityOfClass(clazz: ClassDeclaration): number|null;
|
||||
|
||||
/**
|
||||
* Find the assigned value of a variable declaration.
|
||||
|
@ -26,17 +26,17 @@ export class TypeScriptReflectionHost implements ReflectionHost {
|
||||
.filter((dec): dec is Decorator => dec !== null);
|
||||
}
|
||||
|
||||
getMembersOfClass(declaration: ts.Declaration): ClassMember[] {
|
||||
const clazz = castDeclarationToClassOrDie(declaration);
|
||||
return clazz.members.map(member => this._reflectMember(member))
|
||||
getMembersOfClass(clazz: ClassDeclaration): ClassMember[] {
|
||||
const tsClazz = castDeclarationToClassOrDie(clazz);
|
||||
return tsClazz.members.map(member => this._reflectMember(member))
|
||||
.filter((member): member is ClassMember => member !== null);
|
||||
}
|
||||
|
||||
getConstructorParameters(declaration: ts.Declaration): CtorParameter[]|null {
|
||||
const clazz = castDeclarationToClassOrDie(declaration);
|
||||
getConstructorParameters(clazz: ClassDeclaration): CtorParameter[]|null {
|
||||
const tsClazz = castDeclarationToClassOrDie(clazz);
|
||||
|
||||
// First, find the constructor.
|
||||
const ctor = clazz.members.find(ts.isConstructorDeclaration);
|
||||
const ctor = tsClazz.members.find(ts.isConstructorDeclaration);
|
||||
if (ctor === undefined) {
|
||||
return null;
|
||||
}
|
||||
@ -139,9 +139,9 @@ export class TypeScriptReflectionHost implements ReflectionHost {
|
||||
return ts.isClassDeclaration(node) && (node.name !== undefined) && ts.isIdentifier(node.name);
|
||||
}
|
||||
|
||||
hasBaseClass(node: ts.Declaration): boolean {
|
||||
return ts.isClassDeclaration(node) && node.heritageClauses !== undefined &&
|
||||
node.heritageClauses.some(clause => clause.token === ts.SyntaxKind.ExtendsKeyword);
|
||||
hasBaseClass(clazz: ClassDeclaration): boolean {
|
||||
return ts.isClassDeclaration(clazz) && clazz.heritageClauses !== undefined &&
|
||||
clazz.heritageClauses.some(clause => clause.token === ts.SyntaxKind.ExtendsKeyword);
|
||||
}
|
||||
|
||||
getDeclarationOfIdentifier(id: ts.Identifier): Declaration|null {
|
||||
@ -166,7 +166,7 @@ export class TypeScriptReflectionHost implements ReflectionHost {
|
||||
};
|
||||
}
|
||||
|
||||
getGenericArityOfClass(clazz: ts.Declaration): number|null {
|
||||
getGenericArityOfClass(clazz: ClassDeclaration): number|null {
|
||||
if (!ts.isClassDeclaration(clazz)) {
|
||||
return null;
|
||||
}
|
||||
@ -419,7 +419,8 @@ export function reflectObjectLiteral(node: ts.ObjectLiteralExpression): Map<stri
|
||||
return map;
|
||||
}
|
||||
|
||||
function castDeclarationToClassOrDie(declaration: ts.Declaration): ts.ClassDeclaration {
|
||||
function castDeclarationToClassOrDie(declaration: ClassDeclaration):
|
||||
ClassDeclaration<ts.ClassDeclaration> {
|
||||
if (!ts.isClassDeclaration(declaration)) {
|
||||
throw new Error(
|
||||
`Reflecting on a ${ts.SyntaxKind[declaration.kind]} instead of a ClassDeclaration.`);
|
||||
|
27
packages/compiler-cli/src/ngtsc/reflection/src/util.ts
Normal file
27
packages/compiler-cli/src/ngtsc/reflection/src/util.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @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';
|
||||
|
||||
import {ClassDeclaration} from './host';
|
||||
|
||||
|
||||
export function isNamedClassDeclaration(node: ts.Node):
|
||||
node is ClassDeclaration<ts.ClassDeclaration>&{name: ts.Identifier} {
|
||||
return ts.isClassDeclaration(node) && (node.name !== undefined);
|
||||
}
|
||||
|
||||
export function isNamedFunctionDeclaration(node: ts.Node):
|
||||
node is ClassDeclaration<ts.FunctionDeclaration>&{name: ts.Identifier} {
|
||||
return ts.isFunctionDeclaration(node) && (node.name !== undefined);
|
||||
}
|
||||
|
||||
export function isNamedVariableDeclaration(node: ts.Node):
|
||||
node is ClassDeclaration<ts.VariableDeclaration>&{name: ts.Identifier} {
|
||||
return ts.isVariableDeclaration(node) && (node.name !== undefined);
|
||||
}
|
@ -11,6 +11,7 @@ import * as ts from 'typescript';
|
||||
import {getDeclaration, makeProgram} from '../../testing/in_memory_typescript';
|
||||
import {CtorParameter} from '../src/host';
|
||||
import {TypeScriptReflectionHost} from '../src/typescript';
|
||||
import {isNamedClassDeclaration} from '../src/util';
|
||||
|
||||
describe('reflector', () => {
|
||||
describe('ctor params', () => {
|
||||
@ -25,7 +26,7 @@ describe('reflector', () => {
|
||||
}
|
||||
`
|
||||
}]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -54,7 +55,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -83,7 +84,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -111,7 +112,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -139,7 +140,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -166,7 +167,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -198,7 +199,7 @@ describe('reflector', () => {
|
||||
`
|
||||
}
|
||||
]);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', ts.isClassDeclaration);
|
||||
const clazz = getDeclaration(program, 'entry.ts', 'Foo', isNamedClassDeclaration);
|
||||
const checker = program.getTypeChecker();
|
||||
const host = new TypeScriptReflectionHost(checker);
|
||||
const args = host.getConstructorParameters(clazz) !;
|
||||
@ -292,4 +293,4 @@ function argExpressionToString(name: ts.Node | null): string {
|
||||
} else {
|
||||
throw new Error(`Unexpected node in arg expression: ${ts.SyntaxKind[name.kind]}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user