Converted to Kotlin
This commit is contained in:
-148
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.generation.ClassMemberWithElement;
|
||||
import com.intellij.codeInsight.generation.MemberChooserObject;
|
||||
import com.intellij.codeInsight.generation.MemberChooserObjectBase;
|
||||
import com.intellij.codeInsight.generation.PsiElementMemberChooserObject;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.idea.JetDescriptorIconProvider;
|
||||
import org.jetbrains.kotlin.psi.JetClass;
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration;
|
||||
import org.jetbrains.kotlin.renderer.*;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
|
||||
public class DescriptorClassMember extends MemberChooserObjectBase implements ClassMemberWithElement {
|
||||
|
||||
public static final String NO_PARENT_FOR = "No parent for ";
|
||||
@NotNull
|
||||
private final DeclarationDescriptor myDescriptor;
|
||||
@NotNull
|
||||
private final PsiElement myPsiElement;
|
||||
|
||||
private static final DescriptorRenderer MEMBER_RENDERER = DescriptorRenderer.Companion.withOptions(
|
||||
new Function1<DescriptorRendererOptions, Unit>() {
|
||||
@Override
|
||||
public Unit invoke(DescriptorRendererOptions options) {
|
||||
options.setWithDefinedIn(false);
|
||||
options.setModifiers(Collections.<DescriptorRendererModifier>emptySet());
|
||||
options.setStartFromName(true);
|
||||
options.setNameShortness(NameShortness.SHORT);
|
||||
return Unit.INSTANCE$;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
public DescriptorClassMember(@NotNull PsiElement element, @NotNull DeclarationDescriptor descriptor) {
|
||||
super(getText(descriptor), getIcon(element, descriptor));
|
||||
myPsiElement = element;
|
||||
myDescriptor = descriptor;
|
||||
}
|
||||
|
||||
private static String getText(DeclarationDescriptor descriptor) {
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
return RendererPackage.render(DescriptorUtils.getFqNameSafe(descriptor));
|
||||
}
|
||||
else {
|
||||
return MEMBER_RENDERER.render(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
private static Icon getIcon(PsiElement element, DeclarationDescriptor declarationDescriptor) {
|
||||
if (element.isValid()) {
|
||||
boolean isClass = element instanceof PsiClass || element instanceof JetClass;
|
||||
int flags = isClass ? 0 : Iconable.ICON_FLAG_VISIBILITY;
|
||||
if (element instanceof JetDeclaration) { // kotlin declaration
|
||||
// visibility and abstraction better detect by a descriptor
|
||||
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, flags);
|
||||
}
|
||||
else {
|
||||
// it is better to show java icons for java code
|
||||
return element.getIcon(flags);
|
||||
}
|
||||
}
|
||||
|
||||
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemberChooserObject getParentNodeDelegate() {
|
||||
DeclarationDescriptor parent = myDescriptor.getContainingDeclaration();
|
||||
PsiElement declaration;
|
||||
if (myPsiElement instanceof JetDeclaration) {
|
||||
// kotlin
|
||||
declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, JetNamedDeclaration.class);
|
||||
if (declaration == null) {
|
||||
declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, JetFile.class);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// java or bytecode
|
||||
declaration = ((PsiMember) myPsiElement).getContainingClass();
|
||||
}
|
||||
assert parent != null : NO_PARENT_FOR + myDescriptor;
|
||||
assert declaration != null : NO_PARENT_FOR + myPsiElement;
|
||||
|
||||
if (declaration instanceof JetFile) {
|
||||
JetFile file = (JetFile) declaration;
|
||||
return new PsiElementMemberChooserObject(file, file.getName());
|
||||
}
|
||||
|
||||
return new DescriptorClassMember(declaration, parent);
|
||||
}
|
||||
|
||||
public DeclarationDescriptor getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
DescriptorClassMember that = (DescriptorClassMember) o;
|
||||
|
||||
if (!myDescriptor.equals(that.myDescriptor)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return myDescriptor.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getElement() {
|
||||
return myPsiElement;
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight
|
||||
|
||||
import com.intellij.codeInsight.generation.ClassMemberWithElement
|
||||
import com.intellij.codeInsight.generation.MemberChooserObject
|
||||
import com.intellij.codeInsight.generation.MemberChooserObjectBase
|
||||
import com.intellij.codeInsight.generation.PsiElementMemberChooserObject
|
||||
import com.intellij.openapi.util.Iconable
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.JetDescriptorIconProvider
|
||||
import org.jetbrains.kotlin.psi.JetClass
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.psi.JetNamedDeclaration
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRendererModifier
|
||||
import org.jetbrains.kotlin.renderer.NameShortness
|
||||
import org.jetbrains.kotlin.renderer.render
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import javax.swing.Icon
|
||||
|
||||
public class DescriptorClassMember(private val myPsiElement: PsiElement, public val descriptor: DeclarationDescriptor) : MemberChooserObjectBase(DescriptorClassMember.getText(descriptor), DescriptorClassMember.getIcon(myPsiElement, descriptor)), ClassMemberWithElement {
|
||||
|
||||
override fun getParentNodeDelegate(): MemberChooserObject {
|
||||
val parent = descriptor.containingDeclaration
|
||||
var declaration: PsiElement?
|
||||
if (myPsiElement is JetDeclaration) {
|
||||
// kotlin
|
||||
declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, javaClass<JetNamedDeclaration>())
|
||||
if (declaration == null) {
|
||||
declaration = PsiTreeUtil.getStubOrPsiParentOfType(myPsiElement, javaClass<JetFile>())
|
||||
}
|
||||
}
|
||||
else {
|
||||
// java or bytecode
|
||||
declaration = (myPsiElement as PsiMember).containingClass
|
||||
}
|
||||
assert(parent != null) { "$NO_PARENT_FOR$descriptor" }
|
||||
assert(declaration != null) { "$NO_PARENT_FOR$myPsiElement" }
|
||||
|
||||
if (declaration is JetFile) {
|
||||
return PsiElementMemberChooserObject(declaration, declaration.name)
|
||||
}
|
||||
|
||||
return DescriptorClassMember(declaration!!, parent!!)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || javaClass != other.javaClass) return false
|
||||
|
||||
val that = other as DescriptorClassMember
|
||||
|
||||
if (descriptor != that.descriptor) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return descriptor.hashCode()
|
||||
}
|
||||
|
||||
override fun getElement(): PsiElement {
|
||||
return myPsiElement
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
public val NO_PARENT_FOR: String = "No parent for "
|
||||
|
||||
private val MEMBER_RENDERER = DescriptorRenderer.withOptions {
|
||||
withDefinedIn = false
|
||||
modifiers = emptySet<DescriptorRendererModifier>()
|
||||
startFromName = true
|
||||
nameShortness = NameShortness.SHORT
|
||||
}
|
||||
|
||||
private fun getText(descriptor: DeclarationDescriptor): String {
|
||||
if (descriptor is ClassDescriptor) {
|
||||
return DescriptorUtils.getFqNameSafe(descriptor).render()
|
||||
}
|
||||
else {
|
||||
return MEMBER_RENDERER.render(descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getIcon(element: PsiElement, declarationDescriptor: DeclarationDescriptor): Icon {
|
||||
if (element.isValid) {
|
||||
val isClass = element is PsiClass || element is JetClass
|
||||
val flags = if (isClass) 0 else Iconable.ICON_FLAG_VISIBILITY
|
||||
if (element is JetDeclaration) {
|
||||
// kotlin declaration
|
||||
// visibility and abstraction better detect by a descriptor
|
||||
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, flags)
|
||||
}
|
||||
else {
|
||||
// it is better to show java icons for java code
|
||||
return element.getIcon(flags)
|
||||
}
|
||||
}
|
||||
|
||||
return JetDescriptorIconProvider.getIcon(declarationDescriptor, element, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.idea.JetBundle;
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ImplementMethodsHandler extends OverrideImplementMethodsHandler implements IntentionAction {
|
||||
@Override
|
||||
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull ClassDescriptor descriptor) {
|
||||
return OverrideResolver.getMissingImplementations(descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getChooserTitle() {
|
||||
return "Implement Members";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNoMethodsFoundHint() {
|
||||
return "No methods to implement have been found";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return JetBundle.message("implement.members");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return JetBundle.message("implement.members");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return isValidFor(editor, file);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.JetBundle
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
|
||||
public class ImplementMethodsHandler : OverrideImplementMethodsHandler(), IntentionAction {
|
||||
override fun collectMethodsToGenerate(descriptor: ClassDescriptor): Set<CallableMemberDescriptor> {
|
||||
return OverrideResolver.getMissingImplementations(descriptor)
|
||||
}
|
||||
|
||||
override fun getChooserTitle(): String {
|
||||
return "Implement Members"
|
||||
}
|
||||
|
||||
override fun getNoMethodsFoundHint(): String {
|
||||
return "No methods to implement have been found"
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
return JetBundle.message("implement.members")
|
||||
}
|
||||
|
||||
override fun getFamilyName(): String {
|
||||
return JetBundle.message("implement.members")
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor, file: PsiFile): Boolean {
|
||||
return isValidFor(editor, file)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -221,7 +221,7 @@ public abstract class OverrideImplementMethodsHandler : LanguageCodeInsightActio
|
||||
classOrObject: JetClassOrObject): List<JetElement> {
|
||||
val overridingMembers = ArrayList<JetElement>()
|
||||
for (selectedElement in selectedElements) {
|
||||
val descriptor = selectedElement.getDescriptor()
|
||||
val descriptor = selectedElement.descriptor
|
||||
if (descriptor is SimpleFunctionDescriptor) {
|
||||
overridingMembers.add(overrideFunction(classOrObject, descriptor))
|
||||
}
|
||||
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight;
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver;
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilPackage;
|
||||
import org.jetbrains.kotlin.types.JetType;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE;
|
||||
|
||||
public class OverrideMethodsHandler extends OverrideImplementMethodsHandler {
|
||||
@Override
|
||||
protected Set<CallableMemberDescriptor> collectMethodsToGenerate(@NotNull ClassDescriptor descriptor) {
|
||||
Set<CallableMemberDescriptor> superMethods = collectSuperMethods(descriptor);
|
||||
for (DeclarationDescriptor member : descriptor.getDefaultType().getMemberScope().getAllDescriptors()) {
|
||||
if (member instanceof CallableMemberDescriptor) {
|
||||
CallableMemberDescriptor callable = (CallableMemberDescriptor) member;
|
||||
if (callable.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
superMethods.removeAll(callable.getOverriddenDescriptors());
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<CallableMemberDescriptor> result = new HashSet<CallableMemberDescriptor>();
|
||||
for (CallableMemberDescriptor superMethod : superMethods) {
|
||||
if (superMethod.getModality().isOverridable()) {
|
||||
if (!CallResolverUtilPackage.isOrOverridesSynthesized(superMethod)) {
|
||||
result.add(superMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<CallableMemberDescriptor> collectSuperMethods(@NotNull ClassDescriptor classDescriptor) {
|
||||
Set<CallableMemberDescriptor> inheritedFunctions = new LinkedHashSet<CallableMemberDescriptor>();
|
||||
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
|
||||
for (DeclarationDescriptor descriptor : supertype.getMemberScope().getAllDescriptors()) {
|
||||
if (descriptor instanceof CallableMemberDescriptor) {
|
||||
inheritedFunctions.add((CallableMemberDescriptor) descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only those actually inherited
|
||||
Set<CallableMemberDescriptor> filteredMembers = OverrideResolver.filterOutOverridden(inheritedFunctions);
|
||||
|
||||
// Group members with "the same" signature
|
||||
Multimap<CallableMemberDescriptor, CallableMemberDescriptor> factoredMembers = LinkedHashMultimap.create();
|
||||
for (CallableMemberDescriptor one : filteredMembers) {
|
||||
if (factoredMembers.values().contains(one)) continue;
|
||||
for (CallableMemberDescriptor another : filteredMembers) {
|
||||
// if (one == another) continue;
|
||||
factoredMembers.put(one, one);
|
||||
if (OverridingUtil.DEFAULT.isOverridableBy(one, another).getResult() == OVERRIDABLE
|
||||
|| OverridingUtil.DEFAULT.isOverridableBy(another, one).getResult() == OVERRIDABLE) {
|
||||
factoredMembers.put(one, another);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return factoredMembers.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getChooserTitle() {
|
||||
return "Override Members";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getNoMethodsFoundHint() {
|
||||
return "No methods to override have been found";
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.codeInsight
|
||||
|
||||
import com.google.common.collect.LinkedHashMultimap
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.OverrideResolver
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import java.util.HashSet
|
||||
import java.util.LinkedHashSet
|
||||
|
||||
public class OverrideMethodsHandler : OverrideImplementMethodsHandler() {
|
||||
override fun collectMethodsToGenerate(descriptor: ClassDescriptor): Set<CallableMemberDescriptor> {
|
||||
val superMethods = collectSuperMethods(descriptor)
|
||||
for (member in descriptor.defaultType.memberScope.getAllDescriptors()) {
|
||||
if (member is CallableMemberDescriptor) {
|
||||
if (member.kind == CallableMemberDescriptor.Kind.DECLARATION) {
|
||||
superMethods.removeAll(member.overriddenDescriptors)
|
||||
}
|
||||
}
|
||||
}
|
||||
val result = HashSet<CallableMemberDescriptor>()
|
||||
for (superMethod in superMethods) {
|
||||
if (superMethod.modality.isOverridable) {
|
||||
if (!isOrOverridesSynthesized(superMethod)) {
|
||||
result.add(superMethod)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private fun collectSuperMethods(classDescriptor: ClassDescriptor): MutableSet<CallableMemberDescriptor> {
|
||||
val inheritedFunctions = LinkedHashSet<CallableMemberDescriptor>()
|
||||
for (supertype in classDescriptor.typeConstructor.supertypes) {
|
||||
for (descriptor in supertype.memberScope.getAllDescriptors()) {
|
||||
if (descriptor is CallableMemberDescriptor) {
|
||||
inheritedFunctions.add(descriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only those actually inherited
|
||||
val filteredMembers = OverrideResolver.filterOutOverridden(inheritedFunctions)
|
||||
|
||||
// Group members with "the same" signature
|
||||
val factoredMembers = LinkedHashMultimap.create<CallableMemberDescriptor, CallableMemberDescriptor>()
|
||||
for (one in filteredMembers) {
|
||||
if (factoredMembers.values().contains(one)) continue
|
||||
for (another in filteredMembers) {
|
||||
// if (one == another) continue;
|
||||
factoredMembers.put(one, one)
|
||||
if (OverridingUtil.DEFAULT.isOverridableBy(one, another).result == OVERRIDABLE || OverridingUtil.DEFAULT.isOverridableBy(another, one).result == OVERRIDABLE) {
|
||||
factoredMembers.put(one, another)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return factoredMembers.keySet()
|
||||
}
|
||||
|
||||
override fun getChooserTitle(): String {
|
||||
return "Override Members"
|
||||
}
|
||||
|
||||
override fun getNoMethodsFoundHint(): String {
|
||||
return "No methods to override have been found"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user