refactor(ivy): use wrapped metadata in all DecoratorHandlers (#26860)
Previously, the Directive, Injectable, and Pipe DecoratorHandlers were directly returning @angular/compiler metadata from their analyze() steps. This precludes returning any additional information along with that metadata. This commit introduces a wrapper interface for these handlers, opening the door for additional information to be returned from analyze(). Testing strategy: this is a refactor commit, existing test coverage is sufficient. PR Close #26860
This commit is contained in:
parent
84e311038d
commit
afbee736ea
@ -19,7 +19,9 @@ import {extractDirectiveGuards, getConstructorDependencies, isAngularCore, unwra
|
|||||||
|
|
||||||
const EMPTY_OBJECT: {[key: string]: string} = {};
|
const EMPTY_OBJECT: {[key: string]: string} = {};
|
||||||
|
|
||||||
export class DirectiveDecoratorHandler implements DecoratorHandler<R3DirectiveMetadata, Decorator> {
|
export interface DirectiveHandlerData { meta: R3DirectiveMetadata; }
|
||||||
|
export class DirectiveDecoratorHandler implements
|
||||||
|
DecoratorHandler<DirectiveHandlerData, Decorator> {
|
||||||
constructor(
|
constructor(
|
||||||
private checker: ts.TypeChecker, private reflector: ReflectionHost,
|
private checker: ts.TypeChecker, private reflector: ReflectionHost,
|
||||||
private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {}
|
private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {}
|
||||||
@ -32,7 +34,7 @@ export class DirectiveDecoratorHandler implements DecoratorHandler<R3DirectiveMe
|
|||||||
decorator => decorator.name === 'Directive' && (this.isCore || isAngularCore(decorator)));
|
decorator => decorator.name === 'Directive' && (this.isCore || isAngularCore(decorator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<R3DirectiveMetadata> {
|
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<DirectiveHandlerData> {
|
||||||
const directiveResult =
|
const directiveResult =
|
||||||
extractDirectiveMetadata(node, decorator, this.checker, this.reflector, this.isCore);
|
extractDirectiveMetadata(node, decorator, this.checker, this.reflector, this.isCore);
|
||||||
const analysis = directiveResult && directiveResult.metadata;
|
const analysis = directiveResult && directiveResult.metadata;
|
||||||
@ -54,12 +56,20 @@ export class DirectiveDecoratorHandler implements DecoratorHandler<R3DirectiveMe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {analysis};
|
if (analysis === undefined) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
analysis: {
|
||||||
|
meta: analysis,
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(node: ts.ClassDeclaration, analysis: R3DirectiveMetadata, pool: ConstantPool):
|
compile(node: ts.ClassDeclaration, analysis: DirectiveHandlerData, pool: ConstantPool):
|
||||||
CompileResult {
|
CompileResult {
|
||||||
const res = compileDirectiveFromMetadata(analysis, pool, makeBindingParser());
|
const res = compileDirectiveFromMetadata(analysis.meta, pool, makeBindingParser());
|
||||||
return {
|
return {
|
||||||
name: 'ngDirectiveDef',
|
name: 'ngDirectiveDef',
|
||||||
initializer: res.expression,
|
initializer: res.expression,
|
||||||
|
@ -16,12 +16,13 @@ import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';
|
|||||||
|
|
||||||
import {getConstructorDependencies, isAngularCore} from './util';
|
import {getConstructorDependencies, isAngularCore} from './util';
|
||||||
|
|
||||||
|
export interface InjectableHandlerData { meta: R3InjectableMetadata; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts the `compileIvyInjectable` compiler for `@Injectable` decorators to the Ivy compiler.
|
* Adapts the `compileIvyInjectable` compiler for `@Injectable` decorators to the Ivy compiler.
|
||||||
*/
|
*/
|
||||||
export class InjectableDecoratorHandler implements
|
export class InjectableDecoratorHandler implements
|
||||||
DecoratorHandler<R3InjectableMetadata, Decorator> {
|
DecoratorHandler<InjectableHandlerData, Decorator> {
|
||||||
constructor(private reflector: ReflectionHost, private isCore: boolean) {}
|
constructor(private reflector: ReflectionHost, private isCore: boolean) {}
|
||||||
|
|
||||||
detect(node: ts.Declaration, decorators: Decorator[]|null): Decorator|undefined {
|
detect(node: ts.Declaration, decorators: Decorator[]|null): Decorator|undefined {
|
||||||
@ -32,14 +33,16 @@ export class InjectableDecoratorHandler implements
|
|||||||
decorator => decorator.name === 'Injectable' && (this.isCore || isAngularCore(decorator)));
|
decorator => decorator.name === 'Injectable' && (this.isCore || isAngularCore(decorator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<R3InjectableMetadata> {
|
analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<InjectableHandlerData> {
|
||||||
return {
|
return {
|
||||||
analysis: extractInjectableMetadata(node, decorator, this.reflector, this.isCore),
|
analysis: {
|
||||||
|
meta: extractInjectableMetadata(node, decorator, this.reflector, this.isCore),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(node: ts.ClassDeclaration, analysis: R3InjectableMetadata): CompileResult {
|
compile(node: ts.ClassDeclaration, analysis: InjectableHandlerData): CompileResult {
|
||||||
const res = compileIvyInjectable(analysis);
|
const res = compileIvyInjectable(analysis.meta);
|
||||||
return {
|
return {
|
||||||
name: 'ngInjectableDef',
|
name: 'ngInjectableDef',
|
||||||
initializer: res.expression,
|
initializer: res.expression,
|
||||||
|
@ -17,7 +17,9 @@ import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform';
|
|||||||
import {SelectorScopeRegistry} from './selector_scope';
|
import {SelectorScopeRegistry} from './selector_scope';
|
||||||
import {getConstructorDependencies, isAngularCore, unwrapExpression} from './util';
|
import {getConstructorDependencies, isAngularCore, unwrapExpression} from './util';
|
||||||
|
|
||||||
export class PipeDecoratorHandler implements DecoratorHandler<R3PipeMetadata, Decorator> {
|
export interface PipeHandlerData { meta: R3PipeMetadata; }
|
||||||
|
|
||||||
|
export class PipeDecoratorHandler implements DecoratorHandler<PipeHandlerData, Decorator> {
|
||||||
constructor(
|
constructor(
|
||||||
private checker: ts.TypeChecker, private reflector: ReflectionHost,
|
private checker: ts.TypeChecker, private reflector: ReflectionHost,
|
||||||
private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {}
|
private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {}
|
||||||
@ -30,7 +32,7 @@ export class PipeDecoratorHandler implements DecoratorHandler<R3PipeMetadata, De
|
|||||||
decorator => decorator.name === 'Pipe' && (this.isCore || isAngularCore(decorator)));
|
decorator => decorator.name === 'Pipe' && (this.isCore || isAngularCore(decorator)));
|
||||||
}
|
}
|
||||||
|
|
||||||
analyze(clazz: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<R3PipeMetadata> {
|
analyze(clazz: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput<PipeHandlerData> {
|
||||||
if (clazz.name === undefined) {
|
if (clazz.name === undefined) {
|
||||||
throw new FatalDiagnosticError(
|
throw new FatalDiagnosticError(
|
||||||
ErrorCode.DECORATOR_ON_ANONYMOUS_CLASS, clazz, `@Pipes must have names`);
|
ErrorCode.DECORATOR_ON_ANONYMOUS_CLASS, clazz, `@Pipes must have names`);
|
||||||
@ -77,16 +79,18 @@ export class PipeDecoratorHandler implements DecoratorHandler<R3PipeMetadata, De
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
analysis: {
|
analysis: {
|
||||||
name,
|
meta: {
|
||||||
type,
|
name,
|
||||||
pipeName,
|
type,
|
||||||
deps: getConstructorDependencies(clazz, this.reflector, this.isCore), pure,
|
pipeName,
|
||||||
}
|
deps: getConstructorDependencies(clazz, this.reflector, this.isCore), pure,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
compile(node: ts.ClassDeclaration, analysis: R3PipeMetadata): CompileResult {
|
compile(node: ts.ClassDeclaration, analysis: PipeHandlerData): CompileResult {
|
||||||
const res = compilePipeFromMetadata(analysis);
|
const res = compilePipeFromMetadata(analysis.meta);
|
||||||
return {
|
return {
|
||||||
name: 'ngPipeDef',
|
name: 'ngPipeDef',
|
||||||
initializer: res.expression,
|
initializer: res.expression,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user