Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bb241ee

Browse files
crisbetoAndrewKushnir
authored andcommitted
refactor(compiler-cli): track member metadata using output AST (#63957) (#64317)
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
1 parent 2c79ca0 commit bb241ee

File tree

1 file changed

+31
-19
lines changed
  • packages/compiler-cli/src/ngtsc/annotations/common/src

1 file changed

+31
-19
lines changed

‎packages/compiler-cli/src/ngtsc/annotations/common/src/metadata.ts‎

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {ErrorCode, FatalDiagnosticError, makeRelatedInformation} from '../../../diagnostics';
9+
import {ErrorCode, FatalDiagnosticError} from '../../../diagnostics';
1010
import {
1111
ArrowFunctionExpr,
1212
Expression,
@@ -19,6 +19,7 @@ import {
1919
import ts from 'typescript';
2020

2121
import {
22+
ClassMember,
2223
ClassMemberAccessLevel,
2324
CtorParameter,
2425
DeclarationNode,
@@ -88,15 +89,32 @@ export function extractClassMetadata(
8889
const classMembers = reflection.getMembersOfClass(clazz).filter(
8990
(member) =>
9091
!member.isStatic &&
91-
member.decorators !== null &&
92-
member.decorators.length > 0 &&
9392
// Private fields are not supported in the metadata emit
9493
member.accessLevel !== ClassMemberAccessLevel.EcmaScriptPrivate,
9594
);
96-
const duplicateDecoratedMembers = classMembers.filter(
97-
(member, i, arr) => arr.findIndex((arrayMember) => arrayMember.name === member.name) < i,
98-
);
99-
if (duplicateDecoratedMembers.length > 0) {
95+
96+
const decoratedMembers: {key: string; value: Expression; quoted: boolean}[] = [];
97+
const seenMemberNames = new Set<string>();
98+
let duplicateDecoratedMembers: ClassMember[] | null = null;
99+
100+
for (const member of classMembers) {
101+
if (member.decorators !== null && member.decorators.length > 0) {
102+
decoratedMembers.push({
103+
key: member.name,
104+
quoted: false,
105+
value: decoratedClassMemberToMetadata(member.decorators!, isCore),
106+
});
107+
108+
if (seenMemberNames.has(member.name)) {
109+
duplicateDecoratedMembers ??= [];
110+
duplicateDecoratedMembers.push(member);
111+
} else {
112+
seenMemberNames.add(member.name);
113+
}
114+
}
115+
}
116+
117+
if (duplicateDecoratedMembers !== null) {
100118
// This should theoretically never happen, because the only way to have duplicate instance
101119
// member names is getter/setter pairs and decorators cannot appear in both a getter and the
102120
// corresponding setter.
@@ -107,13 +125,9 @@ export function extractClassMetadata(
107125
duplicateDecoratedMembers.map((member) => member.name).join(', '),
108126
);
109127
}
110-
const decoratedMembers = classMembers.map((member) =>
111-
classMemberToMetadata(member.nameNode ?? member.name, member.decorators!, isCore),
112-
);
128+
113129
if (decoratedMembers.length > 0) {
114-
metaPropDecorators = new WrappedNodeExpr(
115-
ts.factory.createObjectLiteralExpression(decoratedMembers),
116-
);
130+
metaPropDecorators = literalMap(decoratedMembers);
117131
}
118132

119133
return {
@@ -153,16 +167,14 @@ function ctorParameterToMetadata(param: CtorParameter, isCore: boolean): Express
153167
/**
154168
* Convert a reflected class member to metadata.
155169
*/
156-
function classMemberToMetadata(
157-
name: ts.PropertyName | string,
170+
function decoratedClassMemberToMetadata(
158171
decorators: Decorator[],
159172
isCore: boolean,
160-
): ts.PropertyAssignment {
173+
): LiteralArrayExpr {
161174
const ngDecorators = decorators
162175
.filter((dec) => isAngularDecorator(dec, isCore))
163-
.map((decorator: Decorator) => decoratorToMetadata(decorator));
164-
const decoratorMeta = ts.factory.createArrayLiteralExpression(ngDecorators);
165-
return ts.factory.createPropertyAssignment(name, decoratorMeta);
176+
.map((decorator: Decorator) => new WrappedNodeExpr(decoratorToMetadata(decorator)));
177+
return new LiteralArrayExpr(ngDecorators);
166178
}
167179

168180
/**

0 commit comments

Comments
 (0)