| // Copyright (c) 2017, 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. |
| |
| /// TODO(johnniwinther): Port this test to use the equivalence framework. |
| |
| import 'package:async_helper/async_helper.dart'; |
| import 'package:compiler/src/compiler.dart'; |
| import 'package:compiler/src/commandline_options.dart'; |
| import 'package:compiler/src/common_elements.dart'; |
| import 'package:compiler/src/elements/entities.dart'; |
| import 'package:compiler/src/inferrer/type_graph_inferrer.dart'; |
| import 'package:compiler/src/types/types.dart'; |
| import 'package:compiler/src/world.dart'; |
| import 'package:expect/expect.dart'; |
| |
| import 'type_mask_test_helper.dart'; |
| import '../memory_compiler.dart'; |
| |
| bool isContainer(TypeMask mask) { |
| return mask is ContainerTypeMask; |
| } |
| |
| const String TEST = ''' |
| |
| foo1() { |
| final methods = []; |
| var res, sum; |
| for (int i = 0; i != 3; i++) { |
| methods.add((int x) { res = x; sum = x + i; }); |
| } |
| methods[0](499); |
| probe1res(res); |
| probe1sum(sum); |
| probe1methods(methods); |
| } |
| probe1res(x) => x; |
| probe1sum(x) => x; |
| probe1methods(x) => x; |
| |
| nonContainer(choice) { |
| var m = choice == 0 ? [] : "<String>"; |
| if (m is !List) throw 123; |
| // The union then filter leaves us with a non-container type. |
| return m; |
| } |
| |
| foo2(int choice) { |
| final methods = nonContainer(choice); |
| var res, sum; |
| for (int i = 0; i != 3; i++) { |
| methods.add((int x) { res = x; sum = x + i; }); |
| } |
| methods[0](499); |
| probe2res(res); |
| probe2methods(methods); |
| } |
| probe2res(x) => x; |
| probe2methods(x) => x; |
| |
| main() { |
| foo1(); |
| foo2(0); |
| foo2(1); |
| } |
| '''; |
| |
| void main() { |
| runTest({bool useKernel}) async { |
| CompilationResult result = await runCompiler( |
| memorySourceFiles: {'main.dart': TEST}, |
| options: useKernel ? [Flags.useKernel] : []); |
| Expect.isTrue(result.isSuccess); |
| Compiler compiler = result.compiler; |
| |
| TypeGraphInferrer typesInferrer = |
| compiler.globalInference.typesInferrerInternal; |
| ClosedWorld closedWorld = typesInferrer.closedWorld; |
| ElementEnvironment elementEnvironment = closedWorld.elementEnvironment; |
| CommonMasks commonMasks = closedWorld.commonMasks; |
| |
| typeOf(String name) { |
| LibraryEntity library = elementEnvironment.mainLibrary; |
| MemberEntity member = |
| elementEnvironment.lookupLibraryMember(library, name); |
| return typesInferrer.getReturnTypeOfMember(member); |
| } |
| |
| checkType(String name, type) { |
| var mask = typeOf(name); |
| Expect.equals(type.nullable(), simplify(mask, closedWorld), name); |
| } |
| |
| checkContainer(String name, bool value) { |
| var mask = typeOf(name); |
| Expect.equals( |
| value, isContainer(mask), '$name is container (mask: $mask)'); |
| } |
| |
| checkContainer('probe1methods', true); |
| checkType('probe1res', commonMasks.uint31Type); |
| checkType('probe1sum', commonMasks.positiveIntType); |
| |
| checkContainer('probe2methods', false); |
| checkType('probe2res', commonMasks.dynamicType); |
| } |
| |
| asyncTest(() async { |
| print('--test from ast---------------------------------------------------'); |
| await runTest(useKernel: false); |
| print('--test from kernel------------------------------------------------'); |
| await runTest(useKernel: true); |
| }); |
| } |