| OLD | NEW |
| 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 | 7 |
| 8 void runSanityChecks(Program program) { | 8 void runSanityChecks(Program program) { |
| 9 CheckParentPointers.check(program); | 9 CheckParentPointers.check(program); |
| 10 CheckReferences.check(program); | 10 CheckReferences.check(program); |
| 11 } | 11 } |
| 12 | 12 |
| 13 class CheckParentPointers extends FakeNodeVisitor { | 13 class CheckParentPointers extends Visitor { |
| 14 static void check(TreeNode node) { | 14 static void check(TreeNode node) { |
| 15 node.accept(new CheckParentPointers(node.parent)); | 15 node.accept(new CheckParentPointers(node.parent)); |
| 16 } | 16 } |
| 17 | 17 |
| 18 TreeNode parent; | 18 TreeNode parent; |
| 19 | 19 |
| 20 CheckParentPointers([this.parent]); | 20 CheckParentPointers([this.parent]); |
| 21 | 21 |
| 22 defaultTreeNode(TreeNode node) { | 22 defaultTreeNode(TreeNode node) { |
| 23 if (node.parent != parent) { | 23 if (node.parent != parent) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 109 visitInterfaceType(InterfaceType node) { | 109 visitInterfaceType(InterfaceType node) { |
| 110 node.visitChildren(this); | 110 node.visitChildren(this); |
| 111 if (node.typeArguments.length != node.classNode.typeParameters.length) { | 111 if (node.typeArguments.length != node.classNode.typeParameters.length) { |
| 112 throw 'Type $node provides ${node.typeArguments.length} type arguments ' | 112 throw 'Type $node provides ${node.typeArguments.length} type arguments ' |
| 113 'but the class declares ${node.classNode.typeParameters.length} ' | 113 'but the class declares ${node.classNode.typeParameters.length} ' |
| 114 'parameters. Found in $context.'; | 114 'parameters. Found in $context.'; |
| 115 } | 115 } |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 abstract class FakeNode implements TreeNode {} | |
| 120 | |
| 121 abstract class FakeNodeVisitor extends Visitor { | |
| 122 visitFakeNode(FakeNode node) => defaultNode(node); | |
| 123 } | |
| 124 | |
| 125 class FakeExpression extends Expression implements FakeNode { | |
| 126 Expression node; | |
| 127 | |
| 128 FakeExpression(this.node) { | |
| 129 node?.parent = this; | |
| 130 } | |
| 131 | |
| 132 accept(FakeNodeVisitor v) => v.visitFakeNode(this); | |
| 133 | |
| 134 visitChildren(Visitor v) { | |
| 135 node?.accept(v); | |
| 136 } | |
| 137 | |
| 138 transformChildren(Transformer v) { | |
| 139 if (node != null) { | |
| 140 node = node.accept(v); | |
| 141 node?.parent = this; | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 DartType getStaticType(types) => const BottomType(); | |
| 146 } | |
| 147 | |
| 148 class FakeStatement extends Statement implements FakeNode { | |
| 149 Statement node; | |
| 150 | |
| 151 FakeStatement(this.node) { | |
| 152 node?.parent = this; | |
| 153 } | |
| 154 | |
| 155 accept(FakeNodeVisitor v) => v.visitFakeNode(this); | |
| 156 | |
| 157 visitChildren(Visitor v) { | |
| 158 node?.accept(v); | |
| 159 } | |
| 160 | |
| 161 transformChildren(Transformer v) { | |
| 162 if (node != null) { | |
| 163 node = node.accept(v); | |
| 164 node?.parent = this; | |
| 165 } | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 class InsertWrappers extends Transformer { | |
| 170 defaultExpression(node) => new FakeExpression(defaultTreeNode(node)); | |
| 171 defaultStatement(node) => new FakeStatement(defaultTreeNode(node)); | |
| 172 | |
| 173 visitVariableDeclaration(VariableDeclaration node) { | |
| 174 return defaultTreeNode(node); | |
| 175 } | |
| 176 } | |
| 177 | |
| 178 class CheckTransformers extends FakeNodeVisitor { | |
| 179 static void transformAndCheck(TreeNode node) { | |
| 180 var transformed = node.accept(new InsertWrappers()); | |
| 181 CheckParentPointers.check(transformed); | |
| 182 transformed.accept(new CheckTransformers()); | |
| 183 } | |
| 184 | |
| 185 defaultNode(TreeNode node) { | |
| 186 if (node is FakeNode) { | |
| 187 if (node.parent is FakeNode) { | |
| 188 throw 'FakeNode was wrapped multiple times'; | |
| 189 } | |
| 190 } else if (node is Expression || | |
| 191 node is Statement && node is! VariableDeclaration) { | |
| 192 if (node.parent is! FakeNode) { | |
| 193 throw '${node.runtimeType} inside ${node.parent.runtimeType} was not wra
pped'; | |
| 194 } | |
| 195 } | |
| 196 node.visitChildren(this); | |
| 197 } | |
| 198 } | |
| 199 | |
| 200 class SizeCounter extends RecursiveVisitor { | 119 class SizeCounter extends RecursiveVisitor { |
| 201 int size = 0; | 120 int size = 0; |
| 202 int emptyArguments = 0; | 121 int emptyArguments = 0; |
| 203 | 122 |
| 204 void visit(TreeNode node) => node.accept(this); | 123 void visit(TreeNode node) => node.accept(this); |
| 205 | 124 |
| 206 visitArguments(Arguments node) { | 125 visitArguments(Arguments node) { |
| 207 super.visitArguments(node); | 126 super.visitArguments(node); |
| 208 if (node.positional.isEmpty && | 127 if (node.positional.isEmpty && |
| 209 node.positional.isEmpty && | 128 node.positional.isEmpty && |
| 210 node.types.isEmpty) { | 129 node.types.isEmpty) { |
| 211 ++emptyArguments; | 130 ++emptyArguments; |
| 212 } | 131 } |
| 213 } | 132 } |
| 214 | 133 |
| 215 defaultNode(TreeNode node) { | 134 defaultNode(Node node) { |
| 216 ++size; | 135 ++size; |
| 217 node.visitChildren(this); | 136 node.visitChildren(this); |
| 218 } | 137 } |
| 219 } | 138 } |
| OLD | NEW |