| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 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. |
| 4 |
| 5 import 'package:expect/expect.dart'; |
| 6 import |
| 7 '../../../sdk/lib/_internal/compiler/implementation/types/types.dart' |
| 8 show ContainerTypeMask, TypeMask; |
| 9 |
| 10 import 'compiler_helper.dart'; |
| 11 import 'parser_helper.dart'; |
| 12 |
| 13 |
| 14 String generateTest(String listAllocation) { |
| 15 return """ |
| 16 int anInt = 42; |
| 17 double aDouble = 42.5; |
| 18 |
| 19 class A { |
| 20 final field; |
| 21 var nonFinalField; |
| 22 |
| 23 A(this.field); |
| 24 |
| 25 A.bar(list) { |
| 26 nonFinalField = list; |
| 27 } |
| 28 |
| 29 receiveIt(list) { |
| 30 list[0] = aDouble; |
| 31 } |
| 32 |
| 33 returnIt() { |
| 34 return listReturnedFromSelector; |
| 35 } |
| 36 |
| 37 useField() { |
| 38 field[0] = aDouble; |
| 39 } |
| 40 |
| 41 set callSetter(list) { |
| 42 list[0] = aDouble; |
| 43 } |
| 44 |
| 45 operator[](index) { |
| 46 index[0] = aDouble; |
| 47 } |
| 48 |
| 49 operator[]=(index, value) { |
| 50 index[0] = anInt; |
| 51 if (value == listEscapingTwiceInIndexSet) { |
| 52 value[0] = aDouble; |
| 53 } |
| 54 } |
| 55 } |
| 56 |
| 57 class B extends A { |
| 58 B(list) : super.bar(list); |
| 59 |
| 60 set nonFinalField(value) { |
| 61 value[0] = aDouble; |
| 62 } |
| 63 } |
| 64 |
| 65 var listInField = $listAllocation; |
| 66 var listPassedToClosure = $listAllocation; |
| 67 var listReturnedFromClosure = $listAllocation; |
| 68 var listPassedToMethod = $listAllocation; |
| 69 var listReturnedFromMethod = $listAllocation; |
| 70 var listUsedWithCascade = $listAllocation; |
| 71 var listUsedInClosure = $listAllocation; |
| 72 var listPassedToSelector = $listAllocation; |
| 73 var listReturnedFromSelector = $listAllocation; |
| 74 var listUsedWithAddAndInsert = $listAllocation; |
| 75 var listUsedWithNonOkSelector = $listAllocation; |
| 76 var listUsedWithConstraint = $listAllocation; |
| 77 var listEscapingFromSetter = $listAllocation; |
| 78 var listUsedInLocal = $listAllocation; |
| 79 var listUnset = $listAllocation; |
| 80 var listOnlySetWithConstraint = $listAllocation; |
| 81 var listEscapingInSetterValue = $listAllocation; |
| 82 var listEscapingInIndex = $listAllocation; |
| 83 var listEscapingInIndexSet = $listAllocation; |
| 84 var listEscapingTwiceInIndexSet = $listAllocation; |
| 85 var listPassedAsOptionalParameter = $listAllocation; |
| 86 var listPassedAsNamedParameter = $listAllocation; |
| 87 var listSetInNonFinalField = $listAllocation; |
| 88 |
| 89 foo(list) { |
| 90 list[0] = aDouble; |
| 91 } |
| 92 |
| 93 bar() { |
| 94 return listReturnedFromMethod; |
| 95 } |
| 96 |
| 97 takeOptional([list]) { |
| 98 list[0] = aDouble; |
| 99 } |
| 100 |
| 101 takeNamed({list}) { |
| 102 list[0] = aDouble; |
| 103 } |
| 104 |
| 105 main() { |
| 106 listReturnedFromMethod[0] = anInt; |
| 107 bar()[0] = aDouble; |
| 108 |
| 109 listPassedToMethod[0] = anInt; |
| 110 foo(listPassedToMethod); |
| 111 |
| 112 listPassedToClosure[0] = anInt; |
| 113 ((a) => a[0] = aDouble)(listPassedToClosure); |
| 114 |
| 115 listReturnedFromClosure[0] = anInt; |
| 116 (() => listReturnedFromClosure)[0] = aDouble; |
| 117 |
| 118 listInField[0] = anInt; |
| 119 new A(listInField).useField(); |
| 120 |
| 121 listUsedWithCascade[0] = anInt; |
| 122 listUsedWithCascade..[0] = aDouble; |
| 123 |
| 124 listUsedInClosure[0] = anInt; |
| 125 (() => listUsedInClosure[0] = aDouble)(); |
| 126 |
| 127 listPassedToSelector[0] = anInt; |
| 128 new A(null).receiveIt(listPassedToSelector); |
| 129 |
| 130 listReturnedFromSelector[0] = anInt; |
| 131 new A(null).returnIt()[0] = aDouble; |
| 132 |
| 133 listUsedWithAddAndInsert.add(anInt); |
| 134 listUsedWithAddAndInsert.insert(0, aDouble); |
| 135 |
| 136 listUsedWithNonOkSelector[0] = anInt; |
| 137 listUsedWithNonOkSelector.addAll(listPassedToClosure); |
| 138 |
| 139 listUsedWithConstraint[0] = anInt; |
| 140 listUsedWithConstraint[0]++; |
| 141 listUsedWithConstraint[0] += anInt; |
| 142 |
| 143 listEscapingFromSetter[0] = anInt; |
| 144 foo(new A(null).field = listEscapingFromSetter); |
| 145 |
| 146 listUsedInLocal[0] = anInt; |
| 147 var a = listUsedInLocal; |
| 148 listUsedInLocal[1] = aDouble; |
| 149 |
| 150 // At least use [listUnused] in a local to pretend it's used. |
| 151 var b = listUnset; |
| 152 |
| 153 listOnlySetWithConstraint[0]++; |
| 154 |
| 155 listEscapingInSetterValue[0] = anInt; |
| 156 new A().callSetter = listEscapingInSetterValue; |
| 157 |
| 158 listEscapingInIndex[0] = anInt; |
| 159 new A()[listEscapingInIndex]; |
| 160 |
| 161 new A()[listEscapingInIndexSet] = 42; |
| 162 |
| 163 new A()[listEscapingTwiceInIndexSet] = listEscapingTwiceInIndexSet; |
| 164 |
| 165 listPassedAsOptionalParameter[0] = anInt; |
| 166 takeOptional(listPassedAsOptionalParameter); |
| 167 |
| 168 listPassedAsNamedParameter[0] = anInt; |
| 169 takeNamed(list: listPassedAsNamedParameter); |
| 170 |
| 171 listSetInNonFinalField[0] = anInt; |
| 172 new B(listSetInNonFinalField); |
| 173 } |
| 174 """; |
| 175 } |
| 176 |
| 177 void main() { |
| 178 doTest('[]'); // Test literal list. |
| 179 doTest('new List()'); // Test growable list. |
| 180 doTest('new List(1)'); // Test fixed list. |
| 181 } |
| 182 |
| 183 void doTest(String allocation) { |
| 184 Uri uri = new Uri(scheme: 'source'); |
| 185 var compiler = compilerFor(generateTest(allocation), uri); |
| 186 compiler.runCompiler(uri); |
| 187 var typesInferrer = compiler.typesTask.typesInferrer; |
| 188 |
| 189 checkType(String name, type) { |
| 190 var element = findElement(compiler, name); |
| 191 ContainerTypeMask mask = typesInferrer.internal.typeOf[element]; |
| 192 Expect.equals(type, mask.elementType.simplify(compiler), name); |
| 193 } |
| 194 |
| 195 checkType('listInField', typesInferrer.numType.nullable()); |
| 196 checkType('listPassedToMethod', typesInferrer.numType.nullable()); |
| 197 checkType('listReturnedFromMethod', typesInferrer.numType.nullable()); |
| 198 checkType('listUsedWithCascade', typesInferrer.numType.nullable()); |
| 199 checkType('listUsedInClosure', typesInferrer.numType.nullable()); |
| 200 checkType('listPassedToSelector', typesInferrer.numType.nullable()); |
| 201 checkType('listReturnedFromSelector', typesInferrer.numType.nullable()); |
| 202 checkType('listUsedWithAddAndInsert', typesInferrer.numType.nullable()); |
| 203 checkType('listUsedWithConstraint', typesInferrer.numType.nullable()); |
| 204 checkType('listEscapingFromSetter', typesInferrer.numType.nullable()); |
| 205 checkType('listUsedInLocal', typesInferrer.numType.nullable()); |
| 206 checkType('listEscapingInSetterValue', typesInferrer.numType.nullable()); |
| 207 checkType('listEscapingInIndex', typesInferrer.numType.nullable()); |
| 208 checkType('listEscapingInIndexSet', typesInferrer.intType.nullable()); |
| 209 checkType('listEscapingTwiceInIndexSet', typesInferrer.numType.nullable()); |
| 210 checkType('listSetInNonFinalField', typesInferrer.numType.nullable()); |
| 211 |
| 212 checkType('listPassedToClosure', typesInferrer.dynamicType); |
| 213 checkType('listReturnedFromClosure', typesInferrer.dynamicType); |
| 214 checkType('listUsedWithNonOkSelector', typesInferrer.dynamicType); |
| 215 checkType('listPassedAsOptionalParameter', typesInferrer.dynamicType); |
| 216 checkType('listPassedAsNamedParameter', typesInferrer.dynamicType); |
| 217 |
| 218 checkType('listUnset', new TypeMask.empty()); |
| 219 checkType('listOnlySetWithConstraint', new TypeMask.empty()); |
| 220 } |
| OLD | NEW |