This reverts commit 4faac78e32657f6b60b98b4330e746ba645c8f2e. internal failure: https://test.corp.google.com/ui#id=OCL:329948619:BASE:329967516:1599160428139:d63165ae PR Close #38765
This commit is contained in:
parent
b0ca3cd0c4
commit
18f84a0328
@ -495,49 +495,36 @@ export class ComponentDecoratorHandler implements
|
|||||||
// Set up the R3TargetBinder, as well as a 'directives' array and a 'pipes' map that are later
|
// Set up the R3TargetBinder, as well as a 'directives' array and a 'pipes' map that are later
|
||||||
// fed to the TemplateDefinitionBuilder. First, a SelectorMatcher is constructed to match
|
// fed to the TemplateDefinitionBuilder. First, a SelectorMatcher is constructed to match
|
||||||
// directives that are in scope.
|
// directives that are in scope.
|
||||||
type MatchedDirective = DirectiveMeta&{selector: string};
|
const matcher = new SelectorMatcher<DirectiveMeta&{expression: Expression}>();
|
||||||
const matcher = new SelectorMatcher<MatchedDirective>();
|
const directives: {selector: string, expression: Expression}[] = [];
|
||||||
|
|
||||||
for (const dir of scope.compilation.directives) {
|
for (const dir of scope.compilation.directives) {
|
||||||
if (dir.selector !== null) {
|
const {ref, selector} = dir;
|
||||||
matcher.addSelectables(CssSelector.parse(dir.selector), dir as MatchedDirective);
|
if (selector !== null) {
|
||||||
|
const expression = this.refEmitter.emit(ref, context);
|
||||||
|
directives.push({selector, expression});
|
||||||
|
matcher.addSelectables(CssSelector.parse(selector), {...dir, expression});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const pipes = new Map<string, Reference<ClassDeclaration>>();
|
const pipes = new Map<string, Expression>();
|
||||||
for (const pipe of scope.compilation.pipes) {
|
for (const pipe of scope.compilation.pipes) {
|
||||||
pipes.set(pipe.name, pipe.ref);
|
pipes.set(pipe.name, this.refEmitter.emit(pipe.ref, context));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, the component template AST is bound using the R3TargetBinder. This produces a
|
// Next, the component template AST is bound using the R3TargetBinder. This produces an
|
||||||
// BoundTarget, which is similar to a ts.TypeChecker.
|
// BoundTarget, which is similar to a ts.TypeChecker.
|
||||||
const binder = new R3TargetBinder(matcher);
|
const binder = new R3TargetBinder(matcher);
|
||||||
const bound = binder.bind({template: metadata.template.nodes});
|
const bound = binder.bind({template: metadata.template.nodes});
|
||||||
|
|
||||||
// The BoundTarget knows which directives and pipes matched the template.
|
// The BoundTarget knows which directives and pipes matched the template.
|
||||||
const usedDirectives = bound.getUsedDirectives().map(directive => {
|
const usedDirectives = bound.getUsedDirectives();
|
||||||
return {
|
const usedPipes = bound.getUsedPipes().map(name => pipes.get(name)!);
|
||||||
selector: directive.selector,
|
|
||||||
expression: this.refEmitter.emit(directive.ref, context),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const usedPipes: {pipeName: string, expression: Expression}[] = [];
|
|
||||||
for (const pipeName of bound.getUsedPipes()) {
|
|
||||||
if (!pipes.has(pipeName)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const pipe = pipes.get(pipeName)!;
|
|
||||||
usedPipes.push({
|
|
||||||
pipeName,
|
|
||||||
expression: this.refEmitter.emit(pipe, context),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scan through the directives/pipes actually used in the template and check whether any
|
// Scan through the directives/pipes actually used in the template and check whether any
|
||||||
// import which needs to be generated would create a cycle.
|
// import which needs to be generated would create a cycle.
|
||||||
const cycleDetected =
|
const cycleDetected =
|
||||||
usedDirectives.some(dir => this._isCyclicImport(dir.expression, context)) ||
|
usedDirectives.some(dir => this._isCyclicImport(dir.expression, context)) ||
|
||||||
usedPipes.some(pipe => this._isCyclicImport(pipe.expression, context));
|
usedPipes.some(pipe => this._isCyclicImport(pipe, context));
|
||||||
|
|
||||||
if (!cycleDetected) {
|
if (!cycleDetected) {
|
||||||
// No cycle was detected. Record the imports that need to be created in the cycle detector
|
// No cycle was detected. Record the imports that need to be created in the cycle detector
|
||||||
@ -545,8 +532,8 @@ export class ComponentDecoratorHandler implements
|
|||||||
for (const {expression} of usedDirectives) {
|
for (const {expression} of usedDirectives) {
|
||||||
this._recordSyntheticImport(expression, context);
|
this._recordSyntheticImport(expression, context);
|
||||||
}
|
}
|
||||||
for (const {expression} of usedPipes) {
|
for (const pipe of usedPipes) {
|
||||||
this._recordSyntheticImport(expression, context);
|
this._recordSyntheticImport(pipe, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the directive/pipe arrays in ɵcmp need to be wrapped in closures.
|
// Check whether the directive/pipe arrays in ɵcmp need to be wrapped in closures.
|
||||||
@ -555,11 +542,16 @@ export class ComponentDecoratorHandler implements
|
|||||||
const wrapDirectivesAndPipesInClosure =
|
const wrapDirectivesAndPipesInClosure =
|
||||||
usedDirectives.some(
|
usedDirectives.some(
|
||||||
dir => isExpressionForwardReference(dir.expression, node.name, context)) ||
|
dir => isExpressionForwardReference(dir.expression, node.name, context)) ||
|
||||||
usedPipes.some(
|
usedPipes.some(pipe => isExpressionForwardReference(pipe, node.name, context));
|
||||||
pipe => isExpressionForwardReference(pipe.expression, node.name, context));
|
|
||||||
|
|
||||||
data.directives = usedDirectives;
|
// Actual compilation still uses the full scope, not the narrowed scope determined by
|
||||||
data.pipes = new Map(usedPipes.map(pipe => [pipe.pipeName, pipe.expression]));
|
// R3TargetBinder. This is a hedge against potential issues with the R3TargetBinder - right
|
||||||
|
// now the TemplateDefinitionBuilder is the "source of truth" for which directives/pipes are
|
||||||
|
// actually used (though the two should agree perfectly).
|
||||||
|
//
|
||||||
|
// TODO(alxhub): switch TemplateDefinitionBuilder over to using R3TargetBinder directly.
|
||||||
|
data.directives = directives;
|
||||||
|
data.pipes = pipes;
|
||||||
data.wrapDirectivesAndPipesInClosure = wrapDirectivesAndPipesInClosure;
|
data.wrapDirectivesAndPipesInClosure = wrapDirectivesAndPipesInClosure;
|
||||||
} else {
|
} else {
|
||||||
// Declaring the directiveDefs/pipeDefs arrays directly would require imports that would
|
// Declaring the directiveDefs/pipeDefs arrays directly would require imports that would
|
||||||
|
Loading…
x
Reference in New Issue
Block a user