Synthetic extensions for non-public get/set java methods

This commit is contained in:
Valentin Kipyatkov
2015-07-29 18:15:27 +03:00
parent d5f95cf126
commit c3064e2b0f
8 changed files with 84 additions and 35 deletions
@@ -116,7 +116,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
return descriptor.valueParameters.isEmpty()
&& descriptor.typeParameters.isEmpty()
&& descriptor.visibility == Visibilities.PUBLIC //TODO: what about protected and package-local?
&& descriptor.visibility.isVisibleOutside()
}
private fun isGoodSetMethod(descriptor: FunctionDescriptor, getMethod: FunctionDescriptor): Boolean {
@@ -133,7 +133,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
return parameter.varargElementType == null
&& descriptor.typeParameters.isEmpty()
&& descriptor.returnType?.let { it.isUnit() } ?: false
&& descriptor.visibility == Visibilities.PUBLIC
&& descriptor.visibility.isVisibleOutside()
}
private fun FunctionDescriptor.findOverridden(condition: (FunctionDescriptor) -> Boolean): FunctionDescriptor? {
@@ -251,15 +251,15 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
name: Name,
type: JetType
) : SyntheticJavaPropertyDescriptor, PropertyDescriptorImpl(
DescriptorUtils.getContainingModule(ownerClass)/* TODO:is it ok? */,
DescriptorUtils.getContainingModule(ownerClass),
null,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.PUBLIC,
syntheticExtensionVisibility(getMethod),
setMethod != null,
name,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE/*TODO?*/
SourceElement.NO_SOURCE
) {
init {
val classTypeParams = ownerClass.typeConstructor.parameters
@@ -273,24 +273,24 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
val getter = PropertyGetterDescriptorImpl(this,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.PUBLIC,
visibility,
false,
false,
CallableMemberDescriptor.Kind.SYNTHESIZED,
null,
SourceElement.NO_SOURCE/*TODO*/)
SourceElement.NO_SOURCE)
getter.initialize(null)
val setter = if (setMethod != null)
PropertySetterDescriptorImpl(this,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.PUBLIC,
syntheticExtensionVisibility(setMethod),
false,
false,
CallableMemberDescriptor.Kind.SYNTHESIZED,
null,
SourceElement.NO_SOURCE/*TODO*/)
SourceElement.NO_SOURCE)
else
null
setter?.initializeDefault()
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.DescriptorSubstitutor
import org.jetbrains.kotlin.types.JetType
@@ -46,7 +45,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : JetScope by Jet
}
private fun extensionForFunctionNotCached(function: FunctionDescriptor): FunctionDescriptor? {
if (function.visibility == Visibilities.PRIVATE || function.visibility == Visibilities.PRIVATE_TO_THIS || function.visibility == Visibilities.INVISIBLE_FAKE) return null
if (!function.visibility.isVisibleOutside()) return null
if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all?
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
if (function.returnType == null) return null
@@ -111,24 +110,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : JetScope by Jet
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(originalFunction, this, typeSubstitutor)
val originalVisibility = originalFunction.visibility
val visibility = when (originalVisibility) {
Visibilities.PUBLIC -> Visibilities.PUBLIC
else -> object : Visibility(originalVisibility.name, originalVisibility.isPublicAPI) {
override fun isVisible(receiver: ReceiverValue, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
= originalVisibility.isVisible(receiver, originalFunction, from)
override fun mustCheckInImports()
= throw UnsupportedOperationException("Should never be called for this visibility")
override fun normalize()
= originalVisibility.normalize()
override val displayName: String
get() = originalVisibility.displayName + " for synthetic extension"
}
}
val visibility = syntheticExtensionVisibility(originalFunction)
initialize(receiverType, null, typeParameters, valueParameters, returnType, Modality.FINAL, visibility)
}
@@ -16,8 +16,9 @@
package org.jetbrains.kotlin.synthetic
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
return if (overriddenDescriptors.isEmpty())
@@ -25,3 +26,27 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
else
overriddenDescriptors.any { it.hasJavaOriginInHierarchy() }
}
fun Visibility.isVisibleOutside() = this != Visibilities.PRIVATE && this != Visibilities.PRIVATE_TO_THIS && this != Visibilities.INVISIBLE_FAKE
fun syntheticExtensionVisibility(originalDescriptor: DeclarationDescriptorWithVisibility): Visibility {
val originalVisibility = originalDescriptor.visibility
return when (originalVisibility) {
Visibilities.PUBLIC -> Visibilities.PUBLIC
else -> object : Visibility(originalVisibility.name, originalVisibility.isPublicAPI) {
override fun isVisible(receiver: ReceiverValue, what: DeclarationDescriptorWithVisibility, from: DeclarationDescriptor)
= originalVisibility.isVisible(receiver, originalDescriptor, from)
override fun mustCheckInImports()
= throw UnsupportedOperationException("Should never be called for this visibility")
override fun normalize()
= originalVisibility.normalize()
override val displayName: String
get() = originalVisibility.displayName + " for synthetic extension"
}
}
}