feat(compiler): add change detector generation
Runtime and Codegen. Part of #3605 Closes #4057
This commit is contained in:
parent
2daf2eedb6
commit
12dd44f7f6
|
@ -0,0 +1,81 @@
|
||||||
|
import {TypeMetadata, SourceModule} from './api';
|
||||||
|
import {
|
||||||
|
ChangeDetectorJITGenerator
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection_jit_generator';
|
||||||
|
|
||||||
|
import {createChangeDetectorDefinitions} from './change_definition_factory';
|
||||||
|
import {isJsObject, CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||||
|
|
||||||
|
import {
|
||||||
|
ChangeDetectorGenConfig,
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
DynamicProtoChangeDetector,
|
||||||
|
ChangeDetectionStrategy
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
|
import {TemplateAst} from './template_ast';
|
||||||
|
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
|
||||||
|
|
||||||
|
var IS_DART = !isJsObject({});
|
||||||
|
|
||||||
|
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector";
|
||||||
|
const UTIL = "ChangeDetectionUtil";
|
||||||
|
|
||||||
|
const JS_CHANGE_DETECTOR_IMPORTS = CONST_EXPR([
|
||||||
|
['angular2/src/core/change_detection/abstract_change_detector', 'acd'],
|
||||||
|
['angular2/src/core/change_detection/change_detection_util', 'cdu']
|
||||||
|
]);
|
||||||
|
|
||||||
|
const DART_CHANGE_DETECTOR_IMPORTS =
|
||||||
|
CONST_EXPR([['angular2/src/core/change_detection/pregen_proto_change_detector', '_gen']]);
|
||||||
|
|
||||||
|
export class ChangeDetectionCompiler {
|
||||||
|
constructor(private _genConfig: ChangeDetectorGenConfig) {}
|
||||||
|
|
||||||
|
compileComponentRuntime(componentType: TypeMetadata, strategy: ChangeDetectionStrategy,
|
||||||
|
parsedTemplate: TemplateAst[]): Function[] {
|
||||||
|
var changeDetectorDefinitions =
|
||||||
|
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||||
|
return changeDetectorDefinitions.map(definition =>
|
||||||
|
this._createChangeDetectorFactory(definition));
|
||||||
|
}
|
||||||
|
|
||||||
|
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
|
||||||
|
if (IS_DART) {
|
||||||
|
var proto = new DynamicProtoChangeDetector(definition);
|
||||||
|
return (dispatcher) => proto.instantiate(dispatcher);
|
||||||
|
} else {
|
||||||
|
// TODO(tbosch): provide a flag in _genConfig whether to allow eval or fall back to dynamic
|
||||||
|
// change detection as well!
|
||||||
|
return new ChangeDetectorJITGenerator(definition, UTIL, ABSTRACT_CHANGE_DETECTOR).generate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileComponentCodeGen(componentType: TypeMetadata, strategy: ChangeDetectionStrategy,
|
||||||
|
parsedTemplate: TemplateAst[]): SourceModule {
|
||||||
|
var changeDetectorDefinitions =
|
||||||
|
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
|
||||||
|
var imports = IS_DART ? DART_CHANGE_DETECTOR_IMPORTS : JS_CHANGE_DETECTOR_IMPORTS;
|
||||||
|
var factories = [];
|
||||||
|
var sourceParts = changeDetectorDefinitions.map(definition => {
|
||||||
|
var codegen: any;
|
||||||
|
// TODO(tbosch): move the 2 code generators to the same place, one with .dart and one with .ts
|
||||||
|
// suffix
|
||||||
|
// and have the same API for calling them!
|
||||||
|
if (IS_DART) {
|
||||||
|
codegen = new Codegen();
|
||||||
|
var className = definition.id;
|
||||||
|
codegen.generate(componentType.typeName, className, definition);
|
||||||
|
factories.push(`(dispatcher) => new ${className}(dispatcher)`);
|
||||||
|
return codegen.toString();
|
||||||
|
} else {
|
||||||
|
codegen = new ChangeDetectorJITGenerator(definition, `cdu.${UTIL}`,
|
||||||
|
`acd.${ABSTRACT_CHANGE_DETECTOR}`);
|
||||||
|
factories.push(`function(dispatcher) { return new ${codegen.typeName}(dispatcher); }`);
|
||||||
|
return codegen.generateSource();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sourceParts.push(`var CHANGE_DETECTORS = [ ${factories.join(',')} ];`);
|
||||||
|
return new SourceModule(componentType.typeUrl, sourceParts.join('\n'), imports);
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,7 +76,7 @@ export class StyleCompiler {
|
||||||
private _styleCodeGen(moduleName: string, plainStyles: string[], absUrls: string[], shim: boolean,
|
private _styleCodeGen(moduleName: string, plainStyles: string[], absUrls: string[], shim: boolean,
|
||||||
suffix: string): SourceModule {
|
suffix: string): SourceModule {
|
||||||
var imports: string[][] = [];
|
var imports: string[][] = [];
|
||||||
var moduleSource = `${codeGenExportVar('STYLES')} (`;
|
var moduleSource = `var STYLES = (`;
|
||||||
moduleSource +=
|
moduleSource +=
|
||||||
`[${plainStyles.map( plainStyle => escapeString(this._shimIfNeeded(plainStyle, shim)) ).join(',')}]`;
|
`[${plainStyles.map( plainStyle => escapeString(this._shimIfNeeded(plainStyle, shim)) ).join(',')}]`;
|
||||||
for (var i = 0; i < absUrls.length; i++) {
|
for (var i = 0; i < absUrls.length; i++) {
|
||||||
|
@ -109,14 +109,6 @@ function escapeString(input: string): string {
|
||||||
return `'${escapedInput}'`;
|
return `'${escapedInput}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function codeGenExportVar(name: string): string {
|
|
||||||
if (IS_DART) {
|
|
||||||
return `var ${name} =`;
|
|
||||||
} else {
|
|
||||||
return `var ${name} = exports.${name} =`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function codeGenConcatArray(expression: string): string {
|
function codeGenConcatArray(expression: string): string {
|
||||||
return `${IS_DART ? '..addAll' : '.concat'}(${expression})`;
|
return `${IS_DART ? '..addAll' : '.concat'}(${expression})`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ export class PreGeneratedChangeDetection extends ChangeDetection {
|
||||||
|
|
||||||
this._genConfig =
|
this._genConfig =
|
||||||
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
||||||
assertionsEnabled(), false);
|
assertionsEnabled(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isSupported(): boolean { return PregenProtoChangeDetector.isSupported(); }
|
static isSupported(): boolean { return PregenProtoChangeDetector.isSupported(); }
|
||||||
|
@ -133,7 +133,7 @@ export class DynamicChangeDetection extends ChangeDetection {
|
||||||
super();
|
super();
|
||||||
this._genConfig =
|
this._genConfig =
|
||||||
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
||||||
assertionsEnabled(), false);
|
assertionsEnabled(), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
getProtoChangeDetector(id: string, definition: ChangeDetectorDefinition): ProtoChangeDetector {
|
getProtoChangeDetector(id: string, definition: ChangeDetectorDefinition): ProtoChangeDetector {
|
||||||
|
@ -157,7 +157,7 @@ export class JitChangeDetection extends ChangeDetection {
|
||||||
super();
|
super();
|
||||||
this._genConfig =
|
this._genConfig =
|
||||||
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
isPresent(config) ? config : new ChangeDetectorGenConfig(assertionsEnabled(),
|
||||||
assertionsEnabled(), false);
|
assertionsEnabled(), false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static isSupported(): boolean { return JitProtoChangeDetector.isSupported(); }
|
static isSupported(): boolean { return JitProtoChangeDetector.isSupported(); }
|
||||||
|
|
|
@ -7,11 +7,16 @@ library change_detection.change_detection_jit_generator;
|
||||||
/// `PregenProtoChangeDetector`, and
|
/// `PregenProtoChangeDetector`, and
|
||||||
/// `src/transform/template_compiler/change_detector_codegen.dart` for details.
|
/// `src/transform/template_compiler/change_detector_codegen.dart` for details.
|
||||||
class ChangeDetectorJITGenerator {
|
class ChangeDetectorJITGenerator {
|
||||||
ChangeDetectorJITGenerator(typeName, strategy, records, directiveMementos) {}
|
String typeName;
|
||||||
|
ChangeDetectorJITGenerator(definition, changeDetectionUtilVarName, abstractChangeDetectorVarName) {}
|
||||||
|
|
||||||
generate() {
|
generate() {
|
||||||
throw "Jit Change Detection is not supported in Dart";
|
throw "Jit Change Detection is not supported in Dart";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateSource() {
|
||||||
|
throw "Jit Change Detection is not supported in Dart";
|
||||||
|
}
|
||||||
|
|
||||||
static bool isSupported() => false;
|
static bool isSupported() => false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import {BaseException, Type, isBlank, isPresent} from 'angular2/src/core/facade/lang';
|
import {
|
||||||
|
BaseException,
|
||||||
|
Type,
|
||||||
|
isBlank,
|
||||||
|
isPresent,
|
||||||
|
StringWrapper
|
||||||
|
} from 'angular2/src/core/facade/lang';
|
||||||
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
|
|
||||||
import {AbstractChangeDetector} from './abstract_change_detector';
|
import {AbstractChangeDetector} from './abstract_change_detector';
|
||||||
|
@ -11,10 +17,9 @@ import {CodegenLogicUtil} from './codegen_logic_util';
|
||||||
import {codify} from './codegen_facade';
|
import {codify} from './codegen_facade';
|
||||||
import {EventBinding} from './event_binding';
|
import {EventBinding} from './event_binding';
|
||||||
import {BindingTarget} from './binding_record';
|
import {BindingTarget} from './binding_record';
|
||||||
import {ChangeDetectorGenConfig} from './interfaces';
|
import {ChangeDetectorGenConfig, ChangeDetectorDefinition} from './interfaces';
|
||||||
import {ChangeDetectionStrategy} from './constants';
|
import {ChangeDetectionStrategy} from './constants';
|
||||||
|
import {createPropertyRecords, createEventRecords} from './proto_change_detector';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The code generator takes a list of proto records and creates a function/class
|
* The code generator takes a list of proto records and creates a function/class
|
||||||
|
@ -25,39 +30,65 @@ import {ChangeDetectionStrategy} from './constants';
|
||||||
* `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates
|
* `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates
|
||||||
* here, please make equivalent changes there.
|
* here, please make equivalent changes there.
|
||||||
*/
|
*/
|
||||||
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector";
|
|
||||||
const UTIL = "ChangeDetectionUtil";
|
|
||||||
const IS_CHANGED_LOCAL = "isChanged";
|
const IS_CHANGED_LOCAL = "isChanged";
|
||||||
const CHANGES_LOCAL = "changes";
|
const CHANGES_LOCAL = "changes";
|
||||||
|
|
||||||
export class ChangeDetectorJITGenerator {
|
export class ChangeDetectorJITGenerator {
|
||||||
_logic: CodegenLogicUtil;
|
private _logic: CodegenLogicUtil;
|
||||||
_names: CodegenNameUtil;
|
private _names: CodegenNameUtil;
|
||||||
_typeName: string;
|
private id: string;
|
||||||
|
private changeDetectionStrategy: ChangeDetectionStrategy;
|
||||||
|
private records: ProtoRecord[];
|
||||||
|
private propertyBindingTargets: BindingTarget[];
|
||||||
|
private eventBindings: EventBinding[];
|
||||||
|
private directiveRecords: any[];
|
||||||
|
private genConfig: ChangeDetectorGenConfig;
|
||||||
|
typeName: string;
|
||||||
|
|
||||||
constructor(private id: string, private changeDetectionStrategy: ChangeDetectionStrategy,
|
constructor(definition: ChangeDetectorDefinition, private changeDetectionUtilVarName: string,
|
||||||
private records: ProtoRecord[], private propertyBindingTargets: BindingTarget[],
|
private abstractChangeDetectorVarName: string) {
|
||||||
private eventBindings: EventBinding[], private directiveRecords: any[],
|
var propertyBindingRecords = createPropertyRecords(definition);
|
||||||
private genConfig: ChangeDetectorGenConfig) {
|
var eventBindingRecords = createEventRecords(definition);
|
||||||
this._names =
|
var propertyBindingTargets = definition.bindingRecords.map(b => b.target);
|
||||||
new CodegenNameUtil(this.records, this.eventBindings, this.directiveRecords, UTIL);
|
this.id = definition.id;
|
||||||
this._logic = new CodegenLogicUtil(this._names, UTIL, changeDetectionStrategy);
|
this.changeDetectionStrategy = definition.strategy;
|
||||||
this._typeName = sanitizeName(`ChangeDetector_${this.id}`);
|
this.genConfig = definition.genConfig;
|
||||||
|
|
||||||
|
this.records = propertyBindingRecords;
|
||||||
|
this.propertyBindingTargets = propertyBindingTargets;
|
||||||
|
this.eventBindings = eventBindingRecords;
|
||||||
|
this.directiveRecords = definition.directiveRecords;
|
||||||
|
this._names = new CodegenNameUtil(this.records, this.eventBindings, this.directiveRecords,
|
||||||
|
this.changeDetectionUtilVarName);
|
||||||
|
this._logic = new CodegenLogicUtil(this._names, this.changeDetectionUtilVarName,
|
||||||
|
this.changeDetectionStrategy);
|
||||||
|
this.typeName = sanitizeName(`ChangeDetector_${this.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
generate(): Function {
|
generate(): Function {
|
||||||
var classDefinition = `
|
var factorySource = `
|
||||||
var ${this._typeName} = function ${this._typeName}(dispatcher) {
|
${this.generateSource()}
|
||||||
${ABSTRACT_CHANGE_DETECTOR}.call(
|
return function(dispatcher) {
|
||||||
|
return new ${this.typeName}(dispatcher);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return new Function(this.abstractChangeDetectorVarName, this.changeDetectionUtilVarName,
|
||||||
|
factorySource)(AbstractChangeDetector, ChangeDetectionUtil);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateSource(): string {
|
||||||
|
return `
|
||||||
|
var ${this.typeName} = function ${this.typeName}(dispatcher) {
|
||||||
|
${this.abstractChangeDetectorVarName}.call(
|
||||||
this, ${JSON.stringify(this.id)}, dispatcher, ${this.records.length},
|
this, ${JSON.stringify(this.id)}, dispatcher, ${this.records.length},
|
||||||
${this._typeName}.gen_propertyBindingTargets, ${this._typeName}.gen_directiveIndices,
|
${this.typeName}.gen_propertyBindingTargets, ${this.typeName}.gen_directiveIndices,
|
||||||
${codify(this.changeDetectionStrategy)});
|
${codify(this.changeDetectionStrategy)});
|
||||||
this.dehydrateDirectives(false);
|
this.dehydrateDirectives(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
${this._typeName}.prototype = Object.create(${ABSTRACT_CHANGE_DETECTOR}.prototype);
|
${this.typeName}.prototype = Object.create(${this.abstractChangeDetectorVarName}.prototype);
|
||||||
|
|
||||||
${this._typeName}.prototype.detectChangesInRecordsInternal = function(throwOnChange) {
|
${this.typeName}.prototype.detectChangesInRecordsInternal = function(throwOnChange) {
|
||||||
${this._names.genInitLocals()}
|
${this._names.genInitLocals()}
|
||||||
var ${IS_CHANGED_LOCAL} = false;
|
var ${IS_CHANGED_LOCAL} = false;
|
||||||
var ${CHANGES_LOCAL} = null;
|
var ${CHANGES_LOCAL} = null;
|
||||||
|
@ -80,31 +111,25 @@ export class ChangeDetectorJITGenerator {
|
||||||
${this._genPropertyBindingTargets()}
|
${this._genPropertyBindingTargets()}
|
||||||
|
|
||||||
${this._genDirectiveIndices()}
|
${this._genDirectiveIndices()}
|
||||||
|
|
||||||
return function(dispatcher) {
|
|
||||||
return new ${this._typeName}(dispatcher);
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
return new Function(ABSTRACT_CHANGE_DETECTOR, UTIL, classDefinition)(AbstractChangeDetector,
|
|
||||||
ChangeDetectionUtil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_genPropertyBindingTargets(): string {
|
_genPropertyBindingTargets(): string {
|
||||||
var targets = this._logic.genPropertyBindingTargets(this.propertyBindingTargets,
|
var targets = this._logic.genPropertyBindingTargets(this.propertyBindingTargets,
|
||||||
this.genConfig.genDebugInfo);
|
this.genConfig.genDebugInfo);
|
||||||
return `${this._typeName}.gen_propertyBindingTargets = ${targets};`;
|
return `${this.typeName}.gen_propertyBindingTargets = ${targets};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_genDirectiveIndices(): string {
|
_genDirectiveIndices(): string {
|
||||||
var indices = this._logic.genDirectiveIndices(this.directiveRecords);
|
var indices = this._logic.genDirectiveIndices(this.directiveRecords);
|
||||||
return `${this._typeName}.gen_directiveIndices = ${indices};`;
|
return `${this.typeName}.gen_directiveIndices = ${indices};`;
|
||||||
}
|
}
|
||||||
|
|
||||||
_maybeGenHandleEventInternal(): string {
|
_maybeGenHandleEventInternal(): string {
|
||||||
if (this.eventBindings.length > 0) {
|
if (this.eventBindings.length > 0) {
|
||||||
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join("\n");
|
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join("\n");
|
||||||
return `
|
return `
|
||||||
${this._typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
|
${this.typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
|
||||||
var ${this._names.getPreventDefaultAccesor()} = false;
|
var ${this._names.getPreventDefaultAccesor()} = false;
|
||||||
${this._names.genInitEventLocals()}
|
${this._names.genInitEventLocals()}
|
||||||
${handlers}
|
${handlers}
|
||||||
|
@ -156,7 +181,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
}
|
}
|
||||||
var dehydrateFieldsCode = this._names.genDehydrateFields();
|
var dehydrateFieldsCode = this._names.genDehydrateFields();
|
||||||
if (!destroyPipesCode && !dehydrateFieldsCode) return '';
|
if (!destroyPipesCode && !dehydrateFieldsCode) return '';
|
||||||
return `${this._typeName}.prototype.dehydrateDirectives = function(destroyPipes) {
|
return `${this.typeName}.prototype.dehydrateDirectives = function(destroyPipes) {
|
||||||
${destroyPipesCode}
|
${destroyPipesCode}
|
||||||
${dehydrateFieldsCode}
|
${dehydrateFieldsCode}
|
||||||
}`;
|
}`;
|
||||||
|
@ -166,7 +191,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
var hydrateDirectivesCode = this._logic.genHydrateDirectives(this.directiveRecords);
|
var hydrateDirectivesCode = this._logic.genHydrateDirectives(this.directiveRecords);
|
||||||
var hydrateDetectorsCode = this._logic.genHydrateDetectors(this.directiveRecords);
|
var hydrateDetectorsCode = this._logic.genHydrateDetectors(this.directiveRecords);
|
||||||
if (!hydrateDirectivesCode && !hydrateDetectorsCode) return '';
|
if (!hydrateDirectivesCode && !hydrateDetectorsCode) return '';
|
||||||
return `${this._typeName}.prototype.hydrateDirectives = function(directives) {
|
return `${this.typeName}.prototype.hydrateDirectives = function(directives) {
|
||||||
${hydrateDirectivesCode}
|
${hydrateDirectivesCode}
|
||||||
${hydrateDetectorsCode}
|
${hydrateDetectorsCode}
|
||||||
}`;
|
}`;
|
||||||
|
@ -177,7 +202,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
if (notifications.length > 0) {
|
if (notifications.length > 0) {
|
||||||
var directiveNotifications = notifications.join("\n");
|
var directiveNotifications = notifications.join("\n");
|
||||||
return `
|
return `
|
||||||
${this._typeName}.prototype.afterContentLifecycleCallbacksInternal = function() {
|
${this.typeName}.prototype.afterContentLifecycleCallbacksInternal = function() {
|
||||||
${directiveNotifications}
|
${directiveNotifications}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -191,7 +216,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
if (notifications.length > 0) {
|
if (notifications.length > 0) {
|
||||||
var directiveNotifications = notifications.join("\n");
|
var directiveNotifications = notifications.join("\n");
|
||||||
return `
|
return `
|
||||||
${this._typeName}.prototype.afterViewLifecycleCallbacksInternal = function() {
|
${this.typeName}.prototype.afterViewLifecycleCallbacksInternal = function() {
|
||||||
${directiveNotifications}
|
${directiveNotifications}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -239,7 +264,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
var pipeName = r.name;
|
var pipeName = r.name;
|
||||||
|
|
||||||
var init = `
|
var init = `
|
||||||
if (${pipe} === ${UTIL}.uninitialized) {
|
if (${pipe} === ${this.changeDetectionUtilVarName}.uninitialized) {
|
||||||
${pipe} = ${this._names.getPipesAccessorName()}.get('${pipeName}');
|
${pipe} = ${this._names.getPipesAccessorName()}.get('${pipeName}');
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -251,7 +276,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
|
|
||||||
var check = `
|
var check = `
|
||||||
if (${oldValue} !== ${newValue}) {
|
if (${oldValue} !== ${newValue}) {
|
||||||
${newValue} = ${UTIL}.unwrapValue(${newValue})
|
${newValue} = ${this.changeDetectionUtilVarName}.unwrapValue(${newValue})
|
||||||
${this._genChangeMarker(r)}
|
${this._genChangeMarker(r)}
|
||||||
${this._genUpdateDirectiveOrElement(r)}
|
${this._genUpdateDirectiveOrElement(r)}
|
||||||
${this._genAddToChanges(r)}
|
${this._genAddToChanges(r)}
|
||||||
|
@ -342,7 +367,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
|
|
||||||
_genCheckNoChanges(): string {
|
_genCheckNoChanges(): string {
|
||||||
if (this.genConfig.genCheckNoChanges) {
|
if (this.genConfig.genCheckNoChanges) {
|
||||||
return `${this._typeName}.prototype.checkNoChanges = function() { this.runDetectChanges(true); }`;
|
return `${this.typeName}.prototype.checkNoChanges = function() { this.runDetectChanges(true); }`;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ export interface ProtoChangeDetector { instantiate(dispatcher: ChangeDispatcher)
|
||||||
|
|
||||||
export class ChangeDetectorGenConfig {
|
export class ChangeDetectorGenConfig {
|
||||||
constructor(public genCheckNoChanges: boolean, public genDebugInfo: boolean,
|
constructor(public genCheckNoChanges: boolean, public genDebugInfo: boolean,
|
||||||
public logBindingUpdate: boolean) {}
|
public logBindingUpdate: boolean, public useJit: boolean) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ChangeDetectorDefinition {
|
export class ChangeDetectorDefinition {
|
||||||
|
|
|
@ -4,9 +4,6 @@ import {isPresent} from 'angular2/src/core/facade/lang';
|
||||||
import {ProtoChangeDetector, ChangeDetector, ChangeDetectorDefinition} from './interfaces';
|
import {ProtoChangeDetector, ChangeDetector, ChangeDetectorDefinition} from './interfaces';
|
||||||
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
import {ChangeDetectorJITGenerator} from './change_detection_jit_generator';
|
||||||
|
|
||||||
import {coalesce} from './coalesce';
|
|
||||||
import {createPropertyRecords, createEventRecords} from './proto_change_detector';
|
|
||||||
|
|
||||||
export class JitProtoChangeDetector implements ProtoChangeDetector {
|
export class JitProtoChangeDetector implements ProtoChangeDetector {
|
||||||
_factory: Function;
|
_factory: Function;
|
||||||
|
|
||||||
|
@ -19,13 +16,6 @@ export class JitProtoChangeDetector implements ProtoChangeDetector {
|
||||||
instantiate(dispatcher: any): ChangeDetector { return this._factory(dispatcher); }
|
instantiate(dispatcher: any): ChangeDetector { return this._factory(dispatcher); }
|
||||||
|
|
||||||
_createFactory(definition: ChangeDetectorDefinition) {
|
_createFactory(definition: ChangeDetectorDefinition) {
|
||||||
var propertyBindingRecords = createPropertyRecords(definition);
|
return new ChangeDetectorJITGenerator(definition, 'util', 'AbstractChangeDetector').generate();
|
||||||
var eventBindingRecords = createEventRecords(definition);
|
|
||||||
var propertyBindingTargets = this.definition.bindingRecords.map(b => b.target);
|
|
||||||
|
|
||||||
return new ChangeDetectorJITGenerator(
|
|
||||||
definition.id, definition.strategy, propertyBindingRecords, propertyBindingTargets,
|
|
||||||
eventBindingRecords, this.definition.directiveRecords, this.definition.genConfig)
|
|
||||||
.generate();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import {
|
||||||
|
ChangeDetectorDefinition,
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
|
// Note: This class is only here so that we can reference it from TypeScript code.
|
||||||
|
// The actual implementation lives under modules_dart.
|
||||||
|
// TODO(tbosch): Move the corresponding code into angular2/src/compiler once
|
||||||
|
// the new compiler is done.
|
||||||
|
export class Codegen {
|
||||||
|
generate(typeName: string, changeDetectorTypeName: string, def: ChangeDetectorDefinition): void {
|
||||||
|
throw "Not implemented in JS";
|
||||||
|
}
|
||||||
|
toString(): string { throw "Not implemented in JS"; }
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import {
|
||||||
TestComponentBuilder
|
TestComponentBuilder
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {isBlank} from 'angular2/src/core/facade/lang';
|
|
||||||
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
||||||
import {DirectiveMetadata, TypeMetadata, ChangeDetectionMetadata} from 'angular2/src/compiler/api';
|
import {DirectiveMetadata, TypeMetadata, ChangeDetectionMetadata} from 'angular2/src/compiler/api';
|
||||||
import {MockSchemaRegistry} from './template_parser_spec';
|
import {MockSchemaRegistry} from './template_parser_spec';
|
||||||
|
@ -23,7 +22,6 @@ import {
|
||||||
ChangeDetectorDefinition,
|
ChangeDetectorDefinition,
|
||||||
ChangeDetectorGenConfig,
|
ChangeDetectorGenConfig,
|
||||||
DynamicProtoChangeDetector,
|
DynamicProtoChangeDetector,
|
||||||
ProtoChangeDetector,
|
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
ChangeDispatcher,
|
ChangeDispatcher,
|
||||||
DirectiveIndex,
|
DirectiveIndex,
|
||||||
|
@ -33,6 +31,7 @@ import {
|
||||||
} from 'angular2/src/core/change_detection/change_detection';
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
import {Pipes} from 'angular2/src/core/change_detection/pipes';
|
import {Pipes} from 'angular2/src/core/change_detection/pipes';
|
||||||
import {createChangeDetectorDefinitions} from 'angular2/src/compiler/change_definition_factory';
|
import {createChangeDetectorDefinitions} from 'angular2/src/compiler/change_definition_factory';
|
||||||
|
import {TestContext, TestDirective, TestDispatcher, TestPipes} from './change_detector_mocks';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('ChangeDefinitionFactory', () => {
|
describe('ChangeDefinitionFactory', () => {
|
||||||
|
@ -62,8 +61,8 @@ export function main() {
|
||||||
protoViewIndex: number = 0): ChangeDetector {
|
protoViewIndex: number = 0): ChangeDetector {
|
||||||
var protoChangeDetectors =
|
var protoChangeDetectors =
|
||||||
createChangeDetectorDefinitions(
|
createChangeDetectorDefinitions(
|
||||||
new TypeMetadata({typeName: 'SomeComp'}), ChangeDetectionStrategy.CheckAlways,
|
new TypeMetadata({typeName: 'SomeComp'}), ChangeDetectionStrategy.Default,
|
||||||
new ChangeDetectorGenConfig(true, true, false),
|
new ChangeDetectorGenConfig(true, true, false, false),
|
||||||
parser.parse(domParser.parse(template, 'TestComp'), directives))
|
parser.parse(domParser.parse(template, 'TestComp'), directives))
|
||||||
.map(definition => new DynamicProtoChangeDetector(definition));
|
.map(definition => new DynamicProtoChangeDetector(definition));
|
||||||
var changeDetector = protoChangeDetectors[protoViewIndex].instantiate(dispatcher);
|
var changeDetector = protoChangeDetectors[protoViewIndex].instantiate(dispatcher);
|
||||||
|
@ -164,47 +163,3 @@ export function main() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestContext {
|
|
||||||
eventLog: string[] = [];
|
|
||||||
someProp: string;
|
|
||||||
someProp2: string;
|
|
||||||
|
|
||||||
onEvent(value: string) { this.eventLog.push(value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestDirective {
|
|
||||||
eventLog: string[] = [];
|
|
||||||
dirProp: string;
|
|
||||||
|
|
||||||
onEvent(value: string) { this.eventLog.push(value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestDispatcher implements ChangeDispatcher {
|
|
||||||
log: string[];
|
|
||||||
|
|
||||||
constructor(public directives: any[], public detectors: ProtoChangeDetector[]) { this.clear(); }
|
|
||||||
|
|
||||||
getDirectiveFor(di: DirectiveIndex) { return this.directives[di.directiveIndex]; }
|
|
||||||
|
|
||||||
getDetectorFor(di: DirectiveIndex) { return this.detectors[di.directiveIndex]; }
|
|
||||||
|
|
||||||
clear() { this.log = []; }
|
|
||||||
|
|
||||||
notifyOnBinding(target: BindingTarget, value) {
|
|
||||||
this.log.push(`${target.mode}(${target.name})=${this._asString(value)}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
logBindingUpdate(target, value) {}
|
|
||||||
|
|
||||||
notifyAfterContentChecked() {}
|
|
||||||
notifyAfterViewChecked() {}
|
|
||||||
|
|
||||||
getDebugContext(a, b) { return null; }
|
|
||||||
|
|
||||||
_asString(value) { return (isBlank(value) ? 'null' : value.toString()); }
|
|
||||||
}
|
|
||||||
|
|
||||||
class TestPipes implements Pipes {
|
|
||||||
get(type: string) { return null; }
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,138 @@
|
||||||
|
import {
|
||||||
|
ddescribe,
|
||||||
|
describe,
|
||||||
|
xdescribe,
|
||||||
|
it,
|
||||||
|
iit,
|
||||||
|
xit,
|
||||||
|
expect,
|
||||||
|
beforeEach,
|
||||||
|
afterEach,
|
||||||
|
AsyncTestCompleter,
|
||||||
|
inject
|
||||||
|
} from 'angular2/test_lib';
|
||||||
|
import {IS_DART} from '../platform';
|
||||||
|
|
||||||
|
import {CONST_EXPR} from 'angular2/src/core/facade/lang';
|
||||||
|
import {MapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
|
import {Promise} from 'angular2/src/core/facade/async';
|
||||||
|
|
||||||
|
import {ChangeDetectionCompiler} from 'angular2/src/compiler/change_detector_compiler';
|
||||||
|
|
||||||
|
import {HtmlParser} from 'angular2/src/compiler/html_parser';
|
||||||
|
import {
|
||||||
|
DirectiveMetadata,
|
||||||
|
TypeMetadata,
|
||||||
|
ChangeDetectionMetadata,
|
||||||
|
SourceModule
|
||||||
|
} from 'angular2/src/compiler/api';
|
||||||
|
|
||||||
|
import {MockSchemaRegistry} from './template_parser_spec';
|
||||||
|
|
||||||
|
import {TemplateParser} from 'angular2/src/compiler/template_parser';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Parser,
|
||||||
|
Lexer,
|
||||||
|
ChangeDetectorGenConfig,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
ChangeDispatcher,
|
||||||
|
DirectiveIndex,
|
||||||
|
Locals,
|
||||||
|
BindingTarget,
|
||||||
|
ChangeDetector
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
|
import {evalModule} from './eval_module';
|
||||||
|
|
||||||
|
import {TestContext, TestDispatcher, TestPipes} from './change_detector_mocks';
|
||||||
|
|
||||||
|
// Attention: These module names have to correspond to real modules!
|
||||||
|
const MODULE_NAME = 'angular2/test/compiler/change_detector_compiler_spec';
|
||||||
|
|
||||||
|
export function main() {
|
||||||
|
describe('ChangeDetectorCompiler', () => {
|
||||||
|
var domParser: HtmlParser;
|
||||||
|
var parser: TemplateParser;
|
||||||
|
|
||||||
|
function createCompiler(useJit: boolean): ChangeDetectionCompiler {
|
||||||
|
return new ChangeDetectionCompiler(new ChangeDetectorGenConfig(true, true, false, useJit));
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
domParser = new HtmlParser();
|
||||||
|
parser = new TemplateParser(
|
||||||
|
new Parser(new Lexer()),
|
||||||
|
new MockSchemaRegistry({'invalidProp': false}, {'mappedAttr': 'mappedProp'}));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('compileComponentRuntime', () => {
|
||||||
|
function detectChanges(compiler: ChangeDetectionCompiler, template: string,
|
||||||
|
directives: DirectiveMetadata[] = CONST_EXPR([])): string[] {
|
||||||
|
var type = new TypeMetadata({typeName: 'SomeComp'});
|
||||||
|
var parsedTemplate = parser.parse(domParser.parse(template, 'TestComp'), directives);
|
||||||
|
var factories =
|
||||||
|
compiler.compileComponentRuntime(type, ChangeDetectionStrategy.Default, parsedTemplate);
|
||||||
|
return testChangeDetector(factories[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should watch element properties (no jit)', () => {
|
||||||
|
expect(detectChanges(createCompiler(false), '<div [el-prop]="someProp">'))
|
||||||
|
.toEqual(['elementProperty(elProp)=someValue']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should watch element properties (jit)', () => {
|
||||||
|
expect(detectChanges(createCompiler(true), '<div [el-prop]="someProp">'))
|
||||||
|
.toEqual(['elementProperty(elProp)=someValue']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('compileComponentCodeGen', () => {
|
||||||
|
function detectChanges(compiler: ChangeDetectionCompiler, template: string,
|
||||||
|
directives: DirectiveMetadata[] = CONST_EXPR([])): Promise<string[]> {
|
||||||
|
var type = new TypeMetadata({typeName: 'SomeComp'});
|
||||||
|
var parsedTemplate = parser.parse(domParser.parse(template, 'TestComp'), directives);
|
||||||
|
var sourceModule =
|
||||||
|
compiler.compileComponentCodeGen(type, ChangeDetectionStrategy.Default, parsedTemplate);
|
||||||
|
var testableModule = createTestableModule(sourceModule, 0);
|
||||||
|
return evalModule(testableModule.source, testableModule.imports, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should watch element properties', inject([AsyncTestCompleter], (async) => {
|
||||||
|
detectChanges(createCompiler(true), '<div [el-prop]="someProp">')
|
||||||
|
.then((value) => {
|
||||||
|
expect(value).toEqual(['elementProperty(elProp)=someValue']);
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function createTestableModule(sourceModule: SourceModule, changeDetectorIndex: number):
|
||||||
|
SourceModule {
|
||||||
|
var testableSource;
|
||||||
|
var testableImports = [[MODULE_NAME, 'mocks']].concat(sourceModule.imports);
|
||||||
|
if (IS_DART) {
|
||||||
|
testableSource = `${sourceModule.source}
|
||||||
|
run(_) { return mocks.testChangeDetector(CHANGE_DETECTORS[${changeDetectorIndex}]); }`;
|
||||||
|
} else {
|
||||||
|
testableSource = `${sourceModule.source}
|
||||||
|
exports.run = function(_) { return mocks.testChangeDetector(CHANGE_DETECTORS[${changeDetectorIndex}]); }`;
|
||||||
|
}
|
||||||
|
return new SourceModule(null, testableSource, testableImports);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function testChangeDetector(changeDetectorFactory: Function): string[] {
|
||||||
|
var dispatcher = new TestDispatcher([], []);
|
||||||
|
var cd = changeDetectorFactory(dispatcher);
|
||||||
|
var ctx = new TestContext();
|
||||||
|
ctx.someProp = 'someValue';
|
||||||
|
var locals = new Locals(null, MapWrapper.createFromStringMap({'someVar': null}));
|
||||||
|
cd.hydrate(ctx, locals, dispatcher, new TestPipes());
|
||||||
|
cd.detectChanges();
|
||||||
|
return dispatcher.log;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
import {isBlank} from 'angular2/src/core/facade/lang';
|
||||||
|
import {Pipes} from 'angular2/src/core/change_detection/pipes';
|
||||||
|
import {
|
||||||
|
ProtoChangeDetector,
|
||||||
|
ChangeDispatcher,
|
||||||
|
DirectiveIndex,
|
||||||
|
BindingTarget
|
||||||
|
} from 'angular2/src/core/change_detection/change_detection';
|
||||||
|
|
||||||
|
export class TestContext {
|
||||||
|
eventLog: string[] = [];
|
||||||
|
someProp: string;
|
||||||
|
someProp2: string;
|
||||||
|
|
||||||
|
onEvent(value: string) { this.eventLog.push(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TestDirective {
|
||||||
|
eventLog: string[] = [];
|
||||||
|
dirProp: string;
|
||||||
|
|
||||||
|
onEvent(value: string) { this.eventLog.push(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TestDispatcher implements ChangeDispatcher {
|
||||||
|
log: string[];
|
||||||
|
|
||||||
|
constructor(public directives: any[], public detectors: ProtoChangeDetector[]) { this.clear(); }
|
||||||
|
|
||||||
|
getDirectiveFor(di: DirectiveIndex) { return this.directives[di.directiveIndex]; }
|
||||||
|
|
||||||
|
getDetectorFor(di: DirectiveIndex) { return this.detectors[di.directiveIndex]; }
|
||||||
|
|
||||||
|
clear() { this.log = []; }
|
||||||
|
|
||||||
|
notifyOnBinding(target: BindingTarget, value) {
|
||||||
|
this.log.push(`${target.mode}(${target.name})=${this._asString(value)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
logBindingUpdate(target, value) {}
|
||||||
|
|
||||||
|
notifyAfterContentChecked() {}
|
||||||
|
notifyAfterViewChecked() {}
|
||||||
|
|
||||||
|
getDebugContext(a, b) { return null; }
|
||||||
|
|
||||||
|
_asString(value) { return (isBlank(value) ? 'null' : value.toString()); }
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TestPipes implements Pipes {
|
||||||
|
get(type: string) { return null; }
|
||||||
|
}
|
|
@ -65,7 +65,7 @@ export const PROP_NAME = 'propName';
|
||||||
* In this case, we expect `id` and `expression` to be the same string.
|
* In this case, we expect `id` and `expression` to be the same string.
|
||||||
*/
|
*/
|
||||||
export function getDefinition(id: string): TestDefinition {
|
export function getDefinition(id: string): TestDefinition {
|
||||||
var genConfig = new ChangeDetectorGenConfig(true, true, true);
|
var genConfig = new ChangeDetectorGenConfig(true, true, true, true);
|
||||||
var testDef = null;
|
var testDef = null;
|
||||||
if (StringMapWrapper.contains(_ExpressionWithLocals.availableDefinitions, id)) {
|
if (StringMapWrapper.contains(_ExpressionWithLocals.availableDefinitions, id)) {
|
||||||
let val = StringMapWrapper.get(_ExpressionWithLocals.availableDefinitions, id);
|
let val = StringMapWrapper.get(_ExpressionWithLocals.availableDefinitions, id);
|
||||||
|
@ -121,7 +121,7 @@ export function getDefinition(id: string): TestDefinition {
|
||||||
[_DirectiveUpdating.recordNoCallbacks], genConfig);
|
[_DirectiveUpdating.recordNoCallbacks], genConfig);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
} else if (id == "updateElementProduction") {
|
} else if (id == "updateElementProduction") {
|
||||||
var genConfig = new ChangeDetectorGenConfig(false, false, false);
|
var genConfig = new ChangeDetectorGenConfig(false, false, false, true);
|
||||||
var records = _createBindingRecords("name");
|
var records = _createBindingRecords("name");
|
||||||
let cdDef = new ChangeDetectorDefinition(id, null, [], records, [], [], genConfig);
|
let cdDef = new ChangeDetectorDefinition(id, null, [], records, [], [], genConfig);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
|
@ -167,7 +167,7 @@ class _ExpressionWithLocals {
|
||||||
var variableBindings = _convertLocalsToVariableBindings(this.locals);
|
var variableBindings = _convertLocalsToVariableBindings(this.locals);
|
||||||
var bindingRecords = _createBindingRecords(this._expression);
|
var bindingRecords = _createBindingRecords(this._expression);
|
||||||
var directiveRecords = [];
|
var directiveRecords = [];
|
||||||
var genConfig = new ChangeDetectorGenConfig(true, true, true);
|
var genConfig = new ChangeDetectorGenConfig(true, true, true, true);
|
||||||
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings, bindingRecords,
|
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings, bindingRecords,
|
||||||
[], directiveRecords, genConfig);
|
[], directiveRecords, genConfig);
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ class _ExpressionWithMode {
|
||||||
_createHostEventRecords("(host-event)='false'", dirRecordWithOnPush))
|
_createHostEventRecords("(host-event)='false'", dirRecordWithOnPush))
|
||||||
}
|
}
|
||||||
|
|
||||||
var genConfig = new ChangeDetectorGenConfig(true, true, true);
|
var genConfig = new ChangeDetectorGenConfig(true, true, true, true);
|
||||||
|
|
||||||
return new ChangeDetectorDefinition('(empty id)', this._strategy, variableBindings,
|
return new ChangeDetectorDefinition('(empty id)', this._strategy, variableBindings,
|
||||||
bindingRecords, eventRecords, directiveRecords, genConfig);
|
bindingRecords, eventRecords, directiveRecords, genConfig);
|
||||||
|
@ -260,7 +260,7 @@ class _DirectiveUpdating {
|
||||||
createChangeDetectorDefinition(): ChangeDetectorDefinition {
|
createChangeDetectorDefinition(): ChangeDetectorDefinition {
|
||||||
var strategy = null;
|
var strategy = null;
|
||||||
var variableBindings = [];
|
var variableBindings = [];
|
||||||
var genConfig = new ChangeDetectorGenConfig(true, true, true);
|
var genConfig = new ChangeDetectorGenConfig(true, true, true, true);
|
||||||
|
|
||||||
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings,
|
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings,
|
||||||
this._bindingRecords, [], this._directiveRecords,
|
this._bindingRecords, [], this._directiveRecords,
|
||||||
|
|
|
@ -1512,7 +1512,8 @@ export function main() {
|
||||||
describe('logging property updates', () => {
|
describe('logging property updates', () => {
|
||||||
beforeEachBindings(() => [
|
beforeEachBindings(() => [
|
||||||
bind(ChangeDetection)
|
bind(ChangeDetection)
|
||||||
.toValue(new DynamicChangeDetection(new ChangeDetectorGenConfig(true, true, true)))
|
.toValue(
|
||||||
|
new DynamicChangeDetection(new ChangeDetectorGenConfig(true, true, true, false)))
|
||||||
]);
|
]);
|
||||||
|
|
||||||
it('should reflect property values as attributes',
|
it('should reflect property values as attributes',
|
||||||
|
|
|
@ -249,7 +249,7 @@ function setUpChangeDetection(changeDetection: ChangeDetection, iterations, obje
|
||||||
var dispatcher = new DummyDispatcher();
|
var dispatcher = new DummyDispatcher();
|
||||||
var parser = new Parser(new Lexer());
|
var parser = new Parser(new Lexer());
|
||||||
|
|
||||||
var genConfig = new ChangeDetectorGenConfig(false, false, false);
|
var genConfig = new ChangeDetectorGenConfig(false, false, false, true);
|
||||||
var parentProto = changeDetection.getProtoChangeDetector(
|
var parentProto = changeDetection.getProtoChangeDetector(
|
||||||
"id", new ChangeDetectorDefinition('parent', null, [], [], [], [], genConfig));
|
"id", new ChangeDetectorDefinition('parent', null, [], [], [], [], genConfig));
|
||||||
var parentCd = parentProto.instantiate(dispatcher);
|
var parentCd = parentProto.instantiate(dispatcher);
|
||||||
|
|
|
@ -58,7 +58,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
|
||||||
}
|
}
|
||||||
if (generateChangeDetectors) {
|
if (generateChangeDetectors) {
|
||||||
var saved = reflector.reflectionCapabilities;
|
var saved = reflector.reflectionCapabilities;
|
||||||
var genConfig = new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled(), reflectPropertiesAsAttributes);
|
var genConfig = new ChangeDetectorGenConfig(assertionsEnabled(), assertionsEnabled(), reflectPropertiesAsAttributes, false);
|
||||||
|
|
||||||
reflector.reflectionCapabilities = const NullReflectionCapabilities();
|
reflector.reflectionCapabilities = const NullReflectionCapabilities();
|
||||||
var defs = getChangeDetectorDefinitions(viewDefEntry.hostMetadata,
|
var defs = getChangeDetectorDefinitions(viewDefEntry.hostMetadata,
|
||||||
|
|
Loading…
Reference in New Issue