1 19 20 package org.netbeans.modules.junit; 21 22 import com.sun.source.tree.BlockTree; 23 import com.sun.source.tree.ClassTree; 24 import com.sun.source.tree.CompilationUnitTree; 25 import com.sun.source.tree.ExpressionTree; 26 import com.sun.source.tree.IdentifierTree; 27 import com.sun.source.tree.LiteralTree; 28 import com.sun.source.tree.MethodInvocationTree; 29 import com.sun.source.tree.MethodTree; 30 import com.sun.source.tree.ModifiersTree; 31 import com.sun.source.tree.StatementTree; 32 import com.sun.source.tree.Tree; 33 import com.sun.source.tree.TypeParameterTree; 34 import com.sun.source.tree.VariableTree; 35 import com.sun.source.util.TreePath; 36 import java.io.IOException ; 37 import java.util.ArrayList ; 38 import java.util.Collections ; 39 import java.util.EnumSet ; 40 import java.util.HashSet ; 41 import java.util.Iterator ; 42 import java.util.List ; 43 import java.util.Set ; 44 import java.util.logging.Level ; 45 import java.util.logging.Logger ; 46 import javax.lang.model.element.Element; 47 import javax.lang.model.element.ElementKind; 48 import javax.lang.model.element.ExecutableElement; 49 import javax.lang.model.element.Modifier; 50 import javax.lang.model.element.TypeElement; 51 import javax.lang.model.element.VariableElement; 52 import javax.lang.model.type.TypeKind; 53 import javax.lang.model.type.TypeMirror; 54 import javax.lang.model.util.ElementFilter; 55 import javax.lang.model.util.Types; 56 import org.netbeans.api.java.source.CancellableTask; 57 import org.netbeans.api.java.source.ClasspathInfo; 58 import org.netbeans.api.java.source.Comment; 59 import org.netbeans.api.java.source.CompilationInfo; 60 import org.netbeans.api.java.source.ElementHandle; 61 import org.netbeans.api.java.source.JavaSource.Phase; 62 import org.netbeans.api.java.source.TreeMaker; 63 import org.netbeans.api.java.source.WorkingCopy; 64 import org.openide.util.NbBundle; 65 import static javax.lang.model.element.Modifier.ABSTRACT; 66 import static javax.lang.model.element.Modifier.PUBLIC; 67 import static javax.lang.model.element.Modifier.PRIVATE; 68 import static javax.lang.model.element.Modifier.PROTECTED; 69 import static javax.lang.model.element.Modifier.STATIC; 70 import static org.netbeans.modules.junit.TestCreator.ACCESS_MODIFIERS; 71 72 76 abstract class AbstractTestGenerator implements CancellableTask<WorkingCopy>{ 77 78 84 private static final String INSTANCE_VAR_NAME = "instance"; 90 private static final String RESULT_VAR_NAME = "result"; 97 private static final String EXP_RESULT_VAR_NAME = "expResult"; 102 private static final String ARTIFICAL_VAR_NAME_BASE = "arg"; 104 private static final EnumSet <Modifier> NO_MODIFIERS 105 = EnumSet.noneOf(Modifier.class); 106 107 115 protected static EnumSet <Modifier> accessModifiers() { 116 123 return EnumSet.copyOf(ACCESS_MODIFIERS); 124 } 125 126 133 protected static EnumSet <Modifier> noModifiers() { 134 141 return EnumSet.copyOf(NO_MODIFIERS); 142 } 143 144 145 protected final TestGeneratorSetup setup; 146 147 private final List <ElementHandle<TypeElement>> srcTopClassElemHandles; 148 149 private final List <String > suiteMembers; 150 151 private final boolean isNewTestClass; 152 153 private List <String >processedClassNames; 154 155 158 private String initialMainMethodBody; 159 160 private volatile boolean cancelled = false; 161 162 163 166 protected AbstractTestGenerator(TestGeneratorSetup setup) { 167 this.setup = setup; 168 this.srcTopClassElemHandles = null; 169 this.suiteMembers = null; 170 this.isNewTestClass = true; } 172 173 177 protected AbstractTestGenerator( 178 TestGeneratorSetup setup, 179 List <ElementHandle<TypeElement>> srcTopClassHandles, 180 List <String >suiteMembers, 181 boolean isNewTestClass) { 182 this.setup = setup; 183 this.srcTopClassElemHandles = srcTopClassHandles; 184 this.suiteMembers = suiteMembers; 185 this.isNewTestClass = isNewTestClass; 186 } 187 188 190 public void run(WorkingCopy workingCopy) throws IOException { 191 192 workingCopy.toPhase(Phase.ELEMENTS_RESOLVED); 193 194 CompilationUnitTree compUnit = workingCopy.getCompilationUnit(); 195 List <ClassTree> tstTopClasses = TopClassFinder.findTopClasses( 196 compUnit, 197 workingCopy.getTreeUtilities()); 198 TreePath compUnitPath = new TreePath(compUnit); 199 200 List <TypeElement> srcTopClassElems 201 = resolveHandles(workingCopy, srcTopClassElemHandles); 202 203 if ((srcTopClassElems != null) && !srcTopClassElems.isEmpty()) { 204 205 final String className 206 = workingCopy.getClasspathInfo() 207 .getClassPath(ClasspathInfo.PathKind.SOURCE) 208 .getResourceName(workingCopy.getFileObject(), '.', false); 209 210 211 for (TypeElement srcTopClass : srcTopClassElems) { 212 createOrUpdateTestClass(srcTopClass, 213 tstTopClasses, 214 className, 215 compUnitPath, 216 workingCopy); 217 } 218 } else if (suiteMembers != null) { for (ClassTree tstClass : tstTopClasses) { 220 TreePath tstClassTreePath = new TreePath(compUnitPath, 221 tstClass); 222 ClassTree origTstTopClass = tstClass; 223 ClassTree tstTopClass = generateMissingSuiteClassMembers( 224 tstClass, 225 tstClassTreePath, 226 suiteMembers, 227 isNewTestClass, 228 workingCopy); 229 if (tstTopClass != origTstTopClass) { 230 workingCopy.rewrite(origTstTopClass, 231 tstTopClass); 232 } 233 classProcessed(tstClass); 234 } 235 } else if (srcTopClassElems == null) { for (ClassTree tstClass : tstTopClasses) { 237 ClassTree origTstTopClass = tstClass; 238 ClassTree tstTopClass = generateMissingInitMembers( 239 tstClass, 240 new TreePath(compUnitPath, 241 tstClass), 242 workingCopy); 243 if (tstTopClass != origTstTopClass) { 244 workingCopy.rewrite(origTstTopClass, 245 tstTopClass); 246 } 247 } 248 } 249 } 250 251 253 private void createOrUpdateTestClass(TypeElement srcTopClass, 254 List <ClassTree> tstTopClasses, 255 String testClassName, 256 TreePath compUnitPath, 257 WorkingCopy workingCopy) { 258 String srcClassName = srcTopClass.getSimpleName().toString(); 259 String tstClassName = TestUtil.getTestClassName(srcClassName); 260 261 List <ExecutableElement> srcMethods 262 = findTestableMethods(srcTopClass); 263 boolean srcHasTestableMethods = !srcMethods.isEmpty(); 264 265 ClassTree tstTopClass = null; 266 for (ClassTree tstClass : tstTopClasses) { 267 if (tstClass.getSimpleName().contentEquals(tstClassName)) { 268 tstTopClass = tstClass; 269 break; 270 } 271 } 272 273 if (tstTopClass != null) { 274 TreePath tstTopClassTreePath = new TreePath(compUnitPath, 275 tstTopClass); 276 277 ClassTree origTstTopClass = tstTopClass; 278 if (srcHasTestableMethods) { 279 tstTopClass = generateMissingTestMethods( 280 srcTopClass, 281 srcMethods, 282 tstTopClass, 283 tstTopClassTreePath, 284 isNewTestClass, 285 workingCopy); 286 } else if (isNewTestClass) { 287 tstTopClass = generateMissingInitMembers( 288 tstTopClass, 289 tstTopClassTreePath, 290 workingCopy); 291 } 292 if (tstTopClass != origTstTopClass) { 293 workingCopy.rewrite(origTstTopClass, 294 tstTopClass); 295 } 296 } else { 297 if (srcHasTestableMethods 298 || tstClassName.equals(TestUtil.getSimpleName(testClassName))) { 299 tstTopClass = generateNewTestClass(workingCopy, 300 tstClassName, 301 srcTopClass, 302 srcMethods); 303 305 } 307 } 308 } 309 310 312 private ClassTree generateNewTestClass(WorkingCopy workingCopy, 313 String name, 314 TypeElement srcClass, 315 List <ExecutableElement> srcMethods) { 316 List <? extends Tree> initMembers = generateInitMembers(workingCopy); 317 List <MethodTree> testMethods = generateTestMethods(srcClass, 318 srcMethods, 319 workingCopy); 320 List <? extends Tree> members; 321 if (initMembers.isEmpty() && testMethods.isEmpty()) { 322 members = Collections.<Tree>emptyList(); 323 } else if (initMembers.isEmpty()) { 324 members = testMethods; 325 } else if (testMethods.isEmpty()) { 326 members = initMembers; 327 } else { 328 List <Tree> allMembers = new ArrayList <Tree>( 329 initMembers.size() + testMethods.size()); 330 allMembers.addAll(initMembers); 331 allMembers.addAll(testMethods); 332 333 members = allMembers; 334 } 335 336 return composeNewTestClass(workingCopy, name, members); 337 } 338 339 341 protected abstract ClassTree composeNewTestClass( 342 WorkingCopy workingCopy, 343 String name, 344 List <? extends Tree> members); 345 346 348 protected abstract List <? extends Tree> generateInitMembers(WorkingCopy workingCopy); 349 350 352 protected abstract ClassTree generateMissingInitMembers( 353 ClassTree tstClass, 354 TreePath tstClassTreePath, 355 WorkingCopy workingCopy); 356 357 359 protected abstract boolean generateMissingInitMembers( 360 List <Tree> tstMembers, 361 ClassMap clsMap, 362 WorkingCopy workingCopy); 363 364 371 protected int getPlaceForFirstInitMethod(ClassMap clsMap) { 372 int targetIndex; 373 if (clsMap.containsMethods()) { 374 targetIndex = clsMap.getFirstMethodIndex(); 375 } else if (clsMap.containsInitializers()) { 376 targetIndex = clsMap.getLastInitializerIndex() + 1; 377 } else if (clsMap.containsNestedClasses()) { 378 targetIndex = clsMap.getFirstNestedClassIndex(); 379 } else { 380 targetIndex = -1; } 382 return targetIndex; 383 } 384 385 390 protected ClassTree generateMissingTestMethods( 391 TypeElement srcClass, 392 List <ExecutableElement> srcMethods, 393 ClassTree tstClass, 394 TreePath tstClassTreePath, 395 boolean generateMissingInitMembers, 396 WorkingCopy workingCopy) { 397 if (srcMethods.isEmpty()) { 398 return tstClass; 399 } 400 401 ClassMap clsMap = ClassMap.forClass(tstClass, 402 tstClassTreePath, 403 workingCopy.getTrees()); 404 405 List <? extends Tree> tstMembersOrig = tstClass.getMembers(); 406 List <Tree> tstMembers = new ArrayList <Tree>(tstMembersOrig.size() + 4); 407 tstMembers.addAll(tstMembersOrig); 408 409 if (generateMissingInitMembers) { 410 generateMissingInitMembers(tstMembers, clsMap, 411 workingCopy); 412 } 413 generateMissingPostInitMethods(tstClassTreePath, 414 tstMembers, 415 clsMap, 416 workingCopy); 417 418 Boolean useNoArgConstrutor = null; 419 for (ExecutableElement srcMethod : srcMethods) { 420 String testMethodName = createTestMethodName( 421 srcMethod.getSimpleName().toString()); 422 int testMethodIndex = clsMap.findNoArgMethod(testMethodName); 423 if (testMethodIndex != -1) { 424 continue; } 426 427 if (useNoArgConstrutor == null) { 428 useNoArgConstrutor = Boolean.valueOf( 429 hasAccessibleNoArgConstructor(srcClass)); 430 } 431 MethodTree newTestMethod = generateTestMethod( 432 srcClass, 433 srcMethod, 434 useNoArgConstrutor.booleanValue(), 435 workingCopy); 436 437 tstMembers.add(newTestMethod); 438 clsMap.addNoArgMethod(newTestMethod.getName().toString()); 439 } 440 441 if (tstMembers.size() == tstMembersOrig.size()) { return tstClass; 443 } 444 445 ClassTree newClass = workingCopy.getTreeMaker().Class( 446 tstClass.getModifiers(), 447 tstClass.getSimpleName(), 448 tstClass.getTypeParameters(), 449 tstClass.getExtendsClause(), 450 (List <? extends ExpressionTree>) tstClass.getImplementsClause(), 451 tstMembers); 452 return newClass; 453 } 454 455 457 protected abstract void generateMissingPostInitMethods( 458 TreePath tstClassTreePath, 459 List <Tree> tstMembers, 460 ClassMap clsMap, 461 WorkingCopy workingCopy); 462 463 465 private List <MethodTree> generateTestMethods( 466 TypeElement srcClass, 467 List <ExecutableElement> srcMethods, 468 WorkingCopy workingCopy) { 469 if (srcMethods.isEmpty()) { 470 return Collections.<MethodTree>emptyList(); 471 } 472 473 boolean useNoArgConstrutor = hasAccessibleNoArgConstructor(srcClass); 474 List <MethodTree> testMethods = new ArrayList <MethodTree>(srcMethods.size()); 475 for (ExecutableElement srcMethod : srcMethods) { 476 testMethods.add( 477 generateTestMethod(srcClass, 478 srcMethod, 479 useNoArgConstrutor, 480 workingCopy)); 481 } 482 return testMethods; 483 } 484 485 487 protected MethodTree generateTestMethod(TypeElement srcClass, 488 ExecutableElement srcMethod, 489 boolean useNoArgConstructor, 490 WorkingCopy workingCopy) { 491 final TreeMaker maker = workingCopy.getTreeMaker(); 492 493 String testMethodName = createTestMethodName( 494 srcMethod.getSimpleName().toString()); 495 ModifiersTree modifiers = maker.Modifiers(createModifierSet(PUBLIC)); 496 List <ExpressionTree> throwsList; 497 if (throwsNonRuntimeExceptions(workingCopy, srcMethod)) { 498 throwsList = Collections.<ExpressionTree>singletonList( 499 maker.Identifier("Exception")); } else { 501 throwsList = Collections.<ExpressionTree>emptyList(); 502 } 503 504 MethodTree method = composeNewTestMethod( 505 testMethodName, 506 generateTestMethodBody(srcClass, srcMethod, useNoArgConstructor, 507 workingCopy), 508 throwsList, 509 workingCopy); 510 511 if (setup.isGenerateMethodJavadoc()) { 512 Comment javadoc = Comment.create( 513 NbBundle.getMessage( 514 TestCreator.class, 515 "TestCreator.variantMethods.JavaDoc.comment", srcMethod.getSimpleName().toString(), 517 srcClass.getSimpleName().toString())); 518 maker.addComment(method, javadoc, false); 519 } 520 521 return method; 522 } 523 524 526 protected String createTestMethodName(String smName) { 527 return "test" + smName.substring(0,1).toUpperCase() + smName.substring(1); 529 } 530 531 533 protected abstract MethodTree composeNewTestMethod( 534 String testMethodName, 535 BlockTree testMethodBody, 536 List <ExpressionTree> throwsList, 537 WorkingCopy workingCopy); 538 539 541 private ClassTree generateMissingSuiteClassMembers( 542 ClassTree tstClass, 543 TreePath tstClassTreePath, 544 List <String > suiteMembers, 545 boolean isNewTestClass, 546 WorkingCopy workingCopy) { 547 final TreeMaker maker = workingCopy.getTreeMaker(); 548 549 List <? extends Tree> tstMembersOrig = tstClass.getMembers(); 550 List <Tree> tstMembers = new ArrayList <Tree>(tstMembersOrig.size() + 2); 551 tstMembers.addAll(tstMembersOrig); 552 boolean membersChanged = false; 553 554 ClassMap classMap = ClassMap.forClass(tstClass, 555 tstClassTreePath, 556 workingCopy.getTrees()); 557 558 if (isNewTestClass) { 559 membersChanged |= generateMissingInitMembers(tstMembers, 560 classMap, 561 workingCopy); 562 } 563 564 return finishSuiteClass(tstClass, 565 tstClassTreePath, 566 tstMembers, 567 suiteMembers, 568 membersChanged, 569 classMap, 570 workingCopy); 571 } 572 573 575 protected abstract ClassTree finishSuiteClass( 576 ClassTree tstClass, 577 TreePath tstClassTreePath, 578 List <Tree> tstMembers, 579 List <String > suiteMembers, 580 boolean membersChanged, 581 ClassMap classMap, 582 WorkingCopy workingCopy); 583 584 662 695 703 private MethodTree createMainMethod(TreeMaker maker) { 704 String initialMainMethodBody = getInitialMainMethodBody(); 705 if (initialMainMethodBody.length() == 0) { 706 return null; 707 } 708 709 ModifiersTree modifiers = maker.Modifiers( 710 createModifierSet(Modifier.PUBLIC, Modifier.STATIC)); 711 VariableTree param = maker.Variable( 712 maker.Modifiers(Collections.<Modifier>emptySet()), 713 "argList", maker.Identifier("String[]"), null); MethodTree mainMethod = maker.Method( 717 modifiers, "main", maker.PrimitiveType(TypeKind.VOID), Collections.<TypeParameterTree>emptyList(), Collections.<VariableTree>singletonList(param), Collections.<ExpressionTree>emptyList(), '{' + initialMainMethodBody + '}', null); 726 return mainMethod; 727 } 728 729 881 883 protected BlockTree generateTestMethodBody(TypeElement srcClass, 884 ExecutableElement srcMethod, 885 boolean useNoArgConstructor, 886 WorkingCopy workingCopy) { 887 TreeMaker maker = workingCopy.getTreeMaker(); 888 889 boolean isStatic = srcMethod.getModifiers().contains(Modifier.STATIC); 890 List <StatementTree> statements = new ArrayList <StatementTree>(8); 891 892 if (setup.isGenerateDefMethodBody()) { 893 StatementTree sout = generateSystemOutPrintln( 894 maker, 895 srcMethod.getSimpleName().toString()); 896 List <VariableTree> paramVariables = generateParamVariables( 897 maker, 898 srcMethod); 899 statements.add(sout); 900 statements.addAll(paramVariables); 901 902 if (!isStatic) { 903 VariableTree instanceVarInit = maker.Variable( 904 maker.Modifiers(Collections.<Modifier>emptySet()), 905 INSTANCE_VAR_NAME, 906 maker.QualIdent(srcClass), 907 useNoArgConstructor 908 ? generateNoArgConstructorCall(maker, srcClass) 909 : maker.Literal(null)); 910 statements.add(instanceVarInit); 911 } 912 913 MethodInvocationTree methodCall = maker.MethodInvocation( 914 Collections.<ExpressionTree>emptyList(), maker.MemberSelect( 916 isStatic ? maker.QualIdent(srcClass) 917 : maker.Identifier(INSTANCE_VAR_NAME), 918 srcMethod.getSimpleName()), 919 createIdentifiers(maker, paramVariables)); 920 921 TypeMirror retType = srcMethod.getReturnType(); 922 TypeKind retTypeKind = retType.getKind(); 923 924 if (retTypeKind == TypeKind.VOID) { 925 StatementTree methodCallStmt = maker.ExpressionStatement(methodCall); 926 927 statements.add(methodCallStmt); 928 } else { 929 ExpressionTree retTypeTree = retTypeKind.isPrimitive() 930 ? maker.Identifier(retType.toString()) 931 : maker.QualIdent( 932 workingCopy.getTypes().asElement(retType)); 933 934 VariableTree expectedValue = maker.Variable( 935 maker.Modifiers(NO_MODIFIERS), 936 EXP_RESULT_VAR_NAME, 937 retTypeTree, 938 getDefaultValue(maker, retType)); 939 VariableTree actualValue = maker.Variable( 940 maker.Modifiers(NO_MODIFIERS), 941 RESULT_VAR_NAME, 942 retTypeTree, 943 methodCall); 944 945 List <ExpressionTree> comparisonArgs = new ArrayList <ExpressionTree>(2); 946 comparisonArgs.add(maker.Identifier(expectedValue.getName().toString())); 947 comparisonArgs.add(maker.Identifier(actualValue.getName().toString())); 948 949 MethodInvocationTree comparison = maker.MethodInvocation( 950 Collections.<ExpressionTree>emptyList(), maker.Identifier("assertEquals"), comparisonArgs); 953 StatementTree comparisonStmt = maker.ExpressionStatement( 954 comparison); 955 956 statements.add(expectedValue); 957 statements.add(actualValue); 958 statements.add(comparisonStmt); 959 } 960 } 961 962 977 if (setup.isGenerateDefMethodBody()) { 978 String failMsg = NbBundle.getMessage( 979 TestCreator.class, 980 "TestCreator.variantMethods.defaultFailMsg"); MethodInvocationTree failMethodCall = maker.MethodInvocation( 982 Collections.<ExpressionTree>emptyList(), maker.Identifier("fail"), Collections.<ExpressionTree>singletonList( 985 maker.Literal(failMsg))); 986 statements.add(maker.ExpressionStatement(failMethodCall)); 987 } 988 989 return maker.Block(statements, false); 990 } 991 992 994 private StatementTree generateSystemOutPrintln(TreeMaker maker, 995 String arg) { 996 MethodInvocationTree methodInvocation = maker.MethodInvocation( 997 Collections.<ExpressionTree>emptyList(), maker.MemberSelect( 999 maker.MemberSelect( 1000 maker.Identifier("System"), "out"), "println"), Collections.<LiteralTree>singletonList( 1002 maker.Literal(arg))); return maker.ExpressionStatement(methodInvocation); 1004 } 1005 1006 1008 private List <VariableTree> generateParamVariables( 1009 TreeMaker maker, 1010 ExecutableElement srcMethod) { 1011 List <? extends VariableElement> params = srcMethod.getParameters(); 1012 if ((params == null) || params.isEmpty()) { 1013 return Collections.<VariableTree>emptyList(); 1014 } 1015 1016 Set <Modifier> noModifiers = Collections.<Modifier>emptySet(); 1017 List <VariableTree> paramVariables = new ArrayList <VariableTree>(params.size()); 1018 String [] varNames = getTestSkeletonVarNames(params); 1019 int index = 0; 1020 for (VariableElement param : params) { 1021 TypeMirror paramType = param.asType(); 1022 paramVariables.add( 1023 maker.Variable(maker.Modifiers(noModifiers), 1024 varNames[index++], 1025 maker.Type(paramType), 1026 getDefaultValue(maker, paramType))); 1027 } 1028 return paramVariables; 1029 } 1030 1031 1033 private List <IdentifierTree> createIdentifiers( 1034 TreeMaker maker, 1035 List <VariableTree> variables) { 1036 List <IdentifierTree> identifiers; 1037 if (variables.isEmpty()) { 1038 identifiers = Collections.<IdentifierTree>emptyList(); 1039 } else { 1040 identifiers = new ArrayList <IdentifierTree>(variables.size()); 1041 for (VariableTree var : variables) { 1042 identifiers.add(maker.Identifier(var.getName().toString())); 1043 } 1044 } 1045 return identifiers; 1046 } 1047 1048 1068 private String [] getTestSkeletonVarNames( 1069 final List <? extends VariableElement> sourceMethodParams) { 1070 1071 1072 if (sourceMethodParams.isEmpty()) { 1073 return new String [0]; 1074 } 1075 1076 final int count = sourceMethodParams.size(); 1077 String [] varNames = new String [count]; 1078 boolean[] conflicts = new boolean[count]; 1079 boolean issueFound = false; 1080 1081 Set <String > varNamesSet = new HashSet <String >((int) ((count + 2) * 1.4)); 1082 varNamesSet.add(INSTANCE_VAR_NAME); 1083 varNamesSet.add(RESULT_VAR_NAME); 1084 varNamesSet.add(EXP_RESULT_VAR_NAME); 1085 1086 Iterator <? extends VariableElement> it = sourceMethodParams.iterator(); 1087 for (int i = 0; i < count; i++) { 1088 String paramName = it.next().getSimpleName().toString(); 1089 varNames[i] = paramName; 1090 1091 if (paramName == null) { 1092 issueFound = true; 1093 } else if (!varNamesSet.add(paramName)) { 1094 conflicts[i] = true; 1095 issueFound = true; 1096 } else { 1097 conflicts[i] = false; 1098 } 1099 } 1100 1101 if (issueFound) { 1102 for (int i = 0; i < count; i++) { 1103 String paramName; 1104 if (varNames[i] == null) { 1105 paramName = ARTIFICAL_VAR_NAME_BASE + i; 1106 if (varNamesSet.add(paramName)) { 1107 varNames[i] = paramName; 1108 continue; 1109 } else { 1110 conflicts[i] = true; 1111 } 1112 } 1113 if (conflicts[i]) { 1114 String paramNamePrefix = varNames[i] + '_'; 1115 1116 int index = 2; 1117 while (!varNamesSet.add( 1118 paramName = (paramNamePrefix + (index++)))); 1119 varNames[i] = paramName; 1120 } 1121 } 1122 } 1123 1124 return varNames; 1125 } 1126 1127 1129 private ExpressionTree getDefaultValue(TreeMaker maker, 1130 TypeMirror type) { 1131 ExpressionTree defValue; 1132 TypeKind typeKind = type.getKind(); 1133 if (typeKind.isPrimitive()) { 1134 switch (typeKind) { 1135 case BOOLEAN: 1136 defValue = maker.Literal(Boolean.FALSE); 1137 break; 1138 case CHAR: 1139 defValue = maker.Literal(new Character (' ')); 1140 break; 1141 case BYTE: 1142 defValue = maker.Literal(new Byte ((byte) 0)); 1143 break; 1144 case SHORT: 1145 defValue = maker.Literal(new Short ((short) 0)); 1146 break; 1147 case INT: 1148 defValue = maker.Literal(new Integer (0)); 1149 break; 1150 case FLOAT: 1151 defValue = maker.Literal(new Float (0.0F)); 1152 break; 1153 case LONG: 1154 defValue = maker.Literal(new Long (0L)); 1155 break; 1156 case DOUBLE: 1157 defValue = maker.Literal(new Double (0.0)); 1158 break; 1159 default: 1160 assert false : "unknown primitive type"; defValue = maker.Literal(new Integer (0)); 1162 break; 1163 } 1164 } else if ((typeKind == TypeKind.DECLARED) 1165 && type.toString().equals("java.lang.String")) { defValue = maker.Literal(""); } else { 1168 defValue = maker.Literal(null); 1169 } 1170 return defValue; 1171 } 1172 1173 1175 private ExpressionTree generateNoArgConstructorCall(TreeMaker maker, 1176 TypeElement cls) { 1177 return maker.NewClass( 1178 null, Collections.<ExpressionTree>emptyList(), maker.QualIdent(cls), Collections.<ExpressionTree>emptyList(), null); } 1184 1185 1187 private List <ExecutableElement> findTestableMethods(TypeElement classElem) { 1188 List <ExecutableElement> methods 1189 = ElementFilter.methodsIn(classElem.getEnclosedElements()); 1190 1191 if (methods.isEmpty()) { 1192 return Collections.<ExecutableElement>emptyList(); 1193 } 1194 1195 List <ExecutableElement> testableMethods = null; 1196 1197 int skippedCount = 0; 1198 for (ExecutableElement method : methods) { 1199 if (isTestableMethod(method)) { 1200 if (testableMethods == null) { 1201 testableMethods = new ArrayList <ExecutableElement>( 1202 methods.size() - skippedCount); 1203 } 1204 testableMethods.add(method); 1205 } else { 1206 skippedCount++; 1207 } 1208 } 1209 1210 return (testableMethods != null) 1211 ? testableMethods 1212 : Collections.<ExecutableElement>emptyList(); 1213 } 1214 1215 1217 private boolean isTestableMethod(ExecutableElement method) { 1218 if (method.getKind() != ElementKind.METHOD) { 1219 throw new IllegalArgumentException (); 1220 } 1221 1222 return setup.isMethodTestable(method); 1223 } 1224 1225 1227 protected boolean hasAccessibleNoArgConstructor(TypeElement srcClass) { 1228 boolean answer; 1229 1230 List <ExecutableElement> constructors 1231 = ElementFilter.constructorsIn(srcClass.getEnclosedElements()); 1232 1233 if (constructors.isEmpty()) { 1234 answer = true; } else { 1236 answer = false; 1237 for (ExecutableElement constructor : constructors) { 1238 if (constructor.getParameters().isEmpty()) { 1239 answer = !constructor.getModifiers().contains(Modifier.PRIVATE); 1240 break; 1241 } 1242 } 1243 } 1244 return answer; 1245 } 1246 1247 1249 private boolean throwsNonRuntimeExceptions(CompilationInfo compInfo, 1250 ExecutableElement method) { 1251 List <? extends TypeMirror> thrownTypes = method.getThrownTypes(); 1252 if (thrownTypes.isEmpty()) { 1253 return false; 1254 } 1255 1256 String runtimeExcName = "java.lang.RuntimeException"; TypeElement runtimeExcElement = compInfo.getElements() 1258 .getTypeElement(runtimeExcName); 1259 if (runtimeExcElement == null) { 1260 Logger.getLogger("junit").log( Level.WARNING, 1262 "Could not find TypeElement for " + runtimeExcName); 1264 return true; 1265 } 1266 1267 Types types = compInfo.getTypes(); 1268 TypeMirror runtimeExcType = runtimeExcElement.asType(); 1269 for (TypeMirror exceptionType : thrownTypes) { 1270 if (!types.isSubtype(exceptionType, runtimeExcType)) { 1271 return true; 1272 } 1273 } 1274 1275 return false; 1276 } 1277 1278 1280 private <T extends Element> List <T> resolveHandles( 1281 CompilationInfo compInfo, 1282 List <ElementHandle<T>> handles) { 1283 if (handles == null) { 1284 return null; 1285 } 1286 if (handles.isEmpty()) { 1287 return Collections.<T>emptyList(); 1288 } 1289 1290 List <T> elements = new ArrayList <T>(handles.size()); 1291 for (ElementHandle<T> handle : handles) { 1292 elements.add(handle.resolve(compInfo)); 1293 } 1294 return elements; 1295 } 1296 1297 1300 public void cancel() { 1301 cancelled = true; 1302 } 1303 1304 1306 private void classProcessed(ClassTree cls) { 1307 if (processedClassNames == null) { 1308 processedClassNames = new ArrayList <String >(4); 1309 } 1310 processedClassNames.add(cls.getSimpleName().toString()); 1311 } 1312 1313 1315 List <String > getProcessedClassNames() { 1316 return processedClassNames != null 1317 ? processedClassNames 1318 : Collections.<String >emptyList(); 1319 } 1320 1321 1322 1323 1343 1345 private String getInitialMainMethodBody() { 1346 if (initialMainMethodBody == null) { 1347 initialMainMethodBody = JUnitSettings.getDefault() 1348 .getGenerateMainMethodBody(); 1349 if (initialMainMethodBody == null) { 1350 1354 initialMainMethodBody = ""; } 1356 } 1357 return initialMainMethodBody; 1358 } 1359 1360 1367 static Set <Modifier> createModifierSet(Modifier... modifiers) { 1368 EnumSet <Modifier> modifierSet = EnumSet.noneOf(Modifier.class); 1369 for (Modifier m : modifiers) { 1370 modifierSet.add(m); 1371 } 1372 return modifierSet; 1373 } 1374 1375} 1376 | Popular Tags |