mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java] Consider @Blocking and @NonBlocking on classes in BlockingMethodInNonBlockingContextInspection
GitOrigin-RevId: d3a486b85659c78901a326f08ebadeadd8e656ab
This commit is contained in:
committed by
intellij-monorepo-bot
parent
5ec97fe500
commit
9d7c5caf91
@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(value = ElementType.METHOD)
|
||||
@Retention(value = RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface Blocking {
|
||||
}
|
||||
@@ -5,6 +5,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(value = ElementType.METHOD)
|
||||
@Retention(value = RetentionPolicy.CLASS)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
public @interface NonBlocking {}
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.NonBlocking;
|
||||
|
||||
public class TestClassAnnotationsDetection {
|
||||
@NonBlocking
|
||||
private static void nonBlocking(BlockingApiClass blockingApi, NonBlockingApiClass nonBlockingApi) {
|
||||
blockingApi.<warning descr="Possibly blocking call in non-blocking context could lead to thread starvation">runBlocking</warning>();
|
||||
blockingApi.runNonBlocking();
|
||||
|
||||
nonBlockingApi.<warning descr="Possibly blocking call in non-blocking context could lead to thread starvation">runBlocking</warning>();
|
||||
nonBlockingApi.runNonBlocking();
|
||||
}
|
||||
}
|
||||
|
||||
@Blocking
|
||||
class BlockingApiClass {
|
||||
public void runBlocking() { }
|
||||
|
||||
@NonBlocking
|
||||
public void runNonBlocking() { }
|
||||
}
|
||||
|
||||
@NonBlocking
|
||||
class NonBlockingApiClass {
|
||||
@Blocking
|
||||
public void runBlocking() { }
|
||||
|
||||
public void runNonBlocking() { }
|
||||
}
|
||||
+14
-2
@@ -6,6 +6,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@@ -21,9 +22,20 @@ public interface BlockingMethodChecker {
|
||||
*/
|
||||
boolean isApplicable(@NotNull PsiFile file);
|
||||
|
||||
boolean isMethodBlocking(@NotNull PsiMethod method);
|
||||
/**
|
||||
* @deprecated Override {@link #isMethodBlocking(MethodContext)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2022.1")
|
||||
default boolean isMethodBlocking(@NotNull PsiMethod method) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isMethodNonBlocking(@NotNull PsiMethod method) {
|
||||
default boolean isMethodBlocking(@NotNull MethodContext methodContext) {
|
||||
return isMethodBlocking(methodContext.getMethod());
|
||||
}
|
||||
|
||||
default boolean isMethodNonBlocking(@NotNull MethodContext methodContext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInspection.blockingCallsDetection;
|
||||
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public final class MethodContext {
|
||||
|
||||
private final PsiMethod myMethod;
|
||||
private final List<BlockingMethodChecker> myCheckers;
|
||||
|
||||
public MethodContext(@NotNull PsiMethod method, @NotNull List<BlockingMethodChecker> checkers) {
|
||||
myMethod = method;
|
||||
myCheckers = checkers;
|
||||
}
|
||||
|
||||
public @NotNull PsiMethod getMethod() {
|
||||
return myMethod;
|
||||
}
|
||||
|
||||
public @NotNull List<BlockingMethodChecker> getCheckers() {
|
||||
return myCheckers;
|
||||
}
|
||||
|
||||
public boolean isMethodNonBlocking() {
|
||||
for (BlockingMethodChecker checker : myCheckers) {
|
||||
if (checker.isMethodNonBlocking(this)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+32
-15
@@ -3,39 +3,56 @@ package com.intellij.codeInspection.blockingCallsDetection;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import one.util.streamex.StreamEx;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.codeInspection.blockingCallsDetection.BlockingMethodInNonBlockingContextInspection.DEFAULT_BLOCKING_ANNOTATIONS;
|
||||
import java.util.Collection;
|
||||
|
||||
public final class AnnotationBasedBlockingMethodChecker implements BlockingMethodChecker {
|
||||
private final List<String> myBlockingAnnotations;
|
||||
private final List<String> myNonBlockingAnnotations;
|
||||
private final Collection<String> myBlockingAnnotations;
|
||||
private final Collection<String> myNonBlockingAnnotations;
|
||||
|
||||
public AnnotationBasedBlockingMethodChecker(List<String> blockingAnnotations, List<String> nonBlockingAnnotations) {
|
||||
public AnnotationBasedBlockingMethodChecker(@NotNull Collection<String> blockingAnnotations,
|
||||
@NotNull Collection<String> nonBlockingAnnotations) {
|
||||
myBlockingAnnotations = blockingAnnotations;
|
||||
myNonBlockingAnnotations = nonBlockingAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull PsiFile file) {
|
||||
return myBlockingAnnotations != null &&
|
||||
StreamEx.of(DEFAULT_BLOCKING_ANNOTATIONS)
|
||||
.append(myBlockingAnnotations)
|
||||
.anyMatch(annotation -> JavaPsiFacade.getInstance(file.getProject()).findClass(annotation, file.getResolveScope()) != null);
|
||||
JavaPsiFacade javaPsi = JavaPsiFacade.getInstance(file.getProject());
|
||||
GlobalSearchScope fileResolveScope = file.getResolveScope();
|
||||
for (String annotation : myBlockingAnnotations) {
|
||||
if (javaPsi.findClass(annotation, fileResolveScope) != null) return true;
|
||||
}
|
||||
for (String annotation : myNonBlockingAnnotations) {
|
||||
if (javaPsi.findClass(annotation, fileResolveScope) != null) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMethodBlocking(@NotNull PsiMethod method) {
|
||||
return AnnotationUtil.findAnnotation(method, myBlockingAnnotations, false) != null;
|
||||
public boolean isMethodBlocking(@NotNull MethodContext context) {
|
||||
return isMethodOrClassAnnotated(context.getMethod(), myBlockingAnnotations, myNonBlockingAnnotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMethodNonBlocking(@NotNull PsiMethod method) {
|
||||
return AnnotationUtil.findAnnotation(method, myNonBlockingAnnotations, false) != null;
|
||||
public boolean isMethodNonBlocking(@NotNull MethodContext context) {
|
||||
return isMethodOrClassAnnotated(context.getMethod(), myNonBlockingAnnotations, myBlockingAnnotations);
|
||||
}
|
||||
|
||||
private static boolean isMethodOrClassAnnotated(@NotNull PsiMethod method,
|
||||
@NotNull Collection<String> annotations,
|
||||
@NotNull Collection<String> denyAnnotations) {
|
||||
if (AnnotationUtil.findAnnotation(method, annotations, false) != null) return true;
|
||||
// @NonBlocking on method overrides @Blocking on class
|
||||
if (AnnotationUtil.findAnnotation(method, denyAnnotations, false) != null) return false;
|
||||
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
return containingClass != null
|
||||
&& AnnotationUtil.findAnnotation(containingClass, annotations, false) != null;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-16
@@ -2,35 +2,33 @@
|
||||
package com.intellij.codeInspection.blockingCallsDetection;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import one.util.streamex.StreamEx;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.uast.UCallExpression;
|
||||
import org.jetbrains.uast.UMethod;
|
||||
import org.jetbrains.uast.UastContextKt;
|
||||
import org.jetbrains.uast.UastUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
import static com.intellij.codeInspection.blockingCallsDetection.BlockingMethodInNonBlockingContextInspection.DEFAULT_NONBLOCKING_ANNOTATIONS;
|
||||
public final class AnnotationBasedNonBlockingContextChecker implements NonBlockingContextChecker {
|
||||
|
||||
public class AnnotationBasedNonBlockingContextChecker implements NonBlockingContextChecker {
|
||||
private final Collection<String> myBlockingAnnotations;
|
||||
private final Collection<String> myNonBlockingAnnotations;
|
||||
|
||||
private final List<String> myNonBlockingAnnotations;
|
||||
|
||||
public AnnotationBasedNonBlockingContextChecker(List<String> nonBlockingAnnotations) {
|
||||
public AnnotationBasedNonBlockingContextChecker(@NotNull Collection<String> blockingAnnotations,
|
||||
@NotNull Collection<String> nonBlockingAnnotations) {
|
||||
myBlockingAnnotations = blockingAnnotations;
|
||||
myNonBlockingAnnotations = nonBlockingAnnotations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isApplicable(@NotNull PsiFile file) {
|
||||
return myNonBlockingAnnotations != null &&
|
||||
StreamEx.of(DEFAULT_NONBLOCKING_ANNOTATIONS)
|
||||
.append(myNonBlockingAnnotations)
|
||||
.anyMatch(annotation -> JavaPsiFacade.getInstance(file.getProject()).findClass(annotation, file.getResolveScope()) != null);
|
||||
JavaPsiFacade javaPsi = JavaPsiFacade.getInstance(file.getProject());
|
||||
for (String annotation : myNonBlockingAnnotations) {
|
||||
if (javaPsi.findClass(annotation, file.getResolveScope()) != null) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -42,6 +40,17 @@ public class AnnotationBasedNonBlockingContextChecker implements NonBlockingCont
|
||||
if (callingMethod == null) return false;
|
||||
PsiMethod psiCallingMethod = callingMethod.getJavaPsi();
|
||||
|
||||
return AnnotationUtil.findAnnotation(psiCallingMethod, myNonBlockingAnnotations, false) != null;
|
||||
if (AnnotationUtil.findAnnotation(psiCallingMethod, myNonBlockingAnnotations, false) != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AnnotationUtil.findAnnotation(psiCallingMethod, myBlockingAnnotations, false) != null) {
|
||||
// @Blocking on method overrides @NonBlocking on class
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiClass containingClass = psiCallingMethod.getContainingClass();
|
||||
return containingClass != null
|
||||
&& AnnotationUtil.findAnnotation(containingClass, myNonBlockingAnnotations, false) != null;
|
||||
}
|
||||
}
|
||||
|
||||
+40
-36
@@ -9,6 +9,7 @@ import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.progress.ProgressIndicatorProvider;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ProjectManager;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
@@ -25,8 +26,10 @@ import org.jetbrains.uast.UCallExpression;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
public final class BlockingMethodInNonBlockingContextInspection extends AbstractBaseUastLocalInspectionTool {
|
||||
|
||||
@@ -52,31 +55,44 @@ public final class BlockingMethodInNonBlockingContextInspection extends Abstract
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
List<NonBlockingContextChecker> nonBlockingContextCheckers = getNonBlockingContextCheckers(holder.getFile());
|
||||
Collection<String> nonBlockingAnnotations = union(myNonBlockingAnnotations, DEFAULT_NONBLOCKING_ANNOTATIONS);
|
||||
Collection<String> blockingAnnotations = union(myBlockingAnnotations, DEFAULT_BLOCKING_ANNOTATIONS);
|
||||
|
||||
List<NonBlockingContextChecker> nonBlockingContextCheckers =
|
||||
getNonBlockingContextCheckers(holder.getFile(), blockingAnnotations, nonBlockingAnnotations);
|
||||
if (nonBlockingContextCheckers.isEmpty()) return PsiElementVisitor.EMPTY_VISITOR;
|
||||
|
||||
List<BlockingMethodChecker> blockingMethodCheckers = getBlockingMethodCheckers(holder.getFile());
|
||||
List<BlockingMethodChecker> blockingMethodCheckers =
|
||||
getBlockingMethodCheckers(holder.getFile(), blockingAnnotations, nonBlockingAnnotations);
|
||||
if (blockingMethodCheckers.isEmpty()) return PsiElementVisitor.EMPTY_VISITOR;
|
||||
|
||||
return new BlockingMethodInNonBlockingContextVisitor(holder, blockingMethodCheckers, nonBlockingContextCheckers);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<NonBlockingContextChecker> getNonBlockingContextCheckers(@NotNull PsiFile file) {
|
||||
private static @NotNull List<NonBlockingContextChecker> getNonBlockingContextCheckers(@NotNull PsiFile file,
|
||||
@NotNull Collection<String> blockingAnnotations,
|
||||
@NotNull Collection<String> nonBlockingAnnotations) {
|
||||
List<NonBlockingContextChecker> nonBlockingContextCheckers = new ArrayList<>(NonBlockingContextChecker.EP_NAME.getExtensionList());
|
||||
nonBlockingContextCheckers.add(new AnnotationBasedNonBlockingContextChecker(myNonBlockingAnnotations));
|
||||
nonBlockingContextCheckers.add(new AnnotationBasedNonBlockingContextChecker(blockingAnnotations, nonBlockingAnnotations));
|
||||
nonBlockingContextCheckers.removeIf(checker -> !checker.isApplicable(file));
|
||||
return nonBlockingContextCheckers;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<BlockingMethodChecker> getBlockingMethodCheckers(@NotNull PsiFile file) {
|
||||
private static @NotNull List<BlockingMethodChecker> getBlockingMethodCheckers(@NotNull PsiFile file,
|
||||
@NotNull Collection<String> blockingAnnotations,
|
||||
@NotNull Collection<String> nonBlockingAnnotations) {
|
||||
List<BlockingMethodChecker> blockingMethodCheckers = new ArrayList<>(BlockingMethodChecker.EP_NAME.getExtensionList());
|
||||
blockingMethodCheckers.add(new AnnotationBasedBlockingMethodChecker(myBlockingAnnotations, myNonBlockingAnnotations));
|
||||
blockingMethodCheckers.add(new AnnotationBasedBlockingMethodChecker(blockingAnnotations, nonBlockingAnnotations));
|
||||
blockingMethodCheckers.removeIf(checker -> !checker.isApplicable(file));
|
||||
return blockingMethodCheckers;
|
||||
}
|
||||
|
||||
private static Collection<String> union(Collection<String> annotations, Collection<String> defaultAnnotations) {
|
||||
Set<String> result = new HashSet<>(defaultAnnotations);
|
||||
result.addAll(annotations != null ? annotations : emptyList());
|
||||
return result;
|
||||
}
|
||||
|
||||
private final class OptionsPanel extends JPanel {
|
||||
private OptionsPanel() {
|
||||
super(new BorderLayout());
|
||||
@@ -123,15 +139,15 @@ public final class BlockingMethodInNonBlockingContextInspection extends Abstract
|
||||
|
||||
private static class BlockingMethodInNonBlockingContextVisitor extends PsiElementVisitor {
|
||||
private final ProblemsHolder myHolder;
|
||||
private final List<? extends BlockingMethodChecker> myBlockingMethodCheckers;
|
||||
private final List<? extends NonBlockingContextChecker> myNonBlockingContextCheckers;
|
||||
private final List<BlockingMethodChecker> myBlockingMethodCheckers;
|
||||
private final List<NonBlockingContextChecker> myNonBlockingContextCheckers;
|
||||
|
||||
BlockingMethodInNonBlockingContextVisitor(@NotNull ProblemsHolder holder,
|
||||
List<? extends BlockingMethodChecker> blockingMethodCheckers,
|
||||
List<? extends NonBlockingContextChecker> nonBlockingContextCheckers) {
|
||||
List<BlockingMethodChecker> blockingMethodCheckers,
|
||||
List<NonBlockingContextChecker> nonBlockingContextCheckers) {
|
||||
myHolder = holder;
|
||||
this.myBlockingMethodCheckers = blockingMethodCheckers;
|
||||
this.myNonBlockingContextCheckers = nonBlockingContextCheckers;
|
||||
myBlockingMethodCheckers = blockingMethodCheckers;
|
||||
myNonBlockingContextCheckers = nonBlockingContextCheckers;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,10 +161,8 @@ public final class BlockingMethodInNonBlockingContextInspection extends Abstract
|
||||
PsiMethod referencedMethod = callExpression.resolve();
|
||||
if (referencedMethod == null) return;
|
||||
|
||||
if (!isMethodOrSupersBlocking(referencedMethod, myBlockingMethodCheckers)) return;
|
||||
|
||||
// if some implementation believes this method is non-blocking then we don't report it
|
||||
if (isMethodNonBlocking(referencedMethod, myBlockingMethodCheckers)) return;
|
||||
MethodContext methodContext = new MethodContext(referencedMethod, myBlockingMethodCheckers);
|
||||
if (!isMethodOrSupersBlocking(methodContext)) return;
|
||||
|
||||
PsiElement elementToHighLight = AnalysisUastUtil.getMethodIdentifierSourcePsi(callExpression);
|
||||
if (elementToHighLight == null) return;
|
||||
@@ -162,25 +176,15 @@ public final class BlockingMethodInNonBlockingContextInspection extends Abstract
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isMethodOrSupersBlocking(PsiMethod referencedMethod,
|
||||
List<? extends BlockingMethodChecker> blockingMethodCheckers) {
|
||||
return StreamEx.of(referencedMethod).append(referencedMethod.findDeepestSuperMethods())
|
||||
.anyMatch(method -> isMethodBlocking(method, blockingMethodCheckers));
|
||||
private static boolean isMethodOrSupersBlocking(MethodContext methodContext) {
|
||||
return StreamEx.of(methodContext.getMethod()).append(methodContext.getMethod().findDeepestSuperMethods())
|
||||
.anyMatch(method -> isMethodBlocking(methodContext));
|
||||
}
|
||||
|
||||
private static boolean isMethodBlocking(PsiMethod method,
|
||||
List<? extends BlockingMethodChecker> blockingMethodCheckers) {
|
||||
return blockingMethodCheckers.stream().anyMatch(extension -> {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
return extension.isMethodBlocking(method);
|
||||
});
|
||||
}
|
||||
|
||||
private static boolean isMethodNonBlocking(PsiMethod method,
|
||||
List<? extends BlockingMethodChecker> blockingMethodCheckers) {
|
||||
return blockingMethodCheckers.stream().anyMatch(extension -> {
|
||||
ProgressIndicatorProvider.checkCanceled();
|
||||
return extension.isMethodNonBlocking(method);
|
||||
private static boolean isMethodBlocking(MethodContext methodContext) {
|
||||
return methodContext.getCheckers().stream().anyMatch(extension -> {
|
||||
ProgressManager.checkCanceled();
|
||||
return extension.isMethodBlocking(methodContext);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+2
-3
@@ -2,7 +2,6 @@
|
||||
package com.intellij.codeInspection.blockingCallsDetection;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import one.util.streamex.StreamEx;
|
||||
@@ -21,8 +20,8 @@ final class ThrowsTypeBlockingMethodChecker implements BlockingMethodChecker {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMethodBlocking(@NotNull PsiMethod method) {
|
||||
return StreamEx.of(method.getThrowsList().getReferencedTypes())
|
||||
public boolean isMethodBlocking(@NotNull MethodContext context) {
|
||||
return StreamEx.of(context.getMethod().getThrowsList().getReferencedTypes())
|
||||
.cross(BLOCKING_EXCEPTION_TYPES)
|
||||
.anyMatch(entry -> InheritanceUtil.isInheritor(entry.getKey(), entry.getValue()));
|
||||
}
|
||||
|
||||
+5
@@ -70,6 +70,11 @@ public class BlockingMethodInNonBlockingContextInspectionTest extends UsefulTest
|
||||
myFixture.testHighlighting(true, false, true, "TestSimpleAnnotationsDetection.java");
|
||||
}
|
||||
|
||||
public void testClassAnnotationDetection() {
|
||||
myFixture.configureByFiles("TestClassAnnotationsDetection.java", "Blocking.java", "NonBlocking.java");
|
||||
myFixture.testHighlighting(true, false, true, "TestClassAnnotationsDetection.java");
|
||||
}
|
||||
|
||||
public void testExternalBlockingAnnotationDetection() {
|
||||
myFixture.configureByFiles("TestExternalAnnotationsDetection.java", "Blocking.java", "NonBlocking.java", "annotations.xml");
|
||||
myFixture.testHighlighting(true, false, true, "TestExternalAnnotationsDetection.java");
|
||||
|
||||
+3
-4
@@ -2,6 +2,7 @@
|
||||
package org.jetbrains.kotlin.idea.inspections.blockingCallsDetection
|
||||
|
||||
import com.intellij.codeInspection.blockingCallsDetection.BlockingMethodChecker
|
||||
import com.intellij.codeInspection.blockingCallsDetection.MethodContext
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiMethod
|
||||
@@ -23,10 +24,8 @@ internal class CoroutineBlockingMethodChecker : BlockingMethodChecker {
|
||||
return languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines)
|
||||
}
|
||||
|
||||
override fun isMethodBlocking(method: PsiMethod): Boolean = false
|
||||
|
||||
override fun isMethodNonBlocking(method: PsiMethod): Boolean {
|
||||
val uMethod = method.toUElement()
|
||||
override fun isMethodNonBlocking(context: MethodContext): Boolean {
|
||||
val uMethod = context.method.toUElement()
|
||||
val sourcePsi = uMethod?.sourcePsi ?: return false
|
||||
return sourcePsi is KtNamedFunction && sourcePsi.modifierList?.hasSuspendModifier() == true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user