Correct visibility for non-public SAM-adapters

This commit is contained in:
Valentin Kipyatkov
2015-07-29 17:58:42 +03:00
parent 2eb04db95a
commit d5f95cf126
19 changed files with 219 additions and 96 deletions
@@ -183,7 +183,7 @@ public class OverloadsAnnotationChecker: DeclarationChecker {
if (descriptor is FunctionDescriptor && descriptor.getModality() == Modality.ABSTRACT) {
diagnosticHolder.report(ErrorsJvm.OVERLOADS_ABSTRACT.on(declaration))
}
else if ((!descriptor.getVisibility().isPublicAPI() && descriptor.getVisibility() != Visibilities.INTERNAL) ||
else if ((!descriptor.getVisibility().isPublicAPI && descriptor.getVisibility() != Visibilities.INTERNAL) ||
DescriptorUtils.isLocal(descriptor)) {
diagnosticHolder.report(ErrorsJvm.OVERLOADS_PRIVATE.on(declaration))
}
@@ -27,6 +27,7 @@ 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
@@ -45,7 +46,6 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : JetScope by Jet
}
private fun extensionForFunctionNotCached(function: FunctionDescriptor): FunctionDescriptor? {
//TODO!
if (function.visibility == Visibilities.PRIVATE || function.visibility == Visibilities.PRIVATE_TO_THIS || function.visibility == Visibilities.INVISIBLE_FAKE) return null
if (!function.hasJavaOriginInHierarchy()) return null //TODO: should we go into base at all?
if (!SingleAbstractMethodUtils.isSamAdapterNecessary(function)) return null
@@ -110,7 +110,27 @@ class SamAdapterFunctionsScope(storageManager: StorageManager) : JetScope by Jet
val returnType = typeSubstitutor.safeSubstitute(originalFunction.returnType!!, Variance.OUT_VARIANCE)
val receiverType = typeSubstitutor.safeSubstitute(ownerClass.defaultType, Variance.INVARIANT)
val valueParameters = SingleAbstractMethodUtils.createValueParametersForSamAdapter(originalFunction, this, typeSubstitutor)
initialize(receiverType, null, typeParameters, valueParameters, returnType, Modality.FINAL, Visibilities.PUBLIC)
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"
}
}
initialize(receiverType, null, typeParameters, valueParameters, returnType, Modality.FINAL, visibility)
}
override fun hasStableParameterNames() = originalFunction.hasStableParameterNames()
@@ -339,7 +339,7 @@ public class DeclarationsChecker {
JetFunction function = (JetFunction) member;
hasDeferredType = function.getTypeReference() == null && function.hasBody() && !function.hasBlockBody();
}
if ((memberDescriptor.getVisibility().isPublicAPI()) && memberDescriptor.getOverriddenDescriptors().size() == 0 && hasDeferredType) {
if ((memberDescriptor.getVisibility().getIsPublicAPI()) && memberDescriptor.getOverriddenDescriptors().size() == 0 && hasDeferredType) {
trace.report(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE.on(member));
}
}
@@ -27,10 +27,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.*;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.JetKeywordToken;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
@@ -896,7 +893,7 @@ public class DescriptorResolver {
boolean definedInClass = DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) != null;
boolean isLocal = DescriptorUtils.isLocal(descriptor);
Visibility visibility = descriptor.getVisibility();
boolean transformNeeded = !isLocal && !visibility.isPublicAPI()
boolean transformNeeded = !isLocal && !visibility.getIsPublicAPI()
&& !(definedInClass && Visibilities.isPrivate(visibility));
if (transformNeeded) {
if (type.getConstructor().getSupertypes().size() == 1) {
@@ -0,0 +1,13 @@
// FILE: KotlinFile.kt
package k
import JavaClass
fun foo(javaClass: JavaClass) {
javaClass.<!INVISIBLE_MEMBER!>doSomething<!> <!TYPE_MISMATCH!>{ }<!>
}
// FILE: JavaClass.java
public class JavaClass {
void doSomething(Runnable runnable) { runnable.run(); }
}
@@ -0,0 +1,13 @@
package
public open class JavaClass {
public constructor JavaClass()
public/*package*/ open fun doSomething(/*0*/ runnable: java.lang.Runnable!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package k {
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
}
@@ -0,0 +1,13 @@
// FILE: KotlinFile.kt
package k
import JavaClass
fun foo(javaClass: JavaClass) {
javaClass.<!INVISIBLE_MEMBER!>doSomething<!> <!TYPE_MISMATCH!>{ }<!>
}
// FILE: JavaClass.java
public class JavaClass {
private void doSomething(Runnable runnable) { runnable.run(); }
}
@@ -0,0 +1,13 @@
package
public open class JavaClass {
public constructor JavaClass()
private open fun doSomething(/*0*/ runnable: java.lang.Runnable!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package k {
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
}
@@ -0,0 +1,24 @@
// FILE: KotlinFile.kt
package k
import JavaClass
fun foo(javaClass: JavaClass) {
javaClass.<!INVISIBLE_MEMBER!>doSomething<!> <!TYPE_MISMATCH!>{
bar()
}<!>
}
class X : JavaClass() {
fun foo(other: JavaClass) {
doSomething { bar() }
other.doSomething { bar() } // currently not flagged as error - see KT-8654
}
}
fun bar(){}
// FILE: JavaClass.java
public class JavaClass {
protected void doSomething(Runnable runnable) { runnable.run(); }
}
@@ -0,0 +1,23 @@
package
public open class JavaClass {
public constructor JavaClass()
protected/*protected and package*/ open fun doSomething(/*0*/ runnable: java.lang.Runnable!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
package k {
internal fun bar(): kotlin.Unit
internal fun foo(/*0*/ javaClass: JavaClass): kotlin.Unit
internal final class X : JavaClass {
public constructor X()
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun doSomething(/*0*/ runnable: java.lang.Runnable!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(/*0*/ other: JavaClass): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -14435,6 +14435,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("PackageLocal.kt")
public void testPackageLocal() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/PackageLocal.kt");
doTest(fileName);
}
@TestMetadata("ParameterTypeAnnotation.kt")
public void testParameterTypeAnnotation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ParameterTypeAnnotation.kt");
@@ -14447,6 +14453,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("Private.kt")
public void testPrivate() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Private.kt");
doTest(fileName);
}
@TestMetadata("Protected.kt")
public void testProtected() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/Protected.kt");
doTest(fileName);
}
@TestMetadata("ReturnTypeAnnotation.kt")
public void testReturnTypeAnnotation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/syntheticExtensions/samAdapters/ReturnTypeAnnotation.kt");