check annotations if they contain given meta annotations

This commit is contained in:
Anna.Kozlova
2016-10-25 14:14:57 +02:00
parent b5efcf9fc7
commit e9a202cedf
2 changed files with 52 additions and 67 deletions
@@ -16,6 +16,7 @@
package com.intellij.execution.junit;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.MetaAnnotationUtil;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.execution.*;
import com.intellij.execution.junit2.info.MethodLocation;
@@ -25,22 +26,17 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.*;
import com.intellij.testIntegration.JavaTestFramework;
import com.intellij.testIntegration.TestFramework;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
public class JUnitUtil {
@@ -225,11 +221,11 @@ public class JUnitUtil {
if (module != null) {
for (final PsiMethod method : psiClass.getAllMethods()) {
ProgressManager.checkCanceled();
if (isMetaAnnotated(method, TEST5_ANNOTATIONS)) return true;
if (MetaAnnotationUtil.isMetaAnnotated(method, TEST5_ANNOTATIONS)) return true;
}
for (PsiClass aClass : psiClass.getInnerClasses()) {
if (isMetaAnnotated(aClass, Collections.singleton(JUNIT5_NESTED))) return true;
if (MetaAnnotationUtil.isMetaAnnotated(aClass, Collections.singleton(JUNIT5_NESTED))) return true;
}
}
@@ -262,64 +258,9 @@ public class JUnitUtil {
return true;
}
return isMetaAnnotated(method, TEST5_ANNOTATIONS);
return MetaAnnotationUtil.isMetaAnnotated(method, TEST5_ANNOTATIONS);
}
private static final ConcurrentMap<String, Key<CachedValue>> annotationsKeyForProvider = ContainerUtil.newConcurrentMap();
@NotNull
private static Key<CachedValue<Boolean>> getKeyForAnnotations(Collection<String> annotations) {
String name = StringUtil.join(annotations, ", ");
Key<CachedValue> key = annotationsKeyForProvider.get(name);
if (key == null) {
key = ConcurrencyUtil.cacheOrGet(annotationsKeyForProvider, name, Key.<CachedValue>create(name));
}
//noinspection unchecked
return (Key)key;
}
private static boolean isMetaAnnotated(PsiModifierListOwner listOwner, final Collection<String> annotations) {
if (AnnotationUtil.isAnnotated(listOwner, annotations, false)) {
return true;
}
PsiModifierList modifierList = listOwner.getModifierList();
if (modifierList != null) {
for (PsiAnnotation annotation : modifierList.getApplicableAnnotations()) {
PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
if (nameReferenceElement != null) {
PsiElement resolve = nameReferenceElement.resolve();
if (resolve instanceof PsiClass) {
Boolean annotated = CachedValuesManager.getManager(listOwner.getProject()).getCachedValue(resolve, getKeyForAnnotations(annotations), () -> new CachedValueProvider.Result<>(
isTestAnnotatedAnnotation((PsiClass)resolve, new HashSet<>(), annotations), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT), false);
if (annotated != null && annotated) return true;
}
}
}
}
return false;
}
private static boolean isTestAnnotatedAnnotation(PsiClass aClass, final Set<PsiClass> visited, final Collection<String> annotations) {
if (AnnotationUtil.isAnnotated(aClass, annotations, false)) {
return true;
}
PsiModifierList modifierList = aClass.getModifierList();
if (modifierList != null) {
for (PsiAnnotation psiAnnotation : modifierList.getApplicableAnnotations()) {
PsiJavaCodeReferenceElement nameReferenceElement = psiAnnotation.getNameReferenceElement();
if (nameReferenceElement != null) {
PsiElement resolve = nameReferenceElement.resolve();
if (resolve instanceof PsiClass && visited.add((PsiClass)resolve) &&
((PsiClass)resolve).isAnnotationType() &&
isTestAnnotatedAnnotation((PsiClass)resolve, visited, annotations)) {
return true;
}
}
}
}
return false;
}
@Nullable
private static PsiClass getTestCaseClassOrNull(final Location<?> location) {