fix(compiler-cli): do not fold errors past calls in the collector (#21708)

Folding errors passed calls prevented the static reflector from
begin able to ignore errors in annotations it doesn't know as
the call to the unknown annotation was elided from the metadata.

Fixes: #21273

PR Close #21708
This commit is contained in:
Chuck Jazdzewski 2018-01-22 11:30:58 -08:00 committed by Miško Hevery
parent e82812b9a9
commit dd8679037e
5 changed files with 52 additions and 10 deletions

View File

@ -289,7 +289,7 @@ export class MetadataCollector {
ts.TypeAliasDeclaration | ts.EnumDeclaration) => exportedIdentifierName(node.name);
// Predeclare classes and functions
// Pre-declare classes and functions
ts.forEachChild(sourceFile, node => {
switch (node.kind) {
case ts.SyntaxKind.ClassDeclaration:
@ -454,7 +454,7 @@ export class MetadataCollector {
};
} else {
nextDefaultValue =
recordEntry(errorSym('Unsuppported enum member name', member.name), node);
recordEntry(errorSym('Unsupported enum member name', member.name), node);
}
}
if (writtenMembers) {

View File

@ -356,9 +356,6 @@ export class Evaluator {
}
}
const args = arrayOrEmpty(callExpression.arguments).map(arg => this.evaluateNode(arg));
if (!this.options.verboseInvalidExpression && args.some(isMetadataError)) {
return args.find(isMetadataError);
}
if (this.isFoldable(callExpression)) {
if (isMethodCallOf(callExpression, 'concat')) {
const arrayValue = <MetadataValue[]>this.evaluateNode(

View File

@ -1054,11 +1054,21 @@ describe('Collector', () => {
expect(metadata.metadata.MyComponent).toEqual({
__symbolic: 'class',
decorators: [{
__symbolic: 'call',
expression: {
__symbolic: 'reference',
module: '@angular/core',
name: 'Component',
line: 4,
character: 9
},
arguments: [{
__symbolic: 'error',
message: 'Expression form not supported',
line: 5,
character: 55
}]
}]
});
});
});

View File

@ -1698,6 +1698,40 @@ describe('ngc transformer command-line', () => {
expect(messages[0]).toContain(`is imported recursively by the module 'MyFaultyImport`);
});
// Regression test for #21273
it('should not report errors for unknown property annotations', () => {
write('src/tsconfig.json', `{
"extends": "../tsconfig-base.json",
"files": ["test-module.ts"]
}`);
write('src/test-decorator.ts', `
export function Convert(p: any): any {
// Make sur this doesn't look like a macro function
var r = p;
return r;
}
`);
write('src/test-module.ts', `
import {Component, Input, NgModule} from '@angular/core';
import {Convert} from './test-decorator';
@Component({template: '{{name}}'})
export class TestComponent {
@Input() @Convert(convert) name: string;
}
function convert(n: any) { return n; }
@NgModule({declarations: [TestComponent]})
export class TestModule {}
`);
const messages: string[] = [];
expect(
main(['-p', path.join(basePath, 'src/tsconfig.json')], message => messages.push(message)))
.toBe(0, `Compile failed:\n ${messages.join('\n ')}`);
});
it('should allow using 2 classes with the same name in declarations with noEmitOnError=true',
() => {
write('src/tsconfig.json', `{

View File

@ -364,7 +364,8 @@ describe('StaticReflector', () => {
const classData: any = moduleMetadata['InvalidMetadata'];
expect(classData).toBeDefined();
simplify(
reflector.getStaticSymbol('/tmp/src/invalid-metadata.ts', ''), classData.decorators[0]);
reflector.getStaticSymbol('/tmp/src/invalid-metadata.ts', ''),
classData.decorators[0].arguments);
} catch (e) {
expect(e.position).toBeDefined();
threw = true;