feat(ivy): support separate .js and .d.ts trees when generating imports (#26403)

The `NgModule` handler generates `R3References` for its declarations, imports,
exports, and bootstrap components, based on the relative import path
between the module and the classes it's referring to. This works fine for
compilation of a .ts Program inside ngtsc, but in ngcc the import needed
in the .d.ts file may be very different to the import needed between .js
files (for example, if the .js files are flattened and the .d.ts is not).

This commit introduces a new API in the `ReflectionHost` for extracting the
.d.ts version of a declaration, and makes use of it in the
`NgModuleDecorationHandler` to write a correct expression for the `NgModule`
definition type.

PR Close #26403
This commit is contained in:
Pete Bacon Darwin
2018-10-15 11:48:03 +01:00
committed by Kara Erickson
parent eb5d3088a4
commit 1918f8d5b5
8 changed files with 74 additions and 24 deletions

View File

@ -15,7 +15,7 @@ import {findAll, getNameText, getOriginalSymbol, isDefined} from '../utils';
import {DecoratedClass} from './decorated_class';
import {DecoratedFile} from './decorated_file';
import {NgccReflectionHost, PRE_NGCC_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host';
import {NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host';
export const DECORATORS = 'decorators' as ts.__String;
export const PROP_DECORATORS = 'propDecorators' as ts.__String;
@ -213,13 +213,13 @@ export class Fesm2015ReflectionHost extends TypeScriptReflectionHost implements
/**
* Search the given module for variable declarations in which the initializer
* is an identifier marked with the `PRE_NGCC_MARKER`.
* is an identifier marked with the `PRE_R3_MARKER`.
* @param module the module in which to search for switchable declarations.
* @returns an array of variable declarations that match.
*/
getSwitchableDeclarations(module: ts.Node): SwitchableVariableDeclaration[] {
// Don't bother to walk the AST if the marker is not found in the text
return module.getText().indexOf(PRE_NGCC_MARKER) >= 0 ?
return module.getText().indexOf(PRE_R3_MARKER) >= 0 ?
findAll(module, isSwitchableVariableDeclaration) :
[];
}

View File

@ -9,14 +9,14 @@ import * as ts from 'typescript';
import {ReflectionHost} from '../../../ngtsc/host';
import {DecoratedFile} from './decorated_file';
export const PRE_NGCC_MARKER = '__PRE_R3__';
export const POST_NGCC_MARKER = '__POST_R3__';
export const PRE_R3_MARKER = '__PRE_R3__';
export const POST_R3_MARKER = '__POST_R3__';
export type SwitchableVariableDeclaration = ts.VariableDeclaration & {initializer: ts.Identifier};
export function isSwitchableVariableDeclaration(node: ts.Node):
node is SwitchableVariableDeclaration {
return ts.isVariableDeclaration(node) && !!node.initializer &&
ts.isIdentifier(node.initializer) && node.initializer.text.endsWith(PRE_NGCC_MARKER);
ts.isIdentifier(node.initializer) && node.initializer.text.endsWith(PRE_R3_MARKER);
}
/**
@ -33,7 +33,7 @@ export interface NgccReflectionHost extends ReflectionHost {
/**
* Search the given module for variable declarations in which the initializer
* is an identifier marked with the `PRE_NGCC_MARKER`.
* is an identifier marked with the `PRE_R3_MARKER`.
* @param module The module in which to search for switchable declarations.
* @returns An array of variable declarations that match.
*/

View File

@ -7,7 +7,7 @@
*/
import * as ts from 'typescript';
import MagicString from 'magic-string';
import {NgccReflectionHost, POST_NGCC_MARKER, PRE_NGCC_MARKER, SwitchableVariableDeclaration} from '../host/ngcc_host';
import {NgccReflectionHost, POST_R3_MARKER, PRE_R3_MARKER, SwitchableVariableDeclaration} from '../host/ngcc_host';
import {AnalyzedClass} from '../analysis/decoration_analyzer';
import {Renderer} from './renderer';
@ -85,7 +85,7 @@ export class Fesm2015Renderer extends Renderer {
declarations.forEach(declaration => {
const start = declaration.initializer.getStart();
const end = declaration.initializer.getEnd();
const replacement = declaration.initializer.text.replace(PRE_NGCC_MARKER, POST_NGCC_MARKER);
const replacement = declaration.initializer.text.replace(PRE_R3_MARKER, POST_R3_MARKER);
outputText.overwrite(start, end, replacement);
});
}