Synthetic extensions for non-public get/set java methods
This commit is contained in:
+9
-9
@@ -116,7 +116,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
|
|||||||
|
|
||||||
return descriptor.valueParameters.isEmpty()
|
return descriptor.valueParameters.isEmpty()
|
||||||
&& descriptor.typeParameters.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 {
|
private fun isGoodSetMethod(descriptor: FunctionDescriptor, getMethod: FunctionDescriptor): Boolean {
|
||||||
@@ -133,7 +133,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
|
|||||||
return parameter.varargElementType == null
|
return parameter.varargElementType == null
|
||||||
&& descriptor.typeParameters.isEmpty()
|
&& descriptor.typeParameters.isEmpty()
|
||||||
&& descriptor.returnType?.let { it.isUnit() } ?: false
|
&& descriptor.returnType?.let { it.isUnit() } ?: false
|
||||||
&& descriptor.visibility == Visibilities.PUBLIC
|
&& descriptor.visibility.isVisibleOutside()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FunctionDescriptor.findOverridden(condition: (FunctionDescriptor) -> Boolean): FunctionDescriptor? {
|
private fun FunctionDescriptor.findOverridden(condition: (FunctionDescriptor) -> Boolean): FunctionDescriptor? {
|
||||||
@@ -251,15 +251,15 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
|
|||||||
name: Name,
|
name: Name,
|
||||||
type: JetType
|
type: JetType
|
||||||
) : SyntheticJavaPropertyDescriptor, PropertyDescriptorImpl(
|
) : SyntheticJavaPropertyDescriptor, PropertyDescriptorImpl(
|
||||||
DescriptorUtils.getContainingModule(ownerClass)/* TODO:is it ok? */,
|
DescriptorUtils.getContainingModule(ownerClass),
|
||||||
null,
|
null,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
syntheticExtensionVisibility(getMethod),
|
||||||
setMethod != null,
|
setMethod != null,
|
||||||
name,
|
name,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
SourceElement.NO_SOURCE/*TODO?*/
|
SourceElement.NO_SOURCE
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
val classTypeParams = ownerClass.typeConstructor.parameters
|
val classTypeParams = ownerClass.typeConstructor.parameters
|
||||||
@@ -273,24 +273,24 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager) : JetScopeImp
|
|||||||
val getter = PropertyGetterDescriptorImpl(this,
|
val getter = PropertyGetterDescriptorImpl(this,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
visibility,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
null,
|
null,
|
||||||
SourceElement.NO_SOURCE/*TODO*/)
|
SourceElement.NO_SOURCE)
|
||||||
getter.initialize(null)
|
getter.initialize(null)
|
||||||
|
|
||||||
val setter = if (setMethod != null)
|
val setter = if (setMethod != null)
|
||||||
PropertySetterDescriptorImpl(this,
|
PropertySetterDescriptorImpl(this,
|
||||||
Annotations.EMPTY,
|
Annotations.EMPTY,
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Visibilities.PUBLIC,
|
syntheticExtensionVisibility(setMethod),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
null,
|
null,
|
||||||
SourceElement.NO_SOURCE/*TODO*/)
|
SourceElement.NO_SOURCE)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
setter?.initializeDefault()
|
setter?.initializeDefault()
|
||||||
|
|||||||
+2
-20
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parentsWithSelf
|
||||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
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.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.DescriptorSubstitutor
|
import org.jetbrains.kotlin.types.DescriptorSubstitutor
|
||||||
import org.jetbrains.kotlin.types.JetType
|
import org.jetbrains.kotlin.types.JetType
|
||||||
@@ -46,7 +45,7 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : JetScope by Jet
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extensionForFunctionNotCached(function: FunctionDescriptor): FunctionDescriptor? {
|
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 (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all?
|
||||||
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
|
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
|
||||||
if (function.returnType == null) 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 receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
|
||||||
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(originalFunction, this, typeSubstitutor)
|
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(originalFunction, this, typeSubstitutor)
|
||||||
|
|
||||||
val originalVisibility = originalFunction.visibility
|
val visibility = syntheticExtensionVisibility(originalFunction)
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initialize(receiverType, null, typeParameters, valueParameters, returnType, Modality.FINAL, visibility)
|
initialize(receiverType, null, typeParameters, valueParameters, returnType, Modality.FINAL, visibility)
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-1
@@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.synthetic
|
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.load.java.descriptors.JavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
|
||||||
fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
|
fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
|
||||||
return if (overriddenDescriptors.isEmpty())
|
return if (overriddenDescriptors.isEmpty())
|
||||||
@@ -25,3 +26,27 @@ fun FunctionDescriptor.hasJavaOriginInHierarchy(): Boolean {
|
|||||||
else
|
else
|
||||||
overriddenDescriptors.any { it.hasJavaOriginInHierarchy() }
|
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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+7
-3
@@ -1,10 +1,14 @@
|
|||||||
// FILE: KotlinFile.kt
|
// FILE: KotlinFile.kt
|
||||||
|
package k
|
||||||
|
|
||||||
|
import JavaClass
|
||||||
|
|
||||||
fun foo(javaClass: JavaClass) {
|
fun foo(javaClass: JavaClass) {
|
||||||
javaClass.somethingPublic
|
javaClass.somethingPublic
|
||||||
javaClass.<!UNRESOLVED_REFERENCE!>somethingProtected<!>
|
javaClass.<!INVISIBLE_MEMBER!>somethingProtected<!>
|
||||||
javaClass.<!UNRESOLVED_REFERENCE!>somethingPrivate<!>
|
javaClass.<!UNRESOLVED_REFERENCE!>somethingPrivate<!>
|
||||||
javaClass.<!UNRESOLVED_REFERENCE!>somethingPackage<!>
|
javaClass.<!INVISIBLE_MEMBER!>somethingPackage<!>
|
||||||
<!VAL_REASSIGNMENT!>javaClass.somethingPublic<!> = 1
|
<!INVISIBLE_SETTER!>javaClass.somethingPublic<!> = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// FILE: JavaClass.java
|
// FILE: JavaClass.java
|
||||||
|
|||||||
+4
-2
@@ -1,7 +1,5 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
|
|
||||||
|
|
||||||
public open class JavaClass {
|
public open class JavaClass {
|
||||||
public constructor JavaClass()
|
public constructor JavaClass()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
@@ -13,3 +11,7 @@ public open class JavaClass {
|
|||||||
protected/*protected and package*/ open fun setSomethingPublic(/*0*/ value: kotlin.Int): kotlin.Unit
|
protected/*protected and package*/ open fun setSomethingPublic(/*0*/ value: kotlin.Int): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
package k {
|
||||||
|
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// FILE: KotlinFile.kt
|
||||||
|
package k
|
||||||
|
|
||||||
|
import JavaClass
|
||||||
|
|
||||||
|
fun foo(javaClass: JavaClass) {
|
||||||
|
val <!UNUSED_VARIABLE!>v<!> = javaClass.<!INVISIBLE_MEMBER!>something<!>
|
||||||
|
javaClass.<!INVISIBLE_MEMBER!>something<!> = 1
|
||||||
|
javaClass.<!INVISIBLE_MEMBER!>something<!>++
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: JavaClass.java
|
||||||
|
public class JavaClass {
|
||||||
|
protected int getSomething() { return 1; }
|
||||||
|
public void setSomething(int value) {}
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public open class JavaClass {
|
||||||
|
public constructor JavaClass()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
protected/*protected and package*/ open fun getSomething(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open fun setSomething(/*0*/ value: kotlin.Int): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
package k {
|
||||||
|
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
|
||||||
|
}
|
||||||
@@ -14366,6 +14366,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("SetterHasHigherAccess.kt")
|
||||||
|
public void testSetterHasHigherAccess() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/SetterHasHigherAccess.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("SetterOnly.kt")
|
@TestMetadata("SetterOnly.kt")
|
||||||
public void testSetterOnly() throws Exception {
|
public void testSetterOnly() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/SetterOnly.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/javaProperties/SetterOnly.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user