refactor(compiler): split compiler and core (#18683)
After this, neither @angular/compiler nor @angular/comnpiler-cli depend on @angular/core. This add a duplication of some interfaces and enums which is stored in @angular/compiler/src/core.ts BREAKING CHANGE: - `@angular/platform-server` now additionally depends on `@angular/platform-browser-dynamic` as a peer dependency. PR Close #18683
This commit is contained in:

committed by
Miško Hevery

parent
a0ca01d580
commit
0cc77b4a69
@ -8,6 +8,6 @@ ts_library(
|
||||
"testing/**",
|
||||
]),
|
||||
module_name = "@angular/compiler",
|
||||
deps = ["//packages/core"],
|
||||
deps = [],
|
||||
tsconfig = ":tsconfig-build.json",
|
||||
)
|
||||
|
@ -11,9 +11,6 @@
|
||||
"dependencies": {
|
||||
"tslib": "^1.7.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/core": "0.0.0-PLACEHOLDER"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.git"
|
||||
|
@ -6,9 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {MissingTranslationStrategy, ViewEncapsulation, ɵConsole as Console} from '@angular/core';
|
||||
|
||||
import {CompilerConfig} from '../config';
|
||||
import {MissingTranslationStrategy, ViewEncapsulation} from '../core';
|
||||
import {DirectiveNormalizer} from '../directive_normalizer';
|
||||
import {DirectiveResolver} from '../directive_resolver';
|
||||
import {Lexer} from '../expression_parser/lexer';
|
||||
@ -61,7 +60,6 @@ export function createAotCompiler(compilerHost: AotCompilerHost, options: AotCom
|
||||
const summaryResolver = new AotSummaryResolver(compilerHost, symbolCache);
|
||||
const symbolResolver = new StaticSymbolResolver(compilerHost, symbolCache, summaryResolver);
|
||||
const staticReflector = new StaticReflector(summaryResolver, symbolResolver);
|
||||
const console = new Console();
|
||||
const htmlParser = new I18NHtmlParser(
|
||||
new HtmlParser(), translations, options.i18nFormat, options.missingTranslation, console);
|
||||
const config = new CompilerConfig({
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {MissingTranslationStrategy} from '@angular/core';
|
||||
import {MissingTranslationStrategy} from '../core';
|
||||
|
||||
export interface AotCompilerOptions {
|
||||
locale?: string;
|
||||
|
@ -6,10 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Attribute, Component, ContentChild, ContentChildren, Directive, Host, HostBinding, HostListener, Inject, Injectable, Input, NgModule, Optional, Output, Pipe, Self, SkipSelf, ViewChild, ViewChildren, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||
|
||||
import {CompileSummaryKind} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {MetadataFactory, createAttribute, createComponent, createContentChild, createContentChildren, createDirective, createHost, createHostBinding, createHostListener, createInject, createInjectable, createInput, createNgModule, createOptional, createOutput, createPipe, createSelf, createSkipSelf, createViewChild, createViewChildren} from '../core';
|
||||
import * as o from '../output/output_ast';
|
||||
import {SummaryResolver} from '../summary_resolver';
|
||||
import {syntaxError} from '../util';
|
||||
@ -48,8 +47,8 @@ export class StaticReflector implements CompileReflector {
|
||||
private opaqueToken: StaticSymbol;
|
||||
private ROUTES: StaticSymbol;
|
||||
private ANALYZE_FOR_ENTRY_COMPONENTS: StaticSymbol;
|
||||
private annotationForParentClassWithSummaryKind = new Map<CompileSummaryKind, any[]>();
|
||||
private annotationNames = new Map<any, string>();
|
||||
private annotationForParentClassWithSummaryKind =
|
||||
new Map<CompileSummaryKind, MetadataFactory<any>[]>();
|
||||
|
||||
constructor(
|
||||
private summaryResolver: SummaryResolver<StaticSymbol>,
|
||||
@ -64,16 +63,12 @@ export class StaticReflector implements CompileReflector {
|
||||
knownMetadataFunctions.forEach(
|
||||
(kf) => this._registerFunction(this.getStaticSymbol(kf.filePath, kf.name), kf.fn));
|
||||
this.annotationForParentClassWithSummaryKind.set(
|
||||
CompileSummaryKind.Directive, [Directive, Component]);
|
||||
this.annotationForParentClassWithSummaryKind.set(CompileSummaryKind.Pipe, [Pipe]);
|
||||
this.annotationForParentClassWithSummaryKind.set(CompileSummaryKind.NgModule, [NgModule]);
|
||||
CompileSummaryKind.Directive, [createDirective, createComponent]);
|
||||
this.annotationForParentClassWithSummaryKind.set(CompileSummaryKind.Pipe, [createPipe]);
|
||||
this.annotationForParentClassWithSummaryKind.set(CompileSummaryKind.NgModule, [createNgModule]);
|
||||
this.annotationForParentClassWithSummaryKind.set(
|
||||
CompileSummaryKind.Injectable, [Injectable, Pipe, Directive, Component, NgModule]);
|
||||
this.annotationNames.set(Directive, 'Directive');
|
||||
this.annotationNames.set(Component, 'Component');
|
||||
this.annotationNames.set(Pipe, 'Pipe');
|
||||
this.annotationNames.set(NgModule, 'NgModule');
|
||||
this.annotationNames.set(Injectable, 'Injectable');
|
||||
CompileSummaryKind.Injectable,
|
||||
[createInjectable, createPipe, createDirective, createComponent, createNgModule]);
|
||||
}
|
||||
|
||||
componentModuleUrl(typeOrFunc: StaticSymbol): string {
|
||||
@ -129,12 +124,12 @@ export class StaticReflector implements CompileReflector {
|
||||
const requiredAnnotationTypes =
|
||||
this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind !) !;
|
||||
const typeHasRequiredAnnotation = requiredAnnotationTypes.some(
|
||||
(requiredType: any) => ownAnnotations.some(ann => ann instanceof requiredType));
|
||||
(requiredType) => ownAnnotations.some(ann => requiredType.isTypeOf(ann)));
|
||||
if (!typeHasRequiredAnnotation) {
|
||||
this.reportError(
|
||||
syntaxError(
|
||||
`Class ${type.name} in ${type.filePath} extends from a ${CompileSummaryKind[summary.type.summaryKind!]} in another compilation unit without duplicating the decorator. ` +
|
||||
`Please add a ${requiredAnnotationTypes.map((type: any) => this.annotationNames.get(type)).join(' or ')} decorator to the class.`),
|
||||
`Please add a ${requiredAnnotationTypes.map((type) => type.ngMetadataName).join(' or ')} decorator to the class.`),
|
||||
type);
|
||||
}
|
||||
}
|
||||
@ -281,50 +276,48 @@ export class StaticReflector implements CompileReflector {
|
||||
this.ANALYZE_FOR_ENTRY_COMPONENTS =
|
||||
this.findDeclaration(ANGULAR_CORE, 'ANALYZE_FOR_ENTRY_COMPONENTS');
|
||||
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), Host);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), createHost);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Injectable'), Injectable);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), Self);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), SkipSelf);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Inject'), Inject);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), Optional);
|
||||
this.findDeclaration(ANGULAR_CORE, 'Injectable'), createInjectable);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), createSelf);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Attribute'), Attribute);
|
||||
this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), createSkipSelf);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'ContentChild'), ContentChild);
|
||||
this.findDeclaration(ANGULAR_CORE, 'Inject'), createInject);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'ContentChildren'), ContentChildren);
|
||||
this.findDeclaration(ANGULAR_CORE, 'Optional'), createOptional);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'ViewChild'), ViewChild);
|
||||
this.findDeclaration(ANGULAR_CORE, 'Attribute'), createAttribute);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'ViewChildren'), ViewChildren);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Input'), Input);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Output'), Output);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Pipe'), Pipe);
|
||||
this.findDeclaration(ANGULAR_CORE, 'ContentChild'), createContentChild);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'HostBinding'), HostBinding);
|
||||
this.findDeclaration(ANGULAR_CORE, 'ContentChildren'), createContentChildren);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'HostListener'), HostListener);
|
||||
this.findDeclaration(ANGULAR_CORE, 'ViewChild'), createViewChild);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Directive'), Directive);
|
||||
this.findDeclaration(ANGULAR_CORE, 'ViewChildren'), createViewChildren);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Input'), createInput);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Component'), Component);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'NgModule'), NgModule);
|
||||
this.findDeclaration(ANGULAR_CORE, 'Output'), createOutput);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Pipe'), createPipe);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'HostBinding'), createHostBinding);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'HostListener'), createHostListener);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Directive'), createDirective);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Component'), createComponent);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'NgModule'), createNgModule);
|
||||
|
||||
// Note: Some metadata classes can be used directly with Provider.deps.
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), Host);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), Self);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), SkipSelf);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), Optional);
|
||||
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'trigger'), trigger);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'state'), state);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'transition'), transition);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'style'), style);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'animate'), animate);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'keyframes'), keyframes);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'sequence'), sequence);
|
||||
this._registerFunction(this.findDeclaration(ANGULAR_CORE, 'group'), group);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), createHost);
|
||||
this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), createSelf);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), createSkipSelf);
|
||||
this._registerDecoratorOrConstructor(
|
||||
this.findDeclaration(ANGULAR_CORE, 'Optional'), createOptional);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -755,4 +748,4 @@ function positionalError(message: string, fileName: string, line: number, column
|
||||
(result as any).line = line;
|
||||
(result as any).column = column;
|
||||
return result;
|
||||
}
|
||||
}
|
@ -6,11 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '@angular/core';
|
||||
|
||||
|
||||
export function assertArrayOfStrings(identifier: string, value: any) {
|
||||
if (!isDevMode() || value == null) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (!Array.isArray(value)) {
|
||||
@ -34,7 +31,7 @@ const INTERPOLATION_BLACKLIST_REGEXPS = [
|
||||
export function assertInterpolationSymbols(identifier: string, value: any): void {
|
||||
if (value != null && !(Array.isArray(value) && value.length == 2)) {
|
||||
throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
|
||||
} else if (isDevMode() && value != null) {
|
||||
} else if (value != null) {
|
||||
const start = value[0] as string;
|
||||
const end = value[1] as string;
|
||||
// black list checking
|
||||
|
@ -6,12 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectionStrategy, ComponentFactory, RendererType2, SchemaMetadata, Type, ViewEncapsulation, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {StaticSymbol} from './aot/static_symbol';
|
||||
import {ChangeDetectionStrategy, SchemaMetadata, Type, ViewEncapsulation} from './core';
|
||||
import {LifecycleHooks} from './lifecycle_reflector';
|
||||
import {CssSelector} from './selector';
|
||||
import {splitAtColon} from './util';
|
||||
import {splitAtColon, stringify} from './util';
|
||||
|
||||
|
||||
|
||||
@ -294,7 +293,7 @@ export class CompileTemplateMetadata {
|
||||
|
||||
export interface CompileEntryComponentMetadata {
|
||||
componentType: any;
|
||||
componentFactory: StaticSymbol|ComponentFactory<any>;
|
||||
componentFactory: StaticSymbol|object;
|
||||
}
|
||||
|
||||
// Note: This should only use interfaces as nested data types
|
||||
@ -317,8 +316,8 @@ export interface CompileDirectiveSummary extends CompileTypeSummary {
|
||||
changeDetection: ChangeDetectionStrategy|null;
|
||||
template: CompileTemplateSummary|null;
|
||||
componentViewType: StaticSymbol|ProxyClass|null;
|
||||
rendererType: StaticSymbol|RendererType2|null;
|
||||
componentFactory: StaticSymbol|ComponentFactory<any>|null;
|
||||
rendererType: StaticSymbol|object|null;
|
||||
componentFactory: StaticSymbol|object|null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -344,8 +343,8 @@ export class CompileDirectiveMetadata {
|
||||
entryComponents: CompileEntryComponentMetadata[],
|
||||
template: CompileTemplateMetadata,
|
||||
componentViewType: StaticSymbol|ProxyClass|null,
|
||||
rendererType: StaticSymbol|RendererType2|null,
|
||||
componentFactory: StaticSymbol|ComponentFactory<any>|null,
|
||||
rendererType: StaticSymbol|object|null,
|
||||
componentFactory: StaticSymbol|object|null,
|
||||
}): CompileDirectiveMetadata {
|
||||
const hostListeners: {[key: string]: string} = {};
|
||||
const hostProperties: {[key: string]: string} = {};
|
||||
@ -422,8 +421,8 @@ export class CompileDirectiveMetadata {
|
||||
template: CompileTemplateMetadata|null;
|
||||
|
||||
componentViewType: StaticSymbol|ProxyClass|null;
|
||||
rendererType: StaticSymbol|RendererType2|null;
|
||||
componentFactory: StaticSymbol|ComponentFactory<any>|null;
|
||||
rendererType: StaticSymbol|object|null;
|
||||
componentFactory: StaticSymbol|object|null;
|
||||
|
||||
constructor({isHost, type, isComponent, selector, exportAs,
|
||||
changeDetection, inputs, outputs, hostListeners, hostProperties,
|
||||
@ -447,8 +446,8 @@ export class CompileDirectiveMetadata {
|
||||
entryComponents: CompileEntryComponentMetadata[],
|
||||
template: CompileTemplateMetadata|null,
|
||||
componentViewType: StaticSymbol|ProxyClass|null,
|
||||
rendererType: StaticSymbol|RendererType2|null,
|
||||
componentFactory: StaticSymbol|ComponentFactory<any>|null,
|
||||
rendererType: StaticSymbol|object|null,
|
||||
componentFactory: StaticSymbol|object|null,
|
||||
}) {
|
||||
this.isHost = !!isHost;
|
||||
this.type = type;
|
||||
@ -534,7 +533,8 @@ export function createHostComponentMeta(
|
||||
queries: [],
|
||||
viewQueries: [],
|
||||
componentViewType: hostViewType,
|
||||
rendererType: {id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}},
|
||||
rendererType:
|
||||
{id: '__Host__', encapsulation: ViewEncapsulation.None, styles: [], data: {}} as object,
|
||||
entryComponents: [],
|
||||
componentFactory: null
|
||||
});
|
||||
@ -720,7 +720,7 @@ function _normalizeArray(obj: any[] | undefined | null): any[] {
|
||||
|
||||
export class ProviderMeta {
|
||||
token: any;
|
||||
useClass: Type<any>|null;
|
||||
useClass: Type|null;
|
||||
useValue: any;
|
||||
useExisting: any;
|
||||
useFactory: Function|null;
|
||||
@ -728,7 +728,7 @@ export class ProviderMeta {
|
||||
multi: boolean;
|
||||
|
||||
constructor(token: any, {useClass, useValue, useExisting, useFactory, deps, multi}: {
|
||||
useClass?: Type<any>,
|
||||
useClass?: Type,
|
||||
useValue?: any,
|
||||
useExisting?: any,
|
||||
useFactory?: Function|null,
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component} from '@angular/core';
|
||||
import {Component} from './core';
|
||||
import * as o from './output/output_ast';
|
||||
|
||||
/**
|
||||
|
@ -21,9 +21,13 @@
|
||||
* </p>
|
||||
* </div>
|
||||
*/
|
||||
export {VERSION} from './version';
|
||||
|
||||
import * as core from './core';
|
||||
|
||||
export {core};
|
||||
|
||||
export * from './version';
|
||||
export * from './template_parser/template_ast';
|
||||
export {TEMPLATE_TRANSFORMS} from './template_parser/template_parser';
|
||||
export {CompilerConfig, preserveWhitespacesDefault} from './config';
|
||||
export * from './compile_metadata';
|
||||
export * from './aot/compiler_factory';
|
||||
@ -37,9 +41,8 @@ export * from './aot/static_symbol_resolver';
|
||||
export * from './aot/summary_resolver';
|
||||
export * from './ast_path';
|
||||
export * from './summary_resolver';
|
||||
export {Identifiers} from './identifiers';
|
||||
export {JitCompiler} from './jit/compiler';
|
||||
export * from './jit/compiler_factory';
|
||||
export * from './jit/jit_reflector';
|
||||
export * from './compile_reflector';
|
||||
export * from './url_resolver';
|
||||
export * from './resource_loader';
|
||||
@ -69,5 +72,5 @@ export * from './selector';
|
||||
export * from './style_compiler';
|
||||
export * from './template_parser/template_parser';
|
||||
export {ViewCompiler} from './view_compiler/view_compiler';
|
||||
export {getParseErrors, isSyntaxError, syntaxError} from './util';
|
||||
export {getParseErrors, isSyntaxError, syntaxError, Version} from './util';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
|
@ -6,7 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {MissingTranslationStrategy, ViewEncapsulation} from '@angular/core';
|
||||
import {CompileIdentifierMetadata} from './compile_metadata';
|
||||
import {MissingTranslationStrategy, ViewEncapsulation} from './core';
|
||||
import {Identifiers} from './identifiers';
|
||||
import * as o from './output/output_ast';
|
||||
import {noUndefined} from './util';
|
||||
|
||||
export class CompilerConfig {
|
||||
@ -15,20 +18,23 @@ export class CompilerConfig {
|
||||
// templates. They have been deprecated in 4.x, `<ng-template>` should be used instead.
|
||||
public enableLegacyTemplate: boolean;
|
||||
public useJit: boolean;
|
||||
public jitDevMode: boolean;
|
||||
public missingTranslation: MissingTranslationStrategy|null;
|
||||
public preserveWhitespaces: boolean;
|
||||
|
||||
constructor(
|
||||
{defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, missingTranslation,
|
||||
enableLegacyTemplate, preserveWhitespaces}: {
|
||||
{defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, jitDevMode = false,
|
||||
missingTranslation, enableLegacyTemplate, preserveWhitespaces}: {
|
||||
defaultEncapsulation?: ViewEncapsulation,
|
||||
useJit?: boolean,
|
||||
jitDevMode?: boolean,
|
||||
missingTranslation?: MissingTranslationStrategy,
|
||||
enableLegacyTemplate?: boolean,
|
||||
preserveWhitespaces?: boolean
|
||||
} = {}) {
|
||||
this.defaultEncapsulation = defaultEncapsulation;
|
||||
this.useJit = !!useJit;
|
||||
this.jitDevMode = !!jitDevMode;
|
||||
this.missingTranslation = missingTranslation || null;
|
||||
this.enableLegacyTemplate = enableLegacyTemplate !== false;
|
||||
this.preserveWhitespaces = preserveWhitespacesDefault(noUndefined(preserveWhitespaces));
|
||||
|
262
packages/compiler/src/core.ts
Normal file
262
packages/compiler/src/core.ts
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// Attention:
|
||||
// This file duplicates types and values from @angular/core
|
||||
// so that we are able to make @angular/compiler independent of @angular/core.
|
||||
// This is important to prevent a build cycle, as @angular/core needs to
|
||||
// be compiled with the compiler.
|
||||
|
||||
export interface Inject { token: any; }
|
||||
export const createInject = makeMetadataFactory<Inject>('Inject', (token: any) => ({token}));
|
||||
export const createInjectionToken =
|
||||
makeMetadataFactory<object>('InjectionToken', (token: any) => token);
|
||||
|
||||
export interface Attribute { attributeName?: string; }
|
||||
export const createAttribute =
|
||||
makeMetadataFactory<Attribute>('Attribute', (attributeName?: string) => ({attributeName}));
|
||||
|
||||
export interface Query {
|
||||
descendants: boolean;
|
||||
first: boolean;
|
||||
read: any;
|
||||
isViewQuery: boolean;
|
||||
selector: any;
|
||||
}
|
||||
|
||||
export const createContentChildren = makeMetadataFactory<Query>(
|
||||
'ContentChildren',
|
||||
(selector?: any, data: any = {}) =>
|
||||
({selector, first: false, isViewQuery: false, descendants: false, ...data}));
|
||||
export const createContentChild = makeMetadataFactory<Query>(
|
||||
'ContentChild', (selector?: any, data: any = {}) =>
|
||||
({selector, first: true, isViewQuery: false, descendants: true, ...data}));
|
||||
export const createViewChildren = makeMetadataFactory<Query>(
|
||||
'ViewChildren', (selector?: any, data: any = {}) =>
|
||||
({selector, first: false, isViewQuery: true, descendants: true, ...data}));
|
||||
export const createViewChild = makeMetadataFactory<Query>(
|
||||
'ViewChild', (selector: any, data: any) =>
|
||||
({selector, first: true, isViewQuery: true, descendants: true, ...data}));
|
||||
|
||||
export interface Directive {
|
||||
selector?: string;
|
||||
inputs?: string[];
|
||||
outputs?: string[];
|
||||
host?: {[key: string]: string};
|
||||
providers?: Provider[];
|
||||
exportAs?: string;
|
||||
queries?: {[key: string]: any};
|
||||
}
|
||||
export const createDirective =
|
||||
makeMetadataFactory<Directive>('Directive', (dir: Directive = {}) => dir);
|
||||
|
||||
export interface Component extends Directive {
|
||||
changeDetection?: ChangeDetectionStrategy;
|
||||
viewProviders?: Provider[];
|
||||
moduleId?: string;
|
||||
templateUrl?: string;
|
||||
template?: string;
|
||||
styleUrls?: string[];
|
||||
styles?: string[];
|
||||
animations?: any[];
|
||||
encapsulation?: ViewEncapsulation;
|
||||
interpolation?: [string, string];
|
||||
entryComponents?: Array<Type|any[]>;
|
||||
preserveWhitespaces?: boolean;
|
||||
}
|
||||
export enum ViewEncapsulation {
|
||||
Emulated = 0,
|
||||
Native = 1,
|
||||
None = 2
|
||||
}
|
||||
|
||||
export enum ChangeDetectionStrategy {
|
||||
OnPush = 0,
|
||||
Default = 1
|
||||
}
|
||||
|
||||
export const createComponent = makeMetadataFactory<Component>(
|
||||
'Component', (c: Component = {}) => ({changeDetection: ChangeDetectionStrategy.Default, ...c}));
|
||||
|
||||
export interface Pipe {
|
||||
name: string;
|
||||
pure?: boolean;
|
||||
}
|
||||
export const createPipe = makeMetadataFactory<Pipe>('Pipe', (p: Pipe) => ({pure: true, ...p}));
|
||||
|
||||
export interface Input { bindingPropertyName?: string; }
|
||||
export const createInput =
|
||||
makeMetadataFactory<Input>('Input', (bindingPropertyName?: string) => ({bindingPropertyName}));
|
||||
|
||||
export interface Output { bindingPropertyName?: string; }
|
||||
export const createOutput = makeMetadataFactory<Output>(
|
||||
'Output', (bindingPropertyName?: string) => ({bindingPropertyName}));
|
||||
|
||||
export interface HostBinding { hostPropertyName?: string; }
|
||||
export const createHostBinding = makeMetadataFactory<HostBinding>(
|
||||
'HostBinding', (hostPropertyName?: string) => ({hostPropertyName}));
|
||||
|
||||
export interface HostListener {
|
||||
eventName?: string;
|
||||
args?: string[];
|
||||
}
|
||||
export const createHostListener = makeMetadataFactory<HostListener>(
|
||||
'HostListener', (eventName?: string, args?: string[]) => ({eventName, args}));
|
||||
|
||||
export interface NgModule {
|
||||
providers?: Provider[];
|
||||
declarations?: Array<Type|any[]>;
|
||||
imports?: Array<Type|ModuleWithProviders|any[]>;
|
||||
exports?: Array<Type|any[]>;
|
||||
entryComponents?: Array<Type|any[]>;
|
||||
bootstrap?: Array<Type|any[]>;
|
||||
schemas?: Array<SchemaMetadata|any[]>;
|
||||
id?: string;
|
||||
}
|
||||
export const createNgModule =
|
||||
makeMetadataFactory<NgModule>('NgModule', (ngModule: NgModule) => ngModule);
|
||||
|
||||
export interface ModuleWithProviders {
|
||||
ngModule: Type;
|
||||
providers?: Provider[];
|
||||
}
|
||||
|
||||
export interface SchemaMetadata { name: string; }
|
||||
|
||||
export const CUSTOM_ELEMENTS_SCHEMA: SchemaMetadata = {
|
||||
name: 'custom-elements'
|
||||
};
|
||||
|
||||
export const NO_ERRORS_SCHEMA: SchemaMetadata = {
|
||||
name: 'no-errors-schema'
|
||||
};
|
||||
|
||||
export const createOptional = makeMetadataFactory('Optional');
|
||||
export const createInjectable = makeMetadataFactory('Injectable');
|
||||
export const createSelf = makeMetadataFactory('Self');
|
||||
export const createSkipSelf = makeMetadataFactory('SkipSelf');
|
||||
export const createHost = makeMetadataFactory('Host');
|
||||
|
||||
export interface Type extends Function { new (...args: any[]): any; }
|
||||
export const Type = Function;
|
||||
|
||||
export enum SecurityContext {
|
||||
NONE = 0,
|
||||
HTML = 1,
|
||||
STYLE = 2,
|
||||
SCRIPT = 3,
|
||||
URL = 4,
|
||||
RESOURCE_URL = 5,
|
||||
}
|
||||
|
||||
export type Provider = any;
|
||||
|
||||
export const enum NodeFlags {
|
||||
None = 0,
|
||||
TypeElement = 1 << 0,
|
||||
TypeText = 1 << 1,
|
||||
ProjectedTemplate = 1 << 2,
|
||||
CatRenderNode = TypeElement | TypeText,
|
||||
TypeNgContent = 1 << 3,
|
||||
TypePipe = 1 << 4,
|
||||
TypePureArray = 1 << 5,
|
||||
TypePureObject = 1 << 6,
|
||||
TypePurePipe = 1 << 7,
|
||||
CatPureExpression = TypePureArray | TypePureObject | TypePurePipe,
|
||||
TypeValueProvider = 1 << 8,
|
||||
TypeClassProvider = 1 << 9,
|
||||
TypeFactoryProvider = 1 << 10,
|
||||
TypeUseExistingProvider = 1 << 11,
|
||||
LazyProvider = 1 << 12,
|
||||
PrivateProvider = 1 << 13,
|
||||
TypeDirective = 1 << 14,
|
||||
Component = 1 << 15,
|
||||
CatProviderNoDirective =
|
||||
TypeValueProvider | TypeClassProvider | TypeFactoryProvider | TypeUseExistingProvider,
|
||||
CatProvider = CatProviderNoDirective | TypeDirective,
|
||||
OnInit = 1 << 16,
|
||||
OnDestroy = 1 << 17,
|
||||
DoCheck = 1 << 18,
|
||||
OnChanges = 1 << 19,
|
||||
AfterContentInit = 1 << 20,
|
||||
AfterContentChecked = 1 << 21,
|
||||
AfterViewInit = 1 << 22,
|
||||
AfterViewChecked = 1 << 23,
|
||||
EmbeddedViews = 1 << 24,
|
||||
ComponentView = 1 << 25,
|
||||
TypeContentQuery = 1 << 26,
|
||||
TypeViewQuery = 1 << 27,
|
||||
StaticQuery = 1 << 28,
|
||||
DynamicQuery = 1 << 29,
|
||||
CatQuery = TypeContentQuery | TypeViewQuery,
|
||||
|
||||
// mutually exclusive values...
|
||||
Types = CatRenderNode | TypeNgContent | TypePipe | CatPureExpression | CatProvider | CatQuery
|
||||
}
|
||||
|
||||
export const enum DepFlags {
|
||||
None = 0,
|
||||
SkipSelf = 1 << 0,
|
||||
Optional = 1 << 1,
|
||||
Value = 2 << 2,
|
||||
}
|
||||
|
||||
export const enum ArgumentType {Inline = 0, Dynamic = 1}
|
||||
|
||||
export const enum BindingFlags {
|
||||
TypeElementAttribute = 1 << 0,
|
||||
TypeElementClass = 1 << 1,
|
||||
TypeElementStyle = 1 << 2,
|
||||
TypeProperty = 1 << 3,
|
||||
SyntheticProperty = 1 << 4,
|
||||
SyntheticHostProperty = 1 << 5,
|
||||
CatSyntheticProperty = SyntheticProperty | SyntheticHostProperty,
|
||||
|
||||
// mutually exclusive values...
|
||||
Types = TypeElementAttribute | TypeElementClass | TypeElementStyle | TypeProperty
|
||||
}
|
||||
|
||||
export const enum QueryBindingType {First = 0, All = 1}
|
||||
|
||||
export const enum QueryValueType {
|
||||
ElementRef = 0,
|
||||
RenderElement = 1,
|
||||
TemplateRef = 2,
|
||||
ViewContainerRef = 3,
|
||||
Provider = 4
|
||||
}
|
||||
|
||||
export const enum ViewFlags {
|
||||
None = 0,
|
||||
OnPush = 1 << 1,
|
||||
}
|
||||
|
||||
export enum MissingTranslationStrategy {
|
||||
Error = 0,
|
||||
Warning = 1,
|
||||
Ignore = 2,
|
||||
}
|
||||
|
||||
export interface MetadataFactory<T> {
|
||||
(...args: any[]): T;
|
||||
isTypeOf(obj: any): obj is T;
|
||||
ngMetadataName: string;
|
||||
}
|
||||
|
||||
function makeMetadataFactory<T>(name: string, props?: (...args: any[]) => T): MetadataFactory<T> {
|
||||
const factory: any = (...args: any[]) => {
|
||||
const values = props ? props(...args) : {};
|
||||
return {
|
||||
ngMetadataName: name,
|
||||
...values,
|
||||
};
|
||||
};
|
||||
factory.isTypeOf = (obj: any) => obj && obj.ngMetadataName === name;
|
||||
factory.ngMetadataName = name;
|
||||
return factory;
|
||||
}
|
@ -6,11 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ViewEncapsulation, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileAnimationEntryMetadata, CompileDirectiveMetadata, CompileStylesheetMetadata, CompileTemplateMetadata, templateSourceUrl} from './compile_metadata';
|
||||
import {CompilerConfig, preserveWhitespacesDefault} from './config';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {ViewEncapsulation} from './core';
|
||||
import * as html from './ml_parser/ast';
|
||||
import {HtmlParser} from './ml_parser/html_parser';
|
||||
import {InterpolationConfig} from './ml_parser/interpolation_config';
|
||||
@ -18,7 +16,7 @@ import {ResourceLoader} from './resource_loader';
|
||||
import {extractStyleUrls, isStyleUrlResolvable} from './style_url_resolver';
|
||||
import {PreparsedElementType, preparseElement} from './template_parser/template_preparser';
|
||||
import {UrlResolver} from './url_resolver';
|
||||
import {SyncAsync, isDefined, syntaxError} from './util';
|
||||
import {SyncAsync, isDefined, stringify, syntaxError} from './util';
|
||||
|
||||
export interface PrenormalizedTemplateMetadata {
|
||||
ngModuleType: any;
|
||||
@ -34,7 +32,6 @@ export interface PrenormalizedTemplateMetadata {
|
||||
preserveWhitespaces: boolean|null;
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class DirectiveNormalizer {
|
||||
private _resourceLoaderCache = new Map<string, SyncAsync<string>>();
|
||||
|
||||
|
@ -6,13 +6,16 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Component, Directive, HostBinding, HostListener, Input, Output, Query, Type, resolveForwardRef, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {splitAtColon} from './util';
|
||||
|
||||
import {Component, Directive, Type, createComponent, createContentChild, createContentChildren, createDirective, createHostBinding, createHostListener, createInput, createOutput, createViewChild, createViewChildren} from './core';
|
||||
import {resolveForwardRef, splitAtColon, stringify} from './util';
|
||||
|
||||
const QUERY_METADATA_IDENTIFIERS = [
|
||||
createViewChild,
|
||||
createViewChildren,
|
||||
createContentChild,
|
||||
createContentChildren,
|
||||
];
|
||||
|
||||
/*
|
||||
* Resolve a `Type` for {@link Directive}.
|
||||
@ -21,11 +24,10 @@ import {splitAtColon} from './util';
|
||||
*
|
||||
* See {@link Compiler}
|
||||
*/
|
||||
@CompilerInjectable()
|
||||
export class DirectiveResolver {
|
||||
constructor(private _reflector: CompileReflector) {}
|
||||
|
||||
isDirective(type: Type<any>) {
|
||||
isDirective(type: Type) {
|
||||
const typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
||||
return typeMetadata && typeMetadata.some(isDirectiveMetadata);
|
||||
}
|
||||
@ -33,10 +35,10 @@ export class DirectiveResolver {
|
||||
/**
|
||||
* Return {@link Directive} for a given `Type`.
|
||||
*/
|
||||
resolve(type: Type<any>): Directive;
|
||||
resolve(type: Type<any>, throwIfNotFound: true): Directive;
|
||||
resolve(type: Type<any>, throwIfNotFound: boolean): Directive|null;
|
||||
resolve(type: Type<any>, throwIfNotFound = true): Directive|null {
|
||||
resolve(type: Type): Directive;
|
||||
resolve(type: Type, throwIfNotFound: true): Directive;
|
||||
resolve(type: Type, throwIfNotFound: boolean): Directive|null;
|
||||
resolve(type: Type, throwIfNotFound = true): Directive|null {
|
||||
const typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
||||
if (typeMetadata) {
|
||||
const metadata = findLast(typeMetadata, isDirectiveMetadata);
|
||||
@ -54,15 +56,14 @@ export class DirectiveResolver {
|
||||
}
|
||||
|
||||
private _mergeWithPropertyMetadata(
|
||||
dm: Directive, propertyMetadata: {[key: string]: any[]},
|
||||
directiveType: Type<any>): Directive {
|
||||
dm: Directive, propertyMetadata: {[key: string]: any[]}, directiveType: Type): Directive {
|
||||
const inputs: string[] = [];
|
||||
const outputs: string[] = [];
|
||||
const host: {[key: string]: string} = {};
|
||||
const queries: {[key: string]: any} = {};
|
||||
|
||||
Object.keys(propertyMetadata).forEach((propName: string) => {
|
||||
const input = findLast(propertyMetadata[propName], (a) => a instanceof Input);
|
||||
const input = findLast(propertyMetadata[propName], (a) => createInput.isTypeOf(a));
|
||||
if (input) {
|
||||
if (input.bindingPropertyName) {
|
||||
inputs.push(`${propName}: ${input.bindingPropertyName}`);
|
||||
@ -70,7 +71,7 @@ export class DirectiveResolver {
|
||||
inputs.push(propName);
|
||||
}
|
||||
}
|
||||
const output = findLast(propertyMetadata[propName], (a) => a instanceof Output);
|
||||
const output = findLast(propertyMetadata[propName], (a) => createOutput.isTypeOf(a));
|
||||
if (output) {
|
||||
if (output.bindingPropertyName) {
|
||||
outputs.push(`${propName}: ${output.bindingPropertyName}`);
|
||||
@ -78,7 +79,7 @@ export class DirectiveResolver {
|
||||
outputs.push(propName);
|
||||
}
|
||||
}
|
||||
const hostBindings = propertyMetadata[propName].filter(a => a && a instanceof HostBinding);
|
||||
const hostBindings = propertyMetadata[propName].filter(a => createHostBinding.isTypeOf(a));
|
||||
hostBindings.forEach(hostBinding => {
|
||||
if (hostBinding.hostPropertyName) {
|
||||
const startWith = hostBinding.hostPropertyName[0];
|
||||
@ -93,12 +94,13 @@ export class DirectiveResolver {
|
||||
host[`[${propName}]`] = propName;
|
||||
}
|
||||
});
|
||||
const hostListeners = propertyMetadata[propName].filter(a => a && a instanceof HostListener);
|
||||
const hostListeners = propertyMetadata[propName].filter(a => createHostListener.isTypeOf(a));
|
||||
hostListeners.forEach(hostListener => {
|
||||
const args = hostListener.args || [];
|
||||
host[`(${hostListener.eventName})`] = `${propName}(${args.join(',')})`;
|
||||
});
|
||||
const query = findLast(propertyMetadata[propName], (a) => a instanceof Query);
|
||||
const query = findLast(
|
||||
propertyMetadata[propName], (a) => QUERY_METADATA_IDENTIFIERS.some(i => i.isTypeOf(a)));
|
||||
if (query) {
|
||||
queries[propName] = query;
|
||||
}
|
||||
@ -125,7 +127,7 @@ export class DirectiveResolver {
|
||||
|
||||
private _merge(
|
||||
directive: Directive, inputs: string[], outputs: string[], host: {[key: string]: string},
|
||||
queries: {[key: string]: any}, directiveType: Type<any>): Directive {
|
||||
queries: {[key: string]: any}, directiveType: Type): Directive {
|
||||
const mergedInputs =
|
||||
this._dedupeBindings(directive.inputs ? directive.inputs.concat(inputs) : inputs);
|
||||
const mergedOutputs =
|
||||
@ -133,30 +135,31 @@ export class DirectiveResolver {
|
||||
const mergedHost = directive.host ? {...directive.host, ...host} : host;
|
||||
const mergedQueries = directive.queries ? {...directive.queries, ...queries} : queries;
|
||||
|
||||
if (directive instanceof Component) {
|
||||
return new Component({
|
||||
selector: directive.selector,
|
||||
if (createComponent.isTypeOf(directive)) {
|
||||
const comp = directive as Component;
|
||||
return createComponent({
|
||||
selector: comp.selector,
|
||||
inputs: mergedInputs,
|
||||
outputs: mergedOutputs,
|
||||
host: mergedHost,
|
||||
exportAs: directive.exportAs,
|
||||
moduleId: directive.moduleId,
|
||||
exportAs: comp.exportAs,
|
||||
moduleId: comp.moduleId,
|
||||
queries: mergedQueries,
|
||||
changeDetection: directive.changeDetection,
|
||||
providers: directive.providers,
|
||||
viewProviders: directive.viewProviders,
|
||||
entryComponents: directive.entryComponents,
|
||||
template: directive.template,
|
||||
templateUrl: directive.templateUrl,
|
||||
styles: directive.styles,
|
||||
styleUrls: directive.styleUrls,
|
||||
encapsulation: directive.encapsulation,
|
||||
animations: directive.animations,
|
||||
interpolation: directive.interpolation,
|
||||
changeDetection: comp.changeDetection,
|
||||
providers: comp.providers,
|
||||
viewProviders: comp.viewProviders,
|
||||
entryComponents: comp.entryComponents,
|
||||
template: comp.template,
|
||||
templateUrl: comp.templateUrl,
|
||||
styles: comp.styles,
|
||||
styleUrls: comp.styleUrls,
|
||||
encapsulation: comp.encapsulation,
|
||||
animations: comp.animations,
|
||||
interpolation: comp.interpolation,
|
||||
preserveWhitespaces: directive.preserveWhitespaces,
|
||||
});
|
||||
} else {
|
||||
return new Directive({
|
||||
return createDirective({
|
||||
selector: directive.selector,
|
||||
inputs: mergedInputs,
|
||||
outputs: mergedOutputs,
|
||||
@ -170,7 +173,7 @@ export class DirectiveResolver {
|
||||
}
|
||||
|
||||
function isDirectiveMetadata(type: any): type is Directive {
|
||||
return type instanceof Directive;
|
||||
return createDirective.isTypeOf(type) || createComponent.isTypeOf(type);
|
||||
}
|
||||
|
||||
export function findLast<T>(arr: T[], condition: (value: T) => boolean): T|null {
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import * as chars from '../chars';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
|
||||
export enum TokenType {
|
||||
Character,
|
||||
@ -21,7 +20,6 @@ export enum TokenType {
|
||||
|
||||
const KEYWORDS = ['var', 'let', 'as', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this'];
|
||||
|
||||
@CompilerInjectable()
|
||||
export class Lexer {
|
||||
tokenize(text: string): Token[] {
|
||||
const scanner = new _Scanner(text);
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import * as chars from '../chars';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/interpolation_config';
|
||||
import {escapeRegExp} from '../util';
|
||||
|
||||
@ -29,7 +28,6 @@ function _createInterpolateRegExp(config: InterpolationConfig): RegExp {
|
||||
return new RegExp(pattern, 'g');
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class Parser {
|
||||
private errors: ParserError[] = [];
|
||||
|
||||
|
@ -10,8 +10,6 @@
|
||||
/**
|
||||
* Extract i18n messages from source code
|
||||
*/
|
||||
import {ViewEncapsulation, ɵConsole as Console} from '@angular/core';
|
||||
|
||||
import {analyzeAndValidateNgModules, extractProgramSymbols} from '../aot/compiler';
|
||||
import {createAotUrlResolver} from '../aot/compiler_factory';
|
||||
import {StaticReflector} from '../aot/static_reflector';
|
||||
@ -20,6 +18,7 @@ import {StaticSymbolResolver, StaticSymbolResolverHost} from '../aot/static_symb
|
||||
import {AotSummaryResolver, AotSummaryResolverHost} from '../aot/summary_resolver';
|
||||
import {CompileDirectiveMetadata} from '../compile_metadata';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {ViewEncapsulation} from '../core';
|
||||
import {DirectiveNormalizer} from '../directive_normalizer';
|
||||
import {DirectiveResolver} from '../directive_resolver';
|
||||
import {CompileMetadataResolver} from '../metadata_resolver';
|
||||
@ -34,6 +33,7 @@ import {syntaxError} from '../util';
|
||||
import {MessageBundle} from './message_bundle';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The host of the Extractor disconnects the implementation from TypeScript / other language
|
||||
* services and from underlying file systems.
|
||||
@ -110,7 +110,7 @@ export class Extractor {
|
||||
const resolver = new CompileMetadataResolver(
|
||||
config, new NgModuleResolver(staticReflector), new DirectiveResolver(staticReflector),
|
||||
new PipeResolver(staticReflector), summaryResolver, elementSchemaRegistry, normalizer,
|
||||
new Console(), symbolCache, staticReflector);
|
||||
console, symbolCache, staticReflector);
|
||||
|
||||
// TODO(vicb): implicit tags & attributes
|
||||
const messageBundle = new MessageBundle(htmlParser, [], {}, locale);
|
||||
|
@ -6,11 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {MissingTranslationStrategy, ɵConsole as Console} from '@angular/core';
|
||||
|
||||
import {MissingTranslationStrategy} from '../core';
|
||||
import {HtmlParser} from '../ml_parser/html_parser';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../ml_parser/interpolation_config';
|
||||
import {ParseTreeResult} from '../ml_parser/parser';
|
||||
import {Console} from '../util';
|
||||
|
||||
import {digest} from './digest';
|
||||
import {mergeTranslations} from './extractor_merger';
|
||||
|
@ -6,13 +6,16 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {MissingTranslationStrategy, ɵConsole as Console} from '@angular/core';
|
||||
import {MissingTranslationStrategy} from '../core';
|
||||
import * as html from '../ml_parser/ast';
|
||||
import {HtmlParser} from '../ml_parser/html_parser';
|
||||
import {Console} from '../util';
|
||||
|
||||
import * as i18n from './i18n_ast';
|
||||
import {I18nError} from './parse_util';
|
||||
import {PlaceholderMapper, Serializer} from './serializers/serializer';
|
||||
|
||||
|
||||
/**
|
||||
* A container for translated messages
|
||||
*/
|
||||
|
@ -6,10 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, ElementRef, Injector, LOCALE_ID, NgModuleFactory, NgModuleRef, QueryList, Renderer, SecurityContext, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation, ɵCodegenComponentFactoryResolver, ɵEMPTY_ARRAY, ɵEMPTY_MAP, ɵand, ɵccf, ɵcmf, ɵcrt, ɵdid, ɵeld, ɵinlineInterpolate, ɵinterpolate, ɵmod, ɵmpd, ɵncd, ɵnov, ɵpad, ɵpid, ɵpod, ɵppd, ɵprd, ɵqud, ɵregisterModuleFactory, ɵted, ɵunv, ɵvid} from '@angular/core';
|
||||
|
||||
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {Attribute, Component, Directive, HostBinding, HostListener, Inject, Input, NgModule, Output, Pipe, Query} from './core';
|
||||
import * as o from './output/output_ast';
|
||||
|
||||
const CORE = '@angular/core';
|
||||
@ -18,121 +17,109 @@ export class Identifiers {
|
||||
static ANALYZE_FOR_ENTRY_COMPONENTS: o.ExternalReference = {
|
||||
name: 'ANALYZE_FOR_ENTRY_COMPONENTS',
|
||||
moduleName: CORE,
|
||||
runtime: ANALYZE_FOR_ENTRY_COMPONENTS
|
||||
|
||||
};
|
||||
static ElementRef:
|
||||
o.ExternalReference = {name: 'ElementRef', moduleName: CORE, runtime: ElementRef};
|
||||
static NgModuleRef:
|
||||
o.ExternalReference = {name: 'NgModuleRef', moduleName: CORE, runtime: NgModuleRef};
|
||||
static ViewContainerRef:
|
||||
o.ExternalReference = {name: 'ViewContainerRef', moduleName: CORE, runtime: ViewContainerRef};
|
||||
static ElementRef: o.ExternalReference = {name: 'ElementRef', moduleName: CORE};
|
||||
static NgModuleRef: o.ExternalReference = {name: 'NgModuleRef', moduleName: CORE};
|
||||
static ViewContainerRef: o.ExternalReference = {name: 'ViewContainerRef', moduleName: CORE};
|
||||
static ChangeDetectorRef: o.ExternalReference = {
|
||||
name: 'ChangeDetectorRef',
|
||||
moduleName: CORE,
|
||||
runtime: ChangeDetectorRef
|
||||
|
||||
};
|
||||
static QueryList: o.ExternalReference = {name: 'QueryList', moduleName: CORE, runtime: QueryList};
|
||||
static TemplateRef:
|
||||
o.ExternalReference = {name: 'TemplateRef', moduleName: CORE, runtime: TemplateRef};
|
||||
static QueryList: o.ExternalReference = {name: 'QueryList', moduleName: CORE};
|
||||
static TemplateRef: o.ExternalReference = {name: 'TemplateRef', moduleName: CORE};
|
||||
static CodegenComponentFactoryResolver: o.ExternalReference = {
|
||||
name: 'ɵCodegenComponentFactoryResolver',
|
||||
moduleName: CORE,
|
||||
runtime: ɵCodegenComponentFactoryResolver
|
||||
|
||||
};
|
||||
static ComponentFactoryResolver: o.ExternalReference = {
|
||||
name: 'ComponentFactoryResolver',
|
||||
moduleName: CORE,
|
||||
runtime: ComponentFactoryResolver
|
||||
|
||||
};
|
||||
static ComponentFactory:
|
||||
o.ExternalReference = {name: 'ComponentFactory', moduleName: CORE, runtime: ComponentFactory};
|
||||
static ComponentRef:
|
||||
o.ExternalReference = {name: 'ComponentRef', moduleName: CORE, runtime: ComponentRef};
|
||||
static NgModuleFactory:
|
||||
o.ExternalReference = {name: 'NgModuleFactory', moduleName: CORE, runtime: NgModuleFactory};
|
||||
static ComponentFactory: o.ExternalReference = {name: 'ComponentFactory', moduleName: CORE};
|
||||
static ComponentRef: o.ExternalReference = {name: 'ComponentRef', moduleName: CORE};
|
||||
static NgModuleFactory: o.ExternalReference = {name: 'NgModuleFactory', moduleName: CORE};
|
||||
static createModuleFactory: o.ExternalReference = {
|
||||
name: 'ɵcmf',
|
||||
moduleName: CORE,
|
||||
runtime: ɵcmf,
|
||||
|
||||
};
|
||||
static moduleDef: o.ExternalReference = {
|
||||
name: 'ɵmod',
|
||||
moduleName: CORE,
|
||||
runtime: ɵmod,
|
||||
|
||||
};
|
||||
static moduleProviderDef: o.ExternalReference = {
|
||||
name: 'ɵmpd',
|
||||
moduleName: CORE,
|
||||
runtime: ɵmpd,
|
||||
|
||||
};
|
||||
static RegisterModuleFactoryFn: o.ExternalReference = {
|
||||
name: 'ɵregisterModuleFactory',
|
||||
moduleName: CORE,
|
||||
runtime: ɵregisterModuleFactory,
|
||||
|
||||
};
|
||||
static Injector: o.ExternalReference = {name: 'Injector', moduleName: CORE, runtime: Injector};
|
||||
static Injector: o.ExternalReference = {name: 'Injector', moduleName: CORE};
|
||||
static ViewEncapsulation: o.ExternalReference = {
|
||||
name: 'ViewEncapsulation',
|
||||
moduleName: CORE,
|
||||
runtime: ViewEncapsulation
|
||||
|
||||
};
|
||||
static ChangeDetectionStrategy: o.ExternalReference = {
|
||||
name: 'ChangeDetectionStrategy',
|
||||
moduleName: CORE,
|
||||
runtime: ChangeDetectionStrategy
|
||||
|
||||
};
|
||||
static SecurityContext: o.ExternalReference = {
|
||||
name: 'SecurityContext',
|
||||
moduleName: CORE,
|
||||
runtime: SecurityContext,
|
||||
|
||||
};
|
||||
static LOCALE_ID: o.ExternalReference = {name: 'LOCALE_ID', moduleName: CORE, runtime: LOCALE_ID};
|
||||
static LOCALE_ID: o.ExternalReference = {name: 'LOCALE_ID', moduleName: CORE};
|
||||
static TRANSLATIONS_FORMAT: o.ExternalReference = {
|
||||
name: 'TRANSLATIONS_FORMAT',
|
||||
moduleName: CORE,
|
||||
runtime: TRANSLATIONS_FORMAT
|
||||
|
||||
};
|
||||
static inlineInterpolate: o.ExternalReference = {
|
||||
name: 'ɵinlineInterpolate',
|
||||
moduleName: CORE,
|
||||
runtime: ɵinlineInterpolate
|
||||
|
||||
};
|
||||
static interpolate:
|
||||
o.ExternalReference = {name: 'ɵinterpolate', moduleName: CORE, runtime: ɵinterpolate};
|
||||
static EMPTY_ARRAY:
|
||||
o.ExternalReference = {name: 'ɵEMPTY_ARRAY', moduleName: CORE, runtime: ɵEMPTY_ARRAY};
|
||||
static EMPTY_MAP:
|
||||
o.ExternalReference = {name: 'ɵEMPTY_MAP', moduleName: CORE, runtime: ɵEMPTY_MAP};
|
||||
static Renderer: o.ExternalReference = {name: 'Renderer', moduleName: CORE, runtime: Renderer};
|
||||
static viewDef: o.ExternalReference = {name: 'ɵvid', moduleName: CORE, runtime: ɵvid};
|
||||
static elementDef: o.ExternalReference = {name: 'ɵeld', moduleName: CORE, runtime: ɵeld};
|
||||
static anchorDef: o.ExternalReference = {name: 'ɵand', moduleName: CORE, runtime: ɵand};
|
||||
static textDef: o.ExternalReference = {name: 'ɵted', moduleName: CORE, runtime: ɵted};
|
||||
static directiveDef: o.ExternalReference = {name: 'ɵdid', moduleName: CORE, runtime: ɵdid};
|
||||
static providerDef: o.ExternalReference = {name: 'ɵprd', moduleName: CORE, runtime: ɵprd};
|
||||
static queryDef: o.ExternalReference = {name: 'ɵqud', moduleName: CORE, runtime: ɵqud};
|
||||
static pureArrayDef: o.ExternalReference = {name: 'ɵpad', moduleName: CORE, runtime: ɵpad};
|
||||
static pureObjectDef: o.ExternalReference = {name: 'ɵpod', moduleName: CORE, runtime: ɵpod};
|
||||
static purePipeDef: o.ExternalReference = {name: 'ɵppd', moduleName: CORE, runtime: ɵppd};
|
||||
static pipeDef: o.ExternalReference = {name: 'ɵpid', moduleName: CORE, runtime: ɵpid};
|
||||
static nodeValue: o.ExternalReference = {name: 'ɵnov', moduleName: CORE, runtime: ɵnov};
|
||||
static ngContentDef: o.ExternalReference = {name: 'ɵncd', moduleName: CORE, runtime: ɵncd};
|
||||
static unwrapValue: o.ExternalReference = {name: 'ɵunv', moduleName: CORE, runtime: ɵunv};
|
||||
static createRendererType2: o.ExternalReference = {name: 'ɵcrt', moduleName: CORE, runtime: ɵcrt};
|
||||
static interpolate: o.ExternalReference = {name: 'ɵinterpolate', moduleName: CORE};
|
||||
static EMPTY_ARRAY: o.ExternalReference = {name: 'ɵEMPTY_ARRAY', moduleName: CORE};
|
||||
static EMPTY_MAP: o.ExternalReference = {name: 'ɵEMPTY_MAP', moduleName: CORE};
|
||||
static Renderer: o.ExternalReference = {name: 'Renderer', moduleName: CORE};
|
||||
static viewDef: o.ExternalReference = {name: 'ɵvid', moduleName: CORE};
|
||||
static elementDef: o.ExternalReference = {name: 'ɵeld', moduleName: CORE};
|
||||
static anchorDef: o.ExternalReference = {name: 'ɵand', moduleName: CORE};
|
||||
static textDef: o.ExternalReference = {name: 'ɵted', moduleName: CORE};
|
||||
static directiveDef: o.ExternalReference = {name: 'ɵdid', moduleName: CORE};
|
||||
static providerDef: o.ExternalReference = {name: 'ɵprd', moduleName: CORE};
|
||||
static queryDef: o.ExternalReference = {name: 'ɵqud', moduleName: CORE};
|
||||
static pureArrayDef: o.ExternalReference = {name: 'ɵpad', moduleName: CORE};
|
||||
static pureObjectDef: o.ExternalReference = {name: 'ɵpod', moduleName: CORE};
|
||||
static purePipeDef: o.ExternalReference = {name: 'ɵppd', moduleName: CORE};
|
||||
static pipeDef: o.ExternalReference = {name: 'ɵpid', moduleName: CORE};
|
||||
static nodeValue: o.ExternalReference = {name: 'ɵnov', moduleName: CORE};
|
||||
static ngContentDef: o.ExternalReference = {name: 'ɵncd', moduleName: CORE};
|
||||
static unwrapValue: o.ExternalReference = {name: 'ɵunv', moduleName: CORE};
|
||||
static createRendererType2: o.ExternalReference = {name: 'ɵcrt', moduleName: CORE};
|
||||
// type only
|
||||
static RendererType2: o.ExternalReference = {
|
||||
name: 'RendererType2',
|
||||
moduleName: CORE,
|
||||
// type only
|
||||
runtime: null
|
||||
|
||||
};
|
||||
// type only
|
||||
static ViewDefinition: o.ExternalReference = {
|
||||
name: 'ɵViewDefinition',
|
||||
moduleName: CORE,
|
||||
// type only
|
||||
runtime: null
|
||||
};
|
||||
static createComponentFactory:
|
||||
o.ExternalReference = {name: 'ɵccf', moduleName: CORE, runtime: ɵccf};
|
||||
static createComponentFactory: o.ExternalReference = {name: 'ɵccf', moduleName: CORE};
|
||||
}
|
||||
|
||||
export function createTokenForReference(reference: any): CompileTokenMetadata {
|
||||
|
@ -1,17 +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
|
||||
*/
|
||||
|
||||
/**
|
||||
* A replacement for @Injectable to be used in the compiler, so that
|
||||
* we don't try to evaluate the metadata in the compiler during AoT.
|
||||
* This decorator is enough to make the compiler work with the ReflectiveInjector though.
|
||||
* @Annotation
|
||||
*/
|
||||
export function CompilerInjectable(): (data: any) => any {
|
||||
return (x) => x;
|
||||
}
|
@ -6,11 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type, ɵConsole as Console, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata';
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {Type} from '../core';
|
||||
import {CompileMetadataResolver} from '../metadata_resolver';
|
||||
import {NgModuleCompiler} from '../ng_module_compiler';
|
||||
import * as ir from '../output/output_ast';
|
||||
@ -19,10 +18,13 @@ import {jitStatements} from '../output/output_jit';
|
||||
import {CompiledStylesheet, StyleCompiler} from '../style_compiler';
|
||||
import {SummaryResolver} from '../summary_resolver';
|
||||
import {TemplateParser} from '../template_parser/template_parser';
|
||||
import {OutputContext, SyncAsync} from '../util';
|
||||
import {Console, OutputContext, SyncAsync, stringify} from '../util';
|
||||
import {ViewCompiler} from '../view_compiler/view_compiler';
|
||||
|
||||
|
||||
export interface ModuleWithComponentFactories {
|
||||
ngModuleFactory: object;
|
||||
componentFactories: object[];
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal module of the Angular compiler that begins with component types,
|
||||
@ -33,41 +35,38 @@ import {ViewCompiler} from '../view_compiler/view_compiler';
|
||||
* from a trusted source. Attacker-controlled data introduced by a template could expose your
|
||||
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
||||
*/
|
||||
@CompilerInjectable()
|
||||
export class JitCompiler implements Compiler {
|
||||
private _compiledTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
||||
private _compiledHostTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
||||
private _compiledDirectiveWrapperCache = new Map<Type<any>, Type<any>>();
|
||||
private _compiledNgModuleCache = new Map<Type<any>, NgModuleFactory<any>>();
|
||||
export class JitCompiler {
|
||||
private _compiledTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledDirectiveWrapperCache = new Map<Type, Type>();
|
||||
private _compiledNgModuleCache = new Map<Type, object>();
|
||||
private _sharedStylesheetCount = 0;
|
||||
|
||||
constructor(
|
||||
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
||||
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
||||
private _viewCompiler: ViewCompiler, private _ngModuleCompiler: NgModuleCompiler,
|
||||
private _summaryResolver: SummaryResolver<Type<any>>, private _compilerConfig: CompilerConfig,
|
||||
private _console: Console) {}
|
||||
private _metadataResolver: CompileMetadataResolver, private _templateParser: TemplateParser,
|
||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _ngModuleCompiler: NgModuleCompiler, private _summaryResolver: SummaryResolver<Type>,
|
||||
private _reflector: CompileReflector, private _compilerConfig: CompilerConfig,
|
||||
private _console: Console,
|
||||
private getExtraNgModuleProviders: (ngModule: any) => CompileProviderMetadata[]) {}
|
||||
|
||||
get injector(): Injector { return this._injector; }
|
||||
|
||||
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
compileModuleSync(moduleType: Type): object {
|
||||
return SyncAsync.assertSync(this._compileModuleAndComponents(moduleType, true));
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
||||
compileModuleAsync(moduleType: Type): Promise<object> {
|
||||
return Promise.resolve(this._compileModuleAndComponents(moduleType, false));
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
||||
compileModuleAndAllComponentsSync(moduleType: Type): ModuleWithComponentFactories {
|
||||
return SyncAsync.assertSync(this._compileModuleAndAllComponents(moduleType, true));
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
||||
Promise<ModuleWithComponentFactories<T>> {
|
||||
compileModuleAndAllComponentsAsync(moduleType: Type): Promise<ModuleWithComponentFactories> {
|
||||
return Promise.resolve(this._compileModuleAndAllComponents(moduleType, false));
|
||||
}
|
||||
|
||||
getNgContentSelectors(component: Type<any>): string[] {
|
||||
getNgContentSelectors(component: Type): string[] {
|
||||
this._console.warn(
|
||||
'Compiler.getNgContentSelectors is deprecated. Use ComponentFactory.ngContentSelectors instead!');
|
||||
const template = this._compiledTemplateCache.get(component);
|
||||
@ -77,9 +76,9 @@ export class JitCompiler implements Compiler {
|
||||
return template.compMeta.template !.ngContentSelectors;
|
||||
}
|
||||
|
||||
getComponentFactory<T>(component: Type<T>): ComponentFactory<T> {
|
||||
getComponentFactory(component: Type): object {
|
||||
const summary = this._metadataResolver.getDirectiveSummary(component);
|
||||
return <ComponentFactory<T>>summary.componentFactory;
|
||||
return summary.componentFactory as object;
|
||||
}
|
||||
|
||||
loadAotSummaries(summaries: () => any[]) {
|
||||
@ -90,26 +89,28 @@ export class JitCompiler implements Compiler {
|
||||
});
|
||||
}
|
||||
|
||||
hasAotSummary(ref: Type<any>) { return !!this._summaryResolver.resolveSummary(ref); }
|
||||
hasAotSummary(ref: Type) { return !!this._summaryResolver.resolveSummary(ref); }
|
||||
|
||||
private _filterJitIdentifiers(ids: CompileIdentifierMetadata[]): any[] {
|
||||
return ids.map(mod => mod.reference).filter((ref) => !this.hasAotSummary(ref));
|
||||
}
|
||||
|
||||
private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
|
||||
SyncAsync<NgModuleFactory<T>> {
|
||||
private _compileModuleAndComponents(moduleType: Type, isSync: boolean): SyncAsync<object> {
|
||||
return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
|
||||
this._compileComponents(moduleType, null);
|
||||
return this._compileModule(moduleType);
|
||||
});
|
||||
}
|
||||
|
||||
private _compileModuleAndAllComponents<T>(moduleType: Type<T>, isSync: boolean):
|
||||
SyncAsync<ModuleWithComponentFactories<T>> {
|
||||
private _compileModuleAndAllComponents(moduleType: Type, isSync: boolean):
|
||||
SyncAsync<ModuleWithComponentFactories> {
|
||||
return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
|
||||
const componentFactories: ComponentFactory<any>[] = [];
|
||||
const componentFactories: object[] = [];
|
||||
this._compileComponents(moduleType, componentFactories);
|
||||
return new ModuleWithComponentFactories(this._compileModule(moduleType), componentFactories);
|
||||
return {
|
||||
ngModuleFactory: this._compileModule(moduleType),
|
||||
componentFactories: componentFactories
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -134,22 +135,16 @@ export class JitCompiler implements Compiler {
|
||||
return SyncAsync.all(loading);
|
||||
}
|
||||
|
||||
private _compileModule<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
private _compileModule(moduleType: Type): object {
|
||||
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType) !;
|
||||
if (!ngModuleFactory) {
|
||||
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType) !;
|
||||
// Always provide a bound Compiler
|
||||
const extraProviders = [this._metadataResolver.getProviderMetadata(new ProviderMeta(
|
||||
Compiler, {useFactory: () => new ModuleBoundCompiler(this, moduleMeta.type.reference)}))];
|
||||
const extraProviders = this.getExtraNgModuleProviders(moduleMeta.type.reference);
|
||||
const outputCtx = createOutputContext();
|
||||
const compileResult = this._ngModuleCompiler.compile(outputCtx, moduleMeta, extraProviders);
|
||||
if (!this._compilerConfig.useJit) {
|
||||
ngModuleFactory =
|
||||
interpretStatements(outputCtx.statements)[compileResult.ngModuleFactoryVar];
|
||||
} else {
|
||||
ngModuleFactory = jitStatements(
|
||||
ngModuleJitUrl(moduleMeta), outputCtx.statements, )[compileResult.ngModuleFactoryVar];
|
||||
}
|
||||
ngModuleFactory = this._interpretOrJit(
|
||||
ngModuleJitUrl(moduleMeta), outputCtx.statements)[compileResult.ngModuleFactoryVar];
|
||||
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
|
||||
}
|
||||
return ngModuleFactory;
|
||||
@ -158,7 +153,7 @@ export class JitCompiler implements Compiler {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_compileComponents(mainModule: Type<any>, allComponentFactories: ComponentFactory<any>[]|null) {
|
||||
_compileComponents(mainModule: Type, allComponentFactories: object[]|null) {
|
||||
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
|
||||
const moduleByJitDirective = new Map<any, CompileNgModuleMetadata>();
|
||||
const templates = new Set<CompiledTemplate>();
|
||||
@ -175,7 +170,7 @@ export class JitCompiler implements Compiler {
|
||||
const template =
|
||||
this._createCompiledHostTemplate(dirMeta.type.reference, localModuleMeta);
|
||||
templates.add(template);
|
||||
allComponentFactories.push(<ComponentFactory<any>>dirMeta.componentFactory);
|
||||
allComponentFactories.push(dirMeta.componentFactory as object);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -203,7 +198,7 @@ export class JitCompiler implements Compiler {
|
||||
templates.forEach((template) => this._compileTemplate(template));
|
||||
}
|
||||
|
||||
clearCacheFor(type: Type<any>) {
|
||||
clearCacheFor(type: Type) {
|
||||
this._compiledNgModuleCache.delete(type);
|
||||
this._metadataResolver.clearCacheFor(type);
|
||||
this._compiledHostTemplateCache.delete(type);
|
||||
@ -220,7 +215,7 @@ export class JitCompiler implements Compiler {
|
||||
this._compiledNgModuleCache.clear();
|
||||
}
|
||||
|
||||
private _createCompiledHostTemplate(compType: Type<any>, ngModule: CompileNgModuleMetadata):
|
||||
private _createCompiledHostTemplate(compType: Type, ngModule: CompileNgModuleMetadata):
|
||||
CompiledTemplate {
|
||||
if (!ngModule) {
|
||||
throw new Error(
|
||||
@ -231,10 +226,9 @@ export class JitCompiler implements Compiler {
|
||||
const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
|
||||
assertComponent(compMeta);
|
||||
|
||||
const componentFactory = <ComponentFactory<any>>compMeta.componentFactory;
|
||||
const hostClass = this._metadataResolver.getHostComponentType(compType);
|
||||
const hostMeta = createHostComponentMeta(
|
||||
hostClass, compMeta, <any>getComponentViewDefinitionFactory(componentFactory));
|
||||
hostClass, compMeta, (compMeta.componentFactory as any).viewDefFactory);
|
||||
compiledTemplate =
|
||||
new CompiledTemplate(true, compMeta.type, hostMeta, ngModule, [compMeta.type]);
|
||||
this._compiledHostTemplateCache.set(compType, compiledTemplate);
|
||||
@ -280,13 +274,8 @@ export class JitCompiler implements Compiler {
|
||||
const compileResult = this._viewCompiler.compileComponent(
|
||||
outputContext, compMeta, parsedTemplate, ir.variable(componentStylesheet.stylesVar),
|
||||
usedPipes);
|
||||
let evalResult: any;
|
||||
if (!this._compilerConfig.useJit) {
|
||||
evalResult = interpretStatements(outputContext.statements);
|
||||
} else {
|
||||
evalResult = jitStatements(
|
||||
templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
|
||||
}
|
||||
const evalResult = this._interpretOrJit(
|
||||
templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
|
||||
const viewClass = evalResult[compileResult.viewClassVar];
|
||||
const rendererType = evalResult[compileResult.rendererTypeVar];
|
||||
template.compiled(viewClass, rendererType);
|
||||
@ -306,12 +295,16 @@ export class JitCompiler implements Compiler {
|
||||
result: CompiledStylesheet,
|
||||
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
||||
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
||||
return this._interpretOrJit(
|
||||
sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++),
|
||||
result.outputCtx.statements)[result.stylesVar];
|
||||
}
|
||||
|
||||
private _interpretOrJit(sourceUrl: string, statements: ir.Statement[]): any {
|
||||
if (!this._compilerConfig.useJit) {
|
||||
return interpretStatements(result.outputCtx.statements)[result.stylesVar];
|
||||
return interpretStatements(statements, this._reflector);
|
||||
} else {
|
||||
return jitStatements(
|
||||
sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++),
|
||||
result.outputCtx.statements)[result.stylesVar];
|
||||
return jitStatements(sourceUrl, statements, this._reflector, this._compilerConfig.jitDevMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -342,46 +335,6 @@ function assertComponent(meta: CompileDirectiveMetadata) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `Compiler` by delegating to the JitCompiler using a known module.
|
||||
*/
|
||||
class ModuleBoundCompiler implements Compiler {
|
||||
constructor(private _delegate: JitCompiler, private _ngModule: Type<any>) {}
|
||||
|
||||
get _injector(): Injector { return this._delegate.injector; }
|
||||
|
||||
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
return this._delegate.compileModuleSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
||||
return this._delegate.compileModuleAsync(moduleType);
|
||||
}
|
||||
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
||||
return this._delegate.compileModuleAndAllComponentsSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
||||
Promise<ModuleWithComponentFactories<T>> {
|
||||
return this._delegate.compileModuleAndAllComponentsAsync(moduleType);
|
||||
}
|
||||
|
||||
getNgContentSelectors(component: Type<any>): string[] {
|
||||
return this._delegate.getNgContentSelectors(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all caches
|
||||
*/
|
||||
clearCache(): void { this._delegate.clearCache(); }
|
||||
|
||||
/**
|
||||
* Clears the cache for the given component/ngModule.
|
||||
*/
|
||||
clearCacheFor(type: Type<any>) { this._delegate.clearCacheFor(type); }
|
||||
}
|
||||
|
||||
|
||||
function flattenSummaries(fn: () => any[], out: CompileTypeSummary[] = []): CompileTypeSummary[] {
|
||||
fn().forEach((entry) => {
|
||||
if (typeof entry === 'function') {
|
||||
|
@ -1,191 +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
|
||||
*/
|
||||
|
||||
import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Inject, InjectionToken, Injector, MissingTranslationStrategy, Optional, PACKAGE_ROOT_URL, PlatformRef, StaticProvider, TRANSLATIONS, TRANSLATIONS_FORMAT, Type, ViewEncapsulation, createPlatformFactory, isDevMode, platformCore, ɵConsole as Console} from '@angular/core';
|
||||
|
||||
import {StaticSymbolCache} from '../aot/static_symbol';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {DirectiveNormalizer} from '../directive_normalizer';
|
||||
import {DirectiveResolver} from '../directive_resolver';
|
||||
import {Lexer} from '../expression_parser/lexer';
|
||||
import {Parser} from '../expression_parser/parser';
|
||||
import * as i18n from '../i18n/index';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {CompileMetadataResolver, ERROR_COLLECTOR_TOKEN} from '../metadata_resolver';
|
||||
import {HtmlParser} from '../ml_parser/html_parser';
|
||||
import {NgModuleCompiler} from '../ng_module_compiler';
|
||||
import {NgModuleResolver} from '../ng_module_resolver';
|
||||
import {PipeResolver} from '../pipe_resolver';
|
||||
import {ResourceLoader} from '../resource_loader';
|
||||
import {DomElementSchemaRegistry} from '../schema/dom_element_schema_registry';
|
||||
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
|
||||
import {StyleCompiler} from '../style_compiler';
|
||||
import {JitSummaryResolver, SummaryResolver} from '../summary_resolver';
|
||||
import {TEMPLATE_TRANSFORMS, TemplateParser} from '../template_parser/template_parser';
|
||||
import {DEFAULT_PACKAGE_URL_PROVIDER, UrlResolver} from '../url_resolver';
|
||||
import {ViewCompiler} from '../view_compiler/view_compiler';
|
||||
|
||||
import {JitCompiler} from './compiler';
|
||||
import {JitReflector} from './jit_reflector';
|
||||
|
||||
const _NO_RESOURCE_LOADER: ResourceLoader = {
|
||||
get(url: string): Promise<string>{
|
||||
throw new Error(
|
||||
`No ResourceLoader implementation has been provided. Can't read the url "${url}"`);}
|
||||
};
|
||||
|
||||
const baseHtmlParser = new InjectionToken('HtmlParser');
|
||||
|
||||
/**
|
||||
* A set of providers that provide `JitCompiler` and its dependencies to use for
|
||||
* template compilation.
|
||||
*/
|
||||
export const COMPILER_PROVIDERS = <StaticProvider[]>[
|
||||
{provide: CompileReflector, useValue: new JitReflector()},
|
||||
{provide: ResourceLoader, useValue: _NO_RESOURCE_LOADER},
|
||||
{provide: JitSummaryResolver, deps: []},
|
||||
{provide: SummaryResolver, useExisting: JitSummaryResolver},
|
||||
{provide: Console, deps: []},
|
||||
{provide: Lexer, deps: []},
|
||||
{provide: Parser, deps: [Lexer]},
|
||||
{
|
||||
provide: baseHtmlParser,
|
||||
useClass: HtmlParser,
|
||||
deps: [],
|
||||
},
|
||||
{
|
||||
provide: i18n.I18NHtmlParser,
|
||||
useFactory: (parser: HtmlParser, translations: string | null, format: string,
|
||||
config: CompilerConfig, console: Console) => {
|
||||
translations = translations || '';
|
||||
const missingTranslation =
|
||||
translations ? config.missingTranslation ! : MissingTranslationStrategy.Ignore;
|
||||
return new i18n.I18NHtmlParser(parser, translations, format, missingTranslation, console);
|
||||
},
|
||||
deps: [
|
||||
baseHtmlParser,
|
||||
[new Optional(), new Inject(TRANSLATIONS)],
|
||||
[new Optional(), new Inject(TRANSLATIONS_FORMAT)],
|
||||
[CompilerConfig],
|
||||
[Console],
|
||||
]
|
||||
},
|
||||
{
|
||||
provide: HtmlParser,
|
||||
useExisting: i18n.I18NHtmlParser,
|
||||
},
|
||||
{
|
||||
provide: TemplateParser, deps: [CompilerConfig, CompileReflector,
|
||||
Parser, ElementSchemaRegistry,
|
||||
i18n.I18NHtmlParser, Console, [Optional, TEMPLATE_TRANSFORMS]]
|
||||
},
|
||||
{ provide: DirectiveNormalizer, deps: [ResourceLoader, UrlResolver, HtmlParser, CompilerConfig]},
|
||||
{ provide: CompileMetadataResolver, deps: [CompilerConfig, NgModuleResolver,
|
||||
DirectiveResolver, PipeResolver,
|
||||
SummaryResolver,
|
||||
ElementSchemaRegistry,
|
||||
DirectiveNormalizer, Console,
|
||||
[Optional, StaticSymbolCache],
|
||||
CompileReflector,
|
||||
[Optional, ERROR_COLLECTOR_TOKEN]]},
|
||||
DEFAULT_PACKAGE_URL_PROVIDER,
|
||||
{ provide: StyleCompiler, deps: [UrlResolver]},
|
||||
{ provide: ViewCompiler, deps: [CompilerConfig, CompileReflector, ElementSchemaRegistry]},
|
||||
{ provide: NgModuleCompiler, deps: [CompileReflector] },
|
||||
{ provide: CompilerConfig, useValue: new CompilerConfig()},
|
||||
{ provide: JitCompiler, deps: [Injector, CompileMetadataResolver,
|
||||
TemplateParser, StyleCompiler,
|
||||
ViewCompiler, NgModuleCompiler,
|
||||
SummaryResolver, CompilerConfig,
|
||||
Console]},
|
||||
{ provide: Compiler, useExisting: JitCompiler},
|
||||
{ provide: DomElementSchemaRegistry, deps: []},
|
||||
{ provide: ElementSchemaRegistry, useExisting: DomElementSchemaRegistry},
|
||||
{ provide: UrlResolver, deps: [PACKAGE_ROOT_URL]},
|
||||
{ provide: DirectiveResolver, deps: [CompileReflector]},
|
||||
{ provide: PipeResolver, deps: [CompileReflector]},
|
||||
{ provide: NgModuleResolver, deps: [CompileReflector]},
|
||||
];
|
||||
|
||||
@CompilerInjectable()
|
||||
export class JitCompilerFactory implements CompilerFactory {
|
||||
private _defaultOptions: CompilerOptions[];
|
||||
constructor(@Inject(COMPILER_OPTIONS) defaultOptions: CompilerOptions[]) {
|
||||
const compilerOptions: CompilerOptions = {
|
||||
useDebug: isDevMode(),
|
||||
useJit: true,
|
||||
defaultEncapsulation: ViewEncapsulation.Emulated,
|
||||
missingTranslation: MissingTranslationStrategy.Warning,
|
||||
enableLegacyTemplate: true,
|
||||
preserveWhitespaces: true,
|
||||
};
|
||||
|
||||
this._defaultOptions = [compilerOptions, ...defaultOptions];
|
||||
}
|
||||
createCompiler(options: CompilerOptions[] = []): Compiler {
|
||||
const opts = _mergeOptions(this._defaultOptions.concat(options));
|
||||
const injector = Injector.create([
|
||||
COMPILER_PROVIDERS, {
|
||||
provide: CompilerConfig,
|
||||
useFactory: () => {
|
||||
return new CompilerConfig({
|
||||
// let explicit values from the compiler options overwrite options
|
||||
// from the app providers
|
||||
useJit: opts.useJit,
|
||||
// let explicit values from the compiler options overwrite options
|
||||
// from the app providers
|
||||
defaultEncapsulation: opts.defaultEncapsulation,
|
||||
missingTranslation: opts.missingTranslation,
|
||||
enableLegacyTemplate: opts.enableLegacyTemplate,
|
||||
preserveWhitespaces: opts.preserveWhitespaces,
|
||||
});
|
||||
},
|
||||
deps: []
|
||||
},
|
||||
opts.providers !
|
||||
]);
|
||||
return injector.get(Compiler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A platform that included corePlatform and the compiler.
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const platformCoreDynamic = createPlatformFactory(platformCore, 'coreDynamic', [
|
||||
{provide: COMPILER_OPTIONS, useValue: {}, multi: true},
|
||||
{provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
|
||||
]);
|
||||
|
||||
function _mergeOptions(optionsArr: CompilerOptions[]): CompilerOptions {
|
||||
return {
|
||||
useJit: _lastDefined(optionsArr.map(options => options.useJit)),
|
||||
defaultEncapsulation: _lastDefined(optionsArr.map(options => options.defaultEncapsulation)),
|
||||
providers: _mergeArrays(optionsArr.map(options => options.providers !)),
|
||||
missingTranslation: _lastDefined(optionsArr.map(options => options.missingTranslation)),
|
||||
enableLegacyTemplate: _lastDefined(optionsArr.map(options => options.enableLegacyTemplate)),
|
||||
preserveWhitespaces: _lastDefined(optionsArr.map(options => options.preserveWhitespaces)),
|
||||
};
|
||||
}
|
||||
|
||||
function _lastDefined<T>(args: T[]): T|undefined {
|
||||
for (let i = args.length - 1; i >= 0; i--) {
|
||||
if (args[i] !== undefined) {
|
||||
return args[i];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function _mergeArrays(parts: any[][]): any[] {
|
||||
const result: any[] = [];
|
||||
parts.forEach((part) => part && result.push(...part));
|
||||
return result;
|
||||
}
|
@ -1,46 +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
|
||||
*/
|
||||
|
||||
import {Component, ɵReflectionCapabilities as ReflectionCapabilities, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import * as o from '../output/output_ast';
|
||||
import {getUrlScheme} from '../url_resolver';
|
||||
import {MODULE_SUFFIX, ValueTransformer, noUndefined, syntaxError, visitValue} from '../util';
|
||||
|
||||
export class JitReflector implements CompileReflector {
|
||||
private reflectionCapabilities: ReflectionCapabilities;
|
||||
constructor() { this.reflectionCapabilities = new ReflectionCapabilities(); }
|
||||
componentModuleUrl(type: any, cmpMetadata: Component): string {
|
||||
const moduleId = cmpMetadata.moduleId;
|
||||
|
||||
if (typeof moduleId === 'string') {
|
||||
const scheme = getUrlScheme(moduleId);
|
||||
return scheme ? moduleId : `package:${moduleId}${MODULE_SUFFIX}`;
|
||||
} else if (moduleId !== null && moduleId !== void 0) {
|
||||
throw syntaxError(
|
||||
`moduleId should be a string in "${stringify(type)}". See https://goo.gl/wIDDiL for more information.\n` +
|
||||
`If you're using Webpack you should inline the template and the styles, see https://goo.gl/X2J8zc.`);
|
||||
}
|
||||
|
||||
return `./${stringify(type)}`;
|
||||
}
|
||||
parameters(typeOrFunc: /*Type*/ any): any[][] {
|
||||
return this.reflectionCapabilities.parameters(typeOrFunc);
|
||||
}
|
||||
annotations(typeOrFunc: /*Type*/ any): any[] {
|
||||
return this.reflectionCapabilities.annotations(typeOrFunc);
|
||||
}
|
||||
propMetadata(typeOrFunc: /*Type*/ any): {[key: string]: any[]} {
|
||||
return this.reflectionCapabilities.propMetadata(typeOrFunc);
|
||||
}
|
||||
hasLifecycleHook(type: any, lcProperty: string): boolean {
|
||||
return this.reflectionCapabilities.hasLifecycleHook(type, lcProperty);
|
||||
}
|
||||
resolveExternalReference(ref: o.ExternalReference): any { return ref.runtime; }
|
||||
}
|
@ -6,27 +6,26 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Attribute, ChangeDetectionStrategy, Component, ComponentFactory, Directive, Host, Inject, Injectable, InjectionToken, ModuleWithProviders, Optional, Provider, Query, RendererType2, SchemaMetadata, Self, SkipSelf, Type, resolveForwardRef, ɵConsole as Console, ɵERROR_COMPONENT_TYPE, ɵccf as createComponentFactory, ɵisPromise as isPromise, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {StaticSymbol, StaticSymbolCache} from './aot/static_symbol';
|
||||
import {ngfactoryFilePath} from './aot/util';
|
||||
import {assertArrayOfStrings, assertInterpolationSymbols} from './assertions';
|
||||
import * as cpl from './compile_metadata';
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {CompilerConfig} from './config';
|
||||
import {ChangeDetectionStrategy, Component, Directive, ModuleWithProviders, Provider, Query, SchemaMetadata, Type, createAttribute, createComponent, createHost, createInject, createInjectable, createInjectionToken, createOptional, createSelf, createSkipSelf} from './core';
|
||||
import {DirectiveNormalizer} from './directive_normalizer';
|
||||
import {DirectiveResolver} from './directive_resolver';
|
||||
import {Identifiers} from './identifiers';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {getAllLifecycleHooks} from './lifecycle_reflector';
|
||||
import {NgModuleResolver} from './ng_module_resolver';
|
||||
import {PipeResolver} from './pipe_resolver';
|
||||
import {ElementSchemaRegistry} from './schema/element_schema_registry';
|
||||
import {SummaryResolver} from './summary_resolver';
|
||||
import {SyncAsync, ValueTransformer, noUndefined, syntaxError, visitValue} from './util';
|
||||
import {Console, SyncAsync, ValueTransformer, isPromise, noUndefined, resolveForwardRef, stringify, syntaxError, visitValue} from './util';
|
||||
|
||||
export type ErrorCollector = (error: any, type?: any) => void;
|
||||
export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector');
|
||||
|
||||
export const ERROR_COMPONENT_TYPE = 'ngComponentType';
|
||||
|
||||
// Design notes:
|
||||
// - don't lazily create metadata:
|
||||
@ -35,15 +34,14 @@ export const ERROR_COLLECTOR_TOKEN = new InjectionToken('ErrorCollector');
|
||||
// But we want to report errors even when the async work is
|
||||
// not required to check that the user would have been able
|
||||
// to wait correctly.
|
||||
@CompilerInjectable()
|
||||
export class CompileMetadataResolver {
|
||||
private _nonNormalizedDirectiveCache =
|
||||
new Map<Type<any>, {annotation: Directive, metadata: cpl.CompileDirectiveMetadata}>();
|
||||
private _directiveCache = new Map<Type<any>, cpl.CompileDirectiveMetadata>();
|
||||
private _summaryCache = new Map<Type<any>, cpl.CompileTypeSummary|null>();
|
||||
private _pipeCache = new Map<Type<any>, cpl.CompilePipeMetadata>();
|
||||
private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
|
||||
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
|
||||
new Map<Type, {annotation: Directive, metadata: cpl.CompileDirectiveMetadata}>();
|
||||
private _directiveCache = new Map<Type, cpl.CompileDirectiveMetadata>();
|
||||
private _summaryCache = new Map<Type, cpl.CompileTypeSummary|null>();
|
||||
private _pipeCache = new Map<Type, cpl.CompilePipeMetadata>();
|
||||
private _ngModuleCache = new Map<Type, cpl.CompileNgModuleMetadata>();
|
||||
private _ngModuleOfTypes = new Map<Type, Type>();
|
||||
|
||||
constructor(
|
||||
private _config: CompilerConfig, private _ngModuleResolver: NgModuleResolver,
|
||||
@ -51,13 +49,12 @@ export class CompileMetadataResolver {
|
||||
private _summaryResolver: SummaryResolver<any>,
|
||||
private _schemaRegistry: ElementSchemaRegistry,
|
||||
private _directiveNormalizer: DirectiveNormalizer, private _console: Console,
|
||||
@Optional() private _staticSymbolCache: StaticSymbolCache,
|
||||
private _reflector: CompileReflector,
|
||||
@Optional() @Inject(ERROR_COLLECTOR_TOKEN) private _errorCollector?: ErrorCollector) {}
|
||||
private _staticSymbolCache: StaticSymbolCache, private _reflector: CompileReflector,
|
||||
private _errorCollector?: ErrorCollector) {}
|
||||
|
||||
getReflector(): CompileReflector { return this._reflector; }
|
||||
|
||||
clearCacheFor(type: Type<any>) {
|
||||
clearCacheFor(type: Type) {
|
||||
const dirMeta = this._directiveCache.get(type);
|
||||
this._directiveCache.delete(type);
|
||||
this._nonNormalizedDirectiveCache.delete(type);
|
||||
@ -115,7 +112,7 @@ export class CompileMetadataResolver {
|
||||
return this.getGeneratedClass(dirType, cpl.hostViewClassName(dirType));
|
||||
}
|
||||
|
||||
getHostComponentType(dirType: any): StaticSymbol|Type<any> {
|
||||
getHostComponentType(dirType: any): StaticSymbol|Type {
|
||||
const name = `${cpl.identifierName({reference: dirType})}_Host`;
|
||||
if (dirType instanceof StaticSymbol) {
|
||||
return this._staticSymbolCache.get(dirType.filePath, name);
|
||||
@ -127,7 +124,7 @@ export class CompileMetadataResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private getRendererType(dirType: any): StaticSymbol|RendererType2 {
|
||||
private getRendererType(dirType: any): StaticSymbol|object {
|
||||
if (dirType instanceof StaticSymbol) {
|
||||
return this._staticSymbolCache.get(
|
||||
ngfactoryFilePath(dirType.filePath), cpl.rendererTypeName(dirType));
|
||||
@ -140,7 +137,7 @@ export class CompileMetadataResolver {
|
||||
|
||||
private getComponentFactory(
|
||||
selector: string, dirType: any, inputs: {[key: string]: string}|null,
|
||||
outputs: {[key: string]: string}): StaticSymbol|ComponentFactory<any> {
|
||||
outputs: {[key: string]: string}): StaticSymbol|object {
|
||||
if (dirType instanceof StaticSymbol) {
|
||||
return this._staticSymbolCache.get(
|
||||
ngfactoryFilePath(dirType.filePath), cpl.componentFactoryName(dirType));
|
||||
@ -148,14 +145,15 @@ export class CompileMetadataResolver {
|
||||
const hostView = this.getHostComponentViewClass(dirType);
|
||||
// Note: ngContentSelectors will be filled later once the template is
|
||||
// loaded.
|
||||
const createComponentFactory =
|
||||
this._reflector.resolveExternalReference(Identifiers.createComponentFactory);
|
||||
return createComponentFactory(selector, dirType, <any>hostView, inputs, outputs, []);
|
||||
}
|
||||
}
|
||||
|
||||
private initComponentFactory(
|
||||
factory: StaticSymbol|ComponentFactory<any>, ngContentSelectors: string[]) {
|
||||
private initComponentFactory(factory: StaticSymbol|object, ngContentSelectors: string[]) {
|
||||
if (!(factory instanceof StaticSymbol)) {
|
||||
factory.ngContentSelectors.push(...ngContentSelectors);
|
||||
(factory as any).ngContentSelectors.push(...ngContentSelectors);
|
||||
}
|
||||
}
|
||||
|
||||
@ -250,23 +248,24 @@ export class CompileMetadataResolver {
|
||||
}
|
||||
let nonNormalizedTemplateMetadata: cpl.CompileTemplateMetadata = undefined !;
|
||||
|
||||
if (dirMeta instanceof Component) {
|
||||
if (createComponent.isTypeOf(dirMeta)) {
|
||||
// component
|
||||
assertArrayOfStrings('styles', dirMeta.styles);
|
||||
assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
|
||||
assertInterpolationSymbols('interpolation', dirMeta.interpolation);
|
||||
const compMeta = dirMeta as Component;
|
||||
assertArrayOfStrings('styles', compMeta.styles);
|
||||
assertArrayOfStrings('styleUrls', compMeta.styleUrls);
|
||||
assertInterpolationSymbols('interpolation', compMeta.interpolation);
|
||||
|
||||
const animations = dirMeta.animations;
|
||||
const animations = compMeta.animations;
|
||||
|
||||
nonNormalizedTemplateMetadata = new cpl.CompileTemplateMetadata({
|
||||
encapsulation: noUndefined(dirMeta.encapsulation),
|
||||
template: noUndefined(dirMeta.template),
|
||||
templateUrl: noUndefined(dirMeta.templateUrl),
|
||||
styles: dirMeta.styles || [],
|
||||
styleUrls: dirMeta.styleUrls || [],
|
||||
encapsulation: noUndefined(compMeta.encapsulation),
|
||||
template: noUndefined(compMeta.template),
|
||||
templateUrl: noUndefined(compMeta.templateUrl),
|
||||
styles: compMeta.styles || [],
|
||||
styleUrls: compMeta.styleUrls || [],
|
||||
animations: animations || [],
|
||||
interpolation: noUndefined(dirMeta.interpolation),
|
||||
isInline: !!dirMeta.template,
|
||||
interpolation: noUndefined(compMeta.interpolation),
|
||||
isInline: !!compMeta.template,
|
||||
externalStylesheets: [],
|
||||
ngContentSelectors: [],
|
||||
preserveWhitespaces: noUndefined(dirMeta.preserveWhitespaces),
|
||||
@ -278,16 +277,17 @@ export class CompileMetadataResolver {
|
||||
let entryComponentMetadata: cpl.CompileEntryComponentMetadata[] = [];
|
||||
let selector = dirMeta.selector;
|
||||
|
||||
if (dirMeta instanceof Component) {
|
||||
if (createComponent.isTypeOf(dirMeta)) {
|
||||
// Component
|
||||
changeDetectionStrategy = dirMeta.changeDetection !;
|
||||
if (dirMeta.viewProviders) {
|
||||
const compMeta = dirMeta as Component;
|
||||
changeDetectionStrategy = compMeta.changeDetection !;
|
||||
if (compMeta.viewProviders) {
|
||||
viewProviders = this._getProvidersMetadata(
|
||||
dirMeta.viewProviders, entryComponentMetadata,
|
||||
compMeta.viewProviders, entryComponentMetadata,
|
||||
`viewProviders for "${stringifyType(directiveType)}"`, [], directiveType);
|
||||
}
|
||||
if (dirMeta.entryComponents) {
|
||||
entryComponentMetadata = flattenAndDedupeArray(dirMeta.entryComponents)
|
||||
if (compMeta.entryComponents) {
|
||||
entryComponentMetadata = flattenAndDedupeArray(compMeta.entryComponents)
|
||||
.map((type) => this._getEntryComponentMetadata(type) !)
|
||||
.concat(entryComponentMetadata);
|
||||
}
|
||||
@ -444,7 +444,7 @@ export class CompileMetadataResolver {
|
||||
|
||||
if (meta.imports) {
|
||||
flattenAndDedupeArray(meta.imports).forEach((importedType) => {
|
||||
let importedModuleType: Type<any> = undefined !;
|
||||
let importedModuleType: Type = undefined !;
|
||||
if (isValidType(importedType)) {
|
||||
importedModuleType = importedType;
|
||||
} else if (importedType && importedType.ngModule) {
|
||||
@ -603,7 +603,7 @@ export class CompileMetadataResolver {
|
||||
return compileMeta;
|
||||
}
|
||||
|
||||
private _checkSelfImport(moduleType: Type<any>, importedModuleType: Type<any>): boolean {
|
||||
private _checkSelfImport(moduleType: Type, importedModuleType: Type): boolean {
|
||||
if (moduleType === importedModuleType) {
|
||||
this._reportError(
|
||||
syntaxError(`'${stringifyType(moduleType)}' module can't import itself`), moduleType);
|
||||
@ -612,7 +612,7 @@ export class CompileMetadataResolver {
|
||||
return false;
|
||||
}
|
||||
|
||||
private _getTypeDescriptor(type: Type<any>): string {
|
||||
private _getTypeDescriptor(type: Type): string {
|
||||
if (this.isDirective(type)) {
|
||||
return 'directive';
|
||||
}
|
||||
@ -633,7 +633,7 @@ export class CompileMetadataResolver {
|
||||
}
|
||||
|
||||
|
||||
private _addTypeToModule(type: Type<any>, moduleType: Type<any>) {
|
||||
private _addTypeToModule(type: Type, moduleType: Type) {
|
||||
const oldModule = this._ngModuleOfTypes.get(type);
|
||||
if (oldModule && oldModule !== moduleType) {
|
||||
this._reportError(
|
||||
@ -685,16 +685,14 @@ export class CompileMetadataResolver {
|
||||
return result;
|
||||
}
|
||||
|
||||
private _getIdentifierMetadata(type: Type<any>): cpl.CompileIdentifierMetadata {
|
||||
private _getIdentifierMetadata(type: Type): cpl.CompileIdentifierMetadata {
|
||||
type = resolveForwardRef(type);
|
||||
return {reference: type};
|
||||
}
|
||||
|
||||
isInjectable(type: any): boolean {
|
||||
const annotations = this._reflector.annotations(type);
|
||||
// Note: We need an exact check here as @Component / @Directive / ... inherit
|
||||
// from @CompilerInjectable!
|
||||
return annotations.some(ann => ann.constructor === Injectable);
|
||||
return annotations.some(ann => createInjectable.isTypeOf(ann));
|
||||
}
|
||||
|
||||
getInjectableSummary(type: any): cpl.CompileTypeSummary {
|
||||
@ -704,7 +702,7 @@ export class CompileMetadataResolver {
|
||||
};
|
||||
}
|
||||
|
||||
private _getInjectableMetadata(type: Type<any>, dependencies: any[]|null = null):
|
||||
private _getInjectableMetadata(type: Type, dependencies: any[]|null = null):
|
||||
cpl.CompileTypeMetadata {
|
||||
const typeSummary = this._loadSummary(type, cpl.CompileSummaryKind.Injectable);
|
||||
if (typeSummary) {
|
||||
@ -713,9 +711,8 @@ export class CompileMetadataResolver {
|
||||
return this._getTypeMetadata(type, dependencies);
|
||||
}
|
||||
|
||||
private _getTypeMetadata(
|
||||
type: Type<any>, dependencies: any[]|null = null,
|
||||
throwOnUnknownDeps = true): cpl.CompileTypeMetadata {
|
||||
private _getTypeMetadata(type: Type, dependencies: any[]|null = null, throwOnUnknownDeps = true):
|
||||
cpl.CompileTypeMetadata {
|
||||
const identifier = this._getIdentifierMetadata(type);
|
||||
return {
|
||||
reference: identifier.reference,
|
||||
@ -780,7 +777,7 @@ export class CompileMetadataResolver {
|
||||
}
|
||||
|
||||
private _getDependenciesMetadata(
|
||||
typeOrFunc: Type<any>|Function, dependencies: any[]|null,
|
||||
typeOrFunc: Type|Function, dependencies: any[]|null,
|
||||
throwOnUnknownDeps = true): cpl.CompileDiDependencyMetadata[] {
|
||||
let hasUnknownDeps = false;
|
||||
const params = dependencies || this._reflector.parameters(typeOrFunc) || [];
|
||||
@ -794,20 +791,21 @@ export class CompileMetadataResolver {
|
||||
let token: any = null;
|
||||
if (Array.isArray(param)) {
|
||||
param.forEach((paramEntry) => {
|
||||
if (paramEntry instanceof Host) {
|
||||
if (createHost.isTypeOf(paramEntry)) {
|
||||
isHost = true;
|
||||
} else if (paramEntry instanceof Self) {
|
||||
} else if (createSelf.isTypeOf(paramEntry)) {
|
||||
isSelf = true;
|
||||
} else if (paramEntry instanceof SkipSelf) {
|
||||
} else if (createSkipSelf.isTypeOf(paramEntry)) {
|
||||
isSkipSelf = true;
|
||||
} else if (paramEntry instanceof Optional) {
|
||||
} else if (createOptional.isTypeOf(paramEntry)) {
|
||||
isOptional = true;
|
||||
} else if (paramEntry instanceof Attribute) {
|
||||
} else if (createAttribute.isTypeOf(paramEntry)) {
|
||||
isAttribute = true;
|
||||
token = paramEntry.attributeName;
|
||||
} else if (paramEntry instanceof Inject) {
|
||||
} else if (createInject.isTypeOf(paramEntry)) {
|
||||
token = paramEntry.token;
|
||||
} else if (paramEntry instanceof InjectionToken) {
|
||||
} else if (
|
||||
createInjectionToken.isTypeOf(paramEntry) || paramEntry instanceof StaticSymbol) {
|
||||
token = paramEntry;
|
||||
} else if (isValidType(paramEntry) && token == null) {
|
||||
token = paramEntry;
|
||||
@ -995,7 +993,7 @@ export class CompileMetadataResolver {
|
||||
|
||||
private _getQueriesMetadata(
|
||||
queries: {[key: string]: Query}, isViewQuery: boolean,
|
||||
directiveType: Type<any>): cpl.CompileQueryMetadata[] {
|
||||
directiveType: Type): cpl.CompileQueryMetadata[] {
|
||||
const res: cpl.CompileQueryMetadata[] = [];
|
||||
|
||||
Object.keys(queries).forEach((propertyName: string) => {
|
||||
@ -1010,7 +1008,7 @@ export class CompileMetadataResolver {
|
||||
|
||||
private _queryVarBindings(selector: any): string[] { return selector.split(/\s*,\s*/); }
|
||||
|
||||
private _getQueryMetadata(q: Query, propertyName: string, typeOrFunc: Type<any>|Function):
|
||||
private _getQueryMetadata(q: Query, propertyName: string, typeOrFunc: Type|Function):
|
||||
cpl.CompileQueryMetadata {
|
||||
let selectors: cpl.CompileTokenMetadata[];
|
||||
if (typeof q.selector === 'string') {
|
||||
@ -1098,9 +1096,9 @@ function stringifyType(type: any): string {
|
||||
/**
|
||||
* Indicates that a component is still being loaded in a synchronous compile.
|
||||
*/
|
||||
function componentStillLoadingError(compType: Type<any>) {
|
||||
function componentStillLoadingError(compType: Type) {
|
||||
const error =
|
||||
Error(`Can't compile synchronously as ${stringify(compType)} is still being loaded!`);
|
||||
(error as any)[ɵERROR_COMPONENT_TYPE] = compType;
|
||||
(error as any)[ERROR_COMPONENT_TYPE] = compType;
|
||||
return error;
|
||||
}
|
||||
|
@ -6,15 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
|
||||
import {getHtmlTagDefinition} from './html_tags';
|
||||
import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from './interpolation_config';
|
||||
import {ParseTreeResult, Parser} from './parser';
|
||||
|
||||
export {ParseTreeResult, TreeError} from './parser';
|
||||
|
||||
@CompilerInjectable()
|
||||
export class HtmlParser extends Parser {
|
||||
constructor() { super(getHtmlTagDefinition); }
|
||||
|
||||
|
@ -6,12 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵNodeFlags as NodeFlags} from '@angular/core';
|
||||
|
||||
import {CompileNgModuleMetadata, CompileProviderMetadata, identifierName} from './compile_metadata';
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {NodeFlags} from './core';
|
||||
import {Identifiers} from './identifiers';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import * as o from './output/output_ast';
|
||||
import {typeSourceSpan} from './parse_util';
|
||||
import {NgModuleProviderAnalyzer} from './provider_analyzer';
|
||||
@ -24,7 +22,6 @@ export class NgModuleCompileResult {
|
||||
|
||||
const LOG_VAR = o.variable('_l');
|
||||
|
||||
@CompilerInjectable()
|
||||
export class NgModuleCompiler {
|
||||
constructor(private reflector: CompileReflector) {}
|
||||
compile(
|
||||
|
@ -6,27 +6,23 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgModule, Type, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {NgModule, Type, createNgModule} from './core';
|
||||
import {findLast} from './directive_resolver';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {stringify} from './util';
|
||||
|
||||
function _isNgModuleMetadata(obj: any): obj is NgModule {
|
||||
return obj instanceof NgModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves types to {@link NgModule}.
|
||||
*/
|
||||
@CompilerInjectable()
|
||||
export class NgModuleResolver {
|
||||
constructor(private _reflector: CompileReflector) {}
|
||||
|
||||
isNgModule(type: any) { return this._reflector.annotations(type).some(_isNgModuleMetadata); }
|
||||
isNgModule(type: any) { return this._reflector.annotations(type).some(createNgModule.isTypeOf); }
|
||||
|
||||
resolve(type: Type<any>, throwIfNotFound = true): NgModule|null {
|
||||
const ngModuleMeta: NgModule = findLast(this._reflector.annotations(type), _isNgModuleMetadata);
|
||||
resolve(type: Type, throwIfNotFound = true): NgModule|null {
|
||||
const ngModuleMeta: NgModule =
|
||||
findLast(this._reflector.annotations(type), createNgModule.isTypeOf);
|
||||
|
||||
if (ngModuleMeta) {
|
||||
return ngModuleMeta;
|
||||
|
@ -353,7 +353,8 @@ export class ExternalExpr extends Expression {
|
||||
}
|
||||
|
||||
export class ExternalReference {
|
||||
constructor(public moduleName: string|null, public name: string|null, public runtime: any|null) {}
|
||||
constructor(public moduleName: string|null, public name: string|null, public runtime?: any|null) {
|
||||
}
|
||||
}
|
||||
|
||||
export class ConditionalExpr extends Expression {
|
||||
|
@ -8,12 +8,15 @@
|
||||
|
||||
|
||||
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
|
||||
import * as o from './output_ast';
|
||||
import {debugOutputAstAsTypeScript} from './ts_emitter';
|
||||
|
||||
export function interpretStatements(statements: o.Statement[]): {[key: string]: any} {
|
||||
export function interpretStatements(
|
||||
statements: o.Statement[], reflector: CompileReflector): {[key: string]: any} {
|
||||
const ctx = new _ExecutionContext(null, null, null, new Map<string, any>());
|
||||
const visitor = new StatementInterpreter();
|
||||
const visitor = new StatementInterpreter(reflector);
|
||||
visitor.visitAllStatements(statements, ctx);
|
||||
const result: {[key: string]: any} = {};
|
||||
ctx.exports.forEach((exportName) => { result[exportName] = ctx.vars.get(exportName); });
|
||||
@ -88,6 +91,7 @@ function createDynamicClass(
|
||||
}
|
||||
|
||||
class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
|
||||
constructor(private reflector: CompileReflector) {}
|
||||
debugAst(ast: o.Expression|o.Statement|o.Type): string { return debugOutputAstAsTypeScript(ast); }
|
||||
|
||||
visitDeclareVarStmt(stmt: o.DeclareVarStmt, ctx: _ExecutionContext): any {
|
||||
@ -227,7 +231,9 @@ class StatementInterpreter implements o.StatementVisitor, o.ExpressionVisitor {
|
||||
return new clazz(...args);
|
||||
}
|
||||
visitLiteralExpr(ast: o.LiteralExpr, ctx: _ExecutionContext): any { return ast.value; }
|
||||
visitExternalExpr(ast: o.ExternalExpr, ctx: _ExecutionContext): any { return ast.value.runtime; }
|
||||
visitExternalExpr(ast: o.ExternalExpr, ctx: _ExecutionContext): any {
|
||||
return this.reflector.resolveExternalReference(ast.value);
|
||||
}
|
||||
visitConditionalExpr(ast: o.ConditionalExpr, ctx: _ExecutionContext): any {
|
||||
if (ast.condition.visitExpression(this, ctx)) {
|
||||
return ast.trueCase.visitExpression(this, ctx);
|
||||
|
@ -6,15 +6,16 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '@angular/core';
|
||||
import {identifierName} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
|
||||
import {EmitterVisitorContext} from './abstract_emitter';
|
||||
import {AbstractJsEmitterVisitor} from './abstract_js_emitter';
|
||||
import * as o from './output_ast';
|
||||
|
||||
function evalExpression(
|
||||
sourceUrl: string, ctx: EmitterVisitorContext, vars: {[key: string]: any}): any {
|
||||
sourceUrl: string, ctx: EmitterVisitorContext, vars: {[key: string]: any},
|
||||
createSourceMap: boolean): any {
|
||||
let fnBody = `${ctx.toSource()}\n//# sourceURL=${sourceUrl}`;
|
||||
const fnArgNames: string[] = [];
|
||||
const fnArgValues: any[] = [];
|
||||
@ -22,7 +23,7 @@ function evalExpression(
|
||||
fnArgNames.push(argName);
|
||||
fnArgValues.push(vars[argName]);
|
||||
}
|
||||
if (isDevMode()) {
|
||||
if (createSourceMap) {
|
||||
// using `new Function(...)` generates a header, 1 line of no arguments, 2 lines otherwise
|
||||
// E.g. ```
|
||||
// function anonymous(a,b,c
|
||||
@ -35,12 +36,14 @@ function evalExpression(
|
||||
return new Function(...fnArgNames.concat(fnBody))(...fnArgValues);
|
||||
}
|
||||
|
||||
export function jitStatements(sourceUrl: string, statements: o.Statement[]): {[key: string]: any} {
|
||||
const converter = new JitEmitterVisitor();
|
||||
export function jitStatements(
|
||||
sourceUrl: string, statements: o.Statement[], reflector: CompileReflector,
|
||||
createSourceMaps: boolean): {[key: string]: any} {
|
||||
const converter = new JitEmitterVisitor(reflector);
|
||||
const ctx = EmitterVisitorContext.createRoot();
|
||||
converter.visitAllStatements(statements, ctx);
|
||||
converter.createReturnStmt(ctx);
|
||||
return evalExpression(sourceUrl, ctx, converter.getArgs());
|
||||
return evalExpression(sourceUrl, ctx, converter.getArgs(), createSourceMaps);
|
||||
}
|
||||
|
||||
export class JitEmitterVisitor extends AbstractJsEmitterVisitor {
|
||||
@ -48,6 +51,8 @@ export class JitEmitterVisitor extends AbstractJsEmitterVisitor {
|
||||
private _evalArgValues: any[] = [];
|
||||
private _evalExportedVars: string[] = [];
|
||||
|
||||
constructor(private reflector: CompileReflector) { super(); }
|
||||
|
||||
createReturnStmt(ctx: EmitterVisitorContext) {
|
||||
const stmt = new o.ReturnStatement(new o.LiteralMapExpr(this._evalExportedVars.map(
|
||||
resultVar => new o.LiteralMapEntry(resultVar, o.variable(resultVar), false))));
|
||||
@ -63,12 +68,12 @@ export class JitEmitterVisitor extends AbstractJsEmitterVisitor {
|
||||
}
|
||||
|
||||
visitExternalExpr(ast: o.ExternalExpr, ctx: EmitterVisitorContext): any {
|
||||
const value = ast.value.runtime;
|
||||
const value = this.reflector.resolveExternalReference(ast.value);
|
||||
let id = this._evalArgValues.indexOf(value);
|
||||
if (id === -1) {
|
||||
id = this._evalArgValues.length;
|
||||
this._evalArgValues.push(value);
|
||||
const name = identifierName({reference: ast.value.runtime}) || 'val';
|
||||
const name = identifierName({reference: value}) || 'val';
|
||||
this._evalArgNames.push(`jit_${name}_${id}`);
|
||||
}
|
||||
ctx.print(ast, this._evalArgNames[id]);
|
||||
|
@ -6,15 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Pipe, Type, resolveForwardRef, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileReflector} from './compile_reflector';
|
||||
import {Pipe, Type, createPipe} from './core';
|
||||
import {findLast} from './directive_resolver';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
|
||||
function _isPipeMetadata(type: any): boolean {
|
||||
return type instanceof Pipe;
|
||||
}
|
||||
import {resolveForwardRef, stringify} from './util';
|
||||
|
||||
/**
|
||||
* Resolve a `Type` for {@link Pipe}.
|
||||
@ -23,22 +18,21 @@ function _isPipeMetadata(type: any): boolean {
|
||||
*
|
||||
* See {@link Compiler}
|
||||
*/
|
||||
@CompilerInjectable()
|
||||
export class PipeResolver {
|
||||
constructor(private _reflector: CompileReflector) {}
|
||||
|
||||
isPipe(type: Type<any>) {
|
||||
isPipe(type: Type) {
|
||||
const typeMetadata = this._reflector.annotations(resolveForwardRef(type));
|
||||
return typeMetadata && typeMetadata.some(_isPipeMetadata);
|
||||
return typeMetadata && typeMetadata.some(createPipe.isTypeOf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@link Pipe} for a given `Type`.
|
||||
*/
|
||||
resolve(type: Type<any>, throwIfNotFound = true): Pipe|null {
|
||||
resolve(type: Type, throwIfNotFound = true): Pipe|null {
|
||||
const metas = this._reflector.annotations(resolveForwardRef(type));
|
||||
if (metas) {
|
||||
const annotation = findLast(metas, _isPipeMetadata);
|
||||
const annotation = findLast(metas, createPipe.isTypeOf);
|
||||
if (annotation) {
|
||||
return annotation;
|
||||
}
|
||||
|
@ -6,9 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, SchemaMetadata, SecurityContext} from '@angular/core';
|
||||
import {CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, SchemaMetadata, SecurityContext} from '../core';
|
||||
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {isNgContainer, isNgContent} from '../ml_parser/tags';
|
||||
import {dashCaseToCamelCase} from '../util';
|
||||
|
||||
@ -241,7 +240,6 @@ const _ATTR_TO_PROP: {[name: string]: string} = {
|
||||
'tabindex': 'tabIndex',
|
||||
};
|
||||
|
||||
@CompilerInjectable()
|
||||
export class DomElementSchemaRegistry extends ElementSchemaRegistry {
|
||||
private _schema: {[element: string]: {[property: string]: string}} = {};
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {SecurityContext} from '@angular/core';
|
||||
import {SecurityContext} from '../core';
|
||||
|
||||
// =================================================================================================
|
||||
// =================================================================================================
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {SchemaMetadata, SecurityContext} from '@angular/core';
|
||||
import {SchemaMetadata, SecurityContext} from '../core';
|
||||
|
||||
export abstract class ElementSchemaRegistry {
|
||||
abstract hasProperty(tagName: string, propName: string, schemaMetas: SchemaMetadata[]): boolean;
|
||||
|
@ -6,10 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ViewEncapsulation} from '@angular/core';
|
||||
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileStylesheetMetadata, identifierModuleUrl, identifierName} from './compile_metadata';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {ViewEncapsulation} from './core';
|
||||
import * as o from './output/output_ast';
|
||||
import {ShadowCss} from './shadow_css';
|
||||
import {UrlResolver} from './url_resolver';
|
||||
@ -31,7 +29,6 @@ export class CompiledStylesheet {
|
||||
public meta: CompileStylesheetMetadata) {}
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class StyleCompiler {
|
||||
private _shadowCss: ShadowCss = new ShadowCss();
|
||||
|
||||
|
@ -5,9 +5,8 @@
|
||||
* 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 {Type} from '@angular/core';
|
||||
import {CompileTypeSummary} from './compile_metadata';
|
||||
import {CompilerInjectable} from './injectable';
|
||||
import {Type} from './core';
|
||||
|
||||
export interface Summary<T> {
|
||||
symbol: T;
|
||||
@ -25,17 +24,16 @@ export abstract class SummaryResolver<T> {
|
||||
abstract addSummary(summary: Summary<T>): void;
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class JitSummaryResolver implements SummaryResolver<Type<any>> {
|
||||
private _summaries = new Map<Type<any>, Summary<Type<any>>>();
|
||||
export class JitSummaryResolver implements SummaryResolver<Type> {
|
||||
private _summaries = new Map<Type, Summary<Type>>();
|
||||
|
||||
isLibraryFile(): boolean { return false; };
|
||||
toSummaryFileName(fileName: string): string { return fileName; }
|
||||
fromSummaryFileName(fileName: string): string { return fileName; }
|
||||
resolveSummary(reference: Type<any>): Summary<Type<any>>|null {
|
||||
resolveSummary(reference: Type): Summary<Type>|null {
|
||||
return this._summaries.get(reference) || null;
|
||||
};
|
||||
getSymbolsOf(): Type<any>[] { return []; }
|
||||
getImportAs(reference: Type<any>): Type<any> { return reference; }
|
||||
addSummary(summary: Summary<Type<any>>) { this._summaries.set(summary.symbol, summary); };
|
||||
getSymbolsOf(): Type[] { return []; }
|
||||
getImportAs(reference: Type): Type { return reference; }
|
||||
addSummary(summary: Summary<Type>) { this._summaries.set(summary.symbol, summary); };
|
||||
}
|
||||
|
@ -6,9 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {SecurityContext} from '@angular/core';
|
||||
|
||||
import {CompileDirectiveSummary, CompilePipeSummary} from '../compile_metadata';
|
||||
import {SecurityContext} from '../core';
|
||||
import {ASTWithSource, BindingPipe, EmptyExpr, ParserError, RecursiveAstVisitor, TemplateBinding} from '../expression_parser/ast';
|
||||
import {Parser} from '../expression_parser/parser';
|
||||
import {InterpolationConfig} from '../ml_parser/interpolation_config';
|
||||
|
@ -6,10 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {SecurityContext} from '@angular/core';
|
||||
|
||||
import {AstPath} from '../ast_path';
|
||||
import {CompileDirectiveSummary, CompileProviderMetadata, CompileTokenMetadata} from '../compile_metadata';
|
||||
import {SecurityContext} from '../core';
|
||||
import {AST} from '../expression_parser/ast';
|
||||
import {LifecycleHooks} from '../lifecycle_reflector';
|
||||
import {ParseSourceSpan} from '../parse_util';
|
||||
|
@ -6,16 +6,14 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Inject, InjectionToken, Optional, SchemaMetadata, ɵConsole as Console} from '@angular/core';
|
||||
|
||||
import {CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeSummary, CompileTokenMetadata, CompileTypeMetadata, identifierName} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {SchemaMetadata} from '../core';
|
||||
import {AST, ASTWithSource, EmptyExpr} from '../expression_parser/ast';
|
||||
import {Parser} from '../expression_parser/parser';
|
||||
import {I18NHtmlParser} from '../i18n/i18n_html_parser';
|
||||
import {Identifiers, createTokenForExternalReference, createTokenForReference} from '../identifiers';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import * as html from '../ml_parser/ast';
|
||||
import {ParseTreeResult} from '../ml_parser/html_parser';
|
||||
import {removeWhitespaces} from '../ml_parser/html_whitespaces';
|
||||
@ -27,7 +25,7 @@ import {ProviderElementContext, ProviderViewContext} from '../provider_analyzer'
|
||||
import {ElementSchemaRegistry} from '../schema/element_schema_registry';
|
||||
import {CssSelector, SelectorMatcher} from '../selector';
|
||||
import {isStyleUrlResolvable} from '../style_url_resolver';
|
||||
import {syntaxError} from '../util';
|
||||
import {Console, syntaxError} from '../util';
|
||||
|
||||
import {BindingParser, BoundProperty} from './binding_parser';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from './template_ast';
|
||||
@ -83,15 +81,6 @@ function warnOnlyOnce(warnings: string[]): (warning: ParseError) => boolean {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides an array of {@link TemplateAstVisitor}s which will be used to transform
|
||||
* parsed templates before compilation is invoked, allowing custom expression syntax
|
||||
* and other advanced transformations.
|
||||
*
|
||||
* This is currently an internal-only feature and not meant for general use.
|
||||
*/
|
||||
export const TEMPLATE_TRANSFORMS = new InjectionToken('TemplateTransforms');
|
||||
|
||||
export class TemplateParseError extends ParseError {
|
||||
constructor(message: string, span: ParseSourceSpan, level: ParseErrorLevel) {
|
||||
super(span, message, level);
|
||||
@ -104,13 +93,12 @@ export class TemplateParseResult {
|
||||
public errors?: ParseError[]) {}
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class TemplateParser {
|
||||
constructor(
|
||||
private _config: CompilerConfig, private _reflector: CompileReflector,
|
||||
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
|
||||
private _htmlParser: I18NHtmlParser, private _console: Console,
|
||||
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
|
||||
public transforms: TemplateAstVisitor[]) {}
|
||||
|
||||
parse(
|
||||
component: CompileDirectiveMetadata, template: string, directives: CompileDirectiveSummary[],
|
||||
|
@ -6,23 +6,17 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Inject, InjectionToken, PACKAGE_ROOT_URL} from '@angular/core';
|
||||
|
||||
import {CompilerInjectable} from './injectable';
|
||||
|
||||
/**
|
||||
* Create a {@link UrlResolver} with no package prefix.
|
||||
*/
|
||||
export function createUrlResolverWithoutPackagePrefix(): UrlResolver {
|
||||
return new UrlResolver();
|
||||
}
|
||||
|
||||
export function createOfflineCompileUrlResolver(): UrlResolver {
|
||||
return new UrlResolver('.');
|
||||
}
|
||||
|
||||
/**
|
||||
* A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
|
||||
*/
|
||||
export const DEFAULT_PACKAGE_URL_PROVIDER = {
|
||||
provide: PACKAGE_ROOT_URL,
|
||||
useValue: '/'
|
||||
};
|
||||
|
||||
/**
|
||||
* Used by the {@link Compiler} when resolving HTML and CSS template URLs.
|
||||
*
|
||||
|
@ -6,13 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵisPromise as isPromise} from '@angular/core';
|
||||
|
||||
import * as o from './output/output_ast';
|
||||
import {ParseError} from './parse_util';
|
||||
|
||||
export const MODULE_SUFFIX = '';
|
||||
|
||||
const CAMEL_CASE_REGEXP = /([A-Z])/g;
|
||||
const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
|
||||
|
||||
@ -163,3 +159,69 @@ export interface OutputContext {
|
||||
statements: o.Statement[];
|
||||
importExpr(reference: any, typeParams?: o.Type[]|null): o.Expression;
|
||||
}
|
||||
|
||||
export function stringify(token: any): string {
|
||||
if (typeof token === 'string') {
|
||||
return token;
|
||||
}
|
||||
|
||||
if (token instanceof Array) {
|
||||
return '[' + token.map(stringify).join(', ') + ']';
|
||||
}
|
||||
|
||||
if (token == null) {
|
||||
return '' + token;
|
||||
}
|
||||
|
||||
if (token.overriddenName) {
|
||||
return `${token.overriddenName}`;
|
||||
}
|
||||
|
||||
if (token.name) {
|
||||
return `${token.name}`;
|
||||
}
|
||||
|
||||
const res = token.toString();
|
||||
|
||||
if (res == null) {
|
||||
return '' + res;
|
||||
}
|
||||
|
||||
const newLineIndex = res.indexOf('\n');
|
||||
return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazily retrieves the reference value from a forwardRef.
|
||||
*/
|
||||
export function resolveForwardRef(type: any): any {
|
||||
if (typeof type === 'function' && type.hasOwnProperty('__forward_ref__')) {
|
||||
return type();
|
||||
} else {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the argument is shaped like a Promise
|
||||
*/
|
||||
export function isPromise(obj: any): obj is Promise<any> {
|
||||
// allow any Promise/A+ compliant thenable.
|
||||
// It's up to the caller to ensure that obj.then conforms to the spec
|
||||
return !!obj && typeof obj.then === 'function';
|
||||
}
|
||||
|
||||
export class Version {
|
||||
constructor(public full: string) {}
|
||||
|
||||
get major(): string { return this.full.split('.')[0]; }
|
||||
|
||||
get minor(): string { return this.full.split('.')[1]; }
|
||||
|
||||
get patch(): string { return this.full.split('.').slice(2).join('.'); }
|
||||
}
|
||||
|
||||
export interface Console {
|
||||
log(message: string): void;
|
||||
warn(message: string): void;
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
* Entry point for all public APIs of the common package.
|
||||
*/
|
||||
|
||||
import {Version} from '@angular/core';
|
||||
import {Version} from './util';
|
||||
/**
|
||||
* @stable
|
||||
*/
|
||||
|
@ -6,10 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags} from '@angular/core';
|
||||
|
||||
import {CompileDiDependencyMetadata, CompileEntryComponentMetadata, CompileProviderMetadata, CompileTokenMetadata} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {DepFlags, NodeFlags} from '../core';
|
||||
import {Identifiers, createTokenForExternalReference} from '../identifiers';
|
||||
import {LifecycleHooks} from '../lifecycle_reflector';
|
||||
import * as o from '../output/output_ast';
|
||||
|
@ -6,15 +6,13 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ChangeDetectionStrategy, ɵArgumentType as ArgumentType, ɵBindingFlags as BindingFlags, ɵDepFlags as DepFlags, ɵNodeFlags as NodeFlags, ɵQueryBindingType as QueryBindingType, ɵQueryValueType as QueryValueType, ɵViewFlags as ViewFlags, ɵelementEventFullName as elementEventFullName} from '@angular/core';
|
||||
|
||||
import {CompileDiDependencyMetadata, CompileDirectiveMetadata, CompilePipeSummary, CompileProviderMetadata, CompileTokenMetadata, CompileTypeMetadata, rendererTypeName, tokenReference, viewClassName} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {BuiltinConverter, EventHandlerVars, LocalResolver, convertActionBinding, convertPropertyBinding, convertPropertyBindingBuiltins} from '../compiler_util/expression_converter';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {ArgumentType, BindingFlags, ChangeDetectionStrategy, DepFlags, NodeFlags, QueryBindingType, QueryValueType, ViewFlags} from '../core';
|
||||
import {AST, ASTWithSource, Interpolation} from '../expression_parser/ast';
|
||||
import {Identifiers} from '../identifiers';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {LifecycleHooks} from '../lifecycle_reflector';
|
||||
import {isNgContainer} from '../ml_parser/tags';
|
||||
import * as o from '../output/output_ast';
|
||||
@ -35,7 +33,6 @@ export class ViewCompileResult {
|
||||
constructor(public viewClassVar: string, public rendererTypeVar: string) {}
|
||||
}
|
||||
|
||||
@CompilerInjectable()
|
||||
export class ViewCompiler {
|
||||
constructor(
|
||||
private _config: CompilerConfig, private _reflector: CompileReflector,
|
||||
@ -1072,3 +1069,7 @@ function calcStaticDynamicQueryFlags(
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
export function elementEventFullName(target: string | null, name: string): string {
|
||||
return target ? `${target}:${name}` : name;
|
||||
}
|
||||
|
@ -459,6 +459,11 @@ describe('compiler (unbundled Angular)', () => {
|
||||
});
|
||||
|
||||
describe('inheritance with summaries', () => {
|
||||
let angularSummaryFiles: MockDirectory;
|
||||
beforeEach(() => {
|
||||
angularSummaryFiles = compile(angularFiles, {useSummaries: false, emit: true}).outDir;
|
||||
});
|
||||
|
||||
function compileParentAndChild(
|
||||
{parentClassDecorator, parentModuleDecorator, childClassDecorator, childModuleDecorator}: {
|
||||
parentClassDecorator: string,
|
||||
@ -494,8 +499,8 @@ describe('compiler (unbundled Angular)', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const {outDir: libOutDir} = compile([libInput, angularFiles], {useSummaries: true});
|
||||
const {genFiles} = compile([libOutDir, appInput, angularFiles], {useSummaries: true});
|
||||
const {outDir: libOutDir} = compile([libInput, angularSummaryFiles], {useSummaries: true});
|
||||
const {genFiles} = compile([libOutDir, appInput, angularSummaryFiles], {useSummaries: true});
|
||||
return genFiles.find(gf => gf.srcFileUrl === '/app/main.ts');
|
||||
}
|
||||
|
||||
@ -529,8 +534,8 @@ describe('compiler (unbundled Angular)', () => {
|
||||
}
|
||||
};
|
||||
|
||||
const {outDir: libOutDir} = compile([libInput, angularFiles], {useSummaries: true});
|
||||
const {genFiles} = compile([libOutDir, appInput, angularFiles], {useSummaries: true});
|
||||
const {outDir: libOutDir} = compile([libInput, angularSummaryFiles], {useSummaries: true});
|
||||
const {genFiles} = compile([libOutDir, appInput, angularSummaryFiles], {useSummaries: true});
|
||||
const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts');
|
||||
const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy;
|
||||
expect(toTypeScript(mainNgFactory))
|
||||
@ -578,10 +583,12 @@ describe('compiler (unbundled Angular)', () => {
|
||||
`
|
||||
}
|
||||
};
|
||||
const {outDir: lib1OutDir} = compile([lib1Input, angularFiles], {useSummaries: true});
|
||||
const {outDir: lib1OutDir} =
|
||||
compile([lib1Input, angularSummaryFiles], {useSummaries: true});
|
||||
const {outDir: lib2OutDir} =
|
||||
compile([lib1OutDir, lib2Input, angularFiles], {useSummaries: true});
|
||||
const {genFiles} = compile([lib2OutDir, appInput, angularFiles], {useSummaries: true});
|
||||
compile([lib1OutDir, lib2Input, angularSummaryFiles], {useSummaries: true});
|
||||
const {genFiles} =
|
||||
compile([lib2OutDir, appInput, angularSummaryFiles], {useSummaries: true});
|
||||
const mainNgFactory = genFiles.find(gf => gf.srcFileUrl === '/app/main.ts');
|
||||
const flags = NodeFlags.TypeDirective | NodeFlags.Component | NodeFlags.OnDestroy;
|
||||
expect(toTypeScript(mainNgFactory))
|
||||
|
@ -12,10 +12,17 @@ import {MockDirectory, compile, setup} from './test_util';
|
||||
|
||||
describe('aot summaries for jit', () => {
|
||||
let angularFiles = setup();
|
||||
let angularSummaryFiles: MockDirectory;
|
||||
|
||||
beforeEach(() => {
|
||||
angularSummaryFiles = compile(angularFiles, {useSummaries: false, emit: true}).outDir;
|
||||
});
|
||||
|
||||
function compileApp(rootDir: MockDirectory, options: {useSummaries?: boolean} = {}):
|
||||
{genFiles: GeneratedFile[], outDir: MockDirectory} {
|
||||
return compile([rootDir, angularFiles], {...options, enableSummariesForJit: true});
|
||||
return compile(
|
||||
[rootDir, options.useSummaries ? angularSummaryFiles : angularFiles],
|
||||
{...options, enableSummariesForJit: true});
|
||||
}
|
||||
|
||||
it('should create @Injectable summaries', () => {
|
||||
|
@ -6,8 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, StaticSymbolResolverHost} from '@angular/compiler';
|
||||
import {HostListener, Inject, animate, group, keyframes, sequence, state, style, transition, trigger} from '@angular/core';
|
||||
import {StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, StaticSymbolResolverHost, core as compilerCore} from '@angular/compiler';
|
||||
import {CollectorOptions} from '@angular/tsc-wrapped';
|
||||
|
||||
import {MockStaticSymbolResolverHost, MockSummaryResolver} from './static_symbol_resolver_spec';
|
||||
@ -66,14 +65,6 @@ describe('StaticReflector', () => {
|
||||
expect(annotations.length).toEqual(1);
|
||||
const annotation = annotations[0];
|
||||
expect(annotation.selector).toEqual('my-hero-detail');
|
||||
expect(annotation.animations).toEqual([trigger('myAnimation', [
|
||||
state('state1', style({'background': 'white'})),
|
||||
transition(
|
||||
'* => *',
|
||||
sequence([group([animate(
|
||||
'1s 0.5s',
|
||||
keyframes([style({'background': 'blue'}), style({'background': 'red'})]))])]))
|
||||
])]);
|
||||
});
|
||||
|
||||
it('should get and empty annotation list for an unknown class', () => {
|
||||
@ -97,7 +88,8 @@ describe('StaticReflector', () => {
|
||||
reflector.findDeclaration('src/app/hero-detail.component', 'HeroDetailComponent');
|
||||
const props = reflector.propMetadata(HeroDetailComponent);
|
||||
expect(props['hero']).toBeTruthy();
|
||||
expect(props['onMouseOver']).toEqual([new HostListener('mouseover', ['$event'])]);
|
||||
expect(props['onMouseOver']).toEqual([compilerCore.createHostListener(
|
||||
'mouseover', ['$event'])]);
|
||||
});
|
||||
|
||||
it('should get an empty object from propMetadata for an unknown class', () => {
|
||||
@ -401,7 +393,7 @@ describe('StaticReflector', () => {
|
||||
const src = '/tmp/src/forward-ref.ts';
|
||||
const dep = reflector.getStaticSymbol(src, 'Dep');
|
||||
const props = reflector.parameters(reflector.getStaticSymbol(src, 'Forward'));
|
||||
expect(props).toEqual([[dep, new Inject(dep)]]);
|
||||
expect(props).toEqual([[dep, compilerCore.createInject(dep)]]);
|
||||
});
|
||||
|
||||
it('should report an error for invalid function calls', () => {
|
||||
@ -600,7 +592,7 @@ describe('StaticReflector', () => {
|
||||
|
||||
const someClass = reflector.getStaticSymbol(file, 'SomeClass');
|
||||
const parameters = reflector.parameters(someClass);
|
||||
expect(parameters.toString()).toEqual('@Inject');
|
||||
expect(compilerCore.createInject.isTypeOf(parameters[0][0])).toBe(true);
|
||||
});
|
||||
|
||||
it('should reject a ctor parameter without a @Inject and a type exprssion', () => {
|
||||
@ -889,431 +881,237 @@ describe('StaticReflector', () => {
|
||||
});
|
||||
|
||||
const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
'/tmp/@angular/common/src/forms-deprecated/directives.d.ts': [{
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'FORM_DIRECTIVES': [
|
||||
{
|
||||
'__symbolic': 'reference',
|
||||
'name': 'NgFor',
|
||||
'module': '@angular/common/src/directives/ng_for'
|
||||
}
|
||||
]
|
||||
}
|
||||
}],
|
||||
'/tmp/@angular/common/src/directives/ng_for.d.ts': {
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'NgFor': {
|
||||
'__symbolic': 'class',
|
||||
'decorators': [
|
||||
{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'Directive',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
{
|
||||
'selector': '[ngFor][ngForOf]',
|
||||
'inputs': ['ngForTrackBy', 'ngForOf', 'ngForTemplate']
|
||||
}
|
||||
]
|
||||
'/tmp/@angular/common/src/forms-deprecated/directives.d.ts': [{
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'FORM_DIRECTIVES': [{
|
||||
'__symbolic': 'reference',
|
||||
'name': 'NgFor',
|
||||
'module': '@angular/common/src/directives/ng_for'
|
||||
}]
|
||||
}
|
||||
}],
|
||||
'/tmp/@angular/common/src/directives/ng_for.d.ts': {
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'NgFor': {
|
||||
'__symbolic': 'class',
|
||||
'decorators': [{
|
||||
'__symbolic': 'call',
|
||||
'expression': {'__symbolic': 'reference', 'name': 'Directive', 'module': '@angular/core'},
|
||||
'arguments': [{
|
||||
'selector': '[ngFor][ngForOf]',
|
||||
'inputs': ['ngForTrackBy', 'ngForOf', 'ngForTemplate']
|
||||
}]
|
||||
}],
|
||||
'members': {
|
||||
'__ctor__': [{
|
||||
'__symbolic': 'constructor',
|
||||
'parameters': [
|
||||
{'__symbolic': 'reference', 'module': '@angular/core', 'name': 'ViewContainerRef'},
|
||||
{'__symbolic': 'reference', 'module': '@angular/core', 'name': 'TemplateRef'},
|
||||
{'__symbolic': 'reference', 'module': '@angular/core', 'name': 'IterableDiffers'}, {
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'ChangeDetectorRef'
|
||||
}
|
||||
],
|
||||
'members': {
|
||||
'__ctor__': [
|
||||
{
|
||||
'__symbolic': 'constructor',
|
||||
'parameters': [
|
||||
{
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'ViewContainerRef'
|
||||
},
|
||||
{
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'TemplateRef'
|
||||
},
|
||||
{
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'IterableDiffers'
|
||||
},
|
||||
{
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'ChangeDetectorRef'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/@angular/core/src/linker/view_container_ref.d.ts':
|
||||
{version: 3, 'metadata': {'ViewContainerRef': {'__symbolic': 'class'}}},
|
||||
'/tmp/@angular/core/src/linker/template_ref.d.ts':
|
||||
{version: 3, 'module': './template_ref', 'metadata': {'TemplateRef': {'__symbolic': 'class'}}},
|
||||
'/tmp/@angular/core/src/change_detection/differs/iterable_differs.d.ts':
|
||||
{version: 3, 'metadata': {'IterableDiffers': {'__symbolic': 'class'}}},
|
||||
'/tmp/@angular/core/src/change_detection/change_detector_ref.d.ts':
|
||||
{version: 3, 'metadata': {'ChangeDetectorRef': {'__symbolic': 'class'}}},
|
||||
'/tmp/src/app/hero-detail.component.d.ts': {
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'HeroDetailComponent': {
|
||||
'__symbolic': 'class',
|
||||
'decorators': [
|
||||
{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'Component',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
{
|
||||
'selector': 'my-hero-detail',
|
||||
'template':
|
||||
'\n <div *ngIf="hero">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]="hero.name" placeholder="name"/>\n </div>\n </div>\n',
|
||||
'animations': [{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'trigger',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
'myAnimation',
|
||||
[{ '__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'state',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
'state1',
|
||||
{ '__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'style',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
{ 'background':'white' }
|
||||
]
|
||||
}
|
||||
]
|
||||
}, {
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'transition',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments': [
|
||||
'* => *',
|
||||
{
|
||||
'__symbolic':'call',
|
||||
'expression':{
|
||||
'__symbolic':'reference',
|
||||
'name':'sequence',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[[{ '__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'group',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[[{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'animate',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[
|
||||
'1s 0.5s',
|
||||
{ '__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'keyframes',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[[{ '__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'style',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[ { 'background': 'blue'} ]
|
||||
}, {
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic':'reference',
|
||||
'name':'style',
|
||||
'module': '@angular/core'
|
||||
},
|
||||
'arguments':[ { 'background': 'red'} ]
|
||||
}]]
|
||||
}
|
||||
]
|
||||
}]]
|
||||
}]]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
'members': {
|
||||
'hero': [
|
||||
{
|
||||
'__symbolic': 'property',
|
||||
'decorators': [
|
||||
{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'name': 'Input',
|
||||
'module': '@angular/core'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'onMouseOver': [
|
||||
{
|
||||
'__symbolic': 'method',
|
||||
'decorators': [
|
||||
{
|
||||
'__symbolic': 'call',
|
||||
'expression': {
|
||||
'__symbolic': 'reference',
|
||||
'module': '@angular/core',
|
||||
'name': 'HostListener'
|
||||
},
|
||||
'arguments': [
|
||||
'mouseover',
|
||||
[
|
||||
'$event'
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/src/extern.d.ts': {'__symbolic': 'module', 'version': 3, metadata: {s: 's'}},
|
||||
'/tmp/src/error-reporting.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
SomeClass: {
|
||||
__symbolic: 'class',
|
||||
decorators: [
|
||||
{
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
name: 'Component',
|
||||
module: '@angular/core'
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
entryComponents: [
|
||||
{
|
||||
__symbolic: 'reference',
|
||||
module: 'src/error-references',
|
||||
name: 'Link1',
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/src/error-references.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
Link1: {
|
||||
__symbolic: 'reference',
|
||||
module: 'src/error-references',
|
||||
name: 'Link2'
|
||||
},
|
||||
Link2: {
|
||||
__symbolic: 'reference',
|
||||
module: 'src/error-references',
|
||||
name: 'ErrorSym'
|
||||
},
|
||||
ErrorSym: {
|
||||
__symbolic: 'error',
|
||||
message: 'A reasonable error message',
|
||||
line: 12,
|
||||
character: 33
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/src/function-declaration.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
one: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: [
|
||||
{__symbolic: 'reference', name: 'a'}
|
||||
]
|
||||
},
|
||||
add: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a','b'],
|
||||
value: {
|
||||
__symbolic: 'binop',
|
||||
operator: '+',
|
||||
left: {__symbolic: 'reference', name: 'a'},
|
||||
right: {
|
||||
__symbolic: 'binop',
|
||||
operator: '+',
|
||||
left: {__symbolic: 'reference', name: 'b'},
|
||||
right: {__symbolic: 'reference', name: 'oneLiteral'}
|
||||
}
|
||||
}
|
||||
},
|
||||
oneLiteral: 1
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/@angular/core/src/linker/view_container_ref.d.ts':
|
||||
{version: 3, 'metadata': {'ViewContainerRef': {'__symbolic': 'class'}}},
|
||||
'/tmp/@angular/core/src/linker/template_ref.d.ts': {
|
||||
version: 3,
|
||||
'module': './template_ref',
|
||||
'metadata': {'TemplateRef': {'__symbolic': 'class'}}
|
||||
},
|
||||
'/tmp/@angular/core/src/change_detection/differs/iterable_differs.d.ts':
|
||||
{version: 3, 'metadata': {'IterableDiffers': {'__symbolic': 'class'}}},
|
||||
'/tmp/@angular/core/src/change_detection/change_detector_ref.d.ts':
|
||||
{version: 3, 'metadata': {'ChangeDetectorRef': {'__symbolic': 'class'}}},
|
||||
'/tmp/src/app/hero-detail.component.d.ts': {
|
||||
'__symbolic': 'module',
|
||||
'version': 3,
|
||||
'metadata': {
|
||||
'HeroDetailComponent': {
|
||||
'__symbolic': 'class',
|
||||
'decorators': [{
|
||||
'__symbolic': 'call',
|
||||
'expression': {'__symbolic': 'reference', 'name': 'Component', 'module': '@angular/core'},
|
||||
'arguments': [{
|
||||
'selector': 'my-hero-detail',
|
||||
'template':
|
||||
'\n <div *ngIf="hero">\n <h2>{{hero.name}} details!</h2>\n <div><label>id: </label>{{hero.id}}</div>\n <div>\n <label>name: </label>\n <input [(ngModel)]="hero.name" placeholder="name"/>\n </div>\n </div>\n',
|
||||
}]
|
||||
}],
|
||||
'members': {
|
||||
'hero': [{
|
||||
'__symbolic': 'property',
|
||||
'decorators': [{
|
||||
'__symbolic': 'call',
|
||||
'expression':
|
||||
{'__symbolic': 'reference', 'name': 'Input', 'module': '@angular/core'}
|
||||
}]
|
||||
}],
|
||||
'onMouseOver': [{
|
||||
'__symbolic': 'method',
|
||||
'decorators': [{
|
||||
'__symbolic': 'call',
|
||||
'expression':
|
||||
{'__symbolic': 'reference', 'module': '@angular/core', 'name': 'HostListener'},
|
||||
'arguments': ['mouseover', ['$event']]
|
||||
}]
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/src/extern.d.ts': {'__symbolic': 'module', 'version': 3, metadata: {s: 's'}},
|
||||
'/tmp/src/error-reporting.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
SomeClass: {
|
||||
__symbolic: 'class',
|
||||
decorators: [{
|
||||
__symbolic: 'call',
|
||||
expression: {__symbolic: 'reference', name: 'Component', module: '@angular/core'},
|
||||
arguments: [{
|
||||
entryComponents: [{
|
||||
__symbolic: 'reference',
|
||||
module: 'src/error-references',
|
||||
name: 'Link1',
|
||||
}]
|
||||
}]
|
||||
}],
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/src/error-references.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
Link1: {__symbolic: 'reference', module: 'src/error-references', name: 'Link2'},
|
||||
Link2: {__symbolic: 'reference', module: 'src/error-references', name: 'ErrorSym'},
|
||||
ErrorSym:
|
||||
{__symbolic: 'error', message: 'A reasonable error message', line: 12, character: 33}
|
||||
}
|
||||
},
|
||||
'/tmp/src/function-declaration.d.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
one: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: [{__symbolic: 'reference', name: 'a'}]
|
||||
},
|
||||
'/tmp/src/function-reference.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
one: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-declaration',
|
||||
name: 'one'
|
||||
},
|
||||
arguments: ['some-value']
|
||||
},
|
||||
three: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-declaration',
|
||||
name: 'add'
|
||||
},
|
||||
arguments: [1, 1]
|
||||
},
|
||||
recursion: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'recursive'
|
||||
},
|
||||
arguments: [1]
|
||||
},
|
||||
indirectRecursion: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'indirectRecursion1'
|
||||
},
|
||||
arguments: [1]
|
||||
add: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a', 'b'],
|
||||
value: {
|
||||
__symbolic: 'binop',
|
||||
operator: '+',
|
||||
left: {__symbolic: 'reference', name: 'a'},
|
||||
right: {
|
||||
__symbolic: 'binop',
|
||||
operator: '+',
|
||||
left: {__symbolic: 'reference', name: 'b'},
|
||||
right: {__symbolic: 'reference', name: 'oneLiteral'}
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/src/function-recursive.d.ts': {
|
||||
__symbolic: 'modules',
|
||||
version: 3,
|
||||
metadata: {
|
||||
recursive: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'recursive',
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
__symbolic: 'reference',
|
||||
name: 'a'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
indirectRecursion1: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'indirectRecursion2',
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
__symbolic: 'reference',
|
||||
name: 'a'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
indirectRecursion2: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'indirectRecursion1',
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
__symbolic: 'reference',
|
||||
name: 'a'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
oneLiteral: 1
|
||||
}
|
||||
},
|
||||
'/tmp/src/function-reference.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
one: {
|
||||
__symbolic: 'call',
|
||||
expression: {__symbolic: 'reference', module: './function-declaration', name: 'one'},
|
||||
arguments: ['some-value']
|
||||
},
|
||||
'/tmp/src/spread.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {
|
||||
spread: [0, {__symbolic: 'spread', expression: [1, 2, 3, 4]}, 5]
|
||||
three: {
|
||||
__symbolic: 'call',
|
||||
expression: {__symbolic: 'reference', module: './function-declaration', name: 'add'},
|
||||
arguments: [1, 1]
|
||||
},
|
||||
recursion: {
|
||||
__symbolic: 'call',
|
||||
expression: {__symbolic: 'reference', module: './function-recursive', name: 'recursive'},
|
||||
arguments: [1]
|
||||
},
|
||||
indirectRecursion: {
|
||||
__symbolic: 'call',
|
||||
expression:
|
||||
{__symbolic: 'reference', module: './function-recursive', name: 'indirectRecursion1'},
|
||||
arguments: [1]
|
||||
}
|
||||
}
|
||||
},
|
||||
'/tmp/src/function-recursive.d.ts': {
|
||||
__symbolic: 'modules',
|
||||
version: 3,
|
||||
metadata: {
|
||||
recursive: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'recursive',
|
||||
},
|
||||
arguments: [{__symbolic: 'reference', name: 'a'}]
|
||||
}
|
||||
},
|
||||
'/tmp/src/custom-decorator.ts': `
|
||||
indirectRecursion1: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'indirectRecursion2',
|
||||
},
|
||||
arguments: [{__symbolic: 'reference', name: 'a'}]
|
||||
}
|
||||
},
|
||||
indirectRecursion2: {
|
||||
__symbolic: 'function',
|
||||
parameters: ['a'],
|
||||
value: {
|
||||
__symbolic: 'call',
|
||||
expression: {
|
||||
__symbolic: 'reference',
|
||||
module: './function-recursive',
|
||||
name: 'indirectRecursion1',
|
||||
},
|
||||
arguments: [{__symbolic: 'reference', name: 'a'}]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'/tmp/src/spread.ts': {
|
||||
__symbolic: 'module',
|
||||
version: 3,
|
||||
metadata: {spread: [0, {__symbolic: 'spread', expression: [1, 2, 3, 4]}, 5]}
|
||||
},
|
||||
'/tmp/src/custom-decorator.ts': `
|
||||
export function CustomDecorator(): any {
|
||||
return () => {};
|
||||
}
|
||||
`,
|
||||
'/tmp/src/custom-decorator-reference.ts': `
|
||||
'/tmp/src/custom-decorator-reference.ts': `
|
||||
import {CustomDecorator} from './custom-decorator';
|
||||
|
||||
@CustomDecorator()
|
||||
@ -1321,7 +1119,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
@CustomDecorator() get foo(): string { return ''; }
|
||||
}
|
||||
`,
|
||||
'/tmp/src/invalid-calll-definitions.ts': `
|
||||
'/tmp/src/invalid-calll-definitions.ts': `
|
||||
export function someFunction(a: any) {
|
||||
if (Array.isArray(a)) {
|
||||
return a;
|
||||
@ -1329,7 +1127,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
return undefined;
|
||||
}
|
||||
`,
|
||||
'/tmp/src/invalid-calls.ts': `
|
||||
'/tmp/src/invalid-calls.ts': `
|
||||
import {someFunction} from './nvalid-calll-definitions.ts';
|
||||
import {Component} from '@angular/core';
|
||||
import {NgIf} from '@angular/common';
|
||||
@ -1347,7 +1145,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
})
|
||||
export class MyOtherComponent { }
|
||||
`,
|
||||
'/tmp/src/static-method.ts': `
|
||||
'/tmp/src/static-method.ts': `
|
||||
import {Component} from '@angular/core/src/metadata';
|
||||
|
||||
@Component({
|
||||
@ -1374,7 +1172,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
}
|
||||
}
|
||||
`,
|
||||
'/tmp/src/static-method-call.ts': `
|
||||
'/tmp/src/static-method-call.ts': `
|
||||
import {Component} from '@angular/core';
|
||||
import {MyModule} from './static-method';
|
||||
|
||||
@ -1398,7 +1196,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
})
|
||||
export class MyFactoryComponent { }
|
||||
`,
|
||||
'/tmp/src/static-field.ts': `
|
||||
'/tmp/src/static-field.ts': `
|
||||
import {Injectable} from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
@ -1406,12 +1204,12 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
static VALUE = 'Some string';
|
||||
}
|
||||
`,
|
||||
'/tmp/src/macro-function.ts': `
|
||||
'/tmp/src/macro-function.ts': `
|
||||
export function v(value: any) {
|
||||
return { provide: 'a', useValue: value };
|
||||
}
|
||||
`,
|
||||
'/tmp/src/call-macro-function.ts': `
|
||||
'/tmp/src/call-macro-function.ts': `
|
||||
import {Component} from '@angular/core';
|
||||
import {v} from './macro-function';
|
||||
|
||||
@ -1425,7 +1223,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
})
|
||||
export class MyComponentNested { }
|
||||
`,
|
||||
'/tmp/src/static-field-reference.ts': `
|
||||
'/tmp/src/static-field-reference.ts': `
|
||||
import {Component} from '@angular/core';
|
||||
import {MyModule} from './static-field';
|
||||
|
||||
@ -1434,12 +1232,12 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
})
|
||||
export class Foo { }
|
||||
`,
|
||||
'/tmp/src/static-method-def.ts': `
|
||||
'/tmp/src/static-method-def.ts': `
|
||||
export class ClassWithStatics {
|
||||
static staticMethod() {}
|
||||
}
|
||||
`,
|
||||
'/tmp/src/static-method-ref.ts': `
|
||||
'/tmp/src/static-method-ref.ts': `
|
||||
import {Component} from '@angular/core';
|
||||
import {ClassWithStatics} from './static-method-def';
|
||||
|
||||
@ -1450,7 +1248,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
|
||||
}
|
||||
`,
|
||||
'/tmp/src/invalid-metadata.ts': `
|
||||
'/tmp/src/invalid-metadata.ts': `
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
@ -1458,7 +1256,7 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
})
|
||||
export class InvalidMetadata {}
|
||||
`,
|
||||
'/tmp/src/forward-ref.ts': `
|
||||
'/tmp/src/forward-ref.ts': `
|
||||
import {forwardRef} from '@angular/core';
|
||||
import {Component} from '@angular/core';
|
||||
import {Inject} from '@angular/core';
|
||||
@ -1470,4 +1268,4 @@ const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
||||
@Input f: Forward;
|
||||
}
|
||||
`
|
||||
};
|
||||
};
|
||||
|
@ -611,7 +611,15 @@ export function expectNoDiagnostics(program: ts.Program) {
|
||||
}
|
||||
|
||||
export function isSource(fileName: string): boolean {
|
||||
return !/\.d\.ts$/.test(fileName) && /\.ts$/.test(fileName);
|
||||
return !isDts(fileName) && /\.ts$/.test(fileName);
|
||||
}
|
||||
|
||||
function isDts(fileName: string): boolean {
|
||||
return /\.d.ts$/.test(fileName);
|
||||
}
|
||||
|
||||
function isSourceOrDts(fileName: string): boolean {
|
||||
return /\.ts$/.test(fileName);
|
||||
}
|
||||
|
||||
export function compile(
|
||||
@ -628,7 +636,8 @@ export function compile(
|
||||
const preCompile = options.preCompile || (() => {});
|
||||
const postCompile = options.postCompile || expectNoDiagnostics;
|
||||
const rootDirArr = toMockFileArray(rootDirs);
|
||||
const scriptNames = rootDirArr.map(entry => entry.fileName).filter(isSource);
|
||||
const scriptNames = rootDirArr.map(entry => entry.fileName)
|
||||
.filter(options.useSummaries ? isSource : isSourceOrDts);
|
||||
|
||||
const host = new MockCompilerHost(scriptNames, arrayToMockDir(rootDirArr));
|
||||
const aotHost = new MockAotCompilerHost(host);
|
||||
@ -659,9 +668,11 @@ export function compile(
|
||||
}
|
||||
let outDir: MockDirectory = {};
|
||||
if (emit) {
|
||||
outDir = arrayToMockDir(toMockFileArray([
|
||||
host.writtenFiles, host.overrides
|
||||
]).filter((entry) => !isSource(entry.fileName)));
|
||||
const dtsFilesWithGenFiles = new Set<string>(genFiles.map(gf => gf.srcFileUrl).filter(isDts));
|
||||
outDir =
|
||||
arrayToMockDir(toMockFileArray([host.writtenFiles, host.overrides])
|
||||
.filter((entry) => !isSource(entry.fileName))
|
||||
.concat(rootDirArr.filter(e => dtsFilesWithGenFiles.has(e.fileName))));
|
||||
}
|
||||
return {genFiles, outDir};
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {LifecycleHooks as Hooks, hasLifecycleHook as hasLifecycleHookImpl} from '@angular/compiler/src/lifecycle_reflector';
|
||||
import {SimpleChanges} from '@angular/core';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
function hasLifecycleHook(hook: Hooks, directive: any): boolean {
|
||||
return hasLifecycleHookImpl(new JitReflector(), hook, directive);
|
||||
|
@ -11,7 +11,6 @@ import {CompilerConfig, preserveWhitespacesDefault} from '@angular/compiler/src/
|
||||
import {DirectiveNormalizer} from '@angular/compiler/src/directive_normalizer';
|
||||
import {ResourceLoader} from '@angular/compiler/src/resource_loader';
|
||||
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
|
||||
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/src/test_bindings';
|
||||
import {ViewEncapsulation} from '@angular/core/src/metadata/view';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
@ -19,6 +18,7 @@ import {AsyncTestCompleter, beforeEach, describe, expect, inject, it} from '@ang
|
||||
import {noUndefined} from '../src/util';
|
||||
|
||||
import {SpyResourceLoader} from './spies';
|
||||
import {TEST_COMPILER_PROVIDERS} from './test_bindings';
|
||||
|
||||
const SOME_MODULE_URL = 'package:some/module/a.js';
|
||||
const SOME_HTTP_MODULE_URL = 'http://some/module/a.js';
|
||||
|
@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {Component, Directive, Injector, ɵViewMetadata as ViewMetadata} from '@angular/core';
|
||||
import {Component, Directive, Injector} from '@angular/core';
|
||||
import {TestBed, inject} from '@angular/core/testing';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
import {MockDirectiveResolver} from '../testing';
|
||||
|
||||
@ -22,7 +22,7 @@ export function main() {
|
||||
});
|
||||
|
||||
beforeEach(inject([Injector], (injector: Injector) => {
|
||||
dirResolver = new MockDirectiveResolver(injector, new JitReflector());
|
||||
dirResolver = new MockDirectiveResolver(new JitReflector());
|
||||
}));
|
||||
|
||||
describe('Directive overriding', () => {
|
||||
@ -38,48 +38,6 @@ export function main() {
|
||||
expect(metadata.selector).toEqual('someOtherSelector');
|
||||
});
|
||||
});
|
||||
|
||||
describe('View overriding', () => {
|
||||
it('should fallback to the default ViewResolver when templates are not overridden', () => {
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('template');
|
||||
});
|
||||
|
||||
it('should allow overriding the @View', () => {
|
||||
dirResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('overridden template');
|
||||
});
|
||||
|
||||
it('should allow overriding a view after it has been resolved', () => {
|
||||
dirResolver.resolve(SomeComponent);
|
||||
dirResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('overridden template');
|
||||
});
|
||||
});
|
||||
|
||||
describe('inline template definition overriding', () => {
|
||||
it('should allow overriding the default template', () => {
|
||||
dirResolver.setInlineTemplate(SomeComponent, 'overridden template');
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('overridden template');
|
||||
});
|
||||
|
||||
it('should allow overriding an overridden @View', () => {
|
||||
dirResolver.setView(SomeComponent, new ViewMetadata({template: 'overridden template'}));
|
||||
dirResolver.setInlineTemplate(SomeComponent, 'overridden template x 2');
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('overridden template x 2');
|
||||
});
|
||||
|
||||
it('should allow overriding a view after it has been resolved', () => {
|
||||
dirResolver.resolve(SomeComponent);
|
||||
dirResolver.setInlineTemplate(SomeComponent, 'overridden template');
|
||||
const view = <Component>dirResolver.resolve(SomeComponent);
|
||||
expect(view.template).toEqual('overridden template');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {core} from '@angular/compiler';
|
||||
import {DirectiveResolver} from '@angular/compiler/src/directive_resolver';
|
||||
import {Component, ContentChild, ContentChildren, Directive, HostBinding, HostListener, Input, Output, ViewChild, ViewChildren} from '@angular/core/src/metadata';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
@Directive({selector: 'someDirective'})
|
||||
class SomeDirective {
|
||||
@ -119,7 +120,7 @@ export function main() {
|
||||
|
||||
it('should read out the Directive metadata', () => {
|
||||
const directiveMetadata = resolver.resolve(SomeDirective);
|
||||
expect(directiveMetadata).toEqual(new Directive({
|
||||
expect(directiveMetadata).toEqual(core.createDirective({
|
||||
selector: 'someDirective',
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
@ -147,7 +148,7 @@ export function main() {
|
||||
class ChildWithDecorator extends Parent {
|
||||
}
|
||||
|
||||
expect(resolver.resolve(ChildNoDecorator)).toEqual(new Directive({
|
||||
expect(resolver.resolve(ChildNoDecorator)).toEqual(core.createDirective({
|
||||
selector: 'p',
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
@ -157,7 +158,7 @@ export function main() {
|
||||
providers: undefined
|
||||
}));
|
||||
|
||||
expect(resolver.resolve(ChildWithDecorator)).toEqual(new Directive({
|
||||
expect(resolver.resolve(ChildWithDecorator)).toEqual(core.createDirective({
|
||||
selector: 'c',
|
||||
inputs: [],
|
||||
outputs: [],
|
||||
|
@ -253,7 +253,7 @@ export function main() {
|
||||
});
|
||||
|
||||
it('should extract from attributes in translatable ICUs', () => {
|
||||
expect(extract(`<!-- i18n -->{count, plural, =0 {<p><b i18n-title="m|d@@i"
|
||||
expect(extract(`<!-- i18n -->{count, plural, =0 {<p><b i18n-title="m|d@@i"
|
||||
title="msg"></b></p>}}<!-- /i18n -->`))
|
||||
.toEqual([
|
||||
[['msg'], 'm', 'd', 'i'],
|
||||
|
@ -1,152 +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
|
||||
*/
|
||||
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {MetadataOverrider} from '../testing/src/metadata_overrider';
|
||||
|
||||
interface SomeMetadataType {
|
||||
plainProp?: string;
|
||||
getterProp?: string;
|
||||
arrayProp?: any[];
|
||||
}
|
||||
|
||||
interface OtherMetadataType extends SomeMetadataType {
|
||||
otherPlainProp?: string;
|
||||
}
|
||||
|
||||
class SomeMetadata implements SomeMetadataType {
|
||||
plainProp: string;
|
||||
private _getterProp: string;
|
||||
get getterProp(): string { return this._getterProp; }
|
||||
arrayProp: any[];
|
||||
|
||||
constructor(options: SomeMetadataType) {
|
||||
this.plainProp = options.plainProp !;
|
||||
this._getterProp = options.getterProp !;
|
||||
this.arrayProp = options.arrayProp !;
|
||||
}
|
||||
}
|
||||
|
||||
class OtherMetadata extends SomeMetadata implements OtherMetadataType {
|
||||
otherPlainProp: string;
|
||||
|
||||
constructor(options: OtherMetadataType) {
|
||||
super({
|
||||
plainProp: options.plainProp,
|
||||
getterProp: options.getterProp,
|
||||
arrayProp: options.arrayProp
|
||||
});
|
||||
|
||||
this.otherPlainProp = options.otherPlainProp !;
|
||||
}
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe('metadata overrider', () => {
|
||||
let overrider: MetadataOverrider;
|
||||
|
||||
beforeEach(() => { overrider = new MetadataOverrider(); });
|
||||
|
||||
it('should return a new instance with the same values', () => {
|
||||
const oldInstance = new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someInput'});
|
||||
const newInstance = overrider.overrideMetadata(SomeMetadata, oldInstance, {});
|
||||
expect(newInstance).not.toBe(oldInstance);
|
||||
expect(newInstance).toBeAnInstanceOf(SomeMetadata);
|
||||
expect(newInstance).toEqual(oldInstance);
|
||||
});
|
||||
|
||||
it('should set individual properties and keep others', () => {
|
||||
const oldInstance =
|
||||
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
|
||||
const newInstance =
|
||||
overrider.overrideMetadata(SomeMetadata, oldInstance, {set: {plainProp: 'newPlainProp'}});
|
||||
expect(newInstance)
|
||||
.toEqual(new SomeMetadata({plainProp: 'newPlainProp', getterProp: 'someGetterProp'}));
|
||||
});
|
||||
|
||||
describe('add properties', () => {
|
||||
it('should replace non array values', () => {
|
||||
const oldInstance =
|
||||
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
|
||||
const newInstance = overrider.overrideMetadata(
|
||||
SomeMetadata, oldInstance, {add: {plainProp: 'newPlainProp'}});
|
||||
expect(newInstance)
|
||||
.toEqual(new SomeMetadata({plainProp: 'newPlainProp', getterProp: 'someGetterProp'}));
|
||||
});
|
||||
|
||||
it('should add to array values', () => {
|
||||
const oldInstance = new SomeMetadata({arrayProp: ['a']});
|
||||
const newInstance =
|
||||
overrider.overrideMetadata(SomeMetadata, oldInstance, {add: {arrayProp: ['b']}});
|
||||
expect(newInstance).toEqual(new SomeMetadata({arrayProp: ['a', 'b']}));
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove', () => {
|
||||
it('should set values to undefined if their value matches', () => {
|
||||
const oldInstance =
|
||||
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
|
||||
const newInstance = overrider.overrideMetadata(
|
||||
SomeMetadata, oldInstance, {remove: {plainProp: 'somePlainProp'}});
|
||||
expect(newInstance)
|
||||
.toEqual(new SomeMetadata({plainProp: undefined, getterProp: 'someGetterProp'}));
|
||||
});
|
||||
|
||||
it('should leave values if their value does not match', () => {
|
||||
const oldInstance =
|
||||
new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'});
|
||||
const newInstance = overrider.overrideMetadata(
|
||||
SomeMetadata, oldInstance, {remove: {plainProp: 'newPlainProp'}});
|
||||
expect(newInstance)
|
||||
.toEqual(new SomeMetadata({plainProp: 'somePlainProp', getterProp: 'someGetterProp'}));
|
||||
});
|
||||
|
||||
it('should remove a value from an array', () => {
|
||||
const oldInstance =
|
||||
new SomeMetadata({arrayProp: ['a', 'b', 'c'], getterProp: 'someGetterProp'});
|
||||
const newInstance = overrider.overrideMetadata(
|
||||
SomeMetadata, oldInstance, {remove: {arrayProp: ['a', 'c']}});
|
||||
expect(newInstance)
|
||||
.toEqual(new SomeMetadata({arrayProp: ['b'], getterProp: 'someGetterProp'}));
|
||||
});
|
||||
|
||||
it('should support types as values', () => {
|
||||
class Class1 {}
|
||||
class Class2 {}
|
||||
class Class3 {}
|
||||
|
||||
const instance1 = new SomeMetadata({arrayProp: [Class1, Class2, Class3]});
|
||||
const instance2 =
|
||||
overrider.overrideMetadata(SomeMetadata, instance1, {remove: {arrayProp: [Class1]}});
|
||||
expect(instance2).toEqual(new SomeMetadata({arrayProp: [Class2, Class3]}));
|
||||
const instance3 =
|
||||
overrider.overrideMetadata(SomeMetadata, instance2, {remove: {arrayProp: [Class3]}});
|
||||
expect(instance3).toEqual(new SomeMetadata({arrayProp: [Class2]}));
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('subclasses', () => {
|
||||
it('should set individual properties and keep others', () => {
|
||||
const oldInstance = new OtherMetadata({
|
||||
plainProp: 'somePlainProp',
|
||||
getterProp: 'someGetterProp',
|
||||
otherPlainProp: 'newOtherProp'
|
||||
});
|
||||
const newInstance = overrider.overrideMetadata(
|
||||
OtherMetadata, oldInstance, {set: {plainProp: 'newPlainProp'}});
|
||||
expect(newInstance).toEqual(new OtherMetadata({
|
||||
plainProp: 'newPlainProp',
|
||||
getterProp: 'someGetterProp',
|
||||
otherPlainProp: 'newOtherProp'
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import {LIFECYCLE_HOOKS_VALUES, LifecycleHooks} from '@angular/compiler/src/lifecycle_reflector';
|
||||
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/src/test_bindings';
|
||||
import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, Component, Directive, DoCheck, Injectable, NgModule, OnChanges, OnDestroy, OnInit, Pipe, SimpleChanges, ViewEncapsulation, ɵstringify as stringify} from '@angular/core';
|
||||
import {TestBed, async, inject} from '@angular/core/testing';
|
||||
|
||||
@ -17,6 +16,7 @@ import {ResourceLoader} from '../src/resource_loader';
|
||||
import {MockResourceLoader} from '../testing/src/resource_loader_mock';
|
||||
|
||||
import {MalformedStylesComponent} from './metadata_resolver_fixture';
|
||||
import {TEST_COMPILER_PROVIDERS} from './test_bindings';
|
||||
|
||||
export function main() {
|
||||
describe('CompileMetadataResolver', () => {
|
||||
|
@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {Injector, NgModule} from '@angular/core';
|
||||
import {beforeEach, describe, expect, inject, it} from '@angular/core/testing/src/testing_internal';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
import {MockNgModuleResolver} from '../testing';
|
||||
|
||||
@ -17,7 +17,7 @@ export function main() {
|
||||
let ngModuleResolver: MockNgModuleResolver;
|
||||
|
||||
beforeEach(inject([Injector], (injector: Injector) => {
|
||||
ngModuleResolver = new MockNgModuleResolver(injector, new JitReflector());
|
||||
ngModuleResolver = new MockNgModuleResolver(new JitReflector());
|
||||
}));
|
||||
|
||||
describe('NgModule overriding', () => {
|
||||
|
@ -6,10 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {NgModuleResolver} from '@angular/compiler/src/ng_module_resolver';
|
||||
import {ɵstringify as stringify} from '@angular/core';
|
||||
import {NgModule} from '@angular/core/src/metadata';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
class SomeClass1 {}
|
||||
class SomeClass2 {}
|
||||
|
@ -9,6 +9,7 @@
|
||||
import {EmitterVisitorContext} from '@angular/compiler/src/output/abstract_emitter';
|
||||
import * as o from '@angular/compiler/src/output/output_ast';
|
||||
import {JitEmitterVisitor} from '@angular/compiler/src/output/output_jit';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
const anotherModuleUrl = 'somePackage/someOtherPath';
|
||||
|
||||
@ -23,7 +24,7 @@ export function main() {
|
||||
(_, index) => new o.ExternalReference(
|
||||
anotherModuleUrl, `id_${index}_1`, {name: `id_${index}_1`}));
|
||||
const ctx = EmitterVisitorContext.createRoot();
|
||||
const converter = new JitEmitterVisitor();
|
||||
const converter = new JitEmitterVisitor(new JitReflector());
|
||||
converter.visitAllStatements(
|
||||
[o.literalArr([...externalIds1, ...externalIds].map(id => o.importExpr(id))).toStmt()],
|
||||
ctx);
|
||||
|
@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {Injector, Pipe} from '@angular/core';
|
||||
import {inject} from '@angular/core/testing';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
import {MockPipeResolver} from '../testing';
|
||||
|
||||
@ -17,7 +17,7 @@ export function main() {
|
||||
let pipeResolver: MockPipeResolver;
|
||||
|
||||
beforeEach(inject([Injector], (injector: Injector) => {
|
||||
pipeResolver = new MockPipeResolver(injector, new JitReflector());
|
||||
pipeResolver = new MockPipeResolver(new JitReflector());
|
||||
}));
|
||||
|
||||
describe('Pipe overriding', () => {
|
||||
|
@ -6,10 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {JitReflector} from '@angular/compiler';
|
||||
import {PipeResolver} from '@angular/compiler/src/pipe_resolver';
|
||||
import {ɵstringify as stringify} from '@angular/core';
|
||||
import {Pipe} from '@angular/core/src/metadata';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
@Pipe({name: 'somePipe', pure: true})
|
||||
class SomePipe {
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {DirectiveResolver, ResourceLoader} from '@angular/compiler';
|
||||
import {Compiler, Component, Injector, NgModule, NgModuleFactory, ɵViewMetadata as ViewMetadata, ɵstringify as stringify} from '@angular/core';
|
||||
import {Compiler, Component, Injector, NgModule, NgModuleFactory, ɵstringify as stringify} from '@angular/core';
|
||||
import {TestBed, async, fakeAsync, inject, tick} from '@angular/core/testing';
|
||||
import {expect} from '@angular/platform-browser/testing/src/matchers';
|
||||
import {MockDirectiveResolver} from '../testing';
|
||||
@ -137,8 +137,9 @@ export function main() {
|
||||
}
|
||||
|
||||
resourceLoader.spy('get').and.callFake(() => Promise.resolve(''));
|
||||
dirResolver.setView(SomeComp, new ViewMetadata({template: ''}));
|
||||
dirResolver.setView(ChildComp, new ViewMetadata({templateUrl: '/someTpl.html'}));
|
||||
dirResolver.setDirective(SomeComp, new Component({selector: 'some-cmp', template: ''}));
|
||||
dirResolver.setDirective(
|
||||
ChildComp, new Component({selector: 'child-cmp', templateUrl: '/someTpl.html'}));
|
||||
expect(() => compiler.compileModuleSync(SomeModule))
|
||||
.toThrowError(
|
||||
`Can't compile synchronously as ${stringify(ChildComp)} is still being loaded!`);
|
||||
|
@ -5,16 +5,16 @@
|
||||
* 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 {CompileQueryMetadata, CompilerConfig, JitReflector, ProxyClass, StaticSymbol, preserveWhitespacesDefault} from '@angular/compiler';
|
||||
import {CompileQueryMetadata, CompilerConfig, ProxyClass, StaticSymbol, preserveWhitespacesDefault} from '@angular/compiler';
|
||||
import {CompileAnimationEntryMetadata, CompileDiDependencyMetadata, CompileDirectiveMetadata, CompileDirectiveSummary, CompilePipeMetadata, CompilePipeSummary, CompileProviderMetadata, CompileTemplateMetadata, CompileTokenMetadata, CompileTypeMetadata, tokenReference} from '@angular/compiler/src/compile_metadata';
|
||||
import {DomElementSchemaRegistry} from '@angular/compiler/src/schema/dom_element_schema_registry';
|
||||
import {ElementSchemaRegistry} from '@angular/compiler/src/schema/element_schema_registry';
|
||||
import {AttrAst, BoundDirectivePropertyAst, BoundElementPropertyAst, BoundEventAst, BoundTextAst, DirectiveAst, ElementAst, EmbeddedTemplateAst, NgContentAst, PropertyBindingType, ProviderAstType, ReferenceAst, TemplateAst, TemplateAstVisitor, TextAst, VariableAst, templateVisitAll} from '@angular/compiler/src/template_parser/template_ast';
|
||||
import {TEMPLATE_TRANSFORMS, TemplateParser, splitClasses} from '@angular/compiler/src/template_parser/template_parser';
|
||||
import {TEST_COMPILER_PROVIDERS} from '@angular/compiler/testing/src/test_bindings';
|
||||
import {TemplateParser, splitClasses} from '@angular/compiler/src/template_parser/template_parser';
|
||||
import {ChangeDetectionStrategy, ComponentFactory, RendererType2, SchemaMetadata, SecurityContext, ViewEncapsulation} from '@angular/core';
|
||||
import {Console} from '@angular/core/src/console';
|
||||
import {TestBed, inject} from '@angular/core/testing';
|
||||
import {JitReflector} from '@angular/platform-browser-dynamic/src/compiler_reflector';
|
||||
|
||||
import {CompileEntryComponentMetadata, CompileStylesheetMetadata} from '../../src/compile_metadata';
|
||||
import {Identifiers, createTokenForExternalReference, createTokenForReference} from '../../src/identifiers';
|
||||
@ -22,6 +22,7 @@ import {DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig} from '../../src/ml_pa
|
||||
import {noUndefined} from '../../src/util';
|
||||
import {MockSchemaRegistry} from '../../testing';
|
||||
import {unparse} from '../expression_parser/unparser';
|
||||
import {TEST_COMPILER_PROVIDERS} from '../test_bindings';
|
||||
|
||||
const someModuleUrl = 'package:someModule';
|
||||
|
||||
@ -37,29 +38,28 @@ function createTypeMeta({reference, diDeps}: {reference: any, diDeps?: any[]}):
|
||||
return {reference: reference, diDeps: diDeps || [], lifecycleHooks: []};
|
||||
}
|
||||
|
||||
function compileDirectiveMetadataCreate(
|
||||
{isHost, type, isComponent, selector, exportAs, changeDetection, inputs, outputs, host,
|
||||
providers, viewProviders, queries, viewQueries, entryComponents, template, componentViewType,
|
||||
rendererType, componentFactory}: {
|
||||
isHost?: boolean,
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
selector?: string | null,
|
||||
exportAs?: string | null,
|
||||
changeDetection?: ChangeDetectionStrategy | null,
|
||||
inputs?: string[],
|
||||
outputs?: string[],
|
||||
host?: {[key: string]: string},
|
||||
providers?: CompileProviderMetadata[] | null,
|
||||
viewProviders?: CompileProviderMetadata[] | null,
|
||||
queries?: CompileQueryMetadata[] | null,
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
entryComponents?: CompileEntryComponentMetadata[],
|
||||
template?: CompileTemplateMetadata,
|
||||
componentViewType?: StaticSymbol | ProxyClass | null,
|
||||
rendererType?: StaticSymbol | RendererType2 | null,
|
||||
componentFactory?: StaticSymbol | ComponentFactory<any>
|
||||
}) {
|
||||
function compileDirectiveMetadataCreate({isHost, type, isComponent, selector, exportAs,
|
||||
changeDetection, inputs, outputs, host, providers,
|
||||
viewProviders, queries, viewQueries, entryComponents,
|
||||
template, componentViewType, rendererType}: {
|
||||
isHost?: boolean,
|
||||
type?: CompileTypeMetadata,
|
||||
isComponent?: boolean,
|
||||
selector?: string | null,
|
||||
exportAs?: string | null,
|
||||
changeDetection?: ChangeDetectionStrategy | null,
|
||||
inputs?: string[],
|
||||
outputs?: string[],
|
||||
host?: {[key: string]: string},
|
||||
providers?: CompileProviderMetadata[] | null,
|
||||
viewProviders?: CompileProviderMetadata[] | null,
|
||||
queries?: CompileQueryMetadata[] | null,
|
||||
viewQueries?: CompileQueryMetadata[],
|
||||
entryComponents?: CompileEntryComponentMetadata[],
|
||||
template?: CompileTemplateMetadata,
|
||||
componentViewType?: StaticSymbol | ProxyClass | null,
|
||||
rendererType?: StaticSymbol | RendererType2 | null,
|
||||
}) {
|
||||
return CompileDirectiveMetadata.create({
|
||||
isHost: !!isHost,
|
||||
type: noUndefined(type) !,
|
||||
@ -78,7 +78,7 @@ function compileDirectiveMetadataCreate(
|
||||
template: noUndefined(template) !,
|
||||
componentViewType: noUndefined(componentViewType),
|
||||
rendererType: noUndefined(rendererType),
|
||||
componentFactory: noUndefined(componentFactory),
|
||||
componentFactory: null,
|
||||
});
|
||||
}
|
||||
|
||||
@ -274,38 +274,6 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('TemplateParser template transform', () => {
|
||||
beforeEach(() => { TestBed.configureCompiler({providers: TEST_COMPILER_PROVIDERS}); });
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureCompiler({
|
||||
providers:
|
||||
[{provide: TEMPLATE_TRANSFORMS, useValue: new FooAstTransformer(), multi: true}]
|
||||
});
|
||||
});
|
||||
|
||||
describe('single', () => {
|
||||
commonBeforeEach();
|
||||
it('should transform TemplateAST', () => {
|
||||
expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'foo']]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('multiple', () => {
|
||||
beforeEach(() => {
|
||||
TestBed.configureCompiler({
|
||||
providers:
|
||||
[{provide: TEMPLATE_TRANSFORMS, useValue: new BarAstTransformer(), multi: true}]
|
||||
});
|
||||
});
|
||||
|
||||
commonBeforeEach();
|
||||
it('should compose transformers', () => {
|
||||
expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'bar']]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('TemplateParser Security', () => {
|
||||
// Semi-integration test to make sure TemplateParser properly sets the security context.
|
||||
// Uses the actual DomElementSchemaRegistry.
|
||||
|
@ -7,9 +7,9 @@
|
||||
*/
|
||||
|
||||
import {ElementSchemaRegistry, ResourceLoader, UrlResolver} from '@angular/compiler';
|
||||
import {MockResourceLoader} from '@angular/compiler/testing/src/resource_loader_mock';
|
||||
import {MockSchemaRegistry} from '@angular/compiler/testing/src/schema_registry_mock';
|
||||
import {Provider} from '@angular/core';
|
||||
import {MockResourceLoader} from './resource_loader_mock';
|
||||
import {MockSchemaRegistry} from './schema_registry_mock';
|
||||
|
||||
export function createUrlResolverWithoutPackagePrefix(): UrlResolver {
|
||||
return new UrlResolver();
|
@ -5,144 +5,28 @@
|
||||
* 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 {CompileReflector, DirectiveResolver} from '@angular/compiler';
|
||||
import {Compiler, Component, Directive, Injectable, Injector, Provider, Type, resolveForwardRef, ɵViewMetadata as ViewMetadata} from '@angular/core';
|
||||
|
||||
|
||||
import {CompileReflector, DirectiveResolver, core} from '@angular/compiler';
|
||||
|
||||
/**
|
||||
* An implementation of {@link DirectiveResolver} that allows overriding
|
||||
* various properties of directives.
|
||||
*/
|
||||
@Injectable()
|
||||
export class MockDirectiveResolver extends DirectiveResolver {
|
||||
private _directives = new Map<Type<any>, Directive>();
|
||||
private _providerOverrides = new Map<Type<any>, any[]>();
|
||||
private _viewProviderOverrides = new Map<Type<any>, any[]>();
|
||||
private _views = new Map<Type<any>, ViewMetadata>();
|
||||
private _inlineTemplates = new Map<Type<any>, string>();
|
||||
private _directives = new Map<core.Type, core.Directive>();
|
||||
|
||||
constructor(private _injector: Injector, reflector: CompileReflector) { super(reflector); }
|
||||
constructor(reflector: CompileReflector) { super(reflector); }
|
||||
|
||||
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
||||
|
||||
private _clearCacheFor(component: Type<any>) { this._compiler.clearCacheFor(component); }
|
||||
|
||||
resolve(type: Type<any>): Directive;
|
||||
resolve(type: Type<any>, throwIfNotFound: true): Directive;
|
||||
resolve(type: Type<any>, throwIfNotFound: boolean): Directive|null;
|
||||
resolve(type: Type<any>, throwIfNotFound = true): Directive|null {
|
||||
let metadata = this._directives.get(type) || null;
|
||||
if (!metadata) {
|
||||
metadata = super.resolve(type, throwIfNotFound);
|
||||
}
|
||||
if (!metadata) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const providerOverrides = this._providerOverrides.get(type);
|
||||
const viewProviderOverrides = this._viewProviderOverrides.get(type);
|
||||
|
||||
let providers = metadata.providers;
|
||||
if (providerOverrides != null) {
|
||||
const originalViewProviders: Provider[] = metadata.providers || [];
|
||||
providers = originalViewProviders.concat(providerOverrides);
|
||||
}
|
||||
|
||||
if (metadata instanceof Component) {
|
||||
let viewProviders = metadata.viewProviders;
|
||||
if (viewProviderOverrides != null) {
|
||||
const originalViewProviders: Provider[] = metadata.viewProviders || [];
|
||||
viewProviders = originalViewProviders.concat(viewProviderOverrides);
|
||||
}
|
||||
|
||||
let view = this._views.get(type) || metadata;
|
||||
let animations = view.animations;
|
||||
let templateUrl: string|undefined = view.templateUrl;
|
||||
|
||||
let inlineTemplate = this._inlineTemplates.get(type);
|
||||
if (inlineTemplate) {
|
||||
templateUrl = undefined;
|
||||
} else {
|
||||
inlineTemplate = view.template;
|
||||
}
|
||||
|
||||
return new Component({
|
||||
selector: metadata.selector,
|
||||
inputs: metadata.inputs,
|
||||
outputs: metadata.outputs,
|
||||
host: metadata.host,
|
||||
exportAs: metadata.exportAs,
|
||||
moduleId: metadata.moduleId,
|
||||
queries: metadata.queries,
|
||||
changeDetection: metadata.changeDetection,
|
||||
providers: providers,
|
||||
viewProviders: viewProviders,
|
||||
entryComponents: metadata.entryComponents,
|
||||
template: inlineTemplate,
|
||||
templateUrl: templateUrl,
|
||||
animations: animations,
|
||||
styles: view.styles,
|
||||
styleUrls: view.styleUrls,
|
||||
encapsulation: view.encapsulation,
|
||||
interpolation: view.interpolation,
|
||||
preserveWhitespaces: view.preserveWhitespaces,
|
||||
});
|
||||
}
|
||||
|
||||
return new Directive({
|
||||
selector: metadata.selector,
|
||||
inputs: metadata.inputs,
|
||||
outputs: metadata.outputs,
|
||||
host: metadata.host,
|
||||
providers: providers,
|
||||
exportAs: metadata.exportAs,
|
||||
queries: metadata.queries
|
||||
});
|
||||
resolve(type: core.Type): core.Directive;
|
||||
resolve(type: core.Type, throwIfNotFound: true): core.Directive;
|
||||
resolve(type: core.Type, throwIfNotFound: boolean): core.Directive|null;
|
||||
resolve(type: core.Type, throwIfNotFound = true): core.Directive|null {
|
||||
return this._directives.get(type) || super.resolve(type, throwIfNotFound);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the {@link Directive} for a directive.
|
||||
* Overrides the {@link core.Directive} for a directive.
|
||||
*/
|
||||
setDirective(type: Type<any>, metadata: Directive): void {
|
||||
setDirective(type: core.Type, metadata: core.Directive): void {
|
||||
this._directives.set(type, metadata);
|
||||
this._clearCacheFor(type);
|
||||
}
|
||||
|
||||
setProvidersOverride(type: Type<any>, providers: Provider[]): void {
|
||||
this._providerOverrides.set(type, providers);
|
||||
this._clearCacheFor(type);
|
||||
}
|
||||
|
||||
setViewProvidersOverride(type: Type<any>, viewProviders: Provider[]): void {
|
||||
this._viewProviderOverrides.set(type, viewProviders);
|
||||
this._clearCacheFor(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the {@link ViewMetadata} for a component.
|
||||
*/
|
||||
setView(component: Type<any>, view: ViewMetadata): void {
|
||||
this._views.set(component, view);
|
||||
this._clearCacheFor(component);
|
||||
}
|
||||
/**
|
||||
* Overrides the inline template for a component - other configuration remains unchanged.
|
||||
*/
|
||||
setInlineTemplate(component: Type<any>, template: string): void {
|
||||
this._inlineTemplates.set(component, template);
|
||||
this._clearCacheFor(component);
|
||||
}
|
||||
}
|
||||
|
||||
function flattenArray(tree: any[], out: Array<Type<any>|any[]>): void {
|
||||
if (tree == null) return;
|
||||
for (let i = 0; i < tree.length; i++) {
|
||||
const item = resolveForwardRef(tree[i]);
|
||||
if (Array.isArray(item)) {
|
||||
flattenArray(item, out);
|
||||
} else {
|
||||
out.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,131 +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
|
||||
*/
|
||||
|
||||
import {ɵstringify as stringify} from '@angular/core';
|
||||
import {MetadataOverride} from '@angular/core/testing';
|
||||
|
||||
type StringMap = {
|
||||
[key: string]: any
|
||||
};
|
||||
|
||||
let _nextReferenceId = 0;
|
||||
|
||||
export class MetadataOverrider {
|
||||
private _references = new Map<any, string>();
|
||||
/**
|
||||
* Creates a new instance for the given metadata class
|
||||
* based on an old instance and overrides.
|
||||
*/
|
||||
overrideMetadata<C extends T, T>(
|
||||
metadataClass: {new (options: T): C;}, oldMetadata: C, override: MetadataOverride<T>): C {
|
||||
const props: StringMap = {};
|
||||
if (oldMetadata) {
|
||||
_valueProps(oldMetadata).forEach((prop) => props[prop] = (<any>oldMetadata)[prop]);
|
||||
}
|
||||
|
||||
if (override.set) {
|
||||
if (override.remove || override.add) {
|
||||
throw new Error(`Cannot set and add/remove ${stringify(metadataClass)} at the same time!`);
|
||||
}
|
||||
setMetadata(props, override.set);
|
||||
}
|
||||
if (override.remove) {
|
||||
removeMetadata(props, override.remove, this._references);
|
||||
}
|
||||
if (override.add) {
|
||||
addMetadata(props, override.add);
|
||||
}
|
||||
return new metadataClass(<any>props);
|
||||
}
|
||||
}
|
||||
|
||||
function removeMetadata(metadata: StringMap, remove: any, references: Map<any, string>) {
|
||||
const removeObjects = new Set<string>();
|
||||
for (const prop in remove) {
|
||||
const removeValue = remove[prop];
|
||||
if (removeValue instanceof Array) {
|
||||
removeValue.forEach(
|
||||
(value: any) => { removeObjects.add(_propHashKey(prop, value, references)); });
|
||||
} else {
|
||||
removeObjects.add(_propHashKey(prop, removeValue, references));
|
||||
}
|
||||
}
|
||||
|
||||
for (const prop in metadata) {
|
||||
const propValue = metadata[prop];
|
||||
if (propValue instanceof Array) {
|
||||
metadata[prop] = propValue.filter(
|
||||
(value: any) => !removeObjects.has(_propHashKey(prop, value, references)));
|
||||
} else {
|
||||
if (removeObjects.has(_propHashKey(prop, propValue, references))) {
|
||||
metadata[prop] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addMetadata(metadata: StringMap, add: any) {
|
||||
for (const prop in add) {
|
||||
const addValue = add[prop];
|
||||
const propValue = metadata[prop];
|
||||
if (propValue != null && propValue instanceof Array) {
|
||||
metadata[prop] = propValue.concat(addValue);
|
||||
} else {
|
||||
metadata[prop] = addValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setMetadata(metadata: StringMap, set: any) {
|
||||
for (const prop in set) {
|
||||
metadata[prop] = set[prop];
|
||||
}
|
||||
}
|
||||
|
||||
function _propHashKey(propName: any, propValue: any, references: Map<any, string>): string {
|
||||
const replacer = (key: any, value: any) => {
|
||||
if (typeof value === 'function') {
|
||||
value = _serializeReference(value, references);
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
return `${propName}:${JSON.stringify(propValue, replacer)}`;
|
||||
}
|
||||
|
||||
function _serializeReference(ref: any, references: Map<any, string>): string {
|
||||
let id = references.get(ref);
|
||||
if (!id) {
|
||||
id = `${stringify(ref)}${_nextReferenceId++}`;
|
||||
references.set(ref, id);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
function _valueProps(obj: any): string[] {
|
||||
const props: string[] = [];
|
||||
// regular public props
|
||||
Object.keys(obj).forEach((prop) => {
|
||||
if (!prop.startsWith('_')) {
|
||||
props.push(prop);
|
||||
}
|
||||
});
|
||||
|
||||
// getters
|
||||
let proto = obj;
|
||||
while (proto = Object.getPrototypeOf(proto)) {
|
||||
Object.keys(proto).forEach((protoProp) => {
|
||||
const desc = Object.getOwnPropertyDescriptor(proto, protoProp);
|
||||
if (!protoProp.startsWith('_') && desc && 'get' in desc) {
|
||||
props.push(protoProp);
|
||||
}
|
||||
});
|
||||
}
|
||||
return props;
|
||||
}
|
@ -6,21 +6,18 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompileReflector, NgModuleResolver} from '@angular/compiler';
|
||||
import {Compiler, Injectable, Injector, NgModule, Type} from '@angular/core';
|
||||
import {CompileReflector, NgModuleResolver, core} from '@angular/compiler';
|
||||
|
||||
@Injectable()
|
||||
export class MockNgModuleResolver extends NgModuleResolver {
|
||||
private _ngModules = new Map<Type<any>, NgModule>();
|
||||
private _ngModules = new Map<core.Type, core.NgModule>();
|
||||
|
||||
constructor(private _injector: Injector, reflector: CompileReflector) { super(reflector); }
|
||||
constructor(reflector: CompileReflector) { super(reflector); }
|
||||
|
||||
/**
|
||||
* Overrides the {@link NgModule} for a module.
|
||||
*/
|
||||
setNgModule(type: Type<any>, metadata: NgModule): void {
|
||||
setNgModule(type: core.Type, metadata: core.NgModule): void {
|
||||
this._ngModules.set(type, metadata);
|
||||
this._clearCacheFor(type);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,11 +26,7 @@ export class MockNgModuleResolver extends NgModuleResolver {
|
||||
* default
|
||||
* `NgModuleResolver`, see `setNgModule`.
|
||||
*/
|
||||
resolve(type: Type<any>, throwIfNotFound = true): NgModule {
|
||||
resolve(type: core.Type, throwIfNotFound = true): core.NgModule {
|
||||
return this._ngModules.get(type) || super.resolve(type, throwIfNotFound) !;
|
||||
}
|
||||
|
||||
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
||||
|
||||
private _clearCacheFor(component: Type<any>) { this._compiler.clearCacheFor(component); }
|
||||
}
|
||||
|
@ -6,26 +6,17 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {CompileReflector, PipeResolver} from '@angular/compiler';
|
||||
import {Compiler, Injectable, Injector, Pipe, Type} from '@angular/core';
|
||||
import {CompileReflector, PipeResolver, core} from '@angular/compiler';
|
||||
|
||||
@Injectable()
|
||||
export class MockPipeResolver extends PipeResolver {
|
||||
private _pipes = new Map<Type<any>, Pipe>();
|
||||
private _pipes = new Map<core.Type, core.Pipe>();
|
||||
|
||||
constructor(private _injector: Injector, refector: CompileReflector) { super(refector); }
|
||||
|
||||
private get _compiler(): Compiler { return this._injector.get(Compiler); }
|
||||
|
||||
private _clearCacheFor(pipe: Type<any>) { this._compiler.clearCacheFor(pipe); }
|
||||
constructor(refector: CompileReflector) { super(refector); }
|
||||
|
||||
/**
|
||||
* Overrides the {@link Pipe} for a pipe.
|
||||
*/
|
||||
setPipe(type: Type<any>, metadata: Pipe): void {
|
||||
this._pipes.set(type, metadata);
|
||||
this._clearCacheFor(type);
|
||||
}
|
||||
setPipe(type: core.Type, metadata: core.Pipe): void { this._pipes.set(type, metadata); }
|
||||
|
||||
/**
|
||||
* Returns the {@link Pipe} for a pipe:
|
||||
@ -33,7 +24,7 @@ export class MockPipeResolver extends PipeResolver {
|
||||
* default
|
||||
* `PipeResolver`, see `setPipe`.
|
||||
*/
|
||||
resolve(type: Type<any>, throwIfNotFound = true): Pipe {
|
||||
resolve(type: core.Type, throwIfNotFound = true): core.Pipe {
|
||||
let metadata = this._pipes.get(type);
|
||||
if (!metadata) {
|
||||
metadata = super.resolve(type, throwIfNotFound) !;
|
||||
|
@ -6,8 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ElementSchemaRegistry} from '@angular/compiler';
|
||||
import {SchemaMetadata, SecurityContext} from '@angular/core';
|
||||
import {ElementSchemaRegistry, core} from '@angular/compiler';
|
||||
|
||||
export class MockSchemaRegistry implements ElementSchemaRegistry {
|
||||
constructor(
|
||||
@ -16,20 +15,20 @@ export class MockSchemaRegistry implements ElementSchemaRegistry {
|
||||
public existingElements: {[key: string]: boolean}, public invalidProperties: Array<string>,
|
||||
public invalidAttributes: Array<string>) {}
|
||||
|
||||
hasProperty(tagName: string, property: string, schemas: SchemaMetadata[]): boolean {
|
||||
hasProperty(tagName: string, property: string, schemas: core.SchemaMetadata[]): boolean {
|
||||
const value = this.existingProperties[property];
|
||||
return value === void 0 ? true : value;
|
||||
}
|
||||
|
||||
hasElement(tagName: string, schemaMetas: SchemaMetadata[]): boolean {
|
||||
hasElement(tagName: string, schemaMetas: core.SchemaMetadata[]): boolean {
|
||||
const value = this.existingElements[tagName.toLowerCase()];
|
||||
return value === void 0 ? true : value;
|
||||
}
|
||||
|
||||
allKnownElementNames(): string[] { return Object.keys(this.existingElements); }
|
||||
|
||||
securityContext(selector: string, property: string, isAttribute: boolean): SecurityContext {
|
||||
return SecurityContext.NONE;
|
||||
securityContext(selector: string, property: string, isAttribute: boolean): core.SecurityContext {
|
||||
return core.SecurityContext.NONE;
|
||||
}
|
||||
|
||||
getMappedPropName(attrName: string): string { return this.attrPropMapping[attrName] || attrName; }
|
||||
|
@ -21,122 +21,8 @@
|
||||
* </p>
|
||||
* </div>
|
||||
*/
|
||||
export * from './resource_loader_mock';
|
||||
export * from './schema_registry_mock';
|
||||
export * from './directive_resolver_mock';
|
||||
export * from './ng_module_resolver_mock';
|
||||
export * from './pipe_resolver_mock';
|
||||
|
||||
import {createPlatformFactory, ModuleWithComponentFactories, Injectable, CompilerOptions, COMPILER_OPTIONS, CompilerFactory, ComponentFactory, NgModuleFactory, Injector, NgModule, Component, Directive, Pipe, Type, PlatformRef, ɵstringify} from '@angular/core';
|
||||
import {MetadataOverride, ɵTestingCompilerFactory as TestingCompilerFactory, ɵTestingCompiler as TestingCompiler} from '@angular/core/testing';
|
||||
import {platformCoreDynamic, JitCompiler, DirectiveResolver, NgModuleResolver, PipeResolver, CompileMetadataResolver, CompileReflector} from '@angular/compiler';
|
||||
import {MockDirectiveResolver} from './directive_resolver_mock';
|
||||
import {MockNgModuleResolver} from './ng_module_resolver_mock';
|
||||
import {MockPipeResolver} from './pipe_resolver_mock';
|
||||
import {MetadataOverrider} from './metadata_overrider';
|
||||
|
||||
@Injectable()
|
||||
export class TestingCompilerFactoryImpl implements TestingCompilerFactory {
|
||||
constructor(private _compilerFactory: CompilerFactory) {}
|
||||
|
||||
createTestingCompiler(options: CompilerOptions[]): TestingCompiler {
|
||||
const compiler = <JitCompiler>this._compilerFactory.createCompiler(options);
|
||||
return new TestingCompilerImpl(
|
||||
compiler, compiler.injector.get(MockDirectiveResolver),
|
||||
compiler.injector.get(MockPipeResolver), compiler.injector.get(MockNgModuleResolver),
|
||||
compiler.injector.get(CompileMetadataResolver));
|
||||
}
|
||||
}
|
||||
|
||||
export class TestingCompilerImpl implements TestingCompiler {
|
||||
private _overrider = new MetadataOverrider();
|
||||
constructor(
|
||||
private _compiler: JitCompiler, private _directiveResolver: MockDirectiveResolver,
|
||||
private _pipeResolver: MockPipeResolver, private _moduleResolver: MockNgModuleResolver,
|
||||
private _metadataResolver: CompileMetadataResolver) {}
|
||||
get injector(): Injector { return this._compiler.injector; }
|
||||
|
||||
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
return this._compiler.compileModuleSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
||||
return this._compiler.compileModuleAsync(moduleType);
|
||||
}
|
||||
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
||||
return this._compiler.compileModuleAndAllComponentsSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
||||
Promise<ModuleWithComponentFactories<T>> {
|
||||
return this._compiler.compileModuleAndAllComponentsAsync(moduleType);
|
||||
}
|
||||
|
||||
getNgContentSelectors(component: Type<any>): string[] {
|
||||
return this._compiler.getNgContentSelectors(component);
|
||||
}
|
||||
|
||||
getComponentFactory<T>(component: Type<T>): ComponentFactory<T> {
|
||||
return this._compiler.getComponentFactory(component);
|
||||
}
|
||||
|
||||
checkOverrideAllowed(type: Type<any>) {
|
||||
if (this._compiler.hasAotSummary(type)) {
|
||||
throw new Error(`${ɵstringify(type)} was AOT compiled, so its metadata cannot be changed.`);
|
||||
}
|
||||
}
|
||||
|
||||
overrideModule(ngModule: Type<any>, override: MetadataOverride<NgModule>): void {
|
||||
this.checkOverrideAllowed(ngModule);
|
||||
const oldMetadata = this._moduleResolver.resolve(ngModule, false);
|
||||
this._moduleResolver.setNgModule(
|
||||
ngModule, this._overrider.overrideMetadata(NgModule, oldMetadata, override));
|
||||
}
|
||||
overrideDirective(directive: Type<any>, override: MetadataOverride<Directive>): void {
|
||||
this.checkOverrideAllowed(directive);
|
||||
const oldMetadata = this._directiveResolver.resolve(directive, false);
|
||||
this._directiveResolver.setDirective(
|
||||
directive, this._overrider.overrideMetadata(Directive, oldMetadata !, override));
|
||||
}
|
||||
overrideComponent(component: Type<any>, override: MetadataOverride<Component>): void {
|
||||
this.checkOverrideAllowed(component);
|
||||
const oldMetadata = this._directiveResolver.resolve(component, false);
|
||||
this._directiveResolver.setDirective(
|
||||
component, this._overrider.overrideMetadata(Component, oldMetadata !, override));
|
||||
}
|
||||
overridePipe(pipe: Type<any>, override: MetadataOverride<Pipe>): void {
|
||||
this.checkOverrideAllowed(pipe);
|
||||
const oldMetadata = this._pipeResolver.resolve(pipe, false);
|
||||
this._pipeResolver.setPipe(pipe, this._overrider.overrideMetadata(Pipe, oldMetadata, override));
|
||||
}
|
||||
loadAotSummaries(summaries: () => any[]) { this._compiler.loadAotSummaries(summaries); }
|
||||
clearCache(): void { this._compiler.clearCache(); }
|
||||
clearCacheFor(type: Type<any>) { this._compiler.clearCacheFor(type); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Platform for dynamic tests
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const platformCoreDynamicTesting: (extraProviders?: any[]) => PlatformRef =
|
||||
createPlatformFactory(platformCoreDynamic, 'coreDynamicTesting', [
|
||||
{
|
||||
provide: COMPILER_OPTIONS,
|
||||
useValue: {
|
||||
providers: [
|
||||
{provide: MockPipeResolver, deps: [Injector, CompileReflector]},
|
||||
{provide: PipeResolver, useExisting: MockPipeResolver},
|
||||
{provide: MockDirectiveResolver, deps: [Injector, CompileReflector]},
|
||||
{provide: DirectiveResolver, useExisting: MockDirectiveResolver},
|
||||
{provide: MockNgModuleResolver, deps: [Injector, CompileReflector]},
|
||||
{provide: NgModuleResolver, useExisting: MockNgModuleResolver},
|
||||
]
|
||||
},
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: TestingCompilerFactory,
|
||||
useClass: TestingCompilerFactoryImpl,
|
||||
deps: [CompilerFactory]
|
||||
}
|
||||
]);
|
||||
|
@ -5,8 +5,6 @@
|
||||
// Test that we rely on decorator downleveling
|
||||
"emitDecoratorMetadata": false,
|
||||
"paths": {
|
||||
"@angular/core": ["../../dist/packages/core"],
|
||||
"@angular/core/testing": ["../../dist/packages/core/testing"],
|
||||
"@angular/compiler": ["../../dist/packages/compiler"]
|
||||
}
|
||||
},
|
||||
|
@ -11,10 +11,6 @@
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../dist/packages/compiler",
|
||||
"paths": {
|
||||
"@angular/core": ["../../dist/packages/core"],
|
||||
"@angular/core/testing": ["../../dist/packages/core/testing"]
|
||||
},
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
"inlineSources": true,
|
||||
@ -27,8 +23,5 @@
|
||||
"files": [
|
||||
"index.ts",
|
||||
"../../node_modules/zone.js/dist/zone.js.d.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"annotateForClosureCompiler": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user