fix(compiler): include used components during JIT compilation of partial component declaration (#41353)

In #41104 the list of used directives was split into two arrays of used
directives and components, but the JIT side was not updated. This commit
fixes the JIT integration by including the list of used components.

Fixes #41318

PR Close #41353
This commit is contained in:
JoostK 2021-03-27 00:45:42 +01:00 committed by Alex Rickabaugh
parent 0226a11c18
commit ff9470b0a0
5 changed files with 69 additions and 17 deletions

View File

@ -200,12 +200,8 @@ export interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {
template: string;
isInline?: boolean;
styles?: string[];
directives?: {
selector: string; type: OpaqueValue | (() => OpaqueValue);
inputs?: string[];
outputs?: string[];
exportAs?: string[];
}[];
components?: R3DeclareUsedDirectiveFacade[];
directives?: R3DeclareUsedDirectiveFacade[];
pipes?: {[pipeName: string]: OpaqueValue|(() => OpaqueValue)};
viewProviders?: OpaqueValue;
animations?: OpaqueValue;
@ -215,6 +211,14 @@ export interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {
preserveWhitespaces?: boolean;
}
export interface R3DeclareUsedDirectiveFacade {
selector: string;
type: OpaqueValue|(() => OpaqueValue);
inputs?: string[];
outputs?: string[];
exportAs?: string[];
}
export interface R3UsedDirectiveMetadata {
selector: string;
inputs: string[];

View File

@ -7,7 +7,7 @@
*/
import {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, OpaqueValue, R3ComponentMetadataFacade, R3DeclareComponentFacade, R3DeclareDependencyMetadataFacade, R3DeclareDirectiveFacade, R3DeclareFactoryFacade, R3DeclareInjectorFacade, R3DeclareNgModuleFacade, R3DeclarePipeFacade, R3DeclareQueryMetadataFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3FactoryDefMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
import {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, OpaqueValue, R3ComponentMetadataFacade, R3DeclareComponentFacade, R3DeclareDependencyMetadataFacade, R3DeclareDirectiveFacade, R3DeclareFactoryFacade, R3DeclareInjectorFacade, R3DeclareNgModuleFacade, R3DeclarePipeFacade, R3DeclareQueryMetadataFacade, R3DeclareUsedDirectiveFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3FactoryDefMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
import {ConstantPool} from './constant_pool';
import {ChangeDetectionStrategy, HostBinding, HostListener, Input, Output, Type, ViewEncapsulation} from './core';
import {compileInjectable} from './injectable_compiler_2';
@ -384,7 +384,9 @@ function convertDeclareComponentFacadeToMetadata(
...convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan),
template,
styles: declaration.styles ?? [],
directives: (declaration.directives ?? []).map(convertUsedDirectiveDeclarationToMetadata),
directives: (declaration.components ?? [])
.concat(declaration.directives ?? [])
.map(convertUsedDirectiveDeclarationToMetadata),
pipes: convertUsedPipesToMetadata(declaration.pipes),
viewProviders: declaration.viewProviders !== undefined ?
new WrappedNodeExpr(declaration.viewProviders) :
@ -400,8 +402,7 @@ function convertDeclareComponentFacadeToMetadata(
};
}
function convertUsedDirectiveDeclarationToMetadata(
declaration: NonNullable<R3DeclareComponentFacade['directives']>[number]):
function convertUsedDirectiveDeclarationToMetadata(declaration: R3DeclareUsedDirectiveFacade):
R3UsedDirectiveMetadata {
return {
selector: declaration.selector,

View File

@ -116,6 +116,11 @@ const coreR3DeclareComponentFacade: core.R3DeclareComponentFacade =
const compilerR3DeclareComponentFacade: compiler.R3DeclareComponentFacade =
null! as core.R3DeclareComponentFacade;
const coreR3DeclareUsedDirectiveFacade: core.R3DeclareUsedDirectiveFacade =
null! as compiler.R3DeclareUsedDirectiveFacade;
const compilerR3DeclareUsedDirectiveFacade: compiler.R3DeclareUsedDirectiveFacade =
null! as core.R3DeclareUsedDirectiveFacade;
const coreR3UsedDirectiveMetadata: core.R3UsedDirectiveMetadata =
null! as compiler.R3UsedDirectiveMetadata;
const compilerR3UsedDirectiveMetadata: compiler.R3UsedDirectiveMetadata =

View File

@ -200,12 +200,8 @@ export interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {
template: string;
isInline?: boolean;
styles?: string[];
directives?: {
selector: string; type: OpaqueValue | (() => OpaqueValue);
inputs?: string[];
outputs?: string[];
exportAs?: string[];
}[];
components?: R3DeclareUsedDirectiveFacade[];
directives?: R3DeclareUsedDirectiveFacade[];
pipes?: {[pipeName: string]: OpaqueValue|(() => OpaqueValue)};
viewProviders?: OpaqueValue;
animations?: OpaqueValue;
@ -215,6 +211,14 @@ export interface R3DeclareComponentFacade extends R3DeclareDirectiveFacade {
preserveWhitespaces?: boolean;
}
export interface R3DeclareUsedDirectiveFacade {
selector: string;
type: OpaqueValue|(() => OpaqueValue);
inputs?: string[];
outputs?: string[];
exportAs?: string[];
}
export interface R3UsedDirectiveMetadata {
selector: string;
inputs: string[];

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ChangeDetectionStrategy, Directive, ElementRef, forwardRef, Pipe, Type, ViewEncapsulation, ɵɵngDeclareComponent} from '@angular/core';
import {ChangeDetectionStrategy, Component, Directive, ElementRef, forwardRef, Pipe, Type, ViewEncapsulation, ɵɵngDeclareComponent} from '@angular/core';
import {AttributeMarker, ComponentDef} from '../../../src/render3';
import {functionContaining} from './matcher';
@ -338,6 +338,21 @@ describe('component declaration jit compilation', () => {
});
});
it('should compile used components', () => {
const def = ɵɵngDeclareComponent({
type: TestClass,
template: '<cmp></cmp>',
components: [{
type: TestCmp,
selector: 'cmp',
}],
}) as ComponentDef<TestClass>;
expectComponentDef(def, {
directives: [TestCmp],
});
});
it('should compile used directives', () => {
const def = ɵɵngDeclareComponent({
type: TestClass,
@ -353,6 +368,25 @@ describe('component declaration jit compilation', () => {
});
});
it('should compile used directives together with used components', () => {
const def = ɵɵngDeclareComponent({
type: TestClass,
template: '<cmp dir></cmp>',
components: [{
type: TestCmp,
selector: 'cmp',
}],
directives: [{
type: TestDir,
selector: '[dir]',
}],
}) as ComponentDef<TestClass>;
expectComponentDef(def, {
directives: [TestCmp, TestDir],
});
});
it('should compile forward declared directives', () => {
const def = ɵɵngDeclareComponent({
type: TestClass,
@ -534,6 +568,10 @@ class TestClass {}
class TestDir {
}
@Component({selector: 'cmp', template: ''})
class TestCmp {
}
@Pipe({name: 'test'})
class TestPipe {
}