1 11 package org.eclipse.jdt.internal.corext.refactoring.code.flow; 12 13 import java.util.ArrayList ; 14 import java.util.HashMap ; 15 import java.util.Iterator ; 16 import java.util.List ; 17 18 import org.eclipse.jdt.core.dom.ASTNode; 19 import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration; 20 import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration; 21 import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; 22 import org.eclipse.jdt.core.dom.ArrayAccess; 23 import org.eclipse.jdt.core.dom.ArrayCreation; 24 import org.eclipse.jdt.core.dom.ArrayInitializer; 25 import org.eclipse.jdt.core.dom.ArrayType; 26 import org.eclipse.jdt.core.dom.AssertStatement; 27 import org.eclipse.jdt.core.dom.Assignment; 28 import org.eclipse.jdt.core.dom.Block; 29 import org.eclipse.jdt.core.dom.BooleanLiteral; 30 import org.eclipse.jdt.core.dom.BreakStatement; 31 import org.eclipse.jdt.core.dom.CastExpression; 32 import org.eclipse.jdt.core.dom.CatchClause; 33 import org.eclipse.jdt.core.dom.CharacterLiteral; 34 import org.eclipse.jdt.core.dom.ClassInstanceCreation; 35 import org.eclipse.jdt.core.dom.CompilationUnit; 36 import org.eclipse.jdt.core.dom.ConditionalExpression; 37 import org.eclipse.jdt.core.dom.ConstructorInvocation; 38 import org.eclipse.jdt.core.dom.ContinueStatement; 39 import org.eclipse.jdt.core.dom.DoStatement; 40 import org.eclipse.jdt.core.dom.EmptyStatement; 41 import org.eclipse.jdt.core.dom.EnhancedForStatement; 42 import org.eclipse.jdt.core.dom.EnumConstantDeclaration; 43 import org.eclipse.jdt.core.dom.EnumDeclaration; 44 import org.eclipse.jdt.core.dom.Expression; 45 import org.eclipse.jdt.core.dom.ExpressionStatement; 46 import org.eclipse.jdt.core.dom.FieldAccess; 47 import org.eclipse.jdt.core.dom.FieldDeclaration; 48 import org.eclipse.jdt.core.dom.ForStatement; 49 import org.eclipse.jdt.core.dom.IBinding; 50 import org.eclipse.jdt.core.dom.IMethodBinding; 51 import org.eclipse.jdt.core.dom.ITypeBinding; 52 import org.eclipse.jdt.core.dom.IVariableBinding; 53 import org.eclipse.jdt.core.dom.IfStatement; 54 import org.eclipse.jdt.core.dom.ImportDeclaration; 55 import org.eclipse.jdt.core.dom.InfixExpression; 56 import org.eclipse.jdt.core.dom.Initializer; 57 import org.eclipse.jdt.core.dom.InstanceofExpression; 58 import org.eclipse.jdt.core.dom.Javadoc; 59 import org.eclipse.jdt.core.dom.LabeledStatement; 60 import org.eclipse.jdt.core.dom.MarkerAnnotation; 61 import org.eclipse.jdt.core.dom.MemberValuePair; 62 import org.eclipse.jdt.core.dom.MethodDeclaration; 63 import org.eclipse.jdt.core.dom.MethodInvocation; 64 import org.eclipse.jdt.core.dom.Name; 65 import org.eclipse.jdt.core.dom.NormalAnnotation; 66 import org.eclipse.jdt.core.dom.NullLiteral; 67 import org.eclipse.jdt.core.dom.NumberLiteral; 68 import org.eclipse.jdt.core.dom.PackageDeclaration; 69 import org.eclipse.jdt.core.dom.ParameterizedType; 70 import org.eclipse.jdt.core.dom.ParenthesizedExpression; 71 import org.eclipse.jdt.core.dom.PostfixExpression; 72 import org.eclipse.jdt.core.dom.PrefixExpression; 73 import org.eclipse.jdt.core.dom.PrimitiveType; 74 import org.eclipse.jdt.core.dom.QualifiedName; 75 import org.eclipse.jdt.core.dom.QualifiedType; 76 import org.eclipse.jdt.core.dom.ReturnStatement; 77 import org.eclipse.jdt.core.dom.SimpleName; 78 import org.eclipse.jdt.core.dom.SimpleType; 79 import org.eclipse.jdt.core.dom.SingleMemberAnnotation; 80 import org.eclipse.jdt.core.dom.SingleVariableDeclaration; 81 import org.eclipse.jdt.core.dom.Statement; 82 import org.eclipse.jdt.core.dom.StringLiteral; 83 import org.eclipse.jdt.core.dom.SuperConstructorInvocation; 84 import org.eclipse.jdt.core.dom.SuperFieldAccess; 85 import org.eclipse.jdt.core.dom.SuperMethodInvocation; 86 import org.eclipse.jdt.core.dom.SwitchCase; 87 import org.eclipse.jdt.core.dom.SwitchStatement; 88 import org.eclipse.jdt.core.dom.SynchronizedStatement; 89 import org.eclipse.jdt.core.dom.ThisExpression; 90 import org.eclipse.jdt.core.dom.ThrowStatement; 91 import org.eclipse.jdt.core.dom.TryStatement; 92 import org.eclipse.jdt.core.dom.TypeDeclaration; 93 import org.eclipse.jdt.core.dom.TypeDeclarationStatement; 94 import org.eclipse.jdt.core.dom.TypeLiteral; 95 import org.eclipse.jdt.core.dom.TypeParameter; 96 import org.eclipse.jdt.core.dom.VariableDeclarationExpression; 97 import org.eclipse.jdt.core.dom.VariableDeclarationFragment; 98 import org.eclipse.jdt.core.dom.VariableDeclarationStatement; 99 import org.eclipse.jdt.core.dom.WhileStatement; 100 import org.eclipse.jdt.core.dom.WildcardType; 101 102 import org.eclipse.jface.text.IRegion; 103 import org.eclipse.jface.text.Region; 104 105 import org.eclipse.jdt.internal.corext.dom.GenericVisitor; 106 107 116 abstract class FlowAnalyzer extends GenericVisitor { 117 118 static protected class SwitchData { 119 private boolean fHasDefaultCase; 120 private List fRanges= new ArrayList (4); 121 private List fInfos= new ArrayList (4); 122 public void setHasDefaultCase() { 123 fHasDefaultCase= true; 124 } 125 public boolean hasDefaultCase() { 126 return fHasDefaultCase; 127 } 128 public void add(IRegion range, FlowInfo info) { 129 fRanges.add(range); 130 fInfos.add(info); 131 } 132 public IRegion[] getRanges() { 133 return (IRegion[]) fRanges.toArray(new IRegion[fRanges.size()]); 134 } 135 public FlowInfo[] getInfos() { 136 return (FlowInfo[]) fInfos.toArray(new FlowInfo[fInfos.size()]); 137 } 138 public FlowInfo getInfo(int index) { 139 return (FlowInfo)fInfos.get(index); 140 } 141 } 142 143 private HashMap fData = new HashMap (100); 144 FlowContext fFlowContext= null; 145 146 public FlowAnalyzer(FlowContext context) { 147 fFlowContext= context; 148 } 149 150 protected abstract boolean createReturnFlowInfo(ReturnStatement node); 151 152 protected abstract boolean traverseNode(ASTNode node); 153 154 protected boolean skipNode(ASTNode node) { 155 return !traverseNode(node); 156 } 157 158 protected final boolean visitNode(ASTNode node) { 159 return traverseNode(node); 160 } 161 162 164 protected ReturnFlowInfo createReturn(ReturnStatement statement) { 165 return new ReturnFlowInfo(statement); 166 } 167 168 protected ThrowFlowInfo createThrow() { 169 return new ThrowFlowInfo(); 170 } 171 172 protected BranchFlowInfo createBranch(SimpleName label) { 173 return new BranchFlowInfo(label, fFlowContext); 174 } 175 176 protected GenericSequentialFlowInfo createSequential() { 177 return new GenericSequentialFlowInfo(); 178 } 179 180 protected ConditionalFlowInfo createConditional() { 181 return new ConditionalFlowInfo(); 182 } 183 184 protected EnhancedForFlowInfo createEnhancedFor() { 185 return new EnhancedForFlowInfo(); 186 } 187 188 protected ForFlowInfo createFor() { 189 return new ForFlowInfo(); 190 } 191 192 protected TryFlowInfo createTry() { 193 return new TryFlowInfo(); 194 } 195 196 protected WhileFlowInfo createWhile() { 197 return new WhileFlowInfo(); 198 } 199 200 protected IfFlowInfo createIf() { 201 return new IfFlowInfo(); 202 } 203 204 protected DoWhileFlowInfo createDoWhile() { 205 return new DoWhileFlowInfo(); 206 } 207 208 protected SwitchFlowInfo createSwitch() { 209 return new SwitchFlowInfo(); 210 } 211 212 protected BlockFlowInfo createBlock() { 213 return new BlockFlowInfo(); 214 } 215 216 protected MessageSendFlowInfo createMessageSendFlowInfo() { 217 return new MessageSendFlowInfo(); 218 } 219 220 protected FlowContext getFlowContext() { 221 return fFlowContext; 222 } 223 224 226 protected FlowInfo getFlowInfo(ASTNode node) { 227 return (FlowInfo)fData.remove(node); 228 } 229 230 protected void setFlowInfo(ASTNode node, FlowInfo info) { 231 fData.put(node, info); 232 } 233 234 protected FlowInfo assignFlowInfo(ASTNode target, ASTNode source) { 235 FlowInfo result= getFlowInfo(source); 236 setFlowInfo(target, result); 237 return result; 238 } 239 240 protected FlowInfo accessFlowInfo(ASTNode node) { 241 return (FlowInfo)fData.get(node); 242 } 243 244 246 protected GenericSequentialFlowInfo processSequential(ASTNode parent, List nodes) { 247 GenericSequentialFlowInfo result= createSequential(parent); 248 process(result, nodes); 249 return result; 250 } 251 252 protected GenericSequentialFlowInfo processSequential(ASTNode parent, ASTNode node1) { 253 GenericSequentialFlowInfo result= createSequential(parent); 254 if (node1 != null) 255 result.merge(getFlowInfo(node1), fFlowContext); 256 return result; 257 } 258 259 protected GenericSequentialFlowInfo processSequential(ASTNode parent, ASTNode node1, ASTNode node2) { 260 GenericSequentialFlowInfo result= createSequential(parent); 261 if (node1 != null) 262 result.merge(getFlowInfo(node1), fFlowContext); 263 if (node2 != null) 264 result.merge(getFlowInfo(node2), fFlowContext); 265 return result; 266 } 267 268 protected GenericSequentialFlowInfo createSequential(ASTNode parent) { 269 GenericSequentialFlowInfo result= createSequential(); 270 setFlowInfo(parent, result); 271 return result; 272 } 273 274 protected GenericSequentialFlowInfo createSequential(List nodes) { 275 GenericSequentialFlowInfo result= createSequential(); 276 process(result, nodes); 277 return result; 278 } 279 280 282 protected void process(GenericSequentialFlowInfo info, List nodes) { 283 if (nodes == null) 284 return; 285 for (Iterator iter= nodes.iterator(); iter.hasNext();) { 286 info.merge(getFlowInfo((ASTNode)iter.next()), fFlowContext); 287 } 288 } 289 290 protected void process(GenericSequentialFlowInfo info, ASTNode node) { 291 if (node != null) 292 info.merge(getFlowInfo(node), fFlowContext); 293 } 294 295 protected void process(GenericSequentialFlowInfo info, ASTNode node1, ASTNode node2) { 296 if (node1 != null) 297 info.merge(getFlowInfo(node1), fFlowContext); 298 if (node2 != null) 299 info.merge(getFlowInfo(node2), fFlowContext); 300 } 301 302 304 public boolean visit(EmptyStatement node) { 305 return false; 307 } 308 309 public boolean visit(TryStatement node) { 310 if (traverseNode(node)) { 311 fFlowContext.pushExcptions(node); 312 node.getBody().accept(this); 313 fFlowContext.popExceptions(); 314 List catchClauses= node.catchClauses(); 315 for (Iterator iter= catchClauses.iterator(); iter.hasNext();) { 316 ((CatchClause)iter.next()).accept(this); 317 } 318 Block finallyBlock= node.getFinally(); 319 if (finallyBlock != null) { 320 finallyBlock.accept(this); 321 } 322 } 323 return false; 324 } 325 326 328 protected SwitchData createSwitchData(SwitchStatement node) { 329 SwitchData result= new SwitchData(); 330 List statements= node.statements(); 331 if (statements.isEmpty()) 332 return result; 333 334 int start= -1, end= -1; 335 GenericSequentialFlowInfo info= null; 336 337 for (Iterator iter= statements.iterator(); iter.hasNext(); ) { 338 Statement statement= (Statement)iter.next(); 339 if (statement instanceof SwitchCase) { 340 SwitchCase switchCase= (SwitchCase)statement; 341 if (switchCase.isDefault()) { 342 result.setHasDefaultCase(); 343 } 344 if (info == null) { 345 info= createSequential(); 346 start= statement.getStartPosition(); 347 } else { 348 if (info.isReturn() || info.isPartialReturn() || info.branches()) { 349 result.add(new Region(start, end - start + 1), info); 350 info= createSequential(); 351 start= statement.getStartPosition(); 352 } 353 } 354 } else { 355 info.merge(getFlowInfo(statement), fFlowContext); 356 } 357 end= statement.getStartPosition() + statement.getLength() - 1; 358 } 359 result.add(new Region(start, end - start + 1), info); 360 return result; 361 } 362 363 protected void endVisit(SwitchStatement node, SwitchData data) { 364 SwitchFlowInfo switchFlowInfo= createSwitch(); 365 setFlowInfo(node, switchFlowInfo); 366 switchFlowInfo.mergeTest(getFlowInfo(node.getExpression()), fFlowContext); 367 FlowInfo[] cases= data.getInfos(); 368 for (int i= 0; i < cases.length; i++) 369 switchFlowInfo.mergeCase(cases[i], fFlowContext); 370 switchFlowInfo.mergeDefault(data.hasDefaultCase(), fFlowContext); 371 switchFlowInfo.removeLabel(null); 372 } 373 374 376 public void endVisit(AnnotationTypeDeclaration node) { 377 if (skipNode(node)) 378 return; 379 GenericSequentialFlowInfo info= processSequential(node, node.bodyDeclarations()); 380 info.setNoReturn(); 381 } 382 383 public void endVisit(AnnotationTypeMemberDeclaration node) { 384 if (skipNode(node)) 385 return; 386 GenericSequentialFlowInfo info= processSequential(node, node.getType(), node.getDefault()); 387 info.setNoReturn(); 388 } 389 390 public void endVisit(AnonymousClassDeclaration node) { 391 if (skipNode(node)) 392 return; 393 FlowInfo info= processSequential(node, node.bodyDeclarations()); 394 info.setNoReturn(); 395 } 396 397 public void endVisit(ArrayAccess node) { 398 if (skipNode(node)) 399 return; 400 processSequential(node, node.getArray(), node.getIndex()); 401 } 402 403 public void endVisit(ArrayCreation node) { 404 if (skipNode(node)) 405 return; 406 GenericSequentialFlowInfo info= processSequential(node, node.getType()); 407 process(info, node.dimensions()); 408 process(info, node.getInitializer()); 409 } 410 411 public void endVisit(ArrayInitializer node) { 412 if (skipNode(node)) 413 return; 414 processSequential(node, node.expressions()); 415 } 416 417 public void endVisit(ArrayType node) { 418 if (skipNode(node)) 419 return; 420 processSequential(node, node.getElementType()); 421 } 422 423 public void endVisit(AssertStatement node) { 424 if (skipNode(node)) 425 return; 426 IfFlowInfo info= new IfFlowInfo(); 427 setFlowInfo(node, info); 428 info.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 429 info.merge(getFlowInfo(node.getMessage()), null, fFlowContext); 430 } 431 432 public void endVisit(Assignment node) { 433 if (skipNode(node)) 434 return; 435 FlowInfo lhs= getFlowInfo(node.getLeftHandSide()); 436 FlowInfo rhs= getFlowInfo(node.getRightHandSide()); 437 if (lhs instanceof LocalFlowInfo) { 438 LocalFlowInfo llhs= (LocalFlowInfo)lhs; 439 llhs.setWriteAccess(fFlowContext); 440 if (node.getOperator() != Assignment.Operator.ASSIGN) { 441 GenericSequentialFlowInfo tmp= createSequential(); 442 tmp.merge(new LocalFlowInfo(llhs, FlowInfo.READ, fFlowContext), fFlowContext); 443 tmp.merge(rhs, fFlowContext); 444 rhs= tmp; 445 } 446 } 447 GenericSequentialFlowInfo info= createSequential(node); 448 info.merge(rhs, fFlowContext); 450 info.merge(lhs, fFlowContext); 451 } 452 453 public void endVisit(Block node) { 454 if (skipNode(node)) 455 return; 456 BlockFlowInfo info= createBlock(); 457 setFlowInfo(node, info); 458 process(info, node.statements()); 459 } 460 461 public void endVisit(BooleanLiteral node) { 462 } 464 465 public void endVisit(BreakStatement node) { 466 if (skipNode(node)) 467 return; 468 setFlowInfo(node, createBranch(node.getLabel())); 469 } 470 471 public void endVisit(CastExpression node) { 472 if (skipNode(node)) 473 return; 474 processSequential(node, node.getType(), node.getExpression()); 475 } 476 477 public void endVisit(CatchClause node) { 478 if (skipNode(node)) 479 return; 480 processSequential(node, node.getException(), node.getBody()); 481 } 482 483 public void endVisit(CharacterLiteral node) { 484 } 486 487 public void endVisit(ClassInstanceCreation node) { 488 if (skipNode(node)) 489 return; 490 GenericSequentialFlowInfo info= processSequential(node, node.getExpression()); 491 process(info, node.getType()); 492 process(info, node.arguments()); 493 process(info, node.getAnonymousClassDeclaration()); 494 } 495 496 public void endVisit(CompilationUnit node) { 497 if (skipNode(node)) 498 return; 499 GenericSequentialFlowInfo info= processSequential(node, node.imports()); 500 process(info, node.types()); 501 } 502 503 public void endVisit(ConditionalExpression node) { 504 if (skipNode(node)) 505 return; 506 ConditionalFlowInfo info= createConditional(); 507 setFlowInfo(node, info); 508 info.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 509 info.merge( 510 getFlowInfo(node.getThenExpression()), 511 getFlowInfo(node.getElseExpression()), 512 fFlowContext); 513 } 514 515 public void endVisit(ConstructorInvocation node) { 516 if (skipNode(node)) 517 return; 518 processSequential(node, node.arguments()); 519 } 520 521 public void endVisit(ContinueStatement node) { 522 if (skipNode(node)) 523 return; 524 setFlowInfo(node, createBranch(node.getLabel())); 525 } 526 527 public void endVisit(DoStatement node) { 528 if (skipNode(node)) 529 return; 530 DoWhileFlowInfo info= createDoWhile(); 531 setFlowInfo(node, info); 532 info.mergeAction(getFlowInfo(node.getBody()), fFlowContext); 533 info.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 534 info.removeLabel(null); 535 } 536 537 public void endVisit(EmptyStatement node) { 538 } 540 541 public void endVisit(EnhancedForStatement node) { 542 if (skipNode(node)) 543 return; 544 EnhancedForFlowInfo forInfo= createEnhancedFor(); 545 setFlowInfo(node, forInfo); 546 forInfo.mergeParameter(getFlowInfo(node.getParameter()), fFlowContext); 547 forInfo.mergeExpression(getFlowInfo(node.getExpression()), fFlowContext); 548 forInfo.mergeAction(getFlowInfo(node.getBody()), fFlowContext); 549 forInfo.removeLabel(null); 550 } 551 552 public void endVisit(EnumConstantDeclaration node) { 553 if (skipNode(node)) 554 return; 555 GenericSequentialFlowInfo info= processSequential(node, node.arguments()); 556 process(info, node.getAnonymousClassDeclaration()); 557 } 558 559 public void endVisit(EnumDeclaration node) { 560 if (skipNode(node)) 561 return; 562 GenericSequentialFlowInfo info= processSequential(node, node.superInterfaceTypes()); 563 process(info, node.enumConstants()); 564 process(info, node.bodyDeclarations()); 565 info.setNoReturn(); 566 } 567 568 public void endVisit(ExpressionStatement node) { 569 if (skipNode(node)) 570 return; 571 assignFlowInfo(node, node.getExpression()); 572 } 573 574 public void endVisit(FieldAccess node) { 575 if (skipNode(node)) 576 return; 577 processSequential(node, node.getExpression(), node.getName()); 578 } 579 580 public void endVisit(FieldDeclaration node) { 581 if (skipNode(node)) 582 return; 583 GenericSequentialFlowInfo info= processSequential(node, node.getType()); 584 process(info, node.fragments()); 585 } 586 587 public void endVisit(ForStatement node) { 588 if (skipNode(node)) 589 return; 590 ForFlowInfo forInfo= createFor(); 591 setFlowInfo(node, forInfo); 592 forInfo.mergeInitializer(createSequential(node.initializers()), fFlowContext); 593 forInfo.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 594 forInfo.mergeAction(getFlowInfo(node.getBody()), fFlowContext); 595 forInfo.mergeIncrement(createSequential(node.updaters()), fFlowContext); 597 forInfo.removeLabel(null); 598 } 599 600 public void endVisit(IfStatement node) { 601 if (skipNode(node)) 602 return; 603 IfFlowInfo info= createIf(); 604 setFlowInfo(node, info); 605 info.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 606 info.merge(getFlowInfo(node.getThenStatement()), getFlowInfo(node.getElseStatement()), fFlowContext); 607 } 608 609 public void endVisit(ImportDeclaration node) { 610 if (skipNode(node)) 611 return; 612 assignFlowInfo(node, node.getName()); 613 } 614 615 public void endVisit(InfixExpression node) { 616 if (skipNode(node)) 617 return; 618 GenericSequentialFlowInfo info= processSequential(node, node.getLeftOperand(), node.getRightOperand()); 619 process(info, node.extendedOperands()); 620 } 621 622 public void endVisit(InstanceofExpression node) { 623 if (skipNode(node)) 624 return; 625 processSequential(node, node.getLeftOperand(), node.getRightOperand()); 626 } 627 628 public void endVisit(Initializer node) { 629 if (skipNode(node)) 630 return; 631 assignFlowInfo(node, node.getBody()); 632 } 633 634 public void endVisit(Javadoc node) { 635 } 637 638 public void endVisit(LabeledStatement node) { 639 if (skipNode(node)) 640 return; 641 FlowInfo info= assignFlowInfo(node, node.getBody()); 642 if (info != null) 643 info.removeLabel(node.getLabel()); 644 } 645 646 public void endVisit(MarkerAnnotation node) { 647 } 649 650 public void endVisit(MemberValuePair node) { 651 if (skipNode(node)) 652 return; 653 654 FlowInfo name= getFlowInfo(node.getName()); 655 FlowInfo value= getFlowInfo(node.getValue()); 656 if (name instanceof LocalFlowInfo) { 657 LocalFlowInfo llhs= (LocalFlowInfo)name; 658 llhs.setWriteAccess(fFlowContext); 659 } 660 GenericSequentialFlowInfo info= createSequential(node); 661 info.merge(value, fFlowContext); 663 info.merge(name, fFlowContext); 664 665 } 666 667 public void endVisit(MethodDeclaration node) { 668 if (skipNode(node)) 669 return; 670 GenericSequentialFlowInfo info= processSequential(node, node.getReturnType2()); 671 process(info, node.parameters()); 672 process(info, node.thrownExceptions()); 673 process(info, node.getBody()); 674 } 675 676 public void endVisit(MethodInvocation node) { 677 endVisitMethodInvocation(node, node.getExpression(), node.arguments(), getMethodBinding(node.getName())); 678 } 679 680 public void endVisit(NormalAnnotation node) { 681 if (skipNode(node)) 682 return; 683 GenericSequentialFlowInfo info= processSequential(node, node.getTypeName()); 684 process(info, node.values()); 685 } 686 687 public void endVisit(NullLiteral node) { 688 } 690 691 public void endVisit(NumberLiteral node) { 692 } 694 695 public void endVisit(PackageDeclaration node) { 696 if (skipNode(node)) 697 return; 698 assignFlowInfo(node, node.getName()); 699 } 700 701 public void endVisit(ParameterizedType node) { 702 if (skipNode(node)) 703 return; 704 GenericSequentialFlowInfo info= processSequential(node, node.getType()); 705 process(info, node.typeArguments()); 706 } 707 708 public void endVisit(ParenthesizedExpression node) { 709 if (skipNode(node)) 710 return; 711 assignFlowInfo(node, node.getExpression()); 712 } 713 714 public void endVisit(PostfixExpression node) { 715 endVisitIncDecOperation(node, node.getOperand()); 716 } 717 718 public void endVisit(PrefixExpression node) { 719 PrefixExpression.Operator op= node.getOperator(); 720 if (PrefixExpression.Operator.INCREMENT.equals(op) || PrefixExpression.Operator.DECREMENT.equals(op)) { 721 endVisitIncDecOperation(node, node.getOperand()); 722 } else { 723 assignFlowInfo(node, node.getOperand()); 724 } 725 } 726 727 public void endVisit(PrimitiveType node) { 728 } 730 731 public void endVisit(QualifiedName node) { 732 if (skipNode(node)) 733 return; 734 processSequential(node, node.getQualifier(), node.getName()); 735 } 736 737 public void endVisit(QualifiedType node) { 738 if (skipNode(node)) 739 return; 740 processSequential(node, node.getQualifier(), node.getName()); 741 } 742 743 public void endVisit(ReturnStatement node) { 744 if (skipNode(node)) 745 return; 746 747 if (createReturnFlowInfo(node)) { 748 ReturnFlowInfo info= createReturn(node); 749 setFlowInfo(node, info); 750 info.merge(getFlowInfo(node.getExpression()), fFlowContext); 751 } else { 752 assignFlowInfo(node, node.getExpression()); 753 } 754 } 755 756 public void endVisit(SimpleName node) { 757 if (skipNode(node) || node.isDeclaration()) 758 return; 759 IBinding binding= node.resolveBinding(); 760 if (binding instanceof IVariableBinding) { 761 IVariableBinding variable= (IVariableBinding)binding; 762 if (!variable.isField()) { 763 setFlowInfo(node, new LocalFlowInfo( 764 variable, 765 FlowInfo.READ, 766 fFlowContext)); 767 } 768 } else if (binding instanceof ITypeBinding) { 769 ITypeBinding type= (ITypeBinding)binding; 770 if (type.isTypeVariable()) { 771 setFlowInfo(node, new TypeVariableFlowInfo(type, fFlowContext)); 772 } 773 } 774 } 775 776 public void endVisit(SimpleType node) { 777 if (skipNode(node)) 778 return; 779 assignFlowInfo(node, node.getName()); 780 } 781 782 public void endVisit(SingleMemberAnnotation node) { 783 if (skipNode(node)) 784 return; 785 assignFlowInfo(node, node.getValue()); 786 } 787 788 public void endVisit(SingleVariableDeclaration node) { 789 if (skipNode(node)) 790 return; 791 792 IVariableBinding binding= node.resolveBinding(); 793 LocalFlowInfo nameInfo= null; 794 Expression initializer= node.getInitializer(); 795 if (binding != null && !binding.isField() && initializer != null) { 796 nameInfo= new LocalFlowInfo(binding, FlowInfo.WRITE, fFlowContext); 797 } 798 GenericSequentialFlowInfo info= processSequential(node, node.getType(), initializer); 799 info.merge(nameInfo, fFlowContext); 800 } 801 802 public void endVisit(StringLiteral node) { 803 } 805 806 public void endVisit(SuperConstructorInvocation node) { 807 endVisitMethodInvocation(node, node.getExpression(), node.arguments(), node.resolveConstructorBinding()); 808 } 809 810 public void endVisit(SuperFieldAccess node) { 811 if (skipNode(node)) 812 return; 813 processSequential(node, node.getQualifier(), node.getName()); 814 } 815 816 public void endVisit(SuperMethodInvocation node) { 817 endVisitMethodInvocation(node, node.getQualifier(), node.arguments(), getMethodBinding(node.getName())); 818 } 819 820 public void endVisit(SwitchCase node) { 821 endVisitNode(node); 822 } 823 824 public void endVisit(SwitchStatement node) { 825 if (skipNode(node)) 826 return; 827 endVisit(node, createSwitchData(node)); 828 } 829 830 public void endVisit(SynchronizedStatement node) { 831 if (skipNode(node)) 832 return; 833 GenericSequentialFlowInfo info= processSequential(node, node.getExpression()); 834 process(info, node.getBody()); 835 } 836 837 public void endVisit(ThisExpression node) { 838 if (skipNode(node)) 839 return; 840 assignFlowInfo(node, node.getQualifier()); 841 } 842 843 public void endVisit(ThrowStatement node) { 844 if (skipNode(node)) 845 return; 846 ThrowFlowInfo info= createThrow(); 847 setFlowInfo(node, info); 848 Expression expression= node.getExpression(); 849 info.merge(getFlowInfo(expression), fFlowContext); 850 info.mergeException(expression.resolveTypeBinding(), fFlowContext); 851 } 852 853 public void endVisit(TryStatement node) { 854 if (skipNode(node)) 855 return; 856 TryFlowInfo info= createTry(); 857 setFlowInfo(node, info); 858 info.mergeTry(getFlowInfo(node.getBody()), fFlowContext); 859 info.removeExceptions(node); 860 for (Iterator iter= node.catchClauses().iterator(); iter.hasNext();) { 861 CatchClause element= (CatchClause)iter.next(); 862 info.mergeCatch(getFlowInfo(element), fFlowContext); 863 } 864 info.mergeFinally(getFlowInfo(node.getFinally()), fFlowContext); 865 } 866 867 869 public void endVisit(TypeDeclaration node) { 870 if (skipNode(node)) 871 return; 872 GenericSequentialFlowInfo info= processSequential(node, node.getSuperclassType()); 873 process(info, node.superInterfaceTypes()); 874 process(info, node.bodyDeclarations()); 875 info.setNoReturn(); 876 } 877 878 public void endVisit(TypeDeclarationStatement node) { 879 if (skipNode(node)) 880 return; 881 assignFlowInfo(node, node.getDeclaration()); 882 } 883 884 public void endVisit(TypeLiteral node) { 885 if (skipNode(node)) 886 return; 887 assignFlowInfo(node, node.getType()); 888 } 889 890 public void endVisit(TypeParameter node) { 891 if (skipNode(node)) 892 return; 893 GenericSequentialFlowInfo info= processSequential(node, node.getName()); 894 process(info, node.typeBounds()); 895 } 896 897 public void endVisit(VariableDeclarationExpression node) { 898 if (skipNode(node)) 899 return; 900 GenericSequentialFlowInfo info= processSequential(node, node.getType()); 901 process(info, node.fragments()); 902 } 903 904 public void endVisit(VariableDeclarationStatement node) { 905 if (skipNode(node)) 906 return; 907 GenericSequentialFlowInfo info= processSequential(node, node.getType()); 908 process(info, node.fragments()); 909 } 910 911 public void endVisit(VariableDeclarationFragment node) { 912 if (skipNode(node)) 913 return; 914 915 IVariableBinding binding= node.resolveBinding(); 916 LocalFlowInfo nameInfo= null; 917 Expression initializer= node.getInitializer(); 918 if (binding != null && !binding.isField() && initializer != null) { 919 nameInfo= new LocalFlowInfo(binding, FlowInfo.WRITE, fFlowContext); 920 } 921 GenericSequentialFlowInfo info= processSequential(node, initializer); 922 info.merge(nameInfo, fFlowContext); 923 } 924 925 public void endVisit(WhileStatement node) { 926 if (skipNode(node)) 927 return; 928 WhileFlowInfo info= createWhile(); 929 setFlowInfo(node, info); 930 info.mergeCondition(getFlowInfo(node.getExpression()), fFlowContext); 931 info.mergeAction(getFlowInfo(node.getBody()), fFlowContext); 932 info.removeLabel(null); 933 } 934 935 public void endVisit(WildcardType node) { 936 if (skipNode(node)) 937 return; 938 assignFlowInfo(node, node.getBound()); 939 } 940 941 private void endVisitMethodInvocation(ASTNode node, ASTNode receiver, List arguments, IMethodBinding binding) { 942 if (skipNode(node)) 943 return; 944 MessageSendFlowInfo info= createMessageSendFlowInfo(); 945 setFlowInfo(node, info); 946 for (Iterator iter= arguments.iterator(); iter.hasNext();) { 947 Expression arg= (Expression) iter.next(); 948 info.mergeArgument(getFlowInfo(arg), fFlowContext); 949 } 950 info.mergeReceiver(getFlowInfo(receiver), fFlowContext); 951 info.mergeExceptions(binding, fFlowContext); 952 } 953 954 private void endVisitIncDecOperation(Expression node, Expression operand) { 955 if (skipNode(node)) 956 return; 957 FlowInfo info= getFlowInfo(operand); 958 if (info instanceof LocalFlowInfo) { 959 GenericSequentialFlowInfo result= createSequential(node); 963 result.merge(info, fFlowContext); 964 result.merge( 965 new LocalFlowInfo((LocalFlowInfo)info, FlowInfo.WRITE, fFlowContext), 966 fFlowContext); 967 } else { 968 setFlowInfo(node, info); 969 } 970 } 971 972 private IMethodBinding getMethodBinding(Name name) { 973 if (name == null) 974 return null; 975 IBinding binding= name.resolveBinding(); 976 if (binding instanceof IMethodBinding) 977 return (IMethodBinding)binding; 978 return null; 979 } 980 } 981 | Popular Tags |