Create SyntheticMemberDescriptor interface

Implement this interface by sam adapters/constructors and use it in navigation

 #KT-11708 Fixed
This commit is contained in:
Pavel V. Talanov
2016-06-20 18:16:51 +03:00
parent 4087e650aa
commit bafe8e55ce
15 changed files with 106 additions and 48 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -19,18 +19,16 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor; import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor; import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
public class SamCodegenUtil { public class SamCodegenUtil {
@Nullable @Nullable
public static FunctionDescriptor getOriginalIfSamAdapter(@NotNull FunctionDescriptor fun) { public static FunctionDescriptor getOriginalIfSamAdapter(@NotNull FunctionDescriptor fun) {
if (fun instanceof SamAdapterDescriptor<?>) { if (fun instanceof SamAdapterDescriptor<?> || fun instanceof SamAdapterExtensionFunctionDescriptor) {
return ((SamAdapterDescriptor<?>) fun).getOriginForSam(); //noinspection unchecked
} return ((SyntheticMemberDescriptor<FunctionDescriptor>) fun).getBaseDescriptorForSynthetic();
if (fun instanceof SamAdapterExtensionFunctionDescriptor) {
return ((SamAdapterExtensionFunctionDescriptor) fun).getSourceFunction();
} }
return null; return null;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,12 +18,14 @@ package org.jetbrains.kotlin.load.java.sam;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor; import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
/* package */ class SamAdapterConstructorDescriptor extends JavaConstructorDescriptor implements SamAdapterDescriptor<JavaConstructorDescriptor> { /* package */ class SamAdapterConstructorDescriptor extends JavaConstructorDescriptor
implements SamAdapterDescriptor<JavaConstructorDescriptor> {
private final JavaConstructorDescriptor declaration; private final JavaConstructorDescriptor declaration;
public SamAdapterConstructorDescriptor(@NotNull JavaConstructorDescriptor declaration) { public SamAdapterConstructorDescriptor(@NotNull JavaConstructorDescriptor declaration) {
@@ -61,7 +63,7 @@ import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
@NotNull @NotNull
@Override @Override
public JavaConstructorDescriptor getOriginForSam() { public JavaConstructorDescriptor getBaseDescriptorForSynthetic() {
return declaration; return declaration;
} }
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -45,12 +45,6 @@ import org.jetbrains.kotlin.name.Name;
setParameterNamesStatus(declaration.hasStableParameterNames(), declaration.hasSynthesizedParameterNames()); setParameterNamesStatus(declaration.hasStableParameterNames(), declaration.hasSynthesizedParameterNames());
} }
@NotNull
@Override
public JavaMethodDescriptor getOriginForSam() {
return declaration;
}
@NotNull @NotNull
@Override @Override
protected JavaMethodDescriptor createSubstitutedCopy( protected JavaMethodDescriptor createSubstitutedCopy(
@@ -63,4 +57,10 @@ import org.jetbrains.kotlin.name.Name;
) { ) {
return new SamAdapterFunctionDescriptor(newOwner, (SimpleFunctionDescriptor) original, kind, declaration); return new SamAdapterFunctionDescriptor(newOwner, (SimpleFunctionDescriptor) original, kind, declaration);
} }
@NotNull
@Override
public JavaMethodDescriptor getBaseDescriptorForSynthetic() {
return declaration;
}
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -106,7 +106,7 @@ public class SamAdapterOverridabilityCondition implements ExternalOverridability
return null; return null;
} }
SimpleFunctionDescriptor originalDeclarationOfSam = ((SamAdapterFunctionDescriptor) fun).getOriginForSam(); SimpleFunctionDescriptor originalDeclarationOfSam = ((SamAdapterFunctionDescriptor) fun).getBaseDescriptorForSynthetic();
return ((SimpleFunctionDescriptor) originalDeclarationOfSam.substitute(TypeSubstitutor.create(declarationOrSynthesized.ownerType))); return ((SimpleFunctionDescriptor) originalDeclarationOfSam.substitute(TypeSubstitutor.create(declarationOrSynthesized.ownerType)));
} }
@@ -33,7 +33,7 @@ object ProtectedSyntheticExtensionCallChecker : SimpleCallChecker {
val sourceFunction = when (descriptor) { val sourceFunction = when (descriptor) {
is SyntheticJavaPropertyDescriptor -> descriptor.getMethod is SyntheticJavaPropertyDescriptor -> descriptor.getMethod
is SamAdapterExtensionFunctionDescriptor -> descriptor.sourceFunction is SamAdapterExtensionFunctionDescriptor -> descriptor.baseDescriptorForSynthetic
else -> return else -> return
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import com.intellij.util.SmartList
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils import org.jetbrains.kotlin.load.java.sam.SingleAbstractMethodUtils
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -33,8 +34,8 @@ import org.jetbrains.kotlin.types.*
import java.util.* import java.util.*
import kotlin.properties.Delegates import kotlin.properties.Delegates
interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor { interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, SyntheticMemberDescriptor<FunctionDescriptor> {
val sourceFunction: FunctionDescriptor override val baseDescriptorForSynthetic: FunctionDescriptor
} }
class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope { class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope {
@@ -92,7 +93,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
source: SourceElement source: SourceElement
) : SamAdapterExtensionFunctionDescriptor, SimpleFunctionDescriptorImpl(containingDeclaration, original, annotations, name, kind, source) { ) : SamAdapterExtensionFunctionDescriptor, SimpleFunctionDescriptorImpl(containingDeclaration, original, annotations, name, kind, source) {
override var sourceFunction: FunctionDescriptor by Delegates.notNull() override var baseDescriptorForSynthetic: FunctionDescriptor by Delegates.notNull()
private set private set
private var toSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor>? = null private var toSourceFunctionTypeParameters: Map<TypeParameterDescriptor, TypeParameterDescriptor>? = null
@@ -105,7 +106,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
sourceFunction.name, sourceFunction.name,
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
sourceFunction.original.source) sourceFunction.original.source)
descriptor.sourceFunction = sourceFunction descriptor.baseDescriptorForSynthetic = sourceFunction
val sourceTypeParams = (sourceFunction.typeParameters).toMutableList() val sourceTypeParams = (sourceFunction.typeParameters).toMutableList()
val ownerClass = sourceFunction.containingDeclaration as ClassDescriptor val ownerClass = sourceFunction.containingDeclaration as ClassDescriptor
@@ -138,8 +139,8 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
} }
} }
override fun hasStableParameterNames() = sourceFunction.hasStableParameterNames() override fun hasStableParameterNames() = baseDescriptorForSynthetic.hasStableParameterNames()
override fun hasSynthesizedParameterNames() = sourceFunction.hasSynthesizedParameterNames() override fun hasSynthesizedParameterNames() = baseDescriptorForSynthetic.hasSynthesizedParameterNames()
override fun createSubstitutedCopy( override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor, newOwner: DeclarationDescriptor,
@@ -152,7 +153,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
return MyFunctionDescriptor( return MyFunctionDescriptor(
containingDeclaration, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, source containingDeclaration, original as SimpleFunctionDescriptor?, annotations, newName ?: name, kind, source
).apply { ).apply {
sourceFunction = this@MyFunctionDescriptor.sourceFunction baseDescriptorForSynthetic = this@MyFunctionDescriptor.baseDescriptorForSynthetic
} }
} }
@@ -176,7 +177,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : SyntheticScope
TypeConstructorSubstitution.createByConstructorsMap( TypeConstructorSubstitution.createByConstructorsMap(
substitutionMap, configuration.substitution.approximateCapturedTypes()).buildSubstitutor() substitutionMap, configuration.substitution.approximateCapturedTypes()).buildSubstitutor()
descriptor.sourceFunction = original.sourceFunction.substitute(sourceFunctionSubstitutor) descriptor.baseDescriptorForSynthetic = original.baseDescriptorForSynthetic.substitute(sourceFunctionSubstitutor)
return descriptor return descriptor
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -17,13 +17,11 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
@@ -39,6 +37,10 @@ object DescriptorToSourceUtils {
} }
return return
} }
if (descriptor is SyntheticMemberDescriptor<*>) {
collectEffectiveReferencedDescriptors(result, descriptor.baseDescriptorForSynthetic)
return
}
} }
result.add(descriptor) result.add(descriptor)
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,10 +16,9 @@
package org.jetbrains.kotlin.load.java.descriptors; package org.jetbrains.kotlin.load.java.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor;
public interface SamAdapterDescriptor<D extends FunctionDescriptor> extends FunctionDescriptor, JavaCallableMemberDescriptor { public interface SamAdapterDescriptor<D extends FunctionDescriptor> extends FunctionDescriptor, JavaCallableMemberDescriptor,
@NotNull SyntheticMemberDescriptor<D> {
D getOriginForSam();
} }
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,14 +16,15 @@
package org.jetbrains.kotlin.load.java.descriptors package org.jetbrains.kotlin.load.java.descriptors
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude
class SamConstructorDescriptor( class SamConstructorDescriptor(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
samInterface: JavaClassDescriptor private val samInterface: JavaClassDescriptor
) : SimpleFunctionDescriptorImpl( ) : SimpleFunctionDescriptorImpl(
containingDeclaration, containingDeclaration,
null, null,
@@ -31,7 +32,10 @@ class SamConstructorDescriptor(
samInterface.name, samInterface.name,
CallableMemberDescriptor.Kind.SYNTHESIZED, CallableMemberDescriptor.Kind.SYNTHESIZED,
samInterface.source samInterface.source
) ), SyntheticMemberDescriptor<JavaClassDescriptor> {
override val baseDescriptorForSynthetic: JavaClassDescriptor
get() = samInterface
}
object SamConstructorDescriptorKindExclude : DescriptorKindExclude() { object SamConstructorDescriptorKindExclude : DescriptorKindExclude() {
override fun excludes(descriptor: DeclarationDescriptor) = descriptor is SamConstructorDescriptor override fun excludes(descriptor: DeclarationDescriptor) = descriptor is SamConstructorDescriptor
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2016 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.descriptors.synthetic
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
interface SyntheticMemberDescriptor<out T : DeclarationDescriptor> {
val baseDescriptorForSynthetic: T
}
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -305,7 +305,7 @@ class LookupElementFactory(
return callableWeight(descriptor.getMethod) return callableWeight(descriptor.getMethod)
} }
if (descriptor is SamAdapterExtensionFunctionDescriptor) { if (descriptor is SamAdapterExtensionFunctionDescriptor) {
return callableWeight(descriptor.sourceFunction) return callableWeight(descriptor.baseDescriptorForSynthetic)
} }
if (descriptor.overriddenDescriptors.isNotEmpty()) { if (descriptor.overriddenDescriptors.isNotEmpty()) {
@@ -1,5 +1,5 @@
/* /*
* Copyright 2010-2015 JetBrains s.r.o. * Copyright 2010-2016 JetBrains s.r.o.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -288,7 +288,7 @@ class KotlinIndicesHelper(
// SAM-adapter // SAM-adapter
container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE) container.staticScope.getContributedFunctions(descriptor.name, NoLookupLocation.FROM_IDE)
.filterIsInstance<SamAdapterDescriptor<*>>() .filterIsInstance<SamAdapterDescriptor<*>>()
.firstOrNull { it.originForSam.original == descriptor.original } .firstOrNull { it.baseDescriptorForSynthetic.original == descriptor.original }
?.let { processor(it) } ?.let { processor(it) }
} }
} }
@@ -0,0 +1,13 @@
package test
class MyClass: Test() {
}
fun test(m: MyClass) {
m.ac<caret>t {
}
}
// REF: (in test.Test).act(Action)
@@ -0,0 +1,10 @@
package test;
public class Test {
public interface Action {
String doSmth(String other);
}
void act(Action action) {
}
}
@@ -77,6 +77,12 @@ public class ReferenceResolveWithLibTestGenerated extends AbstractReferenceResol
doTest(fileName); doTest(fileName);
} }
@TestMetadata("overridingFunctionWithSamAdapter.kt")
public void testOverridingFunctionWithSamAdapter() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceWithLib/overridingFunctionWithSamAdapter.kt");
doTest(fileName);
}
@TestMetadata("packageOfLibDeclaration.kt") @TestMetadata("packageOfLibDeclaration.kt")
public void testPackageOfLibDeclaration() throws Exception { public void testPackageOfLibDeclaration() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceWithLib/packageOfLibDeclaration.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/resolve/referenceWithLib/packageOfLibDeclaration.kt");