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

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

Issue 2849803002: Revert "Add typedef AST node boilerplate." (Closed)
Patch Set: Created 3 years, 7 months 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/type_environment.dart ('k') | pkg/kernel/lib/visitor.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.checks; 4 library kernel.checks;
5 5
6 import 'ast.dart'; 6 import 'ast.dart';
7 import 'transformations/flags.dart'; 7 import 'transformations/flags.dart';
8 8
9 void verifyProgram(Program program) { 9 void verifyProgram(Program program) {
10 VerifyingVisitor.check(program); 10 VerifyingVisitor.check(program);
(...skipping 20 matching lines...) Expand all
31 return "$file:${location.line}:${location.column}: Verification error:" 31 return "$file:${location.line}:${location.column}: Verification error:"
32 " $details"; 32 " $details";
33 } else { 33 } else {
34 return "Verification error: $details\n" 34 return "Verification error: $details\n"
35 "Context: '$context'.\n" 35 "Context: '$context'.\n"
36 "Node: '$node'."; 36 "Node: '$node'.";
37 } 37 }
38 } 38 }
39 } 39 }
40 40
41 enum TypedefState { Done, BeingChecked }
42
43 /// Checks that a kernel program is well-formed. 41 /// Checks that a kernel program is well-formed.
44 /// 42 ///
45 /// This does not include any kind of type checking. 43 /// This does not include any kind of type checking.
46 class VerifyingVisitor extends RecursiveVisitor { 44 class VerifyingVisitor extends RecursiveVisitor {
47 final Set<Class> classes = new Set<Class>(); 45 final Set<Class> classes = new Set<Class>();
48 final Set<Typedef> typedefs = new Set<Typedef>(); 46 final Set<TypeParameter> typeParameters = new Set<TypeParameter>();
49 Set<TypeParameter> typeParametersInScope = new Set<TypeParameter>();
50 final List<VariableDeclaration> variableStack = <VariableDeclaration>[]; 47 final List<VariableDeclaration> variableStack = <VariableDeclaration>[];
51 final Map<Typedef, TypedefState> typedefState = <Typedef, TypedefState>{};
52 bool classTypeParametersAreInScope = false; 48 bool classTypeParametersAreInScope = false;
53 49
54 /// If true, relax certain checks for *outline* mode. For example, don't 50 /// If true, relax certain checks for *outline* mode. For example, don't
55 /// attempt to validate constructor initializers. 51 /// attempt to validate constructor initializers.
56 bool isOutline = false; 52 bool isOutline = false;
57 53
58 bool inCatchBlock = false; 54 bool inCatchBlock = false;
59 55
60 Member currentMember; 56 Member currentMember;
61 Class currentClass; 57 Class currentClass;
62 TreeNode currentParent; 58 TreeNode currentParent;
63 59
64 TreeNode get context => currentMember ?? currentClass; 60 TreeNode get context => currentMember ?? currentClass;
65 61
66 static void check(Program program) { 62 static void check(Program program) {
67 program.accept(new VerifyingVisitor()); 63 program.accept(new VerifyingVisitor());
68 } 64 }
69 65
70 defaultTreeNode(TreeNode node) { 66 defaultTreeNode(TreeNode node) {
71 visitChildren(node); 67 visitChildren(node);
72 } 68 }
73 69
74 problem(TreeNode node, String details, {TreeNode context}) { 70 problem(TreeNode node, String details) {
75 context ??= this.context;
76 throw new VerificationError(context, node, details); 71 throw new VerificationError(context, node, details);
77 } 72 }
78 73
79 TreeNode enterParent(TreeNode node) { 74 TreeNode enterParent(TreeNode node) {
80 if (!identical(node.parent, currentParent)) { 75 if (!identical(node.parent, currentParent)) {
81 problem( 76 problem(
82 node, 77 node,
83 "Incorrect parent pointer on ${node.runtimeType}:" 78 "Incorrect parent pointer: expected '${node.parent.runtimeType}',"
84 " expected '${node.parent.runtimeType}',"
85 " but found: '${currentParent.runtimeType}'."); 79 " but found: '${currentParent.runtimeType}'.");
86 } 80 }
87 var oldParent = currentParent; 81 var oldParent = currentParent;
88 currentParent = node; 82 currentParent = node;
89 return oldParent; 83 return oldParent;
90 } 84 }
91 85
92 void exitParent(TreeNode oldParent) { 86 void exitParent(TreeNode oldParent) {
93 currentParent = oldParent; 87 currentParent = oldParent;
94 } 88 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 variableStack.add(variable); 128 variableStack.add(variable);
135 } 129 }
136 130
137 void undeclareVariable(VariableDeclaration variable) { 131 void undeclareVariable(VariableDeclaration variable) {
138 variable.flags &= ~VariableDeclaration.FlagInScope; 132 variable.flags &= ~VariableDeclaration.FlagInScope;
139 } 133 }
140 134
141 void declareTypeParameters(List<TypeParameter> parameters) { 135 void declareTypeParameters(List<TypeParameter> parameters) {
142 for (int i = 0; i < parameters.length; ++i) { 136 for (int i = 0; i < parameters.length; ++i) {
143 var parameter = parameters[i]; 137 var parameter = parameters[i];
144 if (!typeParametersInScope.add(parameter)) { 138 if (!typeParameters.add(parameter)) {
145 problem(parameter, "Type parameter '$parameter' redeclared."); 139 problem(parameter, "Type parameter '$parameter' redeclared.");
146 } 140 }
147 } 141 }
148 } 142 }
149 143
150 void undeclareTypeParameters(List<TypeParameter> parameters) { 144 void undeclareTypeParameters(List<TypeParameter> parameters) {
151 typeParametersInScope.removeAll(parameters); 145 typeParameters.removeAll(parameters);
152 } 146 }
153 147
154 void checkVariableInScope(VariableDeclaration variable, TreeNode where) { 148 void checkVariableInScope(VariableDeclaration variable, TreeNode where) {
155 if (variable.flags & VariableDeclaration.FlagInScope == 0) { 149 if (variable.flags & VariableDeclaration.FlagInScope == 0) {
156 problem(where, "Variable '$variable' used out of scope."); 150 problem(where, "Variable '$variable' used out of scope.");
157 } 151 }
158 } 152 }
159 153
160 visitProgram(Program program) { 154 visitProgram(Program program) {
161 try { 155 try {
162 for (var library in program.libraries) { 156 for (var library in program.libraries) {
163 for (var class_ in library.classes) { 157 for (var class_ in library.classes) {
164 if (!classes.add(class_)) { 158 if (!classes.add(class_)) {
165 problem(class_, "Class '$class_' declared more than once."); 159 problem(class_, "Class '$class_' declared more than once.");
166 } 160 }
167 } 161 }
168 for (var typedef_ in library.typedefs) {
169 if (!typedefs.add(typedef_)) {
170 problem(typedef_, "Typedef '$typedef_' declared more than once.");
171 }
172 }
173 library.members.forEach(declareMember); 162 library.members.forEach(declareMember);
174 for (var class_ in library.classes) { 163 for (var class_ in library.classes) {
175 class_.members.forEach(declareMember); 164 class_.members.forEach(declareMember);
176 } 165 }
177 } 166 }
178 visitChildren(program); 167 visitChildren(program);
179 } finally { 168 } finally {
180 for (var library in program.libraries) { 169 for (var library in program.libraries) {
181 library.members.forEach(undeclareMember); 170 library.members.forEach(undeclareMember);
182 for (var class_ in library.classes) { 171 for (var class_ in library.classes) {
183 class_.members.forEach(undeclareMember); 172 class_.members.forEach(undeclareMember);
184 } 173 }
185 } 174 }
186 variableStack.forEach(undeclareVariable); 175 variableStack.forEach(undeclareVariable);
187 } 176 }
188 } 177 }
189 178
190 void checkTypedef(Typedef node) {
191 var state = typedefState[node];
192 if (state == TypedefState.Done) return;
193 if (state == TypedefState.BeingChecked) {
194 problem(node, "The typedef '$node' refers to itself", context: node);
195 }
196 assert(state == null);
197 typedefState[node] = TypedefState.BeingChecked;
198 var savedTypeParameters = typeParametersInScope;
199 typeParametersInScope = node.typeParameters.toSet();
200 var savedParent = currentParent;
201 currentParent = node;
202 // Visit children without checking the parent pointer on the typedef itself
203 // since this can be called from a context other than its true parent.
204 node.visitChildren(this);
205 currentParent = savedParent;
206 typeParametersInScope = savedTypeParameters;
207 typedefState[node] = TypedefState.Done;
208 }
209
210 visitTypedef(Typedef node) {
211 checkTypedef(node);
212 // Enter and exit the node to check the parent pointer on the typedef node.
213 exitParent(enterParent(node));
214 }
215
216 visitField(Field node) { 179 visitField(Field node) {
217 currentMember = node; 180 currentMember = node;
218 var oldParent = enterParent(node); 181 var oldParent = enterParent(node);
219 classTypeParametersAreInScope = !node.isStatic; 182 classTypeParametersAreInScope = !node.isStatic;
220 node.initializer?.accept(this); 183 node.initializer?.accept(this);
221 classTypeParametersAreInScope = false; 184 classTypeParametersAreInScope = false;
222 visitList(node.annotations, this); 185 visitList(node.annotations, this);
223 exitParent(oldParent); 186 exitParent(oldParent);
224 node.type.accept(this);
225 currentMember = null; 187 currentMember = null;
226 } 188 }
227 189
228 visitProcedure(Procedure node) { 190 visitProcedure(Procedure node) {
229 currentMember = node; 191 currentMember = node;
230 var oldParent = enterParent(node); 192 var oldParent = enterParent(node);
231 classTypeParametersAreInScope = !node.isStatic; 193 classTypeParametersAreInScope = !node.isStatic;
232 node.function.accept(this); 194 node.function.accept(this);
233 classTypeParametersAreInScope = false; 195 classTypeParametersAreInScope = false;
234 visitList(node.annotations, this); 196 visitList(node.annotations, this);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 485
524 @override 486 @override
525 visitClassReference(Class node) { 487 visitClassReference(Class node) {
526 if (!classes.contains(node)) { 488 if (!classes.contains(node)) {
527 problem( 489 problem(
528 node, "Dangling reference to '$node', parent is: '${node.parent}'."); 490 node, "Dangling reference to '$node', parent is: '${node.parent}'.");
529 } 491 }
530 } 492 }
531 493
532 @override 494 @override
533 visitTypedefReference(Typedef node) {
534 if (!typedefs.contains(node)) {
535 problem(
536 node, "Dangling reference to '$node', parent is: '${node.parent}'");
537 }
538 }
539
540 @override
541 visitTypeParameterType(TypeParameterType node) { 495 visitTypeParameterType(TypeParameterType node) {
542 var parameter = node.parameter; 496 var parameter = node.parameter;
543 if (!typeParametersInScope.contains(parameter)) { 497 if (!typeParameters.contains(parameter)) {
544 problem( 498 problem(
545 currentParent, 499 currentParent,
546 "Type parameter '$parameter' referenced out of" 500 "Type parameter '$parameter' referenced out of"
547 " scope, parent is: '${parameter.parent}'."); 501 " scope, parent is: '${parameter.parent}'.");
548 } 502 }
549 if (parameter.parent is Class && !classTypeParametersAreInScope) { 503 if (parameter.parent is Class && !classTypeParametersAreInScope) {
550 problem( 504 problem(
551 currentParent, 505 currentParent,
552 "Type parameter '$parameter' referenced from" 506 "Type parameter '$parameter' referenced from"
553 " static context, parent is '${parameter.parent}'."); 507 " static context, parent is '${parameter.parent}'.");
554 } 508 }
555 } 509 }
556 510
557 @override 511 @override
558 visitInterfaceType(InterfaceType node) { 512 visitInterfaceType(InterfaceType node) {
559 node.visitChildren(this); 513 node.visitChildren(this);
560 if (node.typeArguments.length != node.classNode.typeParameters.length) { 514 if (node.typeArguments.length != node.classNode.typeParameters.length) {
561 problem( 515 problem(
562 currentParent, 516 currentParent,
563 "Type $node provides ${node.typeArguments.length}" 517 "Type $node provides ${node.typeArguments.length}"
564 " type arguments but the class declares" 518 " type arguments but the class declares"
565 " ${node.classNode.typeParameters.length} parameters."); 519 " ${node.classNode.typeParameters.length} parameters.");
566 } 520 }
567 } 521 }
568
569 @override
570 visitTypedefType(TypedefType node) {
571 checkTypedef(node.typedefNode);
572 node.visitChildren(this);
573 if (node.typeArguments.length != node.typedefNode.typeParameters.length) {
574 problem(
575 currentParent,
576 "The typedef type $node provides ${node.typeArguments.length}"
577 " type arguments but the typedef declares"
578 " ${node.typedefNode.typeParameters.length} parameters.");
579 }
580 }
581 } 522 }
582 523
583 class CheckParentPointers extends Visitor { 524 class CheckParentPointers extends Visitor {
584 static void check(TreeNode node) { 525 static void check(TreeNode node) {
585 node.accept(new CheckParentPointers(node.parent)); 526 node.accept(new CheckParentPointers(node.parent));
586 } 527 }
587 528
588 TreeNode parent; 529 TreeNode parent;
589 530
590 CheckParentPointers([this.parent]); 531 CheckParentPointers([this.parent]);
(...skipping 10 matching lines...) Expand all
601 var oldParent = parent; 542 var oldParent = parent;
602 parent = node; 543 parent = node;
603 node.visitChildren(this); 544 node.visitChildren(this);
604 parent = oldParent; 545 parent = oldParent;
605 } 546 }
606 } 547 }
607 548
608 void checkInitializers(Constructor constructor) { 549 void checkInitializers(Constructor constructor) {
609 // TODO(ahe): I'll add more here in other CLs. 550 // TODO(ahe): I'll add more here in other CLs.
610 } 551 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/type_environment.dart ('k') | pkg/kernel/lib/visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698