[java-inspections] CreateLocalFromUsageFix: remove external annotations

Fixes IDEA-367190 NotNull annotation when creating local variable references library which is not in the project
Also: do not resolve reference for writing to a package

GitOrigin-RevId: 31f996515323e250d487bf9b7d343f101d788907
This commit is contained in:
Tagir Valeev
2025-06-12 16:51:42 +00:00
committed by intellij-monorepo-bot
parent 923d5953c9
commit 6cb3ca0045
7 changed files with 38 additions and 7 deletions
@@ -19,9 +19,11 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.util.JavaElementKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.IntroduceVariableUtil;
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
@@ -88,6 +90,7 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
final SmartTypePointer defaultType = SmartTypePointerManager.getInstance(project).createSmartTypePointer(expectedTypes[0]);
final PsiType preferredType = TypeSelectorManagerImpl.getPreferredType(expectedTypes, expectedTypes[0]);
PsiType type = preferredType != null ? preferredType : expectedTypes[0];
type = PsiTypesUtil.removeExternalAnnotations(type);
if (LambdaUtil.notInferredType(type)) {
type = PsiType.getJavaLangObject(element.getManager(), psiFile.getResolveScope());
}
@@ -122,6 +125,7 @@ public class CreateLocalFromUsageFix extends CreateVarFromUsageFix {
}
PsiVariable var = (PsiVariable)decl.getDeclaredElements()[0];
var = (PsiVariable)JavaCodeStyleManager.getInstance(project).shortenClassReferences(var);
boolean isFinal =
JavaCodeStyleSettings.getInstance(psiFile).GENERATE_FINAL_LOCALS &&
!CreateFromUsageUtils.isAccessedForWriting(expressions);
@@ -194,7 +194,8 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
List<ResolveResult[]> qualifiers = resolveAllQualifiers(expression, containingFile);
JavaResolveResult[] result = expression.resolve(parentType, containingFile);
if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION) {
if (result.length == 0 && incompleteCode && parentType != JavaElementType.REFERENCE_EXPRESSION &&
!PsiUtil.isAccessedForWriting(expression)) {
result = expression.resolve(JavaElementType.REFERENCE_EXPRESSION, containingFile);
}
@@ -0,0 +1,10 @@
// "Create local variable 'set'" "true-preview"
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class X {
void test() {
Set<Integer> set = Stream.of(1, 2, 3).collect(Collectors.toSet());
}
}
@@ -14,9 +14,9 @@ class A {
sealed interface BaseInterface<T> permits BaseInterface.Record1, BaseInterface.Record2{
record Record1<T>() implements BaseInterface<T> {
final class Record1<T> implements BaseInterface<T> {
}
record Record2() implements BaseInterface<String> {
final class Record2 implements BaseInterface<String> {
}
}
@@ -0,0 +1,9 @@
// "Create local variable 'set'" "true-preview"
import java.util.stream.Collectors;
import java.util.stream.Stream;
class X {
void test() {
<caret>set = Stream.of(1, 2, 3).collect(Collectors.toSet());
}
}
@@ -13,9 +13,9 @@ class A {
sealed interface BaseInterface<T> permits BaseInterface.Record1, BaseInterface.Record2{
record Record1<T>() implements BaseInterface<T> {
final class Record1<T> implements BaseInterface<T> {
}
record Record2() implements BaseInterface<String> {
final class Record2 implements BaseInterface<String> {
}
}
@@ -2,8 +2,11 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import static com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_21_ANNOTATED;
public class CreateLocalFromUsageTest extends LightQuickFixParameterizedTestCase {
@Override
@@ -11,10 +14,14 @@ public class CreateLocalFromUsageTest extends LightQuickFixParameterizedTestCase
return "/codeInsight/daemonCodeAnalyzer/quickFix/createLocalFromUsage";
}
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return JAVA_21_ANNOTATED;
}
@Override
protected void setUp() throws Exception {
super.setUp();
setLanguageLevel(LanguageLevel.JDK_21);
JavaCodeStyleSettings.getInstance(getProject()).GENERATE_FINAL_LOCALS = getTestName(true).contains("final");
}
}