fix(ivy): throw if @Input and @ContentChild share a property (#28415)

In View Engine, we supported @Input and @ContentChild annotations
on the same property. This feature was somewhat brittle because
it would only work for static queries, so it would break if a
content child was passed in wrapped in an *ngIf. Due to the
inconsistent behavior and low usage both internally and externally,
we will likely be deprecating it in the next version, and it does
not make sense to perpetuate it in Ivy.

This commit ensures that we now throw in Ivy if we encounter the
two annotations on the same property.

PR Close #28415
This commit is contained in:
Kara Erickson
2019-01-28 20:45:41 -08:00
committed by Jason Aden
parent 7d9aa67d8c
commit fdc6e159b4
4 changed files with 70 additions and 5 deletions

View File

@ -13,7 +13,7 @@ import {resolveForwardRef} from '../../di/forward_ref';
import {getReflect, reflectDependencies} from '../../di/jit/util';
import {Type} from '../../interface/type';
import {Query} from '../../metadata/di';
import {Component, Directive} from '../../metadata/directives';
import {Component, Directive, Input} from '../../metadata/directives';
import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from '../../metadata/resource_loading';
import {ViewEncapsulation} from '../../metadata/view';
import {EMPTY_ARRAY, EMPTY_OBJ} from '../empty';
@ -180,13 +180,17 @@ function extractQueriesMetadata(
const queriesMeta: R3QueryMetadataFacade[] = [];
for (const field in propMetadata) {
if (propMetadata.hasOwnProperty(field)) {
propMetadata[field].forEach(ann => {
const annotations = propMetadata[field];
annotations.forEach(ann => {
if (isQueryAnn(ann)) {
if (!ann.selector) {
throw new Error(
`Can't construct a query for the property "${field}" of ` +
`"${renderStringify(type)}" since the query selector wasn't defined.`);
}
if (annotations.some(isInputAnn)) {
throw new Error(`Cannot combine @Input decorators with query decorators`);
}
queriesMeta.push(convertToR3QueryMetadata(field, ann));
}
});
@ -213,6 +217,10 @@ function isViewQuery(value: any): value is Query {
return name === 'ViewChild' || name === 'ViewChildren';
}
function isInputAnn(value: any): value is Input {
return value.ngMetadataName === 'Input';
}
function splitByComma(value: string): string[] {
return value.split(',').map(piece => piece.trim());
}