Skip to content

Commit

Permalink
fix(Compiler): relax childIsRecursive check
Browse files Browse the repository at this point in the history
Fix how the compiler checks for recursive components by also considering
component descendants. Previously, it only checked if the current
component was evaluated previously. This failed in certain cases of
mutually recursive components, causing `createAsync` in tests to not
resolve.

closes [7084](#7084)
  • Loading branch information
KiaraGrouwstra committed Jun 10, 2016
1 parent 80de38b commit d31058f
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
5 changes: 5 additions & 0 deletions modules/@angular/compiler/src/runtime_compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ export class RuntimeCompiler implements ComponentResolver {
var childViewPipes: CompilePipeMetadata[] =
this._metadataResolver.getViewPipesMetadata(dep.comp.type.runtime);
var childIsRecursive = ListWrapper.contains(childCompilingComponentsPath, childCacheKey);
childViewDirectives.map(x => x.type.runtime).forEach(descendant => {
if (ListWrapper.contains(childCompilingComponentsPath, descendant)) {
childIsRecursive = true;
}
});
childCompilingComponentsPath.push(childCacheKey);

var childComp =
Expand Down
41 changes: 40 additions & 1 deletion modules/@angular/core/test/linker/regression_integration_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {
ViewMetadata,
PLATFORM_PIPES,
OpaqueToken,
Injector
Injector,
forwardRef
} from '@angular/core';
import {NgIf, NgClass} from '@angular/common';
import {CompilerConfig} from '@angular/compiler';
Expand Down Expand Up @@ -177,6 +178,16 @@ function declareTests(isJit: boolean) {
async.done();
});
}));

it('should handle mutual recursion entered from multiple sides - #7084',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.createAsync(FakeRecursiveComp)
.then((fixture) => {
fixture.detectChanges();
expect(fixture.nativeElement).toHaveText('[]');
async.done();
});
}));


});
Expand All @@ -200,3 +211,31 @@ class CustomPipe implements PipeTransform {
@Component({selector: 'cmp-content', template: `<ng-content></ng-content>`})
class CmpWithNgContent {
}

@Component({
selector: 'left',
template: `L<right *ngIf="false"></right>`,
directives: [
forwardRef(() => RightComp),
]
})
class LeftComp {}

@Component({
selector: 'right',
template: `R<left *ngIf="false"></left>`,
directives: [
forwardRef(() => LeftComp),
]
})
class RightComp {}

@Component({
selector: 'fakeRecursiveComp',
template: `[<left *ngIf="false"></left><right *ngIf="false"></right>]`,
directives: [
forwardRef(() => LeftComp),
forwardRef(() => RightComp),
]
})
export class FakeRecursiveComp {}

0 comments on commit d31058f

Please sign in to comment.