diff --git a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml index 8d8fafcf6dc9..c150c848e9b2 100644 --- a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml +++ b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml @@ -35,6 +35,7 @@ + diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java index 85b427996145..9ada0f1409ce 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightControlFlowUtil.java @@ -318,6 +318,10 @@ public final class HighlightControlFlowUtil { boolean ignoreFinality) { if (variable instanceof ImplicitVariable) return null; if (!PsiUtil.isAccessedForReading(expression)) return null; + if (ContainerUtil.exists(VariableInitializedBeforeUsageSupport.EP_NAME.getExtensionList(), + ext -> ext.ignoreVariableExpression(expression, variable))) { + return null; + } int startOffset = expression.getTextRange().getStartOffset(); PsiElement topBlock; if (variable.hasInitializer()) { @@ -830,7 +834,7 @@ public final class HighlightControlFlowUtil { @Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { if (expression.isReferenceTo(variable) && - PsiUtil.isAccessedForWriting(expression) && + PsiUtil.isAccessedForWriting(expression) && ControlFlowUtil.isVariableAssignedInLoop(expression, variable)) { stopWalking(); stopped.set(true); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/VariableInitializedBeforeUsageSupport.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/VariableInitializedBeforeUsageSupport.java new file mode 100644 index 000000000000..886c598e80be --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/VariableInitializedBeforeUsageSupport.java @@ -0,0 +1,26 @@ +// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.codeInsight.daemon.impl.analysis; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiReferenceExpression; +import com.intellij.psi.PsiVariable; +import org.jetbrains.annotations.NotNull; + +/** + * Allows skipping 'Variable might not have been initialized' highlighting for specific PsiReference + */ +public interface VariableInitializedBeforeUsageSupport { + ExtensionPointName EP_NAME = + ExtensionPointName.create("com.intellij.lang.jvm.ignoreVariableInitializedBeforeUsageSupport"); + /** + * Checks if the given expression should be ignored for inspection. + * + * @param psiExpression the expression to be checked for ignoring the initializer + * @param psiVariable the variable from the expression resolving + * @return true if the inspection should be skipped for the {@code psiExpression}, + * otherwise false + */ + default boolean ignoreVariableExpression(@NotNull PsiReferenceExpression psiExpression, @NotNull PsiVariable psiVariable) { + return false; + } +} \ No newline at end of file diff --git a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/extension/LombokHighlightErrorFilter.java b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/extension/LombokHighlightErrorFilter.java index 1d6cde149b05..6308d97965a5 100644 --- a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/extension/LombokHighlightErrorFilter.java +++ b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/extension/LombokHighlightErrorFilter.java @@ -150,21 +150,6 @@ public class LombokHighlightErrorFilter implements HighlightInfoFilter { } private enum LombokHighlightFilter { - // ERROR HANDLERS - - //see com.intellij.java.lomboktest.LombokHighlightingTest.testGetterLazyVariableNotInitialized - VARIABLE_MIGHT_NOT_BEEN_INITIALIZED(HighlightSeverity.ERROR, CodeInsightColors.ERRORS_ATTRIBUTES) { - @Override - public boolean descriptionCheck(@Nullable String description, PsiElement highlightedElement) { - return JavaErrorBundle.message("variable.not.initialized", highlightedElement.getText()).equals(description); - } - - @Override - public boolean accept(@NotNull PsiElement highlightedElement) { - return !LazyGetterHandler.isLazyGetterHandled(highlightedElement); - } - }, - // WARNINGS HANDLERS // field should have lazy getter and should be initialized in constructors diff --git a/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/provider/LombokVariableInitializedBeforeUsageSupport.java b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/provider/LombokVariableInitializedBeforeUsageSupport.java new file mode 100644 index 000000000000..3f8eb581199c --- /dev/null +++ b/plugins/lombok/src/main/java/de/plushnikov/intellij/plugin/provider/LombokVariableInitializedBeforeUsageSupport.java @@ -0,0 +1,26 @@ +package de.plushnikov.intellij.plugin.provider; + +import com.intellij.codeInsight.daemon.impl.analysis.VariableInitializedBeforeUsageSupport; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import de.plushnikov.intellij.plugin.LombokClassNames; +import de.plushnikov.intellij.plugin.util.PsiAnnotationUtil; +import org.jetbrains.annotations.NotNull; + + +/** + * A class that implements the VariableInitializedBeforeUsageSupport interface to provide support for Lombok annotated variables. + * It checks if a variable expression should be ignored based on Lombok annotations. + */ +public class LombokVariableInitializedBeforeUsageSupport implements VariableInitializedBeforeUsageSupport { + @Override + public boolean ignoreVariableExpression(@NotNull PsiReferenceExpression psiExpression, @NotNull PsiVariable psiVariable) { + final PsiField field = PsiTreeUtil.getParentOfType(psiExpression, PsiField.class); + if (field == null) { + return false; + } + + final PsiAnnotation getterAnnotation = field.getAnnotation(LombokClassNames.GETTER); + return null != getterAnnotation && PsiAnnotationUtil.getBooleanAnnotationValue(getterAnnotation, "lazy", false); + } +} diff --git a/plugins/lombok/src/main/resources/META-INF/plugin.xml b/plugins/lombok/src/main/resources/META-INF/plugin.xml index 7058070fa106..dad09fc45d1d 100644 --- a/plugins/lombok/src/main/resources/META-INF/plugin.xml +++ b/plugins/lombok/src/main/resources/META-INF/plugin.xml @@ -54,6 +54,7 @@ + bar; private Car car; public GetterLazyInvocationProduceNPE(Bar bar, Car car) {