Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/change_detection/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ class FieldReadAST extends AST {
final String name;

FieldReadAST(lhs, name)
: super('$lhs.$name'),
lhs = lhs,
name = name;
: lhs = lhs,
name = name,
super('$lhs.$name');

WatchRecord<_Handler> setupWatch(WatchGroup watchGroup) =>
watchGroup.addFieldWatch(lhs, name, expression);
Expand Down Expand Up @@ -111,14 +111,14 @@ class MethodAST extends AST {
class CollectionAST extends AST {
final AST valueAST;
CollectionAST(valueAST)
: super('#collection($valueAST)'),
valueAST = valueAST;
: valueAST = valueAST,
super('#collection($valueAST)');

WatchRecord<_Handler> setupWatch(WatchGroup watchGroup) =>
watchGroup.addCollectionWatch(valueAST);
}

_argList(List<AST> items) => items.join(', ');
String _argList(List<AST> items) => items.join(', ');

/**
* The name is a bit oxymoron, but it is essentially the NullObject pattern.
Expand Down
50 changes: 25 additions & 25 deletions lib/change_detection/change_detection.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ abstract class ChangeDetectorGroup<H> {
* Watch a specific [field] on an [object].
*
* If the [field] is:
* - _name_ - Name of the field to watch. (If the [object] is a Map then
* treat it as a key.)
* - _name_ - Name of the property to watch. (If the [object] is a Map then
* treat the name as a key.)
* - _[]_ - Watch all items in an array.
* - _{}_ - Watch all items in a Map.
* - _._ - Watch the actual object identity.
Expand Down Expand Up @@ -51,8 +51,8 @@ abstract class ChangeDetectorGroup<H> {
abstract class ChangeDetector<H> extends ChangeDetectorGroup<H> {
/**
* This method does the work of collecting the changes and returns them as a
* linked list of [ChangeRecord]s. The [ChangeRecord]s are to be returned in
* the same order as they were registered.
* linked list of [ChangeRecord]s. The [ChangeRecord]s are returned in the
* same order as they were registered.
*/
ChangeRecord<H> collectChanges([EvalExceptionHandler exceptionHandler]);
}
Expand Down Expand Up @@ -93,7 +93,7 @@ abstract class WatchRecord<H> extends Record<H> {

/**
* Check to see if the field on the object has changed. Returns [null] if no
* change, or a [ChangeRecord] if the change has been detected.
* change, or a [ChangeRecord] if a change has been detected.
*/
ChangeRecord<H> check();

Expand All @@ -111,11 +111,11 @@ abstract class ChangeRecord<H> extends Record<H> {
}

/**
* If [ChangeDetector] is watching a an [Map] then the
* [currentValue] of [Record] will contain this object. The object contains a
* summary of changes to the map since the last execution. The changes
* are reported as a list of [MapKeyValue]s which contain the current
* and previous value in the list as well as the key.
* If the [ChangeDetector] is watching a [Map] then the [currentValue] of
* [Record] will contain an instance of this object. A [MapChangeRecord]
* contains the changes to the map since the last execution. The changes are
* reported as a list of [MapKeyValue]s which contain the key as well as its
* current and previous value.
*/
abstract class MapChangeRecord<K, V> {
/// The underlying iterable object
Expand Down Expand Up @@ -168,11 +168,11 @@ abstract class ChangedKeyValue<K, V> extends MapKeyValue<K, V> {


/**
* If [ChangeDetector] is watching a an [Iterable] then the
* [currentValue] of [Record] will contain this object. The object contains a
* summary of changes to the collection since the last execution. The changes
* are reported as a list of [CollectionChangeItem]s which contain the current
* and previous position in the list as well as the item.
* If the [ChangeDetector] is watching an [Iterable] then the [currentValue] of
* [Record] will contain this object. The [CollectionChangeRecord] contains the
* changes to the collection since the last execution. The changes are reported
* as a list of [CollectionChangeItem]s which contain the item as well as its
* current and previous position in the list.
*/
abstract class CollectionChangeRecord<K, V> {
/** The underlying iterable object */
Expand All @@ -193,8 +193,8 @@ abstract class CollectionChangeRecord<K, V> {
}

/**
* Each item in collection is wrapped in [CollectionChangeItem], which can track
* the [item]s [currentKey] and [previousKey] location.
* Each changed item in the collection is wrapped in a [CollectionChangeItem],
* which tracks the [item]s [currentKey] and [previousKey] location.
*/
abstract class CollectionChangeItem<K, V> { // TODO(misko): change <K,V> to <V> since K is int.
/** Previous item location in the list or [null] if addition. */
Expand All @@ -208,32 +208,32 @@ abstract class CollectionChangeItem<K, V> { // TODO(misko): change <K,V> to <V>
}

/**
* Used to create a linked list of collection items.
* These items are always in the iteration order of the collection.
* Used to create a linked list of collection items. These items are always in
* the iteration order of the collection.
*/
abstract class CollectionItem<K, V> extends CollectionChangeItem<K, V> {
CollectionItem<K, V> get nextCollectionItem;
}

/**
* A linked list of new items added to the collection.
* These items are always in the iteration order of the collection.
* A linked list of new items added to the collection. These items are always in
* the iteration order of the collection.
*/
abstract class AddedItem<K, V> extends CollectionChangeItem<K, V> {
AddedItem<K, V> get nextAddedItem;
}

/**
* A linked list of moved items in to the collection.
* These items are always in the iteration order of the collection.
* A linked list of items moved in the collection. These items are always in
* the iteration order of the collection.
*/
abstract class MovedItem<K, V> extends CollectionChangeItem<K, V> {
MovedItem<K, V> get nextMovedItem;
}

/**
* A linked list of removed items in to the collection.
* These items are always in the iteration order of the collection.
* A linked list of items removed from the collection. These items are always
* in the iteration order of the collection.
*/
abstract class RemovedItem<K, V> extends CollectionChangeItem<K, V> {
RemovedItem<K, V> get nextRemovedItem;
Expand Down
43 changes: 29 additions & 14 deletions lib/change_detection/dirty_checking_change_detector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -557,11 +557,10 @@ class _MapChangeRecord<K, V> implements MapChangeRecord<K, V> {
}
}

bool _isInRemovals(KeyValueRecord record) {
return record == _removalsHead ||
record._nextRemovedKeyValue != null ||
record._prevRemovedKeyValue != null;
}
bool _isInRemovals(KeyValueRecord record) =>
record == _removalsHead ||
record._nextRemovedKeyValue != null ||
record._prevRemovedKeyValue != null;

void _addToRemovals(KeyValueRecord record) {
assert(record._nextKeyValue == null);
Expand All @@ -580,7 +579,11 @@ class _MapChangeRecord<K, V> implements MapChangeRecord<K, V> {

void _removeFromSeq(KeyValueRecord prev, KeyValueRecord record) {
KeyValueRecord next = record._nextKeyValue;
if (prev == null) _mapHead = next; else prev._nextKeyValue = next;
if (prev == null) {
_mapHead = next;
} else {
prev._nextKeyValue = next;
}
assert((() {
record._nextKeyValue = null;
return true;
Expand All @@ -594,8 +597,16 @@ class _MapChangeRecord<K, V> implements MapChangeRecord<K, V> {

var prev = record._prevRemovedKeyValue;
var next = record._nextRemovedKeyValue;
if (prev == null) _removalsHead = next; else prev._nextRemovedKeyValue = next;
if (next == null) _removalsTail = prev; else next._prevRemovedKeyValue = prev;
if (prev == null) {
_removalsHead = next;
} else {
prev._nextRemovedKeyValue = next;
}
if (next == null) {
_removalsTail = prev;
} else {
next._prevRemovedKeyValue = prev;
}
record._prevRemovedKeyValue = record._nextRemovedKeyValue = null;
}

Expand Down Expand Up @@ -627,7 +638,8 @@ class _MapChangeRecord<K, V> implements MapChangeRecord<K, V> {
}
}

class KeyValueRecord<K, V> implements KeyValue<K, V>, AddedKeyValue<K, V>, RemovedKeyValue<K, V>, ChangedKeyValue<K, V> {
class KeyValueRecord<K, V> implements KeyValue<K, V>, AddedKeyValue<K, V>,
RemovedKeyValue<K, V>, ChangedKeyValue<K, V> {
final K key;
V _previousValue, _currentValue;

Expand Down Expand Up @@ -706,7 +718,7 @@ class _CollectionChangeRecord<K, V> implements CollectionChangeRecord<K, V> {
return false;
} else if (collection is List) {
List list = collection;
for(int index = 0, length = list.length; index < length; index++) {
for(int index = 0; index < list.length; index++) {
var item = list[index];
if (record == null || !identical(item, record.item)) {
record = mismatch(record, item, index);
Expand Down Expand Up @@ -779,7 +791,7 @@ class _CollectionChangeRecord<K, V> implements CollectionChangeRecord<K, V> {
* - [item] is the current item in the collection
* - [index] is the position of the item in the collection
*/
ItemRecord mismatch(ItemRecord record, dynamic item, int index) {
ItemRecord mismatch(ItemRecord record, item, int index) {
// Guard against bogus String changes
if (record != null && item is String && record.item is String &&
record.item == item) {
Expand Down Expand Up @@ -1081,7 +1093,11 @@ class _DuplicateItemRecordList {
var next = beforeRecord;
record._prevDupRec = prev;
record._nextDupRec = next;
if (prev == null) head = record; else prev._nextDupRec = record;
if (prev == null) {
head = record;
} else {
prev._nextDupRec = record;
}
next._prevDupRec = record;
}
}
Expand Down Expand Up @@ -1135,8 +1151,7 @@ class _DuplicateItemRecordList {
* key.
*/
class DuplicateMap {
final Map<dynamic, _DuplicateItemRecordList> map =
new Map<dynamic, _DuplicateItemRecordList>();
final map = <dynamic, _DuplicateItemRecordList>{};

void put(ItemRecord record, [ItemRecord beforeRecord = null]) {
assert(record._nextDupRec == null);
Expand Down
39 changes: 26 additions & 13 deletions lib/change_detection/prototype_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ part of angular.watch_group;
class PrototypeMap<K, V> implements Map<K,V> {
final Map<K, V> prototype;
final Map<K, V> self = new Map();

PrototypeMap(this.prototype);

operator []=(name, value) => self[name] = value;
operator [](name) => self.containsKey(name) ? self[name] : prototype[name];
void operator []=(name, value) {
self[name] = value;
}
V operator [](name) => self.containsKey(name) ? self[name] : prototype[name];

get isEmpty => self.isEmpty && prototype.isEmpty;
get isNotEmpty => self.isNotEmpty || prototype.isNotEmpty;
get keys => self.keys;
get values => self.values;
get length => self.length;
bool get isEmpty => self.isEmpty && prototype.isEmpty;
bool get isNotEmpty => self.isNotEmpty || prototype.isNotEmpty;
// todo(vbe) include prototype keys ?
Iterable<K> get keys => self.keys;
// todo(vbe) include prototype values ?
Iterable<V> get values => self.values;
int get length => self.length;

forEach(fn) => self.forEach(fn);
remove(key) => self.remove(key);
void forEach(fn) {
// todo(vbe) include prototype ?
self.forEach(fn);
}
V remove(key) => self.remove(key);
clear() => self.clear;
containsKey(key) => self.containsKey(key);
containsValue(key) => self.containsValue(key);
addAll(map) => self.addAll(map);
putIfAbsent(key, fn) => self.putIfAbsent(key, fn);
// todo(vbe) include prototype ?
bool containsKey(key) => self.containsKey(key);
// todo(vbe) include prototype ?
bool containsValue(key) => self.containsValue(key);
void addAll(map) {
self.addAll(map);
}
// todo(vbe) include prototype ?
V putIfAbsent(key, fn) => self.putIfAbsent(key, fn);
}
Loading