Load Java declarations which reference FunctionN as Deprecated.Error

#KT-25855 Fixed
This commit is contained in:
Denis Zharkov
2018-08-29 15:01:15 +03:00
parent bcf1b9c804
commit 24a905293f
16 changed files with 196 additions and 22 deletions
@@ -345,6 +345,7 @@ class DeprecationResolver(
result.add(deprecation) result.add(deprecation)
} }
getDeprecationByCoroutinesVersion(target)?.let(result::add) getDeprecationByCoroutinesVersion(target)?.let(result::add)
getDeprecationFromUserData(target)?.let(result::add)
} }
addDeprecationIfPresent(this) addDeprecationIfPresent(this)
@@ -376,6 +377,9 @@ class DeprecationResolver(
} }
} }
private fun getDeprecationFromUserData(target: DeclarationDescriptor): Deprecation? =
target.safeAs<CallableDescriptor>()?.getUserData(DEPRECATED_FUNCTION_KEY)
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> { private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
fun createVersion(version: String): MavenComparableVersion? = try { fun createVersion(version: String): MavenComparableVersion? = try {
MavenComparableVersion(version) MavenComparableVersion(version)
@@ -61,8 +61,11 @@ fun box(): String {
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
Unit> = { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ -> } Unit> = { _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _ -> }
@Suppress("DEPRECATION_ERROR")
J.test(lambda as kotlin.jvm.functions.FunctionN<Unit>) J.test(lambda as kotlin.jvm.functions.FunctionN<Unit>)
@Suppress("DEPRECATION_ERROR")
J.test(::foo as kotlin.jvm.functions.FunctionN<Unit>) J.test(::foo as kotlin.jvm.functions.FunctionN<Unit>)
@Suppress("DEPRECATION_ERROR")
J.test(Fun() as kotlin.jvm.functions.FunctionN<Unit>) J.test(Fun() as kotlin.jvm.functions.FunctionN<Unit>)
return "OK" return "OK"
} }
@@ -39,6 +39,7 @@ fun call(f: (A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A
} }
fun box(): String { fun box(): String {
@Suppress("DEPRECATION_ERROR")
val f = J.FIELD as Function30< val f = J.FIELD as Function30<
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
@@ -48,6 +49,7 @@ fun box(): String {
if (f is Function31<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) return "Fail field 31" if (f is Function31<*, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *, *>) return "Fail field 31"
if (call(f) != "OK") return "Fail field call" if (call(f) != "OK") return "Fail field call"
@Suppress("DEPRECATION_ERROR")
val m = J.getViaMethod() as Function30< val m = J.getViaMethod() as Function30<
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?,
@@ -50,7 +50,9 @@ fun Any.g(
): Any = Any() ): Any = Any()
fun box(): String { fun box(): String {
@Suppress("DEPRECATION_ERROR")
Test.test(::f as kotlin.jvm.functions.FunctionN<Any>) Test.test(::f as kotlin.jvm.functions.FunctionN<Any>)
@Suppress("DEPRECATION_ERROR")
Test.test(Any::g as kotlin.jvm.functions.FunctionN<Any>) Test.test(Any::g as kotlin.jvm.functions.FunctionN<Any>)
return "OK" return "OK"
} }
@@ -0,0 +1,58 @@
// !DIAGNOSTICS: -UNUSED_ANONYMOUS_PARAMETER
// FILE: KI.kt
interface KI {
fun manyParams(x: (String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String, String) -> Unit)
}
// FILE: A.java
import kotlin.jvm.functions.FunctionN;
public class A implements KI {
public FunctionN<?> field;
public A(FunctionN<?> w) {}
public void foo(FunctionN<String> x) {
}
public FunctionN<?> bar() {
return null;
}
public void baz(java.util.List<FunctionN<?>> z) {
}
public void manyParams(FunctionN<Unit> x) {
}
}
// FILE: main.kt
fun <T> any(): T = null!!
fun main() {
val a: A = <!DEPRECATION_ERROR!>A<!>(null)
a.<!DEPRECATION_ERROR!>field<!>.hashCode();
a.<!DEPRECATION_ERROR!>field<!> = null;
a.<!DEPRECATION_ERROR!>foo<!>(null)
a.<!DEPRECATION_ERROR!>bar<!>()
a.<!DEPRECATION_ERROR!>baz<!>(listOf())
a.<!DEPRECATION_ERROR!>manyParams<!>(null)
a.<!NONE_APPLICABLE!>manyParams<!>(any<kotlin.jvm.functions.FunctionN<Unit>>())
// Potentially, this would have better to forbid calling manyParams, too.
// But it might be complicated because we need to match that it is an override
// Seems to be fine because `A::manyParams` is anyway an override in JVM and can be called with (a as K)
a.manyParams {
x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x30, x31, x32 ->
}
}
@@ -0,0 +1,24 @@
package
public fun </*0*/ T> any(): T
public fun main(): kotlin.Unit
public open class A : KI {
public constructor A(/*0*/ w: kotlin.jvm.functions.FunctionN<*>!)
public final var field: kotlin.jvm.functions.FunctionN<*>!
public open fun bar(): kotlin.jvm.functions.FunctionN<*>!
public open fun baz(/*0*/ z: kotlin.collections.(Mutable)List<kotlin.jvm.functions.FunctionN<*>!>!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open fun foo(/*0*/ x: kotlin.jvm.functions.FunctionN<kotlin.String!>!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public abstract override /*1*/ /*fake_override*/ fun manyParams(/*0*/ x: (kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String) -> kotlin.Unit): kotlin.Unit
public open fun manyParams(/*0*/ x: kotlin.jvm.functions.FunctionN<Unit!>!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public interface KI {
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 abstract fun manyParams(/*0*/ x: (kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String, kotlin.String) -> kotlin.Unit): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -2617,6 +2617,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
} }
@TestMetadata("functionN.kt")
public void testFunctionN() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/java/functionN.kt");
}
@TestMetadata("patternCompileCallableReference.kt") @TestMetadata("patternCompileCallableReference.kt")
public void testPatternCompileCallableReference() throws Exception { public void testPatternCompileCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/java/patternCompileCallableReference.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/java/patternCompileCallableReference.kt");
@@ -2617,6 +2617,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/java"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
} }
@TestMetadata("functionN.kt")
public void testFunctionN() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/java/functionN.kt");
}
@TestMetadata("patternCompileCallableReference.kt") @TestMetadata("patternCompileCallableReference.kt")
public void testPatternCompileCallableReference() throws Exception { public void testPatternCompileCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/java/patternCompileCallableReference.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/java/patternCompileCallableReference.kt");
@@ -32,7 +32,7 @@ object JavaToKotlinClassMap : PlatformToKotlinClassMap {
FunctionClassDescriptor.Kind.KSuspendFunction.packageFqName.toString() + "." + FunctionClassDescriptor.Kind.KSuspendFunction.classNamePrefix FunctionClassDescriptor.Kind.KSuspendFunction.packageFqName.toString() + "." + FunctionClassDescriptor.Kind.KSuspendFunction.classNamePrefix
private val FUNCTION_N_CLASS_ID = ClassId.topLevel(FqName("kotlin.jvm.functions.FunctionN")) private val FUNCTION_N_CLASS_ID = ClassId.topLevel(FqName("kotlin.jvm.functions.FunctionN"))
private val FUNCTION_N_FQ_NAME = FUNCTION_N_CLASS_ID.asSingleFqName() val FUNCTION_N_FQ_NAME = FUNCTION_N_CLASS_ID.asSingleFqName()
private val K_FUNCTION_CLASS_ID = ClassId.topLevel(FqName("kotlin.reflect.KFunction")) private val K_FUNCTION_CLASS_ID = ClassId.topLevel(FqName("kotlin.reflect.KFunction"))
private val javaToKotlin = HashMap<FqNameUnsafe, ClassId>() private val javaToKotlin = HashMap<FqNameUnsafe, ClassId>()
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java.descriptors; package org.jetbrains.kotlin.load.java.descriptors;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
@@ -28,6 +29,7 @@ public interface JavaCallableMemberDescriptor extends CallableMemberDescriptor {
JavaCallableMemberDescriptor enhance( JavaCallableMemberDescriptor enhance(
@Nullable KotlinType enhancedReceiverType, @Nullable KotlinType enhancedReceiverType,
@NotNull List<ValueParameterData> enhancedValueParametersData, @NotNull List<ValueParameterData> enhancedValueParametersData,
@NotNull KotlinType enhancedReturnType @NotNull KotlinType enhancedReturnType,
@Nullable Pair<UserDataKey<?>, ?> additionalUserData
); );
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java.descriptors; package org.jetbrains.kotlin.load.java.descriptors;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
@@ -119,8 +120,10 @@ public class JavaClassConstructorDescriptor extends ClassConstructorDescriptorIm
public JavaClassConstructorDescriptor enhance( public JavaClassConstructorDescriptor enhance(
@Nullable KotlinType enhancedReceiverType, @Nullable KotlinType enhancedReceiverType,
@NotNull List<ValueParameterData> enhancedValueParametersData, @NotNull List<ValueParameterData> enhancedValueParametersData,
@NotNull KotlinType enhancedReturnType @NotNull KotlinType enhancedReturnType,
@Nullable Pair<UserDataKey<?>, ?> additionalUserData
) { ) {
JavaClassConstructorDescriptor enhanced = createSubstitutedCopy( JavaClassConstructorDescriptor enhanced = createSubstitutedCopy(
getContainingDeclaration(), /* original = */ null, getKind(), null, getAnnotations(), getSource()); getContainingDeclaration(), /* original = */ null, getKind(), null, getAnnotations(), getSource());
ReceiverParameterDescriptor enhancedReceiver = ReceiverParameterDescriptor enhancedReceiver =
@@ -138,6 +141,10 @@ public class JavaClassConstructorDescriptor extends ClassConstructorDescriptorIm
getVisibility() getVisibility()
); );
if (additionalUserData != null) {
enhanced.putInUserDataMap(additionalUserData.getFirst(), additionalUserData.getSecond());
}
return enhanced; return enhanced;
} }
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java.descriptors; package org.jetbrains.kotlin.load.java.descriptors;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
@@ -144,7 +145,8 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
public JavaMethodDescriptor enhance( public JavaMethodDescriptor enhance(
@Nullable KotlinType enhancedReceiverType, @Nullable KotlinType enhancedReceiverType,
@NotNull List<ValueParameterData> enhancedValueParametersData, @NotNull List<ValueParameterData> enhancedValueParametersData,
@NotNull KotlinType enhancedReturnType @NotNull KotlinType enhancedReturnType,
@Nullable Pair<UserDataKey<?>, ?> additionalUserData
) { ) {
List<ValueParameterDescriptor> enhancedValueParameters = List<ValueParameterDescriptor> enhancedValueParameters =
UtilKt.copyValueParameters(enhancedValueParametersData, getValueParameters(), this); UtilKt.copyValueParameters(enhancedValueParametersData, getValueParameters(), this);
@@ -164,6 +166,11 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
.build(); .build();
assert enhancedMethod != null : "null after substitution while enhancing " + toString(); assert enhancedMethod != null : "null after substitution while enhancing " + toString();
if (additionalUserData != null) {
enhancedMethod.putInUserDataMap(additionalUserData.getFirst(), additionalUserData.getSecond());
}
return enhancedMethod; return enhancedMethod;
} }
} }
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.load.java.descriptors; package org.jetbrains.kotlin.load.java.descriptors;
import kotlin.Pair;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
@@ -33,6 +34,8 @@ import java.util.List;
public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor { public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements JavaCallableMemberDescriptor {
private final boolean isStaticFinal; private final boolean isStaticFinal;
@Nullable
private final Pair<UserDataKey<?>, ?> singleUserData;
private JavaPropertyDescriptor( private JavaPropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration, @NotNull DeclarationDescriptor containingDeclaration,
@@ -44,12 +47,14 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
@NotNull SourceElement source, @NotNull SourceElement source,
@Nullable PropertyDescriptor original, @Nullable PropertyDescriptor original,
@NotNull Kind kind, @NotNull Kind kind,
boolean isStaticFinal boolean isStaticFinal,
@Nullable Pair<UserDataKey<?>, ?> singleUserData
) { ) {
super(containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source, super(containingDeclaration, original, annotations, modality, visibility, isVar, name, kind, source,
false, false, false, false, false, false); false, false, false, false, false, false);
this.isStaticFinal = isStaticFinal; this.isStaticFinal = isStaticFinal;
this.singleUserData = singleUserData;
} }
@NotNull @NotNull
@@ -64,8 +69,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
boolean isStaticFinal boolean isStaticFinal
) { ) {
return new JavaPropertyDescriptor( return new JavaPropertyDescriptor(
containingDeclaration, annotations, modality, visibility, isVar, name, source, null, Kind.DECLARATION, isStaticFinal containingDeclaration, annotations, modality, visibility, isVar, name, source, null, Kind.DECLARATION, isStaticFinal,
); null);
} }
@NotNull @NotNull
@@ -80,8 +85,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
) { ) {
return new JavaPropertyDescriptor( return new JavaPropertyDescriptor(
newOwner, getAnnotations(), newModality, newVisibility, isVar(), newName, SourceElement.NO_SOURCE, original, newOwner, getAnnotations(), newModality, newVisibility, isVar(), newName, SourceElement.NO_SOURCE, original,
kind, isStaticFinal kind, isStaticFinal,
); singleUserData);
} }
@Override @Override
@@ -94,7 +99,8 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
public JavaCallableMemberDescriptor enhance( public JavaCallableMemberDescriptor enhance(
@Nullable KotlinType enhancedReceiverType, @Nullable KotlinType enhancedReceiverType,
@NotNull List<ValueParameterData> enhancedValueParametersData, @NotNull List<ValueParameterData> enhancedValueParametersData,
@NotNull KotlinType enhancedReturnType @NotNull KotlinType enhancedReturnType,
@Nullable Pair<UserDataKey<?>, ?> additionalUserData
) { ) {
JavaPropertyDescriptor enhanced = new JavaPropertyDescriptor( JavaPropertyDescriptor enhanced = new JavaPropertyDescriptor(
getContainingDeclaration(), getContainingDeclaration(),
@@ -104,10 +110,10 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
isVar(), isVar(),
getName(), getName(),
getSource(), getSource(),
getOriginal(), getOriginal() == this ? null : getOriginal(),
getKind(), getKind(),
isStaticFinal isStaticFinal,
); additionalUserData);
PropertyGetterDescriptorImpl newGetter = null; PropertyGetterDescriptorImpl newGetter = null;
PropertyGetterDescriptorImpl getter = getGetter(); PropertyGetterDescriptorImpl getter = getGetter();
@@ -159,4 +165,15 @@ public class JavaPropertyDescriptor extends PropertyDescriptorImpl implements Ja
return isStaticFinal && ConstUtil.canBeUsedForConstVal(type) && return isStaticFinal && ConstUtil.canBeUsedForConstVal(type) &&
(!TypeEnhancementKt.hasEnhancedNullability(type) || KotlinBuiltIns.isString(type)); (!TypeEnhancementKt.hasEnhancedNullability(type) || KotlinBuiltIns.isString(type));
} }
@Nullable
@Override
public <V> V getUserData(UserDataKey<V> key) {
if (singleUserData != null && singleUserData.getFirst().equals(key)) {
//noinspection unchecked
return (V) singleUserData.getSecond();
}
return null;
}
} }
@@ -30,8 +30,10 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.DEPRECATED_FUNCTION_KEY
import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument import org.jetbrains.kotlin.resolve.descriptorUtil.firstArgument
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
@@ -160,7 +162,7 @@ class SignatureEnhancement(
val hasDefaultValue = p.hasDefaultValueInAnnotation(actualType) val hasDefaultValue = p.hasDefaultValueInAnnotation(actualType)
val wereChanges = enhancementResult.wereChanges || (hasDefaultValue != p.declaresDefaultValue()) val wereChanges = enhancementResult.wereChanges || (hasDefaultValue != p.declaresDefaultValue())
ValueParameterEnhancementResult(enhancementResult.type, hasDefaultValue, wereChanges) ValueParameterEnhancementResult(enhancementResult.type, hasDefaultValue, wereChanges, enhancementResult.containsFunctionN)
} }
val returnTypeEnhancement = val returnTypeEnhancement =
@@ -174,14 +176,24 @@ class SignatureEnhancement(
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo) ) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
val containsFunctionN = receiverTypeEnhancement?.containsFunctionN == true || returnTypeEnhancement.containsFunctionN ||
valueParameterEnhancements.any { it.containsFunctionN }
if ((receiverTypeEnhancement?.wereChanges == true) if ((receiverTypeEnhancement?.wereChanges == true)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges } || returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges } || containsFunctionN
) { ) {
val additionalUserData =
if (containsFunctionN)
DEPRECATED_FUNCTION_KEY to DeprecationCausedByFunctionN(this)
else
null
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return this.enhance( return this.enhance(
receiverTypeEnhancement?.type, receiverTypeEnhancement?.type,
valueParameterEnhancements.map { ValueParameterData(it.type, it.hasDefaultValue) }, valueParameterEnhancements.map { ValueParameterData(it.type, it.hasDefaultValue) },
returnTypeEnhancement.type returnTypeEnhancement.type,
additionalUserData
) as D ) as D
} }
@@ -218,9 +230,16 @@ class SignatureEnhancement(
} }
} }
val containsFunctionN = TypeUtils.contains(fromOverride) {
val classifier = it.constructor.declarationDescriptor ?: return@contains false
classifier.name == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME.shortName() &&
classifier.fqNameOrNull() == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME
}
return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let { enhanced -> return fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let { enhanced ->
PartEnhancementResult(enhanced, wereChanges = true) PartEnhancementResult(enhanced, wereChanges = true, containsFunctionN = containsFunctionN)
} ?: PartEnhancementResult(fromOverride, wereChanges = false) } ?: PartEnhancementResult(fromOverride, wereChanges = false, containsFunctionN = containsFunctionN)
} }
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers { private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
@@ -397,12 +416,18 @@ class SignatureEnhancement(
} }
private open class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean) private open class PartEnhancementResult(
val type: KotlinType,
val wereChanges: Boolean,
val containsFunctionN: Boolean
)
private class ValueParameterEnhancementResult( private class ValueParameterEnhancementResult(
type: KotlinType, type: KotlinType,
val hasDefaultValue: Boolean, val hasDefaultValue: Boolean,
wereChanges: Boolean wereChanges: Boolean,
) : PartEnhancementResult(type, wereChanges) containsFunctionN: Boolean
) : PartEnhancementResult(type, wereChanges, containsFunctionN)
private fun CallableMemberDescriptor.partsForValueParameter( private fun CallableMemberDescriptor.partsForValueParameter(
// TODO: investigate if it's really can be a null (check properties' with extension overrides in Java) // TODO: investigate if it's really can be a null (check properties' with extension overrides in Java)
@@ -17,10 +17,14 @@
package org.jetbrains.kotlin.load.java package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.Deprecation
import org.jetbrains.kotlin.resolve.DeprecationLevelValue
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.utils.extractRadix import org.jetbrains.kotlin.utils.extractRadix
@@ -60,4 +64,11 @@ fun KotlinType.lexicalCastFrom(value: String): JavaDefaultValue? {
} }
return if (result != null) Constant(result) else null return if (result != null) Constant(result) else null
} }
class DeprecationCausedByFunctionN(override val target: DeclarationDescriptor) : Deprecation {
override val deprecationLevel: DeprecationLevelValue
get() = DeprecationLevelValue.ERROR
override val message: String?
get() = "Java members containing references to ${JavaToKotlinClassMap.FUNCTION_N_FQ_NAME} are not supported"
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
interface Deprecation { interface Deprecation {
@@ -18,3 +19,4 @@ enum class DeprecationLevelValue {
WARNING, ERROR, HIDDEN WARNING, ERROR, HIDDEN
} }
val DEPRECATED_FUNCTION_KEY = object : CallableDescriptor.UserDataKey<Deprecation> {}