FE: separate type enhancement and FunctionN@Java warnings

This commit is contained in:
pyos
2021-08-09 12:38:04 +02:00
committed by teamcityserver
parent f4f9b1b27b
commit 56d37c8e1c
2 changed files with 34 additions and 69 deletions
@@ -103,7 +103,6 @@ class SignatureEnhancement(
) { it.extensionReceiverParameter!!.type }.enhance()
else null
val predefinedEnhancementInfo =
(this as? JavaMethodDescriptor)
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
@@ -132,23 +131,24 @@ class SignatureEnhancement(
AnnotationQualifierApplicabilityType.METHOD_RETURN_TYPE
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
val containsFunctionN = receiverTypeEnhancement?.containsFunctionN == true || returnTypeEnhancement.containsFunctionN ||
valueParameterEnhancements.any { it.containsFunctionN }
val containsFunctionN = returnType!!.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)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges } || containsFunctionN
if (receiverTypeEnhancement != null || returnTypeEnhancement != null || valueParameterEnhancements.any { it != null } ||
additionalUserData != null
) {
val additionalUserData =
if (containsFunctionN)
DEPRECATED_FUNCTION_KEY to DeprecationCausedByFunctionNInfo(this)
else
null
@Suppress("UNCHECKED_CAST")
return this.enhance(
receiverTypeEnhancement?.type,
valueParameterEnhancements.map { ValueParameterData(it.type, false) },
returnTypeEnhancement.type,
receiverTypeEnhancement ?: extensionReceiverParameter?.type,
valueParameterEnhancements.mapIndexed { index, enhanced ->
ValueParameterData(enhanced ?: valueParameters[index].type, false)
},
returnTypeEnhancement ?: returnType!!,
additionalUserData
) as D
}
@@ -169,7 +169,7 @@ class SignatureEnhancement(
typeParameter, bound, emptyList(), false, context,
AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS,
typeParameterBounds = true
).enhance().type
).enhance() ?: bound
}
}
@@ -181,7 +181,14 @@ class SignatureEnhancement(
SignatureParts(
typeContainer = null, type, emptyList(), isCovariant = false,
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 val typeContainer: Annotated?,
@@ -196,35 +203,11 @@ class SignatureEnhancement(
private val isForVarargParameter get() = typeContainer.safeAs<ValueParameterDescriptor>()?.varargElementType != null
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
val qualifiers = computeIndexedQualifiersForOverride()
val qualifiersWithPredefined: ((Int) -> JavaTypeQualifiers)? = predefined?.let {
{ index ->
predefined.map[index] ?: qualifiers(index)
}
fun enhance(predefined: TypeEnhancementInfo? = null): KotlinType? =
with(typeEnhancement) {
fromOverride.enhance(computeIndexedQualifiersForOverride(predefined), isSuperTypesEnhancement)
}
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 {
val (lower, upper) =
if (this.isFlexible())
@@ -414,8 +397,7 @@ class SignatureEnhancement(
): NullabilityQualifierWithMigrationStatus? =
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 indexedThisType = fromOverride.toIndexed()
@@ -431,8 +413,7 @@ class SignatureEnhancement(
val verticalSlice = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type }
indexedThisType[index].computeQualifiersForOverride(verticalSlice)
}
return { index -> computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
return { index -> predefined?.map?.get(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(
// TODO: investigate if it's really can be a null (check properties' with extension overrides in Java)
parameterDescriptor: ValueParameterDescriptor?,
@@ -424,21 +424,12 @@ public class TypeUtils {
@Nullable KotlinType type,
@NotNull Function1<UnwrappedType, Boolean> isSpecialType
) {
return contains(type, isSpecialType, null, null);
}
public static boolean containsStoppingAt(
@Nullable KotlinType type,
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
@NotNull Function1<KotlinType, Boolean> shouldStopAt
) {
return contains(type, isSpecialType, shouldStopAt, null);
return contains(type, isSpecialType, null);
}
private static boolean contains(
@Nullable KotlinType type,
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
@Nullable Function1<KotlinType, Boolean> shouldStopAt,
SmartSet<KotlinType> visited
) {
if (type == null) return false;
@@ -448,7 +439,6 @@ public class TypeUtils {
if (noExpectedType(type)) return isSpecialType.invoke(unwrappedType);
if (visited != null && visited.contains(type)) return false;
if (isSpecialType.invoke(unwrappedType)) return true;
if (shouldStopAt != null && shouldStopAt.invoke(unwrappedType)) return false;
if (visited == null) {
visited = SmartSet.create();
@@ -457,13 +447,13 @@ public class TypeUtils {
FlexibleType flexibleType = unwrappedType instanceof FlexibleType ? (FlexibleType) unwrappedType : null;
if (flexibleType != null
&& (contains(flexibleType.getLowerBound(), isSpecialType, shouldStopAt, visited)
|| contains(flexibleType.getUpperBound(), isSpecialType, shouldStopAt, visited))) {
&& (contains(flexibleType.getLowerBound(), isSpecialType, visited)
|| contains(flexibleType.getUpperBound(), isSpecialType, visited))) {
return true;
}
if (unwrappedType instanceof DefinitelyNotNullType &&
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, shouldStopAt, visited)) {
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, visited)) {
return true;
}
@@ -471,14 +461,14 @@ public class TypeUtils {
if (typeConstructor instanceof IntersectionTypeConstructor) {
IntersectionTypeConstructor intersectionTypeConstructor = (IntersectionTypeConstructor) typeConstructor;
for (KotlinType supertype : intersectionTypeConstructor.getSupertypes()) {
if (contains(supertype, isSpecialType, shouldStopAt, visited)) return true;
if (contains(supertype, isSpecialType, visited)) return true;
}
return false;
}
for (TypeProjection projection : type.getArguments()) {
if (projection.isStarProjection()) continue;
if (contains(projection.getType(), isSpecialType, shouldStopAt, visited)) return true;
if (contains(projection.getType(), isSpecialType, visited)) return true;
}
return false;
}