refactor(change_detect): Abstract name logic into NameRegistry
Create `NameRegistry`, responsible for understanding how names are generated for change detector fields and variables. Use `NameRegistry` for both JS Jit & Dart pre-generated detectors. Making progress on #3248
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,134 @@
|
||||
import {RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
|
||||
import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
import {DirectiveIndex} from './directive_record';
|
||||
|
||||
import {ProtoRecord} from './proto_record';
|
||||
|
||||
// `context` is always the first field.
|
||||
var _CONTEXT_IDX = 0;
|
||||
|
||||
var _whiteSpaceRegExp = RegExpWrapper.create("\\W", "g");
|
||||
|
||||
/**
|
||||
* Returns `s` with all non-identifier characters removed.
|
||||
*/
|
||||
export function sanitizeName(s: string): string {
|
||||
return StringWrapper.replaceAll(s, _whiteSpaceRegExp, '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Class responsible for providing field and local variable names for change detector classes.
|
||||
* Also provides some convenience functions, for example, declaring variables, destroying pipes,
|
||||
* and dehydrating the detector.
|
||||
*/
|
||||
export class CodegenNameUtil {
|
||||
/**
|
||||
* Record names sanitized for use as fields.
|
||||
* See [sanitizeName] for details.
|
||||
*/
|
||||
_sanitizedNames: List<string>;
|
||||
|
||||
constructor(public records: List<ProtoRecord>, public directiveRecords: List<any>,
|
||||
public fieldPrefix: string, public utilName: string) {
|
||||
this._sanitizedNames = ListWrapper.createFixedSize(this.records.length + 1);
|
||||
this._sanitizedNames[_CONTEXT_IDX] = 'context';
|
||||
for (var i = 0, iLen = this.records.length; i < iLen; ++i) {
|
||||
this._sanitizedNames[i + 1] = sanitizeName(`${this.records[i].name}${i}`);
|
||||
}
|
||||
}
|
||||
|
||||
getContextName(): string { return this.getFieldName(_CONTEXT_IDX); }
|
||||
|
||||
getLocalName(idx: int): string { return this._sanitizedNames[idx]; }
|
||||
|
||||
getChangeName(idx: int): string { return `c_${this._sanitizedNames[idx]}`; }
|
||||
|
||||
/**
|
||||
* Generate a statement initializing local variables used when detecting changes.
|
||||
*/
|
||||
genInitLocals(): string {
|
||||
var declarations = [];
|
||||
var assignments = [];
|
||||
for (var i = 0, iLen = this.getFieldCount(); i < iLen; ++i) {
|
||||
var changeName = this.getChangeName(i);
|
||||
declarations.push(`${this.getLocalName(i)},${changeName}`);
|
||||
assignments.push(changeName);
|
||||
}
|
||||
return `var ${ListWrapper.join(declarations, ',')};` +
|
||||
`${ListWrapper.join(assignments, '=')} = false;`;
|
||||
}
|
||||
|
||||
getFieldCount(): int { return this._sanitizedNames.length; }
|
||||
|
||||
getFieldName(idx: int): string { return `${this.fieldPrefix}${this._sanitizedNames[idx]}`; }
|
||||
|
||||
getAllFieldNames(): List<string> {
|
||||
var fieldList = [];
|
||||
for (var k = 0, kLen = this.getFieldCount(); k < kLen; ++k) {
|
||||
fieldList.push(this.getFieldName(k));
|
||||
}
|
||||
for (var i = 0, iLen = this.records.length; i < iLen; ++i) {
|
||||
var rec = this.records[i];
|
||||
if (rec.isPipeRecord()) {
|
||||
fieldList.push(this.getPipeName(rec.selfIndex));
|
||||
}
|
||||
}
|
||||
for (var j = 0, jLen = this.directiveRecords.length; j < jLen; ++j) {
|
||||
var dRec = this.directiveRecords[j];
|
||||
fieldList.push(this.getDirectiveName(dRec.directiveIndex));
|
||||
if (dRec.isOnPushChangeDetection()) {
|
||||
fieldList.push(this.getDetectorName(dRec.directiveIndex));
|
||||
}
|
||||
}
|
||||
return fieldList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a statement which declares all fields.
|
||||
* This is only necessary for Dart change detectors.
|
||||
*/
|
||||
genDeclareFields(): string {
|
||||
var fields = this.getAllFieldNames();
|
||||
ListWrapper.removeAt(fields, _CONTEXT_IDX);
|
||||
return ListWrapper.isEmpty(fields) ? '' : `var ${ListWrapper.join(fields, ', ')};`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates statements which clear all fields so that the change detector is dehydrated.
|
||||
*/
|
||||
genDehydrateFields(): string {
|
||||
var fields = this.getAllFieldNames();
|
||||
ListWrapper.removeAt(fields, _CONTEXT_IDX);
|
||||
if (!ListWrapper.isEmpty(fields)) {
|
||||
// At least one assignment.
|
||||
fields.push(`${this.utilName}.uninitialized();`);
|
||||
}
|
||||
return `${this.getContextName()} = null; ${ListWrapper.join(fields, ' = ')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates statements destroying all pipe variables.
|
||||
*/
|
||||
genPipeOnDestroy(): string {
|
||||
return ListWrapper.join(ListWrapper.map(ListWrapper.filter(this.records, (r) => {
|
||||
return r.isPipeRecord();
|
||||
}), (r) => { return `${this.getPipeName(r.selfIndex)}.onDestroy();`; }), '\n');
|
||||
}
|
||||
|
||||
getPipeName(idx: int): string { return `${this.fieldPrefix}${this._sanitizedNames[idx]}_pipe`; }
|
||||
|
||||
getAllDirectiveNames(): List<string> {
|
||||
return ListWrapper.map(this.directiveRecords, d => this.getDirectiveName(d.directiveIndex));
|
||||
}
|
||||
|
||||
getDirectiveName(d: DirectiveIndex): string { return `${this.fieldPrefix}directive_${d.name}`; }
|
||||
|
||||
getAllDetectorNames(): List<string> {
|
||||
return ListWrapper.map(
|
||||
ListWrapper.filter(this.directiveRecords, r => r.isOnPushChangeDetection()),
|
||||
(d) => this.getDetectorName(d.directiveIndex));
|
||||
}
|
||||
|
||||
getDetectorName(d: DirectiveIndex): string { return `${this.fieldPrefix}detector_${d.name}`; }
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+12
-15
@@ -30,13 +30,15 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||
dynamic _locals = null;
|
||||
dynamic _alreadyChecked = false;
|
||||
dynamic currentProto = null;
|
||||
MyComponent _context = null;
|
||||
dynamic _myNum0 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
dynamic _interpolate1 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
MyComponent _context;
|
||||
var _myNum0, _interpolate1;
|
||||
|
||||
_MyComponent_ChangeDetector0(
|
||||
dynamic dispatcher, this._protos, this._directiveRecords)
|
||||
: super("MyComponent_comp_0", dispatcher);
|
||||
: super("MyComponent_comp_0", dispatcher) {
|
||||
_context = null;
|
||||
_myNum0 = _interpolate1 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
}
|
||||
|
||||
void detectChangesInRecords(throwOnChange) {
|
||||
if (!hydrated()) {
|
||||
@@ -50,12 +52,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||
}
|
||||
|
||||
void __detectChangesInRecords(throwOnChange) {
|
||||
var context = null;
|
||||
var myNum0 = null;
|
||||
var interpolate1 = null;
|
||||
var change_context = false;
|
||||
var change_myNum0 = false;
|
||||
var change_interpolate1 = false;
|
||||
var context, c_context, myNum0, c_myNum0, interpolate1, c_interpolate1;
|
||||
c_context = c_myNum0 = c_interpolate1 = false;
|
||||
var isChanged = false;
|
||||
currentProto = null;
|
||||
var changes = null;
|
||||
@@ -64,15 +62,15 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||
currentProto = _protos[0];
|
||||
myNum0 = context.myNum;
|
||||
if (!_gen.looseIdentical(myNum0, _myNum0)) {
|
||||
change_myNum0 = true;
|
||||
c_myNum0 = true;
|
||||
|
||||
_myNum0 = myNum0;
|
||||
}
|
||||
if (change_myNum0) {
|
||||
if (c_myNum0) {
|
||||
currentProto = _protos[1];
|
||||
interpolate1 = "Salad: " "${myNum0 == null ? "" : myNum0}" " is awesome";
|
||||
if (!_gen.looseIdentical(interpolate1, _interpolate1)) {
|
||||
change_interpolate1 = true;
|
||||
c_interpolate1 = true;
|
||||
if (throwOnChange) {
|
||||
_gen.ChangeDetectionUtil.throwOnChange(currentProto,
|
||||
_gen.ChangeDetectionUtil.simpleChange(
|
||||
@@ -108,8 +106,7 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||
|
||||
void dehydrate() {
|
||||
_context = null;
|
||||
_myNum0 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
_interpolate1 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
_myNum0 = _interpolate1 = _gen.ChangeDetectionUtil.uninitialized();
|
||||
_locals = null;
|
||||
_pipes = null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user