Skip to content

Commit 8524217

Browse files
author
John Messerly
committed
fixes #202, check IndexExpression
[email protected] Review URL: https://codereview.chromium.org/1160673003
1 parent 8865229 commit 8524217

File tree

9 files changed

+67
-12
lines changed

9 files changed

+67
-12
lines changed

pkg/dev_compiler/lib/runtime/dart/_internal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1721,7 +1721,7 @@ var _js_primitives = dart.lazyImport(_js_primitives);
17211721
this[_values] = values;
17221722
}
17231723
get(key) {
1724-
return this.containsKey(key) ? this[_values][core.$get](key) : null;
1724+
return this.containsKey(key) ? this[_values][core.$get](dart.as(key, core.int)) : null;
17251725
}
17261726
get length() {
17271727
return this[_values][core.$length];

pkg/dev_compiler/lib/runtime/dart/collection.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ var math = dart.lazyImport(math);
7979
static from(other) {
8080
let result = HashMap$(K, V).new();
8181
other.forEach(dart.fn((k, v) => {
82-
result.set(k, dart.as(v, V));
82+
result.set(dart.as(k, K), dart.as(v, V));
8383
}));
8484
return result;
8585
}
@@ -1218,7 +1218,7 @@ var math = dart.lazyImport(math);
12181218
static from(other) {
12191219
let result = LinkedHashMap$(K, V).new();
12201220
other.forEach(dart.fn((k, v) => {
1221-
result.set(k, dart.as(v, V));
1221+
result.set(dart.as(k, K), dart.as(v, V));
12221222
}));
12231223
return result;
12241224
}
@@ -3324,7 +3324,7 @@ var math = dart.lazyImport(math);
33243324
isValidKey = null;
33253325
let result = new (SplayTreeMap$(K, V))();
33263326
other.forEach(dart.fn((k, v) => {
3327-
result.set(k, dart.as(v, V));
3327+
result.set(dart.as(k, K), dart.as(v, V));
33283328
}));
33293329
return result;
33303330
}

pkg/dev_compiler/lib/src/checker/checker.dart

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,12 @@ class CodeChecker extends RecursiveAstVisitor {
719719
// Method invocation.
720720
if (element is MethodElement) {
721721
var type = element.type as FunctionType;
722-
assert(type.normalParameterTypes.length == 1);
723-
node.rightOperand =
724-
checkArgument(node.rightOperand, type.normalParameterTypes[0]);
722+
// Analyzer should enforce number of parameter types, but check in
723+
// case we have erroneous input.
724+
if (type.normalParameterTypes.isNotEmpty) {
725+
node.rightOperand =
726+
checkArgument(node.rightOperand, type.normalParameterTypes[0]);
727+
}
725728
} else {
726729
// TODO(vsm): Assert that the analyzer found an error here?
727730
}
@@ -744,6 +747,26 @@ class CodeChecker extends RecursiveAstVisitor {
744747
node.visitChildren(this);
745748
}
746749

750+
@override
751+
void visitIndexExpression(IndexExpression node) {
752+
if (_rules.isDynamicTarget(node.target)) {
753+
_recordDynamicInvoke(node);
754+
} else {
755+
var element = node.staticElement;
756+
if (element is MethodElement) {
757+
var type = element.type as FunctionType;
758+
// Analyzer should enforce number of parameter types, but check in
759+
// case we have erroneous input.
760+
if (type.normalParameterTypes.isNotEmpty) {
761+
node.index = checkArgument(node.index, type.normalParameterTypes[0]);
762+
}
763+
} else {
764+
// TODO(vsm): Assert that the analyzer found an error here?
765+
}
766+
}
767+
node.visitChildren(this);
768+
}
769+
747770
DartType getType(TypeName name) {
748771
return (name == null) ? _rules.provider.dynamicType : name.type;
749772
}

pkg/dev_compiler/test/checker/checker_test.dart

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1923,7 +1923,7 @@ void main() {
19231923
}, inferFromOverrides: true);
19241924
});
19251925

1926-
test('binary operators', () {
1926+
test('binary and index operators', () {
19271927
testChecker({
19281928
'/main.dart': '''
19291929
class A {
@@ -1938,6 +1938,7 @@ void main() {
19381938
A operator &(B b) {}
19391939
A operator ^(B b) {}
19401940
A operator |(B b) {}
1941+
A operator[](B b) {}
19411942
}
19421943
19431944
class B {
@@ -1979,6 +1980,11 @@ void main() {
19791980
p = (/*info:DynamicCast*/c) && /*info:DynamicCast*/c;
19801981
p = (/*severe:StaticTypeError*/y) && p;
19811982
p = c == y;
1983+
1984+
a = a[b];
1985+
a = a[/*info:DynamicCast*/c];
1986+
c = (/*info:DynamicInvoke*/c[b]);
1987+
a[/*severe:StaticTypeError*/y];
19821988
}
19831989
'''
19841990
});
@@ -1999,12 +2005,18 @@ void main() {
19992005
A operator &(B b) {}
20002006
A operator ^(B b) {}
20012007
A operator |(B b) {}
2008+
D operator [](B index) {}
2009+
void operator []=(B index, D value) {}
20022010
}
20032011
20042012
class B {
20052013
A operator -(B b) {}
20062014
}
20072015
2016+
class D {
2017+
D operator +(D d) {}
2018+
}
2019+
20082020
foo() => new A();
20092021
20102022
test() {
@@ -2049,6 +2061,14 @@ void main() {
20492061
a ^= b;
20502062
a |= b;
20512063
(/*info:DynamicInvoke*/c += b);
2064+
2065+
var d = new D();
2066+
a[b] += d;
2067+
a[/*info:DynamicCast*/c] += d;
2068+
a[/*severe:StaticTypeError*/z] += d;
2069+
a[b] += /*info:DynamicCast*/c;
2070+
a[b] += /*severe:StaticTypeError*/z;
2071+
(/*info:DynamicInvoke*/(/*info:DynamicInvoke*/c[b]) += d);
20522072
}
20532073
'''
20542074
});

pkg/dev_compiler/test/dart_codegen/expect/_internal/list.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ RangeError.checkValidIndex(index, this);
109109
}
110110
class ListMapView<E> implements Map<int, E> {List<E> _values;
111111
ListMapView(this._values);
112-
E operator [](Object key) => containsKey(key) ? _values[key] : null;
112+
E operator [](Object key) => containsKey(key) ? _values[DEVC$RT.cast(key, Object, int, "ImplicitCast", """line 251, column 59 of dart:_internal/list.dart: """, key is int, true)] : null;
113113
int get length => _values.length;
114114
Iterable<E> get values => new SubListIterable<E>(_values, 0, null);
115115
Iterable<int> get keys => new _ListIndicesIterable(_values);

pkg/dev_compiler/test/dart_codegen/expect/collection/hash_map.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ part of dart.collection;
1010
factory HashMap.from(Map other) {
1111
HashMap<K, V> result = new HashMap<K, V>();
1212
other.forEach((k, v) {
13-
result[k] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 87, column 40 of dart:collection/hash_map.dart: """, v is V, false);
13+
result[DEVC$RT.cast(k, dynamic, K, "CompositeCast", """line 87, column 35 of dart:collection/hash_map.dart: """, k is K, false)] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 87, column 40 of dart:collection/hash_map.dart: """, v is V, false);
1414
}
1515
);
1616
return result;

pkg/dev_compiler/test/dart_codegen/expect/collection/linked_hash_map.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ part of dart.collection;
66
factory LinkedHashMap.from(Map other) {
77
LinkedHashMap<K, V> result = new LinkedHashMap<K, V>();
88
other.forEach((k, v) {
9-
result[k] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 74, column 40 of dart:collection/linked_hash_map.dart: """, v is V, false);
9+
result[DEVC$RT.cast(k, dynamic, K, "CompositeCast", """line 74, column 35 of dart:collection/linked_hash_map.dart: """, k is K, false)] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 74, column 40 of dart:collection/linked_hash_map.dart: """, v is V, false);
1010
}
1111
);
1212
return result;

pkg/dev_compiler/test/dart_codegen/expect/collection/splay_tree.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ _root = null;
151151
factory SplayTreeMap.from(Map other, [int compare(K key1, K key2), bool isValidKey(Object potentialKey)]) {
152152
SplayTreeMap<K, V> result = new SplayTreeMap<K, V>();
153153
other.forEach((k, v) {
154-
result[k] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 275, column 40 of dart:collection/splay_tree.dart: """, v is V, false);
154+
result[DEVC$RT.cast(k, dynamic, K, "CompositeCast", """line 275, column 35 of dart:collection/splay_tree.dart: """, k is K, false)] = DEVC$RT.cast(v, dynamic, V, "CompositeCast", """line 275, column 40 of dart:collection/splay_tree.dart: """, v is V, false);
155155
}
156156
);
157157
return result;

pkg/dev_compiler/tool/sdk_expected_errors.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,9 @@ warning: line 1033, column 35 of dart:_internal/iterable.dart: [DownCastComposit
703703
warning: line 1115, column 31 of dart:_internal/iterable.dart: [DownCastComposite] l (List<dynamic>) will need runtime check to cast to type List<T>
704704
return new ListMapView<T>(l);
705705
^
706+
warning: line 251, column 59 of dart:_internal/list.dart: [DownCastImplicit] key (Object) will need runtime check to cast to type int
707+
E operator[] (Object key) => containsKey(key) ? _values[key] : null;
708+
^^^
706709
warning: line 179, column 12 of dart:collection: [DownCastComposite] JS('var', '#.splice(#, 2)[1]', bucket, index) (dynamic) will need runtime check to cast to type V
707710
return JS('var', '#.splice(#, 2)[1]', bucket, index);
708711
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -820,6 +823,9 @@ warning: line 1678, column 18 of dart:collection: [DownCastComposite] _cell._ele
820823
warning: line 112, column 40 of dart:collection/hash_map.dart: [DownCastComposite] v (dynamic) will need runtime check to cast to type V
821824
other.forEach((k, v) { result[k] = v; });
822825
^
826+
warning: line 112, column 35 of dart:collection/hash_map.dart: [DownCastComposite] k (dynamic) will need runtime check to cast to type K
827+
other.forEach((k, v) { result[k] = v; });
828+
^
823829
warning: line 128, column 17 of dart:collection/hash_set.dart: [DownCastComposite] elements (Iterable<dynamic>) will need runtime check to cast to type Iterable<E>
824830
for (E e in elements) result.add(e);
825831
^^^^^^^^
@@ -829,6 +835,9 @@ warning: line 33, column 16 of dart:collection/iterator.dart: [DownCastComposite
829835
warning: line 99, column 40 of dart:collection/linked_hash_map.dart: [DownCastComposite] v (dynamic) will need runtime check to cast to type V
830836
other.forEach((k, v) { result[k] = v; });
831837
^
838+
warning: line 99, column 35 of dart:collection/linked_hash_map.dart: [DownCastComposite] k (dynamic) will need runtime check to cast to type K
839+
other.forEach((k, v) { result[k] = v; });
840+
^
832841
warning: line 142, column 12 of dart:collection/linked_hash_map.dart: [DownCastComposite] fillLiteralMap(keyValuePairs, new _LinkedHashMap<K, V>()) (dynamic) will need runtime check to cast to type LinkedHashMap<K, V>
833842
return fillLiteralMap(keyValuePairs, new _LinkedHashMap<K, V>());
834843
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -925,6 +934,9 @@ severe: line 266, column 65 of dart:collection/splay_tree.dart: [InvalidRuntimeC
925934
warning: line 275, column 40 of dart:collection/splay_tree.dart: [DownCastComposite] v (dynamic) will need runtime check to cast to type V
926935
other.forEach((k, v) { result[k] = v; });
927936
^
937+
warning: line 275, column 35 of dart:collection/splay_tree.dart: [DownCastComposite] k (dynamic) will need runtime check to cast to type K
938+
other.forEach((k, v) { result[k] = v; });
939+
^
928940
warning: line 328, column 25 of dart:collection/splay_tree.dart: [DownCastComposite] key (Object) will need runtime check to cast to type K
929941
int comp = _splay(key);
930942
^^^

0 commit comments

Comments
 (0)