| Index: tests/compiler/dart2js/list_tracer_test.dart
|
| ===================================================================
|
| --- tests/compiler/dart2js/list_tracer_test.dart (revision 0)
|
| +++ tests/compiler/dart2js/list_tracer_test.dart (revision 0)
|
| @@ -0,0 +1,220 @@
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +import 'package:expect/expect.dart';
|
| +import
|
| + '../../../sdk/lib/_internal/compiler/implementation/types/types.dart'
|
| + show ContainerTypeMask, TypeMask;
|
| +
|
| +import 'compiler_helper.dart';
|
| +import 'parser_helper.dart';
|
| +
|
| +
|
| +String generateTest(String listAllocation) {
|
| + return """
|
| +int anInt = 42;
|
| +double aDouble = 42.5;
|
| +
|
| +class A {
|
| + final field;
|
| + var nonFinalField;
|
| +
|
| + A(this.field);
|
| +
|
| + A.bar(list) {
|
| + nonFinalField = list;
|
| + }
|
| +
|
| + receiveIt(list) {
|
| + list[0] = aDouble;
|
| + }
|
| +
|
| + returnIt() {
|
| + return listReturnedFromSelector;
|
| + }
|
| +
|
| + useField() {
|
| + field[0] = aDouble;
|
| + }
|
| +
|
| + set callSetter(list) {
|
| + list[0] = aDouble;
|
| + }
|
| +
|
| + operator[](index) {
|
| + index[0] = aDouble;
|
| + }
|
| +
|
| + operator[]=(index, value) {
|
| + index[0] = anInt;
|
| + if (value == listEscapingTwiceInIndexSet) {
|
| + value[0] = aDouble;
|
| + }
|
| + }
|
| +}
|
| +
|
| +class B extends A {
|
| + B(list) : super.bar(list);
|
| +
|
| + set nonFinalField(value) {
|
| + value[0] = aDouble;
|
| + }
|
| +}
|
| +
|
| +var listInField = $listAllocation;
|
| +var listPassedToClosure = $listAllocation;
|
| +var listReturnedFromClosure = $listAllocation;
|
| +var listPassedToMethod = $listAllocation;
|
| +var listReturnedFromMethod = $listAllocation;
|
| +var listUsedWithCascade = $listAllocation;
|
| +var listUsedInClosure = $listAllocation;
|
| +var listPassedToSelector = $listAllocation;
|
| +var listReturnedFromSelector = $listAllocation;
|
| +var listUsedWithAddAndInsert = $listAllocation;
|
| +var listUsedWithNonOkSelector = $listAllocation;
|
| +var listUsedWithConstraint = $listAllocation;
|
| +var listEscapingFromSetter = $listAllocation;
|
| +var listUsedInLocal = $listAllocation;
|
| +var listUnset = $listAllocation;
|
| +var listOnlySetWithConstraint = $listAllocation;
|
| +var listEscapingInSetterValue = $listAllocation;
|
| +var listEscapingInIndex = $listAllocation;
|
| +var listEscapingInIndexSet = $listAllocation;
|
| +var listEscapingTwiceInIndexSet = $listAllocation;
|
| +var listPassedAsOptionalParameter = $listAllocation;
|
| +var listPassedAsNamedParameter = $listAllocation;
|
| +var listSetInNonFinalField = $listAllocation;
|
| +
|
| +foo(list) {
|
| + list[0] = aDouble;
|
| +}
|
| +
|
| +bar() {
|
| + return listReturnedFromMethod;
|
| +}
|
| +
|
| +takeOptional([list]) {
|
| + list[0] = aDouble;
|
| +}
|
| +
|
| +takeNamed({list}) {
|
| + list[0] = aDouble;
|
| +}
|
| +
|
| +main() {
|
| + listReturnedFromMethod[0] = anInt;
|
| + bar()[0] = aDouble;
|
| +
|
| + listPassedToMethod[0] = anInt;
|
| + foo(listPassedToMethod);
|
| +
|
| + listPassedToClosure[0] = anInt;
|
| + ((a) => a[0] = aDouble)(listPassedToClosure);
|
| +
|
| + listReturnedFromClosure[0] = anInt;
|
| + (() => listReturnedFromClosure)[0] = aDouble;
|
| +
|
| + listInField[0] = anInt;
|
| + new A(listInField).useField();
|
| +
|
| + listUsedWithCascade[0] = anInt;
|
| + listUsedWithCascade..[0] = aDouble;
|
| +
|
| + listUsedInClosure[0] = anInt;
|
| + (() => listUsedInClosure[0] = aDouble)();
|
| +
|
| + listPassedToSelector[0] = anInt;
|
| + new A(null).receiveIt(listPassedToSelector);
|
| +
|
| + listReturnedFromSelector[0] = anInt;
|
| + new A(null).returnIt()[0] = aDouble;
|
| +
|
| + listUsedWithAddAndInsert.add(anInt);
|
| + listUsedWithAddAndInsert.insert(0, aDouble);
|
| +
|
| + listUsedWithNonOkSelector[0] = anInt;
|
| + listUsedWithNonOkSelector.addAll(listPassedToClosure);
|
| +
|
| + listUsedWithConstraint[0] = anInt;
|
| + listUsedWithConstraint[0]++;
|
| + listUsedWithConstraint[0] += anInt;
|
| +
|
| + listEscapingFromSetter[0] = anInt;
|
| + foo(new A(null).field = listEscapingFromSetter);
|
| +
|
| + listUsedInLocal[0] = anInt;
|
| + var a = listUsedInLocal;
|
| + listUsedInLocal[1] = aDouble;
|
| +
|
| + // At least use [listUnused] in a local to pretend it's used.
|
| + var b = listUnset;
|
| +
|
| + listOnlySetWithConstraint[0]++;
|
| +
|
| + listEscapingInSetterValue[0] = anInt;
|
| + new A().callSetter = listEscapingInSetterValue;
|
| +
|
| + listEscapingInIndex[0] = anInt;
|
| + new A()[listEscapingInIndex];
|
| +
|
| + new A()[listEscapingInIndexSet] = 42;
|
| +
|
| + new A()[listEscapingTwiceInIndexSet] = listEscapingTwiceInIndexSet;
|
| +
|
| + listPassedAsOptionalParameter[0] = anInt;
|
| + takeOptional(listPassedAsOptionalParameter);
|
| +
|
| + listPassedAsNamedParameter[0] = anInt;
|
| + takeNamed(list: listPassedAsNamedParameter);
|
| +
|
| + listSetInNonFinalField[0] = anInt;
|
| + new B(listSetInNonFinalField);
|
| +}
|
| +""";
|
| +}
|
| +
|
| +void main() {
|
| + doTest('[]'); // Test literal list.
|
| + doTest('new List()'); // Test growable list.
|
| + doTest('new List(1)'); // Test fixed list.
|
| +}
|
| +
|
| +void doTest(String allocation) {
|
| + Uri uri = new Uri(scheme: 'source');
|
| + var compiler = compilerFor(generateTest(allocation), uri);
|
| + compiler.runCompiler(uri);
|
| + var typesInferrer = compiler.typesTask.typesInferrer;
|
| +
|
| + checkType(String name, type) {
|
| + var element = findElement(compiler, name);
|
| + ContainerTypeMask mask = typesInferrer.internal.typeOf[element];
|
| + Expect.equals(type, mask.elementType.simplify(compiler), name);
|
| + }
|
| +
|
| + checkType('listInField', typesInferrer.numType.nullable());
|
| + checkType('listPassedToMethod', typesInferrer.numType.nullable());
|
| + checkType('listReturnedFromMethod', typesInferrer.numType.nullable());
|
| + checkType('listUsedWithCascade', typesInferrer.numType.nullable());
|
| + checkType('listUsedInClosure', typesInferrer.numType.nullable());
|
| + checkType('listPassedToSelector', typesInferrer.numType.nullable());
|
| + checkType('listReturnedFromSelector', typesInferrer.numType.nullable());
|
| + checkType('listUsedWithAddAndInsert', typesInferrer.numType.nullable());
|
| + checkType('listUsedWithConstraint', typesInferrer.numType.nullable());
|
| + checkType('listEscapingFromSetter', typesInferrer.numType.nullable());
|
| + checkType('listUsedInLocal', typesInferrer.numType.nullable());
|
| + checkType('listEscapingInSetterValue', typesInferrer.numType.nullable());
|
| + checkType('listEscapingInIndex', typesInferrer.numType.nullable());
|
| + checkType('listEscapingInIndexSet', typesInferrer.intType.nullable());
|
| + checkType('listEscapingTwiceInIndexSet', typesInferrer.numType.nullable());
|
| + checkType('listSetInNonFinalField', typesInferrer.numType.nullable());
|
| +
|
| + checkType('listPassedToClosure', typesInferrer.dynamicType);
|
| + checkType('listReturnedFromClosure', typesInferrer.dynamicType);
|
| + checkType('listUsedWithNonOkSelector', typesInferrer.dynamicType);
|
| + checkType('listPassedAsOptionalParameter', typesInferrer.dynamicType);
|
| + checkType('listPassedAsNamedParameter', typesInferrer.dynamicType);
|
| +
|
| + checkType('listUnset', new TypeMask.empty());
|
| + checkType('listOnlySetWithConstraint', new TypeMask.empty());
|
| +}
|
|
|