fix(ivy): queries not being inherited from undecorated classes (#30015)
Fixes view and content queries not being inherited in Ivy, if the base class hasn't been annotated with an Angular decorator (e.g. `Component` or `Directive`). Also reworks the way the `ngBaseDef` is created so that it is added at the same point as the queries, rather than inside of the `Input` and `Output` decorators. This PR partially resolves FW-1275. Support for host bindings will be added in a follow-up, because this PR is somewhat large as it is. PR Close #30015
This commit is contained in:

committed by
Andrew Kushnir

parent
8ca208ff59
commit
c7f1b0a97f
@ -6,12 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {R3BaseRefMetaData, compileBaseDefFromMetadata} from '@angular/compiler';
|
||||
import {ConstantPool, R3BaseRefMetaData, compileBaseDefFromMetadata} from '@angular/compiler';
|
||||
|
||||
import {PartialEvaluator} from '../../partial_evaluator';
|
||||
import {ClassDeclaration, ClassMember, Decorator, ReflectionHost} from '../../reflection';
|
||||
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../transform';
|
||||
|
||||
import {queriesFromFields} from './directive';
|
||||
import {isAngularDecorator} from './util';
|
||||
|
||||
function containsNgTopLevelDecorator(decorators: Decorator[] | null, isCore: boolean): boolean {
|
||||
@ -44,17 +45,30 @@ export class BaseDefDecoratorHandler implements
|
||||
|
||||
this.reflector.getMembersOfClass(node).forEach(property => {
|
||||
const {decorators} = property;
|
||||
if (decorators) {
|
||||
for (const decorator of decorators) {
|
||||
if (isAngularDecorator(decorator, 'Input', this.isCore)) {
|
||||
result = result || {};
|
||||
const inputs = result.inputs = result.inputs || [];
|
||||
inputs.push({decorator, property});
|
||||
} else if (isAngularDecorator(decorator, 'Output', this.isCore)) {
|
||||
result = result || {};
|
||||
const outputs = result.outputs = result.outputs || [];
|
||||
outputs.push({decorator, property});
|
||||
}
|
||||
if (!decorators) {
|
||||
return;
|
||||
}
|
||||
for (const decorator of decorators) {
|
||||
if (isAngularDecorator(decorator, 'Input', this.isCore)) {
|
||||
result = result || {};
|
||||
const inputs = result.inputs = result.inputs || [];
|
||||
inputs.push({decorator, property});
|
||||
} else if (isAngularDecorator(decorator, 'Output', this.isCore)) {
|
||||
result = result || {};
|
||||
const outputs = result.outputs = result.outputs || [];
|
||||
outputs.push({decorator, property});
|
||||
} else if (
|
||||
isAngularDecorator(decorator, 'ViewChild', this.isCore) ||
|
||||
isAngularDecorator(decorator, 'ViewChildren', this.isCore)) {
|
||||
result = result || {};
|
||||
const viewQueries = result.viewQueries = result.viewQueries || [];
|
||||
viewQueries.push({member: property, decorators});
|
||||
} else if (
|
||||
isAngularDecorator(decorator, 'ContentChild', this.isCore) ||
|
||||
isAngularDecorator(decorator, 'ContentChildren', this.isCore)) {
|
||||
result = result || {};
|
||||
const queries = result.queries = result.queries || [];
|
||||
queries.push({member: property, decorators});
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -110,11 +124,21 @@ export class BaseDefDecoratorHandler implements
|
||||
});
|
||||
}
|
||||
|
||||
if (metadata.viewQueries) {
|
||||
analysis.viewQueries =
|
||||
queriesFromFields(metadata.viewQueries, this.reflector, this.evaluator);
|
||||
}
|
||||
|
||||
if (metadata.queries) {
|
||||
analysis.queries = queriesFromFields(metadata.queries, this.reflector, this.evaluator);
|
||||
}
|
||||
|
||||
return {analysis};
|
||||
}
|
||||
|
||||
compile(node: ClassDeclaration, analysis: R3BaseRefMetaData): CompileResult[]|CompileResult {
|
||||
const {expression, type} = compileBaseDefFromMetadata(analysis);
|
||||
compile(node: ClassDeclaration, analysis: R3BaseRefMetaData, pool: ConstantPool):
|
||||
CompileResult[]|CompileResult {
|
||||
const {expression, type} = compileBaseDefFromMetadata(analysis, pool);
|
||||
|
||||
return {
|
||||
name: 'ngBaseDef',
|
||||
@ -127,4 +151,6 @@ export class BaseDefDecoratorHandler implements
|
||||
export interface R3BaseRefDecoratorDetection {
|
||||
inputs?: Array<{property: ClassMember, decorator: Decorator}>;
|
||||
outputs?: Array<{property: ClassMember, decorator: Decorator}>;
|
||||
viewQueries?: {member: ClassMember, decorators: Decorator[]}[];
|
||||
queries?: {member: ClassMember, decorators: Decorator[]}[];
|
||||
}
|
||||
|
Reference in New Issue
Block a user