OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2017, 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:compiler/src/common.dart'; | |
6 import 'package:compiler/src/compiler.dart'; | |
7 import 'package:compiler/src/elements/elements.dart'; | |
8 import 'package:compiler/src/resolution/tree_elements.dart'; | |
9 import 'package:compiler/src/tree/nodes.dart'; | |
10 import 'package:compiler/src/types/types.dart'; | |
11 import 'package:expect/expect.dart'; | |
12 | |
13 import '../annotated_code_helper.dart'; | |
14 import '../memory_compiler.dart'; | |
15 import 'enumerator.dart'; | |
16 | |
17 | |
18 checkCode(String annotatedCode) async { | |
19 AnnotatedCode code = processAnnotatedCode(annotatedCode); | |
20 Map<Id, String> expectedMap = computeExpectedMap(code); | |
21 Compiler compiler = | |
22 compilerFor(memorySourceFiles: {'main.dart': code.sourceCode}); | |
23 compiler.stopAfterTypeInference = true; | |
24 Uri mainUri = Uri.parse('memory:main.dart'); | |
25 await compiler.run(mainUri); | |
26 compiler.mainApp.forEachLocalMember((member) { | |
27 if (member.isFunction) { | |
28 checkMember(compiler, expectedMap, member); | |
29 } else if (member.isClass) { | |
30 member.forEachLocalMember((member) { | |
31 checkMember(compiler, expectedMap, member); | |
32 }); | |
33 } | |
34 }); | |
35 expectedMap.forEach((Id id, String expected) { | |
36 reportHere( | |
37 compiler.reporter, | |
38 new SourceSpan(mainUri, id.value, id.value + 1), | |
39 'expected:${expected},actual:null'); | |
40 }); | |
41 } | |
42 | |
43 void checkMember( | |
44 Compiler compiler, Map<Id, String> expectedMap, MemberElement member) { | |
45 ResolvedAst resolvedAst = member.resolvedAst; | |
46 if (resolvedAst.kind != ResolvedAstKind.PARSED) return; | |
47 compiler.reporter.withCurrentElement(member.implementation, () { | |
48 resolvedAst.node.accept(new TypeMaskChecker( | |
49 compiler.reporter, | |
50 expectedMap, | |
51 resolvedAst.elements, | |
52 compiler.globalInference.results.resultOf(member))); | |
53 }); | |
54 } | |
55 | |
56 Map<Id, String> computeExpectedMap(AnnotatedCode code) { | |
57 Map<Id, String> map = <Id, String>{}; | |
58 for (Annotation annotation in code.annotations) { | |
59 map[new Id(annotation.offset)] = annotation.text; | |
60 } | |
61 return map; | |
62 } | |
63 | |
64 class TypeMaskChecker extends Visitor with AstEnumeratorMixin { | |
65 final DiagnosticReporter reporter; | |
66 final Map<Id, String> expectedMap; | |
67 final TreeElements elements; | |
68 final GlobalTypeInferenceElementResult result; | |
69 | |
70 TypeMaskChecker(this.reporter, this.expectedMap, this.elements, this.result); | |
71 | |
72 visitNode(Node node) { | |
73 node.visitChildren(this); | |
74 } | |
75 | |
76 String annotationForId(Id id) { | |
77 if (id == null) return null; | |
78 return expectedMap.remove(id); | |
79 } | |
80 | |
81 void checkValue(Node node, String expected, TypeMask value) { | |
82 if (value != null || expected != null) { | |
83 String valueText = '$value'; | |
84 if (valueText != expected) { | |
85 reportHere(reporter, node, 'expected:${expected},actual:${value}'); | |
86 } | |
87 Expect.equals(expected, valueText); | |
88 } | |
89 } | |
90 | |
91 void checkSend(Send node) { | |
92 Id id = computeId(node); | |
93 TypeMask value = result.typeOfSend(node); | |
94 String expected = annotationForId(id); | |
95 checkValue(node, expected, value); | |
96 } | |
97 | |
98 visitSend(Send node) { | |
99 checkSend(node); | |
100 visitNode(node); | |
Siggi Cherem (dart-lang)
2017/01/24 21:05:59
is this the same as super.visitSend(node);
Johnni Winther
2017/01/25 13:28:14
Yes.
| |
101 } | |
102 | |
103 visitSendSet(SendSet node) { | |
104 checkSend(node); | |
105 visitNode(node); | |
106 } | |
107 } | |
OLD | NEW |