diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/AbstractDelegateInspectionWithExcludedProperties.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/AbstractDelegateInspectionWithExcludedProperties.java new file mode 100644 index 000000000..c67bf92fb --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/AbstractDelegateInspectionWithExcludedProperties.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat Inc. and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package com.redhat.devtools.intellij.lsp4mp4ij.psi.core.inspections; + +import com.intellij.codeInspection.LocalInspectionTool; +import com.intellij.codeInspection.ui.InspectionOptionsPanel; +import com.intellij.codeInspection.ui.ListEditForm; +import com.redhat.devtools.intellij.lsp4mp4ij.MicroProfileBundle; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + +/** + * No-op {@link LocalInspectionTool} used as a basis for mapping properties inspection severities to matching LSP severities. + * Adds the possibility to define excluded properties. + */ +public abstract class AbstractDelegateInspectionWithExcludedProperties extends LocalInspectionTool { + + public final @NotNull List excludeList = new ArrayList<>(); + + public JComponent createOptionsPanel() { + InspectionOptionsPanel panel = new InspectionOptionsPanel(); + + var injectionListTable = new ListEditForm("", MicroProfileBundle.message("microprofile.properties.validation.excluded.properties"), excludeList); + + panel.addGrowing(injectionListTable.getContentPanel()); + + return panel; + } +} diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesExpressionsInspection.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesExpressionsInspection.java index 7b2949fda..a7a896780 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesExpressionsInspection.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesExpressionsInspection.java @@ -16,6 +16,6 @@ /** * Dummy inspection for expression values in Microprofile properties files */ -public class MicroProfilePropertiesExpressionsInspection extends AbstractDelegateInspection { +public class MicroProfilePropertiesExpressionsInspection extends AbstractDelegateInspectionWithExcludedProperties { public static final String ID = getShortName(MicroProfilePropertiesExpressionsInspection.class.getSimpleName()); } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnassignedInspection.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnassignedInspection.java new file mode 100644 index 000000000..b3c4b078a --- /dev/null +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnassignedInspection.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2023 Red Hat Inc. and others. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 + * which is available at https://www.apache.org/licenses/LICENSE-2.0. + * + * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package com.redhat.devtools.intellij.lsp4mp4ij.psi.core.inspections; + +/** + * Dummy inspection for unknown properties in Microprofile properties files + */ +public class MicroProfilePropertiesUnassignedInspection extends AbstractDelegateInspectionWithExcludedProperties { + public static final String ID = getShortName(MicroProfilePropertiesUnassignedInspection.class.getSimpleName()); +} diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnknownInspection.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnknownInspection.java index 1672ea0e8..e8cb383c8 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnknownInspection.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/psi/core/inspections/MicroProfilePropertiesUnknownInspection.java @@ -13,9 +13,16 @@ *******************************************************************************/ package com.redhat.devtools.intellij.lsp4mp4ij.psi.core.inspections; +import java.util.Arrays; + /** * Dummy inspection for unknown properties in Microprofile properties files */ -public class MicroProfilePropertiesUnknownInspection extends AbstractDelegateInspection { +public class MicroProfilePropertiesUnknownInspection extends AbstractDelegateInspectionWithExcludedProperties { public static final String ID = getShortName(MicroProfilePropertiesUnknownInspection.class.getSimpleName()); + + public MicroProfilePropertiesUnknownInspection() { + super(); + excludeList.addAll(Arrays.asList("*/mp-rest/providers/*/priority", "mp.openapi.schema.*", "kafka-streams.*", "camel.*")); + } } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/MicroProfileInspectionsInfo.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/MicroProfileInspectionsInfo.java index df6607bf8..2f734dc31 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/MicroProfileInspectionsInfo.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/MicroProfileInspectionsInfo.java @@ -13,17 +13,16 @@ *******************************************************************************/ package com.redhat.devtools.intellij.lsp4mp4ij.settings; -import com.intellij.codeHighlighting.HighlightDisplayLevel; -import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.InspectionProfile; -import com.intellij.lang.annotation.HighlightSeverity; +import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.openapi.project.Project; import com.intellij.profile.codeInspection.InspectionProfileManager; import com.redhat.devtools.intellij.lsp4ij.operations.diagnostics.SeverityMapping; import com.redhat.devtools.intellij.lsp4mp4ij.psi.core.inspections.*; import org.eclipse.lsp4j.DiagnosticSeverity; -import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** @@ -39,6 +38,9 @@ public class MicroProfileInspectionsInfo { private DiagnosticSeverity valueSeverity = DiagnosticSeverity.Error; private DiagnosticSeverity requiredSeverity = null; private DiagnosticSeverity expressionSeverity = DiagnosticSeverity.Error; + private DiagnosticSeverity unassignedSeverity = DiagnosticSeverity.Warning; + private List excludedUnknownProperties; + private List excludedUnassignedProperties; private MicroProfileInspectionsInfo() { } @@ -52,9 +54,24 @@ public static MicroProfileInspectionsInfo getMicroProfileInspectionInfo(Project wrapper.valueSeverity = SeverityMapping.getSeverity(MicroProfilePropertiesValueInspection.ID, profile); wrapper.requiredSeverity = SeverityMapping.getSeverity(MicroProfilePropertiesRequiredInspection.ID, profile); wrapper.expressionSeverity = SeverityMapping.getSeverity(MicroProfilePropertiesExpressionsInspection.ID, profile); + wrapper.unassignedSeverity = SeverityMapping.getSeverity(MicroProfilePropertiesUnassignedInspection.ID, profile); + + wrapper.excludedUnknownProperties = getExclusions(profile, MicroProfilePropertiesUnknownInspection.ID, project); + wrapper.excludedUnassignedProperties = getExclusions(profile, MicroProfilePropertiesUnassignedInspection.ID, project); + return wrapper; } + private static List getExclusions(InspectionProfile profile, String inspectionId, Project project) { + List exclusions = new ArrayList<>(); + InspectionToolWrapper toolWrapper = profile.getInspectionTool(inspectionId, project); + if (toolWrapper != null && toolWrapper.getTool() instanceof AbstractDelegateInspectionWithExcludedProperties) { + AbstractDelegateInspectionWithExcludedProperties inspection = (AbstractDelegateInspectionWithExcludedProperties) toolWrapper.getTool(); + exclusions.addAll(inspection.excludeList); + } + return exclusions; + } + public DiagnosticSeverity unknownSeverity() { return unknownSeverity; } @@ -79,19 +96,28 @@ public DiagnosticSeverity requiredSeverity() { return requiredSeverity; } + public DiagnosticSeverity unassignedSeverity() { + return unassignedSeverity; + } + + public List getExcludedUnknownProperties() { + return excludedUnknownProperties; + } + + public List getExcludedUnassignedProperties() { + return excludedUnassignedProperties; + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MicroProfileInspectionsInfo that = (MicroProfileInspectionsInfo) o; - return syntaxSeverity == that.syntaxSeverity && unknownSeverity == that.unknownSeverity - && duplicateSeverity == that.duplicateSeverity && valueSeverity == that.valueSeverity - && requiredSeverity == that.requiredSeverity && expressionSeverity == that.expressionSeverity; + return syntaxSeverity == that.syntaxSeverity && unknownSeverity == that.unknownSeverity && duplicateSeverity == that.duplicateSeverity && valueSeverity == that.valueSeverity && requiredSeverity == that.requiredSeverity && expressionSeverity == that.expressionSeverity && unassignedSeverity == that.unassignedSeverity && Objects.equals(excludedUnknownProperties, that.excludedUnknownProperties) && Objects.equals(excludedUnassignedProperties, that.excludedUnassignedProperties); } @Override public int hashCode() { - return Objects.hash(syntaxSeverity, unknownSeverity, duplicateSeverity, valueSeverity, requiredSeverity, - expressionSeverity); + return Objects.hash(syntaxSeverity, unknownSeverity, duplicateSeverity, valueSeverity, requiredSeverity, expressionSeverity, unassignedSeverity, excludedUnknownProperties, excludedUnassignedProperties); } } diff --git a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/UserDefinedMicroProfileSettings.java b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/UserDefinedMicroProfileSettings.java index 5a8c99a31..f067d1548 100644 --- a/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/UserDefinedMicroProfileSettings.java +++ b/src/main/java/com/redhat/devtools/intellij/lsp4mp4ij/settings/UserDefinedMicroProfileSettings.java @@ -142,19 +142,30 @@ public Map toSettingsForMicroProfileLS() { tools.put("validation", validation); validation.put("enabled", isValidationEnabled()); validation.put("syntax", getSeverityNode(inspectionsInfo.syntaxSeverity())); - validation.put("unknown", getSeverityNode(inspectionsInfo.unknownSeverity())); validation.put("duplicate", getSeverityNode(inspectionsInfo.duplicateSeverity())); validation.put("value", getSeverityNode(inspectionsInfo.valueSeverity())); validation.put("required", getSeverityNode(inspectionsInfo.requiredSeverity())); validation.put("expression", getSeverityNode(inspectionsInfo.expressionSeverity())); + + validation.put("unknown", getSeverityAndExclusions(inspectionsInfo.unknownSeverity(), inspectionsInfo.getExcludedUnknownProperties())); + validation.put("unassigned", getSeverityAndExclusions(inspectionsInfo.unassignedSeverity(), inspectionsInfo.getExcludedUnassignedProperties())); + return settings; } + private Map getSeverityAndExclusions(DiagnosticSeverity severity, List exclusions) { + Map inspection = new HashMap<>(); + inspection.put("severity", SeverityMapping.toString(severity)); + if (exclusions != null && !exclusions.isEmpty()) { + inspection.put("excluded", exclusions); + } + return inspection; + } + private Map getSeverityNode(DiagnosticSeverity severity) { return Collections.singletonMap("severity", SeverityMapping.toString(severity)); } - public static class MyState { @Tag("validationEnabled") diff --git a/src/main/resources/META-INF/lsp4ij-quarkus.xml b/src/main/resources/META-INF/lsp4ij-quarkus.xml index a66f7383a..30b6a7ee5 100644 --- a/src/main/resources/META-INF/lsp4ij-quarkus.xml +++ b/src/main/resources/META-INF/lsp4ij-quarkus.xml @@ -113,6 +113,15 @@ enabledByDefault="true" level="ERROR" implementationClass="com.redhat.devtools.intellij.lsp4mp4ij.psi.core.inspections.MicroProfilePropertiesExpressionsInspection"/> + diff --git a/src/main/resources/inspectionDescriptions/MicroProfilePropertiesUnassigned.html b/src/main/resources/inspectionDescriptions/MicroProfilePropertiesUnassigned.html new file mode 100644 index 000000000..2664fc1a8 --- /dev/null +++ b/src/main/resources/inspectionDescriptions/MicroProfilePropertiesUnassigned.html @@ -0,0 +1,20 @@ + + +Reports properties in .java files unassigned from properties file. +

Example:

+

+@ConfigProperty(name="missing.from.properties")
+private String myConfig;
+
+
+

+ ⚠ This inspection is used to configure the Tools for MicroProfile server in Settings | Languages & Frameworks | Language Servers.

+ Consequently, some limitations apply: +

+
    +
  • Scope, Severity and Highlighting are ignored
  • +
  • Excluded properties are respected
  • +
+
+ + \ No newline at end of file diff --git a/src/main/resources/messages/MicroProfileBundle.properties b/src/main/resources/messages/MicroProfileBundle.properties index df72199f0..61e6bd28b 100644 --- a/src/main/resources/messages/MicroProfileBundle.properties +++ b/src/main/resources/messages/MicroProfileBundle.properties @@ -36,3 +36,4 @@ microprofile.properties.validation.unassigned=Unassigned properties microprofile.java=Java microprofile.java.title=MicroProfile configuration in Java files microprofile.java.codeLens.url.enabled=Show Rest endpoint URL as inlay hint? +microprofile.properties.validation.excluded.properties=Excluded properties. Patterns can be used ('*' = any string, '?' = any character). \ No newline at end of file