Skip to content

Commit b0a03fc

Browse files
tboschalxhub
authored andcommitted
refactor(compiler): introduce directive wrappers to generate less code
- for now only wraps the `@Input` properties and calls to `ngOnInit`, `ngDoCheck` and `ngOnChanges` of directives. - also groups eval sources by NgModule. Part of angular#11683
1 parent c951822 commit b0a03fc

23 files changed

+605
-277
lines changed

Diff for: modules/@angular/compiler-cli/src/codegen.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Intended to be used in a build step.
1212
*/
1313
import * as compiler from '@angular/compiler';
14-
import {Component, NgModule, ViewEncapsulation} from '@angular/core';
14+
import {Directive, NgModule, ViewEncapsulation} from '@angular/core';
1515
import {AngularCompilerOptions, NgcCliOptions} from '@angular/tsc-wrapped';
1616
import * as path from 'path';
1717
import * as ts from 'typescript';
@@ -58,7 +58,7 @@ export class CodeGeneratorModuleCollector {
5858

5959
private readFileMetadata(absSourcePath: string): FileMetadata {
6060
const moduleMetadata = this.staticReflector.getModuleMetadata(absSourcePath);
61-
const result: FileMetadata = {components: [], ngModules: [], fileUrl: absSourcePath};
61+
const result: FileMetadata = {directives: [], ngModules: [], fileUrl: absSourcePath};
6262
if (!moduleMetadata) {
6363
console.log(`WARNING: no metadata found for ${absSourcePath}`);
6464
return result;
@@ -78,8 +78,8 @@ export class CodeGeneratorModuleCollector {
7878
annotations.forEach((annotation) => {
7979
if (annotation instanceof NgModule) {
8080
result.ngModules.push(staticType);
81-
} else if (annotation instanceof Component) {
82-
result.components.push(staticType);
81+
} else if (annotation instanceof Directive) {
82+
result.directives.push(staticType);
8383
}
8484
});
8585
}
@@ -127,7 +127,7 @@ export class CodeGenerator {
127127
(fileMeta) =>
128128
this.compiler
129129
.compile(
130-
fileMeta.fileUrl, analyzedNgModules, fileMeta.components, fileMeta.ngModules)
130+
fileMeta.fileUrl, analyzedNgModules, fileMeta.directives, fileMeta.ngModules)
131131
.then((generatedModules) => {
132132
generatedModules.forEach((generatedModule) => {
133133
const sourceFile = this.program.getSourceFile(fileMeta.fileUrl);
@@ -193,8 +193,9 @@ export class CodeGenerator {
193193
// TODO(vicb): do not pass cliOptions.i18nFormat here
194194
const offlineCompiler = new compiler.OfflineCompiler(
195195
resolver, normalizer, tmplParser, new compiler.StyleCompiler(urlResolver),
196-
new compiler.ViewCompiler(config), new compiler.NgModuleCompiler(),
197-
new compiler.TypeScriptEmitter(reflectorHost), cliOptions.locale, cliOptions.i18nFormat);
196+
new compiler.ViewCompiler(config), new compiler.DirectiveWrapperCompiler(config),
197+
new compiler.NgModuleCompiler(), new compiler.TypeScriptEmitter(reflectorHost),
198+
cliOptions.locale, cliOptions.i18nFormat);
198199

199200
return new CodeGenerator(
200201
options, program, compilerHost, staticReflector, offlineCompiler, reflectorHost);
@@ -203,6 +204,6 @@ export class CodeGenerator {
203204

204205
export interface FileMetadata {
205206
fileUrl: string;
206-
components: StaticSymbol[];
207+
directives: StaticSymbol[];
207208
ngModules: StaticSymbol[];
208209
}

Diff for: modules/@angular/compiler-cli/src/extract_i18n.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export class Extractor {
113113
const url = fileMeta.fileUrl;
114114
return Promise.all(fileMeta.components.map(compType => {
115115
const compMeta = this.metadataResolver.getDirectiveMetadata(<any>compType);
116-
const ngModule = analyzedNgModules.ngModuleByComponent.get(compType);
116+
const ngModule = analyzedNgModules.ngModuleByDirective.get(compType);
117117
if (!ngModule) {
118118
throw new Error(
119119
`Cannot determine the module for component ${compMeta.type.name}!`);

Diff for: modules/@angular/compiler/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export * from './src/metadata_resolver';
4444
export * from './src/ml_parser/html_parser';
4545
export * from './src/ml_parser/interpolation_config';
4646
export {NgModuleCompiler} from './src/ng_module_compiler';
47+
export {DirectiveWrapperCompiler} from './src/directive_wrapper_compiler';
4748
export * from './src/output/path_util';
4849
export * from './src/output/ts_emitter';
4950
export * from './src/parse_util';

Diff for: modules/@angular/compiler/src/compiler.ts

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {COMPILER_OPTIONS, Compiler, CompilerFactory, CompilerOptions, Inject, In
1111
import {CompilerConfig} from './config';
1212
import {DirectiveNormalizer} from './directive_normalizer';
1313
import {DirectiveResolver} from './directive_resolver';
14+
import {DirectiveWrapperCompiler} from './directive_wrapper_compiler';
1415
import {Lexer} from './expression_parser/lexer';
1516
import {Parser} from './expression_parser/parser';
1617
import * as i18n from './i18n/index';
@@ -64,6 +65,7 @@ export const COMPILER_PROVIDERS: Array<any|Type<any>|{[k: string]: any}|any[]> =
6465
StyleCompiler,
6566
ViewCompiler,
6667
NgModuleCompiler,
68+
DirectiveWrapperCompiler,
6769
{provide: CompilerConfig, useValue: new CompilerConfig()},
6870
RuntimeCompiler,
6971
{provide: Compiler, useExisting: RuntimeCompiler},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {Injectable} from '@angular/core';
10+
11+
import {CompileDirectiveMetadata, CompileIdentifierMetadata} from './compile_metadata';
12+
import {CompilerConfig} from './config';
13+
import {Identifiers, resolveIdentifier} from './identifiers';
14+
import * as o from './output/output_ast';
15+
import {LifecycleHooks, isDefaultChangeDetectionStrategy} from './private_import_core';
16+
17+
export class DirectiveWrapperCompileResult {
18+
constructor(public statements: o.Statement[], public dirWrapperClassVar: string) {}
19+
}
20+
21+
const CONTEXT_FIELD_NAME = 'context';
22+
const CHANGES_FIELD_NAME = 'changes';
23+
const CHANGED_FIELD_NAME = 'changed';
24+
25+
const CURR_VALUE_VAR = o.variable('currValue');
26+
const THROW_ON_CHANGE_VAR = o.variable('throwOnChange');
27+
const FORCE_UPDATE_VAR = o.variable('forceUpdate');
28+
const VIEW_VAR = o.variable('view');
29+
const RENDER_EL_VAR = o.variable('el');
30+
31+
const RESET_CHANGES_STMT = o.THIS_EXPR.prop(CHANGES_FIELD_NAME).set(o.literalMap([])).toStmt();
32+
33+
/**
34+
* We generate directive wrappers to prevent code bloat when a directive is used.
35+
* A directive wrapper encapsulates
36+
* the dirty checking for `@Input`, the handling of `@HostListener` / `@HostBinding`
37+
* and calling the lifecyclehooks `ngOnInit`, `ngOnChanges`, `ngDoCheck`.
38+
*
39+
* So far, only `@Input` and the lifecycle hooks have been implemented.
40+
*/
41+
@Injectable()
42+
export class DirectiveWrapperCompiler {
43+
static dirWrapperClassName(id: CompileIdentifierMetadata) { return `Wrapper_${id.name}`; }
44+
45+
constructor(private compilerConfig: CompilerConfig) {}
46+
47+
compile(dirMeta: CompileDirectiveMetadata): DirectiveWrapperCompileResult {
48+
const dirDepParamNames: string[] = [];
49+
for (let i = 0; i < dirMeta.type.diDeps.length; i++) {
50+
dirDepParamNames.push(`p${i}`);
51+
}
52+
const dirLifecycleHooks = dirMeta.type.lifecycleHooks;
53+
let lifecycleHooks: GenConfig = {
54+
genChanges: dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1 ||
55+
this.compilerConfig.logBindingUpdate,
56+
ngOnChanges: dirLifecycleHooks.indexOf(LifecycleHooks.OnChanges) !== -1,
57+
ngOnInit: dirLifecycleHooks.indexOf(LifecycleHooks.OnInit) !== -1,
58+
ngDoCheck: dirLifecycleHooks.indexOf(LifecycleHooks.DoCheck) !== -1
59+
};
60+
61+
const fields: o.ClassField[] = [
62+
new o.ClassField(CONTEXT_FIELD_NAME, o.importType(dirMeta.type)),
63+
new o.ClassField(CHANGED_FIELD_NAME, o.BOOL_TYPE),
64+
];
65+
const ctorStmts: o.Statement[] =
66+
[o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(false)).toStmt()];
67+
if (lifecycleHooks.genChanges) {
68+
fields.push(new o.ClassField(CHANGES_FIELD_NAME, new o.MapType(o.DYNAMIC_TYPE)));
69+
ctorStmts.push(RESET_CHANGES_STMT);
70+
}
71+
72+
const methods: o.ClassMethod[] = [];
73+
Object.keys(dirMeta.inputs).forEach((inputFieldName, idx) => {
74+
const fieldName = `_${inputFieldName}`;
75+
// private is fine here as no child view will reference the cached value...
76+
fields.push(new o.ClassField(fieldName, null, [o.StmtModifier.Private]));
77+
ctorStmts.push(o.THIS_EXPR.prop(fieldName)
78+
.set(o.importExpr(resolveIdentifier(Identifiers.UNINITIALIZED)))
79+
.toStmt());
80+
methods.push(checkInputMethod(inputFieldName, o.THIS_EXPR.prop(fieldName), lifecycleHooks));
81+
});
82+
methods.push(detectChangesInternalMethod(lifecycleHooks, this.compilerConfig.genDebugInfo));
83+
84+
ctorStmts.push(
85+
o.THIS_EXPR.prop(CONTEXT_FIELD_NAME)
86+
.set(o.importExpr(dirMeta.type)
87+
.instantiate(dirDepParamNames.map((paramName) => o.variable(paramName))))
88+
.toStmt());
89+
const ctor = new o.ClassMethod(
90+
null, dirDepParamNames.map((paramName) => new o.FnParam(paramName, o.DYNAMIC_TYPE)),
91+
ctorStmts);
92+
93+
const wrapperClassName = DirectiveWrapperCompiler.dirWrapperClassName(dirMeta.type);
94+
const classStmt = new o.ClassStmt(wrapperClassName, null, fields, [], ctor, methods);
95+
return new DirectiveWrapperCompileResult([classStmt], wrapperClassName);
96+
}
97+
}
98+
99+
function detectChangesInternalMethod(
100+
lifecycleHooks: GenConfig, logBindingUpdate: boolean): o.ClassMethod {
101+
const changedVar = o.variable('changed');
102+
const stmts: o.Statement[] = [
103+
changedVar.set(o.THIS_EXPR.prop(CHANGED_FIELD_NAME)).toDeclStmt(),
104+
o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(false)).toStmt(),
105+
];
106+
const lifecycleStmts: o.Statement[] = [];
107+
108+
if (lifecycleHooks.genChanges) {
109+
const onChangesStmts: o.Statement[] = [];
110+
if (lifecycleHooks.ngOnChanges) {
111+
onChangesStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME)
112+
.callMethod('ngOnChanges', [o.THIS_EXPR.prop(CHANGES_FIELD_NAME)])
113+
.toStmt());
114+
}
115+
if (logBindingUpdate) {
116+
onChangesStmts.push(
117+
o.importExpr(resolveIdentifier(Identifiers.setBindingDebugInfoForChanges))
118+
.callFn(
119+
[VIEW_VAR.prop('renderer'), RENDER_EL_VAR, o.THIS_EXPR.prop(CHANGES_FIELD_NAME)])
120+
.toStmt());
121+
}
122+
onChangesStmts.push(RESET_CHANGES_STMT);
123+
lifecycleStmts.push(new o.IfStmt(changedVar, onChangesStmts));
124+
}
125+
126+
if (lifecycleHooks.ngOnInit) {
127+
lifecycleStmts.push(new o.IfStmt(
128+
VIEW_VAR.prop('numberOfChecks').identical(new o.LiteralExpr(0)),
129+
[o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngOnInit', []).toStmt()]));
130+
}
131+
if (lifecycleHooks.ngDoCheck) {
132+
lifecycleStmts.push(o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).callMethod('ngDoCheck', []).toStmt());
133+
}
134+
if (lifecycleStmts.length > 0) {
135+
stmts.push(new o.IfStmt(o.not(THROW_ON_CHANGE_VAR), lifecycleStmts));
136+
}
137+
stmts.push(new o.ReturnStatement(changedVar));
138+
139+
return new o.ClassMethod(
140+
'detectChangesInternal',
141+
[
142+
new o.FnParam(
143+
VIEW_VAR.name, o.importType(resolveIdentifier(Identifiers.AppView), [o.DYNAMIC_TYPE])),
144+
new o.FnParam(RENDER_EL_VAR.name, o.DYNAMIC_TYPE),
145+
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
146+
],
147+
stmts, o.BOOL_TYPE);
148+
}
149+
150+
function checkInputMethod(
151+
input: string, fieldExpr: o.ReadPropExpr, lifecycleHooks: GenConfig): o.ClassMethod {
152+
var onChangeStatements: o.Statement[] = [
153+
o.THIS_EXPR.prop(CHANGED_FIELD_NAME).set(o.literal(true)).toStmt(),
154+
o.THIS_EXPR.prop(CONTEXT_FIELD_NAME).prop(input).set(CURR_VALUE_VAR).toStmt(),
155+
];
156+
if (lifecycleHooks.genChanges) {
157+
onChangeStatements.push(o.THIS_EXPR.prop(CHANGES_FIELD_NAME)
158+
.key(o.literal(input))
159+
.set(o.importExpr(resolveIdentifier(Identifiers.SimpleChange))
160+
.instantiate([fieldExpr, CURR_VALUE_VAR]))
161+
.toStmt());
162+
}
163+
onChangeStatements.push(fieldExpr.set(CURR_VALUE_VAR).toStmt());
164+
165+
var methodBody: o.Statement[] = [
166+
new o.IfStmt(
167+
FORCE_UPDATE_VAR.or(o.importExpr(resolveIdentifier(Identifiers.checkBinding))
168+
.callFn([THROW_ON_CHANGE_VAR, fieldExpr, CURR_VALUE_VAR])),
169+
onChangeStatements),
170+
];
171+
return new o.ClassMethod(
172+
`check_${input}`,
173+
[
174+
new o.FnParam(CURR_VALUE_VAR.name, o.DYNAMIC_TYPE),
175+
new o.FnParam(THROW_ON_CHANGE_VAR.name, o.BOOL_TYPE),
176+
new o.FnParam(FORCE_UPDATE_VAR.name, o.BOOL_TYPE),
177+
],
178+
methodBody);
179+
}
180+
181+
interface GenConfig {
182+
genChanges: boolean;
183+
ngOnChanges: boolean;
184+
ngOnInit: boolean;
185+
ngDoCheck: boolean;
186+
}

Diff for: modules/@angular/compiler/src/identifiers.ts

+35-22
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ANALYZE_FOR_ENTRY_COMPONENTS, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID as LOCALE_ID_, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT as TRANSLATIONS_FORMAT_, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
9+
import {ANALYZE_FOR_ENTRY_COMPONENTS, AnimationTransitionEvent, ChangeDetectionStrategy, ChangeDetectorRef, ComponentFactory, ComponentFactoryResolver, ElementRef, Injector, LOCALE_ID, NgModuleFactory, QueryList, RenderComponentType, Renderer, SecurityContext, SimpleChange, TRANSLATIONS_FORMAT, TemplateRef, ViewContainerRef, ViewEncapsulation} from '@angular/core';
1010

1111
import {CompileIdentifierMetadata, CompileTokenMetadata} from './compile_metadata';
12-
import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AnimationTransition, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, EMPTY_ARRAY, EMPTY_MAP, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, ViewUtils, balanceAnimationKeyframes, castByValue, checkBinding, clearStyles, collectAndResolveStyles, devModeEqual, flattenNestedViewRenderNodes, interpolate, prepareFinalAnimationStyles, pureProxy1, pureProxy10, pureProxy2, pureProxy3, pureProxy4, pureProxy5, pureProxy6, pureProxy7, pureProxy8, pureProxy9, reflector, registerModuleFactory, renderStyles} from './private_import_core';
12+
import {AnimationGroupPlayer, AnimationKeyframe, AnimationSequencePlayer, AnimationStyles, AnimationTransition, AppElement, AppView, ChangeDetectorStatus, CodegenComponentFactoryResolver, DebugAppView, DebugContext, NgModuleInjector, NoOpAnimationPlayer, StaticNodeDebugInfo, TemplateRef_, UNINITIALIZED, ValueUnwrapper, ViewType, balanceAnimationKeyframes, clearStyles, collectAndResolveStyles, devModeEqual, prepareFinalAnimationStyles, reflector, registerModuleFactory, renderStyles, view_utils} from './private_import_core';
1313
import {assetUrl} from './util';
1414

1515
var APP_VIEW_MODULE_URL = assetUrl('core', 'linker/view');
@@ -33,7 +33,7 @@ export class Identifiers {
3333
static ViewUtils: IdentifierSpec = {
3434
name: 'ViewUtils',
3535
moduleUrl: assetUrl('core', 'linker/view_utils'),
36-
runtime: ViewUtils
36+
runtime: view_utils.ViewUtils
3737
};
3838
static AppView:
3939
IdentifierSpec = {name: 'AppView', moduleUrl: APP_VIEW_MODULE_URL, runtime: AppView};
@@ -161,45 +161,48 @@ export class Identifiers {
161161
static checkBinding: IdentifierSpec = {
162162
name: 'checkBinding',
163163
moduleUrl: VIEW_UTILS_MODULE_URL,
164-
runtime: checkBinding
164+
runtime: view_utils.checkBinding
165165
};
166166
static flattenNestedViewRenderNodes: IdentifierSpec = {
167167
name: 'flattenNestedViewRenderNodes',
168168
moduleUrl: VIEW_UTILS_MODULE_URL,
169-
runtime: flattenNestedViewRenderNodes
169+
runtime: view_utils.flattenNestedViewRenderNodes
170170
};
171171
static devModeEqual:
172172
IdentifierSpec = {name: 'devModeEqual', moduleUrl: CD_MODULE_URL, runtime: devModeEqual};
173173
static interpolate: IdentifierSpec = {
174174
name: 'interpolate',
175175
moduleUrl: VIEW_UTILS_MODULE_URL,
176-
runtime: interpolate
176+
runtime: view_utils.interpolate
177177
};
178178
static castByValue: IdentifierSpec = {
179179
name: 'castByValue',
180180
moduleUrl: VIEW_UTILS_MODULE_URL,
181-
runtime: castByValue
181+
runtime: view_utils.castByValue
182182
};
183183
static EMPTY_ARRAY: IdentifierSpec = {
184184
name: 'EMPTY_ARRAY',
185185
moduleUrl: VIEW_UTILS_MODULE_URL,
186-
runtime: EMPTY_ARRAY
186+
runtime: view_utils.EMPTY_ARRAY
187+
};
188+
static EMPTY_MAP: IdentifierSpec = {
189+
name: 'EMPTY_MAP',
190+
moduleUrl: VIEW_UTILS_MODULE_URL,
191+
runtime: view_utils.EMPTY_MAP
187192
};
188-
static EMPTY_MAP:
189-
IdentifierSpec = {name: 'EMPTY_MAP', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: EMPTY_MAP};
190193

191194
static pureProxies = [
192195
null,
193-
{name: 'pureProxy1', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy1},
194-
{name: 'pureProxy2', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy2},
195-
{name: 'pureProxy3', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy3},
196-
{name: 'pureProxy4', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy4},
197-
{name: 'pureProxy5', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy5},
198-
{name: 'pureProxy6', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy6},
199-
{name: 'pureProxy7', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy7},
200-
{name: 'pureProxy8', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy8},
201-
{name: 'pureProxy9', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy9},
202-
{name: 'pureProxy10', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: pureProxy10},
196+
{name: 'pureProxy1', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy1},
197+
{name: 'pureProxy2', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy2},
198+
{name: 'pureProxy3', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy3},
199+
{name: 'pureProxy4', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy4},
200+
{name: 'pureProxy5', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy5},
201+
{name: 'pureProxy6', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy6},
202+
{name: 'pureProxy7', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy7},
203+
{name: 'pureProxy8', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy8},
204+
{name: 'pureProxy9', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy9},
205+
{name: 'pureProxy10', moduleUrl: VIEW_UTILS_MODULE_URL, runtime: view_utils.pureProxy10},
203206
];
204207
static SecurityContext: IdentifierSpec = {
205208
name: 'SecurityContext',
@@ -259,12 +262,22 @@ export class Identifiers {
259262
static LOCALE_ID: IdentifierSpec = {
260263
name: 'LOCALE_ID',
261264
moduleUrl: assetUrl('core', 'i18n/tokens'),
262-
runtime: LOCALE_ID_
265+
runtime: LOCALE_ID
263266
};
264267
static TRANSLATIONS_FORMAT: IdentifierSpec = {
265268
name: 'TRANSLATIONS_FORMAT',
266269
moduleUrl: assetUrl('core', 'i18n/tokens'),
267-
runtime: TRANSLATIONS_FORMAT_
270+
runtime: TRANSLATIONS_FORMAT
271+
};
272+
static setBindingDebugInfo: IdentifierSpec = {
273+
name: 'setBindingDebugInfo',
274+
moduleUrl: VIEW_UTILS_MODULE_URL,
275+
runtime: view_utils.setBindingDebugInfo
276+
};
277+
static setBindingDebugInfoForChanges: IdentifierSpec = {
278+
name: 'setBindingDebugInfoForChanges',
279+
moduleUrl: VIEW_UTILS_MODULE_URL,
280+
runtime: view_utils.setBindingDebugInfoForChanges
268281
};
269282
static AnimationTransition: IdentifierSpec = {
270283
name: 'AnimationTransition',

0 commit comments

Comments
 (0)