<commit_before>package ru.artyushov.jmhPlugin.inspection;

import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.codeInspection.AbstractBaseUastLocalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.uast.UClass;
import org.jetbrains.uast.UMethod;

import static com.intellij.codeInspection.ProblemHighlightType.ERROR;
import static com.intellij.psi.PsiModifier.PUBLIC;
import static com.intellij.psi.PsiType.VOID;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.JMH_ANNOTATION_STATE;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasBenchmarkAnnotation;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasSetupOrTearDownAnnotation;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasStateAnnotation;

public class JmhBenchMethodInvalidSignatureInspection extends AbstractBaseUastLocalInspectionTool {
    private static final LocalQuickFix BENCH_METHOD_QUICK_FIX = new BenchMethodSignatureFix();

    @Override
    public @Nullable ProblemDescriptor[] checkClass(@NotNull UClass aClass, @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)) {
                isBenchmarkClass = true;
                ProblemDescriptor[] problem = checkPublicModifier(method, manager, isOnTheFly);
                if (problem != null) return problem;
                problem = checkSetupTearDownIsNotVoid(method, manager, isOnTheFly);
                if (problem != null) return 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);
                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);
            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);
            return new ProblemDescriptor[]{problem};
        }
        return null;
    }
}<commit_msg>#33 Inspections<commit_after>package ru.artyushov.jmhPlugin.inspection;

import com.intellij.codeInsight.intention.AddAnnotationFix;
import com.intellij.codeInspection.AbstractBaseUastLocalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
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;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasBenchmarkAnnotation;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasSetupOrTearDownAnnotation;
import static ru.artyushov.jmhPlugin.configuration.ConfigurationUtils.hasStateAnnotation;

public class JmhBenchMethodInvalidSignatureInspection extends AbstractBaseUastLocalInspectionTool {
    private static final LocalQuickFix BENCH_METHOD_QUICK_FIX = new BenchMethodSignatureFix();

    @Override
    public @Nullable ProblemDescriptor[] checkClass(@NotNull UClass klass, @NotNull InspectionManager manager, boolean isOnTheFly) {
        boolean isBenchmarkClass = false;
        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;
                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) {
            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};
            }
        }

        // 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};
        }

        if (klass.isFinal()) {
            ProblemDescriptor problem = manager.createProblemDescriptor(klass, "Benchmark classes should not be final", (LocalQuickFix) null, ERROR, isOnTheFly);
            return new ProblemDescriptor[]{problem};
        }

        return null;
    }

}
{'fraction_non_alphanumeric': 0.08104395604395605, 'fraction_numerical': 0.0003746253746253746, 'mean_word_length': 3.4743016759776535, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3960455', 'n_tokens_mistral': 2165, 'n_tokens_neox': 2061, 'n_words': 443}