From e9c669c8417fb1bda6c7f5bdd710783f39ab0764 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 24 Apr 2015 14:05:58 +0200 Subject: [PATCH] OverrideImplementMethodsHandler: J2K --- .../kotlin/idea/quickfix/generateUtil.kt | 2 +- .../OverrideImplementMethodsHandler.kt | 557 ++++++++---------- .../AbstractOverrideImplementTest.java | 6 +- 3 files changed, 262 insertions(+), 303 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt index 3ee7a7f0dca..4cda16f0873 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/quickfix/generateUtil.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.JetWithExpressionInitializer import org.jetbrains.kotlin.psi.JetProperty import org.jetbrains.kotlin.psi.psiUtil.siblings -private fun moveCaretIntoGeneratedElement(editor: Editor, element: PsiElement): Boolean { +public fun moveCaretIntoGeneratedElement(editor: Editor, element: PsiElement): Boolean { // Inspired by GenerateMembersUtils.positionCaret() if (element is JetDeclarationWithBody && element.hasBody()) { diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/codeInsight/OverrideImplementMethodsHandler.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/codeInsight/OverrideImplementMethodsHandler.kt index 8183fb425d7..8c3f69a330d 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/codeInsight/OverrideImplementMethodsHandler.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/codeInsight/OverrideImplementMethodsHandler.kt @@ -14,339 +14,298 @@ * limitations under the License. */ -package org.jetbrains.kotlin.idea.core.codeInsight; +package org.jetbrains.kotlin.idea.core.codeInsight -import com.intellij.codeInsight.hint.HintManager; -import com.intellij.ide.util.MemberChooser; -import com.intellij.lang.ASTNode; -import com.intellij.lang.LanguageCodeInsightActionHandler; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.DialogWrapper; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.*; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.kotlin.builtins.KotlinBuiltIns; -import org.jetbrains.kotlin.descriptors.*; -import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; -import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde; -import org.jetbrains.kotlin.idea.quickfix.QuickfixPackage; -import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; -import org.jetbrains.kotlin.idea.util.ShortenReferences; -import org.jetbrains.kotlin.psi.*; -import org.jetbrains.kotlin.renderer.DescriptorRenderer; -import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder; -import org.jetbrains.kotlin.renderer.NameShortness; -import org.jetbrains.kotlin.types.JetType; +import com.intellij.codeInsight.hint.HintManager +import com.intellij.ide.util.MemberChooser +import com.intellij.lang.ASTNode +import com.intellij.lang.LanguageCodeInsightActionHandler +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.diagnostic.Logger +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.DialogWrapper +import com.intellij.openapi.util.Condition +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.* +import com.intellij.psi.util.PsiTreeUtil +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.idea.caches.resolve.* +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde +import org.jetbrains.kotlin.idea.quickfix.* +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.ShortenReferences +import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder +import org.jetbrains.kotlin.renderer.NameShortness +import org.jetbrains.kotlin.types.JetType -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Set; +import java.util.ArrayList +import java.util.Collections -import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory; +import org.jetbrains.kotlin.psi.JetPsiFactory -public abstract class OverrideImplementMethodsHandler implements LanguageCodeInsightActionHandler { +public abstract class OverrideImplementMethodsHandler : LanguageCodeInsightActionHandler { - private static final DescriptorRenderer OVERRIDE_RENDERER = new DescriptorRendererBuilder() - .setRenderDefaultValues(false) - .setModifiers(DescriptorRenderer.Modifier.OVERRIDE) - .setWithDefinedIn(false) - .setNameShortness(NameShortness.SOURCE_CODE_QUALIFIED) - .setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OVERRIDE) - .setUnitReturnType(false) - .setTypeNormalizer(IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES) - .build(); - - private static final Logger LOG = Logger.getInstance(OverrideImplementMethodsHandler.class.getCanonicalName()); - - public static List membersFromDescriptors( - JetFile file, Iterable missingImplementations - ) { - List members = new ArrayList(); - for (CallableMemberDescriptor memberDescriptor : missingImplementations) { - PsiElement declaration = DescriptorToSourceUtilsIde.INSTANCE$.getAnyDeclaration(file.getProject(), memberDescriptor); - if (declaration == null) { - LOG.error("Can not find declaration for descriptor " + memberDescriptor); - } - else { - DescriptorClassMember member = new DescriptorClassMember(declaration, memberDescriptor); - members.add(member); - } + public fun collectMethodsToGenerate(classOrObject: JetClassOrObject): Set { + val descriptor = classOrObject.resolveToDescriptor() + if (descriptor is ClassDescriptor) { + return collectMethodsToGenerate(descriptor) } - return members; + return emptySet() } - public static void generateMethods( - @NotNull final Editor editor, - @NotNull final JetClassOrObject classOrObject, - @NotNull final List selectedElements - ) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - JetClassBody body = classOrObject.getBody(); - if (body == null) { - JetPsiFactory psiFactory = JetPsiFactory(classOrObject); - classOrObject.add(psiFactory.createWhiteSpace()); - body = (JetClassBody) classOrObject.add(psiFactory.createEmptyClassBody()); - } + protected abstract fun collectMethodsToGenerate(descriptor: ClassDescriptor): Set - PsiElement afterAnchor = findInsertAfterAnchor(editor, body); - - if (afterAnchor == null) return; - - PsiElement firstGenerated = null; - - List elementsToCompact = new ArrayList(); - for (JetElement element : generateOverridingMembers(selectedElements, classOrObject)) { - PsiElement added = body.addAfter(element, afterAnchor); - - if (firstGenerated == null) { - firstGenerated = added; - } - - afterAnchor = added; - elementsToCompact.add((JetElement) added); - } - - ShortenReferences.DEFAULT.process(elementsToCompact); - - if (firstGenerated == null) return; - - Project project = classOrObject.getProject(); - SmartPsiElementPointer pointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(firstGenerated); - - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); - - PsiElement element = pointer.getElement(); - if (element != null) { - QuickfixPackage.moveCaretIntoGeneratedElement(editor, element); - } - } - }); + private fun showOverrideImplementChooser(project: Project, members: Array): MemberChooser? { + val chooser = MemberChooser(members, true, true, project) + chooser.setTitle(getChooserTitle()) + chooser.show() + if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null + return chooser } - @Nullable - private static PsiElement findInsertAfterAnchor(Editor editor, final JetClassBody body) { - PsiElement afterAnchor = body.getLBrace(); - if (afterAnchor == null) return null; + protected abstract fun getChooserTitle(): String - int offset = editor.getCaretModel().getOffset(); - PsiElement offsetCursorElement = PsiTreeUtil.findFirstParent( - body.getContainingFile().findElementAt(offset), - new Condition() { - @Override - public boolean value(PsiElement element) { - return element.getParent() == body; - } - }); - - if (offsetCursorElement instanceof PsiWhiteSpace) { - return removeAfterOffset(offset, (PsiWhiteSpace) offsetCursorElement); + override fun isValidFor(editor: Editor, file: PsiFile): Boolean { + if (file !is JetFile) { + return false } - - if (offsetCursorElement != null && offsetCursorElement != body.getRBrace()) { - return offsetCursorElement; - } - - return afterAnchor; + val elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()) + val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, javaClass()) + return classOrObject != null } - private static PsiElement removeAfterOffset(int offset, PsiWhiteSpace whiteSpace) { - ASTNode spaceNode = whiteSpace.getNode(); - if (spaceNode.getTextRange().contains(offset)) { - String beforeWhiteSpaceText = spaceNode.getText().substring(0, offset - spaceNode.getStartOffset()); - if (!StringUtil.containsLineBreak(beforeWhiteSpaceText)) { - // Prevent insertion on same line - beforeWhiteSpaceText += "\n"; - } + protected abstract fun getNoMethodsFoundHint(): String - JetPsiFactory factory = JetPsiFactory(whiteSpace.getProject()); + public fun invoke(project: Project, editor: Editor, file: PsiFile, implementAll: Boolean) { + val elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()) + val classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, javaClass()) - PsiElement insertAfter = whiteSpace.getPrevSibling(); - whiteSpace.delete(); + assert(classOrObject != null) - PsiElement beforeSpace = factory.createWhiteSpace(beforeWhiteSpaceText); - insertAfter.getParent().addAfter(beforeSpace, insertAfter); - - return insertAfter.getNextSibling(); - } - - return whiteSpace; - } - - private static List generateOverridingMembers(List selectedElements, JetClassOrObject classOrObject) { - List overridingMembers = new ArrayList(); - for (DescriptorClassMember selectedElement : selectedElements) { - DeclarationDescriptor descriptor = selectedElement.getDescriptor(); - if (descriptor instanceof SimpleFunctionDescriptor) { - overridingMembers.add(overrideFunction(classOrObject, (SimpleFunctionDescriptor) descriptor)); - } - else if (descriptor instanceof PropertyDescriptor) { - overridingMembers.add(overrideProperty(classOrObject, (PropertyDescriptor) descriptor)); - } - } - return overridingMembers; - } - - @NotNull - private static JetElement overrideProperty(@NotNull JetClassOrObject classOrObject, @NotNull PropertyDescriptor descriptor) { - PropertyDescriptor newDescriptor = (PropertyDescriptor) descriptor.copy( - descriptor.getContainingDeclaration(), - Modality.OPEN, - descriptor.getVisibility(), - descriptor.getKind(), - /* copyOverrides = */ true); - newDescriptor.addOverriddenDescriptor(descriptor); - - StringBuilder body = new StringBuilder(); - body.append("\nget()"); - body.append(" = "); - body.append(generateUnsupportedOrSuperCall(classOrObject, descriptor)); - if (descriptor.isVar()) { - body.append("\nset(value) {}"); - } - return JetPsiFactory(classOrObject.getProject()).createProperty(OVERRIDE_RENDERER.render(newDescriptor) + body); - } - - @NotNull - private static JetNamedFunction overrideFunction(@NotNull JetClassOrObject classOrObject, @NotNull FunctionDescriptor descriptor) { - FunctionDescriptor newDescriptor = descriptor.copy( - descriptor.getContainingDeclaration(), - Modality.OPEN, - descriptor.getVisibility(), - descriptor.getKind(), - /* copyOverrides = */ true); - newDescriptor.addOverriddenDescriptor(descriptor); - - - JetType returnType = descriptor.getReturnType(); - KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); - - boolean returnsNotUnit = returnType != null && !builtIns.getUnitType().equals(returnType); - boolean isAbstract = descriptor.getModality() == Modality.ABSTRACT; - - String delegation = generateUnsupportedOrSuperCall(classOrObject, descriptor); - - String body = "{" + (returnsNotUnit && !isAbstract ? "return " : "") + delegation + "}"; - - return JetPsiFactory(classOrObject.getProject()).createFunction(OVERRIDE_RENDERER.render(newDescriptor) + body); - } - - private static String generateUnsupportedOrSuperCall(@NotNull JetClassOrObject classOrObject, @NotNull CallableMemberDescriptor descriptor) { - boolean isAbstract = descriptor.getModality() == Modality.ABSTRACT; - if (isAbstract) { - return "throw UnsupportedOperationException()"; - } - else { - StringBuilder builder = new StringBuilder(); - builder.append("super"); - if (classOrObject.getDelegationSpecifiers().size() > 1) { - builder.append("<").append(DescriptorRenderer.COMPACT.renderName(descriptor.getContainingDeclaration().getName())).append(">"); - } - builder.append(".").append(DescriptorRenderer.COMPACT.renderName(descriptor.getName())); - - if (descriptor instanceof FunctionDescriptor) { - builder.append("("); - boolean first = true; - for (ValueParameterDescriptor parameterDescriptor : descriptor.getValueParameters()) { - if (!first) { - builder.append(", "); - } - first = false; - builder.append(DescriptorRenderer.COMPACT.renderName(parameterDescriptor.getName())); - } - builder.append(")"); - } - - return builder.toString(); - } - } - - @NotNull - public Set collectMethodsToGenerate(@NotNull JetClassOrObject classOrObject) { - DeclarationDescriptor descriptor = ResolvePackage.resolveToDescriptor(classOrObject); - if (descriptor instanceof ClassDescriptor) { - return collectMethodsToGenerate((ClassDescriptor) descriptor); - } - return Collections.emptySet(); - } - - protected abstract Set collectMethodsToGenerate(@NotNull ClassDescriptor descriptor); - - private MemberChooser showOverrideImplementChooser( - Project project, - DescriptorClassMember[] members - ) { - MemberChooser chooser = new MemberChooser(members, true, true, project); - chooser.setTitle(getChooserTitle()); - chooser.show(); - if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null; - return chooser; - } - - protected abstract String getChooserTitle(); - - @Override - public boolean isValidFor(Editor editor, PsiFile file) { - if (!(file instanceof JetFile)) { - return false; - } - PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()); - JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class); - return classOrObject != null; - } - - protected abstract String getNoMethodsFoundHint(); - - public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file, boolean implementAll) { - PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()); - JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(elementAtCaret, JetClassOrObject.class); - - assert classOrObject != null; - - Set missingImplementations = collectMethodsToGenerate(classOrObject); + val missingImplementations = collectMethodsToGenerate(classOrObject) if (missingImplementations.isEmpty() && !implementAll) { - HintManager.getInstance().showErrorHint(editor, getNoMethodsFoundHint()); - return; + HintManager.getInstance().showErrorHint(editor, getNoMethodsFoundHint()) + return } - List members = membersFromDescriptors((JetFile) file, missingImplementations); + val members = membersFromDescriptors(file as JetFile, missingImplementations) - List selectedElements; + val selectedElements: List? if (implementAll) { - selectedElements = members; + selectedElements = members } else { - MemberChooser chooser = showOverrideImplementChooser( - project, - members.toArray(new DescriptorClassMember[members.size()])); + val chooser = showOverrideImplementChooser(project, members.toTypedArray()) if (chooser == null) { - return; + return } - selectedElements = chooser.getSelectedElements(); - if (selectedElements == null || selectedElements.isEmpty()) return; + selectedElements = chooser.getSelectedElements() + if (selectedElements == null || selectedElements.isEmpty()) return } - PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiDocumentManager.getInstance(project).commitAllDocuments() - generateMethods(editor, classOrObject, selectedElements); + generateMethods(editor, classOrObject, selectedElements) } - @Override - public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - invoke(project, editor, file, false); + override fun invoke(project: Project, editor: Editor, file: PsiFile) { + invoke(project, editor, file, false) } - @Override - public boolean startInWriteAction() { - return false; + override fun startInWriteAction(): Boolean { + return false + } + + companion object { + + private val OVERRIDE_RENDERER = DescriptorRendererBuilder().setRenderDefaultValues(false).setModifiers(DescriptorRenderer.Modifier.OVERRIDE).setWithDefinedIn(false).setNameShortness(NameShortness.SOURCE_CODE_QUALIFIED).setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OVERRIDE).setUnitReturnType(false).setTypeNormalizer(IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES).build() + + private val LOG = Logger.getInstance(javaClass().getCanonicalName()) + + public fun membersFromDescriptors(file: JetFile, missingImplementations: Iterable): List { + val members = ArrayList() + for (memberDescriptor in missingImplementations) { + val declaration = DescriptorToSourceUtilsIde.getAnyDeclaration(file.getProject(), memberDescriptor) + if (declaration == null) { + LOG.error("Can not find declaration for descriptor " + memberDescriptor) + } + else { + val member = DescriptorClassMember(declaration, memberDescriptor) + members.add(member) + } + } + return members + } + + public fun generateMethods(editor: Editor, classOrObject: JetClassOrObject, selectedElements: List) { + ApplicationManager.getApplication().runWriteAction(object : Runnable { + override fun run() { + var body = classOrObject.getBody() + if (body == null) { + val psiFactory = JetPsiFactory(classOrObject) + classOrObject.add(psiFactory.createWhiteSpace()) + body = classOrObject.add(psiFactory.createEmptyClassBody()) as JetClassBody + } + + var afterAnchor = findInsertAfterAnchor(editor, body) + + if (afterAnchor == null) return + + var firstGenerated: PsiElement? = null + + val elementsToCompact = ArrayList() + for (element in generateOverridingMembers(selectedElements, classOrObject)) { + val added = body!!.addAfter(element, afterAnchor) + + if (firstGenerated == null) { + firstGenerated = added + } + + afterAnchor = added + elementsToCompact.add(added as JetElement) + } + + ShortenReferences.DEFAULT.process(elementsToCompact) + + if (firstGenerated == null) return + + val project = classOrObject.getProject() + val pointer = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(firstGenerated) + + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()) + + val element = pointer.getElement() + if (element != null) { + moveCaretIntoGeneratedElement(editor, element) + } + } + }) + } + + private fun findInsertAfterAnchor(editor: Editor, body: JetClassBody): PsiElement? { + val afterAnchor = body.getLBrace() + if (afterAnchor == null) return null + + val offset = editor.getCaretModel().getOffset() + val offsetCursorElement = PsiTreeUtil.findFirstParent(body.getContainingFile().findElementAt(offset), object : Condition { + override fun value(element: PsiElement): Boolean { + return element.getParent() == body + } + }) + + if (offsetCursorElement is PsiWhiteSpace) { + return removeAfterOffset(offset, offsetCursorElement) + } + + if (offsetCursorElement != null && offsetCursorElement != body.getRBrace()) { + return offsetCursorElement + } + + return afterAnchor + } + + private fun removeAfterOffset(offset: Int, whiteSpace: PsiWhiteSpace): PsiElement { + val spaceNode = whiteSpace.getNode() + if (spaceNode.getTextRange().contains(offset)) { + var beforeWhiteSpaceText = spaceNode.getText().substring(0, offset - spaceNode.getStartOffset()) + if (!StringUtil.containsLineBreak(beforeWhiteSpaceText)) { + // Prevent insertion on same line + beforeWhiteSpaceText += "\n" + } + + val factory = JetPsiFactory(whiteSpace.getProject()) + + val insertAfter = whiteSpace.getPrevSibling() + whiteSpace.delete() + + val beforeSpace = factory.createWhiteSpace(beforeWhiteSpaceText) + insertAfter.getParent().addAfter(beforeSpace, insertAfter) + + return insertAfter.getNextSibling() + } + + return whiteSpace + } + + private fun generateOverridingMembers(selectedElements: List, classOrObject: JetClassOrObject): List { + val overridingMembers = ArrayList() + for (selectedElement in selectedElements) { + val descriptor = selectedElement.getDescriptor() + if (descriptor is SimpleFunctionDescriptor) { + overridingMembers.add(overrideFunction(classOrObject, descriptor)) + } + else if (descriptor is PropertyDescriptor) { + overridingMembers.add(overrideProperty(classOrObject, descriptor)) + } + } + return overridingMembers + } + + private fun overrideProperty(classOrObject: JetClassOrObject, descriptor: PropertyDescriptor): JetElement { + val newDescriptor = descriptor.copy(descriptor.getContainingDeclaration(), Modality.OPEN, descriptor.getVisibility(), descriptor.getKind(), /* copyOverrides = */ true) as PropertyDescriptor + newDescriptor.addOverriddenDescriptor(descriptor) + + val body = StringBuilder() + body.append("\nget()") + body.append(" = ") + body.append(generateUnsupportedOrSuperCall(classOrObject, descriptor)) + if (descriptor.isVar()) { + body.append("\nset(value) {}") + } + return JetPsiFactory(classOrObject.getProject()).createProperty(OVERRIDE_RENDERER.render(newDescriptor) + body) + } + + private fun overrideFunction(classOrObject: JetClassOrObject, descriptor: FunctionDescriptor): JetNamedFunction { + val newDescriptor = descriptor.copy(descriptor.getContainingDeclaration(), Modality.OPEN, descriptor.getVisibility(), descriptor.getKind(), /* copyOverrides = */ true) + newDescriptor.addOverriddenDescriptor(descriptor) + + + val returnType = descriptor.getReturnType() + val builtIns = KotlinBuiltIns.getInstance() + + val returnsNotUnit = returnType != null && builtIns.getUnitType() != returnType + val isAbstract = descriptor.getModality() == Modality.ABSTRACT + + val delegation = generateUnsupportedOrSuperCall(classOrObject, descriptor) + + val body = "{" + (if (returnsNotUnit && !isAbstract) "return " else "") + delegation + "}" + + return JetPsiFactory(classOrObject.getProject()).createFunction(OVERRIDE_RENDERER.render(newDescriptor) + body) + } + + private fun generateUnsupportedOrSuperCall(classOrObject: JetClassOrObject, descriptor: CallableMemberDescriptor): String { + val isAbstract = descriptor.getModality() == Modality.ABSTRACT + if (isAbstract) { + return "throw UnsupportedOperationException()" + } + else { + val builder = StringBuilder() + builder.append("super") + if (classOrObject.getDelegationSpecifiers().size() > 1) { + builder.append("<").append(DescriptorRenderer.COMPACT.renderName(descriptor.getContainingDeclaration().getName())).append(">") + } + builder.append(".").append(DescriptorRenderer.COMPACT.renderName(descriptor.getName())) + + if (descriptor is FunctionDescriptor) { + builder.append("(") + var first = true + for (parameterDescriptor in descriptor.getValueParameters()) { + if (!first) { + builder.append(", ") + } + first = false + builder.append(DescriptorRenderer.COMPACT.renderName(parameterDescriptor.getName())) + } + builder.append(")") + } + + return builder.toString() + } + } } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.java index c24b23f285e..fb03276a079 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractOverrideImplementTest.java @@ -164,7 +164,7 @@ public abstract class AbstractOverrideImplementTest extends JetLightCodeInsightF } performGenerateCommand(classOrObject, - OverrideImplementMethodsHandler.membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride))); + OverrideImplementMethodsHandler.Companion.membersFromDescriptors(jetFile, Collections.singletonList(singleToOverride))); } private void doMultiOverrideImplement(OverrideImplementMethodsHandler handler) { @@ -183,7 +183,7 @@ public abstract class AbstractOverrideImplementTest extends JetLightCodeInsightF } }); - performGenerateCommand(classOrObject, OverrideImplementMethodsHandler.membersFromDescriptors(jetFile, descriptorsList)); + performGenerateCommand(classOrObject, OverrideImplementMethodsHandler.Companion.membersFromDescriptors(jetFile, descriptorsList)); } private void generateImplementation(@NotNull final PsiMethod method) { @@ -210,7 +210,7 @@ public abstract class AbstractOverrideImplementTest extends JetLightCodeInsightF new WriteCommandAction(myFixture.getProject(), myFixture.getFile()) { @Override protected void run(@NotNull Result result) throws Throwable { - OverrideImplementMethodsHandler.generateMethods(myFixture.getEditor(), classOrObject, descriptorsToGenerate); + OverrideImplementMethodsHandler.Companion.generateMethods(myFixture.getEditor(), classOrObject, descriptorsToGenerate); } }.performCommand(); }