diff --git a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/NewCUProposal.java b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/NewCUProposal.java index 37a21c39f6..b799b845a0 100644 --- a/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/NewCUProposal.java +++ b/org.eclipse.jdt.ls.core/src/org/eclipse/jdt/ls/core/internal/corrections/proposals/NewCUProposal.java @@ -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; @@ -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; @@ -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; diff --git a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java index 75e9305293..16e4f7c3f6 100644 --- a/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java +++ b/org.eclipse.jdt.ls.tests/src/org/eclipse/jdt/ls/core/internal/correction/UnresolvedTypesQuickFixTest.java @@ -1415,7 +1415,8 @@ 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(); @@ -1423,7 +1424,14 @@ public void testTypeInSealedTypeDeclaration() throws Exception { 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);