feat(change_detection): generate checkNoChanges only in dev mode
This commit is contained in:
parent
a2bb81c406
commit
71bb4b3ee5
@ -1,4 +1,4 @@
|
|||||||
import {isPresent} from 'angular2/src/facade/lang';
|
import {isPresent, BaseException} from 'angular2/src/facade/lang';
|
||||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {ChangeDetectorRef} from './change_detector_ref';
|
import {ChangeDetectorRef} from './change_detector_ref';
|
||||||
import {ChangeDetector} from './interfaces';
|
import {ChangeDetector} from './interfaces';
|
||||||
@ -38,11 +38,11 @@ export class AbstractChangeDetector implements ChangeDetector {
|
|||||||
|
|
||||||
remove(): void { this.parent.removeChild(this); }
|
remove(): void { this.parent.removeChild(this); }
|
||||||
|
|
||||||
detectChanges(): void { this._detectChanges(false); }
|
detectChanges(): void { this.runDetectChanges(false); }
|
||||||
|
|
||||||
checkNoChanges(): void { this._detectChanges(true); }
|
checkNoChanges(): void { throw new BaseException("Not implemented"); }
|
||||||
|
|
||||||
_detectChanges(throwOnChange: boolean): void {
|
runDetectChanges(throwOnChange: boolean): void {
|
||||||
if (this.mode === DETACHED || this.mode === CHECKED) return;
|
if (this.mode === DETACHED || this.mode === CHECKED) return;
|
||||||
|
|
||||||
this.detectChangesInRecords(throwOnChange);
|
this.detectChangesInRecords(throwOnChange);
|
||||||
@ -67,14 +67,14 @@ export class AbstractChangeDetector implements ChangeDetector {
|
|||||||
_detectChangesInLightDomChildren(throwOnChange: boolean): void {
|
_detectChangesInLightDomChildren(throwOnChange: boolean): void {
|
||||||
var c = this.lightDomChildren;
|
var c = this.lightDomChildren;
|
||||||
for (var i = 0; i < c.length; ++i) {
|
for (var i = 0; i < c.length; ++i) {
|
||||||
c[i]._detectChanges(throwOnChange);
|
c[i].runDetectChanges(throwOnChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_detectChangesInShadowDomChildren(throwOnChange: boolean): void {
|
_detectChangesInShadowDomChildren(throwOnChange: boolean): void {
|
||||||
var c = this.shadowDomChildren;
|
var c = this.shadowDomChildren;
|
||||||
for (var i = 0; i < c.length; ++i) {
|
for (var i = 0; i < c.length; ++i) {
|
||||||
c[i]._detectChanges(throwOnChange);
|
c[i].runDetectChanges(throwOnChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@ export class ChangeDetectorJITGenerator {
|
|||||||
_names: CodegenNameUtil;
|
_names: CodegenNameUtil;
|
||||||
|
|
||||||
constructor(public id: string, public changeDetectionStrategy: string,
|
constructor(public id: string, public changeDetectionStrategy: string,
|
||||||
public records: List<ProtoRecord>, public directiveRecords: List<any>) {
|
public records: List<ProtoRecord>, public directiveRecords: List<any>,
|
||||||
|
private generateCheckNoChanges: boolean) {
|
||||||
this._names = new CodegenNameUtil(this.records, this.directiveRecords, 'this._', UTIL);
|
this._names = new CodegenNameUtil(this.records, this.directiveRecords, 'this._', UTIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +81,8 @@ export class ChangeDetectorJITGenerator {
|
|||||||
${ALREADY_CHECKED_ACCESSOR} = true;
|
${ALREADY_CHECKED_ACCESSOR} = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${this._genCheckNoChanges(typeName)}
|
||||||
|
|
||||||
${typeName}.prototype.callOnAllChangesDone = function() {
|
${typeName}.prototype.callOnAllChangesDone = function() {
|
||||||
${this._genCallOnAllChangesDoneBody()}
|
${this._genCallOnAllChangesDoneBody()}
|
||||||
}
|
}
|
||||||
@ -109,6 +112,7 @@ export class ChangeDetectorJITGenerator {
|
|||||||
return new ${typeName}(dispatcher, protos, directiveRecords);
|
return new ${typeName}(dispatcher, protos, directiveRecords);
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
return new Function('AbstractChangeDetector', 'ChangeDetectionUtil', 'protos',
|
return new Function('AbstractChangeDetector', 'ChangeDetectionUtil', 'protos',
|
||||||
'directiveRecords', classDefinition)(
|
'directiveRecords', classDefinition)(
|
||||||
AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveRecords);
|
AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveRecords);
|
||||||
@ -330,11 +334,23 @@ export class ChangeDetectorJITGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_genThrowOnChangeCheck(oldValue: string, newValue: string): string {
|
_genThrowOnChangeCheck(oldValue: string, newValue: string): string {
|
||||||
return `
|
if (this.generateCheckNoChanges) {
|
||||||
if(throwOnChange) {
|
return `
|
||||||
${UTIL}.throwOnChange(${CURRENT_PROTO}, ${UTIL}.simpleChange(${oldValue}, ${newValue}));
|
if(throwOnChange) {
|
||||||
}
|
${UTIL}.throwOnChange(${CURRENT_PROTO}, ${UTIL}.simpleChange(${oldValue}, ${newValue}));
|
||||||
`;
|
}
|
||||||
|
`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_genCheckNoChanges(typeName: string): string {
|
||||||
|
if (this.generateCheckNoChanges) {
|
||||||
|
return `${typeName}.prototype.checkNoChanges = function() { this.runDetectChanges(true); }`;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_genAddToChanges(r: ProtoRecord): string {
|
_genAddToChanges(r: ProtoRecord): string {
|
||||||
|
@ -65,6 +65,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector {
|
|||||||
|
|
||||||
hydrated(): boolean { return this.values[0] !== null; }
|
hydrated(): boolean { return this.values[0] !== null; }
|
||||||
|
|
||||||
|
checkNoChanges(): void { this.runDetectChanges(true); }
|
||||||
|
|
||||||
detectChangesInRecords(throwOnChange: boolean) {
|
detectChangesInRecords(throwOnChange: boolean) {
|
||||||
if (!this.hydrated()) {
|
if (!this.hydrated()) {
|
||||||
ChangeDetectionUtil.throwDehydrated();
|
ChangeDetectionUtil.throwDehydrated();
|
||||||
|
@ -63,5 +63,6 @@ export interface ProtoChangeDetector { instantiate(dispatcher: any): ChangeDetec
|
|||||||
export class ChangeDetectorDefinition {
|
export class ChangeDetectorDefinition {
|
||||||
constructor(public id: string, public strategy: string, public variableNames: List<string>,
|
constructor(public id: string, public strategy: string, public variableNames: List<string>,
|
||||||
public bindingRecords: List<BindingRecord>,
|
public bindingRecords: List<BindingRecord>,
|
||||||
public directiveRecords: List<DirectiveRecord>) {}
|
public directiveRecords: List<DirectiveRecord>,
|
||||||
|
public generateCheckNoChanges: boolean) {}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ export class JitProtoChangeDetector implements ProtoChangeDetector {
|
|||||||
(b) => { recordBuilder.add(b, definition.variableNames); });
|
(b) => { recordBuilder.add(b, definition.variableNames); });
|
||||||
var records = coalesce(recordBuilder.records);
|
var records = coalesce(recordBuilder.records);
|
||||||
return new ChangeDetectorJITGenerator(definition.id, definition.strategy, records,
|
return new ChangeDetectorJITGenerator(definition.id, definition.strategy, records,
|
||||||
this.definition.directiveRecords)
|
this.definition.directiveRecords,
|
||||||
|
this.definition.generateCheckNoChanges)
|
||||||
.generate();
|
.generate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {Injectable} from 'angular2/di';
|
import {Injectable} from 'angular2/di';
|
||||||
|
|
||||||
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {isPresent, isBlank, BaseException} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, BaseException, assertionsEnabled} from 'angular2/src/facade/lang';
|
||||||
import {reflector} from 'angular2/src/reflection/reflection';
|
import {reflector} from 'angular2/src/reflection/reflection';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -246,7 +246,7 @@ function _getChangeDetectorDefinitions(
|
|||||||
var id = `${hostComponentMetadata.id}_${typeString}_${pvWithIndex.index}`;
|
var id = `${hostComponentMetadata.id}_${typeString}_${pvWithIndex.index}`;
|
||||||
var variableNames = nestedPvVariableNames[pvWithIndex.index];
|
var variableNames = nestedPvVariableNames[pvWithIndex.index];
|
||||||
return new ChangeDetectorDefinition(id, strategyName, variableNames, bindingRecords,
|
return new ChangeDetectorDefinition(id, strategyName, variableNames, bindingRecords,
|
||||||
directiveRecords);
|
directiveRecords, assertionsEnabled());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,10 +74,11 @@ class _CodegenState {
|
|||||||
final List<ProtoRecord> _records;
|
final List<ProtoRecord> _records;
|
||||||
final List<DirectiveRecord> _directiveRecords;
|
final List<DirectiveRecord> _directiveRecords;
|
||||||
final CodegenNameUtil _names;
|
final CodegenNameUtil _names;
|
||||||
|
final bool _generateCheckNoChanges;
|
||||||
|
|
||||||
_CodegenState._(this._changeDetectorDefId, this._contextTypeName,
|
_CodegenState._(this._changeDetectorDefId, this._contextTypeName,
|
||||||
this._changeDetectorTypeName, String changeDetectionStrategy,
|
this._changeDetectorTypeName, String changeDetectionStrategy,
|
||||||
List<ProtoRecord> records, List<DirectiveRecord> directiveRecords)
|
List<ProtoRecord> records, List<DirectiveRecord> directiveRecords, this._generateCheckNoChanges)
|
||||||
: _records = records,
|
: _records = records,
|
||||||
_directiveRecords = directiveRecords,
|
_directiveRecords = directiveRecords,
|
||||||
_names = new CodegenNameUtil(records, directiveRecords, '_', _UTIL),
|
_names = new CodegenNameUtil(records, directiveRecords, '_', _UTIL),
|
||||||
@ -91,7 +92,7 @@ class _CodegenState {
|
|||||||
.forEach((rec) => protoRecords.add(rec, def.variableNames));
|
.forEach((rec) => protoRecords.add(rec, def.variableNames));
|
||||||
var records = coalesce(protoRecords.records);
|
var records = coalesce(protoRecords.records);
|
||||||
return new _CodegenState._(def.id, typeName, changeDetectorTypeName,
|
return new _CodegenState._(def.id, typeName, changeDetectorTypeName,
|
||||||
def.strategy, records, def.directiveRecords);
|
def.strategy, records, def.directiveRecords, def.generateCheckNoChanges);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _writeToBuf(StringBuffer buf) {
|
void _writeToBuf(StringBuffer buf) {
|
||||||
@ -138,6 +139,8 @@ class _CodegenState {
|
|||||||
$_ALREADY_CHECKED_ACCESSOR = true;
|
$_ALREADY_CHECKED_ACCESSOR = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${_genCheckNoChanges()}
|
||||||
|
|
||||||
void callOnAllChangesDone() {
|
void callOnAllChangesDone() {
|
||||||
${_getCallOnAllChangesDoneBody()}
|
${_getCallOnAllChangesDoneBody()}
|
||||||
}
|
}
|
||||||
@ -393,12 +396,24 @@ class _CodegenState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _genThrowOnChangeCheck(String oldValue, String newValue) {
|
String _genThrowOnChangeCheck(String oldValue, String newValue) {
|
||||||
return '''
|
if (this._generateCheckNoChanges) {
|
||||||
if(throwOnChange) {
|
return '''
|
||||||
$_UTIL.throwOnChange(
|
if(throwOnChange) {
|
||||||
$_CURRENT_PROTO, $_UTIL.simpleChange(${oldValue}, ${newValue}));
|
$_UTIL.throwOnChange(
|
||||||
}
|
$_CURRENT_PROTO, $_UTIL.simpleChange(${oldValue}, ${newValue}));
|
||||||
''';
|
}
|
||||||
|
''';
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String _genCheckNoChanges() {
|
||||||
|
if (this._generateCheckNoChanges) {
|
||||||
|
return 'void checkNoChanges() { this.runDetectChanges(true); }';
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _genAddToChanges(ProtoRecord r) {
|
String _genAddToChanges(ProtoRecord r) {
|
||||||
|
@ -23,7 +23,7 @@ export function main() {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
proto = new SpyProtoChangeDetector();
|
proto = new SpyProtoChangeDetector();
|
||||||
def = new ChangeDetectorDefinition('id', null, [], [], []);
|
def = new ChangeDetectorDefinition('id', null, [], [], [], true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return a proto change detector when one is available", () => {
|
it("should return a proto change detector when one is available", () => {
|
||||||
|
@ -69,7 +69,7 @@ export function getDefinition(id: string): TestDefinition {
|
|||||||
var bindingRecords = _createBindingRecords(id);
|
var bindingRecords = _createBindingRecords(id);
|
||||||
var directiveRecords = [];
|
var directiveRecords = [];
|
||||||
let cdDef = new ChangeDetectorDefinition(id, strategy, variableBindings, bindingRecords,
|
let cdDef = new ChangeDetectorDefinition(id, strategy, variableBindings, bindingRecords,
|
||||||
directiveRecords);
|
directiveRecords, true);
|
||||||
testDef = new TestDefinition(id, cdDef, null);
|
testDef = new TestDefinition(id, cdDef, null);
|
||||||
}
|
}
|
||||||
if (isBlank(testDef)) {
|
if (isBlank(testDef)) {
|
||||||
@ -107,7 +107,7 @@ class _ExpressionWithLocals {
|
|||||||
var bindingRecords = _createBindingRecords(this._expression);
|
var bindingRecords = _createBindingRecords(this._expression);
|
||||||
var directiveRecords = [];
|
var directiveRecords = [];
|
||||||
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings, bindingRecords,
|
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings, bindingRecords,
|
||||||
directiveRecords);
|
directiveRecords, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,7 +151,7 @@ class _ExpressionWithMode {
|
|||||||
directiveRecords = [];
|
directiveRecords = [];
|
||||||
}
|
}
|
||||||
return new ChangeDetectorDefinition('(empty id)', this._strategy, variableBindings,
|
return new ChangeDetectorDefinition('(empty id)', this._strategy, variableBindings,
|
||||||
bindingRecords, directiveRecords);
|
bindingRecords, directiveRecords, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,7 +174,7 @@ class _DirectiveUpdating {
|
|||||||
var variableBindings = [];
|
var variableBindings = [];
|
||||||
|
|
||||||
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings,
|
return new ChangeDetectorDefinition('(empty id)', strategy, variableBindings,
|
||||||
this._bindingRecords, this._directiveRecords);
|
this._bindingRecords, this._directiveRecords, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static updateA(expression: string, dirRecord): BindingRecord {
|
static updateA(expression: string, dirRecord): BindingRecord {
|
||||||
|
@ -91,6 +91,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
|||||||
_alreadyChecked = true;
|
_alreadyChecked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkNoChanges() {this.runDetectChanges(true);}
|
||||||
|
|
||||||
void callOnAllChangesDone() {
|
void callOnAllChangesDone() {
|
||||||
dispatcher.notifyOnAllChangesDone();
|
dispatcher.notifyOnAllChangesDone();
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ function setUpChangeDetection(changeDetection: ChangeDetection, iterations, obje
|
|||||||
var parser = new Parser(new Lexer());
|
var parser = new Parser(new Lexer());
|
||||||
|
|
||||||
var parentProto = changeDetection.createProtoChangeDetector(
|
var parentProto = changeDetection.createProtoChangeDetector(
|
||||||
new ChangeDetectorDefinition('parent', null, [], [], []));
|
new ChangeDetectorDefinition('parent', null, [], [], [], false));
|
||||||
var parentCd = parentProto.instantiate(dispatcher);
|
var parentCd = parentProto.instantiate(dispatcher);
|
||||||
|
|
||||||
var directiveRecord = new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0)});
|
var directiveRecord = new DirectiveRecord({directiveIndex: new DirectiveIndex(0, 0)});
|
||||||
@ -277,7 +277,7 @@ function setUpChangeDetection(changeDetection: ChangeDetection, iterations, obje
|
|||||||
];
|
];
|
||||||
|
|
||||||
var proto = changeDetection.createProtoChangeDetector(
|
var proto = changeDetection.createProtoChangeDetector(
|
||||||
new ChangeDetectorDefinition("proto", null, [], bindings, [directiveRecord]));
|
new ChangeDetectorDefinition("proto", null, [], bindings, [directiveRecord], false));
|
||||||
|
|
||||||
var targetObj = new Obj();
|
var targetObj = new Obj();
|
||||||
parentCd.hydrate(object, null, new FakeDirectives(targetObj), null);
|
parentCd.hydrate(object, null, new FakeDirectives(targetObj), null);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user