overriddenDescriptors is empty for java static property and function declarations

Fake overrides are still created for java static with non-empty overriddenDescriptors

Add tests for inheriting visibility for java static members
Add test: check that java static declarations that shadow deprecated declarations should not be deprecated
Add test for corner case where "overriding" java static constant led to incorrect type in inheritor

Fix test data for existing tests
This commit is contained in:
Pavel V. Talanov
2016-02-08 19:04:18 +03:00
parent 7e78e8d8ab
commit 7d98103c0c
30 changed files with 249 additions and 39 deletions
@@ -191,7 +191,7 @@ class CollectionStubMethodGenerator(
): List<FunctionDescriptor> {
val result = ArrayList<FunctionDescriptor>()
OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingStrategy {
OverrideResolver.generateOverridesInAClass(klass, listOf(), object : OverridingStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
if (fakeOverride !is FunctionDescriptor) return
if (fakeOverride.findOverriddenFromDirectSuperClass(mutableCollectionClass)?.kind == DECLARATION) {
@@ -99,7 +99,7 @@ open class LazyClassMemberScope(
}
private fun <D : CallableMemberDescriptor> generateFakeOverrides(name: Name, fromSupertypes: Collection<D>, result: MutableCollection<D>, exactDescriptorClass: Class<out D>) {
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, ArrayList(result), thisDescriptor, object : OverridingStrategy {
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, ArrayList(result), thisDescriptor, object : OverridingStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
assert(exactDescriptorClass.isInstance(fakeOverride)) { "Wrong descriptor type in an override: " + fakeOverride + " while expecting " + exactDescriptorClass.simpleName }
@Suppress("UNCHECKED_CAST")
@@ -0,0 +1,53 @@
// FILE: A.java
public class A {
@Deprecated
public static final String D = "d";
@Deprecated
public void f() {
return text;
}
@Deprecated
public static void bar() {
}
}
// FILE: B.java
public class B extends A {
public static final String D = "d";
@Override
public void f() {
return text;
}
public static void bar() {
}
}
// FILE: C.java
public class C extends A {
}
// FILE: use.kt
fun use(a: A, b: B, c: C) {
a.<!DEPRECATION!>f<!>()
b.<!DEPRECATION!>f<!>()
c.<!DEPRECATION!>f<!>()
A.<!DEPRECATION!>D<!>
B.D
C.<!DEPRECATION!>D<!>
A.<!DEPRECATION!>bar<!>()
B.bar()
C.<!DEPRECATION!>bar<!>()
}
@@ -0,0 +1,39 @@
package
public fun use(/*0*/ a: A, /*1*/ b: B, /*2*/ c: C): kotlin.Unit
public open class A {
public constructor A()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@kotlin.Deprecated(message = "Deprecated in Java") public open fun f(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
@kotlin.Deprecated(message = "Deprecated in Java") public const final val D: kotlin.String = "d"
@kotlin.Deprecated(message = "Deprecated in Java") public open fun bar(): kotlin.Unit
}
public open class B : A {
public constructor B()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@java.lang.Override() public open override /*1*/ fun f(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public const final val D: kotlin.String = "d"
public open fun bar(): kotlin.Unit
}
public open class C : A {
public constructor C()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@kotlin.Deprecated(message = "Deprecated in Java") public open override /*1*/ /*fake_override*/ fun f(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
@kotlin.Deprecated(message = "Deprecated in Java") public const final override /*1*/ /*fake_override*/ val D: kotlin.String
@kotlin.Deprecated(message = "Deprecated in Java") public open override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit
}
@@ -19,5 +19,5 @@ public open class Bbb : Aaa {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public const final override /*1*/ val i: kotlin.String = "s"
public const final val i: kotlin.String = "s"
}
@@ -0,0 +1,24 @@
// FILE: B.kt
import aa.B
fun use() {
// checking that CONST is of platform type
B.CONST = null
B.CONST?.length
B.CONST.length
}
// FILE: aa/A.java
package aa;
public class A {
public static int CONST = 3;
}
// FILE: aa/B.java
package aa;
public class B extends A {
public static String CONST = null;
}
@@ -0,0 +1,3 @@
package
public fun use(): kotlin.Unit
@@ -23,8 +23,8 @@ public/*package*/ open class B : A {
// Static members
public final var a: kotlin.Int
public final override /*1*/ var b: kotlin.Int
public open override /*1*/ fun bar(): kotlin.Unit
public final var b: kotlin.Int
public open fun bar(): kotlin.Unit
public open fun bar(/*0*/ i: kotlin.Int): kotlin.Unit
public open fun foo(): kotlin.Unit
public open fun foo(/*0*/ i: kotlin.Int): kotlin.Unit
@@ -38,5 +38,5 @@ public open class O : A, B {
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final override /*2*/ var field: kotlin.Double
public final var field: kotlin.Double
}
@@ -17,7 +17,7 @@ public interface B : A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public const final override /*1*/ val field: kotlin.String
public const final val field: kotlin.String
}
public open class E : A, B {
@@ -38,5 +38,5 @@ public open class O : A, B {
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final override /*2*/ var field: kotlin.Double
public final var field: kotlin.Double
}
@@ -67,7 +67,7 @@ public open class EO : E {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final override /*2*/ var field: kotlin.Double
public final var field: kotlin.Double
}
public open class O : C, D {
@@ -77,7 +77,7 @@ public open class O : C, D {
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final override /*2*/ var field: kotlin.Double
public final var field: kotlin.Double
}
public open class OO : O {
@@ -35,7 +35,7 @@ public open class E : D, I {
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public/*package*/ final override /*2*/ var a: kotlin.Int
public/*package*/ final var a: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var b: kotlin.Int
public/*package*/ final override /*1*/ /*fake_override*/ var c: kotlin.Int
public/*package*/ open override /*1*/ /*fake_override*/ fun bar(): kotlin.Unit
@@ -18,8 +18,8 @@ public open class B : A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public/*package*/ open override /*1*/ fun bar(): kotlin.Long
public/*package*/ open override /*1*/ fun foo(): kotlin.Unit
public/*package*/ open fun bar(): kotlin.Long
public/*package*/ open fun foo(): kotlin.Unit
}
public final class E : B {
@@ -39,7 +39,7 @@ public open class X : B {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public/*package*/ open override /*1*/ fun foo(): kotlin.Double
public/*package*/ open fun foo(): kotlin.Double
}
public final class Y : X {
@@ -19,7 +19,7 @@ public open class B : A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public open override /*1*/ fun foo(): kotlin.Int
public open fun foo(): kotlin.Int
}
public final class C : B {
@@ -5,11 +5,11 @@ public/*package*/ open class Child : test.Parent {
// Static members
public final override /*1*/ /*fake_override*/ var a: kotlin.Int
public final override /*1*/ var b: kotlin.String
public final var b: kotlin.String!
public final var c: kotlin.Int
public open fun bar(): kotlin.Unit
public open fun bar(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ fun baz(): kotlin.Unit
public open fun baz(): kotlin.Unit
public open fun baz(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun foo(): kotlin.Unit
public open fun foo(/*0*/ p0: kotlin.Int): kotlin.Unit
@@ -0,0 +1,11 @@
package test;
class Parent {
private static int private_ = 1;
static int packagePrivate_ = 2;
protected static int protected_ = 3;
public static int public_ = 4;
}
class Child extends Parent {
}
@@ -0,0 +1,21 @@
package test
public/*package*/ open class Child : test.Parent {
public/*package*/ constructor Child()
// Static members
public/*package*/ final override /*1*/ /*fake_override*/ var packagePrivate_: kotlin.Int
invisible_fake final override /*1*/ /*fake_override*/ var private_: kotlin.Int
protected/*protected static*/ final override /*1*/ /*fake_override*/ var protected_: kotlin.Int
public final override /*1*/ /*fake_override*/ var public_: kotlin.Int
}
public/*package*/ open class Parent {
public/*package*/ constructor Parent()
// Static members
public/*package*/ final var packagePrivate_: kotlin.Int
private final var private_: kotlin.Int
protected/*protected static*/ final var protected_: kotlin.Int
public final var public_: kotlin.Int
}
@@ -5,9 +5,9 @@ public/*package*/ open class Child : test.Parent1, test.Parent2 {
// Static members
public const final override /*1*/ /*fake_override*/ val a: kotlin.Int
public final override /*1*/ var b: kotlin.String
public final var b: kotlin.String!
public final var c: kotlin.Int
public final override /*1*/ var d: kotlin.String
public final var d: kotlin.String!
public const final override /*1*/ /*fake_override*/ val e: kotlin.Int
public open fun bar(): kotlin.Unit
public open fun baz(): kotlin.Unit
@@ -25,9 +25,9 @@ public/*package*/ final enum class StaticMembersInEnum : kotlin.Enum<test.Static
// Static members
public const final override /*1*/ /*fake_override*/ val a: kotlin.Int
public final override /*1*/ var b: kotlin.Int
public final var b: kotlin.Int
public final var c: kotlin.Int
public final override /*1*/ var d: kotlin.Int
public final var d: kotlin.Int
public const final override /*1*/ /*fake_override*/ val e: kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.ERROR, message = "Use 'values()' function instead", replaceWith = kotlin.ReplaceWith(expression = "this.values()", imports = {})) public final /*synthesized*/ val values: kotlin.Array<test.StaticMembersInEnum>
public open fun foo(): kotlin.Unit
@@ -5124,6 +5124,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("javaDeprecatedInheritance.kt")
public void testJavaDeprecatedInheritance() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/javaDeprecatedInheritance.kt");
doTest(fileName);
}
@TestMetadata("javaDocDeprecated.kt")
public void testJavaDocDeprecated() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/deprecated/javaDocDeprecated.kt");
@@ -10179,6 +10185,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("shadowingPrimitiveStaticField.kt")
public void testShadowingPrimitiveStaticField() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/shadowingPrimitiveStaticField.kt");
doTest(fileName);
}
@TestMetadata("Simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/j+k/Simple.kt");
@@ -1704,6 +1704,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTestCompiledJava(fileName);
}
@TestMetadata("StaticMembersFromParentClassVisibility.java")
public void testStaticMembersFromParentClassVisibility() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/static/StaticMembersFromParentClassVisibility.java");
doTestCompiledJava(fileName);
}
@TestMetadata("StaticMembersFromParentInterface.java")
public void testStaticMembersFromParentInterface() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/static/StaticMembersFromParentInterface.java");
@@ -4101,6 +4101,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
doTest(fileName);
}
@TestMetadata("StaticMembersFromParentClassVisibility.java")
public void testStaticMembersFromParentClassVisibility() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/static/StaticMembersFromParentClassVisibility.java");
doTest(fileName);
}
@TestMetadata("StaticMembersFromParentInterface.java")
public void testStaticMembersFromParentInterface() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/static/StaticMembersFromParentInterface.java");
@@ -38,12 +38,29 @@ public final class DescriptorResolverUtils {
}
@NotNull
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverrides(
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForNonStaticMembers(
@NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter
) {
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, false);
}
@NotNull
public static <D extends CallableMemberDescriptor> Collection<D> resolveOverridesForStaticMembers(
@NotNull Name name, @NotNull Collection<D> membersFromSupertypes, @NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor, @NotNull ErrorReporter errorReporter
) {
return resolveOverrides(name, membersFromSupertypes, membersFromCurrent, classDescriptor, errorReporter, true);
}
@NotNull
private static <D extends CallableMemberDescriptor> Collection<D> resolveOverrides(
@NotNull Name name,
@NotNull Collection<D> membersFromSupertypes,
@NotNull Collection<D> membersFromCurrent,
@NotNull ClassDescriptor classDescriptor,
@NotNull final ErrorReporter errorReporter
@NotNull final ErrorReporter errorReporter,
final boolean isStaticContext
) {
final Set<D> result = new LinkedHashSet<D>();
@@ -67,6 +84,17 @@ public final class DescriptorResolverUtils {
public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) {
// nop
}
@Override
public void setOverriddenDescriptors(
@NotNull CallableMemberDescriptor member, @NotNull Collection<? extends CallableMemberDescriptor> overridden
) {
// do not set overridden descriptors for declared static fields and methods from java
if (isStaticContext && member.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return;
}
super.setOverriddenDescriptors(member, overridden);
}
}
);
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName.isRemov
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName.sameAsRenamedInJvmBuiltin
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.sameAsBuiltinMethodWithErasedValueParameters
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties.getBuiltinSpecialPropertyGetterName
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils.resolveOverridesForNonStaticMembers
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaConstructorDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
@@ -225,7 +225,7 @@ class LazyJavaClassMemberScope(
var specialBuiltinsFromSuperTypes = SmartSet.create<SimpleFunctionDescriptor>()
// Merge functions with same signatures
val mergedFunctionFromSuperTypes = DescriptorResolverUtils.resolveOverrides(
val mergedFunctionFromSuperTypes = resolveOverridesForNonStaticMembers(
name, functionsFromSupertypes, emptyList(), ownerDescriptor, ErrorReporter.DO_NOTHING)
// add declarations
@@ -251,8 +251,9 @@ class LazyJavaClassMemberScope(
isSpecialBuiltinName: Boolean
) {
val additionalOverrides =
DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter)
val additionalOverrides = resolveOverridesForNonStaticMembers(
name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter
)
if (!isSpecialBuiltinName) {
result.addAll(additionalOverrides)
@@ -356,7 +357,7 @@ class LazyJavaClassMemberScope(
searchMethodsInSupertypesWithoutBuiltinMagic(it)
}
result.addAll(DescriptorResolverUtils.resolveOverrides(
result.addAll(resolveOverridesForNonStaticMembers(
name, propertiesFromSupertypes + propertiesOverridesFromSuperTypes, result, ownerDescriptor, c.components.errorReporter))
}
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils.resolveOverridesForStaticMembers
import org.jetbrains.kotlin.load.java.descriptors.getParentJavaStaticClassScope
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -76,7 +76,7 @@ class LazyJavaStaticClassScope(
}?.let { result.add(it) }
val functionsFromSupertypes = getStaticFunctionsFromJavaSuperClasses(name, ownerDescriptor)
result.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter))
result.addAll(resolveOverridesForStaticMembers(name, functionsFromSupertypes, result, ownerDescriptor, c.components.errorReporter))
if (jClass.isEnum) {
when (name) {
@@ -91,13 +91,13 @@ class LazyJavaStaticClassScope(
val actualProperties =
if (!result.isEmpty()) {
DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, ownerDescriptor, c.components.errorReporter)
resolveOverridesForStaticMembers(name, propertiesFromSupertypes, result, ownerDescriptor, c.components.errorReporter)
}
else {
propertiesFromSupertypes.groupBy {
it.realOriginal
}.flatMap {
DescriptorResolverUtils.resolveOverrides(name, it.value, result, ownerDescriptor, c.components.errorReporter)
resolveOverridesForStaticMembers(name, it.value, result, ownerDescriptor, c.components.errorReporter)
}
}
@@ -67,7 +67,7 @@ class FunctionClassScope(
/* membersFromSupertypes = */ descriptors,
/* membersFromCurrent = */ if (isFunction && name == invoke?.name) listOf(invoke) else listOf(),
functionClass,
object : OverridingStrategy {
object : OverridingStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)
result.add(fakeOverride)
@@ -18,8 +18,12 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
interface OverridingStrategy {
fun addFakeOverride(fakeOverride: CallableMemberDescriptor)
abstract class OverridingStrategy {
abstract fun addFakeOverride(fakeOverride: CallableMemberDescriptor)
fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor)
abstract fun conflict(fromSuper: CallableMemberDescriptor, fromCurrent: CallableMemberDescriptor)
open fun setOverriddenDescriptors(member: CallableMemberDescriptor, overridden: Collection<CallableMemberDescriptor>) {
member.overriddenDescriptors = overridden
}
}
@@ -317,7 +317,7 @@ public class OverridingUtil {
}
}
fromCurrent.setOverriddenDescriptors(overridden);
strategy.setOverriddenDescriptors(fromCurrent, overridden);
return bound;
}
@@ -501,7 +501,9 @@ public class OverridingUtil {
});
CallableMemberDescriptor fakeOverride =
mostSpecific.copy(current, modality, visibility, CallableMemberDescriptor.Kind.FAKE_OVERRIDE, false);
fakeOverride.setOverriddenDescriptors(effectiveOverridden);
strategy.setOverriddenDescriptors(fakeOverride, effectiveOverridden);
assert !fakeOverride.getOverriddenDescriptors().isEmpty()
: "Overridden descriptors should be set for " + CallableMemberDescriptor.Kind.FAKE_OVERRIDE;
strategy.addFakeOverride(fakeOverride);
}
@@ -220,7 +220,7 @@ class DeserializedClassDescriptor(
private fun <D : CallableMemberDescriptor> generateFakeOverrides(name: Name, fromSupertypes: Collection<D>, result: MutableCollection<D>) {
val fromCurrent = ArrayList<CallableMemberDescriptor>(result)
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : OverridingStrategy {
OverridingUtil.generateOverridesInFunctionGroup(name, fromSupertypes, fromCurrent, classDescriptor, object : OverridingStrategy() {
override fun addFakeOverride(fakeOverride: CallableMemberDescriptor) {
// TODO: report "cannot infer visibility"
OverridingUtil.resolveUnknownVisibilityForMember(fakeOverride, null)