Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(834)

Side by Side Diff: pkg/kernel/lib/checks.dart

Issue 2531873002: Add --verify-ir flag to dartk and test.py. (Closed)
Patch Set: Minor fixes Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | pkg/kernel/lib/text/ast_to_text.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, 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 library kernel.checks;
5
6 import 'ast.dart';
7 import 'transformations/flags.dart';
8
9 void runSanityChecks(Program program) {
10 SanityCheck.check(program);
11 }
12
13 /// Checks that references refer to something in scope.
14 ///
15 /// Currently only checks member, class, and type parameter references.
16 class SanityCheck extends RecursiveVisitor {
17 final Set<Class> classes = new Set<Class>();
18 final Set<TypeParameter> typeParameters = new Set<TypeParameter>();
19
20 Member currentMember;
21 Class currentClass;
22 TreeNode currentParent;
23
24 TreeNode get context => currentMember ?? currentClass;
25
26 static void check(Program program) {
27 program.accept(new SanityCheck());
28 }
29
30 defaultTreeNode(TreeNode node) {
31 visitChildren(node);
32 }
33
34 void visitChildren(TreeNode node) {
35 if (!identical(node.parent, currentParent)) {
36 throw 'Parent pointer on ${node.runtimeType} '
37 'is ${node.parent.runtimeType} '
38 'but should be ${currentParent.runtimeType}';
39 }
40 var oldParent = currentParent;
41 currentParent = node;
42 node.visitChildren(this);
43 currentParent = oldParent;
44 }
45
46 void declareMember(Member member) {
47 if (member.transformerFlags & TransformerFlag.seenBySanityCheck != 0) {
48 throw '$member has been declared more than once';
49 }
50 member.transformerFlags |= TransformerFlag.seenBySanityCheck;
51 }
52
53 void undeclareMember(Member member) {
54 member.transformerFlags &= ~TransformerFlag.seenBySanityCheck;
55 }
56
57 visitProgram(Program program) {
58 for (var library in program.libraries) {
59 classes.addAll(library.classes);
60 library.members.forEach(declareMember);
61 for (var class_ in library.classes) {
62 class_.members.forEach(declareMember);
63 }
64 }
65 visitChildren(program);
66 for (var library in program.libraries) {
67 library.members.forEach(undeclareMember);
68 for (var class_ in library.classes) {
69 class_.members.forEach(undeclareMember);
70 }
71 }
72 }
73
74 defaultMember(Member node) {
75 currentMember = node;
76 visitChildren(node);
77 currentMember = null;
78 }
79
80 visitClass(Class node) {
81 currentClass = node;
82 typeParameters.addAll(node.typeParameters);
83 visitChildren(node);
84 typeParameters.removeAll(node.typeParameters);
85 currentClass = null;
86 }
87
88 visitFunctionNode(FunctionNode node) {
89 typeParameters.addAll(node.typeParameters);
90 visitChildren(node);
91 typeParameters.removeAll(node.typeParameters);
92 }
93
94 visitFunctionType(FunctionType node) {
95 for (int i = 1; i < node.namedParameters.length; ++i) {
96 if (node.namedParameters[i - 1].compareTo(node.namedParameters[i]) >= 0) {
97 throw 'Named parameters are not sorted on function type found in '
98 '$context';
99 }
100 }
101 typeParameters.addAll(node.typeParameters);
102 for (var typeParameter in node.typeParameters) {
103 typeParameter.bound?.accept(this);
104 }
105 visitList(node.positionalParameters, this);
106 visitList(node.namedParameters, this);
107 node.returnType.accept(this);
108 typeParameters.removeAll(node.typeParameters);
109 }
110
111 @override
112 defaultMemberReference(Member node) {
113 if (node.transformerFlags & TransformerFlag.seenBySanityCheck == 0) {
114 throw 'Dangling reference to $node found in $context.\n'
115 'Parent pointer is set to ${node.parent}';
116 }
117 }
118
119 @override
120 visitClassReference(Class node) {
121 if (!classes.contains(node)) {
122 throw 'Dangling reference to $node found in $context.\n'
123 'Parent pointer is set to ${node.parent}';
124 }
125 }
126
127 @override
128 visitTypeParameterType(TypeParameterType node) {
129 if (!typeParameters.contains(node.parameter)) {
130 throw 'Type parameter ${node.parameter} referenced out of scope '
131 'in $context.\n'
132 'Parent pointer is set to ${node.parameter.parent}';
133 }
134 }
135
136 @override
137 visitInterfaceType(InterfaceType node) {
138 node.visitChildren(this);
139 if (node.typeArguments.length != node.classNode.typeParameters.length) {
140 throw 'Type $node provides ${node.typeArguments.length} type arguments '
141 'but the class declares ${node.classNode.typeParameters.length} '
142 'parameters. Found in $context.';
143 }
144 }
145 }
146
147 class CheckParentPointers extends Visitor {
148 static void check(TreeNode node) {
149 node.accept(new CheckParentPointers(node.parent));
150 }
151
152 TreeNode parent;
153
154 CheckParentPointers([this.parent]);
155
156 defaultTreeNode(TreeNode node) {
157 if (node.parent != parent) {
158 throw 'Parent pointer on ${node.runtimeType} '
159 'is ${node.parent.runtimeType} '
160 'but should be ${parent.runtimeType}';
161 }
162 var oldParent = parent;
163 parent = node;
164 node.visitChildren(this);
165 parent = oldParent;
166 }
167 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/ast.dart ('k') | pkg/kernel/lib/text/ast_to_text.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698