Revert "feat(iterable_differ): support immutable lists"

In Dart, ImmutableLists are just a projection of an underlying list.
I.e. if the underlying list changes, the ImmutableList also changes.
So we can't make optimizations based on checking whether a collection
is an ImmutableList.

This reverts commit a10c02cb41.

Closes #8023
This commit is contained in:
Tobias Bosch 2016-04-12 08:02:59 -07:00
parent 01e6b8c7ed
commit d24df799d3
4 changed files with 19 additions and 63 deletions

View File

@ -109,6 +109,7 @@ export class DefaultIterableDiffer implements IterableDiffer {
onDestroy() {} onDestroy() {}
// todo(vicb): optim for UnmodifiableListView (frozen arrays)
check(collection: any): boolean { check(collection: any): boolean {
this._reset(); this._reset();
@ -118,27 +119,24 @@ export class DefaultIterableDiffer implements IterableDiffer {
var item; var item;
var itemTrackBy; var itemTrackBy;
if (isArray(collection)) { if (isArray(collection)) {
if (collection !== this._collection || !ListWrapper.isImmutable(collection)) { var list = collection;
var list = collection; this._length = collection.length;
this._length = collection.length;
for (index = 0; index < this._length; index++) { for (index = 0; index < this._length; index++) {
item = list[index]; item = list[index];
itemTrackBy = this._trackByFn(index, item); itemTrackBy = this._trackByFn(index, item);
if (record === null || !looseIdentical(record.trackById, itemTrackBy)) { if (record === null || !looseIdentical(record.trackById, itemTrackBy)) {
record = this._mismatch(record, item, itemTrackBy, index); record = this._mismatch(record, item, itemTrackBy, index);
mayBeDirty = true; mayBeDirty = true;
} else { } else {
if (mayBeDirty) { if (mayBeDirty) {
// TODO(misko): can we limit this to duplicates only? // TODO(misko): can we limit this to duplicates only?
record = this._verifyReinsertion(record, item, itemTrackBy, index); record = this._verifyReinsertion(record, item, itemTrackBy, index);
}
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
} }
if (!looseIdentical(record.item, item)) this._addIdentityChange(record, item);
record = record._next;
} }
this._truncate(record);
record = record._next;
} }
} else { } else {
index = 0; index = 0;
@ -158,9 +156,9 @@ export class DefaultIterableDiffer implements IterableDiffer {
index++; index++;
}); });
this._length = index; this._length = index;
this._truncate(record);
} }
this._truncate(record);
this._collection = collection; this._collection = collection;
return this.isDirty; return this.isDirty;
} }

View File

@ -1,6 +1,6 @@
library facade.collection; library facade.collection;
import 'dart:collection' show IterableBase, UnmodifiableListView; import 'dart:collection' show IterableBase;
import 'dart:convert' show JsonEncoder; import 'dart:convert' show JsonEncoder;
export 'dart:core' show Iterator, Map, List, Set; export 'dart:core' show Iterator, Map, List, Set;
import 'dart:math' show max, min; import 'dart:math' show max, min;
@ -110,9 +110,6 @@ class ListWrapper {
static List/*<T>*/ createFixedSize/*<T>*/(int size) => new List(size); static List/*<T>*/ createFixedSize/*<T>*/(int size) => new List(size);
static List/*<T>*/ createGrowableSize/*<T>*/(int size) => static List/*<T>*/ createGrowableSize/*<T>*/(int size) =>
new List.generate(size, (_) => null, growable: true); new List.generate(size, (_) => null, growable: true);
static UnmodifiableListView createImmutable(List input) {
return new UnmodifiableListView(input);
}
static bool contains(List m, k) => m.contains(k); static bool contains(List m, k) => m.contains(k);
static int indexOf(List list, value, [int startIndex = 0]) => static int indexOf(List list, value, [int startIndex = 0]) =>
@ -229,10 +226,6 @@ class ListWrapper {
return solution; return solution;
} }
static bool isImmutable(List l) {
return l is UnmodifiableListView;
}
static List flatten(List l) { static List flatten(List l) {
final res = []; final res = [];
l.forEach((item) { l.forEach((item) {

View File

@ -184,11 +184,6 @@ export class ListWrapper {
static createFixedSize(size: number): any[] { return new Array(size); } static createFixedSize(size: number): any[] { return new Array(size); }
static createGrowableSize(size: number): any[] { return new Array(size); } static createGrowableSize(size: number): any[] { return new Array(size); }
static clone<T>(array: T[]): T[] { return array.slice(0); } static clone<T>(array: T[]): T[] { return array.slice(0); }
static createImmutable<T>(array: T[]): T[] {
var result = ListWrapper.clone(array);
Object.seal(result);
return result;
}
static forEachWithIndex<T>(array: T[], fn: (t: T, n: number) => void) { static forEachWithIndex<T>(array: T[], fn: (t: T, n: number) => void) {
for (var i = 0; i < array.length; i++) { for (var i = 0; i < array.length; i++) {
fn(array[i], i); fn(array[i], i);
@ -277,7 +272,6 @@ export class ListWrapper {
return solution; return solution;
} }
static isImmutable(list: any[]): boolean { return Object.isSealed(list); }
static flatten<T>(array: T[][]): T[] { static flatten<T>(array: T[][]): T[] {
let res = []; let res = [];
array.forEach((a) => res = res.concat(a)); array.forEach((a) => res = res.concat(a));

View File

@ -31,6 +31,7 @@ class ComplexItem {
toString() { return `{id: ${this.id}, color: ${this.color}}` } toString() { return `{id: ${this.id}, color: ${this.color}}` }
} }
// todo(vicb): UnmodifiableListView / frozen object when implemented
export function main() { export function main() {
describe('iterable differ', function() { describe('iterable differ', function() {
describe('DefaultIterableDiffer', function() { describe('DefaultIterableDiffer', function() {
@ -313,36 +314,6 @@ export function main() {
})); }));
}); });
it('should not diff immutable collections if they are the same', () => {
// Note: Use trackBy to know if diffing happened
var trackByCount = 0;
var trackBy = (index: number, item: any): any => {
trackByCount++;
return item;
};
var differ = new DefaultIterableDiffer(trackBy);
var l1 = ListWrapper.createImmutable([1]);
differ.check(l1);
expect(trackByCount).toBe(1);
expect(differ.toString())
.toEqual(
iterableChangesAsString({collection: ['1[null->0]'], additions: ['1[null->0]']}));
trackByCount = 0;
differ.check(l1);
expect(trackByCount).toBe(0);
expect(differ.toString())
.toEqual(iterableChangesAsString({collection: ['1'], previous: ['1']}));
trackByCount = 0;
differ.check(l1);
expect(trackByCount).toBe(0);
expect(differ.toString())
.toEqual(iterableChangesAsString({collection: ['1'], previous: ['1']}));
});
describe('diff', () => { describe('diff', () => {
it('should return self when there is a change', it('should return self when there is a change',
() => { expect(differ.diff(['a', 'b'])).toBe(differ); }); () => { expect(differ.diff(['a', 'b'])).toBe(differ); });