ParameterName annotation on type argument used to hold parameter name

This commit is contained in:
Valentin Kipyatkov
2016-09-14 19:37:44 +03:00
parent 3bd39df587
commit 59269ef1ae
37 changed files with 158 additions and 140 deletions
@@ -16,7 +16,10 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
@@ -48,7 +51,6 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral
import java.util.*
@@ -208,7 +210,7 @@ class FunctionDescriptorResolver(
return listOf(it)
}
if (function.valueParameters.size != expectedValueParameters.size) {
val expectedParameterTypes = ExpressionTypingUtils.getValueParametersTypes(expectedValueParameters)
val expectedParameterTypes = expectedValueParameters.map { it.type }
trace.report(EXPECTED_PARAMETERS_NUMBER_MISMATCH.on(function, expectedParameterTypes.size, expectedParameterTypes))
}
}
@@ -226,11 +228,11 @@ class FunctionDescriptorResolver(
private fun KotlinType.functionTypeExpected() = !TypeUtils.noExpectedType(this) && isFunctionType
private fun KotlinType.getReceiverType(): KotlinType? =
if (functionTypeExpected()) getReceiverTypeFromFunctionType(this) else null
if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null
private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
if (functionTypeExpected()) {
createValueParametersForInvokeInFunctionType(owner, getValueParameterTypesFromFunctionType(this))
createValueParametersForInvokeInFunctionType(owner, this.getValueParameterTypesFromFunctionType())
}
else null
@@ -181,7 +181,7 @@ class CallCompleter(
if (call.isCallableReference()) {
// TODO: compute generic type argument for R in the kotlin.Function<R> supertype (KT-12963)
// TODO: also add constraints for parameter types (KT-12964)
if (!TypeUtils.noExpectedType(expectedType) && expectedType.isFunctionType) getReturnTypeFromFunctionType(expectedType)
if (!TypeUtils.noExpectedType(expectedType) && expectedType.isFunctionType) expectedType.getReturnTypeFromFunctionType()
else TypeUtils.NO_EXPECTED_TYPE
}
else expectedType
@@ -174,7 +174,7 @@ fun getEffectiveExpectedType(parameterDescriptor: ValueParameterDescriptor, argu
argument.getArgumentExpression() is KtLambdaExpression &&
parameterDescriptor.type.isExtensionFunctionType
) {
val receiverType = getReceiverTypeFromFunctionType(parameterDescriptor.type)!!
val receiverType = parameterDescriptor.type.getReceiverTypeFromFunctionType()!!
val newExpectedLambdaReturnType =
receiverType.memberScope
@@ -56,7 +56,7 @@ object CoroutineModifierChecker : SimpleDeclarationChecker {
continue
}
val returnType = getReturnTypeFromFunctionType(parameterDescriptor.type)
val returnType = parameterDescriptor.type.getReturnTypeFromFunctionType()
if (returnType.isMarkedNullable || !returnType.isValidContinuation() || !returnType.arguments.single().type.isUnit()) {
report("parameter should have function type like 'Controller.() -> Continuation<Unit>' (Continuation<Unit> for return type is necessary)")
@@ -68,7 +68,7 @@ object CoroutineModifierChecker : SimpleDeclarationChecker {
continue
}
val controller = getReceiverTypeFromFunctionType(parameterDescriptor.type)!!
val controller = parameterDescriptor.type.getReceiverTypeFromFunctionType()!!
val handleResultFunctions =
controller.memberScope
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.createValueParametersForInvokeInFunctionType
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.receivers.ClassQualifier
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.Receiver
@@ -48,6 +49,7 @@ import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import java.lang.UnsupportedOperationException
import javax.inject.Inject
sealed class DoubleColonLHS(val type: KotlinType) {
@@ -534,8 +536,10 @@ class DoubleColonExpressionResolver(
return when (descriptor) {
is FunctionDescriptor -> {
val returnType = descriptor.returnType ?: return null
val valueParametersTypes = ExpressionTypingUtils.getValueParametersTypes(descriptor.valueParameters)
return reflectionTypes.getKFunctionType(Annotations.EMPTY, receiverType, valueParametersTypes, returnType)
val parametersTypes = descriptor.valueParameters.map { it.type }
val parametersNames = descriptor.valueParameters.map { it.name }
return reflectionTypes.getKFunctionType(Annotations.EMPTY, receiverType,
parametersTypes, parametersNames, returnType, descriptor.builtIns)
}
is PropertyDescriptor -> {
val mutable = descriptor.isVar && run {
@@ -187,7 +187,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
functionDescriptor: SimpleFunctionDescriptorImpl,
functionTypeExpected: Boolean
): KotlinType {
val expectedReturnType = if (functionTypeExpected) getReturnTypeFromFunctionType(context.expectedType) else null
val expectedReturnType = if (functionTypeExpected) context.expectedType.getReturnTypeFromFunctionType() else null
val returnType = computeUnsafeReturnType(expression, context, functionDescriptor, expectedReturnType)
if (!expression.functionLiteral.hasDeclaredReturnType() && functionTypeExpected) {
@@ -54,7 +54,7 @@ fun createFunctionType(
parameterNames: List<Name>?,
returnType: KotlinType
): SimpleType {
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, parameterNames, returnType, builtIns)
val size = parameterTypes.size
val classDescriptor = builtIns.getFunction(if (receiverType == null) size else size + 1)
@@ -72,13 +72,7 @@ fun createFunctionType(
AnnotationsImpl(annotations + extensionFunctionAnnotation)
}
val simpleType = KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
if (parameterNames == null || parameterNames.all { it.isSpecial }) {
return simpleType
}
else {
return FunctionType(simpleType, parameterNames)
}
return KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
}
fun getValueParametersCountFromFunctionType(type: KotlinType): Int {
+6
View File
@@ -565,6 +565,12 @@ public abstract class Number {
public abstract fun toShort(): kotlin.Short
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.MustBeDocumented() public final annotation class ParameterName : kotlin.Annotation {
/*primary*/ public constructor ParameterName(/*0*/ name: kotlin.String)
public final val name: kotlin.String
public final fun <get-name>(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.MustBeDocumented() public final annotation class ReplaceWith : kotlin.Annotation {
/*primary*/ public constructor ReplaceWith(/*0*/ expression: kotlin.String, /*1*/ vararg imports: kotlin.String /*kotlin.Array<out kotlin.String>*/)
public final val expression: kotlin.String
+6
View File
@@ -569,6 +569,12 @@ public abstract class Number : kotlin.Any, java.io.Serializable {
public abstract fun toShort(): kotlin.Short
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.MustBeDocumented() public final annotation class ParameterName : kotlin.Annotation {
/*primary*/ public constructor ParameterName(/*0*/ name: kotlin.String)
public final val name: kotlin.String
public final fun <get-name>(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.MustBeDocumented() public final annotation class ReplaceWith : kotlin.Annotation {
/*primary*/ public constructor ReplaceWith(/*0*/ expression: kotlin.String, /*1*/ vararg imports: kotlin.String /*kotlin.Array<out kotlin.String>*/)
public final val expression: kotlin.String
+6
View File
@@ -571,6 +571,12 @@ public abstract class Number : kotlin.Any, java.io.Serializable {
public abstract fun toShort(): kotlin.Short
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.MustBeDocumented() public final annotation class ParameterName : kotlin.Annotation {
/*primary*/ public constructor ParameterName(/*0*/ name: kotlin.String)
public final val name: kotlin.String
public final fun <get-name>(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.MustBeDocumented() public final annotation class ReplaceWith : kotlin.Annotation {
/*primary*/ public constructor ReplaceWith(/*0*/ expression: kotlin.String, /*1*/ vararg imports: kotlin.String /*kotlin.Array<out kotlin.String>*/)
public final val expression: kotlin.String
@@ -569,6 +569,12 @@ public abstract class Number : kotlin.Any, java.io.Serializable {
public abstract fun toShort(): kotlin.Short
}
@kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE_PARAMETER}) @kotlin.annotation.MustBeDocumented() public final annotation class ParameterName : kotlin.Annotation {
/*primary*/ public constructor ParameterName(/*0*/ name: kotlin.String)
public final val name: kotlin.String
public final fun <get-name>(): kotlin.String
}
@kotlin.annotation.Target(allowedTargets = {}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.MustBeDocumented() public final annotation class ReplaceWith : kotlin.Annotation {
/*primary*/ public constructor ReplaceWith(/*0*/ expression: kotlin.String, /*1*/ vararg imports: kotlin.String /*kotlin.Array<out kotlin.String>*/)
public final val expression: kotlin.String
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.CharSequence!> Predicate(/*0*/ function: (T) -> kotlin.Boolean): Predicate<T>
public /*synthesized*/ fun </*0*/ T : kotlin.CharSequence!> Predicate(/*0*/ function: (t: @kotlin.ParameterName(name = "t") T) -> kotlin.Boolean): Predicate<T>
public fun main(/*0*/ args: kotlin.Array<kotlin.String>): kotlin.Unit
public fun process(/*0*/ x: Predicate<kotlin.String>): kotlin.Unit
@@ -1,7 +1,7 @@
package
public /*synthesized*/ fun </*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> ConcMap(/*0*/ function: (K!, MyFunc<in K!, out V!>!) -> V!): ConcMap<K, V>
public /*synthesized*/ fun </*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> MyFunc(/*0*/ function: (K!) -> V!): MyFunc<K, V>
public /*synthesized*/ fun </*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> ConcMap(/*0*/ function: (key: @kotlin.ParameterName(name = "key") K!, MyFunc<in K!, out V!>!) -> V!): ConcMap<K, V>
public /*synthesized*/ fun </*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> MyFunc(/*0*/ function: (String: @kotlin.ParameterName(name = "String") K!) -> V!): MyFunc<K, V>
public fun concurrentMap(): kotlin.Unit
public open class ConcHashMap</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> : ConcMap<K!, V!> {
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ K : kotlin.Any!> A(/*0*/ function: (K!, MyFunc!) -> K!): A<K>
public /*synthesized*/ fun </*0*/ K : kotlin.Any!> A(/*0*/ function: (key: @kotlin.ParameterName(name = "key") K!, MyFunc!) -> K!): A<K>
public /*synthesized*/ fun MyFunc(/*0*/ function: (x: kotlin.String!) -> kotlin.String!): MyFunc
public fun main(): kotlin.Unit
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ E : kotlin.Any!> EventListener(/*0*/ function: (E!) -> kotlin.Unit): EventListener<E>
public /*synthesized*/ fun </*0*/ E : kotlin.Any!> EventListener(/*0*/ function: (e: @kotlin.ParameterName(name = "e") E!) -> kotlin.Unit): EventListener<E>
public fun main(): kotlin.Unit
public open class A {
@@ -11,9 +11,9 @@ public open class A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun bar(/*0*/ l: ((kotlin.Any!) -> kotlin.Unit)!): kotlin.Unit
public final /*synthesized*/ fun bar(/*0*/ l: ((e: @kotlin.ParameterName(name = "e") kotlin.Any!) -> kotlin.Unit)!): kotlin.Unit
public open fun bar(/*0*/ l: EventListener<*>!): kotlin.Unit
public final /*synthesized*/ fun baz(/*0*/ l: ((kotlin.CharSequence!) -> kotlin.Unit)!): kotlin.Unit
public final /*synthesized*/ fun baz(/*0*/ l: ((e: @kotlin.ParameterName(name = "e") kotlin.CharSequence!) -> kotlin.Unit)!): kotlin.Unit
public open fun baz(/*0*/ l: EventListener<out kotlin.CharSequence!>!): kotlin.Unit
}
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ E : kotlin.Any!> EventListener(/*0*/ function: (E!) -> kotlin.Unit): EventListener<E>
public /*synthesized*/ fun </*0*/ E : kotlin.Any!> EventListener(/*0*/ function: (e: @kotlin.ParameterName(name = "e") E!) -> kotlin.Unit): EventListener<E>
public fun main(): kotlin.Unit
public open class A {
@@ -11,7 +11,7 @@ public open class A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun bar(/*0*/ l: ((kotlin.String!) -> kotlin.Unit)!): kotlin.Unit
public final /*synthesized*/ fun bar(/*0*/ l: ((e: @kotlin.ParameterName(name = "e") kotlin.String!) -> kotlin.Unit)!): kotlin.Unit
public open fun bar(/*0*/ l: EventListener<in kotlin.String!>!): kotlin.Unit
}
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ E : kotlin.CharSequence!, /*1*/ F : kotlin.collections.(Mutable)Map<kotlin.String!, E!>!> Function(/*0*/ function: (F!) -> E!): Function<E, F>
public /*synthesized*/ fun </*0*/ E : kotlin.CharSequence!, /*1*/ F : kotlin.collections.(Mutable)Map<kotlin.String!, E!>!> Function(/*0*/ function: (f: @kotlin.ParameterName(name = "f") F!) -> E!): Function<E, F>
public fun main(): kotlin.Unit
public open class A {
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ E : kotlin.collections.(Mutable)Map<kotlin.String!, kotlin.Int!>!, /*1*/ F : kotlin.CharSequence!> Function(/*0*/ function: (E!) -> F!): Function<E, F>
public /*synthesized*/ fun </*0*/ E : kotlin.collections.(Mutable)Map<kotlin.String!, kotlin.Int!>!, /*1*/ F : kotlin.CharSequence!> Function(/*0*/ function: (e: @kotlin.ParameterName(name = "e") E!) -> F!): Function<E, F>
public fun main(): kotlin.Unit
public open class A {
@@ -11,7 +11,7 @@ public open class A {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun bar(/*0*/ l: ((kotlin.collections.(Mutable)Map<kotlin.String!, kotlin.Int!>!) -> kotlin.CharSequence!)!): kotlin.Unit
public final /*synthesized*/ fun bar(/*0*/ l: ((e: (@kotlin.ParameterName(name = "e") kotlin.collections.MutableMap<kotlin.String!, kotlin.Int!>..@kotlin.ParameterName(name = "e") kotlin.collections.Map<kotlin.String!, kotlin.Int!>?)) -> kotlin.CharSequence!)!): kotlin.Unit
public open fun bar(/*0*/ l: Function<*, *>!): kotlin.Unit
}
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (T?) -> kotlin.Boolean): A<T>
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (y: @kotlin.ParameterName(name = "y") T?) -> kotlin.Boolean): A<T>
public fun test(): kotlin.Unit
public interface A</*0*/ T : kotlin.Any!> {
@@ -17,6 +17,6 @@ public open class B {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
// Static members
public final /*synthesized*/ fun bar(/*0*/ y: ((kotlin.String?) -> kotlin.Boolean)!): kotlin.Unit
public final /*synthesized*/ fun bar(/*0*/ y: ((y: @kotlin.ParameterName(name = "y") kotlin.String?) -> kotlin.Boolean)!): kotlin.Unit
public open fun bar(/*0*/ y: A<kotlin.String!>!): kotlin.Unit
}
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (T) -> kotlin.Unit): A<T>
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (x: @kotlin.ParameterName(name = "x") T) -> kotlin.Unit): A<T>
public fun test(): kotlin.Unit
public interface A</*0*/ T : kotlin.Any!> {
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (T!) -> kotlin.Boolean): A<T>
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (t: @kotlin.ParameterName(name = "t") T!) -> kotlin.Boolean): A<T>
public fun main(): kotlin.Unit
public interface A</*0*/ T : kotlin.Any!> {
@@ -1,6 +1,6 @@
package
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (T, T?) -> kotlin.Unit): A<T>
public /*synthesized*/ fun </*0*/ T : kotlin.Any!> A(/*0*/ function: (x: @kotlin.ParameterName(name = "x") T, y: @kotlin.ParameterName(name = "y") T?) -> kotlin.Unit): A<T>
public /*synthesized*/ fun B1(/*0*/ function: (x: kotlin.String, y: kotlin.String?) -> kotlin.Unit): B1
public /*synthesized*/ fun B2(/*0*/ function: (x: kotlin.String, y: kotlin.String?) -> kotlin.Unit): B2
public /*synthesized*/ fun B3(/*0*/ function: (x: kotlin.String!, y: kotlin.String!) -> kotlin.Unit): B3
@@ -17,5 +17,5 @@ public open class JavaClass</*0*/ T : kotlin.Any!> {
}
// Static members
public final /*synthesized*/ fun </*0*/ X : kotlin.Any!> Inner(/*0*/ function: (T!, X!, java.lang.Runnable!) -> T!): JavaClass.Inner<X>
public final /*synthesized*/ fun </*0*/ X : kotlin.Any!> Inner(/*0*/ function: (t: T!, x: @kotlin.ParameterName(name = "x") X!, java.lang.Runnable!) -> T!): JavaClass.Inner<X>
}