Support overrides of generic methods with erased version in Java
This commit is contained in:
+1
-1
@@ -24,7 +24,7 @@ public abstract class A : B {
|
||||
public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.MutableListIterator<kotlin.Int!>
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun outOfBoundsMsg(/*0*/ p0: kotlin.Int): kotlin.String!
|
||||
invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheckForAdd(/*0*/ p0: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ fun remove(/*0*/ x: kotlin.Int): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ element: kotlin.Int): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ elements: kotlin.Collection<kotlin.Int!>): kotlin.Boolean
|
||||
public open override /*1*/ fun removeAt(/*0*/ x: kotlin.Int): kotlin.Int
|
||||
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ public open class SubBug : Bug {
|
||||
public constructor SubBug()
|
||||
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 fun save(): SubBug!
|
||||
public open override /*1*/ fun save(): SubBug!
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// FILE: A.java
|
||||
import java.util.*;
|
||||
public interface A<T> {
|
||||
<E extends CharSequence> E foo(T x, List<? extends T> y);
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import java.util.*;
|
||||
public interface B extends A {
|
||||
@Override
|
||||
public String foo(Object x, List y);
|
||||
}
|
||||
|
||||
// FILE: C.java
|
||||
import java.util.*;
|
||||
public abstract class C {
|
||||
<E extends CharSequence, F extends E> E bar(F x, List<Map<E, F>> y);
|
||||
}
|
||||
|
||||
// FILE: D.java
|
||||
import java.util.*;
|
||||
public class D extends C {
|
||||
@Override
|
||||
public String bar(CharSequence x, List y) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
class E : D(), B {
|
||||
override fun foo(x: Any, y: List<Any?>): String = ""
|
||||
override fun bar(x: CharSequence?, y: List<*>?): String = ""
|
||||
}
|
||||
|
||||
<!ABSTRACT_MEMBER_NOT_IMPLEMENTED!>class E2<!> : B {
|
||||
<!NOTHING_TO_OVERRIDE!>override<!> fun foo(x: Any, y: List<String?>): String = ""
|
||||
}
|
||||
|
||||
|
||||
class F : D()
|
||||
@@ -0,0 +1,57 @@
|
||||
package
|
||||
|
||||
public interface A</*0*/ T : kotlin.Any!> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public abstract fun </*0*/ E : kotlin.CharSequence!> foo(/*0*/ x: T!, /*1*/ y: (kotlin.MutableList<out T!>..kotlin.List<T!>?)): E!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface B : A<kotlin.Any!> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw)
|
||||
@java.lang.Override() public abstract override /*1*/ fun foo(/*0*/ x: kotlin.Any!, /*1*/ y: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw)
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw)
|
||||
}
|
||||
|
||||
public abstract class C {
|
||||
public constructor C()
|
||||
public/*package*/ open fun </*0*/ E : kotlin.CharSequence!, /*1*/ F : E!> bar(/*0*/ x: F!, /*1*/ y: kotlin.(Mutable)List<kotlin.(Mutable)Map<E!, F!>!>!): E!
|
||||
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
|
||||
}
|
||||
|
||||
public open class D : C {
|
||||
public constructor D()
|
||||
@java.lang.Override() public open override /*1*/ fun bar(/*0*/ x: kotlin.CharSequence!, /*1*/ y: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
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
|
||||
}
|
||||
|
||||
public final class E : D, B {
|
||||
public constructor E()
|
||||
public open override /*1*/ fun bar(/*0*/ x: kotlin.CharSequence?, /*1*/ y: kotlin.List<*>?): kotlin.String
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw)
|
||||
public open override /*1*/ fun foo(/*0*/ x: kotlin.Any, /*1*/ y: kotlin.List<kotlin.Any?>): kotlin.String
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw)
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String(raw)
|
||||
}
|
||||
|
||||
public final class E2 : B {
|
||||
public constructor E2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any(raw)?): kotlin.Boolean(raw)
|
||||
public open fun foo(/*0*/ x: kotlin.Any, /*1*/ y: kotlin.List<kotlin.String?>): kotlin.String
|
||||
@java.lang.Override() public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ x: kotlin.Any!, /*1*/ y: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int(raw)
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String(raw)
|
||||
}
|
||||
|
||||
public final class F : D {
|
||||
public constructor F()
|
||||
@java.lang.Override() public open override /*1*/ /*fake_override*/ fun bar(/*0*/ x: kotlin.CharSequence!, /*1*/ y: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package test;
|
||||
import java.util.*;
|
||||
|
||||
public class RawOverrides {
|
||||
public interface A<T> {
|
||||
<E extends CharSequence> E foo(T x, List<? extends T> y);
|
||||
}
|
||||
|
||||
public class B implements A {
|
||||
@Override
|
||||
public String foo(Object x, List y) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class C {
|
||||
<E extends CharSequence, F extends E> E bar(F x, List<Map<E, F>> y) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class D extends C {
|
||||
@Override
|
||||
public String bar(CharSequence x, List y) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package test
|
||||
|
||||
public open class RawOverrides {
|
||||
public constructor RawOverrides()
|
||||
|
||||
public interface A</*0*/ T : kotlin.Any!> {
|
||||
public abstract fun </*0*/ E : kotlin.CharSequence!> foo(/*0*/ p0: T!, /*1*/ p1: (kotlin.MutableList<out T!>..kotlin.List<T!>?)): E!
|
||||
}
|
||||
|
||||
public open inner class B : test.RawOverrides.A<kotlin.Any!> {
|
||||
public constructor B()
|
||||
public open override /*1*/ fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
}
|
||||
|
||||
public open inner class C {
|
||||
public constructor C()
|
||||
public/*package*/ open fun </*0*/ E : kotlin.CharSequence!, /*1*/ F : E!> bar(/*0*/ p0: F!, /*1*/ p1: kotlin.(Mutable)List<kotlin.(Mutable)Map<E!, F!>!>!): E!
|
||||
}
|
||||
|
||||
public open inner class D : test.RawOverrides.C {
|
||||
public constructor D()
|
||||
public open override /*1*/ fun bar(/*0*/ p0: kotlin.CharSequence!, /*1*/ p1: kotlin.(Mutable)List<(raw) kotlin.Any?>!): kotlin.String!
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -4,8 +4,7 @@ public interface OverrideWithErasedParameter {
|
||||
|
||||
public interface Sub</*0*/ T : kotlin.Any!> : test.OverrideWithErasedParameter.Super<T!> {
|
||||
public abstract override /*1*/ /*fake_override*/ fun dummy(): kotlin.Unit
|
||||
public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: T!): kotlin.Unit
|
||||
public abstract fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit
|
||||
public abstract override /*1*/ fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit
|
||||
}
|
||||
|
||||
public interface Super</*0*/ T : kotlin.Any!> {
|
||||
|
||||
+1
-3
@@ -7,8 +7,7 @@ public/*package*/ open class NoSamForTypeParameter {
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived1 : test.NoSamForTypeParameter {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived1()
|
||||
public/*package*/ open override /*1*/ /*fake_override*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
public/*package*/ open fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived2 : test.NoSamForTypeParameter {
|
||||
@@ -18,6 +17,5 @@ public/*package*/ open class NoSamForTypeParameterDerived2 : test.NoSamForTypePa
|
||||
|
||||
public/*package*/ open class NoSamForTypeParameterDerived3 : test.NoSamForTypeParameterDerived1 {
|
||||
public/*package*/ constructor NoSamForTypeParameterDerived3()
|
||||
public/*package*/ open override /*1*/ /*fake_override*/ fun </*0*/ K : java.lang.Runnable!> foo(/*0*/ p0: K!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
public/*package*/ open override /*1*/ fun foo(/*0*/ p0: java.lang.Runnable!, /*1*/ p1: java.lang.Runnable!): kotlin.Unit
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,6 +8,6 @@ public interface MethodTypeParameterErased {
|
||||
|
||||
public open class SubBug : test.MethodTypeParameterErased.Bug<kotlin.Any!> {
|
||||
public constructor SubBug()
|
||||
public open fun save(): test.MethodTypeParameterErased.SubBug!
|
||||
public open override /*1*/ fun save(): test.MethodTypeParameterErased.SubBug!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11442,6 +11442,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("rawOverrides.kt")
|
||||
public void testRawOverrides() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/rawOverrides.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("safeCall.kt")
|
||||
public void testSafeCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/safeCall.kt");
|
||||
|
||||
@@ -229,6 +229,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RawOverrides.java")
|
||||
public void testRawOverrides() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/RawOverrides.java");
|
||||
doTestCompiledJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RawTypeWithUpperBound.java")
|
||||
public void testRawTypeWithUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java");
|
||||
|
||||
+6
@@ -3289,6 +3289,12 @@ public class JvmRuntimeDescriptorLoaderTestGenerated extends AbstractJvmRuntimeD
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RawOverrides.java")
|
||||
public void testRawOverrides() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/RawOverrides.java");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("RawTypeWithUpperBound.java")
|
||||
public void testRawTypeWithUpperBound() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJava/RawTypeWithUpperBound.java");
|
||||
|
||||
+2
-1
@@ -1 +1,2 @@
|
||||
org.jetbrains.kotlin.load.java.FieldOverridabilityCondition
|
||||
org.jetbrains.kotlin.load.java.FieldOverridabilityCondition
|
||||
org.jetbrains.kotlin.load.java.ErasedOverridabilityCondition
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.load.java
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.RawSubstitution
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
|
||||
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition.Result
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
|
||||
class ErasedOverridabilityCondition : ExternalOverridabilityCondition {
|
||||
override fun isOverridable(superDescriptor: CallableDescriptor, subDescriptor: CallableDescriptor): Result {
|
||||
if (subDescriptor !is JavaMethodDescriptor) return Result.UNKNOWN
|
||||
|
||||
var erasedSuper = superDescriptor.substitute(RawSubstitution.buildSubstitutor()) ?: return Result.UNKNOWN
|
||||
|
||||
if (erasedSuper is SimpleFunctionDescriptor && erasedSuper.typeParameters.isNotEmpty()) {
|
||||
// Only simple functions are supported now for erased overrides
|
||||
erasedSuper = erasedSuper.createCopyWithNewTypeParameters(emptyList())
|
||||
}
|
||||
|
||||
val overridabilityResult =
|
||||
OverridingUtil.DEFAULT.isOverridableByWithoutExternalConditions(erasedSuper, subDescriptor, false).result
|
||||
return when (overridabilityResult) {
|
||||
OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE -> Result.OVERRIDABLE
|
||||
else -> Result.UNKNOWN
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,9 @@ public interface SimpleFunctionDescriptor extends FunctionDescriptor {
|
||||
@NotNull
|
||||
SimpleFunctionDescriptor createCopyWithNewValueParameters(@NotNull List<ValueParameterDescriptor> valueParameters);
|
||||
|
||||
@NotNull
|
||||
SimpleFunctionDescriptor createCopyWithNewTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
SimpleFunctionDescriptor getOriginal();
|
||||
|
||||
+16
-5
@@ -283,6 +283,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
protected @Nullable Name name;
|
||||
protected boolean copyOverrides;
|
||||
protected boolean signatureChange;
|
||||
private List<TypeParameterDescriptor> newTypeParameters = null;
|
||||
|
||||
public CopyConfiguration(
|
||||
@NotNull TypeSubstitutor originalSubstitutor,
|
||||
@@ -412,11 +413,21 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
configuration.newOwner, configuration.original, configuration.kind, configuration.name,
|
||||
/* preserveSource = */ configuration.signatureChange);
|
||||
|
||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
|
||||
);
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters;
|
||||
TypeSubstitutor substitutor;
|
||||
|
||||
if (configuration.newTypeParameters == null) {
|
||||
List<TypeParameterDescriptor> originalTypeParameters = getTypeParameters();
|
||||
substitutedTypeParameters = new ArrayList<TypeParameterDescriptor>(originalTypeParameters.size());
|
||||
substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
originalTypeParameters, configuration.originalSubstitutor.getSubstitution(), substitutedDescriptor, substitutedTypeParameters
|
||||
);
|
||||
}
|
||||
else {
|
||||
// They should be already substituted
|
||||
substitutedTypeParameters = configuration.newTypeParameters;
|
||||
substitutor = configuration.originalSubstitutor;
|
||||
}
|
||||
|
||||
KotlinType substitutedReceiverParameterType = null;
|
||||
if (configuration.newExtensionReceiverParameterType != null) {
|
||||
|
||||
+7
@@ -122,4 +122,11 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
|
||||
//noinspection ConstantConditions
|
||||
return (SimpleFunctionDescriptor) newCopyBuilder().setValueParameters(valueParameters).setSignatureChange().build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SimpleFunctionDescriptor createCopyWithNewTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters) {
|
||||
//noinspection ConstantConditions
|
||||
return (SimpleFunctionDescriptor) newCopyBuilder().setTypeParameters(typeParameters).build();
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -67,6 +67,12 @@ public class ErrorSimpleFunctionDescriptorImpl extends SimpleFunctionDescriptorI
|
||||
return this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SimpleFunctionDescriptor createCopyWithNewTypeParameters(@NotNull List<TypeParameterDescriptor> typeParameters) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOverriddenDescriptor(@NotNull CallableMemberDescriptor overriddenFunction) {
|
||||
// nop
|
||||
|
||||
Reference in New Issue
Block a user