FE: separate type enhancement and FunctionN@Java warnings
This commit is contained in:
+28
-53
@@ -103,7 +103,6 @@ class SignatureEnhancement(
|
|||||||
) { it.extensionReceiverParameter!!.type }.enhance()
|
) { it.extensionReceiverParameter!!.type }.enhance()
|
||||||
else null
|
else null
|
||||||
|
|
||||||
|
|
||||||
val predefinedEnhancementInfo =
|
val predefinedEnhancementInfo =
|
||||||
(this as? JavaMethodDescriptor)
|
(this as? JavaMethodDescriptor)
|
||||||
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
|
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
|
||||||
@@ -132,23 +131,24 @@ class SignatureEnhancement(
|
|||||||
AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE
|
AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE
|
||||||
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
|
||||||
|
|
||||||
val containsFunctionN = receiverTypeEnhancement?.containsFunctionN == true || returnTypeEnhancement.containsFunctionN ||
|
val containsFunctionN = returnType!!.containsFunctionN() ||
|
||||||
valueParameterEnhancements.any { it.containsFunctionN }
|
extensionReceiverParameter?.type?.containsFunctionN() ?: false ||
|
||||||
|
valueParameters.any { it.type.containsFunctionN() }
|
||||||
|
val additionalUserData = if (containsFunctionN)
|
||||||
|
DEPRECATED_FUNCTION_KEY to DeprecationCausedByFunctionNInfo(this)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
if ((receiverTypeEnhancement?.wereChanges == true)
|
if (receiverTypeEnhancement != null || returnTypeEnhancement != null || valueParameterEnhancements.any { it != null } ||
|
||||||
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges } || containsFunctionN
|
additionalUserData != null
|
||||||
) {
|
) {
|
||||||
val additionalUserData =
|
|
||||||
if (containsFunctionN)
|
|
||||||
DEPRECATED_FUNCTION_KEY to DeprecationCausedByFunctionNInfo(this)
|
|
||||||
else
|
|
||||||
null
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return this.enhance(
|
return this.enhance(
|
||||||
receiverTypeEnhancement?.type,
|
receiverTypeEnhancement ?: extensionReceiverParameter?.type,
|
||||||
valueParameterEnhancements.map { ValueParameterData(it.type, false) },
|
valueParameterEnhancements.mapIndexed { index, enhanced ->
|
||||||
returnTypeEnhancement.type,
|
ValueParameterData(enhanced ?: valueParameters[index].type, false)
|
||||||
|
},
|
||||||
|
returnTypeEnhancement ?: returnType!!,
|
||||||
additionalUserData
|
additionalUserData
|
||||||
) as D
|
) as D
|
||||||
}
|
}
|
||||||
@@ -169,7 +169,7 @@ class SignatureEnhancement(
|
|||||||
typeParameter, bound, emptyList(), false, context,
|
typeParameter, bound, emptyList(), false, context,
|
||||||
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS,
|
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS,
|
||||||
typeParameterBounds = true
|
typeParameterBounds = true
|
||||||
).enhance().type
|
).enhance() ?: bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,7 +181,14 @@ class SignatureEnhancement(
|
|||||||
SignatureParts(
|
SignatureParts(
|
||||||
typeContainer = null, type, emptyList(), isCovariant = false,
|
typeContainer = null, type, emptyList(), isCovariant = false,
|
||||||
context, AnnotationQualifierApplicabilityType.TYPE_USE, isSuperTypesEnhancement = true
|
context, AnnotationQualifierApplicabilityType.TYPE_USE, isSuperTypesEnhancement = true
|
||||||
).enhance().type
|
).enhance() ?: type
|
||||||
|
|
||||||
|
private fun KotlinType.containsFunctionN(): Boolean =
|
||||||
|
TypeUtils.contains(this) {
|
||||||
|
val classifier = it.constructor.declarationDescriptor ?: return@contains false
|
||||||
|
classifier.name == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME.shortName() &&
|
||||||
|
classifier.fqNameOrNull() == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME
|
||||||
|
}
|
||||||
|
|
||||||
private inner class SignatureParts(
|
private inner class SignatureParts(
|
||||||
private val typeContainer: Annotated?,
|
private val typeContainer: Annotated?,
|
||||||
@@ -196,35 +203,11 @@ class SignatureEnhancement(
|
|||||||
|
|
||||||
private val isForVarargParameter get() = typeContainer.safeAs<ValueParameterDescriptor>()?.varargElementType != null
|
private val isForVarargParameter get() = typeContainer.safeAs<ValueParameterDescriptor>()?.varargElementType != null
|
||||||
|
|
||||||
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
|
fun enhance(predefined: TypeEnhancementInfo? = null): KotlinType? =
|
||||||
val qualifiers = computeIndexedQualifiersForOverride()
|
with(typeEnhancement) {
|
||||||
|
fromOverride.enhance(computeIndexedQualifiersForOverride(predefined), isSuperTypesEnhancement)
|
||||||
val qualifiersWithPredefined: ((Int) -> JavaTypeQualifiers)? = predefined?.let {
|
|
||||||
{ index ->
|
|
||||||
predefined.map[index] ?: qualifiers(index)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun containsFunctionN(type: UnwrappedType): Boolean {
|
|
||||||
val classifier = type.constructor.declarationDescriptor ?: return false
|
|
||||||
|
|
||||||
return classifier.name == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME.shortName() &&
|
|
||||||
classifier.fqNameOrNull() == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
val containsFunctionN = if (isSuperTypesEnhancement) {
|
|
||||||
TypeUtils.containsStoppingAt(fromOverride, ::containsFunctionN) { it is RawType }
|
|
||||||
} else {
|
|
||||||
TypeUtils.contains(fromOverride, ::containsFunctionN)
|
|
||||||
}
|
|
||||||
|
|
||||||
return with(typeEnhancement) {
|
|
||||||
fromOverride.enhance(qualifiersWithPredefined ?: qualifiers, isSuperTypesEnhancement)?.let { enhanced ->
|
|
||||||
PartEnhancementResult(enhanced, wereChanges = true, containsFunctionN = containsFunctionN)
|
|
||||||
} ?: PartEnhancementResult(fromOverride, wereChanges = false, containsFunctionN = containsFunctionN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
||||||
val (lower, upper) =
|
val (lower, upper) =
|
||||||
if (this.isFlexible())
|
if (this.isFlexible())
|
||||||
@@ -414,8 +397,7 @@ class SignatureEnhancement(
|
|||||||
): NullabilityQualifierWithMigrationStatus? =
|
): NullabilityQualifierWithMigrationStatus? =
|
||||||
this.firstNotNullOfOrNull { extractNullability(it, areImprovementsEnabled, typeParameterBounds) }
|
this.firstNotNullOfOrNull { extractNullability(it, areImprovementsEnabled, typeParameterBounds) }
|
||||||
|
|
||||||
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
|
private fun computeIndexedQualifiersForOverride(predefined: TypeEnhancementInfo?): (Int) -> JavaTypeQualifiers {
|
||||||
|
|
||||||
val indexedFromSupertypes = fromOverridden.map { it.toIndexed() }
|
val indexedFromSupertypes = fromOverridden.map { it.toIndexed() }
|
||||||
val indexedThisType = fromOverride.toIndexed()
|
val indexedThisType = fromOverride.toIndexed()
|
||||||
|
|
||||||
@@ -431,8 +413,7 @@ class SignatureEnhancement(
|
|||||||
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type }
|
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type }
|
||||||
indexedThisType[index].computeQualifiersForOverride(verticalSlice)
|
indexedThisType[index].computeQualifiersForOverride(verticalSlice)
|
||||||
}
|
}
|
||||||
|
return { index -> predefined?.map?.get(index) ?: computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
|
||||||
return { index -> computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -504,12 +485,6 @@ class SignatureEnhancement(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private open class PartEnhancementResult(
|
|
||||||
val type: KotlinType,
|
|
||||||
val wereChanges: Boolean,
|
|
||||||
val containsFunctionN: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
||||||
parameterDescriptor: ValueParameterDescriptor?,
|
parameterDescriptor: ValueParameterDescriptor?,
|
||||||
|
|||||||
@@ -424,21 +424,12 @@ public class TypeUtils {
|
|||||||
@Nullable KotlinType type,
|
@Nullable KotlinType type,
|
||||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType
|
@NotNull Function1<UnwrappedType, Boolean> isSpecialType
|
||||||
) {
|
) {
|
||||||
return contains(type, isSpecialType, null, null);
|
return contains(type, isSpecialType, null);
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean containsStoppingAt(
|
|
||||||
@Nullable KotlinType type,
|
|
||||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
|
|
||||||
@NotNull Function1<KotlinType, Boolean> shouldStopAt
|
|
||||||
) {
|
|
||||||
return contains(type, isSpecialType, shouldStopAt, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean contains(
|
private static boolean contains(
|
||||||
@Nullable KotlinType type,
|
@Nullable KotlinType type,
|
||||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
|
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
|
||||||
@Nullable Function1<KotlinType, Boolean> shouldStopAt,
|
|
||||||
SmartSet<KotlinType> visited
|
SmartSet<KotlinType> visited
|
||||||
) {
|
) {
|
||||||
if (type == null) return false;
|
if (type == null) return false;
|
||||||
@@ -448,7 +439,6 @@ public class TypeUtils {
|
|||||||
if (noExpectedType(type)) return isSpecialType.invoke(unwrappedType);
|
if (noExpectedType(type)) return isSpecialType.invoke(unwrappedType);
|
||||||
if (visited != null && visited.contains(type)) return false;
|
if (visited != null && visited.contains(type)) return false;
|
||||||
if (isSpecialType.invoke(unwrappedType)) return true;
|
if (isSpecialType.invoke(unwrappedType)) return true;
|
||||||
if (shouldStopAt != null && shouldStopAt.invoke(unwrappedType)) return false;
|
|
||||||
|
|
||||||
if (visited == null) {
|
if (visited == null) {
|
||||||
visited = SmartSet.create();
|
visited = SmartSet.create();
|
||||||
@@ -457,13 +447,13 @@ public class TypeUtils {
|
|||||||
|
|
||||||
FlexibleType flexibleType = unwrappedType instanceof FlexibleType ? (FlexibleType) unwrappedType : null;
|
FlexibleType flexibleType = unwrappedType instanceof FlexibleType ? (FlexibleType) unwrappedType : null;
|
||||||
if (flexibleType != null
|
if (flexibleType != null
|
||||||
&& (contains(flexibleType.getLowerBound(), isSpecialType, shouldStopAt, visited)
|
&& (contains(flexibleType.getLowerBound(), isSpecialType, visited)
|
||||||
|| contains(flexibleType.getUpperBound(), isSpecialType, shouldStopAt, visited))) {
|
|| contains(flexibleType.getUpperBound(), isSpecialType, visited))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unwrappedType instanceof DefinitelyNotNullType &&
|
if (unwrappedType instanceof DefinitelyNotNullType &&
|
||||||
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, shouldStopAt, visited)) {
|
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, visited)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,14 +461,14 @@ public class TypeUtils {
|
|||||||
if (typeConstructor instanceof IntersectionTypeConstructor) {
|
if (typeConstructor instanceof IntersectionTypeConstructor) {
|
||||||
IntersectionTypeConstructor intersectionTypeConstructor = (IntersectionTypeConstructor) typeConstructor;
|
IntersectionTypeConstructor intersectionTypeConstructor = (IntersectionTypeConstructor) typeConstructor;
|
||||||
for (KotlinType supertype : intersectionTypeConstructor.getSupertypes()) {
|
for (KotlinType supertype : intersectionTypeConstructor.getSupertypes()) {
|
||||||
if (contains(supertype, isSpecialType, shouldStopAt, visited)) return true;
|
if (contains(supertype, isSpecialType, visited)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TypeProjection projection : type.getArguments()) {
|
for (TypeProjection projection : type.getArguments()) {
|
||||||
if (projection.isStarProjection()) continue;
|
if (projection.isStarProjection()) continue;
|
||||||
if (contains(projection.getType(), isSpecialType, shouldStopAt, visited)) return true;
|
if (contains(projection.getType(), isSpecialType, visited)) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user