Skip to content

Commit

Permalink
Add code actions to support new Java 15 modifiers on permitted class.
Browse files Browse the repository at this point in the history
- Add support for code actions to generate sealed/un-sealed/final
  modifiers on class with sealed direct super-class/super-interface
- Fixes eclipse-jdtls#1555
- Add testcase

Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
  • Loading branch information
rgrunber authored and fbricon committed Oct 1, 2020
1 parent 9629104 commit 7909f23
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ private CorrectionMessages() {
public static String RenameRefactoringProposal_additionalInfo;
public static String RenameRefactoringProposal_name;

public static String ModifierCorrectionSubProcessor_changemodifierto_final_description;
public static String ModifierCorrectionSubProcessor_changemodifierto_sealed_description;
public static String ModifierCorrectionSubProcessor_changemodifierto_nonsealed_description;
public static String ModifierCorrectionSubProcessor_changemodifiertoabstract_description;
public static String ModifierCorrectionSubProcessor_changemodifiertostatic_description;
public static String ModifierCorrectionSubProcessor_changemodifiertononstatic_description;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ RemoveDeclarationCorrectionProposal_removeunusedvar_description=Remove declarati
RenameRefactoringProposal_additionalInfo=Start the Rename refactoring
RenameRefactoringProposal_name=Rename in workspace

ModifierCorrectionSubProcessor_changemodifierto_final_description=Change ''{0}'' to ''final''
ModifierCorrectionSubProcessor_changemodifierto_sealed_description=Change ''{0}'' to ''sealed''
ModifierCorrectionSubProcessor_changemodifierto_nonsealed_description=Change ''{0}'' to ''non-sealed''
ModifierCorrectionSubProcessor_changemodifiertoabstract_description=Change ''{0}'' to ''abstract''
ModifierCorrectionSubProcessor_changemodifiertostatic_description=Change ''{0}'' to ''static''
ModifierCorrectionSubProcessor_changemodifiertodefault_description=Change ''{0}'' to ''default''
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ private void process(IInvocationContext context, IProblemLocationCore problem, C
case IProblem.IndirectAccessToStaticMethod:
LocalCorrectionsSubProcessor.addCorrectAccessToStaticProposals(context, problem, proposals);
break;
case IProblem.SealedMissingClassModifier:
case IProblem.SealedMissingInterfaceModifier:
ModifierCorrectionSubProcessor.addSealedMissingModifierProposal(context, problem, proposals);
break;
case IProblem.StaticMethodRequested:
case IProblem.NonStaticFieldFromStaticInvocation:
case IProblem.InstanceMethodDuringConstructorInvocation:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,4 +962,38 @@ private static Modifier findVisibilityModifier(List<IExtendedModifier> modifiers
return null;
}

public static void addSealedMissingModifierProposal(IInvocationContext context, IProblemLocationCore problem, Collection<ChangeCorrectionProposal> proposals) {
if (proposals == null) {
return;
}
ASTNode selectedNode = problem.getCoveringNode(context.getASTRoot());
if (!(selectedNode instanceof SimpleName)) {
return;
}
if (!(((SimpleName) selectedNode).getParent() instanceof TypeDeclaration)) {
return;
}
TypeDeclaration typeDecl = (TypeDeclaration) ((SimpleName) selectedNode).getParent();
boolean isInterface = typeDecl.isInterface();

ICompilationUnit cu = context.getCompilationUnit();
ITypeBinding typeDeclBinding = typeDecl.resolveBinding();
int relevance = IProposalRelevance.CHANGE_MODIFIER_TO_FINAL;
String label;

if (!isInterface) {
// Add final modifier
label = Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifierto_final_description, typeDecl.getName());
proposals.add(new ModifierChangeCorrectionProposal(label, cu, typeDeclBinding, typeDecl, Modifier.FINAL, 0, relevance));
}

// Add sealed modifier
label = Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifierto_sealed_description, typeDecl.getName());
proposals.add(new ModifierChangeCorrectionProposal(label, cu, typeDeclBinding, typeDecl, Modifier.SEALED, 0, relevance));

// Add non-sealed modifier
label = Messages.format(CorrectionMessages.ModifierCorrectionSubProcessor_changemodifierto_nonsealed_description, typeDecl.getName());
proposals.add(new ModifierChangeCorrectionProposal(label, cu, typeDeclBinding, typeDecl, Modifier.NON_SEALED, 0, relevance));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@
*******************************************************************************/
package org.eclipse.jdt.ls.core.internal.correction;

import java.util.HashMap;
import java.util.Map;

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.core.JavaCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -1203,4 +1208,51 @@ public void testClassExtendFinalClass() throws Exception {
Expected e1 = new Expected("Remove 'final' modifier of 'X'", buf.toString());
assertCodeActions(cu, e1);
}

@Test
public void testAddSealedMissingClassModifierProposal() throws Exception {
Map<String, String> options15 = new HashMap<>();
JavaModelUtil.setComplianceOptions(options15, JavaCore.VERSION_15);
options15.put(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
options15.put(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);
fJProject.setOptions(options15);
IPackageFragment pack1 = fSourceFolder.createPackageFragment("test", false, null);
assertNoErrors(fJProject.getResource());

StringBuilder buf = new StringBuilder();
buf = new StringBuilder();
buf.append("package test;\n");
buf.append("\n");
buf.append("public sealed class Shape permits Square {}\n");
buf.append("\n");
buf.append("class Square extends Shape {}\n");
ICompilationUnit cu = pack1.createCompilationUnit("Shape.java", buf.toString(), false, null);

buf = new StringBuilder();
buf.append("package test;\n");
buf.append("\n");
buf.append("public sealed class Shape permits Square {}\n");
buf.append("\n");
buf.append("final class Square extends Shape {}\n");
Expected e1 = new Expected("Change 'Square' to 'final'", buf.toString());
assertCodeActions(cu, e1);

buf = new StringBuilder();
buf.append("package test;\n");
buf.append("\n");
buf.append("public sealed class Shape permits Square {}\n");
buf.append("\n");
buf.append("non-sealed class Square extends Shape {}\n");
Expected e2 = new Expected("Change 'Square' to 'non-sealed'", buf.toString());
assertCodeActions(cu, e2);

buf = new StringBuilder();
buf.append("package test;\n");
buf.append("\n");
buf.append("public sealed class Shape permits Square {}\n");
buf.append("\n");
buf.append("sealed class Square extends Shape {}\n");
Expected e3 = new Expected("Change 'Square' to 'sealed'", buf.toString());
assertCodeActions(cu, e3);
}
}

0 comments on commit 7909f23

Please sign in to comment.