fix(ivy): allow abstract directives to have an invalid constructor (#32987)

For abstract directives, i.e. directives without a selector, it may
happen that their constructor is called explicitly from a subclass,
hence its parameters are not required to be valid for Angular's DI
purposes. Prior to this commit however, having an abstract directive
with a constructor that has parameters that are not eligible for
Angular's DI would produce a compilation error.

A similar scenario may occur for `@Injectable`s, where an explicit
`use*` definition allows for the constructor to be irrelevant. For
example, the situation where `useFactory` is specified allows for the
constructor to be called explicitly with any value, so its constructor
parameters are not required to be valid. For `@Injectable`s this is
handled by generating a DI factory function that throws.

This commit implements the same solution for abstract directives, such
that a compilation error is avoided while still producing an error at
runtime if the type is instantiated implicitly by Angular's DI
mechanism.

Fixes #32981

PR Close #32987
This commit is contained in:
JoostK
2019-10-03 21:54:49 +02:00
committed by Andrew Kushnir
parent e4e8dbdee0
commit 8d15bfa6ee
28 changed files with 307 additions and 117 deletions

View File

@ -45,6 +45,7 @@ export interface CompilerFacade {
createParseSourceSpan(kind: string, typeName: string, sourceUrl: string): ParseSourceSpan;
R3ResolvedDependencyType: typeof R3ResolvedDependencyType;
R3FactoryTarget: typeof R3FactoryTarget;
ResourceLoader: {new (): ResourceLoader};
}
@ -70,6 +71,14 @@ export enum R3ResolvedDependencyType {
ChangeDetectorRef = 2,
}
export enum R3FactoryTarget {
Directive = 0,
Component = 1,
Injectable = 2,
Pipe = 3,
NgModule = 4,
}
export interface R3DependencyMetadataFacade {
token: any;
resolved: R3ResolvedDependencyType;
@ -167,7 +176,7 @@ export interface R3FactoryDefMetadataFacade {
typeArgumentCount: number;
deps: R3DependencyMetadataFacade[]|null;
injectFn: 'directiveInject'|'inject';
isPipe: boolean;
target: R3FactoryTarget;
}
export type ViewEncapsulation = number;