Skip to content
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

Move the code action 'Change modifiers to final where possible' to a source action #1547

Merged
merged 4 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public interface JavaCodeActionKind {
*/
public static final String SOURCE_GENERATE_DELEGATE_METHODS = SOURCE_GENERATE + ".delegateMethods";

/**
* Generate final modifiers where possible
*/
public static final String SOURCE_GENERATE_FINAL_MODIFIERS = SOURCE_GENERATE + ".finalModifiers";

/**
* Override/Implement methods kind
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ public List<ChangeCorrectionProposal> getProposals(CodeActionParams params, IInv
getInverseLocalVariableProposals(params, context, coveringNode, proposals);

getMoveRefactoringProposals(params, context, coveringNode, proposals);
getMakeVariableDeclarationFinalProposals(context, proposals);

boolean noErrorsAtLocation = noErrorsAtLocation(locations);
if (noErrorsAtLocation) {
Expand Down Expand Up @@ -994,20 +993,4 @@ private static <T extends ASTNode> T getEnclosingHeader(ASTNode node, Class<T> h
}
return null;
}



private static boolean getMakeVariableDeclarationFinalProposals(IInvocationContext context, Collection<ChangeCorrectionProposal> resultingCollections) {
IProposableFix fix = (IProposableFix) VariableDeclarationFixCore.createCleanUp(context.getASTRoot(), true, true, true);

if (fix == null) {
return false;
}

FixCorrectionProposal proposal = new FixCorrectionProposal(fix, null, IProposalRelevance.MAKE_VARIABLE_DECLARATION_FINAL, context, CodeActionKind.Refactor);
proposal.setDisplayName("Change modifiers to final where possible");
resultingCollections.add(proposal);
return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ private ActionMessages() {
public static String GenerateConstructorsAction_label;
public static String GenerateConstructorsAction_ellipsisLabel;
public static String GenerateDelegateMethodsAction_label;
public static String GenerateFinalModifiersAction_label;
public static String MoveRefactoringAction_label;
public static String MoveRefactoringAction_templateLabel;
public static String InlineMethodRefactoringAction_label;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ GenerateToStringAction_label=Generate toString()...
GenerateConstructorsAction_label=Generate Constructors
GenerateConstructorsAction_ellipsisLabel=Generate Constructors...
GenerateDelegateMethodsAction_label=Generate Delegate Methods...
GenerateFinalModifiersAction_label=Change modifiers to final where possible
MoveRefactoringAction_label=Move...
MoveRefactoringAction_templateLabel=Move ''{0}''...
InlineMethodRefactoringAction_label=Inline Method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
import org.eclipse.jdt.core.manipulation.CoreASTProvider;
import org.eclipse.jdt.core.manipulation.OrganizeImportsOperation;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.fix.IProposableFix;
import org.eclipse.jdt.internal.corext.fix.VariableDeclarationFixCore;
import org.eclipse.jdt.internal.ui.text.correction.IProblemLocationCore;
import org.eclipse.jdt.ls.core.internal.ChangeUtil;
import org.eclipse.jdt.ls.core.internal.JDTUtils;
Expand All @@ -52,6 +54,8 @@
import org.eclipse.jdt.ls.core.internal.corrections.DiagnosticsHelper;
import org.eclipse.jdt.ls.core.internal.corrections.IInvocationContext;
import org.eclipse.jdt.ls.core.internal.corrections.InnovationContext;
import org.eclipse.jdt.ls.core.internal.corrections.proposals.FixCorrectionProposal;
import org.eclipse.jdt.ls.core.internal.corrections.proposals.IProposalRelevance;
import org.eclipse.jdt.ls.core.internal.handlers.CodeActionHandler;
import org.eclipse.jdt.ls.core.internal.handlers.GenerateConstructorsHandler;
import org.eclipse.jdt.ls.core.internal.handlers.GenerateConstructorsHandler.CheckConstructorsResponse;
Expand Down Expand Up @@ -173,6 +177,10 @@ public List<Either<Command, CodeAction>> getSourceActionCommands(CodeActionParam
Optional<Either<Command, CodeAction>> generateDelegateMethods = getGenerateDelegateMethodsAction(params, context, type);
addSourceActionCommand($, params.getContext(), generateDelegateMethods);

// Add final modifiers where possible
Optional<Either<Command, CodeAction>> generateFinalModifiers = addFinalModifierWherePossibleAction(context);
addSourceActionCommand($, params.getContext(), generateFinalModifiers);

return $;
}

Expand Down Expand Up @@ -382,6 +390,37 @@ private Optional<Either<Command, CodeAction>> getGenerateDelegateMethodsAction(C
}
}

private Optional<Either<Command, CodeAction>> addFinalModifierWherePossibleAction(IInvocationContext context) {
IProposableFix fix = (IProposableFix) VariableDeclarationFixCore.createCleanUp(context.getASTRoot(), true, true, true);

if (fix == null) {
return Optional.empty();
}

FixCorrectionProposal proposal = new FixCorrectionProposal(fix, null, IProposalRelevance.MAKE_VARIABLE_DECLARATION_FINAL, context, JavaCodeActionKind.SOURCE_GENERATE_FINAL_MODIFIERS);
WorkspaceEdit edit;
try {
edit = ChangeUtil.convertToWorkspaceEdit(proposal.getChange());
} catch (CoreException e) {
JavaLanguageServerPlugin.logException("Problem converting proposal to code actions", e);
return Optional.empty();
}

if (!ChangeUtil.hasChanges(edit)) {
return Optional.empty();
}
Command command = new Command(ActionMessages.GenerateFinalModifiersAction_label, CodeActionHandler.COMMAND_ID_APPLY_EDIT, Collections.singletonList(edit));
if (preferenceManager.getClientPreferences().isSupportedCodeActionKind(proposal.getKind())) {
CodeAction codeAction = new CodeAction(ActionMessages.GenerateFinalModifiersAction_label);
codeAction.setKind(proposal.getKind());
codeAction.setCommand(command);
codeAction.setDiagnostics(Collections.EMPTY_LIST);
return Optional.of(Either.forRight(codeAction));
} else {
return Optional.of(Either.forLeft(command));
}
}

private Optional<Either<Command, CodeAction>> convertToWorkspaceEditAction(CodeActionContext context, ICompilationUnit cu, String name, String kind, TextEdit edit) {
WorkspaceEdit workspaceEdit = convertToWorkspaceEdit(cu, edit);
if (!ChangeUtil.hasChanges(workspaceEdit)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ public void setup() throws Exception {
fJProject = newEmptyProject();
fJProject.setOptions(TestOptions.getDefaultOptions());
fSourceFolder = fJProject.getPackageFragmentRoot(fJProject.getProject().getFolder("src"));
setIgnoredKind(CodeActionKind.Refactor, JavaCodeActionKind.SOURCE_OVERRIDE_METHODS, JavaCodeActionKind.SOURCE_GENERATE_TO_STRING, JavaCodeActionKind.SOURCE_GENERATE_CONSTRUCTORS, JavaCodeActionKind.REFACTOR_EXTRACT_FIELD,
JavaCodeActionKind.REFACTOR_EXTRACT_VARIABLE, JavaCodeActionKind.REFACTOR_INTRODUCE_PARAMETER, CodeActionKind.RefactorInline);
setIgnoredKind(CodeActionKind.Refactor, JavaCodeActionKind.SOURCE_OVERRIDE_METHODS, JavaCodeActionKind.SOURCE_GENERATE_TO_STRING, JavaCodeActionKind.SOURCE_GENERATE_CONSTRUCTORS, JavaCodeActionKind.SOURCE_GENERATE_FINAL_MODIFIERS,
JavaCodeActionKind.REFACTOR_EXTRACT_FIELD, JavaCodeActionKind.REFACTOR_EXTRACT_VARIABLE, JavaCodeActionKind.REFACTOR_INTRODUCE_PARAMETER, CodeActionKind.RefactorInline);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public void setup() throws Exception {
fJProject = newEmptyProject();
fJProject.setOptions(TestOptions.getDefaultOptions());
fSourceFolder = fJProject.getPackageFragmentRoot(fJProject.getProject().getFolder("src"));
setIgnoredKind(CodeActionKind.Refactor, JavaCodeActionKind.SOURCE_OVERRIDE_METHODS, JavaCodeActionKind.SOURCE_GENERATE_TO_STRING, JavaCodeActionKind.SOURCE_GENERATE_CONSTRUCTORS, JavaCodeActionKind.REFACTOR_EXTRACT_FIELD,
JavaCodeActionKind.REFACTOR_EXTRACT_VARIABLE, JavaCodeActionKind.REFACTOR_INTRODUCE_PARAMETER, JavaCodeActionKind.REFACTOR_EXTRACT_METHOD, CodeActionKind.RefactorInline);
setIgnoredKind(CodeActionKind.Refactor, JavaCodeActionKind.SOURCE_OVERRIDE_METHODS, JavaCodeActionKind.SOURCE_GENERATE_TO_STRING, JavaCodeActionKind.SOURCE_GENERATE_CONSTRUCTORS, JavaCodeActionKind.SOURCE_GENERATE_FINAL_MODIFIERS,
JavaCodeActionKind.REFACTOR_EXTRACT_FIELD, JavaCodeActionKind.REFACTOR_EXTRACT_VARIABLE, JavaCodeActionKind.REFACTOR_INTRODUCE_PARAMETER, JavaCodeActionKind.REFACTOR_EXTRACT_METHOD, CodeActionKind.RefactorInline);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -899,30 +899,6 @@ public void testInvisibleTypeRequestedFromSuperClass() throws Exception {
assertCodeActions(cu, e1);
}

@Test
public void testInsertFinalModifierWherePossible() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);
StringBuilder buf = new StringBuilder();
buf.append("package test;\n");
buf.append("public class A {\n");
buf.append(" public static void abc(int x){\n");
buf.append(" int b = 3;\n");
buf.append(" }\n");
buf.append("}");
ICompilationUnit cu = pack.createCompilationUnit("A.java", buf.toString(), false, null);

buf = new StringBuilder();
buf.append("package test;\n");
buf.append("public class A {\n");
buf.append(" public static void abc(final int x){\n");
buf.append(" final int b = 3;\n");
buf.append(" }\n");
buf.append("}");
Expected e1 = new Expected("Change modifiers to final where possible", buf.toString());

assertCodeActions(cu, e1);
}

@Test
public void testNonBlankFinalLocalAssignment() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import java.util.Map;
import java.util.stream.Collectors;

import com.google.common.base.Objects;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
Expand Down Expand Up @@ -1161,10 +1163,17 @@ public void testSnippet_if() throws JavaModelException {
CompletionList list = server.completion(JsonMessageHelper.getParams(createCompletionRequest(unit, loc[0], loc[1]))).join().getRight();
assertNotNull(list);
List<CompletionItem> items = new ArrayList<>(list.getItems());
CompletionItem item = items.get(5);
assertEquals("if", item.getLabel());
String insertText = item.getInsertText();
assertEquals("if (${1:con}) {\n\t$TM_SELECTED_TEXT${0}\n}", insertText);
boolean hasIfSnippet = false;
for (CompletionItem item : items) {
if (!Objects.equal(item.getLabel(), "if")) {
continue;
}
if (Objects.equal(item.getInsertText(), "if (${1:con}) {\n\t$TM_SELECTED_TEXT${0}\n}")) {
hasIfSnippet = true;
break;
}
}
assertTrue(hasIfSnippet);
} finally {
System.setProperty(AssistOptions.PROPERTY_SubstringMatch, substringMatch);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2020 Microsoft Corporation 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
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Microsoft Corporation - initial API and implementation
*******************************************************************************/

package org.eclipse.jdt.ls.core.internal.handlers;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.ls.core.internal.correction.AbstractQuickFixTest;
import org.eclipse.jdt.ls.core.internal.correction.TestOptions;
import org.junit.Before;
import org.junit.Test;

public class GenerateFinalModifiersActionTest extends AbstractQuickFixTest {

private IJavaProject fJProject;
private IPackageFragmentRoot fSourceFolder;

@Before
public void setup() throws Exception {
fJProject = newEmptyProject();
fJProject.setOptions(TestOptions.getDefaultOptions());
fSourceFolder = fJProject.getPackageFragmentRoot(fJProject.getProject().getFolder("src"));
this.setIgnoredKind("");
}

@Test
public void testInsertFinalModifierWherePossible() throws Exception {
IPackageFragment pack = fSourceFolder.createPackageFragment("test", false, null);
StringBuilder buf = new StringBuilder();
buf.append("package test;\n");
buf.append("public class A {\n");
buf.append(" public static void abc(int x){\n");
buf.append(" int b = 3;\n");
buf.append(" }\n");
buf.append("}");
ICompilationUnit cu = pack.createCompilationUnit("A.java", buf.toString(), false, null);

buf = new StringBuilder();
buf.append("package test;\n");
buf.append("public class A {\n");
buf.append(" public static void abc(final int x){\n");
buf.append(" final int b = 3;\n");
buf.append(" }\n");
buf.append("}");
Expected e1 = new Expected("Change modifiers to final where possible", buf.toString());

assertCodeActions(cu, e1);
}
}