Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(498)

Side by Side Diff: pkg/yaml/lib/src/deep_equals.dart

Issue 274953002: Bring the YAML package's style up to modern standards. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library deep_equals; 5 library yaml.deep_equals;
6 6
7 /// Returns whether two objects are structurally equivalent. This considers NaN 7 /// Returns whether two objects are structurally equivalent.
8 /// values to be equivalent. It also handles self-referential structures. 8 ///
9 bool deepEquals(obj1, obj2, [List parents1, List parents2]) { 9 /// This considers `NaN` values to be equivalent. It also handles
10 if (identical(obj1, obj2)) return true; 10 /// self-referential structures.
11 if (parents1 == null) { 11 bool deepEquals(obj1, obj2) => new _DeepEquals().equals(obj1, obj2);
12 parents1 = []; 12
13 parents2 = []; 13 /// A class that provides access to the list of parent objects used for loop
14 /// detection.
15 class _DeepEquals {
16 final _parents1 = [];
17 final _parents2 = [];
18
19 /// Returns whether [obj1] and [obj2] are structurally equivalent.
20 bool equals(obj1, obj2) {
21 // _parents1 and _parents2 are guaranteed to be the same size.
22 for (var i = 0; i < _parents1.length; i++) {
23 var loop1 = identical(obj1, _parents1[i]);
24 var loop2 = identical(obj2, _parents2[i]);
25 // If both structures loop in the same place, they're equal at that point in
Bob Nystrom 2014/05/09 00:18:56 Long line.
nweiz 2014/05/20 00:15:07 Done.
26 // the structure. If one loops and the other doesn't, they're not equal.
27 if (loop1 && loop2) return true;
28 if (loop1 || loop2) return false;
29 }
30
31 _parents1.add(obj1);
32 _parents2.add(obj2);
33 try {
34 if (obj1 is List && obj2 is List) {
35 return _listEquals(obj1, obj2);
36 } else if (obj1 is Map && obj2 is Map) {
37 return _mapEquals(obj1, obj2);
38 } else if (obj1 is num && obj2 is num) {
39 return _numEquals(obj1, obj2);
40 } else {
41 return obj1 == obj2;
42 }
43 } finally {
44 _parents1.removeLast();
45 _parents2.removeLast();
46 }
14 } 47 }
15 48
16 // parents1 and parents2 are guaranteed to be the same size. 49 /// Returns whether [list1] and [list2] are structurally equal.
17 for (var i = 0; i < parents1.length; i++) { 50 bool _listEquals(List list1, List list2) {
18 var loop1 = identical(obj1, parents1[i]); 51 if (list1.length != list2.length) return false;
19 var loop2 = identical(obj2, parents2[i]); 52
20 // If both structures loop in the same place, they're equal at that point in 53 for (var i = 0; i < list1.length; i++) {
21 // the structure. If one loops and the other doesn't, they're not equal. 54 if (!equals(list1[i], list2[i])) return false;
22 if (loop1 && loop2) return true; 55 }
23 if (loop1 || loop2) return false; 56
57 return true;
24 } 58 }
25 59
26 parents1.add(obj1); 60 /// Returns whether [map1] and [map2] are structurally equal.
27 parents2.add(obj2); 61 bool _mapEquals(Map map1, Map map2) {
28 try { 62 if (map1.length != map2.length) return false;
29 if (obj1 is List && obj2 is List) { 63
30 return _listEquals(obj1, obj2, parents1, parents2); 64 for (var key in map1.keys) {
31 } else if (obj1 is Map && obj2 is Map) { 65 if (!map2.containsKey(key)) return false;
Bob Nystrom 2014/05/09 00:18:56 What about extra keys in map2?
nweiz 2014/05/20 00:15:07 We check that they're the same length above. If th
32 return _mapEquals(obj1, obj2, parents1, parents2); 66 if (!equals(map1[key], map2[key])) return false;
33 } else if (obj1 is double && obj2 is double) {
34 return _doubleEquals(obj1, obj2);
35 } else {
36 return obj1 == obj2;
37 } 67 }
38 } finally { 68
39 parents1.removeLast(); 69 return true;
40 parents2.removeLast(); 70 }
71
72 /// Returns whether two numbers are equivalent.
73 ///
74 /// This differs from `n1 == n2` in that it considers `NaN` to be equal to
75 /// itself.
76 bool _numEquals(num n1, num n2) {
77 if (n1.isNaN && n2.isNaN) return true;
78 return n1 == n2;
41 } 79 }
42 } 80 }
43
44 /// Returns whether [list1] and [list2] are structurally equal.
45 bool _listEquals(List list1, List list2, List parents1, List parents2) {
46 if (list1.length != list2.length) return false;
47
48 for (var i = 0; i < list1.length; i++) {
49 if (!deepEquals(list1[i], list2[i], parents1, parents2)) return false;
50 }
51
52 return true;
53 }
54
55 /// Returns whether [map1] and [map2] are structurally equal.
56 bool _mapEquals(Map map1, Map map2, List parents1, List parents2) {
57 if (map1.length != map2.length) return false;
58
59 for (var key in map1.keys) {
60 if (!map2.containsKey(key)) return false;
61 if (!deepEquals(map1[key], map2[key], parents1, parents2)) return false;
62 }
63
64 return true;
65 }
66
67 /// Returns whether two doubles are equivalent. This differs from `d1 == d2` in
68 /// that it considers NaN to be equal to itself.
69 bool _doubleEquals(double d1, double d2) {
70 if (d1.isNaN && d2.isNaN) return true;
71 return d1 == d2;
72 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698