From 0b409f5f36cb34c8d2b741e655a76eecaf24e964 Mon Sep 17 00:00:00 2001 From: Hope Hadfield Date: Tue, 30 Jan 2024 13:39:17 -0500 Subject: [PATCH] Add quick fixes to suppress certain warnings using @SuppressWarnings. Signed-off-by: Hope Hadfield --- .../corrections/QuickFixProcessor.java | 25 ++++----- .../SuppressWarningsSubProcessor.java | 53 +++++++++++++++++++ .../org.eclipse.jdt.ls.tp.target | 4 +- .../correction/MissingEnumQuickFixTest.java | 12 ++++- .../DocumentLifeCycleHandlerTest.java | 4 +- 5 files changed, 76 insertions(+), 22 deletions(-) create mode 100644 org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/SuppressWarningsSubProcessor.java diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java index 551a0b6d07..98b83edd99 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/QuickFixProcessor.java @@ -39,6 +39,7 @@ import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.manipulation.CUCorrectionProposalCore; import org.eclipse.jdt.core.manipulation.ChangeCorrectionProposalCore; +import org.eclipse.jdt.internal.corext.util.JavaModelUtil; import org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore; import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; import org.eclipse.jdt.internal.ui.text.correction.IProposalRelevance; @@ -533,17 +534,12 @@ private void process(CodeActionParams params, IInvocationContextCore context, IP // problem, proposals); // break; // case IProblem.UnhandledWarningToken: - // SuppressWarningsSubProcessor.addUnknownSuppressWarningProposals(context, - // problem, proposals); - // break; - // case IProblem.ProblemNotAnalysed: - // SuppressWarningsSubProcessor.addRemoveUnusedSuppressWarningProposals(context, - // problem, proposals); - // break; - // case IProblem.UnusedWarningToken: - // SuppressWarningsSubProcessor.addRemoveUnusedSuppressWarningProposals(context, - // problem, proposals); + // SuppressWarningsSubProcessor.addUnknownSuppressWarningProposals(context, problem, proposals); // break; + case IProblem.ProblemNotAnalysed: + case IProblem.UnusedWarningToken: + SuppressWarningsSubProcessor.addRemoveUnusedSuppressWarningProposals(context, problem, proposals); + break; case IProblem.MissingEnumConstantCase: case IProblem.MissingEnumDefaultCase: case IProblem.SwitchExpressionsYieldMissingEnumConstantCase: @@ -681,12 +677,9 @@ private void process(CodeActionParams params, IInvocationContextCore context, IP String str = problem.toString(); System.out.println(str); } - // if - // (JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) - // { - // SuppressWarningsSubProcessor.addSuppressWarningsProposals(context, - // problem, proposals); - // } + if (JavaModelUtil.is50OrHigher(context.getCompilationUnit().getJavaProject())) { + SuppressWarningsSubProcessor.addSuppressWarningsProposals(context, problem, proposals); + } // ConfigureProblemSeveritySubProcessor.addConfigureProblemSeverityProposal(context, // problem, proposals); } diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/SuppressWarningsSubProcessor.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/SuppressWarningsSubProcessor.java new file mode 100644 index 0000000000..c72d1ae4fa --- /dev/null +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/SuppressWarningsSubProcessor.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2024 Red Hat Inc. and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.ls.core.internal.corrections; + +import java.util.Collection; + +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.dom.ASTNode; +import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; +import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; +import org.eclipse.jdt.internal.ui.text.correction.IInvocationContextCore; +import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore; +import org.eclipse.jdt.internal.ui.text.correction.SuppressWarningsBaseSubProcessor; +import org.eclipse.jdt.internal.ui.text.correction.SuppressWarningsProposalCore; +import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler; +import org.eclipse.jdt.ui.text.java.correction.ASTRewriteCorrectionProposalCore; +import org.eclipse.lsp4j.CodeActionKind; + +public class SuppressWarningsSubProcessor extends SuppressWarningsBaseSubProcessor { + + public static void addSuppressWarningsProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) { + new SuppressWarningsSubProcessor().getSuppressWarningsProposals(context, problem, proposals); + } + + public static void addUnknownSuppressWarningProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) { + new SuppressWarningsSubProcessor().getUnknownSuppressWarningProposals(context, problem, proposals); + } + + public static void addRemoveUnusedSuppressWarningProposals(IInvocationContextCore context, IProblemLocationCore problem, Collection proposals) { + new SuppressWarningsSubProcessor().getRemoveUnusedSuppressWarningProposals(context, problem, proposals); + } + + @Override + protected ProposalKindWrapper createSuppressWarningsProposal(String warningToken, String label, ICompilationUnit cu, ASTNode node, ChildListPropertyDescriptor property, int relevance) { + return CodeActionHandler.wrap(new SuppressWarningsProposalCore(warningToken, label, cu, node, property, relevance), CodeActionKind.QuickFix); + } + + @Override + protected ProposalKindWrapper createASTRewriteCorrectionProposal(String name, ICompilationUnit cu, ASTRewrite rewrite, int relevance) { + return CodeActionHandler.wrap(new ASTRewriteCorrectionProposalCore(name, cu, rewrite, relevance), CodeActionKind.QuickFix); + } + +} diff --git a/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target b/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target index a5c0aab2a2..07b3632c51 100644 --- a/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target +++ b/org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target @@ -24,8 +24,8 @@ - - + + diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/MissingEnumQuickFixTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/MissingEnumQuickFixTest.java index c8259de465..cc0e12a7af 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/MissingEnumQuickFixTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/MissingEnumQuickFixTest.java @@ -71,7 +71,7 @@ public void testMissingEnumConstant() throws Exception { Range range = new Range(new Position(5, 16), new Position(5, 17)); setIgnoredCommands(ActionMessages.GenerateConstructorsAction_ellipsisLabel, ActionMessages.GenerateConstructorsAction_label); List> codeActions = evaluateCodeActions(cu, range); - assertEquals(3, codeActions.size()); + assertEquals(4, codeActions.size()); Either codeAction = codeActions.get(0); CodeAction action = codeAction.getRight(); assertEquals(CodeActionKind.QuickFix, action.getKind()); @@ -84,6 +84,10 @@ public void testMissingEnumConstant() throws Exception { assertEquals("Add missing case statements", action.getTitle()); edit = getTextEdit(codeAction); assertEquals("\n case One:\n break;\n default:\n break;", edit.getNewText()); + codeAction = codeActions.get(2); + action = codeAction.getRight(); + assertEquals(CodeActionKind.QuickFix, action.getKind()); + assertEquals("Add @SuppressWarnings 'incomplete-switch' to 'testing()'", action.getTitle()); } @Test @@ -112,7 +116,7 @@ public void testMissingEnumConstantDespiteDefault() throws Exception { options.put(JavaCore.COMPILER_PB_MISSING_ENUM_CASE_DESPITE_DEFAULT, JavaCore.ENABLED); fJProject.setOptions(options); codeActions = evaluateCodeActions(cu, range); - assertEquals(3, codeActions.size()); + assertEquals(4, codeActions.size()); Either codeAction = codeActions.get(0); CodeAction action = codeAction.getRight(); assertEquals(CodeActionKind.QuickFix, action.getKind()); @@ -125,6 +129,10 @@ public void testMissingEnumConstantDespiteDefault() throws Exception { assertEquals("Insert '//$CASES-OMITTED$'", action.getTitle()); edit = getTextEdit(codeAction); assertEquals(" //$CASES-OMITTED$\n ", edit.getNewText()); + codeAction = codeActions.get(2); + action = codeAction.getRight(); + assertEquals(CodeActionKind.QuickFix, action.getKind()); + assertEquals("Add @SuppressWarnings 'incomplete-switch' to 'testing()'", action.getTitle()); } private TextEdit getTextEdit(Either codeAction) { diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/DocumentLifeCycleHandlerTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/DocumentLifeCycleHandlerTest.java index a95efd1e0e..3f26a07b4f 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/DocumentLifeCycleHandlerTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/handlers/DocumentLifeCycleHandlerTest.java @@ -168,8 +168,8 @@ public void testRemoveDeadCodeAfterIf() throws Exception { ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null); List> codeActions = getCodeActions(cu); - assertEquals(codeActions.size(), 1); - assertEquals(codeActions.get(0).getRight().getKind(), CodeActionKind.QuickFix); + boolean hasCodeAction = codeActions.stream().anyMatch(codeAction -> "Remove (including condition)".equals(codeAction.getRight().getTitle())); + assertTrue("Code action to remove dead code not found", hasCodeAction); } protected List> getCodeActions(ICompilationUnit cu) throws JavaModelException {