[lombok] IDEA-279512 Prevent false-positive for Local variable or parameter can be final inspection with lombok.val

GitOrigin-RevId: 9e4f945cf982e8099fcf626565babc576544d7a3
This commit is contained in:
Michail Plushnikov
2025-02-11 23:24:15 +00:00
committed by intellij-monorepo-bot
parent 5db4998301
commit 4a760237af
7 changed files with 102 additions and 0 deletions
@@ -34,6 +34,7 @@
<extensionPoint qualifiedName="com.intellij.codeInsight.changeVariableTypeQuickFixProvider" interface="com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.lang.jvm.annotationPackageSupport" interface="com.intellij.codeInsight.annoPackages.AnnotationPackageSupport" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.lang.jvm.ignoreAnnotationParamSupport" interface="com.intellij.codeInspection.DefaultAnnotationParamInspection$IgnoreAnnotationParamSupport" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.lang.jvm.ignoreVariableCanBeFinalSupport" interface="com.intellij.codeInspection.localCanBeFinal.IgnoreVariableCanBeFinalSupport" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.javaLanguageLevelPusherCustomizer" interface="com.intellij.openapi.roots.impl.JavaLanguageLevelPusherCustomizer" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.propertyAccessorDetector" interface="com.intellij.psi.util.PropertyAccessorDetector" dynamic="true"/>
@@ -0,0 +1,24 @@
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.localCanBeFinal;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiVariable;
import org.jetbrains.annotations.NotNull;
/**
* Allows skipping 'Local variable or parameter can be final' highlighting for specific PsiVariables
*/
public interface IgnoreVariableCanBeFinalSupport {
ExtensionPointName<IgnoreVariableCanBeFinalSupport> EP_NAME =
ExtensionPointName.create("com.intellij.lang.jvm.ignoreVariableCanBeFinalSupport");
/**
* Checks if the given variable should be ignored for inspection.
*
* @param psiVariable the variable to check
* @return true if the inspection should be skipped for the {@code psiVariable}, otherwise false
*/
default boolean ignoreVariable(@NotNull PsiVariable psiVariable) {
return false;
}
}
@@ -13,6 +13,7 @@ import com.intellij.psi.controlFlow.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.MathUtil;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -365,6 +366,10 @@ public class LocalCanBeFinal extends AbstractBaseJavaLocalInspectionTool impleme
if (modifierList == null) return true;
if (modifierList.hasExplicitModifier(PsiModifier.FINAL)) return true;
if (!REPORT_IMPLICIT_FINALS && modifierList.hasModifierProperty(PsiModifier.FINAL)) return true;
if (ContainerUtil.exists(IgnoreVariableCanBeFinalSupport.EP_NAME.getExtensionList(),
ext -> ext.ignoreVariable(psiVariable))) {
return true;
}
if (psiVariable instanceof PsiLocalVariable) {
return !REPORT_VARIABLES;
}
@@ -0,0 +1,18 @@
package de.plushnikov.intellij.plugin.provider;
import com.intellij.codeInspection.localCanBeFinal.IgnoreVariableCanBeFinalSupport;
import com.intellij.psi.PsiLocalVariable;
import com.intellij.psi.PsiVariable;
import de.plushnikov.intellij.plugin.processor.ValProcessor;
import org.jetbrains.annotations.NotNull;
/**
* Ignore VariableCanBeFinal-Inspection for lombok val annotation
*/
public final class LombokIgnoreVariableCanBeFinalSupport implements IgnoreVariableCanBeFinalSupport {
@Override
public boolean ignoreVariable(@NotNull PsiVariable psiVariable) {
return (psiVariable instanceof PsiLocalVariable psiLocalVariable && ValProcessor.isVal(psiLocalVariable));
}
}
@@ -53,6 +53,7 @@
<lang.psiAugmentProvider implementation="de.plushnikov.intellij.plugin.provider.LombokAugmentProvider"/>
<lang.jvm.annotationPackageSupport implementation="de.plushnikov.intellij.plugin.provider.LombokAnnotationSupport"/>
<lang.jvm.ignoreAnnotationParamSupport implementation="de.plushnikov.intellij.plugin.provider.LombokDefaultAnnotationParamSupport"/>
<lang.jvm.ignoreVariableCanBeFinalSupport implementation="de.plushnikov.intellij.plugin.provider.LombokIgnoreVariableCanBeFinalSupport"/>
<implicitUsageProvider implementation="de.plushnikov.intellij.plugin.provider.LombokImplicitUsageProvider"/>
<projectConfigurable groupId="language"
key="plugin.settings.title" bundle="messages.LombokBundle"
@@ -0,0 +1,42 @@
package com.intellij.java.lomboktest;
import com.intellij.codeInspection.localCanBeFinal.LocalCanBeFinal;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import de.plushnikov.intellij.plugin.LombokTestUtil;
import org.jetbrains.annotations.NotNull;
public class LombokLocalCanBeFinalTest extends LightJavaCodeInsightFixtureTestCase {
private LocalCanBeFinal myTool;
@Override
protected String getBasePath() {
return "/plugins/lombok/testData/inspection/localCanBeFinal";
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LombokTestUtil.LOMBOK_NEW_DESCRIPTOR;
}
@Override
protected void setUp() throws Exception {
super.setUp();
myTool = new LocalCanBeFinal();
}
private void doTest() {
myFixture.enableInspections(myTool);
myFixture.testHighlighting(true, false, false, getTestName(false) + ".java");
}
public void testLombokVal() {
myTool.REPORT_PARAMETERS = true;
myTool.REPORT_VARIABLES = true;
myTool.REPORT_IMPLICIT_FINALS = true;
doTest();
}
}
@@ -0,0 +1,11 @@
import lombok.val;
public class LombokVal {
public String someMethod(String <warning descr="Parameter 'param' can have 'final' modifier">param</warning>) {
val someVar = "Constant";
val someVar2 = someVar + param;
return "Result: " + someVar2;
}
}