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

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

Issue 2665723002: Implement canonical name scheme in kernel. (Closed)
Patch Set: Address Kevin's comments Created 3 years, 10 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_propagation/type_propagation.dart ('k') | pkg/kernel/test/ast_membench.sh » ('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 13 matching lines...) Expand all
24 try { 24 try {
25 location = node?.location ?? context?.location; 25 location = node?.location ?? context?.location;
26 } catch (_) { 26 } catch (_) {
27 // TODO(ahe): Fix the compiler instead. 27 // TODO(ahe): Fix the compiler instead.
28 } 28 }
29 if (location != null) { 29 if (location != null) {
30 String file = location.file ?? ""; 30 String file = location.file ?? "";
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 34 return "Verification error: $details\nContext: '$context'.\nNode: '$node'. ";
35 "Verification error: $details\nContext: '$context'.\nNode: '$node'.";
36 } 35 }
37 } 36 }
38 } 37 }
39 38
40 /// Checks that a kernel program is well-formed. 39 /// Checks that a kernel program is well-formed.
41 /// 40 ///
42 /// This does not include any kind of type checking. 41 /// This does not include any kind of type checking.
43 class VerifyingVisitor extends RecursiveVisitor { 42 class VerifyingVisitor extends RecursiveVisitor {
44 final Set<Class> classes = new Set<Class>(); 43 final Set<Class> classes = new Set<Class>();
45 final Set<TypeParameter> typeParameters = new Set<TypeParameter>(); 44 final Set<TypeParameter> typeParameters = new Set<TypeParameter>();
(...skipping 17 matching lines...) Expand all
63 defaultTreeNode(TreeNode node) { 62 defaultTreeNode(TreeNode node) {
64 visitChildren(node); 63 visitChildren(node);
65 } 64 }
66 65
67 problem(TreeNode node, String details) { 66 problem(TreeNode node, String details) {
68 throw new VerificationError(context, node, details); 67 throw new VerificationError(context, node, details);
69 } 68 }
70 69
71 TreeNode enterParent(TreeNode node) { 70 TreeNode enterParent(TreeNode node) {
72 if (!identical(node.parent, currentParent)) { 71 if (!identical(node.parent, currentParent)) {
73 problem(node, 72 problem(
73 node,
74 "Incorrect parent pointer: expected '${node.parent.runtimeType}'," 74 "Incorrect parent pointer: expected '${node.parent.runtimeType}',"
75 " but found: '${currentParent.runtimeType}'."); 75 " but found: '${currentParent.runtimeType}'.");
76 } 76 }
77 var oldParent = currentParent; 77 var oldParent = currentParent;
78 currentParent = node; 78 currentParent = node;
79 return oldParent; 79 return oldParent;
80 } 80 }
81 81
82 void exitParent(TreeNode oldParent) { 82 void exitParent(TreeNode oldParent) {
83 currentParent = oldParent; 83 currentParent = oldParent;
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 317 }
318 318
319 @override 319 @override
320 visitStaticInvocation(StaticInvocation node) { 320 visitStaticInvocation(StaticInvocation node) {
321 checkTargetedInvocation(node.target, node); 321 checkTargetedInvocation(node.target, node);
322 if (node.target.isInstanceMember) { 322 if (node.target.isInstanceMember) {
323 problem(node, 323 problem(node,
324 "StaticInvocation of '${node.target}' that's an instance member."); 324 "StaticInvocation of '${node.target}' that's an instance member.");
325 } 325 }
326 if (node.isConst && 326 if (node.isConst &&
327 (!node.target.isConst || !node.target.isExternal || 327 (!node.target.isConst ||
328 !node.target.isExternal ||
328 node.target.kind != ProcedureKind.Factory)) { 329 node.target.kind != ProcedureKind.Factory)) {
329 problem(node, "Constant StaticInvocation of '${node.target}' that isn't" 330 problem(
331 node,
332 "Constant StaticInvocation of '${node.target}' that isn't"
330 " a const external factory."); 333 " a const external factory.");
331 } 334 }
332 } 335 }
333 336
334 void checkTargetedInvocation(Member target, InvocationExpression node) { 337 void checkTargetedInvocation(Member target, InvocationExpression node) {
335 visitChildren(node); 338 visitChildren(node);
336 if (target == null) { 339 if (target == null) {
337 problem(node, "${node.runtimeType} without target."); 340 problem(node, "${node.runtimeType} without target.");
338 } 341 }
339 if (target.function == null) { 342 if (target.function == null) {
340 problem(node, "${node.runtimeType} without function."); 343 problem(node, "${node.runtimeType} without function.");
341 } 344 }
342 if (!areArgumentsCompatible(node.arguments, target.function)) { 345 if (!areArgumentsCompatible(node.arguments, target.function)) {
343 problem(node, 346 problem(node,
344 "${node.runtimeType} with incompatible arguments for '${target}'."); 347 "${node.runtimeType} with incompatible arguments for '${target}'.");
345 } 348 }
346 int expectedTypeParameters = target is Constructor 349 int expectedTypeParameters = target is Constructor
347 ? target.enclosingClass.typeParameters.length 350 ? target.enclosingClass.typeParameters.length
348 : target.function.typeParameters.length; 351 : target.function.typeParameters.length;
349 if (node.arguments.types.length != expectedTypeParameters) { 352 if (node.arguments.types.length != expectedTypeParameters) {
350 problem(node, "${node.runtimeType} with wrong number of type arguments" 353 problem(
354 node,
355 "${node.runtimeType} with wrong number of type arguments"
351 " for '${target}'."); 356 " for '${target}'.");
352 } 357 }
353 } 358 }
354 359
355 @override 360 @override
356 visitDirectPropertyGet(DirectPropertyGet node) { 361 visitDirectPropertyGet(DirectPropertyGet node) {
357 visitChildren(node); 362 visitChildren(node);
358 if (node.target == null) { 363 if (node.target == null) {
359 problem(node, "DirectPropertyGet without target."); 364 problem(node, "DirectPropertyGet without target.");
360 } 365 }
361 if (!node.target.hasGetter) { 366 if (!node.target.hasGetter) {
362 problem(node, "DirectPropertyGet of '${node.target}' without getter."); 367 problem(node, "DirectPropertyGet of '${node.target}' without getter.");
363 } 368 }
364 if (!node.target.isInstanceMember) { 369 if (!node.target.isInstanceMember) {
365 problem(node, "DirectPropertyGet of '${node.target}' that isn't an" 370 problem(
371 node,
372 "DirectPropertyGet of '${node.target}' that isn't an"
366 " instance member."); 373 " instance member.");
367 } 374 }
368 } 375 }
369 376
370 @override 377 @override
371 visitDirectPropertySet(DirectPropertySet node) { 378 visitDirectPropertySet(DirectPropertySet node) {
372 visitChildren(node); 379 visitChildren(node);
373 if (node.target == null) { 380 if (node.target == null) {
374 problem(node, "DirectPropertySet without target."); 381 problem(node, "DirectPropertySet without target.");
375 } 382 }
(...skipping 13 matching lines...) Expand all
389 } 396 }
390 } 397 }
391 398
392 @override 399 @override
393 visitConstructorInvocation(ConstructorInvocation node) { 400 visitConstructorInvocation(ConstructorInvocation node) {
394 checkTargetedInvocation(node.target, node); 401 checkTargetedInvocation(node.target, node);
395 if (node.target.enclosingClass.isAbstract) { 402 if (node.target.enclosingClass.isAbstract) {
396 problem(node, "ConstructorInvocation of abstract class."); 403 problem(node, "ConstructorInvocation of abstract class.");
397 } 404 }
398 if (node.isConst && !node.target.isConst) { 405 if (node.isConst && !node.target.isConst) {
399 problem(node, "Constant ConstructorInvocation fo '${node.target}' that" 406 problem(
407 node,
408 "Constant ConstructorInvocation fo '${node.target}' that"
400 " isn't const."); 409 " isn't const.");
401 } 410 }
402 } 411 }
403 412
404 bool areArgumentsCompatible(Arguments arguments, FunctionNode function) { 413 bool areArgumentsCompatible(Arguments arguments, FunctionNode function) {
405 if (arguments.positional.length < function.requiredParameterCount) { 414 if (arguments.positional.length < function.requiredParameterCount) {
406 return false; 415 return false;
407 } 416 }
408 if (arguments.positional.length > function.positionalParameters.length) { 417 if (arguments.positional.length > function.positionalParameters.length) {
409 return false; 418 return false;
410 } 419 }
411 namedLoop: 420 namedLoop:
412 for (int i = 0; i < arguments.named.length; ++i) { 421 for (int i = 0; i < arguments.named.length; ++i) {
413 var argument = arguments.named[i]; 422 var argument = arguments.named[i];
414 String name = argument.name; 423 String name = argument.name;
415 for (int j = 0; j < function.namedParameters.length; ++j) { 424 for (int j = 0; j < function.namedParameters.length; ++j) {
416 if (function.namedParameters[j].name == name) continue namedLoop; 425 if (function.namedParameters[j].name == name) continue namedLoop;
417 } 426 }
418 return false; 427 return false;
419 } 428 }
420 return true; 429 return true;
421 } 430 }
422 431
423 @override 432 @override
424 defaultMemberReference(Member node) { 433 defaultMemberReference(Member node) {
425 if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) { 434 if (node.transformerFlags & TransformerFlag.seenByVerifier == 0) {
426 problem(node, 435 problem(
427 "Dangling reference to '$node', parent is: '${node.parent}'."); 436 node, "Dangling reference to '$node', parent is: '${node.parent}'.");
428 } 437 }
429 } 438 }
430 439
431 @override 440 @override
432 visitClassReference(Class node) { 441 visitClassReference(Class node) {
433 if (!classes.contains(node)) { 442 if (!classes.contains(node)) {
434 problem(node, 443 problem(
435 "Dangling reference to '$node', parent is: '${node.parent}'."); 444 node, "Dangling reference to '$node', parent is: '${node.parent}'.");
436 } 445 }
437 } 446 }
438 447
439 @override 448 @override
440 visitTypeParameterType(TypeParameterType node) { 449 visitTypeParameterType(TypeParameterType node) {
441 var parameter = node.parameter; 450 var parameter = node.parameter;
442 if (!typeParameters.contains(parameter)) { 451 if (!typeParameters.contains(parameter)) {
443 problem(currentParent, "Type parameter '$parameter' referenced out of" 452 problem(
453 currentParent,
454 "Type parameter '$parameter' referenced out of"
444 " scope, parent is: '${parameter.parent}'."); 455 " scope, parent is: '${parameter.parent}'.");
445 } 456 }
446 if (parameter.parent is Class && !classTypeParametersAreInScope) { 457 if (parameter.parent is Class && !classTypeParametersAreInScope) {
447 problem(currentParent, "Type parameter '$parameter' referenced from" 458 problem(
459 currentParent,
460 "Type parameter '$parameter' referenced from"
448 " static context, parent is '${parameter.parent}'."); 461 " static context, parent is '${parameter.parent}'.");
449 } 462 }
450 } 463 }
451 464
452 @override 465 @override
453 visitInterfaceType(InterfaceType node) { 466 visitInterfaceType(InterfaceType node) {
454 node.visitChildren(this); 467 node.visitChildren(this);
455 if (node.typeArguments.length != node.classNode.typeParameters.length) { 468 if (node.typeArguments.length != node.classNode.typeParameters.length) {
456 problem(currentParent, "Type $node provides ${node.typeArguments.length}" 469 problem(
470 currentParent,
471 "Type $node provides ${node.typeArguments.length}"
457 " type arguments but the class declares" 472 " type arguments but the class declares"
458 " ${node.classNode.typeParameters.length} parameters."); 473 " ${node.classNode.typeParameters.length} parameters.");
459 } 474 }
460 } 475 }
461 } 476 }
462 477
463 class CheckParentPointers extends Visitor { 478 class CheckParentPointers extends Visitor {
464 static void check(TreeNode node) { 479 static void check(TreeNode node) {
465 node.accept(new CheckParentPointers(node.parent)); 480 node.accept(new CheckParentPointers(node.parent));
466 } 481 }
467 482
468 TreeNode parent; 483 TreeNode parent;
469 484
470 CheckParentPointers([this.parent]); 485 CheckParentPointers([this.parent]);
471 486
472 defaultTreeNode(TreeNode node) { 487 defaultTreeNode(TreeNode node) {
473 if (node.parent != parent) { 488 if (node.parent != parent) {
474 throw new VerificationError(parent, node, 489 throw new VerificationError(
490 parent,
491 node,
475 "Parent pointer on '${node.runtimeType}' " 492 "Parent pointer on '${node.runtimeType}' "
476 "is '${node.parent.runtimeType}' " 493 "is '${node.parent.runtimeType}' "
477 "but should be '${parent.runtimeType}'."); 494 "but should be '${parent.runtimeType}'.");
478 } 495 }
479 var oldParent = parent; 496 var oldParent = parent;
480 parent = node; 497 parent = node;
481 node.visitChildren(this); 498 node.visitChildren(this);
482 parent = oldParent; 499 parent = oldParent;
483 } 500 }
484 } 501 }
485 502
486 void checkInitializers(Constructor constructor) { 503 void checkInitializers(Constructor constructor) {
487 // TODO(ahe): I'll add more here in other CLs. 504 // TODO(ahe): I'll add more here in other CLs.
488 } 505 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/type_propagation/type_propagation.dart ('k') | pkg/kernel/test/ast_membench.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698