diff --git a/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.kt b/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.kt new file mode 100644 index 00000000000..10680615c68 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.kt @@ -0,0 +1,3 @@ +import java.security.Provider + +class Example : Provider("A", 1.0, "B") diff --git a/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.txt b/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.txt new file mode 100644 index 00000000000..9db2d67d928 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.txt @@ -0,0 +1,114 @@ +package + +public final class Example : java.security.Provider { + public constructor Example() + invisible_fake final override /*1*/ /*fake_override*/ var count: kotlin.Int + protected/*protected and package*/ final override /*1*/ /*fake_override*/ var defaults: java.util.Properties! + public open override /*1*/ /*fake_override*/ val entries: kotlin.collections.MutableSet> + invisible_fake final override /*1*/ /*fake_override*/ var entrySet: kotlin.collections.(Mutable)Set!>! + invisible_fake final override /*1*/ /*fake_override*/ var entrySetCallCount: kotlin.Int + invisible_fake final override /*1*/ /*fake_override*/ var info: kotlin.String! + invisible_fake final override /*1*/ /*fake_override*/ var initialized: kotlin.Boolean + invisible_fake final override /*1*/ /*fake_override*/ var keySet: kotlin.collections.(Mutable)Set! + public open override /*1*/ /*fake_override*/ val keys: kotlin.collections.MutableSet + invisible_fake final override /*1*/ /*fake_override*/ var legacyChanged: kotlin.Boolean + invisible_fake final override /*1*/ /*fake_override*/ var legacyMap: kotlin.collections.(Mutable)Map! + invisible_fake final override /*1*/ /*fake_override*/ var legacyStrings: kotlin.collections.(Mutable)Map! + invisible_fake final override /*1*/ /*fake_override*/ var loadFactor: kotlin.Float + invisible_fake final override /*1*/ /*fake_override*/ var modCount: kotlin.Int + invisible_fake final override /*1*/ /*fake_override*/ var name: kotlin.String! + invisible_fake final override /*1*/ /*fake_override*/ var serviceMap: kotlin.collections.(Mutable)Map! + invisible_fake final override /*1*/ /*fake_override*/ var serviceSet: kotlin.collections.(Mutable)Set! + invisible_fake final override /*1*/ /*fake_override*/ var servicesChanged: kotlin.Boolean + public open override /*1*/ /*fake_override*/ val size: kotlin.Int + invisible_fake final override /*1*/ /*fake_override*/ var table: kotlin.Array<(out) java.util.Hashtable.Entry<*, *>!>! + invisible_fake final override /*1*/ /*fake_override*/ var threshold: kotlin.Int + invisible_fake final override /*1*/ /*fake_override*/ var values: kotlin.collections.(Mutable)Collection! + public open override /*1*/ /*fake_override*/ val values: kotlin.collections.MutableCollection + invisible_fake final override /*1*/ /*fake_override*/ var version: kotlin.Double + invisible_fake open override /*1*/ /*fake_override*/ fun addEntry(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Any!, /*2*/ p2: kotlin.Any!, /*3*/ p3: kotlin.Int): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun check(/*0*/ p0: kotlin.String!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun checkInitialized(): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun checkLegacy(/*0*/ p0: kotlin.Any!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public open override /*1*/ /*fake_override*/ fun compute(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.BiFunction): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun computeIfAbsent(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.Function): kotlin.Any! + public open override /*1*/ /*fake_override*/ fun computeIfPresent(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.BiFunction): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun contains(/*0*/ p0: kotlin.Any!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun containsKey(/*0*/ key: kotlin.Any!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun containsValue(/*0*/ value: kotlin.Any!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun elements(): java.util.Enumeration! + invisible_fake open override /*1*/ /*fake_override*/ fun ensureLegacyParsed(): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun enumerate(/*0*/ p0: java.util.Hashtable!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun enumerateStringProperties(/*0*/ p0: java.util.Hashtable!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun forEach(/*0*/ p0: java.util.function.BiConsumer): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun get(/*0*/ key: kotlin.Any!): kotlin.Any? + invisible_fake open override /*1*/ /*fake_override*/ fun getEnumeration(/*0*/ p0: kotlin.Int): java.util.Enumeration! + public open override /*1*/ /*fake_override*/ fun getInfo(): kotlin.String! + invisible_fake open override /*1*/ /*fake_override*/ fun getIterator(/*0*/ p0: kotlin.Int): kotlin.collections.(Mutable)Iterator! + public open override /*1*/ /*fake_override*/ fun getName(): kotlin.String! + public open override /*1*/ /*fake_override*/ fun getOrDefault(/*0*/ key: kotlin.Any!, /*1*/ defaultValue: kotlin.Any!): kotlin.Any! + public open override /*1*/ /*fake_override*/ fun getProperty(/*0*/ p0: kotlin.String!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun getProperty(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.String!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun getService(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.String!): java.security.Provider.Service! + public open override /*1*/ /*fake_override*/ fun getServices(): kotlin.collections.(Mutable)Set! + invisible_fake open override /*1*/ /*fake_override*/ fun getTypeAndAlgorithm(/*0*/ p0: kotlin.String!): kotlin.Array<(out) kotlin.String!>! + public open override /*1*/ /*fake_override*/ fun getVersion(): kotlin.Double + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + invisible_fake open override /*1*/ /*fake_override*/ fun implClear(): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun implCompute(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.BiFunction!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implComputeIfAbsent(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.Function!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implComputeIfPresent(/*0*/ p0: kotlin.Any!, /*1*/ p1: java.util.function.BiFunction!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implMerge(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!, /*2*/ p2: java.util.function.BiFunction!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implPut(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implPutAll(/*0*/ p0: kotlin.collections.(Mutable)Map<*, *>!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun implPutIfAbsent(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implRemove(/*0*/ p0: kotlin.Any!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implRemove(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Boolean + invisible_fake open override /*1*/ /*fake_override*/ fun implRemoveService(/*0*/ p0: java.security.Provider.Service!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun implReplace(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Any! + invisible_fake open override /*1*/ /*fake_override*/ fun implReplace(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!, /*2*/ p2: kotlin.Any!): kotlin.Boolean + invisible_fake open override /*1*/ /*fake_override*/ fun implReplaceAll(/*0*/ p0: java.util.function.BiFunction!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun keys(): java.util.Enumeration! + public open override /*1*/ /*fake_override*/ fun list(/*0*/ p0: java.io.PrintStream!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun list(/*0*/ p0: java.io.PrintWriter!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun load(/*0*/ p0: java.io.InputStream!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun load(/*0*/ p0: java.io.Reader!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun load0(/*0*/ p0: java.util.Properties.LineReader!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun loadConvert(/*0*/ p0: kotlin.CharArray!, /*1*/ p1: kotlin.Int, /*2*/ p2: kotlin.Int, /*3*/ p3: kotlin.CharArray!): kotlin.String! + public open override /*1*/ /*fake_override*/ fun loadFromXML(/*0*/ p0: java.io.InputStream!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun merge(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any, /*2*/ p2: java.util.function.BiFunction): kotlin.Any? + invisible_fake open override /*1*/ /*fake_override*/ fun parseLegacyPut(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun propertyNames(): java.util.Enumeration<*>! + public open override /*1*/ /*fake_override*/ fun put(/*0*/ key: kotlin.Any!, /*1*/ value: kotlin.Any!): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun putAll(/*0*/ from: kotlin.collections.Map<*, *>): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun putId(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun putIfAbsent(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Any? + invisible_fake open override /*1*/ /*fake_override*/ fun putPropertyStrings(/*0*/ p0: java.security.Provider.Service!): kotlin.Unit + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun putService(/*0*/ p0: java.security.Provider.Service!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun readObject(/*0*/ p0: java.io.ObjectInputStream!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun reconstitutionPut(/*0*/ p0: kotlin.Array<(out) java.util.Hashtable.Entry<*, *>!>!, /*1*/ p1: kotlin.Any!, /*2*/ p2: kotlin.Any!): kotlin.Unit + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun rehash(): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ key: kotlin.Any!): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun remove(/*0*/ key: kotlin.Any!, /*1*/ value: kotlin.Any!): kotlin.Boolean + invisible_fake open override /*1*/ /*fake_override*/ fun removeInvalidServices(/*0*/ p0: kotlin.collections.(Mutable)Map!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun removePropertyStrings(/*0*/ p0: java.security.Provider.Service!): kotlin.Unit + protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeService(/*0*/ p0: java.security.Provider.Service!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun replace(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Any? + public open override /*1*/ /*fake_override*/ fun replace(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!, /*2*/ p2: kotlin.Any!): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun replaceAll(/*0*/ p0: java.util.function.BiFunction): kotlin.Unit + @kotlin.Deprecated(message = "Deprecated in Java") public open override /*1*/ /*fake_override*/ fun save(/*0*/ p0: java.io.OutputStream!, /*1*/ p1: kotlin.String!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun saveConvert(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.Boolean, /*2*/ p2: kotlin.Boolean): kotlin.String! + public open override /*1*/ /*fake_override*/ fun setProperty(/*0*/ p0: kotlin.String!, /*1*/ p1: kotlin.String!): kotlin.Any! + public open override /*1*/ /*fake_override*/ fun store(/*0*/ p0: java.io.OutputStream!, /*1*/ p1: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun store(/*0*/ p0: java.io.Writer!, /*1*/ p1: kotlin.String!): kotlin.Unit + invisible_fake open override /*1*/ /*fake_override*/ fun store0(/*0*/ p0: java.io.BufferedWriter!, /*1*/ p1: kotlin.String!, /*2*/ p2: kotlin.Boolean): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun storeToXML(/*0*/ p0: java.io.OutputStream!, /*1*/ p1: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun storeToXML(/*0*/ p0: java.io.OutputStream!, /*1*/ p1: kotlin.String!, /*2*/ p2: kotlin.String!): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun stringPropertyNames(): kotlin.collections.(Mutable)Set! + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ p0: java.io.ObjectOutputStream!): kotlin.Unit +} diff --git a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java index 9a5b06ecc78..1870f24ba96 100644 --- a/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java +++ b/compiler/tests-java8/tests/org/jetbrains/kotlin/checkers/DiagnosticsWithJava8TestGenerated.java @@ -118,6 +118,12 @@ public class DiagnosticsWithJava8TestGenerated extends AbstractDiagnosticsWithFu String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/hashtableInheritance.kt"); doTest(fileName); } + + @TestMetadata("securityProvider.kt") + public void testSecurityProvider() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJava8/specialBuiltIns/securityProvider.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/diagnostics/testsWithJava8/statics") diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaIncompatibilityRulesOverridabilityCondition.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaIncompatibilityRulesOverridabilityCondition.kt index 37cc5377f61..0ec5afc493c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaIncompatibilityRulesOverridabilityCondition.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JavaIncompatibilityRulesOverridabilityCondition.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature. import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.kotlin.JvmType +import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor import org.jetbrains.kotlin.load.kotlin.forceSingleValueParameterBoxing import org.jetbrains.kotlin.load.kotlin.mapToJvmType import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition @@ -88,6 +89,22 @@ class JavaIncompatibilityRulesOverridabilityCondition : ExternalOverridabilityCo // because of final special bridge generated in Kotlin super class if (overriddenBuiltin == null || subClassDescriptor.hasRealKotlinSuperClassWithOverrideOf(overriddenBuiltin)) return false + // class A extends HashMap { + // void get(Object x) {} + // } + // + // The problem is that when checking overridabilty of `A.get` and `HashMap.get` we fall through to here, because + // we do not recreate a magic copy of it, because it has the same signature. + // But it obviously that if subDescriptor and superDescriptor has the same JVM descriptor, they're one-way overridable. + // Note that it doesn't work if special builtIn was renamed, because we do not consider renamed built-ins + // in `computeJvmDescriptor`. + // TODO: things get more and more complicated here, consider moving signature mapping from backend and using it here instead of all of this magic + if (overriddenBuiltin is FunctionDescriptor && superDescriptor is FunctionDescriptor && + BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(overriddenBuiltin) != null && + subDescriptor.computeJvmDescriptor(withReturnType = false) == superDescriptor.original.computeJvmDescriptor(withReturnType = false)) { + return false + } + // Here we know that something in Java with common signature is going to override some special builtin that is supposed to be // incompatible override return true