1 11 package org.eclipse.jdt.internal.corext.dom.fragments; 12 13 import org.eclipse.jdt.core.ICompilationUnit; 14 import org.eclipse.jdt.core.JavaModelException; 15 import org.eclipse.jdt.core.dom.ASTNode; 16 import org.eclipse.jdt.core.dom.Expression; 17 import org.eclipse.jdt.core.dom.InfixExpression; 18 19 import org.eclipse.jdt.internal.corext.Assert; 20 import org.eclipse.jdt.internal.corext.SourceRange; 21 import org.eclipse.jdt.internal.corext.dom.HierarchicalASTVisitor; 22 import org.eclipse.jdt.internal.corext.dom.Selection; 23 import org.eclipse.jdt.internal.corext.dom.SelectionAnalyzer; 24 25 41 public class ASTFragmentFactory { 42 43 45 53 public static IASTFragment createFragmentForFullSubtree(ASTNode node) { 54 IASTFragment result= FragmentForFullSubtreeFactory.createFragmentFor(node); 55 Assert.isNotNull(result); 56 return result; 57 } 58 59 75 public static IASTFragment createFragmentForSourceRange(SourceRange range, ASTNode scope, ICompilationUnit cu) throws JavaModelException { 76 SelectionAnalyzer sa= new SelectionAnalyzer(Selection.createFromStartLength(range.getOffset(), range.getLength()), false); 77 scope.accept(sa); 78 79 if (isSingleNodeSelected(sa, range, cu)) 80 return ASTFragmentFactory.createFragmentForFullSubtree(sa.getFirstSelectedNode()); 81 if (isEmptySelectionCoveredByANode(range, sa)) 82 return ASTFragmentFactory.createFragmentForFullSubtree(sa.getLastCoveringNode()); 83 return ASTFragmentFactory.createFragmentForSubPartBySourceRange(sa.getLastCoveringNode(), range, cu); 84 } 85 86 88 89 private static boolean isEmptySelectionCoveredByANode(SourceRange range, SelectionAnalyzer sa) { 90 return range.getLength() == 0 && sa.getFirstSelectedNode() == null && sa.getLastCoveringNode() != null; 91 } 92 93 private static boolean isSingleNodeSelected(SelectionAnalyzer sa, SourceRange range, ICompilationUnit cu) throws JavaModelException { 94 return sa.getSelectedNodes().length == 1 && !rangeIncludesNonWhitespaceOutsideNode(range, sa.getFirstSelectedNode(), cu); 95 } 96 private static boolean rangeIncludesNonWhitespaceOutsideNode(SourceRange range, ASTNode node, ICompilationUnit cu) throws JavaModelException { 97 return Util.rangeIncludesNonWhitespaceOutsideRange(range, new SourceRange(node), cu.getBuffer()); 98 } 99 100 101 106 private static IASTFragment createFragmentForSubPartBySourceRange(ASTNode node, SourceRange range, ICompilationUnit cu) throws JavaModelException { 107 return FragmentForSubPartBySourceRangeFactory.createFragmentFor(node, range, cu); 108 } 109 110 private static class FragmentForFullSubtreeFactory extends FragmentFactory { 111 public static IASTFragment createFragmentFor(ASTNode node) { 112 return new FragmentForFullSubtreeFactory().createFragment(node); 113 } 114 115 public boolean visit(InfixExpression node) { 116 120 IASTFragment fragment= AssociativeInfixExpressionFragment.createFragmentForFullSubtree(node); 121 if(fragment == null) 122 return visit((Expression) node); 123 124 setFragment(fragment); 125 return false; 126 } 127 public boolean visit(Expression node) { 128 setFragment(new SimpleExpressionFragment(node)); 129 return false; 130 } 131 public boolean visit(ASTNode node) { 132 setFragment(new SimpleFragment(node)); 133 return false; 134 } 135 } 136 private static class FragmentForSubPartBySourceRangeFactory extends FragmentFactory { 137 private SourceRange fRange; 138 private ICompilationUnit fCu; 139 140 private JavaModelException javaModelException= null; 141 142 public static IASTFragment createFragmentFor(ASTNode node, SourceRange range, ICompilationUnit cu) throws JavaModelException { 143 return new FragmentForSubPartBySourceRangeFactory().createFragment(node, range, cu); 144 } 145 146 public boolean visit(InfixExpression node) { 147 try { 148 setFragment(createInfixExpressionSubPartFragmentBySourceRange(node, fRange, fCu)); 149 } catch(JavaModelException e) { 150 javaModelException= e; 151 } 152 return false; 153 } 154 155 public boolean visit(ASTNode node) { 156 return false; 158 } 159 160 protected IASTFragment createFragment(ASTNode node, SourceRange range, ICompilationUnit cu) throws JavaModelException { 161 fRange= range; 162 fCu= cu; 163 IASTFragment result= createFragment(node); 164 if(javaModelException != null) 165 throw javaModelException; 166 return result; 167 } 168 169 private static IExpressionFragment createInfixExpressionSubPartFragmentBySourceRange(InfixExpression node, SourceRange range, ICompilationUnit cu) throws JavaModelException { 170 return AssociativeInfixExpressionFragment.createSubPartFragmentBySourceRange(node, range, cu); 171 } 172 } 173 private static abstract class FragmentFactory extends HierarchicalASTVisitor { 174 private IASTFragment fFragment; 175 176 protected IASTFragment createFragment(ASTNode node) { 177 fFragment= null; 178 node.accept(this); 179 return fFragment; 180 } 181 182 protected final IASTFragment getFragment() { 183 return fFragment; 184 } 185 protected final void setFragment(IASTFragment fragment) { 186 Assert.isTrue(!isFragmentSet()); 187 fFragment= fragment; 188 } 189 protected final void clearFragment() { 190 fFragment= null; 191 } 192 protected final boolean isFragmentSet() { 193 return getFragment() != null; 194 } 195 } 196 } 197 | Popular Tags |