Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some cleanup #120

Merged
merged 3 commits into from
Nov 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
*/
public abstract class AbstractTool<T> {

protected static final String ORG_JUNIT_CLASS_RULE= "org.junit.ClassRule";
private static final String ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_ALL_CALLBACK= "org.junit.jupiter.api.extension.AfterAllCallback";
private static final String ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_ALL_CALLBACK= "org.junit.jupiter.api.extension.BeforeAllCallback";
private static final String AFTER_ALL_CALLBACK= "AfterAllCallback";
Expand Down Expand Up @@ -129,7 +130,6 @@
protected static final String ORG_JUNIT_JUPITER_API_ASSUMPTIONS= "org.junit.jupiter.api.Assumptions";
protected static final String ORG_JUNIT_ASSUME= "org.junit.Assume";
protected static final String ASSUMPTIONS= "Assumptions";
protected static final String ORG_JUNIT_CLASS_RULE= "org.junit.ClassRule";

public static Collection<String> getUsedVariableNames(ASTNode node) {
CompilationUnit root= (CompilationUnit) node.getRoot();
Expand Down Expand Up @@ -217,7 +217,7 @@

private void adaptExternalResourceHierarchy(ITypeBinding typeBinding, ASTRewrite rewrite, AST ast,
ImportRewrite importRewrite, TextEditGroup group) {
while (typeBinding != null && isExternalResource(typeBinding)) {
while (typeBinding != null && isExternalResource(typeBinding, ORG_JUNIT_RULES_EXTERNAL_RESOURCE)) {
TypeDeclaration typeDecl= findTypeDeclarationInProject(typeBinding);
if (typeDecl != null) {
adaptTypeDeclaration(typeDecl, rewrite, ast, importRewrite, group);
Expand Down Expand Up @@ -287,33 +287,25 @@

private boolean shouldProcessNode(TypeDeclaration node) {
ITypeBinding binding= node.resolveBinding();
return binding != null && isExternalResource(binding);
return binding != null && isExternalResource(binding, ORG_JUNIT_RULES_EXTERNAL_RESOURCE);
}

private void processBeforeMethod(MethodDeclaration method, ASTRewrite rewriter, AST ast, TextEditGroup group,
ImportRewrite importRewriter) {
private void processMethod(MethodDeclaration method, ASTRewrite rewriter, AST ast, TextEditGroup group,
ImportRewrite importRewriter, String methodname, String methodnamejunit5) {
setPublicVisibilityIfProtected(method, rewriter, ast, group);
adaptSuperBeforeCalls(METHOD_BEFORE, METHOD_BEFORE_EACH, method, rewriter, ast, group);
adaptSuperBeforeCalls(methodname, methodnamejunit5, method, rewriter, ast, group);
removeThrowsThrowable(method, rewriter, group);
rewriter.replace(method.getName(), ast.newSimpleName(METHOD_BEFORE_EACH), group);
ensureExtensionContextParameter(method, rewriter, ast, group, importRewriter);
}

private void processAfterMethod(MethodDeclaration method, ASTRewrite rewriter, AST ast, TextEditGroup group,
ImportRewrite importRewriter) {
setPublicVisibilityIfProtected(method, rewriter, ast, group);
adaptSuperBeforeCalls(METHOD_AFTER, METHOD_AFTER_EACH, method, rewriter, ast, group);
rewriter.replace(method.getName(), ast.newSimpleName(METHOD_AFTER_EACH), group);
rewriter.replace(method.getName(), ast.newSimpleName(methodnamejunit5), group);
ensureExtensionContextParameter(method, rewriter, ast, group, importRewriter);
}

private void updateLifecycleMethodsInClass(TypeDeclaration node, ASTRewrite rewriter, AST ast, TextEditGroup group,
ImportRewrite importRewriter) {
for (MethodDeclaration method : node.getMethods()) {
if (isLifecycleMethod(method, METHOD_BEFORE)) {
processBeforeMethod(method, rewriter, ast, group, importRewriter);
processMethod(method, rewriter, ast, group, importRewriter, METHOD_BEFORE, METHOD_BEFORE_EACH);
} else if (isLifecycleMethod(method, METHOD_AFTER)) {
processAfterMethod(method, rewriter, ast, group, importRewriter);
processMethod(method, rewriter, ast, group, importRewriter, METHOD_AFTER,METHOD_AFTER_EACH);
}
}
}
Expand All @@ -337,77 +329,81 @@
importRewrite.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_EACH_CALLBACK);
}

private boolean isUsedAsClassRule(TypeDeclaration node, String annotationclass) {
ITypeBinding typeBinding = node.resolveBinding();
if (typeBinding == null) {
return false;
}

CompilationUnit cu = (CompilationUnit) node.getRoot();
if (cu == null) {
return false;
}
final boolean[] isClassRule = {false};

cu.accept(new ASTVisitor() {
@Override
public boolean visit(FieldDeclaration fieldDeclaration) {
// Prüfe, ob das Feld mit @ClassRule annotiert ist
boolean hasClassRuleAnnotation = fieldDeclaration.modifiers().stream()
.filter(modifier -> modifier instanceof Annotation) // Sicherstellen, dass es sich um eine Annotation handelt
.map(modifier -> (Annotation) modifier) // Cast zu Annotation
.anyMatch(annotation -> {
String annotationBinding = ((Annotation) annotation).getTypeName().getFullyQualifiedName();

return annotationBinding != null && annotationclass.equals(annotationBinding);
});

// Prüfe, ob das Feld vom Typ der aktuellen Klasse ist
if (hasClassRuleAnnotation) {
Type fieldType = fieldDeclaration.getType();
if (fieldType.resolveBinding() != null && fieldType.resolveBinding().isEqualTo(typeBinding)) {
isClassRule[0] = true;
}
}
return super.visit(fieldDeclaration);
}
});

return isClassRule[0];
private boolean isUsedAsClassRule(TypeDeclaration node, String annotationclass) {
ITypeBinding typeBinding= node.resolveBinding();
if (typeBinding == null) {
return false;
}

CompilationUnit cu= (CompilationUnit) node.getRoot();
if (cu == null) {
return false;
}
final boolean[] isClassRule= { false };

cu.accept(new ASTVisitor() {
@Override
public boolean visit(FieldDeclaration fieldDeclaration) {
// Prüfe, ob das Feld mit @ClassRule annotiert ist
boolean hasClassRuleAnnotation= fieldDeclaration.modifiers().stream()
.filter(modifier -> modifier instanceof Annotation) // Sicherstellen, dass es sich um eine
// Annotation handelt
.map(modifier -> (Annotation) modifier) // Cast zu Annotation
.anyMatch(annotation -> {
String annotationBinding= ((Annotation) annotation).getTypeName().getFullyQualifiedName();

return annotationBinding != null && annotationclass.equals(annotationBinding);

Check warning

Code scanning / PMD

Invoke equals() on the object you've already ensured is not null Warning

Invoke equals() on the object you've already ensured is not null
});

// Prüfe, ob das Feld vom Typ der aktuellen Klasse ist
if (hasClassRuleAnnotation) {
Type fieldType= fieldDeclaration.getType();
if (fieldType.resolveBinding() != null && fieldType.resolveBinding().isEqualTo(typeBinding)) {
isClassRule[0]= true;
}
}
return super.visit(fieldDeclaration);
}
});

return isClassRule[0];
}

private void refactorToImplementCallbacks(TypeDeclaration node, ASTRewrite rewriter, AST ast, TextEditGroup group,
ImportRewrite importRewriter) {
// Entferne die Superklasse ExternalResource
rewriter.remove(node.getSuperclassType(), group);
importRewriter.removeImport(ORG_JUNIT_RULES_EXTERNAL_RESOURCE);

// Prüfe, ob die Klasse statisch verwendet wird
boolean isStaticUsage = isUsedAsClassRule(node, "org.junit.ClassRule");

ListRewrite listRewrite = rewriter.getListRewrite(node, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY);

// Füge die entsprechenden Callback-Interfaces hinzu
if (isStaticUsage) {
// Verwende BeforeAllCallback und AfterAllCallback für statische Ressourcen
addInterfaceCallback(listRewrite, ast, BEFORE_ALL_CALLBACK, group);
addInterfaceCallback(listRewrite, ast, AFTER_ALL_CALLBACK, group);
importRewriter.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_ALL_CALLBACK);
importRewriter.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_ALL_CALLBACK);
} else {
// Verwende BeforeEachCallback und AfterEachCallback für nicht-statische Ressourcen
addInterfaceCallback(listRewrite, ast, BEFORE_EACH_CALLBACK, group);
addInterfaceCallback(listRewrite, ast, AFTER_EACH_CALLBACK, group);
importRewriter.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_EACH_CALLBACK);
importRewriter.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_EACH_CALLBACK);
}
ImportRewrite importRewriter) {
// Entferne die Superklasse ExternalResource
rewriter.remove(node.getSuperclassType(), group);
importRewriter.removeImport(ORG_JUNIT_RULES_EXTERNAL_RESOURCE);

// Prüfe, ob die Klasse statisch verwendet wird
boolean isStaticUsage= isUsedAsClassRule(node, ORG_JUNIT_CLASS_RULE);

ListRewrite listRewrite= rewriter.getListRewrite(node, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY);

// Füge die entsprechenden Callback-Interfaces hinzu
if (isStaticUsage) {
// Verwende BeforeAllCallback und AfterAllCallback für statische Ressourcen
addInterfaceCallback(listRewrite, ast, BEFORE_ALL_CALLBACK, group, importRewriter,
ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_ALL_CALLBACK);
addInterfaceCallback(listRewrite, ast, AFTER_ALL_CALLBACK, group, importRewriter,
ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_ALL_CALLBACK);
} else {
// Verwende BeforeEachCallback und AfterEachCallback für nicht-statische
// Ressourcen
addInterfaceCallback(listRewrite, ast, BEFORE_EACH_CALLBACK, group, importRewriter,
ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_EACH_CALLBACK);
addInterfaceCallback(listRewrite, ast, AFTER_EACH_CALLBACK, group, importRewriter,
ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_EACH_CALLBACK);
}
}

private void addBeforeAndAfterEachCallbacks(TypeDeclaration typeDecl, ASTRewrite rewrite, AST ast,
ImportRewrite importRewrite, TextEditGroup group) {
ListRewrite listRewrite= rewrite.getListRewrite(typeDecl, TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY);
listRewrite.insertLast(ast.newSimpleType(ast.newName(BEFORE_EACH_CALLBACK)), group);
listRewrite.insertLast(ast.newSimpleType(ast.newName(AFTER_EACH_CALLBACK)), group);
addInterfaceCallback(listRewrite, ast, BEFORE_EACH_CALLBACK, group, importRewrite,
ORG_JUNIT_JUPITER_API_EXTENSION_BEFORE_EACH_CALLBACK);
addInterfaceCallback(listRewrite, ast, AFTER_EACH_CALLBACK, group, importRewrite,
ORG_JUNIT_JUPITER_API_EXTENSION_AFTER_EACH_CALLBACK);
}

private void adaptSuperBeforeCalls(String vorher, String nachher, MethodDeclaration method, ASTRewrite rewriter,
Expand Down Expand Up @@ -463,7 +459,8 @@
}
}

private void addInterfaceCallback(ListRewrite listRewrite, AST ast, String callbackName, TextEditGroup group) {
private void addInterfaceCallback(ListRewrite listRewrite, AST ast, String callbackName, TextEditGroup group,
ImportRewrite importRewriter, String classtoimport) {
// Prüfen, ob das Interface bereits in der Liste existiert
boolean hasCallback= listRewrite.getRewrittenList().stream().anyMatch(type -> type instanceof SimpleType
&& ((SimpleType) type).getName().getFullyQualifiedName().equals(callbackName));
Expand All @@ -472,6 +469,7 @@
// Interface hinzufügen, wenn es noch nicht existiert
listRewrite.insertLast(ast.newSimpleType(ast.newName(callbackName)), group);
}
importRewriter.addImport(classtoimport);
}

private void addRegisterExtensionAnnotation(FieldDeclaration field, ASTRewrite rewrite, AST ast,
Expand Down Expand Up @@ -502,8 +500,8 @@

// Prüfen, ob ExtensionContext bereits existiert (im AST oder im Rewrite)
boolean hasExtensionContext= method.parameters().stream()
.anyMatch(param -> param instanceof SingleVariableDeclaration
&& isExtensionContext((SingleVariableDeclaration) param))
.anyMatch(param -> param instanceof SingleVariableDeclaration && isExtensionContext(
(SingleVariableDeclaration) param, ORG_JUNIT_JUPITER_API_EXTENSION_EXTENSION_CONTEXT))
|| rewrite.getListRewrite(method, MethodDeclaration.PARAMETERS_PROPERTY).getRewrittenList().stream()
.anyMatch(param -> param instanceof SingleVariableDeclaration
&& ((SingleVariableDeclaration) param).getType().toString().equals(EXTENSION_CONTEXT));
Expand All @@ -522,9 +520,9 @@
}

// Hilfsmethode zum Vergleich des Typs
private boolean isExtensionContext(SingleVariableDeclaration param) {
private boolean isExtensionContext(SingleVariableDeclaration param, String classname) {
ITypeBinding binding= param.getType().resolveBinding();
return binding != null && ORG_JUNIT_JUPITER_API_EXTENSION_EXTENSION_CONTEXT.equals(binding.getQualifiedName());
return binding != null && classname.equals(binding.getQualifiedName());
}

public String extractClassNameFromField(FieldDeclaration field) {
Expand Down Expand Up @@ -632,15 +630,15 @@
return ORG_JUNIT_RULES_EXTERNAL_RESOURCE.equals(binding.getSuperclass().getQualifiedName());
}

private boolean isExternalResource(FieldDeclaration field) {
private boolean isExternalResource(FieldDeclaration field, String typetolookup) {
VariableDeclarationFragment fragment= (VariableDeclarationFragment) field.fragments().get(0);
ITypeBinding binding= fragment.resolveBinding().getType();
return isExternalResource(binding);
return isExternalResource(binding, typetolookup);
}

protected boolean isExternalResource(ITypeBinding typeBinding) {
protected boolean isExternalResource(ITypeBinding typeBinding, String typetolookup) {
while (typeBinding != null) {
if (ORG_JUNIT_RULES_EXTERNAL_RESOURCE.equals(typeBinding.getQualifiedName())) {
if (typetolookup.equals(typeBinding.getQualifiedName())) {
return true;
}
typeBinding= typeBinding.getSuperclass();
Expand All @@ -652,9 +650,9 @@
return method.getName().getIdentifier().equals(methodName);
}

private boolean isStringType(Expression expression) {
private boolean isStringType(Expression expression, Class<String> class1) {
ITypeBinding typeBinding= expression.resolveTypeBinding();
return typeBinding != null && String.class.getCanonicalName().equals(typeBinding.getQualifiedName());
return typeBinding != null && class1.getCanonicalName().equals(typeBinding.getQualifiedName());
}

public void migrateRuleToRegisterExtensionAndAdaptHierarchy(Optional<ASTNode> innerTypeDeclaration,
Expand All @@ -665,17 +663,16 @@
group);
}
for (FieldDeclaration field : testClass.getFields()) {
if (isAnnotatedWithRule(field, ORG_JUNIT_RULE) && isExternalResource(field)) {
if (isAnnotatedWithRule(field, ORG_JUNIT_RULE) && isExternalResource(field, ORG_JUNIT_RULES_EXTERNAL_RESOURCE)) {
removeRuleAnnotation(field, rewrite, group, importRewrite, ORG_JUNIT_RULE);
addRegisterExtensionAnnotation(field, rewrite, ast, importRewrite, group);
importRewrite.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_REGISTER_EXTENSION);
ITypeBinding fieldType= ((VariableDeclarationFragment) field.fragments().get(0)).resolveBinding()
.getType();
adaptExternalResourceHierarchy(fieldType, rewrite, ast, importRewrite, group);
} else if (isAnnotatedWithRule(field, ORG_JUNIT_CLASS_RULE) && isExternalResource(field)) {
} else if (isAnnotatedWithRule(field, ORG_JUNIT_CLASS_RULE) && isExternalResource(field, ORG_JUNIT_RULES_EXTERNAL_RESOURCE)) {
removeRuleAnnotation(field, rewrite, group, importRewrite, ORG_JUNIT_CLASS_RULE);
addRegisterExtensionAnnotation(field, rewrite, ast, importRewrite, group);
importRewrite.addImport(ORG_JUNIT_JUPITER_API_EXTENSION_REGISTER_EXTENSION);
ITypeBinding fieldType= ((VariableDeclarationFragment) field.fragments().get(0)).resolveBinding()
.getType();
adaptExternalResourceHierarchy(fieldType, rewrite, ast, importRewrite, group);
Expand All @@ -699,7 +696,7 @@
FieldDeclaration field= (FieldDeclaration) node.getParent();
ITypeBinding fieldTypeBinding= ((VariableDeclarationFragment) field.fragments().get(0)).resolveBinding()
.getType();
if (!isExternalResource(fieldTypeBinding) || fieldTypeBinding.isAnonymous()) {
if (!isExternalResource(fieldTypeBinding, ORG_JUNIT_RULES_EXTERNAL_RESOURCE) || fieldTypeBinding.isAnonymous()) {
return;
}
if (isDirect(fieldTypeBinding)) {
Expand Down Expand Up @@ -753,7 +750,7 @@
for (int i= 0; i < order.length; i++) {
newArguments[i]= (Expression) ASTNode.copySubtree(node.getAST(), arguments.get(order[i]));
}
if (!isStringType(arguments.get(0))) {
if (!isStringType(arguments.get(0), String.class)) {
return;
}
for (int i= 0; i < arguments.size(); i++) {
Expand Down
Loading