Skip to content

Commit

Permalink
fix(compiler): emit correct type-check-blocks with TemplateRef's (#20463
Browse files Browse the repository at this point in the history
)

The type-check block generated with `"fullTemplateTypeCheck"` was
invalid if the it contained a template ref as would be generated
using the `else` micro-syntax of `NgIf`.

Fixes: #19485

PR Close #20463
  • Loading branch information
chuckjaz authored and mhevery committed Nov 18, 2017
1 parent 3df1542 commit 81f1d42
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
20 changes: 19 additions & 1 deletion packages/compiler-cli/test/diagnostics/check_types_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,23 @@ describe('ng type checker', () => {
addTests({fullTemplateTypeCheck: true});
});

describe('regressions', () => {
// #19485
it('should accept if else (TemplateRef)', () => {
accept(
{
'src/app.component.html': `
<div class="text-center" *ngIf="!person; else e">
No person supplied.
</div>
<ng-template #e>
Welcome {{person.name}}!
<ng-template>`
},
{fullTemplateTypeCheck: true});
});
});

function addTests(config: {fullTemplateTypeCheck: boolean}) {
function a(template: string) { accept({'src/app.component.html': template}, config); }

Expand Down Expand Up @@ -234,6 +251,7 @@ const QUICKSTART = {
`,
'src/app.module.ts': `
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AppComponent, APipe, ADirective } from './app.component';
import { LibDirective, LibPipe } from './lib';
Expand All @@ -246,7 +264,7 @@ const QUICKSTART = {
@NgModule({
declarations: [ AppComponent, APipe, ADirective ],
bootstrap: [ AppComponent ],
imports: [ LibModule ]
imports: [ LibModule, CommonModule ]
})
export class AppModule { }
`
Expand Down
16 changes: 16 additions & 0 deletions packages/compiler/src/aot/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,16 @@ export class AotCompiler {
// and they also cause TypeScript to include these files into the program too,
// which will make them part of the analyzedFiles.
const externalReferences: StaticSymbol[] = [
// Add references that are available from all the modules and imports.
...ngModuleMeta.transitiveModule.directives.map(d => d.reference),
...ngModuleMeta.transitiveModule.pipes.map(d => d.reference),
...ngModuleMeta.importedModules.map(m => m.type.reference),
...ngModuleMeta.exportedModules.map(m => m.type.reference),

// Add references that might be inserted by the template compiler.
...this._externalIdentifierReferences([Identifiers.TemplateRef, Identifiers.ElementRef]),
];

const externalReferenceVars = new Map<any, string>();
externalReferences.forEach((ref, typeIndex) => {
if (this._host.isSourceFile(ref.filePath)) {
Expand Down Expand Up @@ -248,6 +253,17 @@ export class AotCompiler {
}
}

private _externalIdentifierReferences(references: o.ExternalReference[]): StaticSymbol[] {
const result: StaticSymbol[] = [];
for (let reference of references) {
const token = createTokenForExternalReference(this._reflector, reference);
if (token.identifier) {
result.push(token.identifier.reference);
}
}
return result;
}

private _createTypeCheckBlock(
ctx: OutputContext, componentId: string, moduleMeta: CompileNgModuleMetadata,
compMeta: CompileDirectiveMetadata, directives: CompileIdentifierMetadata[],
Expand Down

0 comments on commit 81f1d42

Please sign in to comment.