1 19 20 package org.netbeans.modules.junit; 21 22 import com.sun.source.tree.ClassTree; 23 import com.sun.source.tree.CompilationUnitTree; 24 import com.sun.source.tree.Tree; 25 import com.sun.source.util.TreePath; 26 import com.sun.source.util.Trees; 27 import java.io.IOException ; 28 import java.util.ArrayList ; 29 import java.util.Collection ; 30 import java.util.Collections ; 31 import java.util.List ; 32 import javax.lang.model.element.Element; 33 import javax.lang.model.element.ElementKind; 34 import javax.lang.model.element.TypeElement; 35 import org.netbeans.api.java.source.CancellableTask; 36 import org.netbeans.api.java.source.CompilationController; 37 import org.netbeans.api.java.source.CompilationInfo; 38 import org.netbeans.api.java.source.ElementHandle; 39 import org.netbeans.api.java.source.JavaSource; 40 import org.netbeans.api.java.source.JavaSource.Phase; 41 import org.netbeans.api.java.source.TreeUtilities; 42 import org.netbeans.modules.junit.TestabilityResult.SkippedClass; 43 44 49 final class TopClassFinder { 50 51 private TopClassFinder() { } 52 53 55 private static class TopClassFinderTask 56 implements CancellableTask<CompilationController> { 57 private List <ElementHandle<TypeElement>> topClassElems; 58 private TestabilityJudge judgeOfTestability; 59 private Collection <SkippedClass> nonTestable; 60 private volatile boolean cancelled; 61 private TopClassFinderTask() { 62 this.judgeOfTestability = null; 63 this.nonTestable = null; 64 } 65 private TopClassFinderTask(TestabilityJudge testabilityJudge, 66 Collection <SkippedClass> nonTestable) { 67 if (testabilityJudge == null) { 68 throw new IllegalArgumentException ("judgeOfTestability: null"); } 70 if (nonTestable == null) { 71 throw new IllegalArgumentException ("nonTestable: null"); } 73 this.judgeOfTestability = testabilityJudge; 74 this.nonTestable = nonTestable; 75 } 76 public void run(CompilationController controller) throws IOException { 77 controller.toPhase(Phase.ELEMENTS_RESOLVED); 78 if (cancelled) { 79 return; 80 } 81 82 if (judgeOfTestability == null) { 83 topClassElems = findTopClassElemHandles( 84 controller, 85 controller.getCompilationUnit()); 86 } else { 87 topClassElems = findTopClassElemHandles( 88 controller, 89 controller.getCompilationUnit(), 90 judgeOfTestability, 91 nonTestable); 92 } 93 } 94 public void cancel() { 95 cancelled = true; 96 } 97 } 98 99 101 static List <ElementHandle<TypeElement>> findTopClasses( 102 JavaSource javaSource) 103 throws IOException { 104 TopClassFinderTask analyzer = new TopClassFinderTask(); 105 javaSource.runUserActionTask(analyzer, true); 106 return analyzer.topClassElems; 107 } 108 109 123 static List <ElementHandle<TypeElement>> findTestableTopClasses( 124 JavaSource javaSource, 125 TestabilityJudge testabilityJudge, 126 Collection <SkippedClass> nonTestable) 127 throws IOException { 128 TopClassFinderTask analyzer = new TopClassFinderTask(testabilityJudge, nonTestable); 129 javaSource.runUserActionTask(analyzer, true); 130 return analyzer.topClassElems; 131 } 132 133 137 static List <ClassTree> findTopClasses( 138 CompilationUnitTree compilationUnit, 139 TreeUtilities treeUtils) { 140 List <? extends Tree> typeDecls = compilationUnit.getTypeDecls(); 141 if ((typeDecls == null) || typeDecls.isEmpty()) { 142 return Collections.<ClassTree>emptyList(); 143 } 144 145 List <ClassTree> result = new ArrayList <ClassTree>(typeDecls.size()); 146 147 for (Tree typeDecl : typeDecls) { 148 if (typeDecl.getKind() == Tree.Kind.CLASS) { 149 ClassTree clsTree = (ClassTree) typeDecl; 150 if (isTestable(clsTree, treeUtils)) { 151 result.add(clsTree); 152 } 153 } 154 } 155 156 return result; 157 } 158 159 164 private static List <TypeElement> findTopClassElems( 165 CompilationInfo compInfo, 166 CompilationUnitTree compilationUnit, 167 TestabilityJudge testabilityJudge, 168 Collection <SkippedClass> nonTestable) { 169 List <? extends Tree> typeDecls = compilationUnit.getTypeDecls(); 170 if ((typeDecls == null) || typeDecls.isEmpty()) { 171 return Collections.<TypeElement>emptyList(); 172 } 173 174 List <TypeElement> result = new ArrayList <TypeElement>(typeDecls.size()); 175 176 Trees trees = compInfo.getTrees(); 177 for (Tree typeDecl : typeDecls) { 178 if (typeDecl.getKind() == Tree.Kind.CLASS) { 179 Element element = trees.getElement( 180 new TreePath(new TreePath(compilationUnit), typeDecl)); 181 TypeElement typeElement = (TypeElement) element; 182 if (testabilityJudge != null) { 183 TestabilityResult testabilityStatus 184 = testabilityJudge.isClassTestable(compInfo, 185 typeElement); 186 if (testabilityStatus.isTestable()) { 187 result.add(typeElement); 188 } else { 189 nonTestable.add(new SkippedClass( 190 typeElement.getQualifiedName().toString(), 191 testabilityStatus)); 192 } 193 } else if (isTestable(element)) { 194 result.add(typeElement); 195 } 196 } 197 } 198 199 return result; 200 } 201 202 207 private static List <ElementHandle<TypeElement>> findTopClassElemHandles( 208 CompilationInfo compInfo, 209 CompilationUnitTree compilationUnit) { 210 return getElemHandles(findTopClassElems(compInfo, compilationUnit, 211 null, null)); 212 } 213 214 219 private static List <ElementHandle<TypeElement>> findTopClassElemHandles( 220 CompilationInfo compInfo, 221 CompilationUnitTree compilationUnit, 222 TestabilityJudge testabilityJudge, 223 Collection <SkippedClass> nonTestable) { 224 return getElemHandles(findTopClassElems(compInfo, compilationUnit, 225 testabilityJudge, nonTestable)); 226 } 227 228 private static <T extends Element> List <ElementHandle<T>> getElemHandles(List <T> elements) { 229 if (elements == null) { 230 return null; 231 } 232 if (elements.isEmpty()) { 233 return Collections.<ElementHandle<T>>emptyList(); 234 } 235 236 List <ElementHandle<T>> handles = new ArrayList <ElementHandle<T>>(elements.size()); 237 for (T element : elements) { 238 handles.add(ElementHandle.<T>create(element)); 239 } 240 return handles; 241 } 242 243 private static boolean isTestable(ClassTree typeDecl, 244 TreeUtilities treeUtils) { 245 return !treeUtils.isAnnotation(typeDecl); 246 } 247 248 static boolean isTestable(Element typeDeclElement) { 249 ElementKind elemKind = typeDeclElement.getKind(); 250 return (elemKind != ElementKind.ANNOTATION_TYPE) 251 && (elemKind.isClass()|| elemKind.isInterface()); 252 } 253 254 } 255 | Popular Tags |