fix(compiler-cli): support namespaced query types in directives (#38959)

Previously directive "queries" that relied upon a namespaced type

```ts
queries: {
  'mcontent': new core.ContentChild('test2'),
}
```

caused an error to be thrown. This is now supported.

PR Close #38959
This commit is contained in:
Pete Bacon Darwin 2020-09-30 20:55:30 +01:00 committed by atscott
parent f4fee86f77
commit 2736a43ecb
2 changed files with 12 additions and 3 deletions

View File

@ -463,12 +463,20 @@ export function extractQueriesFromDecorator(
} }
reflectObjectLiteral(queryData).forEach((queryExpr, propertyName) => { reflectObjectLiteral(queryData).forEach((queryExpr, propertyName) => {
queryExpr = unwrapExpression(queryExpr); queryExpr = unwrapExpression(queryExpr);
if (!ts.isNewExpression(queryExpr) || !ts.isIdentifier(queryExpr.expression)) { if (!ts.isNewExpression(queryExpr)) {
throw new FatalDiagnosticError( throw new FatalDiagnosticError(
ErrorCode.VALUE_HAS_WRONG_TYPE, queryData, ErrorCode.VALUE_HAS_WRONG_TYPE, queryData,
'Decorator query metadata must be an instance of a query type'); 'Decorator query metadata must be an instance of a query type');
} }
const type = reflector.getImportOfIdentifier(queryExpr.expression); const queryType = ts.isPropertyAccessExpression(queryExpr.expression) ?
queryExpr.expression.name :
queryExpr.expression;
if (!ts.isIdentifier(queryType)) {
throw new FatalDiagnosticError(
ErrorCode.VALUE_HAS_WRONG_TYPE, queryData,
'Decorator query metadata must be an instance of a query type');
}
const type = reflector.getImportOfIdentifier(queryType);
if (type === null || (!isCore && type.from !== '@angular/core') || if (type === null || (!isCore && type.from !== '@angular/core') ||
!QUERY_TYPES.has(type.name)) { !QUERY_TYPES.has(type.name)) {
throw new FatalDiagnosticError( throw new FatalDiagnosticError(

View File

@ -3064,12 +3064,13 @@ runInEachFileSystem(os => {
it('should generate queries for directives', () => { it('should generate queries for directives', () => {
env.write(`test.ts`, ` env.write(`test.ts`, `
import {Directive, ContentChild, ContentChildren, TemplateRef, ViewChild} from '@angular/core'; import {Directive, ContentChild, ContentChildren, TemplateRef, ViewChild} from '@angular/core';
import * as core from '@angular/core';
@Directive({ @Directive({
selector: '[test]', selector: '[test]',
queries: { queries: {
'mview': new ViewChild('test1'), 'mview': new ViewChild('test1'),
'mcontent': new ContentChild('test2'), 'mcontent': new core.ContentChild('test2'),
} }
}) })
class FooCmp { class FooCmp {