1 11 package org.eclipse.jdt.core.dom; 12 13 import java.util.Map ; 14 15 import org.eclipse.core.runtime.IProgressMonitor; 16 import org.eclipse.jdt.core.IClassFile; 17 import org.eclipse.jdt.core.ICompilationUnit; 18 import org.eclipse.jdt.core.IJavaElement; 19 import org.eclipse.jdt.core.IJavaProject; 20 import org.eclipse.jdt.core.JavaCore; 21 import org.eclipse.jdt.core.JavaModelException; 22 import org.eclipse.jdt.core.WorkingCopyOwner; 23 import org.eclipse.jdt.core.compiler.IProblem; 24 import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; 25 import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; 26 import org.eclipse.jdt.internal.compiler.ast.Statement; 27 import org.eclipse.jdt.internal.compiler.env.IBinaryType; 28 import org.eclipse.jdt.internal.core.*; 29 import org.eclipse.jdt.internal.core.DefaultWorkingCopyOwner; 30 import org.eclipse.jdt.internal.core.PackageFragment; 31 import org.eclipse.jdt.internal.core.util.CodeSnippetParsingUtil; 32 import org.eclipse.jdt.internal.core.util.RecordedParsingInformation; 33 import org.eclipse.jdt.internal.core.util.Util; 34 35 74 public class ASTParser { 75 76 80 public static final int K_EXPRESSION = 0x01; 81 82 86 public static final int K_STATEMENTS = 0x02; 87 88 92 public static final int K_CLASS_BODY_DECLARATIONS = 0x04; 93 94 98 public static final int K_COMPILATION_UNIT = 0x08; 99 100 108 public static ASTParser newParser(int level) { 109 return new ASTParser(level); 110 } 111 112 115 private final int apiLevel; 116 117 120 private int astKind; 121 122 125 private Map compilerOptions; 126 127 130 private boolean resolveBindings; 131 132 135 private boolean partial = false; 136 137 141 private int focalPointPosition; 142 143 146 private char[] rawSource = null; 147 148 151 private ICompilationUnit compilationUnitSource = null; 152 153 156 private IClassFile classFileSource = null; 157 158 162 private int sourceOffset = 0; 163 164 170 private int sourceLength = -1; 171 172 175 private WorkingCopyOwner workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY; 176 177 181 private IJavaProject project = null; 182 183 187 private String unitName = null; 188 189 198 ASTParser(int level) { 199 if ((level != AST.JLS2_INTERNAL) 200 && (level != AST.JLS3)) { 201 throw new IllegalArgumentException (); 202 } 203 this.apiLevel = level; 204 initializeDefaults(); 205 } 206 207 210 private void initializeDefaults() { 211 this.astKind = K_COMPILATION_UNIT; 212 this.rawSource = null; 213 this.classFileSource = null; 214 this.compilationUnitSource = null; 215 this.resolveBindings = false; 216 this.sourceLength = -1; 217 this.sourceOffset = 0; 218 this.workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY; 219 this.unitName = null; 220 this.project = null; 221 this.partial = false; 222 this.compilerOptions = JavaCore.getOptions(); 223 } 224 225 250 public void setCompilerOptions(Map options) { 251 if (options == null) { 252 this.compilerOptions = JavaCore.getOptions(); 253 } 254 this.compilerOptions = options; 255 } 256 257 306 public void setResolveBindings(boolean bindings) { 307 this.resolveBindings = bindings; 308 } 309 310 346 public void setFocalPosition(int position) { 347 this.partial = true; 348 this.focalPointPosition = position; 349 } 350 351 423 public void setKind(int kind) { 424 if ((kind != K_COMPILATION_UNIT) 425 && (kind != K_CLASS_BODY_DECLARATIONS) 426 && (kind != K_EXPRESSION) 427 && (kind != K_STATEMENTS)) { 428 throw new IllegalArgumentException (); 429 } 430 this.astKind = kind; 431 } 432 433 439 public void setSource(char[] source) { 440 this.rawSource = source; 441 this.compilationUnitSource = null; 443 this.classFileSource = null; 444 } 445 446 455 public void setSource(ICompilationUnit source) { 456 this.compilationUnitSource = source; 457 this.rawSource = null; 459 this.classFileSource = null; 460 if (source != null) { 461 this.project = source.getJavaProject(); 462 this.compilerOptions = this.project.getOptions(true); 463 } 464 } 465 466 475 public void setSource(IClassFile source) { 476 this.classFileSource = source; 477 this.rawSource = null; 479 this.compilationUnitSource = null; 480 if (source != null) { 481 this.project = source.getJavaProject(); 482 this.compilerOptions = this.project.getOptions(true); 483 } 484 } 485 486 495 public void setSourceRange(int offset, int length) { 496 if (offset < 0 || length < -1) { 497 throw new IllegalArgumentException (); 498 } 499 this.sourceOffset = offset; 500 this.sourceLength = length; 501 } 502 503 510 public void setWorkingCopyOwner(WorkingCopyOwner owner) { 511 if (owner == null) { 512 this.workingCopyOwner = DefaultWorkingCopyOwner.PRIMARY; 513 } else { 514 this.workingCopyOwner = owner; 515 } 516 } 517 518 535 public void setUnitName(String unitName) { 536 this.unitName = unitName; 537 } 538 539 558 public void setProject(IJavaProject project) { 559 this.project = project; 560 if (project != null) { 561 this.compilerOptions = project.getOptions(true); 562 } 563 } 564 565 580 public ASTNode createAST(IProgressMonitor monitor) { 581 ASTNode result = null; 582 try { 583 if ((this.rawSource == null) 584 && (this.compilationUnitSource == null) 585 && (this.classFileSource == null)) { 586 throw new IllegalStateException ("source not specified"); } 588 result = internalCreateAST(monitor); 589 } finally { 590 initializeDefaults(); 592 } 593 return result; 594 } 595 596 659 public void createASTs(ICompilationUnit[] compilationUnits, String [] bindingKeys, ASTRequestor requestor, IProgressMonitor monitor) { 660 try { 661 if (this.resolveBindings) { 662 if (this.project == null) 663 throw new IllegalStateException ("project not specified"); CompilationUnitResolver.resolve(compilationUnits, bindingKeys, requestor, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, monitor); 665 } else { 666 CompilationUnitResolver.parse(compilationUnits, requestor, this.apiLevel, this.compilerOptions, monitor); 667 } 668 } finally { 669 initializeDefaults(); 671 } 672 } 673 674 713 public IBinding[] createBindings(IJavaElement[] elements, IProgressMonitor monitor) { 714 try { 715 if (this.project == null) 716 throw new IllegalStateException ("project not specified"); return CompilationUnitResolver.resolve(elements, this.apiLevel, this.compilerOptions, this.project, this.workingCopyOwner, monitor); 718 } finally { 719 initializeDefaults(); 721 } 722 } 723 724 private ASTNode internalCreateAST(IProgressMonitor monitor) { 725 boolean needToResolveBindings = this.resolveBindings; 726 switch(this.astKind) { 727 case K_CLASS_BODY_DECLARATIONS : 728 case K_EXPRESSION : 729 case K_STATEMENTS : 730 if (this.rawSource != null) { 731 if (this.sourceOffset + this.sourceLength > this.rawSource.length) { 732 throw new IllegalStateException (); 733 } 734 return internalCreateASTForKind(); 735 } 736 break; 737 case K_COMPILATION_UNIT : 738 CompilationUnitDeclaration compilationUnitDeclaration = null; 739 try { 740 NodeSearcher searcher = null; 741 org.eclipse.jdt.internal.compiler.env.ICompilationUnit sourceUnit = null; 742 IJavaElement element = null; 743 if (this.compilationUnitSource != null) { 744 sourceUnit = (org.eclipse.jdt.internal.compiler.env.ICompilationUnit) this.compilationUnitSource; 745 sourceUnit = new BasicCompilationUnit(sourceUnit.getContents(), sourceUnit.getPackageName(), new String (sourceUnit.getFileName()), this.project); 749 element = this.compilationUnitSource; 750 } else if (this.classFileSource != null) { 751 try { 752 String sourceString = this.classFileSource.getSource(); 753 if (sourceString == null) { 754 throw new IllegalStateException (); 755 } 756 PackageFragment packageFragment = (PackageFragment) this.classFileSource.getParent(); 757 BinaryType type = (BinaryType) this.classFileSource.getType(); 758 IBinaryType binaryType = (IBinaryType) type.getElementInfo(); 759 String fileName = new String (binaryType.getFileName()); sourceUnit = new BasicCompilationUnit(sourceString.toCharArray(), Util.toCharArrays(packageFragment.names), fileName, this.project); 761 element = this.classFileSource; 762 } catch(JavaModelException e) { 763 throw new IllegalStateException (); 765 } 766 } else if (this.rawSource != null) { 767 needToResolveBindings = this.unitName != null && this.project != null && this.compilerOptions != null; 768 sourceUnit = new BasicCompilationUnit(this.rawSource, null, this.unitName == null ? "" : this.unitName, this.project); } else { 770 throw new IllegalStateException (); 771 } 772 if (this.partial) { 773 searcher = new NodeSearcher(this.focalPointPosition); 774 } 775 if (needToResolveBindings && this.project != null) { 776 try { 777 compilationUnitDeclaration = 779 CompilationUnitResolver.resolve( 780 sourceUnit, 781 this.project, 782 searcher, 783 this.compilerOptions, 784 this.workingCopyOwner, 785 monitor); 786 } catch (JavaModelException e) { 787 compilationUnitDeclaration = CompilationUnitResolver.parse( 788 sourceUnit, 789 searcher, 790 this.compilerOptions); 791 needToResolveBindings = false; 792 } 793 } else { 794 compilationUnitDeclaration = CompilationUnitResolver.parse( 795 sourceUnit, 796 searcher, 797 this.compilerOptions); 798 needToResolveBindings = false; 799 } 800 CompilationUnit result = CompilationUnitResolver.convert( 801 compilationUnitDeclaration, 802 sourceUnit.getContents(), 803 this.apiLevel, 804 this.compilerOptions, 805 needToResolveBindings, 806 this.compilationUnitSource == null ? this.workingCopyOwner : this.compilationUnitSource.getOwner(), 807 needToResolveBindings ? new DefaultBindingResolver.BindingTables() : null, 808 monitor); 809 result.setJavaElement(element); 810 return result; 811 } finally { 812 if (compilationUnitDeclaration != null && this.resolveBindings) { 813 compilationUnitDeclaration.cleanUp(); 814 } 815 } 816 } 817 throw new IllegalStateException (); 818 } 819 820 890 private ASTNode internalCreateASTForKind() { 891 final ASTConverter converter = new ASTConverter(this.compilerOptions, false, null); 892 converter.compilationUnitSource = this.rawSource; 893 converter.compilationUnitSourceLength = this.rawSource.length; 894 converter.scanner.setSource(this.rawSource); 895 896 AST ast = AST.newAST(this.apiLevel); 897 ast.setDefaultNodeFlag(ASTNode.ORIGINAL); 898 ast.setBindingResolver(new BindingResolver()); 899 converter.setAST(ast); 900 CodeSnippetParsingUtil codeSnippetParsingUtil = new CodeSnippetParsingUtil(); 901 CompilationUnit compilationUnit = ast.newCompilationUnit(); 902 if (this.sourceLength == -1) { 903 this.sourceLength = this.rawSource.length; 904 } 905 switch(this.astKind) { 906 case K_STATEMENTS : 907 ConstructorDeclaration constructorDeclaration = codeSnippetParsingUtil.parseStatements(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true); 908 RecordedParsingInformation recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation; 909 int[][] comments = recordedParsingInformation.commentPositions; 910 if (comments != null) { 911 converter.buildCommentsTable(compilationUnit, comments); 912 } 913 compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds); 914 if (constructorDeclaration != null) { 915 Block block = ast.newBlock(); 916 Statement[] statements = constructorDeclaration.statements; 917 if (statements != null) { 918 int statementsLength = statements.length; 919 for (int i = 0; i < statementsLength; i++) { 920 block.statements().add(converter.convert(statements[i])); 921 } 922 } 923 rootNodeToCompilationUnit(ast, compilationUnit, block, recordedParsingInformation); 924 ast.setDefaultNodeFlag(0); 925 ast.setOriginalModificationCount(ast.modificationCount()); 926 return block; 927 } else { 928 IProblem[] problems = recordedParsingInformation.problems; 929 if (problems != null) { 930 compilationUnit.setProblems(problems); 931 } 932 ast.setDefaultNodeFlag(0); 933 ast.setOriginalModificationCount(ast.modificationCount()); 934 return compilationUnit; 935 } 936 case K_EXPRESSION : 937 org.eclipse.jdt.internal.compiler.ast.Expression expression = codeSnippetParsingUtil.parseExpression(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true); 938 recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation; 939 comments = recordedParsingInformation.commentPositions; 940 if (comments != null) { 941 converter.buildCommentsTable(compilationUnit, comments); 942 } 943 compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds); 944 if (expression != null) { 945 Expression expression2 = converter.convert(expression); 946 rootNodeToCompilationUnit(expression2.getAST(), compilationUnit, expression2, codeSnippetParsingUtil.recordedParsingInformation); 947 ast.setDefaultNodeFlag(0); 948 ast.setOriginalModificationCount(ast.modificationCount()); 949 return expression2; 950 } else { 951 IProblem[] problems = recordedParsingInformation.problems; 952 if (problems != null) { 953 compilationUnit.setProblems(problems); 954 } 955 ast.setDefaultNodeFlag(0); 956 ast.setOriginalModificationCount(ast.modificationCount()); 957 return compilationUnit; 958 } 959 case K_CLASS_BODY_DECLARATIONS : 960 final org.eclipse.jdt.internal.compiler.ast.ASTNode[] nodes = codeSnippetParsingUtil.parseClassBodyDeclarations(this.rawSource, this.sourceOffset, this.sourceLength, this.compilerOptions, true); 961 recordedParsingInformation = codeSnippetParsingUtil.recordedParsingInformation; 962 comments = recordedParsingInformation.commentPositions; 963 if (comments != null) { 964 converter.buildCommentsTable(compilationUnit, comments); 965 } 966 compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds); 967 if (nodes != null) { 968 TypeDeclaration typeDeclaration = converter.convert(nodes); 969 rootNodeToCompilationUnit(typeDeclaration.getAST(), compilationUnit, typeDeclaration, codeSnippetParsingUtil.recordedParsingInformation); 970 ast.setDefaultNodeFlag(0); 971 ast.setOriginalModificationCount(ast.modificationCount()); 972 return typeDeclaration; 973 } else { 974 IProblem[] problems = recordedParsingInformation.problems; 975 if (problems != null) { 976 compilationUnit.setProblems(problems); 977 } 978 ast.setDefaultNodeFlag(0); 979 ast.setOriginalModificationCount(ast.modificationCount()); 980 return compilationUnit; 981 } 982 } 983 throw new IllegalStateException (); 984 } 985 986 private void propagateErrors(ASTNode astNode, IProblem[] problems) { 987 ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(problems); 988 astNode.accept(syntaxErrorPropagator); 989 } 990 991 private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation) { 992 final int problemsCount = recordedParsingInformation.problemsCount; 993 switch(node.getNodeType()) { 994 case ASTNode.BLOCK : 995 { 996 Block block = (Block) node; 997 if (problemsCount != 0) { 998 final IProblem[] problems = recordedParsingInformation.problems; 1000 for (int i = 0, max = block.statements().size(); i < max; i++) { 1001 propagateErrors((ASTNode) block.statements().get(i), problems); 1002 } 1003 compilationUnit.setProblems(problems); 1004 } 1005 TypeDeclaration typeDeclaration = ast.newTypeDeclaration(); 1006 Initializer initializer = ast.newInitializer(); 1007 initializer.setBody(block); 1008 typeDeclaration.bodyDeclarations().add(initializer); 1009 compilationUnit.types().add(typeDeclaration); 1010 } 1011 break; 1012 case ASTNode.TYPE_DECLARATION : 1013 { 1014 TypeDeclaration typeDeclaration = (TypeDeclaration) node; 1015 if (problemsCount != 0) { 1016 final IProblem[] problems = recordedParsingInformation.problems; 1018 for (int i = 0, max = typeDeclaration.bodyDeclarations().size(); i < max; i++) { 1019 propagateErrors((ASTNode) typeDeclaration.bodyDeclarations().get(i), problems); 1020 } 1021 compilationUnit.setProblems(problems); 1022 } 1023 compilationUnit.types().add(typeDeclaration); 1024 } 1025 break; 1026 default : 1027 if (node instanceof Expression) { 1028 Expression expression = (Expression) node; 1029 if (problemsCount != 0) { 1030 final IProblem[] problems = recordedParsingInformation.problems; 1032 propagateErrors(expression, problems); 1033 compilationUnit.setProblems(problems); 1034 } 1035 ExpressionStatement expressionStatement = ast.newExpressionStatement(expression); 1036 Block block = ast.newBlock(); 1037 block.statements().add(expressionStatement); 1038 Initializer initializer = ast.newInitializer(); 1039 initializer.setBody(block); 1040 TypeDeclaration typeDeclaration = ast.newTypeDeclaration(); 1041 typeDeclaration.bodyDeclarations().add(initializer); 1042 compilationUnit.types().add(typeDeclaration); 1043 } 1044 } 1045 } 1046} 1047 | Popular Tags |