mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
extract method: annotate newly created method @Nullable when applicable (IDEA-76767)
This commit is contained in:
+15
@@ -134,6 +134,21 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
};
|
||||
analyzeDfaWithNestedClosures(scope, holder, dfaRunner, Arrays.asList(dfaRunner.createMemoryState()), onTheFly);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Collection<PsiElement> getNullableReturn(PsiMethod method) {
|
||||
final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner();
|
||||
final DataFlowInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body == null) {
|
||||
return null;
|
||||
}
|
||||
final RunnerResult rc = dfaRunner.analyzeMethod(body, visitor);
|
||||
if (rc == RunnerResult.OK) {
|
||||
return visitor.getProblems(NullabilityProblem.nullableReturn);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void analyzeDfaWithNestedClosures(PsiElement scope,
|
||||
ProblemsHolder holder,
|
||||
|
||||
+25
-3
@@ -17,13 +17,17 @@ package com.intellij.refactoring.extractMethod;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.codeInsight.ExceptionUtil;
|
||||
import com.intellij.codeInsight.NullableNotNullManager;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
|
||||
import com.intellij.codeInsight.highlighting.HighlightManager;
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationIntention;
|
||||
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
|
||||
import com.intellij.codeInsight.intention.impl.AddNullableNotNullAnnotationFix;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.codeInspection.dataFlow.RunnerResult;
|
||||
import com.intellij.codeInspection.dataFlow.StandardDataFlowRunner;
|
||||
import com.intellij.codeInspection.dataFlow.StandardInstructionVisitor;
|
||||
import com.intellij.codeInspection.dataFlow.*;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.BranchingInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
|
||||
import com.intellij.ide.DataManager;
|
||||
@@ -39,6 +43,7 @@ import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -862,6 +867,20 @@ public class ExtractMethodProcessor implements MatchProvider {
|
||||
}
|
||||
}
|
||||
|
||||
if (isNullabilityCheckApplicable() && !(newMethod.getReturnType() instanceof PsiPrimitiveType) &&
|
||||
PsiUtil.isLanguageLevel5OrHigher(newMethod) && Registry.is("annotate.extracted.method.nullable.when.applicable", true)) {
|
||||
final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
|
||||
final PsiClass nullableAnnotationClass =
|
||||
JavaPsiFacade.getInstance(myProject).findClass(manager.getDefaultNullable(), GlobalSearchScope.allScope(myProject));
|
||||
if (nullableAnnotationClass != null) {
|
||||
final Collection<PsiElement> nullableReturn = DataFlowInspectionBase.getNullableReturn(newMethod);
|
||||
if (nullableReturn != null && !nullableReturn.isEmpty()) {
|
||||
final AddNullableNotNullAnnotationFix annotationFix = new AddNullableAnnotationFix(newMethod);
|
||||
annotationFix.invoke(myProject, myTargetClass.getContainingFile(), newMethod, newMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
myExtractedMethod = (PsiMethod)myTargetClass.addAfter(newMethod, myAnchor);
|
||||
if (isNeedToChangeCallContext() && myNeedChangeContext) {
|
||||
ChangeContextUtil.decodeContextInfo(myExtractedMethod, myTargetClass, RefactoringChangeUtil.createThisExpression(myManager, null));
|
||||
@@ -870,7 +889,10 @@ public class ExtractMethodProcessor implements MatchProvider {
|
||||
methodExpression.setQualifierExpression(RefactoringChangeUtil.createThisExpression(myManager, myTargetClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isNullabilityCheckApplicable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean isNeedToChangeCallContext() {
|
||||
|
||||
+10
-5
@@ -657,6 +657,16 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNullabilityCheckApplicable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNeedToChangeCallContext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void apply(final AbstractExtractDialog dialog) {
|
||||
super.apply(dialog);
|
||||
@@ -741,11 +751,6 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor {
|
||||
return myOutputVariables;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNeedToChangeCallContext() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void declareNecessaryVariablesAfterCall(final PsiVariable outputVariable) throws IncorrectOperationException {
|
||||
if (myMultipleExitPoints) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class C {
|
||||
public Object m() {
|
||||
Object o = newMethod();
|
||||
@@ -5,6 +7,7 @@ class C {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object newMethod() {
|
||||
for (Object o : new ArrayList<Object>()) {
|
||||
if (o != null) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Result {
|
||||
private String _message;
|
||||
|
||||
@@ -17,6 +19,7 @@ class Main {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Result newMethod(String name) {
|
||||
Result result;
|
||||
if (name == null) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Test {
|
||||
String foo(int i, boolean flag) {
|
||||
|
||||
@@ -8,6 +10,7 @@ class Test {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private String newMethod(int i, boolean flag) {
|
||||
String xxx = "";
|
||||
if (flag) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class Test {
|
||||
@@ -11,6 +13,7 @@ class Test {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Pojo newMethod() {
|
||||
Pojo x = things.get(0);
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Test {
|
||||
void foo() {
|
||||
Object o = newMethod();
|
||||
@@ -5,6 +7,7 @@ class Test {
|
||||
System.out.println(o);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object newMethod() {
|
||||
Object o = "";
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Test {
|
||||
Object foo() {
|
||||
Object o = newMethod();
|
||||
@@ -6,6 +8,7 @@ class Test {
|
||||
return o;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object newMethod() {
|
||||
Object o = "";
|
||||
for (int i = 0; i < 5; i++) {
|
||||
|
||||
@@ -499,3 +499,6 @@ editor.config.stop.at.project.root.description=Stops searching for .editorconfig
|
||||
|
||||
JDK8042508.bug.fixed=false
|
||||
JDK8042508.bug.fixed.description=Disable check for type variable until javac bug is fixed
|
||||
|
||||
annotate.extracted.method.nullable.when.applicable=true
|
||||
annotate.extracted.method.nullable.when.applicable.description=Enables @Nullable annotation on newly extracted method when applicable
|
||||
|
||||
Reference in New Issue
Block a user