Skip to content

Commit

Permalink
refactor(change_detect): Move (de)hydrate logic into dedicated methods
Browse files Browse the repository at this point in the history
Add additional details here!

Update to angular#3248
  • Loading branch information
Tim Blasi committed Jul 28, 2015
1 parent 74b311a commit 18c4a25
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 35 deletions.
Expand Up @@ -60,8 +60,12 @@ export class AbstractChangeDetector implements ChangeDetector {

hydrate(context: any, locals: Locals, directives: any, pipes: any): void {}

hydrateDirectives(directives: any): void {}

dehydrate(): void {}

dehydrateDirectives(destroyPipes: boolean): void {}

callOnAllChangesDone(): void {}

_detectChangesInLightDomChildren(throwOnChange: boolean): void {
Expand Down Expand Up @@ -94,4 +98,4 @@ export class AbstractChangeDetector implements ChangeDetector {
c["locals"], c["injector"], proto.expressionAsString);
throw new ChangeDetectionError(proto, exception, stack, context);
}
}
}
Expand Up @@ -33,30 +33,31 @@ var ALREADY_CHECKED_ACCESSOR = "this.alreadyChecked";

export class ChangeDetectorJITGenerator {
_names: CodegenNameUtil;
_typeName: string;

constructor(public id: string, public changeDetectionStrategy: string,
public records: List<ProtoRecord>, public directiveRecords: List<any>,
private generateCheckNoChanges: boolean) {
this._names = new CodegenNameUtil(this.records, this.directiveRecords, 'this._', UTIL);
this._typeName = sanitizeName(`ChangeDetector_${this.id}`);
}

generate(): Function {
var typeName = sanitizeName(`ChangeDetector_${this.id}`);
var classDefinition = `
var ${typeName} = function ${typeName}(dispatcher, protos, directiveRecords) {
var ${this._typeName} = function ${this._typeName}(dispatcher, protos, directiveRecords) {
${ABSTRACT_CHANGE_DETECTOR}.call(this, ${JSON.stringify(this.id)}, dispatcher);
${PROTOS_ACCESSOR} = protos;
${DIRECTIVES_ACCESSOR} = directiveRecords;
${LOCALS_ACCESSOR} = null;
${CURRENT_PROTO} = null;
${PIPES_ACCESSOR} = null;
${ALREADY_CHECKED_ACCESSOR} = false;
${this._names.genDehydrateFields()}
this.dehydrateDirectives(false);
}
${typeName}.prototype = Object.create(${ABSTRACT_CHANGE_DETECTOR}.prototype);
${this._typeName}.prototype = Object.create(${ABSTRACT_CHANGE_DETECTOR}.prototype);
${typeName}.prototype.detectChangesInRecords = function(throwOnChange) {
${this._typeName}.prototype.detectChangesInRecords = function(throwOnChange) {
if (!this.hydrated()) {
${UTIL}.throwDehydrated();
}
Expand All @@ -67,7 +68,7 @@ export class ChangeDetectorJITGenerator {
}
}
${typeName}.prototype.__detectChangesInRecords = function(throwOnChange) {
${this._typeName}.prototype.__detectChangesInRecords = function(throwOnChange) {
${CURRENT_PROTO} = null;
${this._names.genInitLocals()}
Expand All @@ -81,35 +82,37 @@ export class ChangeDetectorJITGenerator {
${ALREADY_CHECKED_ACCESSOR} = true;
}
${this._genCheckNoChanges(typeName)}
${this._genCheckNoChanges(this._typeName)}
${typeName}.prototype.callOnAllChangesDone = function() {
${this._typeName}.prototype.callOnAllChangesDone = function() {
${this._genCallOnAllChangesDoneBody()}
}
${typeName}.prototype.hydrate = function(context, locals, directives, pipes) {
${this._typeName}.prototype.hydrate = function(context, locals, directives, pipes) {
${MODE_ACCESSOR} = "${ChangeDetectionUtil.changeDetectionMode(this.changeDetectionStrategy)}";
${this._names.getContextName()} = context;
${LOCALS_ACCESSOR} = locals;
${this._genHydrateDirectives()}
${this._genHydrateDetectors()}
this.hydrateDirectives(directives);
${PIPES_ACCESSOR} = pipes;
${ALREADY_CHECKED_ACCESSOR} = false;
}
${typeName}.prototype.dehydrate = function() {
${this._names.genPipeOnDestroy()}
${this._names.genDehydrateFields()}
${this._maybeGenHydrateDirectives()}
${this._typeName}.prototype.dehydrate = function() {
this.dehydrateDirectives(true);
${LOCALS_ACCESSOR} = null;
${PIPES_ACCESSOR} = null;
}
${typeName}.prototype.hydrated = function() {
${this._maybeGenDehydrateDirectives()}
${this._typeName}.prototype.hydrated = function() {
return ${this._names.getContextName()} !== null;
}
return function(dispatcher) {
return new ${typeName}(dispatcher, protos, directiveRecords);
return new ${this._typeName}(dispatcher, protos, directiveRecords);
}
`;

Expand All @@ -118,6 +121,29 @@ export class ChangeDetectorJITGenerator {
AbstractChangeDetector, ChangeDetectionUtil, this.records, this.directiveRecords);
}

_maybeGenDehydrateDirectives(): string {
var destroyPipesCode = this._names.genPipeOnDestroy();
if (destroyPipesCode) {
destroyPipesCode = `if (destroyPipes) { ${destroyPipesCode} }`;
}
var dehydrateFieldsCode = this._names.genDehydrateFields();
if (!destroyPipesCode && !dehydrateFieldsCode) return '';
return `${this._typeName}.prototype.dehydrateDirectives = function(destroyPipes) {
${destroyPipesCode}
${dehydrateFieldsCode}
}`;
}

_maybeGenHydrateDirectives(): string {
var hydrateDirectivesCode = this._genHydrateDirectives();
var hydrateDetectorsCode = this._genHydrateDetectors();
if (!hydrateDirectivesCode && !hydrateDetectorsCode) return '';
return `${this._typeName}.prototype.hydrateDirectives = function(directives) {
${hydrateDirectivesCode}
${hydrateDetectorsCode}
}`;
}

_genHydrateDirectives(): string {
var directiveFieldNames = this._names.getAllDirectiveNames();
var lines = ListWrapper.createFixedSize(directiveFieldNames.length);
Expand Down
Expand Up @@ -78,7 +78,8 @@ class _CodegenState {

_CodegenState._(this._changeDetectorDefId, this._contextTypeName,
this._changeDetectorTypeName, String changeDetectionStrategy,
List<ProtoRecord> records, List<DirectiveRecord> directiveRecords, this._generateCheckNoChanges)
List<ProtoRecord> records, List<DirectiveRecord> directiveRecords,
this._generateCheckNoChanges)
: _records = records,
_directiveRecords = directiveRecords,
_names = new CodegenNameUtil(records, directiveRecords, '_', _UTIL),
Expand All @@ -92,7 +93,8 @@ class _CodegenState {
.forEach((rec) => protoRecords.add(rec, def.variableNames));
var records = coalesce(protoRecords.records);
return new _CodegenState._(def.id, typeName, changeDetectorTypeName,
def.strategy, records, def.directiveRecords, def.generateCheckNoChanges);
def.strategy, records, def.directiveRecords,
def.generateCheckNoChanges);
}

void _writeToBuf(StringBuffer buf) {
Expand All @@ -113,17 +115,17 @@ class _CodegenState {
this.$_PROTOS_ACCESSOR,
this.$_DIRECTIVES_ACCESSOR)
: super(${_encodeValue(_changeDetectorDefId)}, $_DISPATCHER_ACCESSOR) {
${_names.genDehydrateFields()}
dehydrateDirectives(false);
}
void detectChangesInRecords(throwOnChange) {
if (!hydrated()) {
$_UTIL.throwDehydrated();
}
try {
this.__detectChangesInRecords(throwOnChange);
__detectChangesInRecords(throwOnChange);
} catch (e, s) {
this.throwError($_CURRENT_PROTO, e, s);
throwError($_CURRENT_PROTO, e, s);
}
}
Expand All @@ -149,19 +151,21 @@ class _CodegenState {
$_MODE_ACCESSOR = '$_changeDetectionMode';
${_names.getContextName()} = context;
$_LOCALS_ACCESSOR = locals;
${_genHydrateDirectives()}
${_genHydrateDetectors()}
hydrateDirectives(directives);
$_ALREADY_CHECKED_ACCESSOR = false;
$_PIPES_ACCESSOR = pipes;
}
${_maybeGenHydrateDirectives()}
void dehydrate() {
${_names.genPipeOnDestroy()}
${_names.genDehydrateFields()}
dehydrateDirectives(true);
$_LOCALS_ACCESSOR = null;
$_PIPES_ACCESSOR = null;
}
${_maybeGenDehydrateDirectives()}
hydrated() => ${_names.getContextName()} != null;
static $_GEN_PREFIX.ProtoChangeDetector
Expand All @@ -182,6 +186,34 @@ class _CodegenState {
''');
}

String _maybeGenDehydrateDirectives() {
var destroyPipesParamName = 'destroyPipes';
var destroyPipesCode = _names.genPipeOnDestroy();
if (destroyPipesCode.isNotEmpty) {
destroyPipesCode = 'if (${destroyPipesParamName}) { '
'${destroyPipesCode}'
'}';
}
var dehydrateFieldsCode = _names.genDehydrateFields();
if (destroyPipesCode.isEmpty && dehydrateFieldsCode.isEmpty) return '';
return 'void dehydrateDirectives(${destroyPipesParamName}) {'
'${destroyPipesCode}'
'${dehydrateFieldsCode}'
'}';
}

String _maybeGenHydrateDirectives() {
var hydrateDirectivesCode = _genHydrateDirectives();
var hydrateDetectorsCode = _genHydrateDetectors();
if (hydrateDirectivesCode.isEmpty && hydrateDetectorsCode.isEmpty) {
return '';
}
return 'void hydrateDirectives(directives) { '
'$hydrateDirectivesCode'
'$hydrateDetectorsCode'
'}';
}

String _genHydrateDirectives() {
var buf = new StringBuffer();
var directiveFieldNames = _names.getAllDirectiveNames();
Expand Down Expand Up @@ -410,7 +442,7 @@ class _CodegenState {

String _genCheckNoChanges() {
if (this._generateCheckNoChanges) {
return 'void checkNoChanges() { this.runDetectChanges(true); }';
return 'void checkNoChanges() { runDetectChanges(true); }';
} else {
return '';
}
Expand Down
Expand Up @@ -36,18 +36,17 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
_MyComponent_ChangeDetector0(
dynamic dispatcher, this._protos, this._directiveRecords)
: super("MyComponent_comp_0", dispatcher) {
_context = null;
_myNum0 = _interpolate1 = _gen.ChangeDetectionUtil.uninitialized;
dehydrateDirectives(false);
}

void detectChangesInRecords(throwOnChange) {
if (!hydrated()) {
_gen.ChangeDetectionUtil.throwDehydrated();
}
try {
this.__detectChangesInRecords(throwOnChange);
__detectChangesInRecords(throwOnChange);
} catch (e, s) {
this.throwError(currentProto, e, s);
throwError(currentProto, e, s);
}
}

Expand Down Expand Up @@ -91,7 +90,9 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
_alreadyChecked = true;
}

void checkNoChanges() {this.runDetectChanges(true);}
void checkNoChanges() {
runDetectChanges(true);
}

void callOnAllChangesDone() {
dispatcher.notifyOnAllChangesDone();
Expand All @@ -101,18 +102,22 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
mode = 'ALWAYS_CHECK';
_context = context;
_locals = locals;

hydrateDirectives(directives);
_alreadyChecked = false;
_pipes = pipes;
}

void dehydrate() {
_context = null;
_myNum0 = _interpolate1 = _gen.ChangeDetectionUtil.uninitialized;
dehydrateDirectives(true);
_locals = null;
_pipes = null;
}

void dehydrateDirectives(destroyPipes) {
_context = null;
_myNum0 = _interpolate1 = _gen.ChangeDetectionUtil.uninitialized;
}

hydrated() => _context != null;

static _gen.ProtoChangeDetector newProtoChangeDetector(
Expand Down

0 comments on commit 18c4a25

Please sign in to comment.