Unify creation of special builtin functions

Create all of them --- both renamed and with de-erased signature ---
within 'computeNonDeclaredFunctions'.

This helps to get rid of open 'resolveMethodToFunctionDescriptor'
and guarantees that method inside 'isVisibleAsFunction'
is always without any magic.
This commit is contained in:
Denis Zharkov
2015-10-23 14:47:54 +03:00
parent c855d3fad9
commit 50125f612e
2 changed files with 31 additions and 57 deletions
@@ -106,11 +106,8 @@ public class LazyJavaClassMemberScope(
return false
}
if (name.sameAsBuiltinMethodWithErasedValueParameters) {
val overridden = firstOverriddenBuiltinFunctionWithErasedValueParameters(this)
if (overridden != null) {
if (doesClassOverrideBuiltinWithoutMagic(overridden)) return false
}
if (name.sameAsBuiltinMethodWithErasedValueParameters && hasOverriddenBuiltinFunctionWithErasedValueParameters(this)) {
return false
}
return true
@@ -120,13 +117,6 @@ public class LazyJavaClassMemberScope(
memberIndex().findMethodsByName(name).map { resolveMethodToFunctionDescriptor(it) }
private fun searchMethodsByNameWithoutBuiltinMagic(name: String) = searchMethodsByNameWithoutBuiltinMagic(Name.identifier(name))
// E.g. it have explicit removeAt declaration in Java
private fun doesClassOverrideBuiltinWithoutMagic(callableMemberDescriptor: CallableMemberDescriptor): Boolean {
return memberIndex().findMethodsByName(callableMemberDescriptor.name).any {
otherJavaMethod ->
super.resolveMethodToFunctionDescriptor(otherJavaMethod).doesOverride(callableMemberDescriptor)
}
}
private fun SimpleFunctionDescriptor.doesOverrideRenamedBuiltins(): Boolean {
return BuiltinMethodsWithDifferentJvmName.getBuiltinFunctionNamesByJvmName(name).any {
@@ -200,7 +190,7 @@ public class LazyJavaClassMemberScope(
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val functionsFromSupertypes = getFunctionsFromSupertypes(name)
if (name.sameAsRenamedInJvmBuiltin) {
if (name.sameAsRenamedInJvmBuiltin || name.sameAsBuiltinMethodWithErasedValueParameters) {
addOverriddenBuiltinMethods(result, name, functionsFromSupertypes)
}
@@ -230,6 +220,29 @@ public class LazyJavaClassMemberScope(
}
}
}
for (descriptor in mergedFunctionFromSuperTypes) {
val overridden =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor)
?: continue
if (result.any { it.doesOverride(overridden) }) continue
result.addIfNotNull(
createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overridden)
?.check { override -> override.isVisibleAsFunction() })
}
}
private fun createOverrideForBuiltinFunctionWithErasedParameterIfNeeded(overridden: FunctionDescriptor): SimpleFunctionDescriptor? {
return searchMethodsByNameWithoutBuiltinMagic(overridden.name).firstOrNull {
it.doesOverrideBuiltinFunctionWithErasedValueParameters(overridden)
}?.let {
override ->
override.createCopyWithNewValueParameters(
copyValueParameters(overridden.valueParameters.map { it.type }, override.valueParameters, overridden))
}
}
private fun getFunctionsFromSupertypes(name: Name): Set<SimpleFunctionDescriptor> {
@@ -352,56 +365,17 @@ public class LazyJavaClassMemberScope(
return LazyJavaScope.MethodSignatureData(effectiveSignature, propagated.getErrors() + effectiveSignature.getErrors())
}
override fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor {
val commonResult = super.resolveMethodToFunctionDescriptor(method)
if (commonResult.name.sameAsBuiltinMethodWithErasedValueParameters) {
val erasedCopy = createOverrideForErasedIfNeeded(commonResult)
if (erasedCopy != null) return erasedCopy
}
return commonResult
}
private fun createOverrideForErasedIfNeeded(
methodDescriptor: JavaMethodDescriptor
): JavaMethodDescriptor? {
val overridden = firstOverriddenBuiltinFunctionWithErasedValueParameters(methodDescriptor) ?: return null
val newMethod = JavaMethodDescriptor.createJavaMethod(
methodDescriptor.containingDeclaration, methodDescriptor.annotations, methodDescriptor.name, methodDescriptor.source)
assert(methodDescriptor.typeParameters.isEmpty()) { "There should be methods with no type parameters, but $methodDescriptor found" }
newMethod.initialize(
methodDescriptor.extensionReceiverParameter?.type,
methodDescriptor.dispatchReceiverParameter,
emptyList(),
copyValueParameters(overridden.valueParameters.map { it.type }, methodDescriptor.valueParameters, newMethod),
methodDescriptor.returnType,
methodDescriptor.modality,
methodDescriptor.visibility
)
newMethod.setParameterNamesStatus(methodDescriptor.hasStableParameterNames(), methodDescriptor.hasSynthesizedParameterNames())
return newMethod
}
private fun firstOverriddenBuiltinFunctionWithErasedValueParameters(
private fun hasOverriddenBuiltinFunctionWithErasedValueParameters(
simpleFunctionDescriptor: SimpleFunctionDescriptor
): FunctionDescriptor? {
): Boolean {
val candidatesToOverride =
getFunctionsFromSupertypes(simpleFunctionDescriptor.name).map {
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(it)
}.filterNotNull()
if (candidatesToOverride.isEmpty()) return null
return candidatesToOverride.firstNotNullResult overrides@{
return candidatesToOverride.any {
candidate ->
candidate.check { simpleFunctionDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters(candidate) }
simpleFunctionDescriptor.doesOverrideBuiltinFunctionWithErasedValueParameters(candidate)
}
}
@@ -109,7 +109,7 @@ public abstract class LazyJavaScope(
returnType: KotlinType,
valueParameters: ResolvedValueParameters): MethodSignatureData
open fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor {
fun resolveMethodToFunctionDescriptor(method: JavaMethod): JavaMethodDescriptor {
val annotations = c.resolveAnnotations(method)
val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod(
containingDeclaration, annotations, method.name, c.components.sourceElementFactory.source(method)