Skip to content

Commit

Permalink
Implement methods in newly created type from an inherited sealed class.
Browse files Browse the repository at this point in the history
- When a non-existent type is permitted by a sealed class, the newly
  created type should implement the necessary methods
- Related #1553
  • Loading branch information
rgrunber committed Oct 14, 2020
1 parent c28a4a5 commit da8d4af
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;
import org.eclipse.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.jdt.internal.corext.dom.IASTSharedValues;
import org.eclipse.jdt.internal.corext.fix.AddUnimplementedMethodsOperation;
import org.eclipse.jdt.internal.corext.fix.CompilationUnitRewriteOperationsFixCore.CompilationUnitRewriteOperation;
import org.eclipse.jdt.internal.corext.fix.IProposableFix;
import org.eclipse.jdt.internal.corext.fix.UnimplementedCodeFixCore;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.ls.core.internal.corext.refactoring.nls.changes.CreateFileChange;
Expand Down Expand Up @@ -276,6 +280,7 @@ protected Change createChange() throws CoreException {
CompositeChange change = new CompositeChange(fName);
change.add(new CreateFileChange(targetType.getResource().getRawLocation(), "", ""));
change.add(constructNewCUChange(parentCU));

return change;
} else {
return null;
Expand Down Expand Up @@ -353,6 +358,25 @@ private CompilationUnitChange constructNewCUChange(ICompilationUnit cu) throws C
String lineDelimiter = StubUtility.getLineDelimiterUsed(fCompilationUnit.getJavaProject());
String typeStub = constructTypeStub(cu, fTypeNameWithParameters, Flags.AccPublic, lineDelimiter);
String cuContent = constructCUContent(cu, typeStub, lineDelimiter);

IType cuType = fCompilationUnit.findPrimaryType();
String[] permittedNames = cuType.getPermittedSubtypeNames();
boolean isPermitted = Arrays.asList(permittedNames).stream().anyMatch(p -> fTypeNameWithParameters.equals(p));

if (isPermitted) {
cu.createType(typeStub, null, false, null);
ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
parser.setSource(cu);
parser.setResolveBindings(true);
CompilationUnit cuRoot = (CompilationUnit) parser.createAST(null);

AddUnimplementedMethodsOperation operation = new AddUnimplementedMethodsOperation((ASTNode) cuRoot.types().get(0));
if (operation.getMethodsToImplement().length > 0) {
IProposableFix fix = new UnimplementedCodeFixCore(CorrectionMessages.UnimplementedMethodsCorrectionProposal_description, cuRoot, new CompilationUnitRewriteOperation[] { operation });
return fix.createChange(null);
}
}

CompilationUnitChange cuChange = new CompilationUnitChange("", cu);
cuChange.setEdit(new InsertEdit(0, cuContent));
return cuChange;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1415,15 +1415,23 @@ public void testTypeInSealedTypeDeclaration() throws Exception {
StringBuilder buf = new StringBuilder();
buf.append("package test1;\n");
buf.append("public sealed interface E permits F {\n");
buf.append("}\n");
buf.append("void methodE();\n");
buf.append("}");
ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null);

buf = new StringBuilder();
buf.append("package test1;\n");
buf.append("\n");
buf.append("public final class F implements E {\n");
buf.append("\n");
buf.append("\t@Override\n");
buf.append("\tpublic void methodE() {\n");
buf.append("\t\t// TODO Auto-generated method stub\n");
buf.append("\t\t\n");
buf.append("\t}\n");
buf.append("\n");
buf.append("}\n");
buf.append("\n");
Expected e1 = new Expected("Create class 'F'", buf.toString());

assertCodeActions(cu, e1);
Expand Down

0 comments on commit da8d4af

Please sign in to comment.