fix(core): Remove static dependency from @angular/core to @angular/compiler (#26734)
PR Close #26734
This commit is contained in:
parent
5d740785a9
commit
d042c4afe0
|
@ -332,8 +332,9 @@ function parseFieldToPropertyMapping(
|
|||
*/
|
||||
function parseDecoratedFields(
|
||||
fields: {member: ClassMember, decorators: Decorator[]}[], reflector: ReflectionHost,
|
||||
checker: ts.TypeChecker, mapValueResolver: (publicName: string, internalName: string) =>
|
||||
string | string[]): {[field: string]: string | string[]} {
|
||||
checker: ts.TypeChecker,
|
||||
mapValueResolver: (publicName: string, internalName: string) =>
|
||||
string | [string, string]): {[field: string]: string | [string, string]} {
|
||||
return fields.reduce(
|
||||
(results, field) => {
|
||||
const fieldName = field.member.name;
|
||||
|
@ -356,10 +357,10 @@ function parseDecoratedFields(
|
|||
});
|
||||
return results;
|
||||
},
|
||||
{} as{[field: string]: string | string[]});
|
||||
{} as{[field: string]: string | [string, string]});
|
||||
}
|
||||
|
||||
function resolveInput(publicName: string, internalName: string) {
|
||||
function resolveInput(publicName: string, internalName: string): [string, string] {
|
||||
return [publicName, internalName];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,5 +22,5 @@
|
|||
"ng-update": {
|
||||
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
"sideEffects": true
|
||||
}
|
|
@ -6,6 +6,11 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
//////////////////////////////////////
|
||||
// THIS FILE HAS GLOBAL SIDE EFFECT //
|
||||
// (see bottom of file) //
|
||||
//////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
|
@ -23,6 +28,8 @@
|
|||
*/
|
||||
|
||||
import * as core from './core';
|
||||
import {publishFacade} from './jit_compiler_facade';
|
||||
import {global} from './util';
|
||||
|
||||
export {core};
|
||||
|
||||
|
@ -91,4 +98,9 @@ export {compilePipeFromMetadata, R3PipeMetadata} from './render3/r3_pipe_compile
|
|||
export {makeBindingParser, parseTemplate} from './render3/view/template';
|
||||
export {R3Reference} from './render3/util';
|
||||
export {compileBaseDefFromMetadata, R3BaseRefMetaData, compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings} from './render3/view/compiler';
|
||||
export {publishFacade} from './jit_compiler_facade';
|
||||
// This file only reexports content of the `src` folder. Keep it that way.
|
||||
|
||||
// This function call has a global side effects and publishes the compiler into global namespace for
|
||||
// the late binding of the Compiler to the @angular/core for jit compilation.
|
||||
publishFacade(global);
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @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 set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow
|
||||
* for late binding of `@angular/compiler` for JIT purposes.
|
||||
*
|
||||
* This file has two copies. Please ensure that they are in sync:
|
||||
* - packages/compiler/src/compiler_facade_interface.ts (master)
|
||||
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
|
||||
*
|
||||
* Please ensure that the two files are in sync using this command:
|
||||
* ```
|
||||
* cp packages/compiler/src/compiler_facade_interface.ts \
|
||||
* packages/core/src/render3/jit/compiler_facade_interface.ts
|
||||
* ```
|
||||
*/
|
||||
|
||||
export interface ExportedCompilerFacade { ɵcompilerFacade: CompilerFacade; }
|
||||
|
||||
export interface CompilerFacade {
|
||||
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):
|
||||
any;
|
||||
compileInjectable(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;
|
||||
compileInjector(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectorMetadataFacade): any;
|
||||
compileNgModule(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3NgModuleMetadataFacade): any;
|
||||
compileDirective(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DirectiveMetadataFacade): any;
|
||||
compileComponent(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3ComponentMetadataFacade): any;
|
||||
|
||||
R3ResolvedDependencyType: typeof R3ResolvedDependencyType;
|
||||
}
|
||||
|
||||
export interface CoreEnvironment { [name: string]: Function; }
|
||||
|
||||
export type StringMap = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
export type StringMapWithRename = {
|
||||
[key: string]: string | [string, string];
|
||||
};
|
||||
|
||||
export type Provider = any;
|
||||
|
||||
export enum R3ResolvedDependencyType {
|
||||
Token = 0,
|
||||
Attribute = 1,
|
||||
}
|
||||
|
||||
export interface R3DependencyMetadataFacade {
|
||||
token: any;
|
||||
resolved: R3ResolvedDependencyType;
|
||||
host: boolean;
|
||||
optional: boolean;
|
||||
self: boolean;
|
||||
skipSelf: boolean;
|
||||
}
|
||||
|
||||
export interface R3PipeMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
pipeName: string;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
pure: boolean;
|
||||
}
|
||||
|
||||
export interface R3InjectableMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
ctorDeps: R3DependencyMetadataFacade[]|null;
|
||||
providedIn: any;
|
||||
useClass?: any;
|
||||
useFactory?: any;
|
||||
useExisting?: any;
|
||||
useValue?: any;
|
||||
userDeps?: R3DependencyMetadataFacade[];
|
||||
}
|
||||
|
||||
export interface R3NgModuleMetadataFacade {
|
||||
type: any;
|
||||
bootstrap: Function[];
|
||||
declarations: Function[];
|
||||
imports: Function[];
|
||||
exports: Function[];
|
||||
emitInline: boolean;
|
||||
}
|
||||
|
||||
export interface R3InjectorMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
providers: any;
|
||||
imports: any;
|
||||
}
|
||||
|
||||
export interface R3DirectiveMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
typeArgumentCount: number;
|
||||
typeSourceSpan: null;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
selector: string|null;
|
||||
queries: R3QueryMetadataFacade[];
|
||||
host: {[key: string]: string};
|
||||
propMetadata: {[key: string]: any[]};
|
||||
lifecycle: {usesOnChanges: boolean;};
|
||||
inputs: string[];
|
||||
outputs: string[];
|
||||
usesInheritance: boolean;
|
||||
exportAs: string|null;
|
||||
providers: Provider[]|null;
|
||||
}
|
||||
|
||||
export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
|
||||
template: string;
|
||||
preserveWhitespaces: boolean;
|
||||
animations: any[]|undefined;
|
||||
viewQueries: R3QueryMetadataFacade[];
|
||||
pipes: Map<string, any>;
|
||||
directives: Map<string, any>;
|
||||
styles: string[];
|
||||
encapsulation: ViewEncapsulation;
|
||||
viewProviders: Provider[]|null;
|
||||
}
|
||||
|
||||
export type ViewEncapsulation = number;
|
||||
|
||||
export interface R3QueryMetadataFacade {
|
||||
propertyName: string;
|
||||
first: boolean;
|
||||
predicate: any|string[];
|
||||
descendants: boolean;
|
||||
read: any|null;
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
/**
|
||||
* @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 {CompilerFacade, CoreEnvironment, ExportedCompilerFacade, R3ComponentMetadataFacade, R3DependencyMetadataFacade, R3DirectiveMetadataFacade, R3InjectableMetadataFacade, R3InjectorMetadataFacade, R3NgModuleMetadataFacade, R3PipeMetadataFacade, R3QueryMetadataFacade, StringMap, StringMapWithRename} from './compiler_facade_interface';
|
||||
import {ConstantPool} from './constant_pool';
|
||||
import {HostBinding, HostListener, Input, Output, Type} from './core';
|
||||
import {compileInjectable} from './injectable_compiler_2';
|
||||
import {Expression, LiteralExpr, WrappedNodeExpr} from './output/output_ast';
|
||||
import {R3DependencyMetadata, R3ResolvedDependencyType} from './render3/r3_factory';
|
||||
import {jitExpression} from './render3/r3_jit';
|
||||
import {R3InjectorMetadata, R3NgModuleMetadata, compileInjector, compileNgModule} from './render3/r3_module_compiler';
|
||||
import {compilePipeFromMetadata} from './render3/r3_pipe_compiler';
|
||||
import {R3Reference} from './render3/util';
|
||||
import {R3DirectiveMetadata, R3QueryMetadata} from './render3/view/api';
|
||||
import {compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings} from './render3/view/compiler';
|
||||
import {makeBindingParser, parseTemplate} from './render3/view/template';
|
||||
|
||||
export class CompilerFacadeImpl implements CompilerFacade {
|
||||
R3ResolvedDependencyType = R3ResolvedDependencyType as any;
|
||||
|
||||
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, facade: R3PipeMetadataFacade):
|
||||
any {
|
||||
const res = compilePipeFromMetadata({
|
||||
name: facade.name,
|
||||
type: new WrappedNodeExpr(facade.type),
|
||||
deps: convertR3DependencyMetadataArray(facade.deps),
|
||||
pipeName: facade.pipeName,
|
||||
pure: facade.pure,
|
||||
});
|
||||
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
|
||||
}
|
||||
|
||||
compileInjectable(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3InjectableMetadataFacade): any {
|
||||
const {expression, statements} = compileInjectable({
|
||||
name: facade.name,
|
||||
type: new WrappedNodeExpr(facade.type),
|
||||
providedIn: computeProvidedIn(facade.providedIn),
|
||||
useClass: wrapExpression(facade, USE_CLASS),
|
||||
useFactory: wrapExpression(facade, USE_FACTORY),
|
||||
useValue: wrapExpression(facade, USE_VALUE),
|
||||
useExisting: wrapExpression(facade, USE_EXISTING),
|
||||
ctorDeps: convertR3DependencyMetadataArray(facade.ctorDeps),
|
||||
userDeps: convertR3DependencyMetadataArray(facade.userDeps) || undefined,
|
||||
});
|
||||
|
||||
return jitExpression(expression, angularCoreEnv, sourceMapUrl, statements);
|
||||
}
|
||||
|
||||
compileInjector(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3InjectorMetadataFacade): any {
|
||||
const meta: R3InjectorMetadata = {
|
||||
name: facade.name,
|
||||
type: new WrappedNodeExpr(facade.type),
|
||||
deps: convertR3DependencyMetadataArray(facade.deps),
|
||||
providers: new WrappedNodeExpr(facade.providers),
|
||||
imports: new WrappedNodeExpr(facade.imports),
|
||||
};
|
||||
const res = compileInjector(meta);
|
||||
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
|
||||
}
|
||||
|
||||
compileNgModule(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3NgModuleMetadataFacade): any {
|
||||
const meta: R3NgModuleMetadata = {
|
||||
type: new WrappedNodeExpr(facade.type),
|
||||
bootstrap: facade.bootstrap.map(wrapReference),
|
||||
declarations: facade.declarations.map(wrapReference),
|
||||
imports: facade.imports.map(wrapReference),
|
||||
exports: facade.exports.map(wrapReference),
|
||||
emitInline: true,
|
||||
};
|
||||
const res = compileNgModule(meta);
|
||||
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, []);
|
||||
}
|
||||
|
||||
compileDirective(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3DirectiveMetadataFacade): any {
|
||||
const constantPool = new ConstantPool();
|
||||
const bindingParser = makeBindingParser();
|
||||
|
||||
const meta: R3DirectiveMetadata = convertDirectiveFacadeToMetadata(facade);
|
||||
const res = compileDirectiveFromMetadata(meta, constantPool, bindingParser);
|
||||
const preStatements = [...constantPool.statements, ...res.statements];
|
||||
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
|
||||
}
|
||||
|
||||
compileComponent(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string,
|
||||
facade: R3ComponentMetadataFacade): any {
|
||||
// The ConstantPool is a requirement of the JIT'er.
|
||||
const constantPool = new ConstantPool();
|
||||
|
||||
// Parse the template and check for errors.
|
||||
const template = parseTemplate(
|
||||
facade.template, sourceMapUrl, {
|
||||
preserveWhitespaces: facade.preserveWhitespaces || false,
|
||||
},
|
||||
'');
|
||||
if (template.errors !== undefined) {
|
||||
const errors = template.errors.map(err => err.toString()).join(', ');
|
||||
throw new Error(`Errors during JIT compilation of template for ${facade.name}: ${errors}`);
|
||||
}
|
||||
|
||||
// Compile the component metadata, including template, into an expression.
|
||||
// TODO(alxhub): implement inputs, outputs, queries, etc.
|
||||
const res = compileComponentFromMetadata(
|
||||
{
|
||||
...facade as R3ComponentMetadataFacadeNoPropAndWhitespace,
|
||||
...convertDirectiveFacadeToMetadata(facade),
|
||||
template,
|
||||
viewQueries: facade.viewQueries.map(convertToR3QueryMetadata),
|
||||
wrapDirectivesAndPipesInClosure: false,
|
||||
styles: facade.styles || [],
|
||||
encapsulation: facade.encapsulation as any,
|
||||
animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
|
||||
viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) :
|
||||
null,
|
||||
},
|
||||
constantPool, makeBindingParser());
|
||||
const preStatements = [...constantPool.statements, ...res.statements];
|
||||
|
||||
return jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
|
||||
}
|
||||
}
|
||||
|
||||
// This seems to be needed to placate TS v3.0 only
|
||||
type R3ComponentMetadataFacadeNoPropAndWhitespace = Pick<
|
||||
R3ComponentMetadataFacade,
|
||||
Exclude<Exclude<keyof R3ComponentMetadataFacade, 'preserveWhitespaces'>, 'propMetadata'>>;
|
||||
|
||||
const USE_CLASS = Object.keys({useClass: null})[0];
|
||||
const USE_FACTORY = Object.keys({useFactory: null})[0];
|
||||
const USE_VALUE = Object.keys({useValue: null})[0];
|
||||
const USE_EXISTING = Object.keys({useExisting: null})[0];
|
||||
|
||||
const wrapReference = function(value: Type): R3Reference {
|
||||
const wrapped = new WrappedNodeExpr(value);
|
||||
return {value: wrapped, type: wrapped};
|
||||
};
|
||||
|
||||
function convertToR3QueryMetadata(facade: R3QueryMetadataFacade): R3QueryMetadata {
|
||||
return {
|
||||
...facade,
|
||||
predicate: Array.isArray(facade.predicate) ? facade.predicate :
|
||||
new WrappedNodeExpr(facade.predicate),
|
||||
read: facade.read ? new WrappedNodeExpr(facade.read) : null,
|
||||
};
|
||||
}
|
||||
|
||||
function convertDirectiveFacadeToMetadata(facade: R3DirectiveMetadataFacade): R3DirectiveMetadata {
|
||||
const inputsFromMetadata = parseInputOutputs(facade.inputs || []);
|
||||
const outputsFromMetadata = parseInputOutputs(facade.outputs || []);
|
||||
const propMetadata = facade.propMetadata;
|
||||
const inputsFromType: StringMapWithRename = {};
|
||||
const outputsFromType: StringMap = {};
|
||||
for (const field in propMetadata) {
|
||||
if (propMetadata.hasOwnProperty(field)) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
if (isInput(ann)) {
|
||||
inputsFromType[field] =
|
||||
ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
|
||||
} else if (isOutput(ann)) {
|
||||
outputsFromType[field] = ann.bindingPropertyName || field;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...facade as R3DirectiveMetadataFacadeNoPropAndWhitespace,
|
||||
typeSourceSpan: null !,
|
||||
type: new WrappedNodeExpr(facade.type),
|
||||
deps: convertR3DependencyMetadataArray(facade.deps),
|
||||
host: extractHostBindings(facade.host, facade.propMetadata),
|
||||
inputs: {...inputsFromMetadata, ...inputsFromType},
|
||||
outputs: {...outputsFromMetadata, ...outputsFromType},
|
||||
providers: facade.providers != null ? new WrappedNodeExpr(facade.providers) : null,
|
||||
};
|
||||
}
|
||||
|
||||
// This seems to be needed to placate TS v3.0 only
|
||||
type R3DirectiveMetadataFacadeNoPropAndWhitespace =
|
||||
Pick<R3DirectiveMetadataFacade, Exclude<keyof R3DirectiveMetadataFacade, 'propMetadata'>>;
|
||||
|
||||
function wrapExpression(obj: any, property: string): WrappedNodeExpr<any>|undefined {
|
||||
if (obj.hasOwnProperty(property)) {
|
||||
return new WrappedNodeExpr(obj[property]);
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function computeProvidedIn(providedIn: Type | string | null | undefined): Expression {
|
||||
if (providedIn == null || typeof providedIn === 'string') {
|
||||
return new LiteralExpr(providedIn);
|
||||
} else {
|
||||
return new WrappedNodeExpr(providedIn);
|
||||
}
|
||||
}
|
||||
|
||||
function convertR3DependencyMetadata(facade: R3DependencyMetadataFacade): R3DependencyMetadata {
|
||||
let tokenExpr;
|
||||
if (facade.token === null) {
|
||||
tokenExpr = new LiteralExpr(null);
|
||||
} else if (facade.resolved === R3ResolvedDependencyType.Attribute) {
|
||||
tokenExpr = new LiteralExpr(facade.token);
|
||||
} else {
|
||||
tokenExpr = new WrappedNodeExpr(facade.token);
|
||||
}
|
||||
return {
|
||||
token: tokenExpr,
|
||||
resolved: facade.resolved,
|
||||
host: facade.host,
|
||||
optional: facade.optional,
|
||||
self: facade.self,
|
||||
skipSelf: facade.skipSelf
|
||||
};
|
||||
}
|
||||
|
||||
function convertR3DependencyMetadataArray(facades: R3DependencyMetadataFacade[] | null | undefined):
|
||||
R3DependencyMetadata[]|null {
|
||||
return facades == null ? null : facades.map(convertR3DependencyMetadata);
|
||||
}
|
||||
|
||||
function extractHostBindings(host: {[key: string]: string}, propMetadata: {[key: string]: any[]}): {
|
||||
attributes: StringMap,
|
||||
listeners: StringMap,
|
||||
properties: StringMap,
|
||||
} {
|
||||
// First parse the declarations from the metadata.
|
||||
const {attributes, listeners, properties, animations} = parseHostBindings(host || {});
|
||||
|
||||
if (Object.keys(animations).length > 0) {
|
||||
throw new Error(`Animation bindings are as-of-yet unsupported in Ivy`);
|
||||
}
|
||||
|
||||
// Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
|
||||
for (const field in propMetadata) {
|
||||
if (propMetadata.hasOwnProperty(field)) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
if (isHostBinding(ann)) {
|
||||
properties[ann.hostPropertyName || field] = field;
|
||||
} else if (isHostListener(ann)) {
|
||||
listeners[ann.eventName || field] = `${field}(${(ann.args || []).join(',')})`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {attributes, listeners, properties};
|
||||
}
|
||||
|
||||
function isHostBinding(value: any): value is HostBinding {
|
||||
return value.ngMetadataName === 'HostBinding';
|
||||
}
|
||||
|
||||
function isHostListener(value: any): value is HostListener {
|
||||
return value.ngMetadataName === 'HostListener';
|
||||
}
|
||||
|
||||
|
||||
function isInput(value: any): value is Input {
|
||||
return value.ngMetadataName === 'Input';
|
||||
}
|
||||
|
||||
function isOutput(value: any): value is Output {
|
||||
return value.ngMetadataName === 'Output';
|
||||
}
|
||||
|
||||
function parseInputOutputs(values: string[]): StringMap {
|
||||
return values.reduce(
|
||||
(map, value) => {
|
||||
const [field, property] = value.split(',').map(piece => piece.trim());
|
||||
map[field] = property || field;
|
||||
return map;
|
||||
},
|
||||
{} as StringMap);
|
||||
}
|
||||
|
||||
export function publishFacade(global: any) {
|
||||
const ng: ExportedCompilerFacade = global.ng || (global.ng = {});
|
||||
ng.ɵcompilerFacade = new CompilerFacadeImpl();
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {StaticSymbol} from '../aot/static_symbol';
|
||||
import {CompileShallowModuleMetadata, identifierName} from '../compile_metadata';
|
||||
import {InjectableCompiler} from '../injectable_compiler';
|
||||
import {mapLiteral} from '../output/map_util';
|
||||
|
|
|
@ -86,7 +86,7 @@ export interface R3DirectiveMetadata {
|
|||
/**
|
||||
* A mapping of input field names to the property names.
|
||||
*/
|
||||
inputs: {[field: string]: string | string[]};
|
||||
inputs: {[field: string]: string | [string, string]};
|
||||
|
||||
/**
|
||||
* A mapping of output field names to the property names.
|
||||
|
|
|
@ -44,7 +44,7 @@ export interface DirectiveMeta {
|
|||
*
|
||||
* Goes from property names to field names.
|
||||
*/
|
||||
inputs: {[property: string]: string | string[]};
|
||||
inputs: {[property: string]: string | [string, string]};
|
||||
|
||||
/**
|
||||
* Set of outputs which this directive claims.
|
||||
|
|
|
@ -233,3 +233,19 @@ export interface Console {
|
|||
log(message: string): void;
|
||||
warn(message: string): void;
|
||||
}
|
||||
|
||||
|
||||
declare var WorkerGlobalScope: any;
|
||||
// CommonJS / Node have global context exposed as "global" variable.
|
||||
// We don't want to include the whole node.d.ts this this compilation unit so we'll just fake
|
||||
// the global "global" var for now.
|
||||
declare var global: any;
|
||||
const __window = typeof window !== 'undefined' && window;
|
||||
const __self = typeof self !== 'undefined' && typeof WorkerGlobalScope !== 'undefined' &&
|
||||
self instanceof WorkerGlobalScope && self;
|
||||
const __global = typeof global !== 'undefined' && global;
|
||||
|
||||
// Check __global first, because in Node tests both __global and __window may be defined and _global
|
||||
// should be __global in that case.
|
||||
const _global: {[name: string]: any} = __global || __window || __self;
|
||||
export {_global as global};
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as core from '../../core/src/render3/jit/compiler_facade_interface';
|
||||
import {R3ResolvedDependencyType} from '../public_api';
|
||||
import * as compiler from '../src/compiler_facade_interface';
|
||||
|
||||
/**
|
||||
* This file is compiler level file which asserts that the set of interfaces in `@angular/core` and
|
||||
* `@angular/compiler` match. (Build time failure.)
|
||||
*
|
||||
* If this file fails to compile it means these two files when out of sync:
|
||||
* - packages/compiler/src/compiler_facade_interface.ts (master)
|
||||
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
|
||||
*
|
||||
* Please ensure that the two files are in sync using this command:
|
||||
* ```
|
||||
* cp packages/compiler/src/compiler_facade_interface.ts \
|
||||
* packages/core/src/render3/jit/compiler_facade_interface.ts
|
||||
* ```
|
||||
*/
|
||||
|
||||
const coreExportedCompilerFacade1: core.ExportedCompilerFacade =
|
||||
null !as compiler.ExportedCompilerFacade;
|
||||
const compilerExportedCompilerFacade2: compiler.ExportedCompilerFacade =
|
||||
null !as core.ExportedCompilerFacade;
|
||||
|
||||
const coreCompilerFacade: core.CompilerFacade = null !as compiler.CompilerFacade;
|
||||
const compilerCompilerFacade: compiler.CompilerFacade = null !as core.CompilerFacade;
|
||||
|
||||
const coreCoreEnvironment: core.CoreEnvironment = null !as compiler.CoreEnvironment;
|
||||
const compilerCoreEnvironment: compiler.CoreEnvironment = null !as core.CoreEnvironment;
|
||||
|
||||
const coreStringMap: core.StringMap = null !as compiler.StringMap;
|
||||
const compilerStringMap: compiler.StringMap = null !as core.StringMap;
|
||||
|
||||
const coreProvider: core.Provider = null !as compiler.Provider;
|
||||
const compilerProvider: compiler.Provider = null !as core.Provider;
|
||||
|
||||
const coreR3ResolvedDependencyType: core.R3ResolvedDependencyType =
|
||||
null !as compiler.R3ResolvedDependencyType;
|
||||
const compilerR3ResolvedDependencyType: compiler.R3ResolvedDependencyType =
|
||||
null !as core.R3ResolvedDependencyType;
|
||||
|
||||
const coreR3ResolvedDependencyType2: R3ResolvedDependencyType =
|
||||
null !as core.R3ResolvedDependencyType;
|
||||
const compilerR3ResolvedDependencyType2: R3ResolvedDependencyType =
|
||||
null !as core.R3ResolvedDependencyType;
|
||||
|
||||
const coreR3ResolvedDependencyType3: core.R3ResolvedDependencyType =
|
||||
null !as R3ResolvedDependencyType;
|
||||
const compilerR3ResolvedDependencyType3: compiler.R3ResolvedDependencyType =
|
||||
null !as R3ResolvedDependencyType;
|
||||
|
||||
const coreR3DependencyMetadataFacade: core.R3DependencyMetadataFacade =
|
||||
null !as compiler.R3DependencyMetadataFacade;
|
||||
const compilerR3DependencyMetadataFacade: compiler.R3DependencyMetadataFacade =
|
||||
null !as core.R3DependencyMetadataFacade;
|
||||
|
||||
const coreR3PipeMetadataFacade: core.R3PipeMetadataFacade = null !as compiler.R3PipeMetadataFacade;
|
||||
const compilerR3PipeMetadataFacade: compiler.R3PipeMetadataFacade =
|
||||
null !as core.R3PipeMetadataFacade;
|
||||
|
||||
const coreR3InjectableMetadataFacade: core.R3InjectableMetadataFacade =
|
||||
null !as compiler.R3InjectableMetadataFacade;
|
||||
const compilerR3InjectableMetadataFacade: compiler.R3InjectableMetadataFacade =
|
||||
null !as core.R3InjectableMetadataFacade;
|
||||
|
||||
const coreR3NgModuleMetadataFacade: core.R3NgModuleMetadataFacade =
|
||||
null !as compiler.R3NgModuleMetadataFacade;
|
||||
const compilerR3NgModuleMetadataFacade: compiler.R3NgModuleMetadataFacade =
|
||||
null !as core.R3NgModuleMetadataFacade;
|
||||
|
||||
const coreR3InjectorMetadataFacade: core.R3InjectorMetadataFacade =
|
||||
null !as compiler.R3InjectorMetadataFacade;
|
||||
const compilerR3InjectorMetadataFacade: compiler.R3InjectorMetadataFacade =
|
||||
null !as core.R3InjectorMetadataFacade;
|
||||
|
||||
const coreR3DirectiveMetadataFacade: core.R3DirectiveMetadataFacade =
|
||||
null !as compiler.R3DirectiveMetadataFacade;
|
||||
const compilerR3DirectiveMetadataFacade: compiler.R3DirectiveMetadataFacade =
|
||||
null !as core.R3DirectiveMetadataFacade;
|
||||
|
||||
const coreR3ComponentMetadataFacade: core.R3ComponentMetadataFacade =
|
||||
null !as compiler.R3ComponentMetadataFacade;
|
||||
const compilerR3ComponentMetadataFacade: compiler.R3ComponentMetadataFacade =
|
||||
null !as core.R3ComponentMetadataFacade;
|
||||
|
||||
const coreViewEncapsulation: core.ViewEncapsulation = null !as compiler.ViewEncapsulation;
|
||||
const compilerViewEncapsulation: compiler.ViewEncapsulation = null !as core.ViewEncapsulation;
|
||||
|
||||
const coreR3QueryMetadataFacade: core.R3QueryMetadataFacade =
|
||||
null !as compiler.R3QueryMetadataFacade;
|
||||
const compilerR3QueryMetadataFacade: compiler.R3QueryMetadataFacade =
|
||||
null !as core.R3QueryMetadataFacade;
|
|
@ -13,7 +13,6 @@ ng_module(
|
|||
module_name = "@angular/core",
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"@ngdeps//zone.js",
|
||||
"@rxjs",
|
||||
"@rxjs//operators",
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
"tslib": "^1.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/compiler": "0.0.0-PLACEHOLDER",
|
||||
"rxjs": "^6.0.0",
|
||||
"zone.js": "~0.8.26"
|
||||
},
|
||||
|
@ -28,4 +27,4 @@
|
|||
"packageGroup": "NG_UPDATE_PACKAGE_GROUP"
|
||||
},
|
||||
"sideEffects": false
|
||||
}
|
||||
}
|
|
@ -480,6 +480,7 @@ export function getNodeInjectable(
|
|||
*/
|
||||
export function bloomHashBitOrFactory(token: Type<any>| InjectionToken<any>): number|Function|
|
||||
undefined {
|
||||
ngDevMode && assertDefined(token, 'token must be defined');
|
||||
const tokenId: number|undefined = (token as any)[NG_ELEMENT_ID];
|
||||
return typeof tokenId === 'number' ? tokenId & BLOOM_MASK : tokenId;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* @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 {global} from '../../util';
|
||||
import {CompilerFacade, ExportedCompilerFacade} from './compiler_facade_interface';
|
||||
export * from './compiler_facade_interface';
|
||||
|
||||
export function getCompilerFacade(): CompilerFacade {
|
||||
const globalNg: ExportedCompilerFacade = global.ng;
|
||||
if (!globalNg || !globalNg.ɵcompilerFacade) {
|
||||
throw new Error(
|
||||
`Angular JIT compilation failed: '@angular/compiler' not loaded!\n` +
|
||||
` - JIT compilation is discouraged for production use-cases! Consider AOT mode instead.\n` +
|
||||
` - Did you bootstrap using '@angular/platform-browser-dynamic' or '@angular/platform-server'?\n` +
|
||||
` - Alternatively provide the compiler with 'import "@angular/compiler";' before bootstrapping.`);
|
||||
}
|
||||
return globalNg.ɵcompilerFacade;
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* @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 set of interfaces which are shared between `@angular/core` and `@angular/compiler` to allow
|
||||
* for late binding of `@angular/compiler` for JIT purposes.
|
||||
*
|
||||
* This file has two copies. Please ensure that they are in sync:
|
||||
* - packages/compiler/src/compiler_facade_interface.ts (master)
|
||||
* - packages/core/src/render3/jit/compiler_facade_interface.ts (copy)
|
||||
*
|
||||
* Please ensure that the two files are in sync using this command:
|
||||
* ```
|
||||
* cp packages/compiler/src/compiler_facade_interface.ts \
|
||||
* packages/core/src/render3/jit/compiler_facade_interface.ts
|
||||
* ```
|
||||
*/
|
||||
|
||||
export interface ExportedCompilerFacade { ɵcompilerFacade: CompilerFacade; }
|
||||
|
||||
export interface CompilerFacade {
|
||||
compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3PipeMetadataFacade):
|
||||
any;
|
||||
compileInjectable(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectableMetadataFacade): any;
|
||||
compileInjector(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3InjectorMetadataFacade): any;
|
||||
compileNgModule(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3NgModuleMetadataFacade): any;
|
||||
compileDirective(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3DirectiveMetadataFacade): any;
|
||||
compileComponent(
|
||||
angularCoreEnv: CoreEnvironment, sourceMapUrl: string, meta: R3ComponentMetadataFacade): any;
|
||||
|
||||
R3ResolvedDependencyType: typeof R3ResolvedDependencyType;
|
||||
}
|
||||
|
||||
export interface CoreEnvironment { [name: string]: Function; }
|
||||
|
||||
export type StringMap = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
export type StringMapWithRename = {
|
||||
[key: string]: string | [string, string];
|
||||
};
|
||||
|
||||
export type Provider = any;
|
||||
|
||||
export enum R3ResolvedDependencyType {
|
||||
Token = 0,
|
||||
Attribute = 1,
|
||||
}
|
||||
|
||||
export interface R3DependencyMetadataFacade {
|
||||
token: any;
|
||||
resolved: R3ResolvedDependencyType;
|
||||
host: boolean;
|
||||
optional: boolean;
|
||||
self: boolean;
|
||||
skipSelf: boolean;
|
||||
}
|
||||
|
||||
export interface R3PipeMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
pipeName: string;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
pure: boolean;
|
||||
}
|
||||
|
||||
export interface R3InjectableMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
ctorDeps: R3DependencyMetadataFacade[]|null;
|
||||
providedIn: any;
|
||||
useClass?: any;
|
||||
useFactory?: any;
|
||||
useExisting?: any;
|
||||
useValue?: any;
|
||||
userDeps?: R3DependencyMetadataFacade[];
|
||||
}
|
||||
|
||||
export interface R3NgModuleMetadataFacade {
|
||||
type: any;
|
||||
bootstrap: Function[];
|
||||
declarations: Function[];
|
||||
imports: Function[];
|
||||
exports: Function[];
|
||||
emitInline: boolean;
|
||||
}
|
||||
|
||||
export interface R3InjectorMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
providers: any;
|
||||
imports: any;
|
||||
}
|
||||
|
||||
export interface R3DirectiveMetadataFacade {
|
||||
name: string;
|
||||
type: any;
|
||||
typeArgumentCount: number;
|
||||
typeSourceSpan: null;
|
||||
deps: R3DependencyMetadataFacade[]|null;
|
||||
selector: string|null;
|
||||
queries: R3QueryMetadataFacade[];
|
||||
host: {[key: string]: string};
|
||||
propMetadata: {[key: string]: any[]};
|
||||
lifecycle: {usesOnChanges: boolean;};
|
||||
inputs: string[];
|
||||
outputs: string[];
|
||||
usesInheritance: boolean;
|
||||
exportAs: string|null;
|
||||
providers: Provider[]|null;
|
||||
}
|
||||
|
||||
export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
|
||||
template: string;
|
||||
preserveWhitespaces: boolean;
|
||||
animations: any[]|undefined;
|
||||
viewQueries: R3QueryMetadataFacade[];
|
||||
pipes: Map<string, any>;
|
||||
directives: Map<string, any>;
|
||||
styles: string[];
|
||||
encapsulation: ViewEncapsulation;
|
||||
viewProviders: Provider[]|null;
|
||||
}
|
||||
|
||||
export type ViewEncapsulation = number;
|
||||
|
||||
export interface R3QueryMetadataFacade {
|
||||
propertyName: string;
|
||||
first: boolean;
|
||||
predicate: any|string[];
|
||||
descendants: boolean;
|
||||
read: any|null;
|
||||
}
|
|
@ -6,23 +6,22 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ConstantPool, Expression, R3DirectiveMetadata, R3QueryMetadata, WrappedNodeExpr, compileComponentFromMetadata as compileR3Component, compileDirectiveFromMetadata as compileR3Directive, jitExpression, makeBindingParser, parseHostBindings, parseTemplate} from '@angular/compiler';
|
||||
|
||||
import {Query} from '../../metadata/di';
|
||||
import {Component, Directive, HostBinding, HostListener, Input, Output} from '../../metadata/directives';
|
||||
import {Component, Directive} from '../../metadata/directives';
|
||||
import {componentNeedsResolution, maybeQueueResolutionOfComponentResources} from '../../metadata/resource_loading';
|
||||
import {ViewEncapsulation} from '../../metadata/view';
|
||||
import {Type} from '../../type';
|
||||
import {stringify} from '../../util';
|
||||
import {EMPTY_ARRAY} from '../definition';
|
||||
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF} from '../fields';
|
||||
|
||||
import {R3DirectiveMetadataFacade, getCompilerFacade} from './compiler_facade';
|
||||
import {R3ComponentMetadataFacade, R3QueryMetadataFacade} from './compiler_facade_interface';
|
||||
import {angularCoreEnv} from './environment';
|
||||
import {patchComponentDefWithScope, transitiveScopesFor} from './module';
|
||||
import {getReflect, reflectDependencies} from './util';
|
||||
|
||||
type StringMap = {
|
||||
[key: string]: string
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compile an Angular component according to its decorator metadata, and patch the resulting
|
||||
|
@ -39,6 +38,7 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
|||
maybeQueueResolutionOfComponentResources(metadata);
|
||||
Object.defineProperty(type, NG_COMPONENT_DEF, {
|
||||
get: () => {
|
||||
const compiler = getCompilerFacade();
|
||||
if (ngComponentDef === null) {
|
||||
if (componentNeedsResolution(metadata)) {
|
||||
const error = [`Component '${stringify(type)}' is not resolved:`];
|
||||
|
@ -51,43 +51,20 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
|||
error.push(`Did you run and wait for 'resolveComponentResources()'?`);
|
||||
throw new Error(error.join('\n'));
|
||||
}
|
||||
// The ConstantPool is a requirement of the JIT'er.
|
||||
const constantPool = new ConstantPool();
|
||||
|
||||
// Parse the template and check for errors.
|
||||
const template = parseTemplate(
|
||||
metadata.template !, `ng://${stringify(type)}/template.html`, {
|
||||
preserveWhitespaces: metadata.preserveWhitespaces || false,
|
||||
},
|
||||
'');
|
||||
if (template.errors !== undefined) {
|
||||
const errors = template.errors.map(err => err.toString()).join(', ');
|
||||
throw new Error(
|
||||
`Errors during JIT compilation of template for ${stringify(type)}: ${errors}`);
|
||||
}
|
||||
|
||||
const animations =
|
||||
metadata.animations !== null ? new WrappedNodeExpr(metadata.animations) : null;
|
||||
|
||||
// Compile the component metadata, including template, into an expression.
|
||||
const res = compileR3Component(
|
||||
{
|
||||
...directiveMetadata(type, metadata),
|
||||
template,
|
||||
directives: new Map(),
|
||||
pipes: new Map(),
|
||||
viewQueries: extractQueriesMetadata(getReflect().propMetadata(type), isViewQuery),
|
||||
wrapDirectivesAndPipesInClosure: false,
|
||||
styles: metadata.styles || [],
|
||||
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated, animations,
|
||||
viewProviders: metadata.viewProviders ? new WrappedNodeExpr(metadata.viewProviders) :
|
||||
null
|
||||
},
|
||||
constantPool, makeBindingParser());
|
||||
const preStatements = [...constantPool.statements, ...res.statements];
|
||||
|
||||
ngComponentDef = jitExpression(
|
||||
res.expression, angularCoreEnv, `ng://${type.name}/ngComponentDef.js`, preStatements);
|
||||
const meta: R3ComponentMetadataFacade = {
|
||||
...directiveMetadata(type, metadata),
|
||||
template: metadata.template || '',
|
||||
preserveWhitespaces: metadata.preserveWhitespaces || false,
|
||||
styles: metadata.styles || EMPTY_ARRAY,
|
||||
animations: metadata.animations,
|
||||
viewQueries: extractQueriesMetadata(getReflect().propMetadata(type), isViewQuery),
|
||||
directives: new Map(),
|
||||
pipes: new Map(),
|
||||
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
|
||||
viewProviders: metadata.viewProviders || null,
|
||||
};
|
||||
ngComponentDef = compiler.compileComponent(
|
||||
angularCoreEnv, `ng://${stringify(type)}/template.html`, meta);
|
||||
|
||||
// If component compilation is async, then the @NgModule annotation which declares the
|
||||
// component may execute and set an ngSelectorScope property on the component type. This
|
||||
|
@ -122,12 +99,9 @@ export function compileDirective(type: Type<any>, directive: Directive): void {
|
|||
Object.defineProperty(type, NG_DIRECTIVE_DEF, {
|
||||
get: () => {
|
||||
if (ngDirectiveDef === null) {
|
||||
const constantPool = new ConstantPool();
|
||||
const sourceMapUrl = `ng://${type && type.name}/ngDirectiveDef.js`;
|
||||
const res = compileR3Directive(
|
||||
directiveMetadata(type, directive), constantPool, makeBindingParser());
|
||||
const preStatements = [...constantPool.statements, ...res.statements];
|
||||
ngDirectiveDef = jitExpression(res.expression, angularCoreEnv, sourceMapUrl, preStatements);
|
||||
const facade = directiveMetadata(type, directive);
|
||||
ngDirectiveDef = getCompilerFacade().compileDirective(
|
||||
angularCoreEnv, `ng://${type && type.name}/ngDirectiveDef.js`, facade);
|
||||
}
|
||||
return ngDirectiveDef;
|
||||
},
|
||||
|
@ -144,38 +118,20 @@ export function extendsDirectlyFromObject(type: Type<any>): boolean {
|
|||
* Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
|
||||
* `Component`).
|
||||
*/
|
||||
function directiveMetadata(type: Type<any>, metadata: Directive): R3DirectiveMetadata {
|
||||
function directiveMetadata(type: Type<any>, metadata: Directive): R3DirectiveMetadataFacade {
|
||||
// Reflect inputs and outputs.
|
||||
const propMetadata = getReflect().propMetadata(type);
|
||||
|
||||
const host = extractHostBindings(metadata, propMetadata);
|
||||
|
||||
const inputsFromMetadata = parseInputOutputs(metadata.inputs || []);
|
||||
const outputsFromMetadata = parseInputOutputs(metadata.outputs || []);
|
||||
|
||||
const inputsFromType: {[key: string]: string | string[]} = {};
|
||||
const outputsFromType: StringMap = {};
|
||||
for (const field in propMetadata) {
|
||||
if (propMetadata.hasOwnProperty(field)) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
if (isInput(ann)) {
|
||||
inputsFromType[field] =
|
||||
ann.bindingPropertyName ? [ann.bindingPropertyName, field] : field;
|
||||
} else if (isOutput(ann)) {
|
||||
outputsFromType[field] = ann.bindingPropertyName || field;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: type.name,
|
||||
type: new WrappedNodeExpr(type),
|
||||
type: type,
|
||||
typeArgumentCount: 0,
|
||||
selector: metadata.selector !,
|
||||
deps: reflectDependencies(type), host,
|
||||
inputs: {...inputsFromMetadata, ...inputsFromType},
|
||||
outputs: {...outputsFromMetadata, ...outputsFromType},
|
||||
deps: reflectDependencies(type),
|
||||
host: metadata.host || EMPTY_OBJ,
|
||||
propMetadata: propMetadata,
|
||||
inputs: metadata.inputs || EMPTY_ARRAY,
|
||||
outputs: metadata.outputs || EMPTY_ARRAY,
|
||||
queries: extractQueriesMetadata(propMetadata, isContentQuery),
|
||||
lifecycle: {
|
||||
usesOnChanges: type.prototype.ngOnChanges !== undefined,
|
||||
|
@ -183,57 +139,29 @@ function directiveMetadata(type: Type<any>, metadata: Directive): R3DirectiveMet
|
|||
typeSourceSpan: null !,
|
||||
usesInheritance: !extendsDirectlyFromObject(type),
|
||||
exportAs: metadata.exportAs || null,
|
||||
providers: metadata.providers ? new WrappedNodeExpr(metadata.providers) : null
|
||||
providers: metadata.providers || null,
|
||||
};
|
||||
}
|
||||
|
||||
function extractHostBindings(metadata: Directive, propMetadata: {[key: string]: any[]}): {
|
||||
attributes: StringMap,
|
||||
listeners: StringMap,
|
||||
properties: StringMap,
|
||||
} {
|
||||
// First parse the declarations from the metadata.
|
||||
const {attributes, listeners, properties, animations} = parseHostBindings(metadata.host || {});
|
||||
const EMPTY_OBJ = {};
|
||||
|
||||
if (Object.keys(animations).length > 0) {
|
||||
throw new Error(`Animation bindings are as-of-yet unsupported in Ivy`);
|
||||
}
|
||||
|
||||
// Next, loop over the properties of the object, looking for @HostBinding and @HostListener.
|
||||
for (const field in propMetadata) {
|
||||
if (propMetadata.hasOwnProperty(field)) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
if (isHostBinding(ann)) {
|
||||
properties[ann.hostPropertyName || field] = field;
|
||||
} else if (isHostListener(ann)) {
|
||||
listeners[ann.eventName || field] = `${field}(${(ann.args || []).join(',')})`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {attributes, listeners, properties};
|
||||
function convertToR3QueryPredicate(selector: any): any|string[] {
|
||||
return typeof selector === 'string' ? splitByComma(selector) : selector;
|
||||
}
|
||||
|
||||
function convertToR3QueryPredicate(selector: any): Expression|string[] {
|
||||
return typeof selector === 'string' ? splitByComma(selector) : new WrappedNodeExpr(selector);
|
||||
}
|
||||
|
||||
export function convertToR3QueryMetadata(propertyName: string, ann: Query): R3QueryMetadata {
|
||||
export function convertToR3QueryMetadata(propertyName: string, ann: Query): R3QueryMetadataFacade {
|
||||
return {
|
||||
propertyName: propertyName,
|
||||
predicate: convertToR3QueryPredicate(ann.selector),
|
||||
descendants: ann.descendants,
|
||||
first: ann.first,
|
||||
read: ann.read ? new WrappedNodeExpr(ann.read) : null
|
||||
read: ann.read ? ann.read : null
|
||||
};
|
||||
}
|
||||
|
||||
function extractQueriesMetadata(
|
||||
propMetadata: {[key: string]: any[]},
|
||||
isQueryAnn: (ann: any) => ann is Query): R3QueryMetadata[] {
|
||||
const queriesMeta: R3QueryMetadata[] = [];
|
||||
|
||||
isQueryAnn: (ann: any) => ann is Query): R3QueryMetadataFacade[] {
|
||||
const queriesMeta: R3QueryMetadataFacade[] = [];
|
||||
for (const field in propMetadata) {
|
||||
if (propMetadata.hasOwnProperty(field)) {
|
||||
propMetadata[field].forEach(ann => {
|
||||
|
@ -243,26 +171,9 @@ function extractQueriesMetadata(
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
return queriesMeta;
|
||||
}
|
||||
|
||||
function isInput(value: any): value is Input {
|
||||
return value.ngMetadataName === 'Input';
|
||||
}
|
||||
|
||||
function isOutput(value: any): value is Output {
|
||||
return value.ngMetadataName === 'Output';
|
||||
}
|
||||
|
||||
function isHostBinding(value: any): value is HostBinding {
|
||||
return value.ngMetadataName === 'HostBinding';
|
||||
}
|
||||
|
||||
function isHostListener(value: any): value is HostListener {
|
||||
return value.ngMetadataName === 'HostListener';
|
||||
}
|
||||
|
||||
function isContentQuery(value: any): value is Query {
|
||||
const name = value.ngMetadataName;
|
||||
return name === 'ContentChild' || name === 'ContentChildren';
|
||||
|
@ -276,13 +187,3 @@ function isViewQuery(value: any): value is Query {
|
|||
function splitByComma(value: string): string[] {
|
||||
return value.split(',').map(piece => piece.trim());
|
||||
}
|
||||
|
||||
function parseInputOutputs(values: string[]): StringMap {
|
||||
return values.reduce(
|
||||
(map, value) => {
|
||||
const [field, property] = splitByComma(value);
|
||||
map[field] = property || field;
|
||||
return map;
|
||||
},
|
||||
{} as StringMap);
|
||||
}
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Expression, LiteralExpr, R3DependencyMetadata, R3InjectableMetadata, WrappedNodeExpr, compileInjectable as compileR3Injectable, jitExpression} from '@angular/compiler';
|
||||
|
||||
import {Injectable} from '../../di/injectable';
|
||||
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, StaticClassSansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
|
||||
import {ClassSansProvider, ExistingSansProvider, FactorySansProvider, ValueProvider, ValueSansProvider} from '../../di/provider';
|
||||
import {Type} from '../../type';
|
||||
import {getClosureSafeProperty} from '../../util/property';
|
||||
import {NG_INJECTABLE_DEF} from '../fields';
|
||||
|
||||
import {R3InjectableMetadataFacade, getCompilerFacade} from './compiler_facade';
|
||||
import {angularCoreEnv} from './environment';
|
||||
import {convertDependencies, reflectDependencies} from './util';
|
||||
|
||||
|
@ -31,84 +30,60 @@ export function compileInjectable(type: Type<any>, srcMeta?: Injectable): void {
|
|||
Object.defineProperty(type, NG_INJECTABLE_DEF, {
|
||||
get: () => {
|
||||
if (def === null) {
|
||||
// Check whether the injectable metadata includes a provider specification.
|
||||
const meta: Injectable = srcMeta || {providedIn: null};
|
||||
const hasAProvider = isUseClassProvider(meta) || isUseFactoryProvider(meta) ||
|
||||
isUseValueProvider(meta) || isUseExistingProvider(meta);
|
||||
|
||||
const ctorDeps = reflectDependencies(type);
|
||||
|
||||
let userDeps: R3DependencyMetadata[]|undefined = undefined;
|
||||
const compilerMeta: R3InjectableMetadataFacade = {
|
||||
name: type.name,
|
||||
type: type,
|
||||
providedIn: meta.providedIn,
|
||||
ctorDeps: reflectDependencies(type),
|
||||
userDeps: undefined
|
||||
};
|
||||
if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
|
||||
userDeps = convertDependencies(meta.deps);
|
||||
compilerMeta.userDeps = convertDependencies(meta.deps);
|
||||
}
|
||||
|
||||
// Decide which flavor of factory to generate, based on the provider specified.
|
||||
// Only one of the use* fields should be set.
|
||||
let useClass: Expression|undefined = undefined;
|
||||
let useFactory: Expression|undefined = undefined;
|
||||
let useValue: Expression|undefined = undefined;
|
||||
let useExisting: Expression|undefined = undefined;
|
||||
|
||||
if (!hasAProvider) {
|
||||
// In the case the user specifies a type provider, treat it as {provide: X, useClass: X}.
|
||||
// The deps will have been reflected above, causing the factory to create the class by
|
||||
// calling
|
||||
// its constructor with injected deps.
|
||||
useClass = new WrappedNodeExpr(type);
|
||||
compilerMeta.useClass = type;
|
||||
} else if (isUseClassProvider(meta)) {
|
||||
// The user explicitly specified useClass, and may or may not have provided deps.
|
||||
useClass = new WrappedNodeExpr(meta.useClass);
|
||||
compilerMeta.useClass = meta.useClass;
|
||||
} else if (isUseValueProvider(meta)) {
|
||||
// The user explicitly specified useValue.
|
||||
useValue = new WrappedNodeExpr(meta.useValue);
|
||||
compilerMeta.useValue = meta.useValue;
|
||||
} else if (isUseFactoryProvider(meta)) {
|
||||
// The user explicitly specified useFactory.
|
||||
useFactory = new WrappedNodeExpr(meta.useFactory);
|
||||
compilerMeta.useFactory = meta.useFactory;
|
||||
} else if (isUseExistingProvider(meta)) {
|
||||
// The user explicitly specified useExisting.
|
||||
useExisting = new WrappedNodeExpr(meta.useExisting);
|
||||
compilerMeta.useExisting = meta.useExisting;
|
||||
} else {
|
||||
// Can't happen - either hasAProvider will be false, or one of the providers will be set.
|
||||
throw new Error(`Unreachable state.`);
|
||||
}
|
||||
|
||||
const {expression, statements} = compileR3Injectable({
|
||||
name: type.name,
|
||||
type: new WrappedNodeExpr(type),
|
||||
providedIn: computeProvidedIn(meta.providedIn),
|
||||
useClass,
|
||||
useFactory,
|
||||
useValue,
|
||||
useExisting,
|
||||
ctorDeps,
|
||||
userDeps,
|
||||
});
|
||||
|
||||
def = jitExpression(
|
||||
expression, angularCoreEnv, `ng://${type.name}/ngInjectableDef.js`, statements);
|
||||
def = getCompilerFacade().compileInjectable(
|
||||
angularCoreEnv, `ng://${type.name}/ngInjectableDef.js`, compilerMeta);
|
||||
}
|
||||
return def;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function computeProvidedIn(providedIn: Type<any>| string | null | undefined): Expression {
|
||||
if (providedIn == null || typeof providedIn === 'string') {
|
||||
return new LiteralExpr(providedIn);
|
||||
} else {
|
||||
return new WrappedNodeExpr(providedIn);
|
||||
}
|
||||
}
|
||||
|
||||
type UseClassProvider = Injectable & ClassSansProvider & {deps?: any[]};
|
||||
|
||||
const USE_VALUE =
|
||||
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
|
||||
|
||||
function isUseClassProvider(meta: Injectable): meta is UseClassProvider {
|
||||
return (meta as UseClassProvider).useClass !== undefined;
|
||||
}
|
||||
|
||||
const USE_VALUE =
|
||||
getClosureSafeProperty<ValueProvider>({provide: String, useValue: getClosureSafeProperty});
|
||||
|
||||
function isUseValueProvider(meta: Injectable): meta is Injectable&ValueSansProvider {
|
||||
return USE_VALUE in meta;
|
||||
}
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Expression, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, WrappedNodeExpr, compileInjector, compileNgModule as compileR3NgModule, jitExpression} from '@angular/compiler';
|
||||
|
||||
import {ModuleWithProviders, NgModule, NgModuleDef, NgModuleTransitiveScopes} from '../../metadata/ng_module';
|
||||
import {Type} from '../../type';
|
||||
import {getComponentDef, getDirectiveDef, getNgModuleDef, getPipeDef} from '../definition';
|
||||
import {NG_COMPONENT_DEF, NG_DIRECTIVE_DEF, NG_INJECTOR_DEF, NG_MODULE_DEF, NG_PIPE_DEF} from '../fields';
|
||||
import {ComponentDef} from '../interfaces/definition';
|
||||
|
||||
import {R3InjectorMetadataFacade, getCompilerFacade} from './compiler_facade';
|
||||
import {angularCoreEnv} from './environment';
|
||||
import {reflectDependencies} from './util';
|
||||
|
||||
|
@ -37,48 +36,39 @@ export function compileNgModuleDefs(moduleType: Type<any>, ngModule: NgModule):
|
|||
|
||||
let ngModuleDef: any = null;
|
||||
Object.defineProperty(moduleType, NG_MODULE_DEF, {
|
||||
configurable: true,
|
||||
get: () => {
|
||||
if (ngModuleDef === null) {
|
||||
const meta: R3NgModuleMetadata = {
|
||||
type: wrap(moduleType),
|
||||
bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY).map(wrapReference),
|
||||
declarations: declarations.map(wrapReference),
|
||||
imports: flatten(ngModule.imports || EMPTY_ARRAY)
|
||||
.map(expandModuleWithProviders)
|
||||
.map(wrapReference),
|
||||
exports: flatten(ngModule.exports || EMPTY_ARRAY)
|
||||
.map(expandModuleWithProviders)
|
||||
.map(wrapReference),
|
||||
emitInline: true,
|
||||
};
|
||||
const res = compileR3NgModule(meta);
|
||||
ngModuleDef = jitExpression(
|
||||
res.expression, angularCoreEnv, `ng://${moduleType.name}/ngModuleDef.js`, []);
|
||||
ngModuleDef = getCompilerFacade().compileNgModule(
|
||||
angularCoreEnv, `ng://${moduleType.name}/ngModuleDef.js`, {
|
||||
type: moduleType,
|
||||
bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY),
|
||||
declarations: declarations,
|
||||
imports: flatten(ngModule.imports || EMPTY_ARRAY).map(expandModuleWithProviders),
|
||||
exports: flatten(ngModule.exports || EMPTY_ARRAY).map(expandModuleWithProviders),
|
||||
emitInline: true,
|
||||
});
|
||||
}
|
||||
return ngModuleDef;
|
||||
},
|
||||
// Make the property configurable in dev mode to allow overriding in tests
|
||||
configurable: !!ngDevMode,
|
||||
}
|
||||
});
|
||||
|
||||
let ngInjectorDef: any = null;
|
||||
Object.defineProperty(moduleType, NG_INJECTOR_DEF, {
|
||||
get: () => {
|
||||
if (ngInjectorDef === null) {
|
||||
const meta: R3InjectorMetadata = {
|
||||
const meta: R3InjectorMetadataFacade = {
|
||||
name: moduleType.name,
|
||||
type: wrap(moduleType),
|
||||
type: moduleType,
|
||||
deps: reflectDependencies(moduleType),
|
||||
providers: new WrappedNodeExpr(ngModule.providers || EMPTY_ARRAY),
|
||||
imports: new WrappedNodeExpr([
|
||||
providers: ngModule.providers || EMPTY_ARRAY,
|
||||
imports: [
|
||||
ngModule.imports || EMPTY_ARRAY,
|
||||
ngModule.exports || EMPTY_ARRAY,
|
||||
]),
|
||||
],
|
||||
};
|
||||
const res = compileInjector(meta);
|
||||
ngInjectorDef = jitExpression(
|
||||
res.expression, angularCoreEnv, `ng://${moduleType.name}/ngInjectorDef.js`,
|
||||
res.statements);
|
||||
ngInjectorDef = getCompilerFacade().compileInjector(
|
||||
angularCoreEnv, `ng://${moduleType.name}/ngInjectorDef.js`, meta);
|
||||
}
|
||||
return ngInjectorDef;
|
||||
},
|
||||
|
@ -235,15 +225,6 @@ function expandModuleWithProviders(value: Type<any>| ModuleWithProviders<{}>): T
|
|||
return value;
|
||||
}
|
||||
|
||||
function wrap(value: Type<any>): Expression {
|
||||
return new WrappedNodeExpr(value);
|
||||
}
|
||||
|
||||
function wrapReference(value: Type<any>): R3Reference {
|
||||
const wrapped = wrap(value);
|
||||
return {value: wrapped, type: wrapped};
|
||||
}
|
||||
|
||||
function isModuleWithProviders(value: any): value is ModuleWithProviders<{}> {
|
||||
return (value as{ngModule?: any}).ngModule !== undefined;
|
||||
}
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {WrappedNodeExpr, compilePipeFromMetadata, jitExpression} from '@angular/compiler';
|
||||
|
||||
import {Pipe} from '../../metadata/directives';
|
||||
import {Type} from '../../type';
|
||||
import {NG_PIPE_DEF} from '../fields';
|
||||
import {stringify} from '../util';
|
||||
|
||||
import {getCompilerFacade} from './compiler_facade';
|
||||
import {angularCoreEnv} from './environment';
|
||||
import {reflectDependencies} from './util';
|
||||
|
||||
|
@ -21,18 +20,14 @@ export function compilePipe(type: Type<any>, meta: Pipe): void {
|
|||
Object.defineProperty(type, NG_PIPE_DEF, {
|
||||
get: () => {
|
||||
if (ngPipeDef === null) {
|
||||
const sourceMapUrl = `ng://${stringify(type)}/ngPipeDef.js`;
|
||||
|
||||
const name = type.name;
|
||||
const res = compilePipeFromMetadata({
|
||||
name,
|
||||
type: new WrappedNodeExpr(type),
|
||||
deps: reflectDependencies(type),
|
||||
pipeName: meta.name,
|
||||
pure: meta.pure !== undefined ? meta.pure : true,
|
||||
});
|
||||
|
||||
ngPipeDef = jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
|
||||
ngPipeDef = getCompilerFacade().compilePipe(
|
||||
angularCoreEnv, `ng://${stringify(type)}/ngPipeDef.js`, {
|
||||
type: type,
|
||||
name: type.name,
|
||||
deps: reflectDependencies(type),
|
||||
pipeName: meta.name,
|
||||
pure: meta.pure !== undefined ? meta.pure : true
|
||||
});
|
||||
}
|
||||
return ngPipeDef;
|
||||
},
|
||||
|
|
|
@ -6,44 +6,41 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {LiteralExpr, R3DependencyMetadata, R3ResolvedDependencyType, WrappedNodeExpr} from '@angular/compiler';
|
||||
|
||||
import {Injector} from '../../di/injector';
|
||||
import {Host, Inject, Optional, Self, SkipSelf} from '../../di/metadata';
|
||||
import {ElementRef} from '../../linker/element_ref';
|
||||
import {TemplateRef} from '../../linker/template_ref';
|
||||
import {ViewContainerRef} from '../../linker/view_container_ref';
|
||||
import {Attribute} from '../../metadata/di';
|
||||
import {ReflectionCapabilities} from '../../reflection/reflection_capabilities';
|
||||
import {Type} from '../../type';
|
||||
|
||||
import {CompilerFacade, R3DependencyMetadataFacade, getCompilerFacade} from './compiler_facade';
|
||||
|
||||
let _reflect: ReflectionCapabilities|null = null;
|
||||
|
||||
export function getReflect(): ReflectionCapabilities {
|
||||
return (_reflect = _reflect || new ReflectionCapabilities());
|
||||
}
|
||||
|
||||
export function reflectDependencies(type: Type<any>): R3DependencyMetadata[] {
|
||||
export function reflectDependencies(type: Type<any>): R3DependencyMetadataFacade[] {
|
||||
return convertDependencies(getReflect().parameters(type));
|
||||
}
|
||||
|
||||
export function convertDependencies(deps: any[]): R3DependencyMetadata[] {
|
||||
return deps.map(dep => reflectDependency(dep));
|
||||
export function convertDependencies(deps: any[]): R3DependencyMetadataFacade[] {
|
||||
const compiler = getCompilerFacade();
|
||||
return deps.map(dep => reflectDependency(compiler, dep));
|
||||
}
|
||||
|
||||
function reflectDependency(dep: any | any[]): R3DependencyMetadata {
|
||||
const meta: R3DependencyMetadata = {
|
||||
token: new LiteralExpr(null),
|
||||
function reflectDependency(compiler: CompilerFacade, dep: any | any[]): R3DependencyMetadataFacade {
|
||||
const meta: R3DependencyMetadataFacade = {
|
||||
token: null,
|
||||
host: false,
|
||||
optional: false,
|
||||
resolved: R3ResolvedDependencyType.Token,
|
||||
resolved: compiler.R3ResolvedDependencyType.Token,
|
||||
self: false,
|
||||
skipSelf: false,
|
||||
};
|
||||
|
||||
function setTokenAndResolvedType(token: any): void {
|
||||
meta.resolved = R3ResolvedDependencyType.Token;
|
||||
meta.token = new WrappedNodeExpr(token);
|
||||
meta.resolved = compiler.R3ResolvedDependencyType.Token;
|
||||
meta.token = token;
|
||||
}
|
||||
|
||||
if (Array.isArray(dep)) {
|
||||
|
@ -61,13 +58,13 @@ function reflectDependency(dep: any | any[]): R3DependencyMetadata {
|
|||
} else if (param instanceof Host || param.__proto__.ngMetadataName === 'Host') {
|
||||
meta.host = true;
|
||||
} else if (param instanceof Inject) {
|
||||
meta.token = new WrappedNodeExpr(param.token);
|
||||
meta.token = param.token;
|
||||
} else if (param instanceof Attribute) {
|
||||
if (param.attributeName === undefined) {
|
||||
throw new Error(`Attribute name must be defined.`);
|
||||
}
|
||||
meta.token = new LiteralExpr(param.attributeName);
|
||||
meta.resolved = R3ResolvedDependencyType.Attribute;
|
||||
meta.token = param.attributeName;
|
||||
meta.resolved = compiler.R3ResolvedDependencyType.Attribute;
|
||||
} else {
|
||||
setTokenAndResolvedType(param);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
"name": "EMPTY_ARR"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
"name": "EMPTY_ARRAY"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_OBJ"
|
||||
|
@ -216,7 +216,7 @@
|
|||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
"name": "ViewEncapsulation"
|
||||
},
|
||||
{
|
||||
"name": "ViewRef"
|
||||
|
@ -396,7 +396,7 @@
|
|||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createOutput$1"
|
||||
"name": "createOutput"
|
||||
},
|
||||
{
|
||||
"name": "createRootComponent"
|
||||
|
@ -1122,10 +1122,10 @@
|
|||
"name": "storeCleanupWithContext"
|
||||
},
|
||||
{
|
||||
"name": "stringify$1"
|
||||
"name": "stringify"
|
||||
},
|
||||
{
|
||||
"name": "stringify$2"
|
||||
"name": "stringify$1"
|
||||
},
|
||||
{
|
||||
"name": "swapMultiContextEntries"
|
||||
|
|
|
@ -45,6 +45,7 @@ ts_library(
|
|||
],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/core/testing",
|
||||
"//packages/private/testing",
|
||||
],
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
"name": "EMPTY"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
"name": "EMPTY_ARRAY"
|
||||
},
|
||||
{
|
||||
"name": "EmptyErrorImpl"
|
||||
|
@ -117,7 +117,7 @@
|
|||
"name": "VIEWS"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
"name": "ViewEncapsulation"
|
||||
},
|
||||
{
|
||||
"name": "_renderCompCount"
|
||||
|
@ -438,7 +438,7 @@
|
|||
"name": "setUpAttributes"
|
||||
},
|
||||
{
|
||||
"name": "stringify$2"
|
||||
"name": "stringify$1"
|
||||
},
|
||||
{
|
||||
"name": "syncViewWithBlueprint"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '@angular/compiler';
|
||||
import {withBody} from '@angular/private/testing';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
|
|
@ -47,6 +47,7 @@ ts_library(
|
|||
],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/core/testing",
|
||||
"//packages/private/testing",
|
||||
],
|
||||
|
|
|
@ -240,7 +240,7 @@
|
|||
"name": "BINDING_INDEX"
|
||||
},
|
||||
{
|
||||
"name": "BIND_NAME_REGEXP"
|
||||
"name": "BIND_NAME_REGEXP$1"
|
||||
},
|
||||
{
|
||||
"name": "BLOCK_PLACEHOLDER"
|
||||
|
@ -813,16 +813,16 @@
|
|||
"name": "IDENT"
|
||||
},
|
||||
{
|
||||
"name": "IDENT_BANANA_BOX_IDX"
|
||||
"name": "IDENT_BANANA_BOX_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "IDENT_EVENT_IDX"
|
||||
"name": "IDENT_EVENT_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "IDENT_KW_IDX"
|
||||
"name": "IDENT_KW_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "IDENT_PROPERTY_IDX"
|
||||
"name": "IDENT_PROPERTY_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "ID_SEPARATOR"
|
||||
|
@ -939,22 +939,22 @@
|
|||
"name": "KEY_CONTEXT"
|
||||
},
|
||||
{
|
||||
"name": "KW_AT_IDX"
|
||||
"name": "KW_AT_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KW_BINDON_IDX"
|
||||
"name": "KW_BINDON_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KW_BIND_IDX"
|
||||
"name": "KW_BIND_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KW_LET_IDX"
|
||||
"name": "KW_LET_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KW_ON_IDX"
|
||||
"name": "KW_ON_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KW_REF_IDX"
|
||||
"name": "KW_REF_IDX$1"
|
||||
},
|
||||
{
|
||||
"name": "KeyVisitor"
|
||||
|
@ -1116,7 +1116,7 @@
|
|||
"name": "NG_TOKEN_PATH"
|
||||
},
|
||||
{
|
||||
"name": "NON_BINDABLE_VISITOR"
|
||||
"name": "NON_BINDABLE_VISITOR$1"
|
||||
},
|
||||
{
|
||||
"name": "NOOP"
|
||||
|
@ -1209,7 +1209,7 @@
|
|||
"name": "NodeInjectorFactory"
|
||||
},
|
||||
{
|
||||
"name": "NonBindableVisitor"
|
||||
"name": "NonBindableVisitor$1"
|
||||
},
|
||||
{
|
||||
"name": "NonNullAssert"
|
||||
|
@ -1410,7 +1410,7 @@
|
|||
"name": "RecurseVisitor"
|
||||
},
|
||||
{
|
||||
"name": "RecursiveAstVisitor"
|
||||
"name": "RecursiveAstVisitor$1"
|
||||
},
|
||||
{
|
||||
"name": "RefCountOperator"
|
||||
|
@ -1629,7 +1629,7 @@
|
|||
"name": "TAIL"
|
||||
},
|
||||
{
|
||||
"name": "TEMPLATE_ATTR_PREFIX"
|
||||
"name": "TEMPLATE_ATTR_PREFIX$1"
|
||||
},
|
||||
{
|
||||
"name": "TEXT_CSS_SELECTOR"
|
||||
|
@ -1704,10 +1704,10 @@
|
|||
"name": "Text"
|
||||
},
|
||||
{
|
||||
"name": "Text$1"
|
||||
"name": "Text$2"
|
||||
},
|
||||
{
|
||||
"name": "Text$2"
|
||||
"name": "Text$3"
|
||||
},
|
||||
{
|
||||
"name": "TextAst"
|
||||
|
@ -1770,7 +1770,7 @@
|
|||
"name": "URL_WITH_SCHEMA_REGEXP"
|
||||
},
|
||||
{
|
||||
"name": "USE_VALUE$1"
|
||||
"name": "USE_VALUE$2"
|
||||
},
|
||||
{
|
||||
"name": "UnsubscriptionError"
|
||||
|
@ -1782,7 +1782,7 @@
|
|||
"name": "UrlResolver"
|
||||
},
|
||||
{
|
||||
"name": "VERSION$1"
|
||||
"name": "VERSION"
|
||||
},
|
||||
{
|
||||
"name": "VERSION$2"
|
||||
|
@ -2151,7 +2151,7 @@
|
|||
"name": "__read"
|
||||
},
|
||||
{
|
||||
"name": "__self"
|
||||
"name": "__self$1"
|
||||
},
|
||||
{
|
||||
"name": "__spread"
|
||||
|
@ -2163,7 +2163,7 @@
|
|||
"name": "__values"
|
||||
},
|
||||
{
|
||||
"name": "__window"
|
||||
"name": "__window$1"
|
||||
},
|
||||
{
|
||||
"name": "_addDebugContext"
|
||||
|
@ -2283,7 +2283,7 @@
|
|||
"name": "_getViewQueries"
|
||||
},
|
||||
{
|
||||
"name": "_global"
|
||||
"name": "_global$1"
|
||||
},
|
||||
{
|
||||
"name": "_isClosingComment"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '@angular/compiler';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ ts_library(
|
|||
deps = [
|
||||
":injection",
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/core/testing",
|
||||
"//packages/private/testing",
|
||||
],
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"name": "CIRCULAR$1"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$2"
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
},
|
||||
{
|
||||
"name": "EmptyErrorImpl"
|
||||
|
@ -60,7 +60,7 @@
|
|||
"name": "THROW_IF_NOT_FOUND"
|
||||
},
|
||||
{
|
||||
"name": "USE_VALUE$1"
|
||||
"name": "USE_VALUE"
|
||||
},
|
||||
{
|
||||
"name": "UnsubscriptionErrorImpl"
|
||||
|
@ -159,12 +159,12 @@
|
|||
"name": "providerToRecord"
|
||||
},
|
||||
{
|
||||
"name": "resolveForwardRef$1"
|
||||
"name": "resolveForwardRef"
|
||||
},
|
||||
{
|
||||
"name": "setCurrentInjector"
|
||||
},
|
||||
{
|
||||
"name": "stringify$1"
|
||||
"name": "stringify"
|
||||
}
|
||||
]
|
|
@ -6,15 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import '@angular/compiler';
|
||||
import {INJECTOR, ScopedService} from './usage';
|
||||
|
||||
const UTF8 = {
|
||||
encoding: 'utf-8'
|
||||
};
|
||||
const PACKAGE = 'angular/packages/core/test/bundling/hello_world';
|
||||
|
||||
describe('functional test for injection system bundling', () => {
|
||||
it('should be able to inject the scoped service',
|
||||
|
|
|
@ -50,6 +50,7 @@ ts_library(
|
|||
],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/core",
|
||||
"//packages/core/testing",
|
||||
"//packages/private/testing",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
"name": "EMPTY"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
"name": "EMPTY_ARRAY"
|
||||
},
|
||||
{
|
||||
"name": "ElementRef"
|
||||
|
@ -231,7 +231,7 @@
|
|||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
"name": "ViewEncapsulation"
|
||||
},
|
||||
{
|
||||
"name": "ViewRef"
|
||||
|
@ -453,7 +453,7 @@
|
|||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createOutput$1"
|
||||
"name": "createOutput"
|
||||
},
|
||||
{
|
||||
"name": "createRootComponent"
|
||||
|
@ -1143,10 +1143,10 @@
|
|||
"name": "storeCleanupWithContext"
|
||||
},
|
||||
{
|
||||
"name": "stringify$1"
|
||||
"name": "stringify"
|
||||
},
|
||||
{
|
||||
"name": "stringify$2"
|
||||
"name": "stringify$1"
|
||||
},
|
||||
{
|
||||
"name": "syncViewWithBlueprint"
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '@angular/compiler';
|
||||
import {ɵwhenRendered as whenRendered} from '@angular/core';
|
||||
import {withBody} from '@angular/private/testing';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const UTF8 = {
|
||||
|
|
|
@ -54,6 +54,7 @@ ts_library(
|
|||
],
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/core",
|
||||
"//packages/core/testing",
|
||||
"//packages/platform-browser",
|
||||
|
|
|
@ -99,13 +99,13 @@
|
|||
"name": "COMPONENT_REGEX"
|
||||
},
|
||||
{
|
||||
"name": "COMPONENT_VARIABLE$1"
|
||||
"name": "COMPONENT_VARIABLE"
|
||||
},
|
||||
{
|
||||
"name": "CONTAINER_INDEX"
|
||||
},
|
||||
{
|
||||
"name": "CONTENT_ATTR$1"
|
||||
"name": "CONTENT_ATTR"
|
||||
},
|
||||
{
|
||||
"name": "CONTEXT"
|
||||
|
@ -252,10 +252,10 @@
|
|||
"name": "EMPTY$1"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
"name": "EMPTY_ARRAY"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_ARRAY$2"
|
||||
"name": "EMPTY_ARRAY$1"
|
||||
},
|
||||
{
|
||||
"name": "EMPTY_PAYLOAD"
|
||||
|
@ -330,7 +330,7 @@
|
|||
"name": "HOST"
|
||||
},
|
||||
{
|
||||
"name": "HOST_ATTR$1"
|
||||
"name": "HOST_ATTR"
|
||||
},
|
||||
{
|
||||
"name": "HOST_NODE"
|
||||
|
@ -792,7 +792,7 @@
|
|||
"name": "SanitizingHtmlSerializer"
|
||||
},
|
||||
{
|
||||
"name": "SecurityContext$1"
|
||||
"name": "SecurityContext"
|
||||
},
|
||||
{
|
||||
"name": "Self"
|
||||
|
@ -906,7 +906,7 @@
|
|||
"name": "URL_RE"
|
||||
},
|
||||
{
|
||||
"name": "USE_VALUE$1"
|
||||
"name": "USE_VALUE"
|
||||
},
|
||||
{
|
||||
"name": "UnsubscriptionError"
|
||||
|
@ -930,13 +930,13 @@
|
|||
"name": "VOID_ELEMENTS"
|
||||
},
|
||||
{
|
||||
"name": "Version$1"
|
||||
"name": "Version"
|
||||
},
|
||||
{
|
||||
"name": "ViewContainerRef"
|
||||
},
|
||||
{
|
||||
"name": "ViewEncapsulation$1"
|
||||
"name": "ViewEncapsulation"
|
||||
},
|
||||
{
|
||||
"name": "ViewRef"
|
||||
|
@ -1341,7 +1341,7 @@
|
|||
"name": "createNodeAtIndex"
|
||||
},
|
||||
{
|
||||
"name": "createOutput$1"
|
||||
"name": "createOutput"
|
||||
},
|
||||
{
|
||||
"name": "createPlatform"
|
||||
|
@ -2118,10 +2118,10 @@
|
|||
"name": "isProceduralRenderer"
|
||||
},
|
||||
{
|
||||
"name": "isPromise$1"
|
||||
"name": "isPromise"
|
||||
},
|
||||
{
|
||||
"name": "isPromise$2"
|
||||
"name": "isPromise$1"
|
||||
},
|
||||
{
|
||||
"name": "isRootView"
|
||||
|
@ -2244,10 +2244,10 @@
|
|||
"name": "noSideEffects"
|
||||
},
|
||||
{
|
||||
"name": "noop$2"
|
||||
"name": "noop$1"
|
||||
},
|
||||
{
|
||||
"name": "noop$3"
|
||||
"name": "noop$2"
|
||||
},
|
||||
{
|
||||
"name": "noopScope"
|
||||
|
@ -2274,7 +2274,7 @@
|
|||
"name": "parseCookieValue"
|
||||
},
|
||||
{
|
||||
"name": "parseIntAutoRadix$1"
|
||||
"name": "parseIntAutoRadix"
|
||||
},
|
||||
{
|
||||
"name": "parseNumber"
|
||||
|
@ -2400,7 +2400,7 @@
|
|||
"name": "resolveDirectives"
|
||||
},
|
||||
{
|
||||
"name": "resolveForwardRef$1"
|
||||
"name": "resolveForwardRef"
|
||||
},
|
||||
{
|
||||
"name": "resolveProvider"
|
||||
|
@ -2550,10 +2550,10 @@
|
|||
"name": "strToNumber"
|
||||
},
|
||||
{
|
||||
"name": "stringify$1"
|
||||
"name": "stringify"
|
||||
},
|
||||
{
|
||||
"name": "stringify$2"
|
||||
"name": "stringify$1"
|
||||
},
|
||||
{
|
||||
"name": "subscribeTo"
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '@angular/compiler';
|
||||
import {ɵwhenRendered as whenRendered} from '@angular/core';
|
||||
import {withBody} from '@angular/private/testing';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const UTF8 = {
|
||||
|
|
|
@ -38,6 +38,7 @@ ts_library(
|
|||
"load_domino.ts",
|
||||
],
|
||||
deps = [
|
||||
"//packages/compiler",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-server",
|
||||
"@ngdeps//zone.js",
|
||||
|
|
|
@ -1,138 +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, ContentChild, Directive, Injectable, Injector, Input, NgModule, NgModuleFactory, NgModuleRef, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjector} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
|
||||
const details_elided = {
|
||||
type: Object,
|
||||
} as any;
|
||||
export type $ComponentDef$ = any;
|
||||
|
||||
///////////
|
||||
// Lib A - Compiled pre-Ivy
|
||||
// "enableIvy": false
|
||||
//////////
|
||||
|
||||
// BEGIN FILE: node_modules/libA/module.ts (Compiled without Ivy)
|
||||
@Component({})
|
||||
export class LibAComponent {
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class LibAModule {
|
||||
}
|
||||
// END FILE: node_modules/libA/module.ts
|
||||
// BEGIN FILE: node_modules/libA/module.metadata.json
|
||||
// Abridged version of metadata
|
||||
const node_modules_libA_module_metadata = {
|
||||
'LibAModule': {
|
||||
refs: ['LibAComponent'],
|
||||
constructorDes: [],
|
||||
},
|
||||
'LibAComponent': {
|
||||
constructorDes: [],
|
||||
}
|
||||
};
|
||||
// END FILE: node_modules/libA/module.metadata.json
|
||||
|
||||
|
||||
///////////
|
||||
// Lib B - Compiled with Ivy
|
||||
// "enableIvy": true
|
||||
//////////
|
||||
|
||||
|
||||
// BEGIN FILE: node_modules/libB/module.ts (Compiled with Ivy)
|
||||
@Component({})
|
||||
export class LibBComponent {
|
||||
// COMPILER GENERATED
|
||||
static ngComponentDef: $ComponentDef$ = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class LibBModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: node_modules/libB/module.ts
|
||||
// BEGIN FILE: node_modules/libB/module.metadata.json
|
||||
// Abridged version of metadata
|
||||
// Must still generate metadata in case it should be consumed with non-ivy application
|
||||
// Must mark the metadata with `hasNgDef: true` so that Ivy knows to ignore it.
|
||||
const node_modules_libB_module_metadata = {
|
||||
'LibBModule': {refs: ['LibBComponent'], constructorDes: [], hasNgDef: true},
|
||||
'LibBComponent': {constructorDes: [], hasNgDef: true}
|
||||
};
|
||||
// END FILE: node_modules/libA/module.metadata.json
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Lib B - Compiled with Ivy
|
||||
// "enableIvy": true
|
||||
// "enableIvyBackPatch": true
|
||||
//////////
|
||||
|
||||
|
||||
// BEGIN FILE: src/app.ts (Compiled with Ivy)
|
||||
@Component({})
|
||||
export class AppComponent {
|
||||
// COMPILER GENERATED
|
||||
static ngComponentDef: $ComponentDef$ = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
@NgModule({declarations: [LibAComponent], imports: []})
|
||||
export class AppModule {
|
||||
// COMPILER GENERATED
|
||||
static ngInjectorDef = defineInjector(details_elided);
|
||||
}
|
||||
// END FILE: src/app.ts
|
||||
|
||||
// BEGIN FILE: src/main.ts
|
||||
// platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// CLI rewrites it later to:
|
||||
// platformBrowser().bootstrapModuleFactory(AppModuleFactory);
|
||||
// END FILE: src/main.ts
|
||||
|
||||
// BEGIN FILE: src/app.ngfactory.ts
|
||||
function ngBackPatch_node_modules_libB_module() {
|
||||
ngBackPatch_node_modules_libB_module_LibAComponent();
|
||||
ngBackPatch_node_modules_libB_module_LibAModule();
|
||||
}
|
||||
|
||||
function ngBackPatch_node_modules_libB_module_LibAComponent() {
|
||||
(LibAComponent as any).ngComponentDef = r3.defineComponent(details_elided);
|
||||
}
|
||||
|
||||
function ngBackPatch_node_modules_libB_module_LibAModule() {
|
||||
(LibAModule as any).ngInjectorDef = defineInjector(details_elided);
|
||||
}
|
||||
|
||||
export const AppModuleFactory: NgModuleFactory<AppModule>&{patchedDeps: boolean} = {
|
||||
moduleType: AppModule,
|
||||
patchedDeps: false, create(parentInjector: Injector | null): NgModuleRef<AppModule>{
|
||||
if (!this.patchedDeps) {
|
||||
ngBackPatch_node_modules_libB_module();
|
||||
this.patchedDeps = true;
|
||||
} return details_elided;
|
||||
}
|
||||
};
|
||||
// BEGIN FILE: src/app.ngfactory.ts
|
||||
|
||||
|
||||
// ISSUE: I don't think this works. The issue is that multiple modules get flattened into single
|
||||
// module and hence we can't patch transitively.
|
||||
// ISSUE: can non-ivy @NgModule import Ivy @NgModule? I assume no, since the flattening of modules
|
||||
// happens during compilation.
|
||||
|
||||
// BEGIN FILE: src/main.ts
|
||||
// platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// CLI rewrites it to:
|
||||
// platformBrowser().bootstrapModuleFactory(AppModuleFactory);
|
||||
// END FILE: src/main.ts
|
|
@ -1,78 +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, ContentChild, Directive, Injectable, Input, NgModule, OnDestroy, Optional, Pipe, PipeTransform, QueryList, SimpleChanges, TemplateRef, Type, ViewChild, ViewContainerRef, defineInjectable, defineInjector} from '../../../src/core';
|
||||
import * as r3 from '../../../src/render3/index';
|
||||
|
||||
|
||||
/**
|
||||
* GOALS:
|
||||
* - Patch types in tree shakable way
|
||||
* - Generate these types for files which have `metadata.json` (since those are the files which
|
||||
* have not been compiled with Ivy)
|
||||
* - Have build optimizer hoist the patch functions into corresponding types to allow tree-shaking.
|
||||
*/
|
||||
|
||||
// File: node_modules/some_library/path/public.ts
|
||||
// Implies metadata: node_modules/some_library/path/public.metadata.json
|
||||
// Assume: node_modules/some_library/index.js re-exports ./path/public.ts#ThirdPartyClass
|
||||
@Injectable()
|
||||
class ThirdPartyClass {
|
||||
}
|
||||
|
||||
|
||||
@Injectable()
|
||||
class CompiledWithIvy {
|
||||
// NORMATIVE
|
||||
static ngInjectableDef = defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new CompiledWithIvy(); }});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
// import { CompiledWithIvy } from 'some_library';
|
||||
@NgModule({providers: [ThirdPartyClass, CompiledWithIvy]})
|
||||
class CompiledWithIvyModule {
|
||||
// NORMATIVE
|
||||
static ngInjectorDef = defineInjector({
|
||||
providers: [ThirdPartyClass, CompiledWithIvy],
|
||||
factory: function CompiledWithIvyModule_Factory() { return new CompiledWithIvyModule(); }
|
||||
});
|
||||
// /NORMATIVE
|
||||
}
|
||||
|
||||
/**
|
||||
* Below is a function which should be generated right next to the `@NgModule` which
|
||||
* imports types which have `.metadata.json` files.
|
||||
*
|
||||
* # JIT Mode
|
||||
* - Because the `ngPatch_CompiledWithIvyModule` is invoked all parts get patched.
|
||||
*
|
||||
* # AOT Mode
|
||||
* - Build Optimizer detects `@__BUILD_OPTIMIZER_COLOCATE__` annotation and moves the
|
||||
* code from the current location to the destination.
|
||||
* - The resulting `ngPatch_CompiledWithIvyModule` becomes empty and eligible for tree-shaking.
|
||||
* - Uglify removes the `ngPatch_CompiledWithIvyModule` since it is empty.
|
||||
*
|
||||
* # AOT Closure Mode
|
||||
* - Option A: not supported. (Preferred option)
|
||||
* - Externally very few people use closure they will just have to wait until all of their
|
||||
* libraries are Ivy.
|
||||
* - Internally (g3) we build from source hence everyone switches to Ivy at the same time.
|
||||
* - Option B: Write a closure pass similar to Build Optimizer which would move the code.
|
||||
*/
|
||||
// NORMATIVE
|
||||
ngPatch_depsOf_CompiledWithIvyModule();
|
||||
function ngPatch_depsOf_CompiledWithIvyModule() {
|
||||
ngPatch_node_modules_some_library_path_public_CompileWithIvy();
|
||||
}
|
||||
function ngPatch_node_modules_some_library_path_public_CompileWithIvy() {
|
||||
/** @__BUILD_OPTIMIZER_COLOCATE__ */
|
||||
(ThirdPartyClass as any).ngInjectableDef = defineInjectable(
|
||||
{factory: function CompileWithIvy_Factory() { return new ThirdPartyClass(); }});
|
||||
}
|
||||
// /NORMATIVE
|
|
@ -109,7 +109,7 @@ class ToDoAppComponent {
|
|||
selector: 'todo',
|
||||
template: `
|
||||
<div [class.done]="todo.done">
|
||||
<input type="checkbox" [value]="todo.done" (click)="onCheckboxClick()"></input>
|
||||
<input type="checkbox" [value]="todo.done" (click)="onCheckboxClick()">
|
||||
<span>{{todo.text}}</span>
|
||||
<button (click)="onArchiveClick()">archive</button>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
* 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 'reflect-metadata';
|
||||
|
||||
import {ElementRef, QueryList} from '@angular/core';
|
||||
|
|
|
@ -88,8 +88,8 @@ describe('jit directive helper functions', () => {
|
|||
read: Directive
|
||||
});
|
||||
|
||||
expect(converted.predicate).toEqual(jasmine.any(WrappedNodeExpr));
|
||||
expect(converted.read).toEqual(jasmine.any(WrappedNodeExpr));
|
||||
expect(converted.predicate).toEqual(Directive);
|
||||
expect(converted.read).toEqual(Directive);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// Needed to run animation tests
|
||||
require('zone.js/dist/zone-node.js');
|
||||
|
||||
import '@angular/compiler'; // For JIT mode. Must be in front of any other @angular/* imports.
|
||||
import {DominoAdapter} from '@angular/platform-server/src/domino_adapter';
|
||||
import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter';
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ ts_library(
|
|||
testonly = 1,
|
||||
srcs = ["init_browser_spec.ts"],
|
||||
deps = [
|
||||
"//packages/compiler",
|
||||
"//packages/core/testing",
|
||||
"//packages/platform-browser-dynamic/testing",
|
||||
"//packages/platform-browser/animations",
|
||||
|
@ -18,6 +19,7 @@ ts_library(
|
|||
testonly = 1,
|
||||
srcs = ["init_node_spec.ts"],
|
||||
deps = [
|
||||
"//packages/compiler",
|
||||
"//packages/core/testing",
|
||||
"//packages/platform-server",
|
||||
"//packages/platform-server/testing",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import '@angular/compiler'; // For JIT mode. Must be in front of any other @angular/* imports.
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from '@angular/platform-browser-dynamic/testing';
|
||||
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
|
||||
|
|
|
@ -36,6 +36,7 @@ import 'zone.js/dist/jasmine-patch.js';
|
|||
(global as any).isNode = true;
|
||||
(global as any).isBrowser = false;
|
||||
|
||||
import '@angular/compiler'; // For JIT mode. Must be in front of any other @angular/* imports.
|
||||
// Init TestBed
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {ServerTestingModule, platformServerTesting} from '@angular/platform-server/testing/src/server';
|
||||
|
|
Loading…
Reference in New Issue