[lombok] IDEA-292093 Fix @NonNull on package does not work on Lombok methods

GitOrigin-RevId: 19acc4f9803e8b444e787de482da60cba1c58a19
This commit is contained in:
Michail Plushnikov
2024-09-01 22:28:52 +02:00
committed by intellij-monorepo-bot
parent 82b30feb4e
commit b61e5aa1a0
8 changed files with 114 additions and 3 deletions

View File

@@ -138,7 +138,10 @@ public final class ExtensionMethodsHelper {
for (int i = 1, length = parameters.length; i < length; i++) {
PsiParameter parameter = parameters[i];
lightMethod.addParameter(new LombokLightParameter(parameter.getName(), substitutor.substitute(parameter.getType()), lightMethod, JavaLanguage.INSTANCE));
final LombokLightParameter lombokLightParameter =
new LombokLightParameter(parameter.getName(), substitutor.substitute(parameter.getType()), lightMethod, JavaLanguage.INSTANCE);
lombokLightParameter.setParent(lightMethod);
lightMethod.addParameter(lombokLightParameter);
}
PsiClassType[] thrownTypes = staticMethod.getThrowsList().getReferencedTypes();

View File

@@ -40,7 +40,7 @@ public class LombokLightClassBuilder extends LightPsiClassBuilder implements Psi
myIsAnnotationType = false;
myQualifiedName = qualifiedName;
myBaseIcon = LombokIcons.Nodes.LombokClass;
myModifierList = new LombokLightModifierList(context.getManager(), context.getLanguage());
myModifierList = new LombokLightModifierList(context.getManager(), context.getLanguage()).withParent(this);
}
@NotNull

View File

@@ -31,7 +31,7 @@ public class LombokLightFieldBuilder extends LightFieldBuilder implements Synthe
super(manager, name, type);
myName = name;
myNameIdentifier = new LombokLightIdentifier(manager, name);
myModifierList = new LombokLightModifierList(manager);
myModifierList = new LombokLightModifierList(manager).withParent(this);
setBaseIcon(LombokIcons.Nodes.LombokField);
}

View File

@@ -44,6 +44,7 @@ public class LombokLightMethodBuilder extends LightMethodBuilder implements Synt
new LombokLightModifierList(manager),
new LombokLightReferenceListBuilder(manager, JavaLanguage.INSTANCE, PsiReferenceList.Role.THROWS_LIST),
new LightTypeParameterListBuilder(manager, JavaLanguage.INSTANCE));
getModifierList().withParent(this);
setBaseIcon(LombokIcons.Nodes.LombokMethod);
}
@@ -92,6 +93,7 @@ public class LombokLightMethodBuilder extends LightMethodBuilder implements Synt
public LombokLightMethodBuilder withParameter(@NotNull LombokLightParameter psiParameter) {
addParameter(psiParameter);
psiParameter.setParent(this);
return this;
}

View File

@@ -18,6 +18,7 @@ public class LombokLightModifierList extends LightModifierList implements Synthe
private final Map<String, PsiAnnotation> myAnnotations;
private final Set<String> myImplicitModifiers;
private PsiElement myParent;
public LombokLightModifierList(@NotNull PsiManager manager) {
this(manager, JavaLanguage.INSTANCE);
@@ -74,6 +75,11 @@ public class LombokLightModifierList extends LightModifierList implements Synthe
return result;
}
public LombokLightModifierList withParent(@NotNull PsiElement parent) {
myParent = parent;
return this;
}
public LombokLightModifierList withAnnotation(@NotNull String qualifiedName, @NotNull PsiAnnotation psiAnnotation) {
myAnnotations.put(qualifiedName, psiAnnotation);
return this;
@@ -117,6 +123,11 @@ public class LombokLightModifierList extends LightModifierList implements Synthe
return r == null ? TextRange.EMPTY_RANGE : r;
}
@Override
public PsiElement getParent() {
return myParent;
}
public String toString() {
return "LombokLightModifierList";
}

View File

@@ -15,6 +15,7 @@ import java.util.stream.Stream;
*/
public class LombokLightParameter extends LightParameter implements SyntheticElement {
private final LombokLightIdentifier myNameIdentifier;
private PsiElement myParent;
public LombokLightParameter(@NotNull String name, @NotNull PsiType type, @NotNull PsiElement declarationScope) {
this(name, type, declarationScope, JavaLanguage.INSTANCE);
@@ -25,6 +26,7 @@ public class LombokLightParameter extends LightParameter implements SyntheticEle
@NotNull PsiElement declarationScope,
@NotNull Language language) {
super(name, type, declarationScope, language, new LombokLightModifierList(declarationScope.getManager(), language), type instanceof PsiEllipsisType);
getModifierList().withParent(this);
myNameIdentifier = new LombokLightIdentifier(declarationScope.getManager(), name);
}
@@ -40,6 +42,10 @@ public class LombokLightParameter extends LightParameter implements SyntheticEle
return this;
}
public void setParent(PsiElement parent) {
myParent = parent;
}
@Override
public PsiIdentifier getNameIdentifier() {
return myNameIdentifier;
@@ -69,6 +75,11 @@ public class LombokLightParameter extends LightParameter implements SyntheticEle
return this;
}
@Override
public PsiElement getParent() {
return myParent;
}
@Override
public boolean equals(Object o) {
if (this == o) {

View File

@@ -0,0 +1,51 @@
package com.intellij.java.lomboktest;
import com.intellij.java.codeInspection.DataFlowInspectionTest;
import com.intellij.java.codeInspection.DataFlowInspectionTestCase;
import com.intellij.testFramework.LightProjectDescriptor;
import de.plushnikov.intellij.plugin.LombokTestUtil;
import org.jetbrains.annotations.NotNull;
public class LombokDataFlowInspectionTest extends DataFlowInspectionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR;
}
@Override
protected String getBasePath() {
return "/plugins/lombok/testData/inspection/dataflow";
}
public void testSpringNonNullApiOnPackage () {
DataFlowInspectionTest.addJavaxNullabilityAnnotations(myFixture);
myFixture.addClass("""
package org.springframework.lang;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Target({ElementType.PACKAGE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Nonnull
@TypeQualifierDefault({ElementType.METHOD, ElementType.PARAMETER})
public @interface NonNullApi {
}""");
myFixture.addFileToProject("test/package-info.java", """
@NonNullApi
package test;
import org.springframework.lang.NonNullApi;""");
doTest();
}
}

View File

@@ -0,0 +1,33 @@
package test;
import lombok.Data;
import lombok.experimental.Accessors;
//IDEA-292093 @NonNullApi does not work on Lombok methods
public class SpringNonNullApiOnPackage {
public void test() {
// These trigger the "Passing 'null' argument to parameter annotated as @NotNull" inspection
var a = new Explicit(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>).setNn(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>);
var b = <warning descr="Condition 'a == null' is always 'false'">a == null</warning>;
// These do not
var c = new Lombok(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>).setNn(<warning descr="Passing 'null' argument to parameter annotated as @NotNull">null</warning>);
var d = <warning descr="Condition 'c == null' is always 'false'">c == null</warning>;
}
}
class Explicit {
public Explicit(String sexp) {
}
public String setNn(String s) {
return s;
}
}
@Data
@Accessors(chain = true)
class Lombok {
private String nn;
private final String slom;
}