-
Notifications
You must be signed in to change notification settings - Fork 128
Quick fix to ignore markers on SonarQube related "SuppressWarnings" #1045
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
thahnen
wants to merge
5
commits into
SonarSource:master
Choose a base branch
from
thahnen:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
9f40d50
Do not require CFamily plug-in on forks
thahnen d077d60
Quick fix to ignore markers on SonarQube related "SuppressWarnings"
thahnen ded1d36
Fix Eclipse API incompatibility
thahnen b1caaf7
Apply PR feedback and therefore adjust tests
thahnen 9064926
Apply PR feedback
thahnen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
146 changes: 146 additions & 0 deletions
146
....tests/src/test/java/org/sonarlint/eclipse/jdt/internal/SuppressWarningsQuickFixTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| /* | ||
| * SonarLint for Eclipse | ||
| * Copyright (C) SonarSource Sàrl | ||
| * sonarlint@sonarsource.com | ||
| * | ||
| * This program is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU Lesser General Public | ||
| * License as published by the Free Software Foundation; either | ||
| * version 3 of the License, or (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public License | ||
| * along with this program; if not, write to the Free Software Foundation, | ||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| */ | ||
| package org.sonarlint.eclipse.jdt.internal; | ||
|
|
||
| import org.eclipse.core.resources.IMarker; | ||
| import org.eclipse.core.resources.IProject; | ||
| import org.eclipse.core.resources.IResource; | ||
| import org.eclipse.core.runtime.CoreException; | ||
| import org.eclipse.jdt.core.JavaCore; | ||
| import org.junit.After; | ||
| import org.junit.Test; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.mockito.Mockito.mock; | ||
| import static org.mockito.Mockito.when; | ||
|
|
||
| public class SuppressWarningsQuickFixTest { | ||
| private static final SuppressWarningsQuickFixGenerator generator = new SuppressWarningsQuickFixGenerator(); | ||
|
|
||
| @After | ||
| public void after() { | ||
| var options = JavaCore.getOptions(); | ||
| options.put(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN, JavaCore.WARNING); | ||
| JavaCore.setOptions(options); | ||
| } | ||
|
|
||
| @Test | ||
| public void testIrrelevantMarkers() throws CoreException { | ||
| var marker = mock(IMarker.class); | ||
| when(marker.getType()).thenReturn("noJavaProblem"); | ||
|
|
||
| assertThat(generator.hasResolutions(marker)).isFalse(); | ||
| assertThat(generator.getResolutions(marker)).isEmpty(); | ||
|
|
||
| when(marker.getType()).thenReturn(SuppressWarningsQuickFixGenerator.JAVA_PROBLEM_TYPE); | ||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(null); | ||
|
|
||
| assertThat(generator.hasResolutions(marker)).isFalse(); | ||
|
|
||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_GENERAL); | ||
|
|
||
| assertThat(generator.hasResolutions(marker)).isFalse(); | ||
| } | ||
|
|
||
| @Test | ||
| public void testRelevantMarkers() throws CoreException { | ||
| var marker = getRelevantMarker(); | ||
| assertThat(generator.hasResolutions(marker)).isTrue(); | ||
|
|
||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_GENERAL | ||
| + SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_JAVA_SECURITY_ISSUE); | ||
| assertThat(generator.hasResolutions(marker)).isTrue(); | ||
|
|
||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_GENERAL | ||
| + SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_JAVA_BUGS_ISSUE); | ||
| assertThat(generator.hasResolutions(marker)).isTrue(); | ||
|
|
||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_GENERAL | ||
| + SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_JAVA_ARCHITECTURE_ISSUE); | ||
| assertThat(generator.hasResolutions(marker)).isTrue(); | ||
| } | ||
|
|
||
| @Test | ||
| public void testQuickFix() throws CoreException { | ||
| var marker = getRelevantMarker(); | ||
|
|
||
| var quickFix = getQuickFix(marker); | ||
| assertThat(quickFix.getLabel()).contains("SonarQube"); | ||
| assertThat(quickFix.getDescription()).contains("SonarQube"); | ||
|
|
||
| quickFix.run(marker); | ||
| assertThat(JavaCore.getOption(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN)).isEqualTo(JavaCore.IGNORE); | ||
| } | ||
|
|
||
| /** | ||
| * This tests the conditions to check whether the project related resource has a project and therefore can delegate | ||
| * it to the JDT logic to create a Java project. As there is no project, it is not possible. | ||
| */ | ||
| @Test | ||
| public void testWithoutProjectMarker() throws CoreException { | ||
| var resourceWithoutProject = mock(IResource.class); | ||
| when(resourceWithoutProject.getProject()).thenReturn(null); | ||
|
|
||
| var markerWithResource = getRelevantMarker(); | ||
| when(markerWithResource.getResource()).thenReturn(resourceWithoutProject); | ||
|
|
||
| var quickFix = getQuickFix(markerWithResource); | ||
| quickFix.run(markerWithResource); | ||
| assertThat(JavaCore.getOption(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN)).isEqualTo(JavaCore.IGNORE); | ||
| } | ||
|
|
||
| /** | ||
| * This tests the marker with a project, but the JavaModel cannot be mocked and therefore the Java project created | ||
| * by JDT logic is closed. The quickfix therefore falls back to the global options. | ||
| * | ||
| * The JavaModel and the related logic can only be tested by an integration test which is quite costly. | ||
| */ | ||
| @Test | ||
| public void testClosedJavaProjectMarker() throws CoreException { | ||
| var closedProject = mock(IProject.class); | ||
| when(closedProject.getType()).thenReturn(IResource.PROJECT); | ||
|
|
||
| var resourceWithProject = mock(IResource.class); | ||
| when(resourceWithProject.getProject()).thenReturn(closedProject); | ||
|
|
||
| var markerWithResource = getRelevantMarker(); | ||
| when(markerWithResource.getResource()).thenReturn(resourceWithProject); | ||
|
|
||
| var quickFix = getQuickFix(markerWithResource); | ||
| quickFix.run(markerWithResource); | ||
|
|
||
| // This means the option is not applied on the project but global level. | ||
| assertThat(JavaCore.getOption(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN)).isEqualTo(JavaCore.IGNORE); | ||
| } | ||
|
|
||
| private IMarker getRelevantMarker() throws CoreException { | ||
| var marker = mock(IMarker.class); | ||
| when(marker.getType()).thenReturn(SuppressWarningsQuickFixGenerator.JAVA_PROBLEM_TYPE); | ||
| when(marker.getAttribute(IMarker.MESSAGE)).thenReturn(SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_GENERAL | ||
| + SuppressWarningsQuickFixGenerator.MARKER_MESSAGE_JAVA_ISSUE); | ||
| return marker; | ||
| } | ||
|
|
||
| private SuppressWarningsQuickFix getQuickFix(IMarker marker) { | ||
| var quickFixes = generator.getResolutions(marker); | ||
| assertThat(quickFixes).hasSize(1); | ||
| return (SuppressWarningsQuickFix) quickFixes[0]; | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
...onarlint.eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/SuppressWarningsQuickFix.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /* | ||
| * SonarLint for Eclipse | ||
| * Copyright (C) SonarSource Sàrl | ||
| * sonarlint@sonarsource.com | ||
| * | ||
| * This program is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU Lesser General Public | ||
| * License as published by the Free Software Foundation; either | ||
| * version 3 of the License, or (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public License | ||
| * along with this program; if not, write to the Free Software Foundation, | ||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| */ | ||
| package org.sonarlint.eclipse.jdt.internal; | ||
|
|
||
| import org.eclipse.core.resources.IMarker; | ||
| import org.eclipse.jdt.core.JavaCore; | ||
| import org.eclipse.swt.graphics.Image; | ||
| import org.eclipse.ui.IMarkerResolution2; | ||
| import org.sonarlint.eclipse.ui.internal.SonarLintImages; | ||
|
|
||
| public class SuppressWarningsQuickFix implements IMarkerResolution2 { | ||
| @Override | ||
| public String getLabel() { | ||
| return "Disable warnings on \"@SuppressWarnings(...)\" for SonarQube issues"; | ||
| } | ||
|
|
||
| @Override | ||
| public String getDescription() { | ||
| return "SonarQube uses custom ids that can be set in \"@SuppressWarnings\" to be picked up by the language " | ||
| + "analyzers to suppress potential rule violations. Eclipse JDT does not recognize these IDs and reports them " | ||
| + "as unsupported. This quick fix will disable this compiler warning on the project level if project specific " | ||
| + "Eclipse JDT configurations are available, otherwise on the workspace level."; | ||
| } | ||
|
|
||
| @Override | ||
| public Image getImage() { | ||
| return SonarLintImages.RESOLUTION_QUICKFIX_CHANGE; | ||
| } | ||
|
|
||
| @Override | ||
| public void run(IMarker marker) { | ||
| var resource = marker.getResource(); | ||
| if (resource != null) { | ||
| var javaProject = JavaCore.create(resource.getProject()); | ||
|
thahnen marked this conversation as resolved.
|
||
| if (javaProject != null && javaProject.exists()) { | ||
| var projectOptions = javaProject.getOptions(false); | ||
| if (!projectOptions.isEmpty()) { | ||
| projectOptions.put(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN, JavaCore.IGNORE); | ||
| javaProject.setOptions(projectOptions); | ||
| return; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| var options = JavaCore.getOptions(); | ||
| options.put(JavaCore.COMPILER_PB_UNHANDLED_WARNING_TOKEN, JavaCore.IGNORE); | ||
| JavaCore.setOptions(options); | ||
| } | ||
| } | ||
71 changes: 71 additions & 0 deletions
71
...eclipse.jdt/src/org/sonarlint/eclipse/jdt/internal/SuppressWarningsQuickFixGenerator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| /* | ||
| * SonarLint for Eclipse | ||
| * Copyright (C) SonarSource Sàrl | ||
| * sonarlint@sonarsource.com | ||
| * | ||
| * This program is free software; you can redistribute it and/or | ||
| * modify it under the terms of the GNU Lesser General Public | ||
| * License as published by the Free Software Foundation; either | ||
| * version 3 of the License, or (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| * Lesser General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU Lesser General Public License | ||
| * along with this program; if not, write to the Free Software Foundation, | ||
| * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
| */ | ||
| package org.sonarlint.eclipse.jdt.internal; | ||
|
|
||
| import org.eclipse.core.resources.IMarker; | ||
| import org.eclipse.core.runtime.CoreException; | ||
| import org.eclipse.ui.IMarkerResolution; | ||
| import org.eclipse.ui.IMarkerResolutionGenerator2; | ||
| import org.sonarlint.eclipse.core.SonarLintLogger; | ||
|
|
||
| /** | ||
| * Generator for the Quick Fox on the "Unsupported @SuppressWarnings(...)" marker that is added when the value(s) | ||
| * provided is one indicating a SonarQube-related rule - these are unknown to Eclipse JDT. | ||
| */ | ||
| public class SuppressWarningsQuickFixGenerator implements IMarkerResolutionGenerator2 { | ||
| static final String JAVA_PROBLEM_TYPE = "org.eclipse.jdt.core.problem"; //$NON-NLS-1$ | ||
| static final String MARKER_MESSAGE_GENERAL = "Unsupported @SuppressWarnings"; //$NON-NLS-1$ | ||
| static final String MARKER_MESSAGE_JAVA_ISSUE = "java:"; //$NON-NLS-1$ | ||
| static final String MARKER_MESSAGE_JAVA_SECURITY_ISSUE = "javasecurity:"; //$NON-NLS-1$ | ||
| static final String MARKER_MESSAGE_JAVA_BUGS_ISSUE = "javabugs:"; //$NON-NLS-1$ | ||
| static final String MARKER_MESSAGE_JAVA_ARCHITECTURE_ISSUE = "javaarchitecture:"; //$NON-NLS-1$ | ||
|
|
||
| @Override | ||
| public IMarkerResolution[] getResolutions(IMarker marker) { | ||
| if (isSuppressWarningsJavaProblem(marker)) { | ||
| return new IMarkerResolution[] {new SuppressWarningsQuickFix()}; | ||
| } | ||
| return new IMarkerResolution[0]; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean hasResolutions(IMarker marker) { | ||
| return isSuppressWarningsJavaProblem(marker); | ||
| } | ||
|
|
||
| private boolean isSuppressWarningsJavaProblem(IMarker marker) { | ||
| if (!JavaProjectConfiguratorExtension.isJdtPresent()) { | ||
| return false; | ||
| } | ||
|
|
||
| try { | ||
| var isJavaProblem = marker.getType().equals(JAVA_PROBLEM_TYPE); | ||
| var message = (String) marker.getAttribute(IMarker.MESSAGE); | ||
|
thahnen marked this conversation as resolved.
|
||
| return isJavaProblem && message != null && message.contains(MARKER_MESSAGE_GENERAL) | ||
| && (message.toLowerCase().contains(MARKER_MESSAGE_JAVA_ISSUE) | ||
| || message.toLowerCase().contains(MARKER_MESSAGE_JAVA_SECURITY_ISSUE) | ||
| || message.toLowerCase().contains(MARKER_MESSAGE_JAVA_BUGS_ISSUE) | ||
| || message.toLowerCase().contains(MARKER_MESSAGE_JAVA_ARCHITECTURE_ISSUE)); | ||
| } catch (CoreException err) { | ||
| SonarLintLogger.get().error(err.getMessage(), err); | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.