From 5b81288f357dc064c05d74ed6c2e896acf9325ac Mon Sep 17 00:00:00 2001 From: Tobias Hahnen Date: Mon, 19 Aug 2024 16:44:38 +0200 Subject: [PATCH] SLE-920: Enhance the extension point for diff viewers Enhance the extension point used for syntax highlighting with a new method to take into account the compare/diff viewer. Added implementations for JDT (Java/JSP) and CDT (C/C++) but not PyDev due to a missing `Export-Package` statement in the plug-in. --- .../META-INF/MANIFEST.MF | 4 ++- .../CProjectConfiguratorExtension.java | 25 +++++++++++++++++-- .../eclipse/cdt/internal/CdtUiUtils.java | 8 ++++++ .../META-INF/MANIFEST.MF | 2 ++ .../rule/ISyntaxHighlightingProvider.java | 25 ++++++++++++++++++- .../META-INF/MANIFEST.MF | 1 + .../JavaProjectConfiguratorExtension.java | 12 +++++++++ .../eclipse/jdt/internal/JdtUiUtils.java | 8 ++++++ 8 files changed, 81 insertions(+), 4 deletions(-) diff --git a/org.sonarlint.eclipse.cdt/META-INF/MANIFEST.MF b/org.sonarlint.eclipse.cdt/META-INF/MANIFEST.MF index 2d58896e4..9dd3ebb93 100644 --- a/org.sonarlint.eclipse.cdt/META-INF/MANIFEST.MF +++ b/org.sonarlint.eclipse.cdt/META-INF/MANIFEST.MF @@ -14,7 +14,9 @@ Require-Bundle: org.eclipse.core.runtime, org.sonarlint.eclipse.core, org.eclipse.core.filesystem, org.eclipse.jdt.annotation;resolution:=optional, - org.eclipse.text + org.eclipse.text, + org.eclipse.compare, + org.eclipse.swt Import-Package: org.eclipse.ui.texteditor, org.eclipse.jface.preference Export-Package: org.sonarlint.eclipse.cdt.internal;x-friends:="org.sonarlint.eclipse.core.tests" diff --git a/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CProjectConfiguratorExtension.java b/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CProjectConfiguratorExtension.java index dfcd0fdfa..2112dda31 100644 --- a/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CProjectConfiguratorExtension.java +++ b/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CProjectConfiguratorExtension.java @@ -25,6 +25,8 @@ import java.util.Set; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -32,6 +34,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.widgets.Composite; import org.sonarlint.eclipse.core.SonarLintLogger; import org.sonarlint.eclipse.core.analysis.IAnalysisConfigurator; import org.sonarlint.eclipse.core.analysis.IFileLanguageProvider; @@ -64,6 +67,15 @@ private static boolean isCdtPresent() { } } + private static boolean isCdtUiPresent() { + try { + Class.forName("org.eclipse.cdt.ui.CUIPlugin"); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + @Override public Set enableLanguages() { // Objective-C is not supported by CDT! @@ -103,7 +115,7 @@ public SonarLintLanguage language(ISonarLintFile file) { @Override public Optional sourceViewerConfiguration(String ruleLanguage) { - if (isCdtPresent() && (ruleLanguage.equals(C_LANGUAGE_KEY) || ruleLanguage.equals(CPP_LANGUAGE_KEY))) { + if (isCdtUiPresent() && (ruleLanguage.equals(C_LANGUAGE_KEY) || ruleLanguage.equals(CPP_LANGUAGE_KEY))) { return Optional.of(CdtUiUtils.sourceViewerConfiguration()); } return Optional.empty(); @@ -111,9 +123,18 @@ public Optional sourceViewerConfiguration(String rule @Override public Optional documentPartitioner(String ruleLanguage) { - if (isCdtPresent() && (ruleLanguage.equals(C_LANGUAGE_KEY) || ruleLanguage.equals(CPP_LANGUAGE_KEY))) { + if (isCdtUiPresent() && (ruleLanguage.equals(C_LANGUAGE_KEY) || ruleLanguage.equals(CPP_LANGUAGE_KEY))) { return Optional.of(CdtUiUtils.documentPartitioner()); } return Optional.empty(); } + + @Nullable + @Override + public TextMergeViewer getTextMergeViewer(String ruleLanguage, Composite parent, CompareConfiguration mp) { + if (isCdtUiPresent() && (ruleLanguage.equals(C_LANGUAGE_KEY) || ruleLanguage.equals(CPP_LANGUAGE_KEY))) { + return CdtUiUtils.getTextMergeViewer(parent, mp); + } + return null; + } } diff --git a/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CdtUiUtils.java b/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CdtUiUtils.java index c5c6f9442..16fc08132 100644 --- a/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CdtUiUtils.java +++ b/org.sonarlint.eclipse.cdt/src/org/sonarlint/eclipse/cdt/internal/CdtUiUtils.java @@ -19,11 +19,15 @@ */ package org.sonarlint.eclipse.cdt.internal; +import org.eclipse.cdt.internal.ui.compare.CMergeViewer; import org.eclipse.cdt.internal.ui.text.doctools.DocCommentOwnerManager; import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.text.CSourceViewerConfiguration; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.widgets.Composite; public class CdtUiUtils { @@ -42,4 +46,8 @@ public static IDocumentPartitioner documentPartitioner() { var owner = DocCommentOwnerManager.getInstance().getWorkspaceCommentOwner(); return CUIPlugin.getDefault().getTextTools().createDocumentPartitioner(owner); } + + public static TextMergeViewer getTextMergeViewer(Composite parent, CompareConfiguration mp) { + return new CMergeViewer(parent, 0, mp); + } } diff --git a/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF b/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF index 8ae40770d..dd70493b5 100644 --- a/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF +++ b/org.sonarlint.eclipse.core/META-INF/MANIFEST.MF @@ -39,11 +39,13 @@ Require-Bundle: org.eclipse.equinox.security, org.eclipse.core.net, org.eclipse.core.filesystem, org.eclipse.team.core, + org.eclipse.compare, org.eclipse.jdt.annotation;resolution:=optional, org.eclipse.jgit;resolution:=optional, org.eclipse.egit.core;resolution:=optional, org.eclipse.egit.ui;resolution:=optional, org.eclipse.text, + org.eclipse.swt, org.sonarsource.sonarlint.core.sonarlint-java-client-osgi;bundle-version="[10.4.0,10.5.0)" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-11 diff --git a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/rule/ISyntaxHighlightingProvider.java b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/rule/ISyntaxHighlightingProvider.java index 6e0bf5ff6..c55c83da5 100644 --- a/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/rule/ISyntaxHighlightingProvider.java +++ b/org.sonarlint.eclipse.core/src/org/sonarlint/eclipse/core/rule/ISyntaxHighlightingProvider.java @@ -20,8 +20,12 @@ package org.sonarlint.eclipse.core.rule; import java.util.Optional; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.widgets.Composite; /** * The rule descriptions containing code snippet require the correct syntax highlighting of the language to display @@ -37,7 +41,26 @@ public interface ISyntaxHighlightingProvider { Optional sourceViewerConfiguration(String ruleLanguage); /** - * @return the SourceViewer and its document requiring + * @return the SourceViewer and its document requiring a partitioner that is based on the plug-in implementing it */ Optional documentPartitioner(String ruleLanguage); + + /** + * This is used for displaying language (and therefore implementing plug-in) -specific difference viewers. The + * plug-in directly provides its implementation based on the parent element and the compare configuration that will + * be enhanced by the plug-in specific viewer. + * This is used for example by the "Open fix suggestion" feature in order to provide difference viewers based on the + * language the file has - enhancing the user experience. + * + * @since 10.6 + * + * @param ruleLanguage to be used to check whether this plug-in can contribute a viewer for this language + * @param parent the UI parent element which will embed the viewer + * @param used for configuring the viewer by providing information on the left and right side, e.g. label + * @return + */ + @Nullable + default TextMergeViewer getTextMergeViewer(String ruleLanguage, Composite parent, CompareConfiguration mp) { + return null; + } } diff --git a/org.sonarlint.eclipse.jdt/META-INF/MANIFEST.MF b/org.sonarlint.eclipse.jdt/META-INF/MANIFEST.MF index 68212455e..3d6b20eb9 100644 --- a/org.sonarlint.eclipse.jdt/META-INF/MANIFEST.MF +++ b/org.sonarlint.eclipse.jdt/META-INF/MANIFEST.MF @@ -15,6 +15,7 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.jdt.ui;resolution:=optional, org.sonarlint.eclipse.ui, org.eclipse.ui.ide, + org.eclipse.compare, org.eclipse.swt Import-Package: org.eclipse.ui.texteditor, org.eclipse.jface.preference diff --git a/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JavaProjectConfiguratorExtension.java b/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JavaProjectConfiguratorExtension.java index 53e78abb4..2bc3f5c3c 100644 --- a/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JavaProjectConfiguratorExtension.java +++ b/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JavaProjectConfiguratorExtension.java @@ -23,6 +23,8 @@ import java.util.EnumSet; import java.util.Optional; import java.util.Set; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; @@ -30,6 +32,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.widgets.Composite; import org.sonarlint.eclipse.core.analysis.IAnalysisConfigurator; import org.sonarlint.eclipse.core.analysis.IFileTypeProvider; import org.sonarlint.eclipse.core.analysis.IPreAnalysisContext; @@ -128,4 +131,13 @@ public Optional documentPartitioner(String ruleLanguage) { } return Optional.empty(); } + + @Nullable + @Override + public TextMergeViewer getTextMergeViewer(String ruleLanguage, Composite parent, CompareConfiguration mp) { + if (jdtUiPresent && ruleLanguage.equals(JAVA_LANGUAGE_KEY)) { + return JdtUiUtils.getTextMergeViewer(parent, mp); + } + return null; + } } diff --git a/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JdtUiUtils.java b/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JdtUiUtils.java index bf4502fdc..ea6a9f0b7 100644 --- a/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JdtUiUtils.java +++ b/org.sonarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/JdtUiUtils.java @@ -19,14 +19,18 @@ */ package org.sonarlint.eclipse.jdt.internal; +import org.eclipse.compare.CompareConfiguration; +import org.eclipse.compare.contentmergeviewer.TextMergeViewer; import org.eclipse.core.resources.IMarker; import org.eclipse.jdt.internal.ui.JavaPlugin; +import org.eclipse.jdt.internal.ui.compare.JavaMergeViewer; import org.eclipse.jdt.internal.ui.text.FastJavaPartitionScanner; import org.eclipse.jdt.ui.text.IJavaPartitions; import org.eclipse.jdt.ui.text.JavaSourceViewerConfiguration; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.rules.FastPartitioner; import org.eclipse.jface.text.source.SourceViewerConfiguration; +import org.eclipse.swt.widgets.Composite; import org.sonarlint.eclipse.core.internal.utils.CompatibilityUtils; import org.sonarlint.eclipse.ui.quickfixes.ISonarLintMarkerResolver; @@ -52,4 +56,8 @@ public static IDocumentPartitioner documentPartitioner() { IJavaPartitions.JAVA_STRING, IJavaPartitions.JAVA_CHARACTER, IJavaPartitions.JAVA_MULTI_LINE_STRING }); } + + public static TextMergeViewer getTextMergeViewer(Composite parent, CompareConfiguration mp) { + return new JavaMergeViewer(parent, 0, mp); + } }