1 11 12 package org.eclipse.jdt.core.dom; 13 14 import java.util.ArrayList ; 15 import java.util.Arrays ; 16 import java.util.Collections ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 import org.eclipse.jdt.core.IJavaElement; 21 import org.eclipse.jdt.core.ITypeRoot; 22 import org.eclipse.jdt.core.compiler.IProblem; 23 import org.eclipse.jdt.internal.compiler.parser.Scanner; 24 import org.eclipse.jdt.internal.compiler.util.Util; 25 import org.eclipse.jface.text.IDocument; 26 import org.eclipse.text.edits.TextEdit; 27 28 52 public class CompilationUnit extends ASTNode { 53 54 57 private static final Message[] EMPTY_MESSAGES = new Message[0]; 58 59 62 private static final IProblem[] EMPTY_PROBLEMS = new IProblem[0]; 63 64 69 public static final ChildListPropertyDescriptor IMPORTS_PROPERTY = 70 new ChildListPropertyDescriptor(CompilationUnit.class, "imports", ImportDeclaration.class, NO_CYCLE_RISK); 72 77 public static final ChildPropertyDescriptor PACKAGE_PROPERTY = 78 new ChildPropertyDescriptor(CompilationUnit.class, "package", PackageDeclaration.class, OPTIONAL, NO_CYCLE_RISK); 80 86 private static final List PROPERTY_DESCRIPTORS; 87 88 93 public static final ChildListPropertyDescriptor TYPES_PROPERTY = 94 new ChildListPropertyDescriptor(CompilationUnit.class, "types", AbstractTypeDeclaration.class, CYCLE_RISK); 96 static { 97 List properyList = new ArrayList (4); 98 createPropertyList(CompilationUnit.class, properyList); 99 addProperty(PACKAGE_PROPERTY, properyList); 100 addProperty(IMPORTS_PROPERTY, properyList); 101 addProperty(TYPES_PROPERTY, properyList); 102 PROPERTY_DESCRIPTORS = reapPropertyList(properyList); 103 } 104 105 116 public static List propertyDescriptors(int apiLevel) { 117 return PROPERTY_DESCRIPTORS; 118 } 119 120 125 private DefaultCommentMapper commentMapper = null; 126 127 131 private ITypeRoot typeRoot = null; 132 133 137 private ASTNode.NodeList imports = 138 new ASTNode.NodeList(IMPORTS_PROPERTY); 139 140 148 private int[] lineEndTable = Util.EMPTY_INT_ARRAY; 149 150 153 private Message[] messages; 154 155 160 private List optionalCommentList = null; 161 162 168 Comment[] optionalCommentTable = null; 169 170 174 private PackageDeclaration optionalPackageDeclaration = null; 175 176 179 private IProblem[] problems = EMPTY_PROBLEMS; 180 181 185 private ASTNode.NodeList types = 186 new ASTNode.NodeList(TYPES_PROPERTY); 187 188 200 CompilationUnit(AST ast) { 201 super(ast); 202 } 203 204 207 void accept0(ASTVisitor visitor) { 208 boolean visitChildren = visitor.visit(this); 209 if (visitChildren) { 210 acceptChild(visitor, getPackage()); 212 acceptChildren(visitor, this.imports); 213 acceptChildren(visitor, this.types); 214 } 215 visitor.endVisit(this); 216 } 217 218 221 ASTNode clone0(AST target) { 222 CompilationUnit result = new CompilationUnit(target); 223 result.setSourceRange(this.getStartPosition(), this.getLength()); 225 result.setPackage( 226 (PackageDeclaration) ASTNode.copySubtree(target, getPackage())); 227 result.imports().addAll(ASTNode.copySubtrees(target, imports())); 228 result.types().addAll(ASTNode.copySubtrees(target, types())); 229 return result; 230 } 231 232 233 248 public int getColumnNumber(final int position) { 249 if (this.lineEndTable == null) return -2; 250 final int line = getLineNumber(position); 251 if (line == -1) { 252 return -1; 253 } 254 if (line == 1) { 255 if (position >= getStartPosition() + getLength()) return -1; 256 return position; 257 } 258 int length = this.lineEndTable.length; 260 final int previousLineOffset = this.lineEndTable[line - 2]; 263 final int offsetForLine = previousLineOffset + 1; 265 final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1 : this.lineEndTable[line - 1]; 266 if (offsetForLine > currentLineEnd) { 267 return -1; 268 } else { 269 return position - offsetForLine; 270 } 271 } 272 273 325 public ASTNode findDeclaringNode(IBinding binding) { 326 return this.ast.getBindingResolver().findDeclaringNode(binding); 327 } 328 329 374 public ASTNode findDeclaringNode(String key) { 375 return this.ast.getBindingResolver().findDeclaringNode(key); 376 } 377 378 426 public List getCommentList() { 427 return this.optionalCommentList; 428 } 429 430 436 DefaultCommentMapper getCommentMapper() { 437 return this.commentMapper; 438 } 439 440 452 public int getExtendedLength(ASTNode node) { 453 if (node == null) { 454 throw new IllegalArgumentException (); 455 } 456 if (this.commentMapper == null || node.getAST() != getAST()) { 457 return node.getLength(); 459 } else { 460 return this.commentMapper.getExtendedLength(node); 461 } 462 } 463 464 476 public int getExtendedStartPosition(ASTNode node) { 477 if (node == null) { 478 throw new IllegalArgumentException (); 479 } 480 if (this.commentMapper == null || node.getAST() != getAST()) { 481 return node.getStartPosition(); 483 } else { 484 return this.commentMapper.getExtendedStartPosition(node); 485 } 486 } 487 488 496 public IJavaElement getJavaElement() { 497 return this.typeRoot; 498 } 499 500 515 public Message[] getMessages() { 516 if (this.messages == null) { 517 int problemLength = this.problems.length; 518 if (problemLength == 0) { 519 this.messages = EMPTY_MESSAGES; 520 } else { 521 this.messages = new Message[problemLength]; 522 for (int i = 0; i < problemLength; i++) { 523 IProblem problem = this.problems[i]; 524 int start = problem.getSourceStart(); 525 int end = problem.getSourceEnd(); 526 messages[i] = new Message(problem.getMessage(), start, end - start + 1); 527 } 528 } 529 } 530 return this.messages; 531 } 532 533 536 final int getNodeType0() { 537 return COMPILATION_UNIT; 538 } 539 540 547 public PackageDeclaration getPackage() { 548 return this.optionalPackageDeclaration; 549 } 550 551 569 public int getPosition(int line, int column) { 570 if (this.lineEndTable == null) return -2; 571 if (line < 1 || column < 0) return -1; 572 int length; 573 if ((length = this.lineEndTable.length) == 0) { 574 if (line != 1) return -1; 575 return column >= getStartPosition() + getLength() ? -1 : column; 576 } 577 if (line == 1) { 578 final int endOfLine = this.lineEndTable[0]; 579 return column > endOfLine ? -1 : column; 580 } else if( line > length + 1 ) { 581 return -1; 583 } 584 final int previousLineOffset = this.lineEndTable[line - 2]; 587 final int offsetForLine = previousLineOffset + 1; 589 final int currentLineEnd = line == length + 1 ? getStartPosition() + getLength() - 1 : this.lineEndTable[line-1]; 590 if ((offsetForLine + column) > currentLineEnd) { 591 return -1; 592 } else { 593 return offsetForLine + column; 594 } 595 } 596 597 612 public IProblem[] getProblems() { 613 return this.problems; 614 } 615 616 623 public ITypeRoot getTypeRoot() { 624 return this.typeRoot; 625 } 626 627 634 public List imports() { 635 return this.imports; 636 } 637 638 647 public int firstLeadingCommentIndex(ASTNode node) { 648 if (node == null) { 649 throw new IllegalArgumentException (); 650 } 651 if (this.commentMapper == null || node.getAST() != getAST()) { 652 return -1; 653 } 654 return this.commentMapper.firstLeadingCommentIndex(node); 655 } 656 657 666 public int lastTrailingCommentIndex(ASTNode node) { 667 if (node == null) { 668 throw new IllegalArgumentException (); 669 } 670 if (this.commentMapper == null || node.getAST() != getAST()) { 671 return -1; 672 } 673 return this.commentMapper.lastTrailingCommentIndex(node); 674 } 675 676 683 void initCommentMapper(Scanner scanner) { 684 this.commentMapper = new DefaultCommentMapper(this.optionalCommentTable); 685 this.commentMapper.initialize(this, scanner); 686 } 687 688 691 final List internalGetChildListProperty(ChildListPropertyDescriptor property) { 692 if (property == IMPORTS_PROPERTY) { 693 return imports(); 694 } 695 if (property == TYPES_PROPERTY) { 696 return types(); 697 } 698 return super.internalGetChildListProperty(property); 700 } 701 702 705 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) { 706 if (property == PACKAGE_PROPERTY) { 707 if (get) { 708 return getPackage(); 709 } else { 710 setPackage((PackageDeclaration) child); 711 return null; 712 } 713 } 714 return super.internalGetSetChildProperty(property, get, child); 716 } 717 718 722 final List internalStructuralPropertiesForType(int apiLevel) { 723 return propertyDescriptors(apiLevel); 724 } 725 726 748 public int lineNumber(int position) { 749 int lineNumber = getLineNumber(position); 750 return lineNumber < 1 ? 1 : lineNumber; 751 } 752 753 774 public int getLineNumber(int position) { 775 if (this.lineEndTable == null) return -2; 776 int length; 777 if ((length = this.lineEndTable.length) == 0) { 778 if (position >= getStartPosition() + getLength()) { 779 return -1; 780 } 781 return 1; 782 } 783 int low = 0; 784 if (position < 0) { 785 return -1; 787 } 788 if (position <= this.lineEndTable[low]) { 789 return 1; 791 } 792 int hi = length - 1; 794 if (position > this.lineEndTable[hi]) { 795 if (position >= getStartPosition() + getLength()) { 797 return -1; 799 } else { 800 return length + 1; 801 } 802 } 803 806 while (true) { 808 if (low + 1 == hi) { 812 return low + 2; 815 } 816 int mid = low + (hi - low) / 2; 818 if (position <= this.lineEndTable[mid]) { 820 hi = mid; 823 } else { 824 low = mid; 828 } 829 } 831 } 832 833 836 int memSize() { 837 int size = BASE_NODE_SIZE + 8 * 4; 838 if (this.lineEndTable != null) { 839 size += HEADERS + 4 * this.lineEndTable.length; 840 } 841 if (this.optionalCommentTable != null) { 842 size += HEADERS + 4 * this.optionalCommentTable.length; 843 } 844 return size; 846 } 847 848 864 public void recordModifications() { 865 getAST().recordModifications(this); 866 } 867 868 904 public TextEdit rewrite(IDocument document, Map options) { 905 return getAST().rewrite(document, options); 906 } 907 908 921 void setCommentTable(Comment[] commentTable) { 922 if (commentTable == null) { 925 this.optionalCommentList = null; 926 this.optionalCommentTable = null; 927 } else { 928 int nextAvailablePosition = 0; 929 for (int i = 0; i < commentTable.length; i++) { 930 Comment comment = commentTable[i]; 931 if (comment == null) { 932 throw new IllegalArgumentException (); 933 } 934 int start = comment.getStartPosition(); 935 int length = comment.getLength(); 936 if (start < 0 || length < 0 || start < nextAvailablePosition) { 937 throw new IllegalArgumentException (); 938 } 939 nextAvailablePosition = comment.getStartPosition() + comment.getLength(); 940 } 941 this.optionalCommentTable = commentTable; 942 List commentList = Arrays.asList(commentTable); 943 this.optionalCommentList = Collections.unmodifiableList(commentList); 945 } 946 } 947 948 954 void setTypeRoot(ITypeRoot typeRoot) { 955 this.typeRoot = typeRoot; 956 } 957 958 968 void setLineEndTable(int[] lineEndTable) { 969 if (lineEndTable == null) { 970 throw new NullPointerException (); 971 } 972 checkModifiable(); 975 this.lineEndTable = lineEndTable; 976 } 977 978 991 public void setPackage(PackageDeclaration pkgDecl) { 992 ASTNode oldChild = this.optionalPackageDeclaration; 993 preReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY); 994 this.optionalPackageDeclaration = pkgDecl; 995 postReplaceChild(oldChild, pkgDecl, PACKAGE_PROPERTY); 996 } 997 998 999 1005 void setProblems(IProblem[] problems) { 1006 if (problems == null) { 1007 throw new IllegalArgumentException (); 1008 } 1009 this.problems = problems; 1010 } 1011 1012 1015 final boolean subtreeMatch0(ASTMatcher matcher, Object other) { 1016 return matcher.match(this, other); 1018 } 1019 1020 1023 int treeSize() { 1024 int size = memSize(); 1025 if (this.optionalPackageDeclaration != null) { 1026 size += getPackage().treeSize(); 1027 } 1028 size += this.imports.listSize(); 1029 size += this.types.listSize(); 1030 if (this.optionalCommentList != null) { 1032 for (int i = 0; i < this.optionalCommentList.size(); i++) { 1033 Comment comment = (Comment) this.optionalCommentList.get(i); 1034 if (comment != null && comment.getParent() == null) { 1035 size += comment.treeSize(); 1036 } 1037 } 1038 } 1039 return size; 1040 } 1041 1042 1054 public List types() { 1055 return this.types; 1056 } 1057} 1058 1059 | Popular Tags |