mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
Reworks the logic that tracks the decorator metadata for members to do so using the output AST, rather than wrapping the TypeScript AST. This makes it easier to programmatically generate new members that weren't part of the TypeScript AST before. PR Close #63957 PR Close #64317
This commit is contained in:
parent
2c79ca0b57
commit
bb241ee28b
1 changed files with 31 additions and 19 deletions
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.dev/license
|
||||
*/
|
||||
|
||||
import {ErrorCode, FatalDiagnosticError, makeRelatedInformation} from '../../../diagnostics';
|
||||
import {ErrorCode, FatalDiagnosticError} from '../../../diagnostics';
|
||||
import {
|
||||
ArrowFunctionExpr,
|
||||
Expression,
|
||||
|
|
@ -19,6 +19,7 @@ import {
|
|||
import ts from 'typescript';
|
||||
|
||||
import {
|
||||
ClassMember,
|
||||
ClassMemberAccessLevel,
|
||||
CtorParameter,
|
||||
DeclarationNode,
|
||||
|
|
@ -88,15 +89,32 @@ export function extractClassMetadata(
|
|||
const classMembers = reflection.getMembersOfClass(clazz).filter(
|
||||
(member) =>
|
||||
!member.isStatic &&
|
||||
member.decorators !== null &&
|
||||
member.decorators.length > 0 &&
|
||||
// Private fields are not supported in the metadata emit
|
||||
member.accessLevel !== ClassMemberAccessLevel.EcmaScriptPrivate,
|
||||
);
|
||||
const duplicateDecoratedMembers = classMembers.filter(
|
||||
(member, i, arr) => arr.findIndex((arrayMember) => arrayMember.name === member.name) < i,
|
||||
);
|
||||
if (duplicateDecoratedMembers.length > 0) {
|
||||
|
||||
const decoratedMembers: {key: string; value: Expression; quoted: boolean}[] = [];
|
||||
const seenMemberNames = new Set<string>();
|
||||
let duplicateDecoratedMembers: ClassMember[] | null = null;
|
||||
|
||||
for (const member of classMembers) {
|
||||
if (member.decorators !== null && member.decorators.length > 0) {
|
||||
decoratedMembers.push({
|
||||
key: member.name,
|
||||
quoted: false,
|
||||
value: decoratedClassMemberToMetadata(member.decorators!, isCore),
|
||||
});
|
||||
|
||||
if (seenMemberNames.has(member.name)) {
|
||||
duplicateDecoratedMembers ??= [];
|
||||
duplicateDecoratedMembers.push(member);
|
||||
} else {
|
||||
seenMemberNames.add(member.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (duplicateDecoratedMembers !== null) {
|
||||
// This should theoretically never happen, because the only way to have duplicate instance
|
||||
// member names is getter/setter pairs and decorators cannot appear in both a getter and the
|
||||
// corresponding setter.
|
||||
|
|
@ -107,13 +125,9 @@ export function extractClassMetadata(
|
|||
duplicateDecoratedMembers.map((member) => member.name).join(', '),
|
||||
);
|
||||
}
|
||||
const decoratedMembers = classMembers.map((member) =>
|
||||
classMemberToMetadata(member.nameNode ?? member.name, member.decorators!, isCore),
|
||||
);
|
||||
|
||||
if (decoratedMembers.length > 0) {
|
||||
metaPropDecorators = new WrappedNodeExpr(
|
||||
ts.factory.createObjectLiteralExpression(decoratedMembers),
|
||||
);
|
||||
metaPropDecorators = literalMap(decoratedMembers);
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -153,16 +167,14 @@ function ctorParameterToMetadata(param: CtorParameter, isCore: boolean): Express
|
|||
/**
|
||||
* Convert a reflected class member to metadata.
|
||||
*/
|
||||
function classMemberToMetadata(
|
||||
name: ts.PropertyName | string,
|
||||
function decoratedClassMemberToMetadata(
|
||||
decorators: Decorator[],
|
||||
isCore: boolean,
|
||||
): ts.PropertyAssignment {
|
||||
): LiteralArrayExpr {
|
||||
const ngDecorators = decorators
|
||||
.filter((dec) => isAngularDecorator(dec, isCore))
|
||||
.map((decorator: Decorator) => decoratorToMetadata(decorator));
|
||||
const decoratorMeta = ts.factory.createArrayLiteralExpression(ngDecorators);
|
||||
return ts.factory.createPropertyAssignment(name, decoratorMeta);
|
||||
.map((decorator: Decorator) => new WrappedNodeExpr(decoratorToMetadata(decorator)));
|
||||
return new LiteralArrayExpr(ngDecorators);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue