fix(ivy): correctly write cross-file references (#25080)

There is a bug in the existing handling for cross-file references.
Suppose there are two files, module.ts and component.ts.

component.ts declares two components, one of which uses the other.
In the Ivy model, this means the component will get a directives:
reference to the other in its defineComponent call.

That reference is generated by looking at the declared components
of the module (in module.ts). However, the way ngtsc tracks this
reference, it ends up comparing the identifier of the component
in module.ts with the component.ts file, detecting they're not in
the same file, and generating a relative import.

This commit changes ngtsc to track all identifiers of a reference,
including the one by which it is declared. This allows toExpression()
to correctly decide that a local reference is okay in component.ts.

PR Close #25080
This commit is contained in:
Alex Rickabaugh
2018-07-25 11:16:00 -07:00
committed by Igor Minar
parent ed7aa1c3e5
commit 13a0d527f6
2 changed files with 68 additions and 40 deletions

View File

@ -568,4 +568,38 @@ describe('ngtsc behavioral tests', () => {
expect(jsContents).toContain('i0.ɵd(dirIndex).onClick($event)');
expect(jsContents).toContain('i0.ɵd(dirIndex).onChange(i0.ɵd(dirIndex).arg)');
});
it('should correctly recognize local symbols', () => {
writeConfig();
write('module.ts', `
import {NgModule} from '@angular/core';
import {Dir, Comp} from './test';
@NgModule({
declarations: [Dir, Comp],
exports: [Dir, Comp],
})
class Module {}
`);
write(`test.ts`, `
import {Component, Directive} from '@angular/core';
@Directive({
selector: '[dir]',
})
export class Dir {}
@Component({
selector: 'test',
template: '<div dir>Test</div>',
})
export class Comp {}
`);
const exitCode = main(['-p', basePath], errorSpy);
expect(errorSpy).not.toHaveBeenCalled();
expect(exitCode).toBe(0);
const jsContents = getContents('test.js');
expect(jsContents).not.toMatch(/import \* as i[0-9] from ['"].\/test['"]/);
});
});