| // 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. |
| |
| library type_test_helper; |
| |
| import 'dart:async'; |
| import 'package:expect/expect.dart'; |
| import 'compiler_helper.dart' as mock; |
| import 'memory_compiler.dart' as memory; |
| import 'package:compiler/src/common/resolution.dart'; |
| import 'package:compiler/src/commandline_options.dart'; |
| import 'package:compiler/src/dart_types.dart'; |
| import 'package:compiler/src/compiler.dart' show Compiler; |
| import 'package:compiler/src/elements/elements.dart' |
| show Element, MemberElement, TypeDeclarationElement, ClassElement; |
| |
| GenericType instantiate( |
| TypeDeclarationElement element, List<DartType> arguments) { |
| if (element.isClass) { |
| return new InterfaceType(element, arguments); |
| } else { |
| assert(element.isTypedef); |
| return new TypedefType(element, arguments); |
| } |
| } |
| |
| class TypeEnvironment { |
| final Compiler compiler; |
| |
| Resolution get resolution => compiler.resolution; |
| |
| static Future<TypeEnvironment> create(String source, |
| {bool useMockCompiler: true, |
| bool expectNoErrors: false, |
| bool expectNoWarningsOrErrors: false, |
| bool stopAfterTypeInference: false, |
| String mainSource}) { |
| Uri uri; |
| Compiler compiler; |
| bool stopAfterTypeInference = mainSource != null; |
| if (mainSource == null) { |
| source = '''import 'dart:async'; |
| main() {} |
| $source'''; |
| } else { |
| source = '$mainSource\n$source'; |
| } |
| memory.DiagnosticCollector collector; |
| if (useMockCompiler) { |
| uri = new Uri(scheme: 'source'); |
| mock.MockCompiler mockCompiler = mock.compilerFor(source, uri, |
| analyzeAll: !stopAfterTypeInference, |
| analyzeOnly: !stopAfterTypeInference); |
| mockCompiler.diagnosticHandler = mock.createHandler(mockCompiler, source); |
| collector = mockCompiler.diagnosticCollector; |
| compiler = mockCompiler; |
| } else { |
| collector = new memory.DiagnosticCollector(); |
| uri = Uri.parse('memory:main.dart'); |
| compiler = memory.compilerFor( |
| entryPoint: uri, |
| memorySourceFiles: {'main.dart': source}, |
| diagnosticHandler: collector, |
| options: stopAfterTypeInference |
| ? [] |
| : [Flags.analyzeAll, Flags.analyzeOnly]); |
| } |
| compiler.stopAfterTypeInference = stopAfterTypeInference; |
| return compiler.run(uri).then((_) { |
| if (expectNoErrors || expectNoWarningsOrErrors) { |
| var errors = collector.errors; |
| Expect.isTrue(errors.isEmpty, 'Unexpected errors: ${errors}'); |
| } |
| if (expectNoWarningsOrErrors) { |
| var warnings = collector.warnings; |
| Expect.isTrue(warnings.isEmpty, 'Unexpected warnings: ${warnings}'); |
| } |
| return new TypeEnvironment._(compiler); |
| }); |
| } |
| |
| TypeEnvironment._(Compiler this.compiler); |
| |
| Element getElement(String name) { |
| var element = compiler.mainApp.find(name); |
| Expect.isNotNull(element); |
| if (element.isClass) { |
| element.ensureResolved(compiler.resolution); |
| } else if (element.isTypedef) { |
| element.computeType(compiler.resolution); |
| } |
| return element; |
| } |
| |
| DartType getElementType(String name) { |
| var element = getElement(name); |
| return element.computeType(compiler.resolution); |
| } |
| |
| DartType operator [](String name) { |
| if (name == 'dynamic') return const DynamicType(); |
| if (name == 'void') return const VoidType(); |
| return getElementType(name); |
| } |
| |
| DartType getMemberType(ClassElement element, String name) { |
| MemberElement member = element.localLookup(name); |
| return member.computeType(compiler.resolution); |
| } |
| |
| bool isSubtype(DartType T, DartType S) { |
| return compiler.types.isSubtype(T, S); |
| } |
| |
| bool isMoreSpecific(DartType T, DartType S) { |
| return compiler.types.isMoreSpecific(T, S); |
| } |
| |
| DartType computeLeastUpperBound(DartType T, DartType S) { |
| return compiler.types.computeLeastUpperBound(T, S); |
| } |
| |
| DartType flatten(DartType T) { |
| return compiler.types.flatten(T); |
| } |
| |
| FunctionType functionType(DartType returnType, List<DartType> parameters, |
| {List<DartType> optionalParameters: const <DartType>[], |
| Map<String, DartType> namedParameters}) { |
| List<String> namedParameterNames = <String>[]; |
| List<DartType> namedParameterTypes = <DartType>[]; |
| if (namedParameters != null) { |
| namedParameters.forEach((String name, DartType type) { |
| namedParameterNames.add(name); |
| namedParameterTypes.add(type); |
| }); |
| } |
| return new FunctionType.synthesized(returnType, parameters, |
| optionalParameters, namedParameterNames, namedParameterTypes); |
| } |
| } |