NotNull, diagnostics for EA-232099

GitOrigin-RevId: b4c746caff6dd1d79269a8e2d352955437d07377
This commit is contained in:
Tagir Valeev
2020-06-09 09:11:12 +03:00
committed by intellij-monorepo-bot
parent aa4214f48a
commit a4d6d00243
3 changed files with 49 additions and 29 deletions
@@ -17,6 +17,7 @@ import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -64,10 +65,12 @@ import com.intellij.util.containers.MultiMap;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ipp.psiutils.ErrorUtil;
import one.util.streamex.EntryStream;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
@@ -712,6 +715,21 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
JavaReplaceChoice finalChoice = settings.getReplaceChoice();
PsiExpression[] selectedOccurrences = finalChoice.filter(occurrenceManager);
final PsiElement chosenAnchor = getAnchor(selectedOccurrences);
if (chosenAnchor == null) {
String text = file.getText();
String textWithOccurrences = StreamEx.of(selectedOccurrences)
.map(e -> getPhysicalElement(e).getTextRange())
.flatMapToEntry(range -> EntryStream.of(range.getStartOffset(), "[", range.getEndOffset(), "]").toMap())
.sortedBy(Map.Entry::getKey)
.prepend(0, "")
.append(text.length(), "")
.map(Function.identity())
.pairMap((prev, next) -> text.substring(prev.getKey(), next.getKey()) + next.getValue())
.joining();
LOG.error("Unable to find anchor for a new variable; selectedOccurrences.length = "+selectedOccurrences.length,
new Attachment("source.java", textWithOccurrences));
return;
}
final RefactoringEventData beforeData = new RefactoringEventData();
beforeData.addElement(expr);
@@ -750,7 +768,7 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase {
boolean inFinalContext = occurrenceManager.isInFinalContext();
PsiExpression expr = occurrenceManager.getMainOccurence();
PsiExpression[] selectedOccurrences = choice.filter(occurrenceManager);
final InputValidator validator = new InputValidator(IntroduceVariableBase.this, project, occurrenceManager);
final InputValidator validator = new InputValidator(this, project, occurrenceManager);
final TypeSelectorManagerImpl typeSelectorManager = new TypeSelectorManagerImpl(project, originalType, expr, selectedOccurrences);
typeSelectorManager.setAllOccurrences(true);
@@ -469,8 +469,9 @@ public class JavaVariableInplaceIntroducer extends AbstractJavaInplaceIntroducer
@Nullable
protected PsiVariable introduceVariable() {
PsiVariable variable = VariableExtractor
.introduce(myProject, myExpr, myEditor, myChosenAnchor.getElement(), getOccurrences(), mySettings);
PsiElement anchor = myChosenAnchor.getElement();
if (anchor == null) return null;
PsiVariable variable = VariableExtractor.introduce(myProject, myExpr, myEditor, anchor, getOccurrences(), mySettings);
SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
if (variable instanceof PsiField || variable instanceof PsiResourceVariable) {
myPointer = smartPointerManager.createSmartPsiElementPointer(variable);
@@ -42,23 +42,23 @@ import java.util.Set;
class VariableExtractor {
private static final Logger LOG = Logger.getInstance(VariableExtractor.class);
private final Project myProject;
private final Editor myEditor;
private final IntroduceVariableSettings mySettings;
private final PsiExpression myExpression;
private final @NotNull Project myProject;
private final @Nullable Editor myEditor;
private final @NotNull IntroduceVariableSettings mySettings;
private final @NotNull PsiExpression myExpression;
private @NotNull PsiElement myAnchor;
private final PsiElement myContainer;
private final PsiExpression[] myOccurrences;
private final PsiExpression @NotNull [] myOccurrences;
private final boolean myReplaceSelf;
private final FieldConflictsResolver myFieldConflictsResolver;
private final LogicalPosition myPosition;
private final @NotNull FieldConflictsResolver myFieldConflictsResolver;
private final @Nullable LogicalPosition myPosition;
private VariableExtractor(final Project project,
final PsiExpression expression,
final Editor editor,
final PsiElement anchorStatement,
final PsiExpression[] occurrences,
final IntroduceVariableSettings settings) {
private VariableExtractor(final @NotNull Project project,
final @NotNull PsiExpression expression,
final @Nullable Editor editor,
final @NotNull PsiElement anchorStatement,
final PsiExpression @NotNull [] occurrences,
final @NotNull IntroduceVariableSettings settings) {
myProject = project;
myExpression = expression;
myEditor = editor;
@@ -100,6 +100,7 @@ class VariableExtractor {
ExpressionUtils.isReferenceTo(((PsiExpressionStatement)myAnchor).getExpression(), var)) {
commentTracker.deleteAndRestoreComments(myAnchor);
if (myEditor != null) {
assert myPosition != null;
myEditor.getCaretModel().moveToLogicalPosition(myPosition);
myEditor.getCaretModel().moveToOffset(var.getTextRange().getEndOffset());
myEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
@@ -140,7 +141,7 @@ class VariableExtractor {
}
}
private void highlight(PsiVariable var) {
private void highlight(@NotNull PsiVariable var) {
if (myEditor != null) {
PsiElement[] occurrences =
PsiTreeUtil.collectElements(myContainer, e -> e instanceof PsiReference && ((PsiReference)e).isReferenceTo(var));
@@ -175,7 +176,7 @@ class VariableExtractor {
}
}
private PsiVariable addVariable(PsiElement declaration, PsiExpression initializer) {
private @NotNull PsiVariable addVariable(PsiElement declaration, @NotNull PsiExpression initializer) {
declaration = addDeclaration(declaration, initializer, myAnchor);
declaration = JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(declaration);
return (PsiVariable)(declaration instanceof PsiDeclarationStatement
@@ -240,8 +241,8 @@ class VariableExtractor {
return parent.addBefore(declaration, anchor);
}
@NotNull
private static PsiType stripNullabilityAnnotationsFromTargetType(SmartTypePointer selectedType, final PsiExpression expression) {
private static @NotNull PsiType stripNullabilityAnnotationsFromTargetType(@NotNull SmartTypePointer selectedType,
@NotNull PsiExpression expression) {
PsiType type = selectedType.getType();
if (type == null) {
throw new IncorrectOperationException("Unexpected empty type pointer");
@@ -250,7 +251,7 @@ class VariableExtractor {
PsiDeclarationStatement probe = JavaPsiFacade.getElementFactory(expression.getProject())
.createVariableDeclarationStatement("x", TypeUtils.getObjectType(expression), null, expression);
Project project = expression.getProject();
NullabilityAnnotationInfo nullabilityAnnotationInfo =
NullabilityAnnotationInfo nullabilityAnnotationInfo =
NullableNotNullManager.getInstance(project).findExplicitNullability((PsiLocalVariable)probe.getDeclaredElements()[0]);
NullabilityAnnotationInfo info = DfaPsiUtil.getTypeNullabilityInfo(type);
if (info != null && nullabilityAnnotationInfo != null && info.getNullability() != nullabilityAnnotationInfo.getNullability() &&
@@ -263,9 +264,9 @@ class VariableExtractor {
}
@NotNull
private static PsiElement correctAnchor(PsiExpression expr,
private static PsiElement correctAnchor(@NotNull PsiExpression expr,
@NotNull PsiElement anchor,
PsiExpression[] occurrences) {
PsiExpression @NotNull [] occurrences) {
if (!expr.isPhysical()) {
expr = ObjectUtils.tryCast(expr.getUserData(ElementToWorkOn.PARENT), PsiExpression.class);
if (expr == null) return anchor;
@@ -356,12 +357,12 @@ class VariableExtractor {
}
@Nullable
public static PsiVariable introduce(final Project project,
final PsiExpression expr,
final Editor editor,
final PsiElement anchorStatement,
final PsiExpression[] occurrences,
final IntroduceVariableSettings settings) {
public static PsiVariable introduce(final @NotNull Project project,
final @NotNull PsiExpression expr,
final @Nullable Editor editor,
final @NotNull PsiElement anchorStatement,
final PsiExpression @NotNull [] occurrences,
final @NotNull IntroduceVariableSettings settings) {
Computable<SmartPsiElementPointer<PsiVariable>> computation =
new VariableExtractor(project, expr, editor, anchorStatement, occurrences, settings)::extractVariable;
SmartPsiElementPointer<PsiVariable> pointer = ApplicationManager.getApplication().runWriteAction(computation);