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 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 visitVariableGet(VariableGet node) { | 239 visitVariableGet(VariableGet node) { |
240 checkVariableInScope(node.variable, node); | 240 checkVariableInScope(node.variable, node); |
241 } | 241 } |
242 | 242 |
243 visitVariableSet(VariableSet node) { | 243 visitVariableSet(VariableSet node) { |
244 checkVariableInScope(node.variable, node); | 244 checkVariableInScope(node.variable, node); |
245 visitChildren(node); | 245 visitChildren(node); |
246 } | 246 } |
247 | 247 |
248 @override | 248 @override |
| 249 visitStaticGet(StaticGet node) { |
| 250 visitChildren(node); |
| 251 if (node.target == null) { |
| 252 throw 'StaticGet without target found in $context.'; |
| 253 } |
| 254 if (!node.target.hasGetter) { |
| 255 throw 'StaticGet to ${node.target} without getter found in $context'; |
| 256 } |
| 257 if (node.target.isInstanceMember) { |
| 258 throw 'StaticGet to ${node.target} that is not static found in $context'; |
| 259 } |
| 260 } |
| 261 |
| 262 @override |
| 263 visitStaticSet(StaticSet node) { |
| 264 visitChildren(node); |
| 265 if (node.target == null) { |
| 266 throw 'StaticSet without target found in $context.'; |
| 267 } |
| 268 if (!node.target.hasSetter) { |
| 269 throw 'StaticSet to ${node.target} without setter found in $context'; |
| 270 } |
| 271 if (node.target.isInstanceMember) { |
| 272 throw 'StaticSet to ${node.target} that is not static found in $context'; |
| 273 } |
| 274 } |
| 275 |
| 276 @override |
| 277 visitStaticInvocation(StaticInvocation node) { |
| 278 visitChildren(node); |
| 279 if (node.target == null) { |
| 280 throw 'StaticInvocation without target found in $context.'; |
| 281 } |
| 282 if (node.target.isInstanceMember) { |
| 283 throw 'StaticInvocation to ${node.target} that is not static found in ' |
| 284 '$context'; |
| 285 } |
| 286 if (!areArgumentsCompatible(node.arguments, node.target.function)) { |
| 287 throw 'StaticInvocation with incompatible arguments to ' |
| 288 '${node.target} found in $context'; |
| 289 } |
| 290 if (node.arguments.types.length != |
| 291 node.target.function.typeParameters.length) { |
| 292 throw 'Wrong number of type arguments provided in StaticInvocation ' |
| 293 'to ${node.target} found in $context'; |
| 294 } |
| 295 } |
| 296 |
| 297 @override |
| 298 visitDirectPropertyGet(DirectPropertyGet node) { |
| 299 visitChildren(node); |
| 300 if (node.target == null) { |
| 301 throw 'DirectPropertyGet without target found in $context.'; |
| 302 } |
| 303 if (!node.target.hasGetter) { |
| 304 throw 'DirectPropertyGet to ${node.target} without getter found in ' |
| 305 '$context'; |
| 306 } |
| 307 if (!node.target.isInstanceMember) { |
| 308 throw 'DirectPropertyGet to ${node.target} that is static found in ' |
| 309 '$context'; |
| 310 } |
| 311 } |
| 312 |
| 313 @override |
| 314 visitDirectPropertySet(DirectPropertySet node) { |
| 315 visitChildren(node); |
| 316 if (node.target == null) { |
| 317 throw 'DirectPropertySet without target found in $context.'; |
| 318 } |
| 319 if (!node.target.hasSetter) { |
| 320 throw 'DirectPropertyGet to ${node.target} without setter found in ' |
| 321 '$context'; |
| 322 } |
| 323 if (!node.target.isInstanceMember) { |
| 324 throw 'DirectPropertySet to ${node.target} that is static found in ' |
| 325 '$context'; |
| 326 } |
| 327 } |
| 328 |
| 329 @override |
| 330 visitDirectMethodInvocation(DirectMethodInvocation node) { |
| 331 visitChildren(node); |
| 332 if (node.target == null) { |
| 333 throw 'DirectMethodInvocation without target found in $context.'; |
| 334 } |
| 335 if (!node.target.isInstanceMember) { |
| 336 throw 'DirectMethodInvocation to ${node.target} that is static found in ' |
| 337 '$context'; |
| 338 } |
| 339 if (!areArgumentsCompatible(node.arguments, node.target.function)) { |
| 340 throw 'DirectMethodInvocation with incompatible arguments to ' |
| 341 '${node.target} found in $context'; |
| 342 } |
| 343 if (node.arguments.types.length != |
| 344 node.target.function.typeParameters.length) { |
| 345 throw 'Wrong number of type arguments provided in DirectMethodInvocation ' |
| 346 'to ${node.target} found in $context'; |
| 347 } |
| 348 } |
| 349 |
| 350 @override |
| 351 visitConstructorInvocation(ConstructorInvocation node) { |
| 352 visitChildren(node); |
| 353 if (node.target == null) { |
| 354 throw 'ConstructorInvocation without target found in $context.'; |
| 355 } |
| 356 if (node.target.enclosingClass.isAbstract) { |
| 357 throw 'ConstructorInvocation to abstract class found in $context'; |
| 358 } |
| 359 if (!areArgumentsCompatible(node.arguments, node.target.function)) { |
| 360 throw 'ConstructorInvocation with incompatible arguments to ' |
| 361 '${node.target} found in $context'; |
| 362 } |
| 363 if (node.arguments.types.length != |
| 364 node.target.enclosingClass.typeParameters.length) { |
| 365 throw 'Wrong number of type arguments provided in ConstructorInvocation ' |
| 366 'to ${node.target} found in $context'; |
| 367 } |
| 368 } |
| 369 |
| 370 bool areArgumentsCompatible(Arguments arguments, FunctionNode function) { |
| 371 if (arguments.positional.length < function.requiredParameterCount) { |
| 372 return false; |
| 373 } |
| 374 if (arguments.positional.length > function.positionalParameters.length) { |
| 375 return false; |
| 376 } |
| 377 namedLoop: |
| 378 for (int i = 0; i < arguments.named.length; ++i) { |
| 379 var argument = arguments.named[i]; |
| 380 String name = argument.name; |
| 381 for (int j = 0; j < function.namedParameters.length; ++j) { |
| 382 if (function.namedParameters[j].name == name) continue namedLoop; |
| 383 } |
| 384 return false; |
| 385 } |
| 386 return true; |
| 387 } |
| 388 |
| 389 @override |
249 defaultMemberReference(Member node) { | 390 defaultMemberReference(Member node) { |
250 if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) { | 391 if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) { |
251 throw 'Dangling reference to $node found in $context.\n' | 392 throw 'Dangling reference to $node found in $context.\n' |
252 'Parent pointer is set to ${node.parent}'; | 393 'Parent pointer is set to ${node.parent}'; |
253 } | 394 } |
254 } | 395 } |
255 | 396 |
256 @override | 397 @override |
257 visitClassReference(Class node) { | 398 visitClassReference(Class node) { |
258 if (!classes.contains(node)) { | 399 if (!classes.contains(node)) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 throw 'Parent pointer on ${node.runtimeType} ' | 441 throw 'Parent pointer on ${node.runtimeType} ' |
301 'is ${node.parent.runtimeType} ' | 442 'is ${node.parent.runtimeType} ' |
302 'but should be ${parent.runtimeType}'; | 443 'but should be ${parent.runtimeType}'; |
303 } | 444 } |
304 var oldParent = parent; | 445 var oldParent = parent; |
305 parent = node; | 446 parent = node; |
306 node.visitChildren(this); | 447 node.visitChildren(this); |
307 parent = oldParent; | 448 parent = oldParent; |
308 } | 449 } |
309 } | 450 } |
OLD | NEW |