Use parameter names from function type for invoke() function
#KT-435 Fixed #KT-9016 Fixed
This commit is contained in:
Vendored
+1
-1
@@ -4,6 +4,6 @@ public final class A : (categoryName: [ERROR : No type element]) -> [ERROR : No
|
||||
public constructor A()
|
||||
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 override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: [ERROR : No type element]): [ERROR : No type element]
|
||||
public abstract override /*1*/ /*fake_override*/ fun invoke(/*0*/ categoryName: [ERROR : No type element]): [ERROR : No type element]
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -6,7 +6,7 @@ package typeReferenceError {
|
||||
public constructor Pair()
|
||||
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 override /*1*/ /*fake_override*/ fun invoke(/*0*/ p1: [ERROR : No type element]): [ERROR : main]
|
||||
public abstract override /*1*/ /*fake_override*/ fun invoke(/*0*/ c: [ERROR : No type element]): [ERROR : main]
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
fun Any.foo1() : (i : Int) -> Unit {
|
||||
return {}
|
||||
}
|
||||
|
||||
fun test(a : Any) {
|
||||
a.foo1()(<!NO_VALUE_FOR_PARAMETER(i)!>)<!>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public fun test(/*0*/ a: kotlin.Any): kotlin.Unit
|
||||
public fun kotlin.Any.foo1(): (i: kotlin.Int) -> kotlin.Unit
|
||||
@@ -367,6 +367,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt435.kt")
|
||||
public void testKt435() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/kt435.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt53.kt")
|
||||
public void testKt53() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/kt53.kt");
|
||||
|
||||
+33
-6
@@ -23,23 +23,29 @@ import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
class FunctionInvokeDescriptor private constructor(
|
||||
container: DeclarationDescriptor,
|
||||
original: FunctionInvokeDescriptor?,
|
||||
callableKind: CallableMemberDescriptor.Kind
|
||||
callableKind: CallableMemberDescriptor.Kind,
|
||||
private val hasSynthesizedParameterNames: Boolean
|
||||
) : SimpleFunctionDescriptorImpl(
|
||||
container,
|
||||
original,
|
||||
Annotations.EMPTY,
|
||||
Name.identifier("invoke"),
|
||||
OperatorNameConventions.INVOKE,
|
||||
callableKind,
|
||||
SourceElement.NO_SOURCE
|
||||
) {
|
||||
init {
|
||||
this.isOperator = true
|
||||
}
|
||||
|
||||
// "p0", "p1", etc. should not be baked into the language
|
||||
override fun hasStableParameterNames(): Boolean = false
|
||||
|
||||
override fun hasSynthesizedParameterNames(): Boolean = true
|
||||
override fun hasSynthesizedParameterNames(): Boolean = hasSynthesizedParameterNames
|
||||
|
||||
override fun createSubstitutedCopy(
|
||||
newOwner: DeclarationDescriptor,
|
||||
@@ -49,7 +55,7 @@ class FunctionInvokeDescriptor private constructor(
|
||||
annotations: Annotations,
|
||||
source: SourceElement
|
||||
): FunctionDescriptorImpl {
|
||||
return FunctionInvokeDescriptor(newOwner, original as FunctionInvokeDescriptor?, kind)
|
||||
return FunctionInvokeDescriptor(newOwner, original as FunctionInvokeDescriptor?, kind, hasSynthesizedParameterNames)
|
||||
}
|
||||
|
||||
override fun isExternal(): Boolean = false
|
||||
@@ -58,11 +64,33 @@ class FunctionInvokeDescriptor private constructor(
|
||||
|
||||
override fun isTailrec(): Boolean = false
|
||||
|
||||
fun replaceParameterNames(parameterNames: List<Name>): FunctionInvokeDescriptor {
|
||||
val indexShift = valueParameters.size - parameterNames.size
|
||||
assert(indexShift == 0 || indexShift == 1) // indexShift == 1 for extension function type
|
||||
|
||||
val hasSynthesizedParameterNames = parameterNames.any { it.isSpecial }
|
||||
val newDescriptor = FunctionInvokeDescriptor(containingDeclaration, this, kind, hasSynthesizedParameterNames)
|
||||
val newValueParameters = valueParameters.map {
|
||||
var newName = it.name
|
||||
val parameterIndex = it.index
|
||||
val nameIndex = parameterIndex - indexShift
|
||||
if (nameIndex >= 0) {
|
||||
val parameterName = parameterNames[nameIndex]
|
||||
if (!parameterName.isSpecial) {
|
||||
newName = parameterName
|
||||
}
|
||||
}
|
||||
it.copy(newDescriptor, newName, parameterIndex)
|
||||
}
|
||||
newDescriptor.initialize(extensionReceiverParameterType, dispatchReceiverParameter, typeParameters, newValueParameters, returnType, modality, visibility)
|
||||
return newDescriptor
|
||||
}
|
||||
|
||||
companion object Factory {
|
||||
fun create(functionClass: FunctionClassDescriptor): FunctionInvokeDescriptor {
|
||||
val typeParameters = functionClass.declaredTypeParameters
|
||||
|
||||
val result = FunctionInvokeDescriptor(functionClass, null, CallableMemberDescriptor.Kind.DECLARATION)
|
||||
val result = FunctionInvokeDescriptor(functionClass, null, CallableMemberDescriptor.Kind.DECLARATION, hasSynthesizedParameterNames = true)
|
||||
result.initialize(
|
||||
null,
|
||||
functionClass.thisAsReceiverParameter,
|
||||
@@ -74,7 +102,6 @@ class FunctionInvokeDescriptor private constructor(
|
||||
Modality.ABSTRACT,
|
||||
Visibilities.PUBLIC
|
||||
)
|
||||
result.isOperator = true
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,16 @@
|
||||
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import java.util.*
|
||||
|
||||
abstract class DelegatingSimpleType : SimpleType() {
|
||||
protected abstract val delegate: SimpleType
|
||||
@@ -57,6 +63,28 @@ class FunctionType(
|
||||
*/
|
||||
val parameterNames: List<Name>
|
||||
) : DelegatingSimpleType() {
|
||||
|
||||
override val memberScope = object: MemberScope by delegate.memberScope {
|
||||
private val cache = HashMap<FunctionInvokeDescriptor, FunctionInvokeDescriptor>(2)
|
||||
|
||||
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> {
|
||||
return delegate.memberScope.getContributedFunctions(name, location).replaceParameterNames()
|
||||
}
|
||||
|
||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
|
||||
return delegate.memberScope.getContributedDescriptors(kindFilter, nameFilter).replaceParameterNames()
|
||||
}
|
||||
|
||||
private fun <TDescriptor : DeclarationDescriptor> Collection<TDescriptor>.replaceParameterNames(): List<TDescriptor>
|
||||
= map { it.replaceParameterNames() }
|
||||
|
||||
private fun <TDescriptor : DeclarationDescriptor> TDescriptor.replaceParameterNames(): TDescriptor {
|
||||
if (this !is FunctionInvokeDescriptor) return this
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return cache.getOrPut(this) { this.replaceParameterNames(parameterNames) } as TDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: Annotations)
|
||||
= FunctionType(delegate.replaceAnnotations(newAnnotations), parameterNames)
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ fun x(name: String, next: (name: String) -> String): String {
|
||||
return next(<caret>)
|
||||
}
|
||||
|
||||
//TODO: use parameter names from functional type
|
||||
/*
|
||||
Text: (<highlight>String</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
Text: (<highlight>name: String</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
*/
|
||||
|
||||
@@ -5,8 +5,7 @@ fun call() {
|
||||
header(<caret>"sdf", "sdjfn")
|
||||
}
|
||||
|
||||
//TODO: use parameter names from functional type
|
||||
/*
|
||||
Text: (<highlight>String</highlight>, String), Disabled: false, Strikeout: false, Green: true
|
||||
Text: (<highlight>name: String</highlight>, value: Int), Disabled: false, Strikeout: false, Green: false
|
||||
Text: (<highlight>s: String</highlight>, s1: String), Disabled: false, Strikeout: false, Green: true
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user