Skip to content

Commit ab0c0cb

Browse files
crisbetothePunderWoman
authored andcommitted
refactor(compiler-cli): add function to identify model fields (angular#54252)
Adds a function to the compiler to help us identify fields initialized to a `model`. PR Close angular#54252
1 parent 3e0a20d commit ab0c0cb

5 files changed

Lines changed: 68 additions & 2 deletions

File tree

packages/compiler-cli/src/ngtsc/annotations/directive/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ export * from './src/shared';
1212
export * from './src/input_function';
1313
export * from './src/output_function';
1414
export * from './src/query_functions';
15+
export * from './src/model_function';

packages/compiler-cli/src/ngtsc/annotations/directive/src/initializer_functions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {CORE_MODULE} from '../../common';
2424
*/
2525

2626
export type InitializerApiFunction =
27-
'input'|'ɵoutput'|'output'|'viewChild'|'viewChildren'|'contentChild'|'contentChildren';
27+
'input'|'model'|'ɵoutput'|'output'|'viewChild'|'viewChildren'|'contentChild'|'contentChildren';
2828

2929
/**
3030
* Metadata describing an Angular class member that was recognized through
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import ts from 'typescript';
10+
11+
import {ModelMapping} from '../../../metadata';
12+
import {ClassMember, ReflectionHost} from '../../../reflection';
13+
14+
import {tryParseInitializerApiMember} from './initializer_functions';
15+
import {parseAndValidateInputAndOutputOptions} from './input_output_parse_options';
16+
17+
/**
18+
* Attempts to parse a model class member. Returns the parsed model mapping if possible.
19+
*/
20+
export function tryParseSignalModelMapping(
21+
member: Pick<ClassMember, 'name'|'value'>, reflector: ReflectionHost,
22+
isCore: boolean): ModelMapping|null {
23+
const model = tryParseInitializerApiMember(['model'], member, reflector, isCore);
24+
if (model === null) {
25+
return null;
26+
}
27+
28+
const optionsNode =
29+
(model.isRequired ? model.call.arguments[0] : model.call.arguments[1]) as ts.Expression |
30+
undefined;
31+
const options =
32+
optionsNode !== undefined ? parseAndValidateInputAndOutputOptions(optionsNode) : null;
33+
const classPropertyName = member.name;
34+
const bindingPropertyName = options?.alias ?? classPropertyName;
35+
36+
return {
37+
input: {
38+
isSignal: true,
39+
transform: null,
40+
classPropertyName,
41+
bindingPropertyName,
42+
required: model.isRequired,
43+
},
44+
output: {
45+
isSignal: false,
46+
classPropertyName,
47+
bindingPropertyName: bindingPropertyName + 'Change',
48+
}
49+
};
50+
}

packages/compiler-cli/src/ngtsc/annotations/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
export {forwardRefResolver, getAngularDecorators, isAngularDecorator, NoopReferencesRegistry, ReferencesRegistry, ResourceLoader, ResourceLoaderContext} from './common';
1212
export {ComponentDecoratorHandler} from './component';
13-
export {DirectiveDecoratorHandler, queryDecoratorNames, QueryFunctionName, tryParseInitializerBasedOutput, tryParseSignalInputMapping, tryParseSignalQueryFromInitializer} from './directive';
13+
export {DirectiveDecoratorHandler, queryDecoratorNames, QueryFunctionName, tryParseInitializerBasedOutput, tryParseSignalInputMapping, tryParseSignalModelMapping, tryParseSignalQueryFromInitializer} from './directive';
1414
export {NgModuleDecoratorHandler} from './ng_module';
1515
export {InjectableDecoratorHandler} from './src/injectable';
1616
export {PipeDecoratorHandler} from './src/pipe';

packages/compiler-cli/src/ngtsc/metadata/src/api.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,21 @@ export type InputMapping = InputOrOutput&{
150150
transform: DecoratorInputTransform|null
151151
};
152152

153+
/** Metadata for a model mapping. */
154+
export interface ModelMapping {
155+
/** Information about the input declared by the model. */
156+
input: InputOrOutput&{
157+
/** Whether the input declared by the model is required. */
158+
required: boolean;
159+
160+
/** Model inputs can't have transforms. Keeping it here for consistency. */
161+
transform: null;
162+
};
163+
164+
/** Information about the output implicitly declared by the model. */
165+
output: InputOrOutput;
166+
}
167+
153168
/** Metadata for an `@Input()` transform function. */
154169
export interface DecoratorInputTransform {
155170
/**

0 commit comments

Comments
 (0)