Skip to content

Commit

Permalink
#33 Inspections
Browse files Browse the repository at this point in the history
  • Loading branch information
stokito committed Oct 21, 2020
1 parent 42e52a2 commit 39e7f52
Showing 1 changed file with 43 additions and 28 deletions.
Expand Up @@ -8,9 +8,13 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UField;
import org.jetbrains.uast.UMethod;

import java.util.Objects;

import static com.intellij.codeInspection.ProblemHighlightType.ERROR;
import static com.intellij.psi.PsiModifier.ABSTRACT;
import static com.intellij.psi.PsiModifier.PUBLIC;
import static com.intellij.psi.PsiType.VOID;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.JMH_ANNOTATION_STATE;
Expand All @@ -22,48 +26,59 @@ public class JmhBenchMethodInvalidSignatureInspection extends AbstractBaseUastLo
private static final LocalQuickFix BENCH_METHOD_QUICK_FIX = new BenchMethodSignatureFix();

@Override
public @Nullable ProblemDescriptor[] checkClass(@NotNull UClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
public @Nullable ProblemDescriptor[] checkClass(@NotNull UClass klass, @NotNull InspectionManager manager, boolean isOnTheFly) {
boolean isBenchmarkClass = false;
final UMethod[] methods = aClass.getMethods();
for (final UMethod method : methods) {
if (hasBenchmarkAnnotation(method)) {
isBenchmarkClass = true;
ProblemDescriptor[] problem = checkPublicModifier(method, manager, isOnTheFly);
if (problem != null) return problem;
} else if (hasSetupOrTearDownAnnotation(method)) {
UMethod[] methods = klass.getMethods();
for (UMethod method : methods) {
boolean hasBenchmarkAnnotation = hasBenchmarkAnnotation(method);
boolean hasSetupOrTearDownAnnotation = false;
if (!hasBenchmarkAnnotation) {
hasSetupOrTearDownAnnotation = hasSetupOrTearDownAnnotation(method);
if (hasSetupOrTearDownAnnotation) {
// Check that Setup or TearDown is void
if ((method.getReturnType() == null || !method.getReturnType().equals(VOID))) {
ProblemDescriptor problem = manager.createProblemDescriptor(method, "@Setup or @TearDown method should not return anything", BENCH_METHOD_QUICK_FIX, ERROR, isOnTheFly);
return new ProblemDescriptor[]{problem};
}
}
}
if (hasBenchmarkAnnotation || hasSetupOrTearDownAnnotation) {
isBenchmarkClass = true;
ProblemDescriptor[] problem = checkPublicModifier(method, manager, isOnTheFly);
if (problem != null) return problem;
problem = checkSetupTearDownIsNotVoid(method, manager, isOnTheFly);
if (problem != null) return problem;
if (!method.hasModifierProperty(PUBLIC)) {
ProblemDescriptor problem = manager.createProblemDescriptor(method, "@Benchmark method should be public", BENCH_METHOD_QUICK_FIX, ERROR, isOnTheFly);
return new ProblemDescriptor[]{problem};
}
}
}

if (isBenchmarkClass && !hasStateAnnotation(aClass)) {
if (aClass.getFields().length > 0) {
AddAnnotationFix addAnnotationFix = new AddAnnotationFix(JMH_ANNOTATION_STATE, aClass);
ProblemDescriptor problem = manager.createProblemDescriptor(aClass, "@State missing", addAnnotationFix, ERROR, isOnTheFly);
if (!isBenchmarkClass) {
return null;
}
boolean explicitState = hasStateAnnotation(klass);
// validate against rogue fields
if (!explicitState || klass.hasModifierProperty(ABSTRACT)) {
for (UField field : klass.getFields()) {
// allow static fields
if (field.isStatic()) continue;
AddAnnotationFix addAnnotationFix = new AddAnnotationFix(JMH_ANNOTATION_STATE, klass);
ProblemDescriptor problem = manager.createProblemDescriptor(field, "Field is declared within the class not having @State annotation", addAnnotationFix, ERROR, isOnTheFly);
return new ProblemDescriptor[]{problem};
}
}
return null;
}

@Nullable
private ProblemDescriptor[] checkPublicModifier(@NotNull UMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
if (!method.hasModifierProperty(PUBLIC)) {
ProblemDescriptor problem = manager.createProblemDescriptor(method, "@Benchmark method should be public", BENCH_METHOD_QUICK_FIX, ERROR, isOnTheFly);
// if this is a default package
if (Objects.equals(klass.getName(), klass.getQualifiedName())) {
// QuickFixFactory.getInstance().createCreateClassOrPackageFix(aClass, "@State missing", )
ProblemDescriptor problem = manager.createProblemDescriptor(klass, "Benchmark class should have package other than default", (LocalQuickFix) null, ERROR, isOnTheFly);
return new ProblemDescriptor[]{problem};
}
return null;
}

@Nullable
private ProblemDescriptor[] checkSetupTearDownIsNotVoid(@NotNull UMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
if ((method.getReturnType() == null || !method.getReturnType().equals(VOID))) {
ProblemDescriptor problem = manager.createProblemDescriptor(method, "@Setup and @TearDown method should return void", BENCH_METHOD_QUICK_FIX, ERROR, isOnTheFly);
if (klass.isFinal()) {
ProblemDescriptor problem = manager.createProblemDescriptor(klass, "Benchmark classes should not be final", (LocalQuickFix) null, ERROR, isOnTheFly);
return new ProblemDescriptor[]{problem};
}

return null;
}

}

0 comments on commit 39e7f52

Please sign in to comment.