| Index: tests/compiler/dart2js/inference/inference_test_helper.dart
|
| diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4a916afe0df34900c57938c3e3e1b98c32664275
|
| --- /dev/null
|
| +++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
|
| @@ -0,0 +1,106 @@
|
| +// 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.
|
| +
|
| +import 'package:compiler/src/common.dart';
|
| +import 'package:compiler/src/compiler.dart';
|
| +import 'package:compiler/src/elements/elements.dart';
|
| +import 'package:compiler/src/resolution/tree_elements.dart';
|
| +import 'package:compiler/src/tree/nodes.dart';
|
| +import 'package:compiler/src/types/types.dart';
|
| +import 'package:expect/expect.dart';
|
| +
|
| +import '../annotated_code_helper.dart';
|
| +import '../memory_compiler.dart';
|
| +import 'enumerator.dart';
|
| +
|
| +checkCode(String annotatedCode) async {
|
| + AnnotatedCode code = new AnnotatedCode(annotatedCode);
|
| + Map<Id, String> expectedMap = computeExpectedMap(code);
|
| + Compiler compiler =
|
| + compilerFor(memorySourceFiles: {'main.dart': code.sourceCode});
|
| + compiler.stopAfterTypeInference = true;
|
| + Uri mainUri = Uri.parse('memory:main.dart');
|
| + await compiler.run(mainUri);
|
| + compiler.mainApp.forEachLocalMember((member) {
|
| + if (member.isFunction) {
|
| + checkMember(compiler, expectedMap, member);
|
| + } else if (member.isClass) {
|
| + member.forEachLocalMember((member) {
|
| + checkMember(compiler, expectedMap, member);
|
| + });
|
| + }
|
| + });
|
| + expectedMap.forEach((Id id, String expected) {
|
| + reportHere(
|
| + compiler.reporter,
|
| + new SourceSpan(mainUri, id.value, id.value + 1),
|
| + 'expected:${expected},actual:null');
|
| + });
|
| +}
|
| +
|
| +void checkMember(
|
| + Compiler compiler, Map<Id, String> expectedMap, MemberElement member) {
|
| + ResolvedAst resolvedAst = member.resolvedAst;
|
| + if (resolvedAst.kind != ResolvedAstKind.PARSED) return;
|
| + compiler.reporter.withCurrentElement(member.implementation, () {
|
| + resolvedAst.node.accept(new TypeMaskChecker(
|
| + compiler.reporter,
|
| + expectedMap,
|
| + resolvedAst.elements,
|
| + compiler.globalInference.results.resultOf(member)));
|
| + });
|
| +}
|
| +
|
| +Map<Id, String> computeExpectedMap(AnnotatedCode code) {
|
| + Map<Id, String> map = <Id, String>{};
|
| + for (Annotation annotation in code.annotations) {
|
| + map[new Id(annotation.offset)] = annotation.text;
|
| + }
|
| + return map;
|
| +}
|
| +
|
| +class TypeMaskChecker extends Visitor with AstEnumeratorMixin {
|
| + final DiagnosticReporter reporter;
|
| + final Map<Id, String> expectedMap;
|
| + final TreeElements elements;
|
| + final GlobalTypeInferenceElementResult result;
|
| +
|
| + TypeMaskChecker(this.reporter, this.expectedMap, this.elements, this.result);
|
| +
|
| + visitNode(Node node) {
|
| + node.visitChildren(this);
|
| + }
|
| +
|
| + String annotationForId(Id id) {
|
| + if (id == null) return null;
|
| + return expectedMap.remove(id);
|
| + }
|
| +
|
| + void checkValue(Node node, String expected, TypeMask value) {
|
| + if (value != null || expected != null) {
|
| + String valueText = '$value';
|
| + if (valueText != expected) {
|
| + reportHere(reporter, node, 'expected:${expected},actual:${value}');
|
| + }
|
| + Expect.equals(expected, valueText);
|
| + }
|
| + }
|
| +
|
| + void checkSend(Send node) {
|
| + Id id = computeId(node);
|
| + TypeMask value = result.typeOfSend(node);
|
| + String expected = annotationForId(id);
|
| + checkValue(node, expected, value);
|
| + }
|
| +
|
| + visitSend(Send node) {
|
| + checkSend(node);
|
| + visitNode(node);
|
| + }
|
| +
|
| + visitSendSet(SendSet node) {
|
| + checkSend(node);
|
| + visitNode(node);
|
| + }
|
| +}
|
|
|