1 11 package org.eclipse.jdt.internal.core.jdom; 12 13 import java.util.Enumeration ; 14 15 import org.eclipse.jdt.core.ICompilationUnit; 16 import org.eclipse.jdt.core.IJavaElement; 17 import org.eclipse.jdt.core.IType; 18 import org.eclipse.jdt.core.compiler.CharOperation; 19 import org.eclipse.jdt.core.compiler.InvalidInputException; 20 import org.eclipse.jdt.core.jdom.*; 21 import org.eclipse.jdt.internal.compiler.parser.Scanner; 22 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; 23 import org.eclipse.jdt.internal.core.util.CharArrayBuffer; 24 import org.eclipse.jdt.internal.core.util.Messages; 25 34 class DOMType extends DOMMember implements IDOMType { 36 40 protected String fTypeKeyword; 41 42 46 protected int[] fTypeRange; 47 48 54 protected String fSuperclass; 55 56 61 protected int[] fSuperclassRange; 62 63 64 69 protected int[] fExtendsRange; 70 71 76 protected int[] fImplementsRange; 77 78 84 protected char[] fInterfaces; 85 86 91 protected int[] fInterfacesRange; 92 93 94 95 100 protected int[] fOpenBodyRange; 101 102 109 protected int[] fCloseBodyRange; 110 111 116 protected String [] fSuperInterfaces= CharOperation.NO_STRINGS; 117 118 122 protected String [] fTypeParameters = CharOperation.NO_STRINGS; 123 124 128 protected boolean fIsEnum= false; 129 130 134 protected boolean fIsAnnotation= false; 135 136 140 142 145 DOMType() { 146 } 148 205 DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, int[] superclassRange, int[] extendsRange, String [] implementsList, int[] implementsRange, int[] implementsKeywordRange, int[] openBodyRange, int[] closeBodyRange, boolean isClass) { 206 super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange); 207 208 fTypeRange= typeRange; 209 setMask(MASK_TYPE_IS_CLASS, isClass); 210 211 fExtendsRange= extendsRange; 212 fImplementsRange= implementsKeywordRange; 213 fSuperclassRange= superclassRange; 214 fInterfacesRange= implementsRange; 215 fCloseBodyRange= closeBodyRange; 216 setMask(MASK_TYPE_HAS_SUPERCLASS, superclassRange[0] > 0); 217 setMask(MASK_TYPE_HAS_INTERFACES, implementsList != null); 218 fSuperInterfaces= implementsList; 219 fOpenBodyRange= openBodyRange; 220 fCloseBodyRange= closeBodyRange; 221 setMask(MASK_DETAILED_SOURCE_INDEXES, true); 222 223 } 224 247 DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String [] implementsList, boolean isClass) { 248 this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags, 249 new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, 250 implementsList, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {sourceRange[1], sourceRange[1]}, isClass); 251 setMask(MASK_DETAILED_SOURCE_INDEXES, false); 252 } 253 256 public void addSuperInterface(String name) throws IllegalArgumentException { 257 if (name == null) { 258 throw new IllegalArgumentException (Messages.dom_addNullInterface); 259 } 260 if (fSuperInterfaces == null) { 261 fSuperInterfaces= new String [1]; 262 fSuperInterfaces[0]= name; 263 } else { 264 fSuperInterfaces= appendString(fSuperInterfaces, name); 265 } 266 setSuperInterfaces(fSuperInterfaces); 267 } 268 271 protected void appendMemberBodyContents(CharArrayBuffer buffer) { 272 buffer.append(fDocument, fOpenBodyRange[0], fOpenBodyRange[1] + 1 - fOpenBodyRange[0]); 273 appendContentsOfChildren(buffer); 274 buffer.append(fDocument, fCloseBodyRange[0], fCloseBodyRange[1] + 1 - fCloseBodyRange[0]); 275 buffer.append(fDocument, fCloseBodyRange[1] + 1, fSourceRange[1] - fCloseBodyRange[1]); 276 } 277 280 protected void appendMemberDeclarationContents(CharArrayBuffer buffer) { 281 282 if (fTypeKeyword != null) { 283 buffer.append(fTypeKeyword); 284 buffer.append(fDocument, fTypeRange[1], fNameRange[0] - fTypeRange[1] ); 285 } else { 286 buffer.append(fDocument, fTypeRange[0], fTypeRange[1] + 1 - fTypeRange[0]); 287 } 288 289 buffer.append(getName()); 290 291 if (isClass()) { 292 boolean hasInterfaces = false; 293 if (getMask(MASK_TYPE_HAS_SUPERCLASS)) { 294 if (fExtendsRange[0] < 0) { 295 buffer.append(" extends "); } else { 297 buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]); 298 } 299 if (fSuperclass != null) { 300 buffer.append(fSuperclass); 301 } else { 302 buffer.append(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]); 303 } 304 } 305 if (getMask(MASK_TYPE_HAS_INTERFACES)) { 306 hasInterfaces = true; 307 if (fImplementsRange[0] < 0) { 308 buffer.append(" implements "); } else { 310 buffer.append(fDocument, fImplementsRange[0], fImplementsRange[1] + 1 - fImplementsRange[0]); 311 } 312 if (fInterfaces != null) { 313 buffer.append(fInterfaces); 314 } else { 315 buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]); 316 } 317 } 318 if (hasInterfaces) { 319 if (fImplementsRange[0] < 0) { 320 buffer.append(' '); 321 } else { 322 buffer.append(fDocument, fInterfacesRange[1] + 1, fOpenBodyRange[0] - fInterfacesRange[1] - 1); 323 } 324 } else { 325 if (fSuperclassRange[0] < 0) { 326 buffer.append(' '); 327 } else if (fImplementsRange[0] > 0) { 328 buffer.append(fDocument, fSuperclassRange[1] + 1, fImplementsRange[0] - fSuperclassRange[1] - 1); 329 buffer.append(fDocument, fInterfacesRange[1] + 1, fOpenBodyRange[0] - fInterfacesRange[1] - 1); 330 } else { 331 buffer.append(fDocument, fSuperclassRange[1] + 1, fOpenBodyRange[0] - fSuperclassRange[1] - 1); 332 } 333 } 334 } else { 335 if (getMask(MASK_TYPE_HAS_INTERFACES)) { 336 if (fExtendsRange[0] < 0) { 337 buffer.append(" extends "); } else { 339 buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]); 340 } 341 if (fInterfaces != null) { 342 buffer.append(fInterfaces); 343 buffer.append(' '); 344 } else { 345 buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]); 346 } 347 } else { 348 if (fImplementsRange[0] < 0) { 349 buffer.append(' '); 350 } else { 351 buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] - fNameRange[1] - 1); 352 } 353 } 354 } 355 356 } 357 360 protected void appendSimpleContents(CharArrayBuffer buffer) { 361 buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]); 363 buffer.append(fName); 365 366 367 buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[1] - fNameRange[1]); 369 appendContentsOfChildren(buffer); 371 buffer.append(fDocument, fCloseBodyRange[0], fSourceRange[1] - fCloseBodyRange[0] + 1); 373 374 375 } 376 379 public boolean canHaveChildren() { 380 return true; 381 } 382 387 int getCloseBodyPosition() { 388 return fCloseBodyRange[0]; 389 } 390 393 protected DOMNode getDetailedNode() { 394 return (DOMNode)getFactory().createType(getContents()); 395 } 396 399 public int getInsertionPosition() { 400 return fInsertionPosition; 403 } 404 407 public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException { 408 switch (parent.getElementType()) { 409 case IJavaElement.COMPILATION_UNIT: 410 return ((ICompilationUnit)parent).getType(getName()); 411 case IJavaElement.TYPE: 412 return ((IType)parent).getType(getName()); 413 default: 415 throw new IllegalArgumentException (Messages.element_illegalParent); 416 } 417 } 418 421 protected int getMemberDeclarationStartPosition() { 422 return fTypeRange[0]; 423 } 424 427 public int getNodeType() { 428 return IDOMNode.TYPE; 429 } 430 433 int getOpenBodyEnd() { 434 return fOpenBodyRange[1]; 435 } 436 439 public String getSuperclass() { 440 becomeDetailed(); 441 if (getMask(MASK_TYPE_HAS_SUPERCLASS)) { 442 if (fSuperclass != null) { 443 return fSuperclass; 444 } else { 445 return new String (fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]); 446 } 447 } else { 448 return null; 449 } 450 } 451 454 public String [] getSuperInterfaces() { 455 return fSuperInterfaces; 456 } 457 460 public boolean isAllowableChild(IDOMNode node) { 461 if (node != null) { 462 int type= node.getNodeType(); 463 return type == IDOMNode.TYPE || type == IDOMNode.FIELD|| type == IDOMNode.METHOD || 464 type == IDOMNode.INITIALIZER; 465 } else { 466 return false; 467 } 468 469 } 470 473 public boolean isClass() { 474 return getMask(MASK_TYPE_IS_CLASS); 475 } 476 479 protected DOMNode newDOMNode() { 480 return new DOMType(); 481 } 482 487 void normalize(ILineStartFinder finder) { 488 int openBodyEnd, openBodyStart, closeBodyStart, closeBodyEnd; 490 DOMNode first = (DOMNode) getFirstChild(); 491 DOMNode lastNode = null; 492 Scanner scanner = new Scanner(); 494 scanner.setSource(fDocument); 495 scanner.resetTo(fNameRange[1] + 1, fDocument.length); 496 497 try { 498 int currentToken = scanner.getNextToken(); 499 while(currentToken != TerminalTokens.TokenNameLBRACE && 500 currentToken != TerminalTokens.TokenNameEOF) { 501 currentToken = scanner.getNextToken(); 502 } 503 if(currentToken == TerminalTokens.TokenNameLBRACE) { 504 openBodyEnd = scanner.currentPosition - 1; 505 openBodyStart = scanner.startPosition; 506 } else { 507 openBodyEnd = fDocument.length; 508 openBodyStart = fDocument.length; 509 } 510 } catch(InvalidInputException e) { 511 openBodyEnd = fDocument.length; 512 openBodyStart = fDocument.length; 513 } 514 if (first != null) { 515 int lineStart = finder.getLineStart(first.getStartPosition()); 516 if (lineStart > openBodyEnd) { 517 openBodyEnd = lineStart - 1; 518 } else { 519 openBodyEnd = first.getStartPosition() - 1; 520 } 521 lastNode = (DOMNode) first.getNextNode(); 522 if (lastNode == null) { 523 lastNode = first; 524 } else { 525 while (lastNode.getNextNode() != null) { 526 lastNode = (DOMNode) lastNode.getNextNode(); 527 } 528 } 529 scanner.setSource(fDocument); 530 scanner.resetTo(lastNode.getEndPosition() + 1, fDocument.length); 531 try { 532 int currentToken = scanner.getNextToken(); 533 while(currentToken != TerminalTokens.TokenNameRBRACE && 534 currentToken != TerminalTokens.TokenNameEOF) { 535 currentToken = scanner.getNextToken(); 536 } 537 if(currentToken == TerminalTokens.TokenNameRBRACE) { 538 closeBodyStart = scanner.startPosition; 539 closeBodyEnd = scanner.currentPosition - 1; 540 } else { 541 closeBodyStart = fDocument.length; 542 closeBodyEnd = fDocument.length; 543 } 544 } catch(InvalidInputException e) { 545 closeBodyStart = fDocument.length; 546 closeBodyEnd = fDocument.length; 547 } 548 } else { 549 scanner.resetTo(openBodyEnd, fDocument.length); 550 try { 551 int currentToken = scanner.getNextToken(); 552 while(currentToken != TerminalTokens.TokenNameRBRACE && 553 currentToken != TerminalTokens.TokenNameEOF) { 554 currentToken = scanner.getNextToken(); 555 } 556 if(currentToken == TerminalTokens.TokenNameRBRACE) { 557 closeBodyStart = scanner.startPosition; 558 closeBodyEnd = scanner.currentPosition - 1; 559 } else { 560 closeBodyStart = fDocument.length; 561 closeBodyEnd = fDocument.length; 562 } 563 } catch(InvalidInputException e) { 564 closeBodyStart = fDocument.length; 565 closeBodyEnd = fDocument.length; 566 } 567 openBodyEnd = closeBodyEnd - 1; 568 } 569 setOpenBodyRangeEnd(openBodyEnd); 570 setOpenBodyRangeStart(openBodyStart); 571 setCloseBodyRangeStart(closeBodyStart); 572 setCloseBodyRangeEnd(closeBodyEnd); 573 fInsertionPosition = finder.getLineStart(closeBodyStart); 574 if (lastNode != null && fInsertionPosition < lastNode.getEndPosition()) { 575 fInsertionPosition = getCloseBodyPosition(); 576 } 577 if (fInsertionPosition <= openBodyEnd) { 578 fInsertionPosition = getCloseBodyPosition(); 579 } 580 super.normalize(finder); 581 } 582 583 586 void normalizeEndPosition(ILineStartFinder finder, DOMNode next) { 587 if (next == null) { 588 DOMNode parent = (DOMNode) getParent(); 591 if (parent == null || parent instanceof DOMCompilationUnit) { 592 setSourceRangeEnd(fDocument.length - 1); 593 } else { 594 setSourceRangeEnd(((DOMType)parent).getCloseBodyPosition() - 1); 596 } 597 } else { 598 next.normalizeStartPosition(getEndPosition(), finder); 600 setSourceRangeEnd(next.getStartPosition() - 1); 601 } 602 } 603 604 607 protected void offset(int offset) { 608 super.offset(offset); 609 offsetRange(fCloseBodyRange, offset); 610 offsetRange(fExtendsRange, offset); 611 offsetRange(fImplementsRange, offset); 612 offsetRange(fInterfacesRange, offset); 613 offsetRange(fOpenBodyRange, offset); 614 offsetRange(fSuperclassRange, offset); 615 offsetRange(fTypeRange, offset); 616 } 617 620 public void setClass(boolean b) { 621 becomeDetailed(); 622 fragment(); 623 setMask(MASK_TYPE_IS_CLASS, b); 624 if (b) { 625 fTypeKeyword= "class"; } else { 627 fTypeKeyword= "interface"; setSuperclass(null); 629 } 630 } 631 634 void setCloseBodyRangeEnd(int end) { 635 fCloseBodyRange[1] = end; 636 } 637 640 void setCloseBodyRangeStart(int start) { 641 fCloseBodyRange[0] = start; 642 } 643 652 public void setName(String name) throws IllegalArgumentException { 653 if (name == null) { 654 throw new IllegalArgumentException (Messages.element_nullName); 655 } 656 super.setName(name); 657 Enumeration children= getChildren(); 658 while (children.hasMoreElements()) { 659 IDOMNode child= (IDOMNode)children.nextElement(); 660 if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) { 661 ((DOMNode)child).fragment(); 662 } 663 } 664 } 665 668 void setOpenBodyRangeEnd(int end) { 669 fOpenBodyRange[1] = end; 670 } 671 674 void setOpenBodyRangeStart(int start) { 675 fOpenBodyRange[0] = start; 676 } 677 680 public void setSuperclass(String superclassName) { 681 becomeDetailed(); 682 fragment(); 683 fSuperclass= superclassName; 684 setMask(MASK_TYPE_HAS_SUPERCLASS, superclassName != null); 685 } 686 689 public void setSuperInterfaces(String [] names) { 690 becomeDetailed(); 691 if (names == null) { 692 throw new IllegalArgumentException (Messages.dom_nullInterfaces); 693 } 694 fragment(); 695 fSuperInterfaces= names; 696 if (names.length == 0) { 697 fInterfaces= null; 698 fSuperInterfaces= CharOperation.NO_STRINGS; 699 setMask(MASK_TYPE_HAS_INTERFACES, false); 700 } else { 701 setMask(MASK_TYPE_HAS_INTERFACES, true); 702 CharArrayBuffer buffer = new CharArrayBuffer(); 703 for (int i = 0; i < names.length; i++) { 704 if (i > 0) { 705 buffer.append(", "); } 707 buffer.append(names[i]); 708 } 709 fInterfaces = buffer.getContents(); 710 } 711 } 712 715 void setTypeKeyword(String keyword) { 716 fTypeKeyword = keyword; 717 } 718 721 protected void shareContents(DOMNode node) { 722 super.shareContents(node); 723 DOMType type= (DOMType)node; 724 fCloseBodyRange= rangeCopy(type.fCloseBodyRange); 725 fExtendsRange= type.fExtendsRange; 726 fImplementsRange= rangeCopy(type.fImplementsRange); 727 fInterfaces= type.fInterfaces; 728 fInterfacesRange= rangeCopy(type.fInterfacesRange); 729 fOpenBodyRange= rangeCopy(type.fOpenBodyRange); 730 fSuperclass= type.fSuperclass; 731 fSuperclassRange= rangeCopy(type.fSuperclassRange); 732 fSuperInterfaces= type.fSuperInterfaces; 733 fTypeKeyword= type.fTypeKeyword; 734 fTypeRange= rangeCopy(type.fTypeRange); 735 } 736 739 public String toString() { 740 return "TYPE: " + getName(); } 742 743 747 public String [] getTypeParameters() { 748 return this.fTypeParameters; 749 } 750 751 755 public boolean isEnum() { 756 return this.fIsEnum; 757 } 758 759 763 public boolean isAnnotation() { 764 return this.fIsAnnotation; 765 } 766 767 771 public void setEnum(boolean b) { 772 this.fIsEnum = b; 773 if (this.fIsEnum) { 774 setClass(true); 776 setSuperclass(null); 777 } 778 } 779 780 784 public void setAnnotation(boolean b) { 785 this.fIsAnnotation= b; 786 if (this.fIsAnnotation) { 787 setClass(false); 789 setSuperclass(null); 790 setSuperInterfaces(CharOperation.NO_STRINGS); 791 } 792 } 793 794 798 public void setTypeParameters(String [] typeParameters) { 799 this.fTypeParameters = typeParameters; 800 } 801 } 802 | Popular Tags |