refactor(ivy): first pass at extracting ReflectionHost for abstract reflection (#24541)

ngtsc needs to reflect over code to property compile it. It performs operations
such as enumerating decorators on a type, reading metadata from constructor
parameters, etc.

Depending on the format (ES5, ES6, etc) of the underlying code, the AST
structures over which this reflection takes place can be very different. For
example, in TS/ES6 code `class` declarations are `ts.ClassDeclaration` nodes,
but in ES5 code they've been downleveled to `ts.VariableDeclaration` nodes that
are initialized to IIFEs that build up the classes being defined.

The ReflectionHost abstraction allows ngtsc to perform these operations without
directly querying the AST. Different implementations of ReflectionHost allow
support for different code formats.

PR Close #24541
This commit is contained in:
Alex Rickabaugh
2018-06-13 10:33:04 -07:00
committed by Miško Hevery
parent 84272e2227
commit 10da6a45c6
23 changed files with 724 additions and 465 deletions

View File

@ -14,6 +14,7 @@ import * as api from '../transformers/api';
import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, SelectorScopeRegistry} from './annotations';
import {CompilerHost} from './compiler_host';
import {TypeScriptReflectionHost} from './metadata';
import {IvyCompilation, ivyTransformFactory} from './transform';
export class NgtscProgram implements api.Program {
@ -90,16 +91,17 @@ export class NgtscProgram implements api.Program {
const mergeEmitResultsCallback = opts && opts.mergeEmitResultsCallback || mergeEmitResults;
const checker = this.tsProgram.getTypeChecker();
const scopeRegistry = new SelectorScopeRegistry(checker);
const reflector = new TypeScriptReflectionHost(checker);
const scopeRegistry = new SelectorScopeRegistry(checker, reflector);
// Set up the IvyCompilation, which manages state for the Ivy transformer.
const handlers = [
new ComponentDecoratorHandler(checker, scopeRegistry),
new DirectiveDecoratorHandler(checker, scopeRegistry),
new InjectableDecoratorHandler(checker),
new ComponentDecoratorHandler(checker, reflector, scopeRegistry),
new DirectiveDecoratorHandler(checker, reflector, scopeRegistry),
new InjectableDecoratorHandler(reflector),
new NgModuleDecoratorHandler(checker, scopeRegistry),
];
const compilation = new IvyCompilation(handlers, checker);
const compilation = new IvyCompilation(handlers, checker, reflector);
// Analyze every source file in the program.
this.tsProgram.getSourceFiles()