From 2a6108af97e2f54a8c96890b3ecd66c566b845f6 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Tue, 18 Dec 2018 09:48:15 -0800 Subject: [PATCH] refactor(ivy): split apart the 'metadata' package in the ngtsc compiler (#27743) This refactoring moves code around between a few of the ngtsc subpackages, with the goal of having a more logical package structure. Additional interfaces are also introduced where they make sense. The 'metadata' package formerly contained both the partial evaluator, the TypeScriptReflectionHost as well as some other reflection functions, and the Reference interface and various implementations. This package was split into 3 parts. The partial evaluator now has its own package 'partial_evaluator', and exists behind an interface PartialEvaluator instead of a top-level function. In the future this will be useful for reducing churn as the partial evaluator becomes more complicated. The TypeScriptReflectionHost and other miscellaneous functions have moved into a new 'reflection' package. The former 'host' package which contained the ReflectionHost interface and associated types was also merged into this new 'reflection' package. Finally, the Reference APIs were moved to the 'imports' package, which will consolidate all import-related logic in ngtsc. PR Close #27743 --- packages/compiler-cli/BUILD.bazel | 3 +- packages/compiler-cli/src/ngcc/BUILD.bazel | 5 +- .../ngcc/src/analysis/decoration_analyzer.ts | 12 +- .../module_with_providers_analyzer.ts | 4 +- .../src/analysis/ngcc_references_registry.ts | 4 +- .../analysis/private_declarations_analyzer.ts | 2 +- .../src/ngcc/src/host/decorated_class.ts | 2 +- .../src/ngcc/src/host/esm2015_host.ts | 3 +- .../src/ngcc/src/host/esm5_host.ts | 3 +- .../src/ngcc/src/host/ngcc_host.ts | 2 +- .../src/ngcc/src/rendering/renderer.ts | 1 - .../compiler-cli/src/ngcc/test/BUILD.bazel | 5 +- .../test/analysis/decoration_analyzer_spec.ts | 2 +- .../private_declarations_analyzer_spec.ts | 2 +- .../test/analysis/references_registry_spec.ts | 8 +- .../host/esm2015_host_import_helper_spec.ts | 2 +- .../src/ngcc/test/host/esm2015_host_spec.ts | 2 +- .../test/host/esm5_host_import_helper_spec.ts | 2 +- .../src/ngcc/test/host/esm5_host_spec.ts | 2 +- .../src/ngtsc/annotations/BUILD.bazel | 5 +- .../src/ngtsc/annotations/src/base_def.ts | 10 +- .../src/ngtsc/annotations/src/component.ts | 32 +-- .../src/ngtsc/annotations/src/directive.ts | 76 +++--- .../src/ngtsc/annotations/src/injectable.ts | 3 +- .../src/ngtsc/annotations/src/metadata.ts | 2 +- .../src/ngtsc/annotations/src/ng_module.ts | 21 +- .../src/ngtsc/annotations/src/pipe.ts | 10 +- .../annotations/src/references_registry.ts | 4 +- .../ngtsc/annotations/src/selector_scope.ts | 7 +- .../src/ngtsc/annotations/src/util.ts | 6 +- .../src/ngtsc/annotations/test/BUILD.bazel | 4 +- .../ngtsc/annotations/test/component_spec.ts | 7 +- .../ngtsc/annotations/test/metadata_spec.ts | 4 +- .../annotations/test/selector_scope_spec.ts | 6 +- .../src/ngtsc/imports/BUILD.bazel | 18 ++ .../src/ngtsc/{host => imports}/index.ts | 2 +- .../src/ngtsc/imports/src/references.ts | 150 +++++++++++ .../compiler-cli/src/ngtsc/metadata/index.ts | 12 - .../BUILD.bazel | 7 +- .../src/ngtsc/partial_evaluator/index.ts | 10 + .../ngtsc/partial_evaluator/src/builtin.ts | 21 ++ .../ngtsc/partial_evaluator/src/interface.ts | 31 +++ .../src/interpreter.ts} | 251 +----------------- .../src/ngtsc/partial_evaluator/src/result.ts | 79 ++++++ .../ngtsc/partial_evaluator/test/BUILD.bazel | 29 ++ .../test/evaluator_spec.ts} | 30 ++- packages/compiler-cli/src/ngtsc/program.ts | 15 +- .../ngtsc/{host => reflection}/BUILD.bazel | 4 +- .../src/ngtsc/reflection/index.ts | 10 + .../reflection.ts => reflection/src/host.ts} | 0 .../src/typescript.ts} | 2 +- .../{metadata => reflection}/test/BUILD.bazel | 4 +- .../test/ts_host_spec.ts} | 4 +- .../compiler-cli/src/ngtsc/shims/BUILD.bazel | 2 - .../compiler-cli/src/ngtsc/shims/src/host.ts | 1 - .../compiler-cli/src/ngtsc/switch/BUILD.bazel | 3 - .../src/ngtsc/transform/BUILD.bazel | 3 +- .../src/ngtsc/transform/src/api.ts | 2 +- .../src/ngtsc/transform/src/compilation.ts | 3 +- .../src/ngtsc/transform/src/transform.ts | 3 +- .../src/ngtsc/typecheck/BUILD.bazel | 2 +- .../src/ngtsc/typecheck/src/api.ts | 2 +- .../ngtsc/typecheck/src/type_check_block.ts | 2 +- .../src/ngtsc/typecheck/test/BUILD.bazel | 2 - 64 files changed, 534 insertions(+), 433 deletions(-) create mode 100644 packages/compiler-cli/src/ngtsc/imports/BUILD.bazel rename packages/compiler-cli/src/ngtsc/{host => imports}/index.ts (65%) create mode 100644 packages/compiler-cli/src/ngtsc/imports/src/references.ts delete mode 100644 packages/compiler-cli/src/ngtsc/metadata/index.ts rename packages/compiler-cli/src/ngtsc/{metadata => partial_evaluator}/BUILD.bazel (63%) create mode 100644 packages/compiler-cli/src/ngtsc/partial_evaluator/index.ts create mode 100644 packages/compiler-cli/src/ngtsc/partial_evaluator/src/builtin.ts create mode 100644 packages/compiler-cli/src/ngtsc/partial_evaluator/src/interface.ts rename packages/compiler-cli/src/ngtsc/{metadata/src/resolver.ts => partial_evaluator/src/interpreter.ts} (69%) create mode 100644 packages/compiler-cli/src/ngtsc/partial_evaluator/src/result.ts create mode 100644 packages/compiler-cli/src/ngtsc/partial_evaluator/test/BUILD.bazel rename packages/compiler-cli/src/ngtsc/{metadata/test/resolver_spec.ts => partial_evaluator/test/evaluator_spec.ts} (90%) rename packages/compiler-cli/src/ngtsc/{host => reflection}/BUILD.bazel (71%) create mode 100644 packages/compiler-cli/src/ngtsc/reflection/index.ts rename packages/compiler-cli/src/ngtsc/{host/src/reflection.ts => reflection/src/host.ts} (100%) rename packages/compiler-cli/src/ngtsc/{metadata/src/reflector.ts => reflection/src/typescript.ts} (99%) rename packages/compiler-cli/src/ngtsc/{metadata => reflection}/test/BUILD.bazel (80%) rename packages/compiler-cli/src/ngtsc/{metadata/test/reflector_spec.ts => reflection/test/ts_host_spec.ts} (98%) diff --git a/packages/compiler-cli/BUILD.bazel b/packages/compiler-cli/BUILD.bazel index 859161c0c5..398fb53865 100644 --- a/packages/compiler-cli/BUILD.bazel +++ b/packages/compiler-cli/BUILD.bazel @@ -27,7 +27,8 @@ ts_library( "//packages/compiler-cli/src/ngtsc/annotations", "//packages/compiler-cli/src/ngtsc/diagnostics", "//packages/compiler-cli/src/ngtsc/entry_point", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/partial_evaluator", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/shims", "//packages/compiler-cli/src/ngtsc/switch", "//packages/compiler-cli/src/ngtsc/transform", diff --git a/packages/compiler-cli/src/ngcc/BUILD.bazel b/packages/compiler-cli/src/ngcc/BUILD.bazel index b0f98698e3..3457bfb246 100644 --- a/packages/compiler-cli/src/ngcc/BUILD.bazel +++ b/packages/compiler-cli/src/ngcc/BUILD.bazel @@ -13,8 +13,9 @@ ts_library( "//packages:types", "//packages/compiler", "//packages/compiler-cli/src/ngtsc/annotations", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/imports", + "//packages/compiler-cli/src/ngtsc/partial_evaluator", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/transform", "//packages/compiler-cli/src/ngtsc/translator", "@ngdeps//@types/convert-source-map", diff --git a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts index d9749b1cb1..656a3400e9 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/decoration_analyzer.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import {ConstantPool} from '@angular/compiler'; +import {PartialEvaluator} from '@angular/compiler-cli/src/ngtsc/partial_evaluator'; import * as path from 'canonical-path'; import * as fs from 'fs'; import * as ts from 'typescript'; @@ -59,16 +60,17 @@ export class FileResourceLoader implements ResourceLoader { export class DecorationAnalyzer { resourceLoader = new FileResourceLoader(); scopeRegistry = new SelectorScopeRegistry(this.typeChecker, this.host); + evaluator = new PartialEvaluator(this.host, this.typeChecker); handlers: DecoratorHandler[] = [ - new BaseDefDecoratorHandler(this.typeChecker, this.host), + new BaseDefDecoratorHandler(this.host, this.evaluator), new ComponentDecoratorHandler( - this.typeChecker, this.host, this.scopeRegistry, this.isCore, this.resourceLoader, + this.host, this.evaluator, this.scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs, /* defaultPreserveWhitespaces */ false, /* i18nUseExternalIds */ true), - new DirectiveDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore), + new DirectiveDecoratorHandler(this.host, this.evaluator, this.scopeRegistry, this.isCore), new InjectableDecoratorHandler(this.host, this.isCore), new NgModuleDecoratorHandler( - this.typeChecker, this.host, this.scopeRegistry, this.referencesRegistry, this.isCore), - new PipeDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore), + this.host, this.evaluator, this.scopeRegistry, this.referencesRegistry, this.isCore), + new PipeDecoratorHandler(this.host, this.evaluator, this.scopeRegistry, this.isCore), ]; constructor( diff --git a/packages/compiler-cli/src/ngcc/src/analysis/module_with_providers_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/module_with_providers_analyzer.ts index fe774860d9..c02636bade 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/module_with_providers_analyzer.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/module_with_providers_analyzer.ts @@ -8,8 +8,8 @@ import * as ts from 'typescript'; import {ReferencesRegistry} from '../../../ngtsc/annotations'; -import {Declaration} from '../../../ngtsc/host'; -import {ResolvedReference} from '../../../ngtsc/metadata'; +import {ResolvedReference} from '../../../ngtsc/imports'; +import {Declaration} from '../../../ngtsc/reflection'; import {NgccReflectionHost} from '../host/ngcc_host'; import {isDefined} from '../utils'; diff --git a/packages/compiler-cli/src/ngcc/src/analysis/ngcc_references_registry.ts b/packages/compiler-cli/src/ngcc/src/analysis/ngcc_references_registry.ts index f4779456b6..eaf43bf834 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/ngcc_references_registry.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/ngcc_references_registry.ts @@ -8,8 +8,8 @@ import * as ts from 'typescript'; import {ReferencesRegistry} from '../../../ngtsc/annotations'; -import {Declaration, ReflectionHost} from '../../../ngtsc/host'; -import {Reference, ResolvedReference} from '../../../ngtsc/metadata'; +import {Reference, ResolvedReference} from '../../../ngtsc/imports'; +import {Declaration, ReflectionHost} from '../../../ngtsc/reflection'; import {hasNameIdentifier} from '../utils'; /** diff --git a/packages/compiler-cli/src/ngcc/src/analysis/private_declarations_analyzer.ts b/packages/compiler-cli/src/ngcc/src/analysis/private_declarations_analyzer.ts index 3420b669b6..d8b1ae02b1 100644 --- a/packages/compiler-cli/src/ngcc/src/analysis/private_declarations_analyzer.ts +++ b/packages/compiler-cli/src/ngcc/src/analysis/private_declarations_analyzer.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; import {ReferencesRegistry} from '../../../ngtsc/annotations'; -import {Declaration} from '../../../ngtsc/host'; +import {Declaration} from '../../../ngtsc/reflection'; import {NgccReflectionHost} from '../host/ngcc_host'; import {hasNameIdentifier, isDefined} from '../utils'; diff --git a/packages/compiler-cli/src/ngcc/src/host/decorated_class.ts b/packages/compiler-cli/src/ngcc/src/host/decorated_class.ts index 46cd4c8a19..985ef0a596 100644 --- a/packages/compiler-cli/src/ngcc/src/host/decorated_class.ts +++ b/packages/compiler-cli/src/ngcc/src/host/decorated_class.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; -import {Decorator} from '../../../ngtsc/host'; +import {Decorator} from '../../../ngtsc/reflection'; /** * A simple container that holds the details of a decorated class that has been diff --git a/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts index 34f3345369..c3e57f23bf 100644 --- a/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/src/ngcc/src/host/esm2015_host.ts @@ -8,8 +8,7 @@ import * as ts from 'typescript'; -import {ClassMember, ClassMemberKind, CtorParameter, Decorator, Import} from '../../../ngtsc/host'; -import {TypeScriptReflectionHost, reflectObjectLiteral} from '../../../ngtsc/metadata'; +import {ClassMember, ClassMemberKind, CtorParameter, Decorator, Import, TypeScriptReflectionHost, reflectObjectLiteral} from '../../../ngtsc/reflection'; import {BundleProgram} from '../packages/bundle_program'; import {findAll, getNameText, isDefined} from '../utils'; diff --git a/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts b/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts index 8eb0837607..9482e7730e 100644 --- a/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts +++ b/packages/compiler-cli/src/ngcc/src/host/esm5_host.ts @@ -8,8 +8,7 @@ import * as ts from 'typescript'; -import {ClassMember, ClassMemberKind, Decorator, FunctionDefinition, Parameter} from '../../../ngtsc/host'; -import {reflectObjectLiteral} from '../../../ngtsc/metadata'; +import {ClassMember, ClassMemberKind, Decorator, FunctionDefinition, Parameter, reflectObjectLiteral} from '../../../ngtsc/reflection'; import {getNameText} from '../utils'; import {Esm2015ReflectionHost, ParamInfo, getPropertyValueFromSymbol, isAssignmentStatement} from './esm2015_host'; diff --git a/packages/compiler-cli/src/ngcc/src/host/ngcc_host.ts b/packages/compiler-cli/src/ngcc/src/host/ngcc_host.ts index 1dc7ae8759..38076c9d5e 100644 --- a/packages/compiler-cli/src/ngcc/src/host/ngcc_host.ts +++ b/packages/compiler-cli/src/ngcc/src/host/ngcc_host.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import * as ts from 'typescript'; -import {ReflectionHost} from '../../../ngtsc/host'; +import {ReflectionHost} from '../../../ngtsc/reflection'; import {DecoratedClass} from './decorated_class'; export const PRE_R3_MARKER = '__PRE_R3__'; diff --git a/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts b/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts index f88c6775bf..b6bc54b911 100644 --- a/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts +++ b/packages/compiler-cli/src/ngcc/src/rendering/renderer.ts @@ -13,7 +13,6 @@ import {basename, dirname, relative, resolve} from 'canonical-path'; import {SourceMapConsumer, SourceMapGenerator, RawSourceMap} from 'source-map'; import * as ts from 'typescript'; -import {Decorator} from '../../../ngtsc/host'; import {CompileResult} from '@angular/compiler-cli/src/ngtsc/transform'; import {translateStatement, translateType, ImportManager} from '../../../ngtsc/translator'; import {NgccImportManager} from './ngcc_import_manager'; diff --git a/packages/compiler-cli/src/ngcc/test/BUILD.bazel b/packages/compiler-cli/src/ngcc/test/BUILD.bazel index 826a437aed..72ccc7d222 100644 --- a/packages/compiler-cli/src/ngcc/test/BUILD.bazel +++ b/packages/compiler-cli/src/ngcc/test/BUILD.bazel @@ -10,8 +10,9 @@ ts_library( ]), deps = [ "//packages/compiler-cli/src/ngcc", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/imports", + "//packages/compiler-cli/src/ngtsc/partial_evaluator", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/testing", "//packages/compiler-cli/src/ngtsc/transform", "@ngdeps//@types/convert-source-map", diff --git a/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts b/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts index 1978ba02c8..56ec22c88c 100644 --- a/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/analysis/decoration_analyzer_spec.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; -import {Decorator} from '../../../ngtsc/host'; +import {Decorator} from '../../../ngtsc/reflection'; import {DecoratorHandler} from '../../../ngtsc/transform'; import {DecorationAnalyses, DecorationAnalyzer} from '../../src/analysis/decoration_analyzer'; import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry'; diff --git a/packages/compiler-cli/src/ngcc/test/analysis/private_declarations_analyzer_spec.ts b/packages/compiler-cli/src/ngcc/test/analysis/private_declarations_analyzer_spec.ts index 9188a5344b..36b72f93d5 100644 --- a/packages/compiler-cli/src/ngcc/test/analysis/private_declarations_analyzer_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/analysis/private_declarations_analyzer_spec.ts @@ -6,9 +6,9 @@ * found in the LICENSE file at https://angular.io/license */ -import {ResolvedReference} from '@angular/compiler-cli/src/ngtsc/metadata'; import * as ts from 'typescript'; +import {ResolvedReference} from '../../../ngtsc/imports'; import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry'; import {PrivateDeclarationsAnalyzer} from '../../src/analysis/private_declarations_analyzer'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; diff --git a/packages/compiler-cli/src/ngcc/test/analysis/references_registry_spec.ts b/packages/compiler-cli/src/ngcc/test/analysis/references_registry_spec.ts index b2f9ce27aa..ffb6a46325 100644 --- a/packages/compiler-cli/src/ngcc/test/analysis/references_registry_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/analysis/references_registry_spec.ts @@ -8,7 +8,9 @@ import * as ts from 'typescript'; -import {Reference, TypeScriptReflectionHost, staticallyResolve} from '../../../ngtsc/metadata'; +import {Reference} from '../../../ngtsc/imports'; +import {PartialEvaluator} from '../../../ngtsc/partial_evaluator'; +import {TypeScriptReflectionHost} from '../../../ngtsc/reflection'; import {getDeclaration, makeProgram} from '../../../ngtsc/testing/in_memory_typescript'; import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry'; @@ -37,10 +39,10 @@ describe('NgccReferencesRegistry', () => { const testArrayExpression = testArrayDeclaration.initializer !; const host = new TypeScriptReflectionHost(checker); + const evaluator = new PartialEvaluator(host, checker); const registry = new NgccReferencesRegistry(host); - const references = - staticallyResolve(testArrayExpression, host, checker) as Reference[]; + const references = evaluator.evaluate(testArrayExpression) as Reference[]; registry.add(...references); const map = registry.getDeclarationMap(); diff --git a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_import_helper_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_import_helper_spec.ts index 9440289e86..c3d09c225c 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_import_helper_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_import_helper_spec.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; -import {ClassMemberKind, Import} from '../../../ngtsc/host'; +import {ClassMemberKind, Import} from '../../../ngtsc/reflection'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; import {convertToDirectTsLibImport, getDeclaration, makeTestProgram} from '../helpers/utils'; diff --git a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts index 5c40e9f44c..a68191af74 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm2015_host_spec.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; -import {ClassMemberKind, Import} from '../../../ngtsc/host'; +import {ClassMemberKind, Import} from '../../../ngtsc/reflection'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; import {getDeclaration, makeTestBundleProgram, makeTestProgram} from '../helpers/utils'; diff --git a/packages/compiler-cli/src/ngcc/test/host/esm5_host_import_helper_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm5_host_import_helper_spec.ts index a9d4928ef3..4fca679d42 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm5_host_import_helper_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm5_host_import_helper_spec.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; -import {ClassMemberKind, Import} from '../../../ngtsc/host'; +import {ClassMemberKind, Import} from '../../../ngtsc/reflection'; import {Esm5ReflectionHost} from '../../src/host/esm5_host'; import {convertToDirectTsLibImport, getDeclaration, makeTestProgram} from '../helpers/utils'; diff --git a/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts b/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts index 4fe4b82447..7889ae74d3 100644 --- a/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/host/esm5_host_spec.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; -import {ClassMemberKind, Import} from '../../../ngtsc/host'; +import {ClassMemberKind, Import} from '../../../ngtsc/reflection'; import {Esm2015ReflectionHost} from '../../src/host/esm2015_host'; import {Esm5ReflectionHost} from '../../src/host/esm5_host'; import {getDeclaration, makeTestProgram} from '../helpers/utils'; diff --git a/packages/compiler-cli/src/ngtsc/annotations/BUILD.bazel b/packages/compiler-cli/src/ngtsc/annotations/BUILD.bazel index e86b8e6181..dd014a1670 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/annotations/BUILD.bazel @@ -12,8 +12,9 @@ ts_library( deps = [ "//packages/compiler", "//packages/compiler-cli/src/ngtsc/diagnostics", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/imports", + "//packages/compiler-cli/src/ngtsc/partial_evaluator", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/transform", "//packages/compiler-cli/src/ngtsc/typecheck", "@ngdeps//@types/node", diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/base_def.ts b/packages/compiler-cli/src/ngtsc/annotations/src/base_def.ts index 5924bde1e2..47c64bdb61 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/base_def.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/base_def.ts @@ -9,8 +9,8 @@ import {R3BaseRefMetaData, compileBaseDefFromMetadata} from '@angular/compiler'; import * as ts from 'typescript'; -import {ClassMember, Decorator, ReflectionHost} from '../../host'; -import {staticallyResolve} from '../../metadata'; +import {PartialEvaluator} from '../../partial_evaluator'; +import {ClassMember, Decorator, ReflectionHost} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {isAngularCore} from './util'; @@ -26,7 +26,7 @@ function containsNgTopLevelDecorator(decorators: Decorator[] | null): boolean { export class BaseDefDecoratorHandler implements DecoratorHandler { - constructor(private checker: ts.TypeChecker, private reflector: ReflectionHost, ) {} + constructor(private reflector: ReflectionHost, private evaluator: PartialEvaluator) {} detect(node: ts.ClassDeclaration, decorators: Decorator[]|null): R3BaseRefDecoratorDetection |undefined { @@ -69,7 +69,7 @@ export class BaseDefDecoratorHandler implements const args = decorator.args; let value: string|[string, string]; if (args && args.length > 0) { - const resolvedValue = staticallyResolve(args[0], this.reflector, this.checker); + const resolvedValue = this.evaluator.evaluate(args[0]); if (typeof resolvedValue !== 'string') { throw new TypeError('Input alias does not resolve to a string value'); } @@ -88,7 +88,7 @@ export class BaseDefDecoratorHandler implements const args = decorator.args; let value: string; if (args && args.length > 0) { - const resolvedValue = staticallyResolve(args[0], this.reflector, this.checker); + const resolvedValue = this.evaluator.evaluate(args[0]); if (typeof resolvedValue !== 'string') { throw new TypeError('Output alias does not resolve to a string value'); } diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts index 8631e89645..8d2f05ddc1 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts @@ -11,8 +11,9 @@ import * as path from 'path'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {Decorator, ReflectionHost} from '../../host'; -import {AbsoluteReference, Reference, ResolvedReference, filterToMembersWithDecorator, reflectObjectLiteral, staticallyResolve} from '../../metadata'; +import {ResolvedReference} from '../../imports'; +import {PartialEvaluator} from '../../partial_evaluator'; +import {Decorator, ReflectionHost, filterToMembersWithDecorator, reflectObjectLiteral} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {TypeCheckContext, TypeCheckableDirectiveMeta} from '../../typecheck'; @@ -37,7 +38,7 @@ export interface ComponentHandlerData { export class ComponentDecoratorHandler implements DecoratorHandler { constructor( - private checker: ts.TypeChecker, private reflector: ReflectionHost, + private reflector: ReflectionHost, private evaluator: PartialEvaluator, private scopeRegistry: SelectorScopeRegistry, private isCore: boolean, private resourceLoader: ResourceLoader, private rootDirs: string[], private defaultPreserveWhitespaces: boolean, private i18nUseExternalIds: boolean) {} @@ -62,7 +63,7 @@ export class ComponentDecoratorHandler implements if (this.resourceLoader.preload !== undefined && component.has('templateUrl')) { const templateUrlExpr = component.get('templateUrl') !; - const templateUrl = staticallyResolve(templateUrlExpr, this.reflector, this.checker); + const templateUrl = this.evaluator.evaluate(templateUrlExpr); if (typeof templateUrl !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string'); @@ -97,7 +98,7 @@ export class ComponentDecoratorHandler implements // @Component inherits @Directive, so begin by extracting the @Directive metadata and building // on it. const directiveResult = extractDirectiveMetadata( - node, decorator, this.checker, this.reflector, this.isCore, + node, decorator, this.reflector, this.evaluator, this.isCore, this.elementSchemaRegistry.getDefaultComponentElementName()); if (directiveResult === undefined) { // `extractDirectiveMetadata` returns undefined when the @Directive has `jit: true`. In this @@ -112,7 +113,7 @@ export class ComponentDecoratorHandler implements let templateStr: string|null = null; if (component.has('templateUrl')) { const templateUrlExpr = component.get('templateUrl') !; - const templateUrl = staticallyResolve(templateUrlExpr, this.reflector, this.checker); + const templateUrl = this.evaluator.evaluate(templateUrlExpr); if (typeof templateUrl !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, templateUrlExpr, 'templateUrl must be a string'); @@ -120,7 +121,7 @@ export class ComponentDecoratorHandler implements templateStr = this.resourceLoader.load(templateUrl, containingFile); } else if (component.has('template')) { const templateExpr = component.get('template') !; - const resolvedTemplate = staticallyResolve(templateExpr, this.reflector, this.checker); + const resolvedTemplate = this.evaluator.evaluate(templateExpr); if (typeof resolvedTemplate !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, templateExpr, 'template must be a string'); @@ -134,7 +135,7 @@ export class ComponentDecoratorHandler implements let preserveWhitespaces: boolean = this.defaultPreserveWhitespaces; if (component.has('preserveWhitespaces')) { const expr = component.get('preserveWhitespaces') !; - const value = staticallyResolve(expr, this.reflector, this.checker); + const value = this.evaluator.evaluate(expr); if (typeof value !== 'boolean') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, expr, 'preserveWhitespaces must be a boolean'); @@ -161,7 +162,7 @@ export class ComponentDecoratorHandler implements let interpolation: InterpolationConfig = DEFAULT_INTERPOLATION_CONFIG; if (component.has('interpolation')) { const expr = component.get('interpolation') !; - const value = staticallyResolve(expr, this.reflector, this.checker); + const value = this.evaluator.evaluate(expr); if (!Array.isArray(value) || value.length !== 2 || !value.every(element => typeof element === 'string')) { throw new FatalDiagnosticError( @@ -200,21 +201,21 @@ export class ComponentDecoratorHandler implements const coreModule = this.isCore ? undefined : '@angular/core'; const viewChildFromFields = queriesFromFields( filterToMembersWithDecorator(decoratedElements, 'ViewChild', coreModule), this.reflector, - this.checker); + this.evaluator); const viewChildrenFromFields = queriesFromFields( filterToMembersWithDecorator(decoratedElements, 'ViewChildren', coreModule), this.reflector, - this.checker); + this.evaluator); const viewQueries = [...viewChildFromFields, ...viewChildrenFromFields]; if (component.has('queries')) { const queriesFromDecorator = extractQueriesFromDecorator( - component.get('queries') !, this.reflector, this.checker, this.isCore); + component.get('queries') !, this.reflector, this.evaluator, this.isCore); viewQueries.push(...queriesFromDecorator.view); } let styles: string[]|null = null; if (component.has('styles')) { - styles = parseFieldArrayValue(component, 'styles', this.reflector, this.checker); + styles = parseFieldArrayValue(component, 'styles', this.evaluator); } let styleUrls = this._extractStyleUrls(component); @@ -227,8 +228,7 @@ export class ComponentDecoratorHandler implements let encapsulation: number = 0; if (component.has('encapsulation')) { - encapsulation = parseInt(staticallyResolve( - component.get('encapsulation') !, this.reflector, this.checker) as string); + encapsulation = parseInt(this.evaluator.evaluate(component.get('encapsulation') !) as string); } let animations: Expression|null = null; @@ -333,7 +333,7 @@ export class ComponentDecoratorHandler implements } const styleUrlsExpr = component.get('styleUrls') !; - const styleUrls = staticallyResolve(styleUrlsExpr, this.reflector, this.checker); + const styleUrls = this.evaluator.evaluate(styleUrlsExpr); if (!Array.isArray(styleUrls) || !styleUrls.every(url => typeof url === 'string')) { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, styleUrlsExpr, 'styleUrls must be an array of strings'); diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index e83a36c7b8..a581461bd7 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -10,8 +10,9 @@ import {ConstantPool, Expression, R3DirectiveMetadata, R3QueryMetadata, Statemen import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {ClassMember, ClassMemberKind, Decorator, Import, ReflectionHost} from '../../host'; -import {Reference, ResolvedReference, filterToMembersWithDecorator, reflectObjectLiteral, staticallyResolve} from '../../metadata'; +import {Reference, ResolvedReference} from '../../imports'; +import {PartialEvaluator} from '../../partial_evaluator'; +import {ClassMember, ClassMemberKind, Decorator, ReflectionHost, filterToMembersWithDecorator, reflectObjectLiteral} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {generateSetClassMetadataCall} from './metadata'; @@ -27,7 +28,7 @@ export interface DirectiveHandlerData { export class DirectiveDecoratorHandler implements DecoratorHandler { constructor( - private checker: ts.TypeChecker, private reflector: ReflectionHost, + private reflector: ReflectionHost, private evaluator: PartialEvaluator, private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {} detect(node: ts.Declaration, decorators: Decorator[]|null): Decorator|undefined { @@ -40,7 +41,7 @@ export class DirectiveDecoratorHandler implements analyze(node: ts.ClassDeclaration, decorator: Decorator): AnalysisOutput { const directiveResult = - extractDirectiveMetadata(node, decorator, this.checker, this.reflector, this.isCore); + extractDirectiveMetadata(node, decorator, this.reflector, this.evaluator, this.isCore); const analysis = directiveResult && directiveResult.metadata; // If the directive has a selector, it should be registered with the `SelectorScopeRegistry` so @@ -92,8 +93,8 @@ export class DirectiveDecoratorHandler implements * Helper function to extract metadata from a `Directive` or `Component`. */ export function extractDirectiveMetadata( - clazz: ts.ClassDeclaration, decorator: Decorator, checker: ts.TypeChecker, - reflector: ReflectionHost, isCore: boolean, defaultSelector: string | null = null): { + clazz: ts.ClassDeclaration, decorator: Decorator, reflector: ReflectionHost, + evaluator: PartialEvaluator, isCore: boolean, defaultSelector: string | null = null): { decorator: Map, metadata: R3DirectiveMetadata, decoratedElements: ClassMember[], @@ -127,29 +128,29 @@ export function extractDirectiveMetadata( // Construct the map of inputs both from the @Directive/@Component // decorator, and the decorated // fields. - const inputsFromMeta = parseFieldToPropertyMapping(directive, 'inputs', reflector, checker); + const inputsFromMeta = parseFieldToPropertyMapping(directive, 'inputs', evaluator); const inputsFromFields = parseDecoratedFields( - filterToMembersWithDecorator(decoratedElements, 'Input', coreModule), reflector, checker, + filterToMembersWithDecorator(decoratedElements, 'Input', coreModule), evaluator, resolveInput); // And outputs. - const outputsFromMeta = parseFieldToPropertyMapping(directive, 'outputs', reflector, checker); + const outputsFromMeta = parseFieldToPropertyMapping(directive, 'outputs', evaluator); const outputsFromFields = parseDecoratedFields( - filterToMembersWithDecorator(decoratedElements, 'Output', coreModule), reflector, checker, + filterToMembersWithDecorator(decoratedElements, 'Output', coreModule), evaluator, resolveOutput) as{[field: string]: string}; // Construct the list of queries. const contentChildFromFields = queriesFromFields( filterToMembersWithDecorator(decoratedElements, 'ContentChild', coreModule), reflector, - checker); + evaluator); const contentChildrenFromFields = queriesFromFields( filterToMembersWithDecorator(decoratedElements, 'ContentChildren', coreModule), reflector, - checker); + evaluator); const queries = [...contentChildFromFields, ...contentChildrenFromFields]; if (directive.has('queries')) { const queriesFromDecorator = - extractQueriesFromDecorator(directive.get('queries') !, reflector, checker, isCore); + extractQueriesFromDecorator(directive.get('queries') !, reflector, evaluator, isCore); queries.push(...queriesFromDecorator.content); } @@ -157,7 +158,7 @@ export function extractDirectiveMetadata( let selector = defaultSelector; if (directive.has('selector')) { const expr = directive.get('selector') !; - const resolved = staticallyResolve(expr, reflector, checker); + const resolved = evaluator.evaluate(expr); if (typeof resolved !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, expr, `selector must be a string`); @@ -165,7 +166,7 @@ export function extractDirectiveMetadata( selector = resolved; } - const host = extractHostBindings(directive, decoratedElements, reflector, checker, coreModule); + const host = extractHostBindings(directive, decoratedElements, evaluator, coreModule); const providers: Expression|null = directive.has('providers') ? new WrappedNodeExpr(directive.get('providers') !) : null; @@ -179,7 +180,7 @@ export function extractDirectiveMetadata( let exportAs: string|null = null; if (directive.has('exportAs')) { const expr = directive.get('exportAs') !; - const resolved = staticallyResolve(expr, reflector, checker); + const resolved = evaluator.evaluate(expr); if (typeof resolved !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, expr, `exportAs must be a string`); @@ -207,14 +208,14 @@ export function extractDirectiveMetadata( export function extractQueryMetadata( exprNode: ts.Node, name: string, args: ReadonlyArray, propertyName: string, - reflector: ReflectionHost, checker: ts.TypeChecker): R3QueryMetadata { + reflector: ReflectionHost, evaluator: PartialEvaluator): R3QueryMetadata { if (args.length === 0) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_ARITY_WRONG, exprNode, `@${name} must have arguments`); } const first = name === 'ViewChild' || name === 'ContentChild'; const node = unwrapForwardRef(args[0], reflector); - const arg = staticallyResolve(node, reflector, checker); + const arg = evaluator.evaluate(node); // Extract the predicate let predicate: Expression|string[]|null = null; @@ -244,7 +245,7 @@ export function extractQueryMetadata( } if (options.has('descendants')) { - const descendantsValue = staticallyResolve(options.get('descendants') !, reflector, checker); + const descendantsValue = evaluator.evaluate(options.get('descendants') !); if (typeof descendantsValue !== 'boolean') { throw new Error(`@${name} options.descendants must be a boolean`); } @@ -261,7 +262,7 @@ export function extractQueryMetadata( } export function extractQueriesFromDecorator( - queryData: ts.Expression, reflector: ReflectionHost, checker: ts.TypeChecker, + queryData: ts.Expression, reflector: ReflectionHost, evaluator: PartialEvaluator, isCore: boolean): { content: R3QueryMetadata[], view: R3QueryMetadata[], @@ -283,7 +284,7 @@ export function extractQueriesFromDecorator( } const query = extractQueryMetadata( - queryExpr, type.name, queryExpr.arguments || [], propertyName, reflector, checker); + queryExpr, type.name, queryExpr.arguments || [], propertyName, reflector, evaluator); if (type.name.startsWith('Content')) { content.push(query); } else { @@ -307,14 +308,14 @@ function isStringArrayOrDie(value: any, name: string): value is string[] { } export function parseFieldArrayValue( - directive: Map, field: string, reflector: ReflectionHost, - checker: ts.TypeChecker): null|string[] { + directive: Map, field: string, evaluator: PartialEvaluator): null| + string[] { if (!directive.has(field)) { return null; } // Resolve the field of interest from the directive metadata to a string[]. - const value = staticallyResolve(directive.get(field) !, reflector, checker); + const value = evaluator.evaluate(directive.get(field) !); if (!isStringArrayOrDie(value, field)) { throw new Error(`Failed to resolve @Directive.${field}`); } @@ -327,9 +328,9 @@ export function parseFieldArrayValue( * correctly shaped metadata object. */ function parseFieldToPropertyMapping( - directive: Map, field: string, reflector: ReflectionHost, - checker: ts.TypeChecker): {[field: string]: string} { - const metaValues = parseFieldArrayValue(directive, field, reflector, checker); + directive: Map, field: string, + evaluator: PartialEvaluator): {[field: string]: string} { + const metaValues = parseFieldArrayValue(directive, field, evaluator); if (!metaValues) { return EMPTY_OBJECT; } @@ -350,8 +351,7 @@ function parseFieldToPropertyMapping( * object. */ function parseDecoratedFields( - fields: {member: ClassMember, decorators: Decorator[]}[], reflector: ReflectionHost, - checker: ts.TypeChecker, + fields: {member: ClassMember, decorators: Decorator[]}[], evaluator: PartialEvaluator, mapValueResolver: (publicName: string, internalName: string) => string | [string, string]): {[field: string]: string | [string, string]} { return fields.reduce( @@ -363,7 +363,7 @@ function parseDecoratedFields( if (decorator.args == null || decorator.args.length === 0) { results[fieldName] = fieldName; } else if (decorator.args.length === 1) { - const property = staticallyResolve(decorator.args[0], reflector, checker); + const property = evaluator.evaluate(decorator.args[0]); if (typeof property !== 'string') { throw new Error(`Decorator argument must resolve to a string`); } @@ -389,7 +389,7 @@ function resolveOutput(publicName: string, internalName: string) { export function queriesFromFields( fields: {member: ClassMember, decorators: Decorator[]}[], reflector: ReflectionHost, - checker: ts.TypeChecker): R3QueryMetadata[] { + evaluator: PartialEvaluator): R3QueryMetadata[] { return fields.map(({member, decorators}) => { if (decorators.length !== 1) { throw new Error(`Cannot have multiple query decorators on the same class member`); @@ -398,7 +398,7 @@ export function queriesFromFields( } const decorator = decorators[0]; return extractQueryMetadata( - decorator.node, decorator.name, decorator.args || [], member.name, reflector, checker); + decorator.node, decorator.name, decorator.args || [], member.name, reflector, evaluator); }); } @@ -412,8 +412,8 @@ type StringMap = { }; function extractHostBindings( - metadata: Map, members: ClassMember[], reflector: ReflectionHost, - checker: ts.TypeChecker, coreModule: string | undefined): { + metadata: Map, members: ClassMember[], evaluator: PartialEvaluator, + coreModule: string | undefined): { attributes: StringMap, listeners: StringMap, properties: StringMap, @@ -421,7 +421,7 @@ function extractHostBindings( let hostMetadata: StringMap = {}; if (metadata.has('host')) { const expr = metadata.get('host') !; - const hostMetaMap = staticallyResolve(expr, reflector, checker); + const hostMetaMap = evaluator.evaluate(expr); if (!(hostMetaMap instanceof Map)) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_ARG_NOT_LITERAL, expr, `Decorator host metadata must be an object`); @@ -445,7 +445,7 @@ function extractHostBindings( throw new Error(`@HostBinding() can have at most one argument`); } - const resolved = staticallyResolve(decorator.args[0], reflector, checker); + const resolved = evaluator.evaluate(decorator.args[0]); if (typeof resolved !== 'string') { throw new Error(`@HostBinding()'s argument must be a string`); } @@ -469,7 +469,7 @@ function extractHostBindings( `@HostListener() can have at most two arguments`); } - const resolved = staticallyResolve(decorator.args[0], reflector, checker); + const resolved = evaluator.evaluate(decorator.args[0]); if (typeof resolved !== 'string') { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, decorator.args[0], @@ -479,7 +479,7 @@ function extractHostBindings( eventName = resolved; if (decorator.args.length === 2) { - const resolvedArgs = staticallyResolve(decorator.args[1], reflector, checker); + const resolvedArgs = evaluator.evaluate(decorator.args[1]); if (!isStringArrayOrDie(resolvedArgs, '@HostListener.args')) { throw new FatalDiagnosticError( ErrorCode.VALUE_HAS_WRONG_TYPE, decorator.args[1], diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts index d779bd4f41..638523efa9 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts @@ -10,8 +10,7 @@ import {Expression, LiteralExpr, R3DependencyMetadata, R3InjectableMetadata, R3R import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {Decorator, ReflectionHost} from '../../host'; -import {reflectObjectLiteral} from '../../metadata'; +import {Decorator, ReflectionHost, reflectObjectLiteral} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {generateSetClassMetadataCall} from './metadata'; diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts index 79d18220c4..dc8faa1673 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts @@ -9,7 +9,7 @@ import {ExternalExpr, Identifiers, InvokeFunctionExpr, Statement, WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; -import {CtorParameter, Decorator, ReflectionHost} from '../../host'; +import {CtorParameter, Decorator, ReflectionHost} from '../../reflection'; /** * Given a class declaration, generate a call to `setClassMetadata` with the Angular metadata diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts index 54cb3a65cb..9cdcdcc720 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -10,8 +10,9 @@ import {Expression, LiteralArrayExpr, R3InjectorMetadata, R3NgModuleMetadata, R3 import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {Decorator, ReflectionHost} from '../../host'; -import {Reference, ResolvedReference, ResolvedValue, reflectObjectLiteral, staticallyResolve, typeNodeToValueExpr} from '../../metadata'; +import {Reference, ResolvedReference} from '../../imports'; +import {PartialEvaluator, ResolvedValue} from '../../partial_evaluator'; +import {Decorator, ReflectionHost, reflectObjectLiteral, typeNodeToValueExpr} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {generateSetClassMetadataCall} from './metadata'; @@ -32,7 +33,7 @@ export interface NgModuleAnalysis { */ export class NgModuleDecoratorHandler implements DecoratorHandler { constructor( - private checker: ts.TypeChecker, private reflector: ReflectionHost, + private reflector: ReflectionHost, private evaluator: PartialEvaluator, private scopeRegistry: SelectorScopeRegistry, private referencesRegistry: ReferencesRegistry, private isCore: boolean) {} @@ -72,32 +73,30 @@ export class NgModuleDecoratorHandler implements DecoratorHandler[] = []; if (ngModule.has('declarations')) { const expr = ngModule.get('declarations') !; - const declarationMeta = staticallyResolve(expr, this.reflector, this.checker); + const declarationMeta = this.evaluator.evaluate(expr); declarations = this.resolveTypeList(expr, declarationMeta, 'declarations'); this.referencesRegistry.add(...declarations); } let imports: Reference[] = []; if (ngModule.has('imports')) { const expr = ngModule.get('imports') !; - const importsMeta = staticallyResolve( - expr, this.reflector, this.checker, - ref => this._extractModuleFromModuleWithProvidersFn(ref.node)); + const importsMeta = this.evaluator.evaluate( + expr, ref => this._extractModuleFromModuleWithProvidersFn(ref.node)); imports = this.resolveTypeList(expr, importsMeta, 'imports'); this.referencesRegistry.add(...imports); } let exports: Reference[] = []; if (ngModule.has('exports')) { const expr = ngModule.get('exports') !; - const exportsMeta = staticallyResolve( - expr, this.reflector, this.checker, - ref => this._extractModuleFromModuleWithProvidersFn(ref.node)); + const exportsMeta = this.evaluator.evaluate( + expr, ref => this._extractModuleFromModuleWithProvidersFn(ref.node)); exports = this.resolveTypeList(expr, exportsMeta, 'exports'); this.referencesRegistry.add(...exports); } let bootstrap: Reference[] = []; if (ngModule.has('bootstrap')) { const expr = ngModule.get('bootstrap') !; - const bootstrapMeta = staticallyResolve(expr, this.reflector, this.checker); + const bootstrapMeta = this.evaluator.evaluate(expr); bootstrap = this.resolveTypeList(expr, bootstrapMeta, 'bootstrap'); this.referencesRegistry.add(...bootstrap); } diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts index 71a8109276..c8f5f25ad0 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts @@ -10,8 +10,8 @@ import {LiteralExpr, R3PipeMetadata, Statement, WrappedNodeExpr, compilePipeFrom import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {Decorator, ReflectionHost} from '../../host'; -import {reflectObjectLiteral, staticallyResolve} from '../../metadata'; +import {PartialEvaluator} from '../../partial_evaluator'; +import {Decorator, ReflectionHost, reflectObjectLiteral} from '../../reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler} from '../../transform'; import {generateSetClassMetadataCall} from './metadata'; @@ -25,7 +25,7 @@ export interface PipeHandlerData { export class PipeDecoratorHandler implements DecoratorHandler { constructor( - private checker: ts.TypeChecker, private reflector: ReflectionHost, + private reflector: ReflectionHost, private evaluator: PartialEvaluator, private scopeRegistry: SelectorScopeRegistry, private isCore: boolean) {} detect(node: ts.Declaration, decorators: Decorator[]|null): Decorator|undefined { @@ -63,7 +63,7 @@ export class PipeDecoratorHandler implements DecoratorHandler { ]); const checker = program.getTypeChecker(); const host = new TypeScriptReflectionHost(checker); + const evaluator = new PartialEvaluator(host, checker); const handler = new ComponentDecoratorHandler( - checker, host, new SelectorScopeRegistry(checker, host), false, new NoopResourceLoader(), + host, evaluator, new SelectorScopeRegistry(checker, host), false, new NoopResourceLoader(), [''], false, true); const TestCmp = getDeclaration(program, 'entry.ts', 'TestCmp', ts.isClassDeclaration); const detected = handler.detect(TestCmp, host.getDecoratorsOfDeclaration(TestCmp)); diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts index 405e6ef6aa..be298b3a55 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts @@ -6,12 +6,12 @@ * found in the LICENSE file at https://angular.io/license */ -import {Statement} from '@angular/compiler'; import * as ts from 'typescript'; -import {TypeScriptReflectionHost} from '../../metadata'; +import {TypeScriptReflectionHost} from '../../reflection'; import {getDeclaration, makeProgram} from '../../testing/in_memory_typescript'; import {ImportManager, translateStatement} from '../../translator'; + import {generateSetClassMetadataCall} from '../src/metadata'; const CORE = { diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/selector_scope_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/selector_scope_spec.ts index b926dfba15..c3228f21f7 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/selector_scope_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/selector_scope_spec.ts @@ -8,10 +8,10 @@ import * as ts from 'typescript'; -import {TypeScriptReflectionHost} from '../../metadata'; -import {AbsoluteReference, ResolvedReference} from '../../metadata/src/resolver'; +import {AbsoluteReference, ResolvedReference} from '../../imports'; +import {TypeScriptReflectionHost} from '../../reflection'; import {getDeclaration, makeProgram} from '../../testing/in_memory_typescript'; -import {NgModuleDecoratorHandler} from '../src/ng_module'; + import {SelectorScopeRegistry} from '../src/selector_scope'; describe('SelectorScopeRegistry', () => { diff --git a/packages/compiler-cli/src/ngtsc/imports/BUILD.bazel b/packages/compiler-cli/src/ngtsc/imports/BUILD.bazel new file mode 100644 index 0000000000..816a1f4f9f --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/imports/BUILD.bazel @@ -0,0 +1,18 @@ +package(default_visibility = ["//visibility:public"]) + +load("//tools:defaults.bzl", "ts_library") + +ts_library( + name = "imports", + srcs = glob([ + "index.ts", + "src/*.ts", + ]), + module_name = "@angular/compiler-cli/src/ngtsc/imports", + deps = [ + "//packages:types", + "//packages/compiler", + "@ngdeps//@types/node", + "@ngdeps//typescript", + ], +) diff --git a/packages/compiler-cli/src/ngtsc/host/index.ts b/packages/compiler-cli/src/ngtsc/imports/index.ts similarity index 65% rename from packages/compiler-cli/src/ngtsc/host/index.ts rename to packages/compiler-cli/src/ngtsc/imports/index.ts index 93a06d7a93..94db07ea1a 100644 --- a/packages/compiler-cli/src/ngtsc/host/index.ts +++ b/packages/compiler-cli/src/ngtsc/imports/index.ts @@ -6,4 +6,4 @@ * found in the LICENSE file at https://angular.io/license */ -export * from './src/reflection'; +export {AbsoluteReference, ImportMode, NodeReference, Reference, ResolvedReference} from './src/references'; diff --git a/packages/compiler-cli/src/ngtsc/imports/src/references.ts b/packages/compiler-cli/src/ngtsc/imports/src/references.ts new file mode 100644 index 0000000000..2be1cc4a03 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/imports/src/references.ts @@ -0,0 +1,150 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/// + +import {Expression, ExternalExpr, ExternalReference, WrappedNodeExpr} from '@angular/compiler'; +import * as path from 'path'; +import * as ts from 'typescript'; + + +const TS_DTS_JS_EXTENSION = /(?:\.d)?\.ts$|\.js$/; + +export enum ImportMode { + UseExistingImport, + ForceNewImport, +} + +/** + * A reference to a `ts.Node`. + * + * For example, if an expression evaluates to a function or class definition, it will be returned + * as a `Reference` (assuming references are allowed in evaluation). + */ +export abstract class Reference { + constructor(readonly node: T) {} + + /** + * Whether an `Expression` can be generated which references the node. + */ + // TODO(issue/24571): remove '!'. + readonly expressable !: boolean; + + /** + * Generate an `Expression` representing this type, in the context of the given SourceFile. + * + * This could be a local variable reference, if the symbol is imported, or it could be a new + * import if needed. + */ + abstract toExpression(context: ts.SourceFile, importMode?: ImportMode): Expression|null; + + abstract addIdentifier(identifier: ts.Identifier): void; +} + +/** + * A reference to a node only, without any ability to get an `Expression` representing that node. + * + * This is used for returning references to things like method declarations, which are not directly + * referenceable. + */ +export class NodeReference extends Reference { + constructor(node: T, readonly moduleName: string|null) { super(node); } + + toExpression(context: ts.SourceFile): null { return null; } + + addIdentifier(identifier: ts.Identifier): void {} +} + +/** + * A reference to a node which has a `ts.Identifier` and can be resolved to an `Expression`. + * + * Imports generated by `ResolvedReference`s are always relative. + */ +export class ResolvedReference extends Reference { + protected identifiers: ts.Identifier[] = []; + + constructor(node: T, protected primaryIdentifier: ts.Identifier) { super(node); } + + readonly expressable = true; + + toExpression(context: ts.SourceFile, importMode: ImportMode = ImportMode.UseExistingImport): + Expression { + const localIdentifier = + pickIdentifier(context, this.primaryIdentifier, this.identifiers, importMode); + if (localIdentifier !== null) { + return new WrappedNodeExpr(localIdentifier); + } else { + // Relative import from context -> this.node.getSourceFile(). + // TODO(alxhub): investigate the impact of multiple source roots here. + // TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support. + let relative = + path.posix.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName) + .replace(TS_DTS_JS_EXTENSION, ''); + + // path.relative() does not include the leading './'. + if (!relative.startsWith('.')) { + relative = `./${relative}`; + } + + // path.relative() returns the empty string (converted to './' above) if the two paths are the + // same. + if (relative === './') { + // Same file after all. + return new WrappedNodeExpr(this.primaryIdentifier); + } else { + return new ExternalExpr(new ExternalReference(relative, this.primaryIdentifier.text)); + } + } + } + + addIdentifier(identifier: ts.Identifier): void { this.identifiers.push(identifier); } +} + +/** + * A reference to a node which has a `ts.Identifer` and an expected absolute module name. + * + * An `AbsoluteReference` can be resolved to an `Expression`, and if that expression is an import + * the module specifier will be an absolute module name, not a relative path. + */ +export class AbsoluteReference extends Reference { + private identifiers: ts.Identifier[] = []; + constructor( + node: T, private primaryIdentifier: ts.Identifier, readonly moduleName: string, + readonly symbolName: string) { + super(node); + } + + readonly expressable = true; + + toExpression(context: ts.SourceFile, importMode: ImportMode = ImportMode.UseExistingImport): + Expression { + const localIdentifier = + pickIdentifier(context, this.primaryIdentifier, this.identifiers, importMode); + if (localIdentifier !== null) { + return new WrappedNodeExpr(localIdentifier); + } else { + return new ExternalExpr(new ExternalReference(this.moduleName, this.symbolName)); + } + } + + addIdentifier(identifier: ts.Identifier): void { this.identifiers.push(identifier); } +} + +function pickIdentifier( + context: ts.SourceFile, primary: ts.Identifier, secondaries: ts.Identifier[], + mode: ImportMode): ts.Identifier|null { + context = ts.getOriginalNode(context) as ts.SourceFile; + + if (ts.getOriginalNode(primary).getSourceFile() === context) { + return primary; + } else if (mode === ImportMode.UseExistingImport) { + return secondaries.find(id => ts.getOriginalNode(id).getSourceFile() === context) || null; + } else { + return null; + } +} \ No newline at end of file diff --git a/packages/compiler-cli/src/ngtsc/metadata/index.ts b/packages/compiler-cli/src/ngtsc/metadata/index.ts deleted file mode 100644 index 8e8e7c852c..0000000000 --- a/packages/compiler-cli/src/ngtsc/metadata/index.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license - * Copyright Google Inc. All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -/// - -export {TypeScriptReflectionHost, filterToMembersWithDecorator, findMember, reflectObjectLiteral, reflectTypeEntityToDeclaration, typeNodeToValueExpr} from './src/reflector'; -export {AbsoluteReference, EnumValue, ImportMode, Reference, ResolvedReference, ResolvedValue, isDynamicValue, staticallyResolve} from './src/resolver'; diff --git a/packages/compiler-cli/src/ngtsc/metadata/BUILD.bazel b/packages/compiler-cli/src/ngtsc/partial_evaluator/BUILD.bazel similarity index 63% rename from packages/compiler-cli/src/ngtsc/metadata/BUILD.bazel rename to packages/compiler-cli/src/ngtsc/partial_evaluator/BUILD.bazel index 530adc1b09..95c2478682 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/BUILD.bazel @@ -3,16 +3,17 @@ package(default_visibility = ["//visibility:public"]) load("//tools:defaults.bzl", "ts_library") ts_library( - name = "metadata", + name = "partial_evaluator", srcs = glob([ "index.ts", "src/*.ts", ]), - module_name = "@angular/compiler-cli/src/ngtsc/metadata", + module_name = "@angular/compiler-cli/src/ngtsc/partial_evaluator", deps = [ "//packages:types", "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/host", + "//packages/compiler-cli/src/ngtsc/imports", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/util", "@ngdeps//@types/node", "@ngdeps//typescript", diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/index.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/index.ts new file mode 100644 index 0000000000..2d32afc308 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +export {ForeignFunctionResolver, PartialEvaluator} from './src/interface'; +export {BuiltinFn, DynamicValue, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap, isDynamicValue} from './src/result'; diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/builtin.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/builtin.ts new file mode 100644 index 0000000000..758853946e --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/builtin.ts @@ -0,0 +1,21 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {BuiltinFn, DYNAMIC_VALUE, ResolvedValue, ResolvedValueArray} from './result'; + +export class ArraySliceBuiltinFn extends BuiltinFn { + constructor(private lhs: ResolvedValueArray) { super(); } + + evaluate(args: ResolvedValueArray): ResolvedValue { + if (args.length === 0) { + return this.lhs; + } else { + return DYNAMIC_VALUE; + } + } +} diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/interface.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/interface.ts new file mode 100644 index 0000000000..695f536765 --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/interface.ts @@ -0,0 +1,31 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import * as ts from 'typescript'; + +import {Reference} from '../../imports'; +import {ReflectionHost} from '../../reflection'; + +import {StaticInterpreter} from './interpreter'; +import {ResolvedValue} from './result'; + +export type ForeignFunctionResolver = + (node: Reference, args: ts.Expression[]) => + ts.Expression | null; + +export class PartialEvaluator { + constructor(private host: ReflectionHost, private checker: ts.TypeChecker) {} + + evaluate(expr: ts.Expression, foreignFunctionResolver?: ForeignFunctionResolver): ResolvedValue { + const interpreter = new StaticInterpreter(this.host, this.checker); + return interpreter.visit(expr, { + absoluteModuleName: null, + scope: new Map(), foreignFunctionResolver, + }); + } +} diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/interpreter.ts similarity index 69% rename from packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts rename to packages/compiler-cli/src/ngtsc/partial_evaluator/src/interpreter.ts index c323160fd9..4fb0fca483 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/resolver.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/interpreter.ts @@ -6,97 +6,14 @@ * found in the LICENSE file at https://angular.io/license */ -/** - * resolver.ts implements partial computation of expressions, resolving expressions to static - * values where possible and returning a `DynamicValue` signal when not. - */ - -import {Expression, ExternalExpr, ExternalReference, WrappedNodeExpr} from '@angular/compiler'; -import * as path from 'path'; import * as ts from 'typescript'; -import {ClassMemberKind, ReflectionHost} from '../../host'; +import {AbsoluteReference, NodeReference, Reference, ResolvedReference} from '../../imports'; +import {ReflectionHost} from '../../reflection'; -const TS_DTS_JS_EXTENSION = /(?:\.d)?\.ts$|\.js$/; +import {ArraySliceBuiltinFn} from './builtin'; +import {BuiltinFn, DYNAMIC_VALUE, EnumValue, ResolvedValue, ResolvedValueArray, ResolvedValueMap, isDynamicValue} from './result'; -/** - * Represents a value which cannot be determined statically. - * - * Use `isDynamicValue` to determine whether a `ResolvedValue` is a `DynamicValue`. - */ -export class DynamicValue { - /** - * This is needed so the "is DynamicValue" assertion of `isDynamicValue` actually has meaning. - * - * Otherwise, "is DynamicValue" is akin to "is {}" which doesn't trigger narrowing. - */ - private _isDynamic = true; -} - -/** - * An internal flyweight for `DynamicValue`. Eventually the dynamic value will carry information - * on the location of the node that could not be statically computed. - */ -const DYNAMIC_VALUE: DynamicValue = new DynamicValue(); - -/** - * Used to test whether a `ResolvedValue` is a `DynamicValue`. - */ -export function isDynamicValue(value: any): value is DynamicValue { - return value === DYNAMIC_VALUE; -} - -/** - * A value resulting from static resolution. - * - * This could be a primitive, collection type, reference to a `ts.Node` that declares a - * non-primitive value, or a special `DynamicValue` type which indicates the value was not - * available statically. - */ -export type ResolvedValue = number | boolean | string | null | undefined | Reference | EnumValue | - ResolvedValueArray | ResolvedValueMap | BuiltinFn | DynamicValue; - -/** - * An array of `ResolvedValue`s. - * - * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueArray` - * -> - * `ResolvedValue`. - */ -export interface ResolvedValueArray extends Array {} - -/** - * A map of strings to `ResolvedValue`s. - * - * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueMap` -> - * `ResolvedValue`. - */ export interface ResolvedValueMap extends Map {} - -/** - * A value member of an enumeration. - * - * Contains a `Reference` to the enumeration itself, and the name of the referenced member. - */ -export class EnumValue { - constructor(readonly enumRef: Reference, readonly name: string) {} -} - -/** - * An implementation of a builtin function, such as `Array.prototype.slice`. - */ -export abstract class BuiltinFn { abstract evaluate(args: ResolvedValueArray): ResolvedValue; } - -class ArraySliceBuiltinFn extends BuiltinFn { - constructor(private lhs: ResolvedValueArray) { super(); } - - evaluate(args: ResolvedValueArray): ResolvedValue { - if (args.length === 0) { - return this.lhs; - } else { - return DYNAMIC_VALUE; - } - } -} /** * Tracks the scope of a function body, which includes `ResolvedValue`s for the parameters of that @@ -104,164 +21,6 @@ class ArraySliceBuiltinFn extends BuiltinFn { */ type Scope = Map; -export enum ImportMode { - UseExistingImport, - ForceNewImport, -} - -/** - * A reference to a `ts.Node`. - * - * For example, if an expression evaluates to a function or class definition, it will be returned - * as a `Reference` (assuming references are allowed in evaluation). - */ -export abstract class Reference { - constructor(readonly node: T) {} - - /** - * Whether an `Expression` can be generated which references the node. - */ - // TODO(issue/24571): remove '!'. - readonly expressable !: boolean; - - /** - * Generate an `Expression` representing this type, in the context of the given SourceFile. - * - * This could be a local variable reference, if the symbol is imported, or it could be a new - * import if needed. - */ - abstract toExpression(context: ts.SourceFile, importMode?: ImportMode): Expression|null; - - abstract addIdentifier(identifier: ts.Identifier): void; -} - -/** - * A reference to a node only, without any ability to get an `Expression` representing that node. - * - * This is used for returning references to things like method declarations, which are not directly - * referenceable. - */ -export class NodeReference extends Reference { - constructor(node: T, readonly moduleName: string|null) { super(node); } - - toExpression(context: ts.SourceFile): null { return null; } - - addIdentifier(identifier: ts.Identifier): void {} -} - -/** - * A reference to a node which has a `ts.Identifier` and can be resolved to an `Expression`. - * - * Imports generated by `ResolvedReference`s are always relative. - */ -export class ResolvedReference extends Reference { - protected identifiers: ts.Identifier[] = []; - - constructor(node: T, protected primaryIdentifier: ts.Identifier) { super(node); } - - readonly expressable = true; - - toExpression(context: ts.SourceFile, importMode: ImportMode = ImportMode.UseExistingImport): - Expression { - const localIdentifier = - pickIdentifier(context, this.primaryIdentifier, this.identifiers, importMode); - if (localIdentifier !== null) { - return new WrappedNodeExpr(localIdentifier); - } else { - // Relative import from context -> this.node.getSourceFile(). - // TODO(alxhub): investigate the impact of multiple source roots here. - // TODO(alxhub): investigate the need to map such paths via the Host for proper g3 support. - let relative = - path.posix.relative(path.dirname(context.fileName), this.node.getSourceFile().fileName) - .replace(TS_DTS_JS_EXTENSION, ''); - - // path.relative() does not include the leading './'. - if (!relative.startsWith('.')) { - relative = `./${relative}`; - } - - // path.relative() returns the empty string (converted to './' above) if the two paths are the - // same. - if (relative === './') { - // Same file after all. - return new WrappedNodeExpr(this.primaryIdentifier); - } else { - return new ExternalExpr(new ExternalReference(relative, this.primaryIdentifier.text)); - } - } - } - - addIdentifier(identifier: ts.Identifier): void { this.identifiers.push(identifier); } -} - -/** - * A reference to a node which has a `ts.Identifer` and an expected absolute module name. - * - * An `AbsoluteReference` can be resolved to an `Expression`, and if that expression is an import - * the module specifier will be an absolute module name, not a relative path. - */ -export class AbsoluteReference extends Reference { - private identifiers: ts.Identifier[] = []; - constructor( - node: T, private primaryIdentifier: ts.Identifier, readonly moduleName: string, - readonly symbolName: string) { - super(node); - } - - readonly expressable = true; - - toExpression(context: ts.SourceFile, importMode: ImportMode = ImportMode.UseExistingImport): - Expression { - const localIdentifier = - pickIdentifier(context, this.primaryIdentifier, this.identifiers, importMode); - if (localIdentifier !== null) { - return new WrappedNodeExpr(localIdentifier); - } else { - return new ExternalExpr(new ExternalReference(this.moduleName, this.symbolName)); - } - } - - addIdentifier(identifier: ts.Identifier): void { this.identifiers.push(identifier); } -} - -function pickIdentifier( - context: ts.SourceFile, primary: ts.Identifier, secondaries: ts.Identifier[], - mode: ImportMode): ts.Identifier|null { - context = ts.getOriginalNode(context) as ts.SourceFile; - - if (ts.getOriginalNode(primary).getSourceFile() === context) { - return primary; - } else if (mode === ImportMode.UseExistingImport) { - return secondaries.find(id => ts.getOriginalNode(id).getSourceFile() === context) || null; - } else { - return null; - } -} - -/** - * Statically resolve the given `ts.Expression` into a `ResolvedValue`. - * - * @param node the expression to statically resolve if possible - * @param checker a `ts.TypeChecker` used to understand the expression - * @param foreignFunctionResolver a function which will be used whenever a "foreign function" is - * encountered. A foreign function is a function which has no body - usually the result of calling - * a function declared in another library's .d.ts file. In these cases, the foreignFunctionResolver - * will be called with the function's declaration, and can optionally return a `ts.Expression` - * (possibly extracted from the foreign function's type signature) which will be used as the result - * of the call. - * @returns a `ResolvedValue` representing the resolved value - */ -export function staticallyResolve( - node: ts.Expression, host: ReflectionHost, checker: ts.TypeChecker, - foreignFunctionResolver?: - (node: Reference, args: ts.Expression[]) => - ts.Expression | null): ResolvedValue { - return new StaticInterpreter(host, checker).visit(node, { - absoluteModuleName: null, - scope: new Map(), foreignFunctionResolver, - }); -} - interface BinaryOperatorDef { literal: boolean; op: (a: any, b: any) => ResolvedValue; @@ -309,7 +68,7 @@ interface Context { args: ReadonlyArray): ts.Expression|null; } -class StaticInterpreter { +export class StaticInterpreter { constructor(private host: ReflectionHost, private checker: ts.TypeChecker) {} visit(node: ts.Expression, context: Context): ResolvedValue { diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/src/result.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/result.ts new file mode 100644 index 0000000000..219563aefd --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/src/result.ts @@ -0,0 +1,79 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import * as ts from 'typescript'; + +import {Reference} from '../../imports'; + + +/** + * A value resulting from static resolution. + * + * This could be a primitive, collection type, reference to a `ts.Node` that declares a + * non-primitive value, or a special `DynamicValue` type which indicates the value was not + * available statically. + */ +export type ResolvedValue = number | boolean | string | null | undefined | Reference | EnumValue | + ResolvedValueArray | ResolvedValueMap | BuiltinFn | DynamicValue; + +/** + * Represents a value which cannot be determined statically. + * + * Use `isDynamicValue` to determine whether a `ResolvedValue` is a `DynamicValue`. + */ +export class DynamicValue { + /** + * This is needed so the "is DynamicValue" assertion of `isDynamicValue` actually has meaning. + * + * Otherwise, "is DynamicValue" is akin to "is {}" which doesn't trigger narrowing. + */ + private _isDynamic = true; +} + +/** + * An internal flyweight for `DynamicValue`. Eventually the dynamic value will carry information + * on the location of the node that could not be statically computed. + */ +export const DYNAMIC_VALUE: DynamicValue = new DynamicValue(); + +/** + * Used to test whether a `ResolvedValue` is a `DynamicValue`. + */ +export function isDynamicValue(value: any): value is DynamicValue { + return value === DYNAMIC_VALUE; +} + +/** + * An array of `ResolvedValue`s. + * + * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueArray` + * -> + * `ResolvedValue`. + */ +export interface ResolvedValueArray extends Array {} + +/** + * A map of strings to `ResolvedValue`s. + * + * This is a reified type to allow the circular reference of `ResolvedValue` -> `ResolvedValueMap` -> + * `ResolvedValue`. + */ export interface ResolvedValueMap extends Map {} + +/** + * A value member of an enumeration. + * + * Contains a `Reference` to the enumeration itself, and the name of the referenced member. + */ +export class EnumValue { + constructor(readonly enumRef: Reference, readonly name: string) {} +} + +/** + * An implementation of a builtin function, such as `Array.prototype.slice`. + */ +export abstract class BuiltinFn { abstract evaluate(args: ResolvedValueArray): ResolvedValue; } diff --git a/packages/compiler-cli/src/ngtsc/partial_evaluator/test/BUILD.bazel b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/BUILD.bazel new file mode 100644 index 0000000000..c79c44c2cb --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/BUILD.bazel @@ -0,0 +1,29 @@ +package(default_visibility = ["//visibility:public"]) + +load("//tools:defaults.bzl", "jasmine_node_test", "ts_library") + +ts_library( + name = "test_lib", + testonly = True, + srcs = glob([ + "**/*.ts", + ]), + deps = [ + "//packages:types", + "//packages/compiler", + "//packages/compiler-cli/src/ngtsc/imports", + "//packages/compiler-cli/src/ngtsc/partial_evaluator", + "//packages/compiler-cli/src/ngtsc/reflection", + "//packages/compiler-cli/src/ngtsc/testing", + "@ngdeps//typescript", + ], +) + +jasmine_node_test( + name = "test", + bootstrap = ["angular/tools/testing/init_node_no_angular_spec.js"], + deps = [ + ":test_lib", + "//tools/testing:node_no_angular", + ], +) diff --git a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts similarity index 90% rename from packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts rename to packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts index 8a4ed0a3fd..6f6f82cf2f 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/test/resolver_spec.ts +++ b/packages/compiler-cli/src/ngtsc/partial_evaluator/test/evaluator_spec.ts @@ -9,9 +9,11 @@ import {WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; -import {TypeScriptReflectionHost} from '..'; +import {AbsoluteReference, Reference} from '../../imports'; +import {TypeScriptReflectionHost} from '../../reflection'; import {getDeclaration, makeProgram} from '../../testing/in_memory_typescript'; -import {AbsoluteReference, EnumValue, Reference, ResolvedValue, staticallyResolve} from '../src/resolver'; +import {PartialEvaluator} from '../src/interface'; +import {EnumValue, ResolvedValue} from '../src/result'; function makeSimpleProgram(contents: string): ts.Program { return makeProgram([{name: 'entry.ts', contents}]).program; @@ -32,7 +34,8 @@ function makeExpression( function evaluate(code: string, expr: string): T { const {expression, checker} = makeExpression(code, expr); const host = new TypeScriptReflectionHost(checker); - return staticallyResolve(expression, host, checker) as T; + const evaluator = new PartialEvaluator(host, checker); + return evaluator.evaluate(expression) as T; } describe('ngtsc metadata', () => { @@ -55,8 +58,9 @@ describe('ngtsc metadata', () => { ]); const decl = getDeclaration(program, 'entry.ts', 'X', ts.isVariableDeclaration); const host = new TypeScriptReflectionHost(program.getTypeChecker()); + const evaluator = new PartialEvaluator(host, program.getTypeChecker()); - const value = staticallyResolve(decl.initializer !, host, program.getTypeChecker()); + const value = evaluator.evaluate(decl.initializer !); expect(value).toEqual('test'); }); @@ -142,7 +146,8 @@ describe('ngtsc metadata', () => { const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - const resolved = staticallyResolve(expr, host, checker); + const evaluator = new PartialEvaluator(host, checker); + const resolved = evaluator.evaluate(expr); if (!(resolved instanceof Reference)) { return fail('Expected expression to resolve to a reference'); } @@ -173,7 +178,8 @@ describe('ngtsc metadata', () => { const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - const resolved = staticallyResolve(expr, host, checker); + const evaluator = new PartialEvaluator(host, checker); + const resolved = evaluator.evaluate(expr); if (!(resolved instanceof AbsoluteReference)) { return fail('Expected expression to resolve to an absolute reference'); } @@ -205,7 +211,8 @@ describe('ngtsc metadata', () => { const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - expect(staticallyResolve(expr, host, checker)).toEqual('test'); + const evaluator = new PartialEvaluator(host, checker); + expect(evaluator.evaluate(expr)).toEqual('test'); }); it('reads values from named exports', () => { @@ -223,7 +230,8 @@ describe('ngtsc metadata', () => { const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - expect(staticallyResolve(expr, host, checker)).toEqual('test'); + const evaluator = new PartialEvaluator(host, checker); + expect(evaluator.evaluate(expr)).toEqual('test'); }); it('chain of re-exports works', () => { @@ -241,7 +249,8 @@ describe('ngtsc metadata', () => { const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); const expr = result.initializer !; - expect(staticallyResolve(expr, host, checker)).toEqual('test'); + const evaluator = new PartialEvaluator(host, checker); + expect(evaluator.evaluate(expr)).toEqual('test'); }); it('map spread works', () => { @@ -297,7 +306,8 @@ describe('ngtsc metadata', () => { const checker = program.getTypeChecker(); const host = new TypeScriptReflectionHost(checker); const result = getDeclaration(program, 'entry.ts', 'target$', ts.isVariableDeclaration); - const res = staticallyResolve(result.initializer !, host, checker); + const evaluator = new PartialEvaluator(host, checker); + const res = evaluator.evaluate(result.initializer !); expect(res instanceof Reference).toBe(true); }); }); diff --git a/packages/compiler-cli/src/ngtsc/program.ts b/packages/compiler-cli/src/ngtsc/program.ts index f6e7c95816..1cb8599b32 100644 --- a/packages/compiler-cli/src/ngtsc/program.ts +++ b/packages/compiler-cli/src/ngtsc/program.ts @@ -7,7 +7,6 @@ */ import {GeneratedFile} from '@angular/compiler'; -import * as path from 'path'; import * as ts from 'typescript'; import * as api from '../transformers/api'; @@ -16,7 +15,8 @@ import {nocollapseHack} from '../transformers/nocollapse_hack'; import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, NoopReferencesRegistry, PipeDecoratorHandler, ResourceLoader, SelectorScopeRegistry} from './annotations'; import {BaseDefDecoratorHandler} from './annotations/src/base_def'; import {FlatIndexGenerator} from './entry_point'; -import {TypeScriptReflectionHost} from './metadata'; +import {PartialEvaluator} from './partial_evaluator'; +import {TypeScriptReflectionHost} from './reflection'; import {FileResourceLoader, HostResourceLoader} from './resource_loader'; import {FactoryGenerator, FactoryInfo, GeneratedShimsHostWrapper, ShimGenerator, SummaryGenerator, generatedFactoryTransform} from './shims'; import {ivySwitchTransform} from './switch'; @@ -251,20 +251,21 @@ export class NgtscProgram implements api.Program { private makeCompilation(): IvyCompilation { const checker = this.tsProgram.getTypeChecker(); + const evaluator = new PartialEvaluator(this.reflector, checker); const scopeRegistry = new SelectorScopeRegistry(checker, this.reflector); const referencesRegistry = new NoopReferencesRegistry(); // Set up the IvyCompilation, which manages state for the Ivy transformer. const handlers = [ - new BaseDefDecoratorHandler(checker, this.reflector), + new BaseDefDecoratorHandler(this.reflector, evaluator), new ComponentDecoratorHandler( - checker, this.reflector, scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs, + this.reflector, evaluator, scopeRegistry, this.isCore, this.resourceLoader, this.rootDirs, this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false), - new DirectiveDecoratorHandler(checker, this.reflector, scopeRegistry, this.isCore), + new DirectiveDecoratorHandler(this.reflector, evaluator, scopeRegistry, this.isCore), new InjectableDecoratorHandler(this.reflector, this.isCore), new NgModuleDecoratorHandler( - checker, this.reflector, scopeRegistry, referencesRegistry, this.isCore), - new PipeDecoratorHandler(checker, this.reflector, scopeRegistry, this.isCore), + this.reflector, evaluator, scopeRegistry, referencesRegistry, this.isCore), + new PipeDecoratorHandler(this.reflector, evaluator, scopeRegistry, this.isCore), ]; return new IvyCompilation( diff --git a/packages/compiler-cli/src/ngtsc/host/BUILD.bazel b/packages/compiler-cli/src/ngtsc/reflection/BUILD.bazel similarity index 71% rename from packages/compiler-cli/src/ngtsc/host/BUILD.bazel rename to packages/compiler-cli/src/ngtsc/reflection/BUILD.bazel index b0cfa74ad6..440d3398e0 100644 --- a/packages/compiler-cli/src/ngtsc/host/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/reflection/BUILD.bazel @@ -3,11 +3,11 @@ package(default_visibility = ["//visibility:public"]) load("//tools:defaults.bzl", "ts_library") ts_library( - name = "host", + name = "reflection", srcs = glob([ "index.ts", "src/**/*.ts", ]), - module_name = "@angular/compiler-cli/src/ngtsc/host", + module_name = "@angular/compiler-cli/src/ngtsc/reflection", deps = ["@ngdeps//typescript"], ) diff --git a/packages/compiler-cli/src/ngtsc/reflection/index.ts b/packages/compiler-cli/src/ngtsc/reflection/index.ts new file mode 100644 index 0000000000..d5615ed5ac --- /dev/null +++ b/packages/compiler-cli/src/ngtsc/reflection/index.ts @@ -0,0 +1,10 @@ +/** + * @license + * Copyright Google Inc. All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +export * from './src/host'; +export {TypeScriptReflectionHost, filterToMembersWithDecorator, reflectIdentifierOfDeclaration, reflectNameOfDeclaration, reflectObjectLiteral, reflectTypeEntityToDeclaration, typeNodeToValueExpr} from './src/typescript'; \ No newline at end of file diff --git a/packages/compiler-cli/src/ngtsc/host/src/reflection.ts b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts similarity index 100% rename from packages/compiler-cli/src/ngtsc/host/src/reflection.ts rename to packages/compiler-cli/src/ngtsc/reflection/src/host.ts diff --git a/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts similarity index 99% rename from packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts rename to packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts index 2211a54a2a..460a1e3eea 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/src/reflector.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/typescript.ts @@ -8,7 +8,7 @@ import * as ts from 'typescript'; -import {ClassMember, ClassMemberKind, CtorParameter, Declaration, Decorator, FunctionDefinition, Import, ReflectionHost} from '../../host'; +import {ClassMember, ClassMemberKind, CtorParameter, Declaration, Decorator, FunctionDefinition, Import, ReflectionHost} from './host'; /** * reflector.ts implements static reflection of declarations using the TypeScript `ts.TypeChecker`. diff --git a/packages/compiler-cli/src/ngtsc/metadata/test/BUILD.bazel b/packages/compiler-cli/src/ngtsc/reflection/test/BUILD.bazel similarity index 80% rename from packages/compiler-cli/src/ngtsc/metadata/test/BUILD.bazel rename to packages/compiler-cli/src/ngtsc/reflection/test/BUILD.bazel index 7fd3b12092..c9301bc16d 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/test/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/reflection/test/BUILD.bazel @@ -10,9 +10,7 @@ ts_library( ]), deps = [ "//packages:types", - "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/testing", "@ngdeps//typescript", ], diff --git a/packages/compiler-cli/src/ngtsc/metadata/test/reflector_spec.ts b/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts similarity index 98% rename from packages/compiler-cli/src/ngtsc/metadata/test/reflector_spec.ts rename to packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts index d8d2c3c2e9..e9e596b434 100644 --- a/packages/compiler-cli/src/ngtsc/metadata/test/reflector_spec.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/test/ts_host_spec.ts @@ -8,9 +8,9 @@ import * as ts from 'typescript'; -import {CtorParameter} from '../../host'; import {getDeclaration, makeProgram} from '../../testing/in_memory_typescript'; -import {TypeScriptReflectionHost} from '../src/reflector'; +import {CtorParameter} from '../src/host'; +import {TypeScriptReflectionHost} from '../src/typescript'; describe('reflector', () => { describe('ctor params', () => { diff --git a/packages/compiler-cli/src/ngtsc/shims/BUILD.bazel b/packages/compiler-cli/src/ngtsc/shims/BUILD.bazel index 68e66fb562..d936b34d9b 100644 --- a/packages/compiler-cli/src/ngtsc/shims/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/shims/BUILD.bazel @@ -11,8 +11,6 @@ ts_library( module_name = "@angular/compiler-cli/src/ngtsc/shims", deps = [ "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", "//packages/compiler-cli/src/ngtsc/util", "@ngdeps//@types/node", "@ngdeps//typescript", diff --git a/packages/compiler-cli/src/ngtsc/shims/src/host.ts b/packages/compiler-cli/src/ngtsc/shims/src/host.ts index 4bcf98e2f8..5dcf0af8dc 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/host.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.io/license */ -import * as path from 'path'; import * as ts from 'typescript'; export interface ShimGenerator { diff --git a/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel b/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel index 59b24432f9..d57955dcec 100644 --- a/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/switch/BUILD.bazel @@ -11,9 +11,6 @@ ts_library( module_name = "@angular/compiler-cli/src/ngtsc/switch", deps = [ "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", - "//packages/compiler-cli/src/ngtsc/util", "@ngdeps//typescript", ], ) diff --git a/packages/compiler-cli/src/ngtsc/transform/BUILD.bazel b/packages/compiler-cli/src/ngtsc/transform/BUILD.bazel index 67a726fdbc..cece39c676 100644 --- a/packages/compiler-cli/src/ngtsc/transform/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/transform/BUILD.bazel @@ -12,8 +12,7 @@ ts_library( deps = [ "//packages/compiler", "//packages/compiler-cli/src/ngtsc/diagnostics", - "//packages/compiler-cli/src/ngtsc/host", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/reflection", "//packages/compiler-cli/src/ngtsc/translator", "//packages/compiler-cli/src/ngtsc/typecheck", "//packages/compiler-cli/src/ngtsc/util", diff --git a/packages/compiler-cli/src/ngtsc/transform/src/api.ts b/packages/compiler-cli/src/ngtsc/transform/src/api.ts index 59a3182350..6580e425ad 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/api.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/api.ts @@ -9,7 +9,7 @@ import {ConstantPool, Expression, Statement, Type} from '@angular/compiler'; import * as ts from 'typescript'; -import {Decorator} from '../../host'; +import {Decorator} from '../../reflection'; import {TypeCheckContext} from '../../typecheck'; diff --git a/packages/compiler-cli/src/ngtsc/transform/src/compilation.ts b/packages/compiler-cli/src/ngtsc/transform/src/compilation.ts index f42e828a43..06e075c4b7 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/compilation.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/compilation.ts @@ -10,8 +10,7 @@ import {ConstantPool} from '@angular/compiler'; import * as ts from 'typescript'; import {FatalDiagnosticError} from '../../diagnostics'; -import {Decorator, ReflectionHost} from '../../host'; -import {reflectNameOfDeclaration} from '../../metadata/src/reflector'; +import {Decorator, ReflectionHost, reflectNameOfDeclaration} from '../../reflection'; import {TypeCheckContext} from '../../typecheck'; import {AnalysisOutput, CompileResult, DecoratorHandler} from './api'; diff --git a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts index 267eeff035..8eba7da50b 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts @@ -9,9 +9,8 @@ import {ConstantPool} from '@angular/compiler'; import * as ts from 'typescript'; -import {Decorator, ReflectionHost} from '../../host'; +import {Decorator, ReflectionHost} from '../../reflection'; import {ImportManager, translateExpression, translateStatement} from '../../translator'; -import {relativePathBetween} from '../../util/src/path'; import {VisitListEntryResult, Visitor, visit} from '../../util/src/visitor'; import {CompileResult} from './api'; diff --git a/packages/compiler-cli/src/ngtsc/typecheck/BUILD.bazel b/packages/compiler-cli/src/ngtsc/typecheck/BUILD.bazel index fd79b3cd3c..9b8dd51221 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/typecheck/BUILD.bazel @@ -9,7 +9,7 @@ ts_library( deps = [ "//packages:types", "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/metadata", + "//packages/compiler-cli/src/ngtsc/imports", "//packages/compiler-cli/src/ngtsc/translator", "//packages/compiler-cli/src/ngtsc/util", "@ngdeps//typescript", diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/api.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/api.ts index 79ce553b37..b603836a05 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/api.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/api.ts @@ -9,7 +9,7 @@ import {BoundTarget, DirectiveMeta} from '@angular/compiler'; import * as ts from 'typescript'; -import {Reference} from '../../metadata'; +import {Reference} from '../../imports'; /** * Extension of `DirectiveMeta` that includes additional information required to type-check the diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts index c37d7a10e5..08d207f5ac 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/type_check_block.ts @@ -9,7 +9,7 @@ import {AST, BindingType, BoundTarget, ImplicitReceiver, PropertyRead, TmplAstBoundText, TmplAstElement, TmplAstNode, TmplAstTemplate, TmplAstVariable} from '@angular/compiler'; import * as ts from 'typescript'; -import {Reference} from '../../metadata'; +import {Reference} from '../../imports'; import {ImportManager, translateExpression} from '../../translator'; import {TypeCheckBlockMetadata, TypeCheckableDirectiveMeta} from './api'; diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/BUILD.bazel b/packages/compiler-cli/src/ngtsc/typecheck/test/BUILD.bazel index 6de544a767..97da7159e6 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/BUILD.bazel +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/BUILD.bazel @@ -10,8 +10,6 @@ ts_library( ]), deps = [ "//packages:types", - "//packages/compiler", - "//packages/compiler-cli/src/ngtsc/host", "//packages/compiler-cli/src/ngtsc/testing", "//packages/compiler-cli/src/ngtsc/typecheck", "@ngdeps//typescript",