KT-6566 Generate Override/Implement method does not work for locally declared classes

#KT-6566 Fixed
This commit is contained in:
Valentin Kipyatkov
2015-01-12 15:04:44 +03:00
parent eed0def1cb
commit c915eb4eac
29 changed files with 168 additions and 77 deletions
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.util;
import kotlin.Function1;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder;
import org.jetbrains.kotlin.renderer.NameShortness;
import org.jetbrains.kotlin.types.JetType;
public class IdeDescriptorRenderers {
@@ -38,17 +39,17 @@ public class IdeDescriptorRenderers {
};
public static final DescriptorRenderer SOURCE_CODE = commonBuilder()
.setShortNames(false)
.setNameShortness(NameShortness.SOURCE_CODE_QUALIFIED)
.setTypeNormalizer(APPROXIMATE_FLEXIBLE_TYPES)
.build();
public static final DescriptorRenderer SOURCE_CODE_FOR_TYPE_ARGUMENTS = commonBuilder()
.setShortNames(false)
.setNameShortness(NameShortness.SOURCE_CODE_QUALIFIED)
.setTypeNormalizer(APPROXIMATE_FLEXIBLE_TYPES_IN_ARGUMENTS)
.build();
public static final DescriptorRenderer SOURCE_CODE_SHORT_NAMES_IN_TYPES = commonBuilder()
.setShortNames(true)
.setNameShortness(NameShortness.SHORT)
.setTypeNormalizer(APPROXIMATE_FLEXIBLE_TYPES)
.build();
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers;
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;
@@ -54,7 +55,7 @@ public abstract class OverrideImplementMethodsHandler implements LanguageCodeIns
.setRenderDefaultValues(false)
.setModifiers(DescriptorRenderer.Modifier.OVERRIDE)
.setWithDefinedIn(false)
.setShortNames(false)
.setNameShortness(NameShortness.SOURCE_CODE_QUALIFIED)
.setOverrideRenderingPolicy(DescriptorRenderer.OverrideRenderingPolicy.RENDER_OVERRIDE)
.setUnitReturnType(false)
.setTypeNormalizer(IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES)
@@ -22,10 +22,6 @@ import com.intellij.codeInsight.lookup.AutoCompletionPolicy
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.codeInsight.completion.CompletionService
import com.intellij.codeInsight.completion.CompletionProgressIndicator
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import com.intellij.codeInsight.completion.PrefixMatcher
@@ -66,6 +62,8 @@ import org.jetbrains.kotlin.psi.JetDeclarationWithBody
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
import org.jetbrains.kotlin.psi.JetLoopExpression
import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder
import org.jetbrains.kotlin.renderer.NameShortness
enum class ItemPriority {
MULTIPLE_ARGUMENTS_ITEM
@@ -109,21 +107,6 @@ fun rethrowWithCancelIndicator(exception: ProcessCanceledException): ProcessCanc
return exception
}
fun qualifiedNameForSourceCode(descriptor: ClassifierDescriptor): String? {
val name = descriptor.getName()
if (name.isSpecial()) return null
val nameString = IdeDescriptorRenderers.SOURCE_CODE.renderName(name)
val qualifier = qualifierName(descriptor.getContainingDeclaration())
return if (qualifier != null && qualifier != "") qualifier + "." + nameString else nameString
}
private fun qualifierName(descriptor: DeclarationDescriptor): String? = when (descriptor) {
is ClassDescriptor -> if (descriptor.getKind() != ClassKind.CLASS_OBJECT) qualifiedNameForSourceCode(descriptor) else qualifierName(descriptor.getContainingDeclaration())
is PackageViewDescriptor -> IdeDescriptorRenderers.SOURCE_CODE.renderFqName(descriptor.getFqName())
is PackageFragmentDescriptor -> IdeDescriptorRenderers.SOURCE_CODE.renderFqName(descriptor.fqName)
else -> null
}
fun PrefixMatcher.asNameFilter() = { (name: Name) -> !name.isSpecial() && prefixMatches(name.getIdentifier()) }
fun LookupElementPresentation.prependTailText(text: String, grayed: Boolean) {
@@ -43,11 +43,11 @@ import org.jetbrains.kotlin.psi.JetBinaryExpressionWithTypeRHS
import org.jetbrains.kotlin.idea.codeInsight.ShortenReferences
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.completion.qualifiedNameForSourceCode
import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.JetTypeArgumentList
import com.intellij.codeInsight.lookup.Lookup
import org.jetbrains.kotlin.idea.completion.isAfterDot
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
public abstract class KotlinCallableInsertHandler : BaseDeclarationInsertHandler() {
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
@@ -257,7 +257,7 @@ object CastReceiverInsertHandler : KotlinCallableInsertHandler() {
val project = context.getProject()
val thisObj = if (descriptor.getExtensionReceiverParameter() != null) descriptor.getExtensionReceiverParameter() else descriptor.getDispatchReceiverParameter()
val fqName = qualifiedNameForSourceCode(thisObj.getType().getConstructor().getDeclarationDescriptor())
val fqName = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(thisObj.getType().getConstructor().getDeclarationDescriptor())
val parentCast = JetPsiFactory(project).createExpression("(expr as $fqName)") as JetParenthesizedExpression
val cast = parentCast.getExpression() as JetBinaryExpressionWithTypeRHS
@@ -23,13 +23,13 @@ import org.jetbrains.kotlin.psi.JetFile
import org.jetbrains.kotlin.idea.codeInsight.ShortenReferences
import org.jetbrains.kotlin.idea.completion.DeclarationDescriptorLookupObject
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.idea.completion.qualifiedNameForSourceCode
import com.intellij.psi.PsiClass
import org.jetbrains.kotlin.psi.JetNameReferenceExpression
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.idea.completion.isAfterDot
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
public object KotlinClassInsertHandler : BaseDeclarationInsertHandler() {
override fun handleInsert(context: InsertionContext, item: LookupElement) {
@@ -52,7 +52,7 @@ public object KotlinClassInsertHandler : BaseDeclarationInsertHandler() {
if (nameRef != null) {
val bindingContext = nameRef.getResolutionFacade().analyze(nameRef, BodyResolveMode.PARTIAL)
val target = bindingContext[BindingContext.REFERENCE_TARGET, nameRef] as? ClassDescriptor
if (target != null && qualifiedNameForSourceCode(target) == qualifiedName) return
if (target != null && IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(target) == qualifiedName) return
}
val tempPrefix = if (nameRef != null)
@@ -83,7 +83,7 @@ public object KotlinClassInsertHandler : BaseDeclarationInsertHandler() {
private fun qualifiedNameToInsert(item: LookupElement): String {
val lookupObject = item.getObject()
return when (lookupObject) {
is DeclarationDescriptorLookupObject -> qualifiedNameForSourceCode(lookupObject.descriptor as ClassDescriptor)!!
is DeclarationDescriptorLookupObject -> IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(lookupObject.descriptor as ClassDescriptor)
is PsiClass -> lookupObject.getQualifiedName()!!
else -> error("Unknown object in LookupElement with KotlinClassInsertHandler: $lookupObject")
}
@@ -25,8 +25,6 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import com.intellij.codeInsight.completion.InsertionContext
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
import org.jetbrains.kotlin.idea.completion.qualifiedNameForSourceCode
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionFacade
@@ -35,6 +33,7 @@ import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.idea.util.fuzzyReturnType
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
import org.jetbrains.kotlin.idea.completion.isVisible
import org.jetbrains.kotlin.idea.completion.ExpectedInfo
// adds java static members, enum members and members from class object
class StaticMembers(
@@ -103,7 +102,7 @@ class StaticMembers(
private fun createLookupElement(memberDescriptor: DeclarationDescriptor, classDescriptor: ClassDescriptor): LookupElement {
val lookupElement = lookupElementFactory.createLookupElement(memberDescriptor, resolutionFacade, bindingContext, false)
val qualifierPresentation = classDescriptor.getName().asString()
val qualifierText = qualifiedNameForSourceCode(classDescriptor)
val qualifierText = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classDescriptor)
return object: LookupElementDecorator<LookupElement>(lookupElement) {
override fun getAllLookupStrings(): Set<String> {
@@ -164,7 +164,7 @@ class TypeInstantiationItems(
var signatureText: String? = null
val insertHandler: InsertHandler<LookupElement>
val typeText = qualifiedNameForSourceCode(classifier) + IdeDescriptorRenderers.SOURCE_CODE.renderTypeArguments(typeArgsToUse)
val typeText = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(classifier) + IdeDescriptorRenderers.SOURCE_CODE.renderTypeArguments(typeArgsToUse)
if (isAbstract) {
val constructorParenthesis = if (classifier.getKind() != ClassKind.TRAIT) "()" else ""
itemText += constructorParenthesis
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.load.java.structure.impl.JavaFieldImpl;
import org.jetbrains.kotlin.load.java.structure.impl.JavaMethodImpl;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder;
import org.jetbrains.kotlin.renderer.NameShortness;
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver;
import org.jetbrains.kotlin.resolve.jvm.JvmPackage;
@@ -55,7 +56,7 @@ import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_SIGNATURE
public class KotlinSignatureAnnotationIntention extends BaseIntentionAction implements Iconable {
private static final DescriptorRenderer RENDERER = new DescriptorRendererBuilder()
.setTypeNormalizer(IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES)
.setShortNames(true)
.setNameShortness(NameShortness.SHORT)
.setModifiers()
.setWithDefinedIn(false).build();
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.name.Name;
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.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil;
import org.jetbrains.kotlin.resolve.VisibilityUtil;
@@ -65,7 +66,7 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction<JetNamedFunc
.setTypeNormalizer(IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES)
.setWithDefinedIn(false)
.setModifiers()
.setShortNames(true)
.setNameShortness(NameShortness.SHORT)
.setUnitReturnType(false).build();
private final List<FunctionDescriptor> possibleSignatures;
@@ -0,0 +1,11 @@
abstract class C<A> {
abstract fun f(a: A)
}
fun f() {
class R
object : C<R> {
<caret>
}
}
@@ -0,0 +1,13 @@
abstract class C<A> {
abstract fun f(a: A)
}
fun f() {
class R
object : C<R> {
override fun f(a: R) {
<selection><caret>throw UnsupportedOperationException()</selection>
}
}
}
@@ -1,3 +1,3 @@
object {}
// RESULT: Cannot perform an action because following types are unavailable from debugger scope: errors.MyClass.baseFun.<no name provided>
// RESULT: Cannot perform an action because following types are unavailable from debugger scope: <no name provided>
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.A
Cannot extract method since following types are not denotable in the target scope: A
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.A
Cannot extract method since following types are not denotable in the target scope: A
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.A
Cannot extract method since following types are not denotable in the target scope: A
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.&lt;no name provided&gt;
Cannot extract method since following types are not denotable in the target scope: &lt;no name provided&gt;
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.&lt;no name provided&gt;
Cannot extract method since following types are not denotable in the target scope: &lt;no name provided&gt;
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.T
Cannot extract method since following types are not denotable in the target scope: T
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.X
Cannot extract method since following types are not denotable in the target scope: X
@@ -1 +1 @@
Cannot extract method since following types are not denotable in the target scope: foo.X
Cannot extract method since following types are not denotable in the target scope: X
@@ -193,4 +193,8 @@ public final class OverrideImplementTest extends AbstractOverrideImplementTest {
public void testMultipleSupers() {
doMultiOverrideFileTest();
}
public void testLocalClass() {
doImplementFileTest();
}
}