Create From Usage: Use supplied type arguments to infer function type parameters
This commit is contained in:
+99
-22
@@ -51,7 +51,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
|
|||||||
import org.jetbrains.jet.plugin.refactoring.EmptyValidator
|
import org.jetbrains.jet.plugin.refactoring.EmptyValidator
|
||||||
import org.jetbrains.jet.plugin.refactoring.CollectingValidator
|
import org.jetbrains.jet.plugin.refactoring.CollectingValidator
|
||||||
import org.jetbrains.jet.plugin.util.isUnit
|
import org.jetbrains.jet.plugin.util.isUnit
|
||||||
import com.intellij.util.ArrayUtil
|
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.jet.lexer.JetTokens
|
import org.jetbrains.jet.lexer.JetTokens
|
||||||
@@ -59,6 +58,13 @@ import org.jetbrains.jet.plugin.util.application.runWriteAction
|
|||||||
import org.jetbrains.jet.plugin.refactoring.isMultiLine
|
import org.jetbrains.jet.plugin.refactoring.isMultiLine
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||||
import com.intellij.psi.SmartPointerManager
|
import com.intellij.psi.SmartPointerManager
|
||||||
|
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||||
|
import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl
|
||||||
|
import java.util.LinkedHashMap
|
||||||
|
import org.jetbrains.jet.plugin.util.IdeDescriptorRenderers
|
||||||
|
|
||||||
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
|
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
|
||||||
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
|
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
|
||||||
@@ -71,12 +77,14 @@ class TypeCandidate(val theType: JetType, scope: JetScope? = null) {
|
|||||||
public val typeParameters: Array<TypeParameterDescriptor>
|
public val typeParameters: Array<TypeParameterDescriptor>
|
||||||
var renderedType: String? = null
|
var renderedType: String? = null
|
||||||
private set
|
private set
|
||||||
var typeParameterNames: Array<String>? = null
|
var renderedTypeParameters: List<RenderedTypeParameter>? = null
|
||||||
private set
|
private set
|
||||||
|
|
||||||
fun render(typeParameterNameMap: Map<TypeParameterDescriptor, String>) {
|
fun render(typeParameterNameMap: Map<TypeParameterDescriptor, String>, fakeFunction: FunctionDescriptor) {
|
||||||
renderedType = theType.renderShort(typeParameterNameMap);
|
renderedType = theType.renderShort(typeParameterNameMap);
|
||||||
typeParameterNames = typeParameters.map { typeParameterNameMap[it]!! }.copyToArray()
|
renderedTypeParameters = typeParameters.map {
|
||||||
|
RenderedTypeParameter(it, it.getContainingDeclaration() == fakeFunction, typeParameterNameMap[it]!!)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -93,6 +101,12 @@ class TypeCandidate(val theType: JetType, scope: JetScope? = null) {
|
|||||||
override fun toString() = theType.toString()
|
override fun toString() = theType.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RenderedTypeParameter(
|
||||||
|
val typeParameter: TypeParameterDescriptor,
|
||||||
|
val fake: Boolean,
|
||||||
|
val text: String
|
||||||
|
)
|
||||||
|
|
||||||
fun List<TypeCandidate>.getTypeByRenderedType(renderedType: String): JetType? =
|
fun List<TypeCandidate>.getTypeByRenderedType(renderedType: String): JetType? =
|
||||||
firstOrNull { it.renderedType == renderedType }?.theType
|
firstOrNull { it.renderedType == renderedType }?.theType
|
||||||
|
|
||||||
@@ -140,7 +154,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
fun computeTypeCandidates(
|
fun computeTypeCandidates(
|
||||||
typeInfo: TypeInfo,
|
typeInfo: TypeInfo,
|
||||||
substitutions: Array<JetTypeSubstitution>,
|
substitutions: List<JetTypeSubstitution>,
|
||||||
scope: JetScope): List<TypeCandidate> {
|
scope: JetScope): List<TypeCandidate> {
|
||||||
if (typeInfo is TypeInfo.ByType && typeInfo.keepUnsubstituted) return computeTypeCandidates(typeInfo)
|
if (typeInfo is TypeInfo.ByType && typeInfo.keepUnsubstituted) return computeTypeCandidates(typeInfo)
|
||||||
return typeCandidates.getOrPut(typeInfo) {
|
return typeCandidates.getOrPut(typeInfo) {
|
||||||
@@ -201,6 +215,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val receiverClassDescriptor: ClassDescriptor?
|
val receiverClassDescriptor: ClassDescriptor?
|
||||||
val typeParameterNameMap: Map<TypeParameterDescriptor, String>
|
val typeParameterNameMap: Map<TypeParameterDescriptor, String>
|
||||||
val receiverTypeCandidate: TypeCandidate?
|
val receiverTypeCandidate: TypeCandidate?
|
||||||
|
val substitutions: List<JetTypeSubstitution>
|
||||||
|
|
||||||
{
|
{
|
||||||
// gather relevant information
|
// gather relevant information
|
||||||
@@ -213,7 +228,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
containingElement = placement.containingElement
|
containingElement = placement.containingElement
|
||||||
}
|
}
|
||||||
placement is CallablePlacement.WithReceiver -> {
|
placement is CallablePlacement.WithReceiver -> {
|
||||||
receiverClassDescriptor = DescriptorUtils.getClassDescriptorForType(placement.receiverTypeCandidate.theType)
|
receiverClassDescriptor =
|
||||||
|
placement.receiverTypeCandidate.theType.getConstructor().getDeclarationDescriptor() as? ClassDescriptor
|
||||||
val classDeclaration = receiverClassDescriptor?.let { DescriptorToSourceUtils.classDescriptorToDeclaration(it) }
|
val classDeclaration = receiverClassDescriptor?.let { DescriptorToSourceUtils.classDescriptorToDeclaration(it) }
|
||||||
isExtension = !(classDeclaration is JetClassOrObject && classDeclaration.isWritable())
|
isExtension = !(classDeclaration is JetClassOrObject && classDeclaration.isWritable())
|
||||||
containingElement = if (isExtension) config.currentFile else classDeclaration as JetElement
|
containingElement = if (isExtension) config.currentFile else classDeclaration as JetElement
|
||||||
@@ -239,13 +255,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// figure out type substitutions for type parameters
|
// figure out type substitutions for type parameters
|
||||||
val classTypeParameters = receiverType?.getArguments() ?: Collections.emptyList()
|
val substitutionMap = LinkedHashMap<JetType, JetType>()
|
||||||
val ownerTypeArguments = (placement as? CallablePlacement.WithReceiver)?.receiverTypeCandidate?.theType?.getArguments()
|
collectSubstitutionsForReceiverTypeParameters(receiverType, substitutionMap)
|
||||||
?: Collections.emptyList()
|
val typeArgumentsForFakeFunction = callableInfo.typeParameterInfos
|
||||||
assert(ownerTypeArguments.size == classTypeParameters.size)
|
.map {
|
||||||
val substitutions = ownerTypeArguments.zip(classTypeParameters).map {
|
val typeCandidates = computeTypeCandidates(it)
|
||||||
JetTypeSubstitution(it.first.getType(), it.second.getType())
|
assert (typeCandidates.size == 1, "Ambiguous type candidates for type parameter $it: $typeCandidates")
|
||||||
}.copyToArray()
|
typeCandidates.first().theType
|
||||||
|
}
|
||||||
|
.subtract(substitutionMap.keySet())
|
||||||
|
val fakeFunction = createFakeFunctionDescriptor(scope, typeArgumentsForFakeFunction.size)
|
||||||
|
collectSubstitutionsForCallableTypeParameters(fakeFunction, typeArgumentsForFakeFunction, substitutionMap)
|
||||||
|
substitutions = substitutionMap.map { JetTypeSubstitution(it.key, it.value) }
|
||||||
|
|
||||||
callableInfo.parameterInfos.forEach {
|
callableInfo.parameterInfos.forEach {
|
||||||
computeTypeCandidates(it.typeInfo, substitutions, scope)
|
computeTypeCandidates(it.typeInfo, substitutions, scope)
|
||||||
@@ -261,18 +282,61 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
// figure out type parameter renames to avoid conflicts
|
// figure out type parameter renames to avoid conflicts
|
||||||
typeParameterNameMap = getTypeParameterRenames(scope)
|
typeParameterNameMap = getTypeParameterRenames(scope)
|
||||||
callableInfo.parameterInfos.forEach { renderTypeCandidates(it.typeInfo, typeParameterNameMap) }
|
callableInfo.parameterInfos.forEach { renderTypeCandidates(it.typeInfo, typeParameterNameMap, fakeFunction) }
|
||||||
if (!skipReturnType) {
|
if (!skipReturnType) {
|
||||||
renderTypeCandidates(callableInfo.returnTypeInfo, typeParameterNameMap)
|
renderTypeCandidates(callableInfo.returnTypeInfo, typeParameterNameMap, fakeFunction)
|
||||||
}
|
}
|
||||||
receiverTypeCandidate?.render(typeParameterNameMap)
|
receiverTypeCandidate?.render(typeParameterNameMap, fakeFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectSubstitutionsForReceiverTypeParameters(
|
||||||
|
receiverType: JetType?,
|
||||||
|
result: MutableMap<JetType, JetType>
|
||||||
|
) {
|
||||||
|
val classTypeParameters = receiverType?.getArguments() ?: Collections.emptyList()
|
||||||
|
val ownerTypeArguments = (placement as? CallablePlacement.WithReceiver)?.receiverTypeCandidate?.theType?.getArguments()
|
||||||
|
?: Collections.emptyList()
|
||||||
|
assert(ownerTypeArguments.size == classTypeParameters.size)
|
||||||
|
ownerTypeArguments.zip(classTypeParameters).forEach { result[it.first.getType()] = it.second.getType() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectSubstitutionsForCallableTypeParameters(
|
||||||
|
fakeFunction: FunctionDescriptor,
|
||||||
|
typeArguments: Set<JetType>,
|
||||||
|
result: MutableMap<JetType, JetType>) {
|
||||||
|
for ((typeArgument, typeParameter) in typeArguments zip fakeFunction.getTypeParameters()) {
|
||||||
|
result[typeArgument] = typeParameter.getDefaultType()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createFakeFunctionDescriptor(scope: JetScope, typeParameterCount: Int): FunctionDescriptor {
|
||||||
|
val fakeFunction = SimpleFunctionDescriptorImpl.create(
|
||||||
|
MutablePackageFragmentDescriptor(currentFileModule, FqName("fake")),
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Name.identifier("fake"),
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
SourceElement.NO_SOURCE
|
||||||
|
)
|
||||||
|
val validator = CollectingValidator { scope.getClassifier(Name.identifier(it)) == null }
|
||||||
|
val typeParameters = typeParameterCount.indices.map {
|
||||||
|
TypeParameterDescriptorImpl.createWithDefaultBound(
|
||||||
|
fakeFunction,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
false,
|
||||||
|
Variance.INVARIANT,
|
||||||
|
Name.identifier(validator.validateName("T")),
|
||||||
|
it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return fakeFunction.initialize(null, null, typeParameters, Collections.emptyList(), null, null, Visibilities.INTERNAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderTypeCandidates(
|
private fun renderTypeCandidates(
|
||||||
typeInfo: TypeInfo,
|
typeInfo: TypeInfo,
|
||||||
typeParameterNameMap: Map<TypeParameterDescriptor, String>
|
typeParameterNameMap: Map<TypeParameterDescriptor, String>,
|
||||||
|
fakeFunction: FunctionDescriptor
|
||||||
) {
|
) {
|
||||||
typeCandidates[typeInfo]?.forEach { it.render(typeParameterNameMap) }
|
typeCandidates[typeInfo]?.forEach { it.render(typeParameterNameMap, fakeFunction) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createDeclarationSkeleton(): JetCallableDeclaration {
|
private fun createDeclarationSkeleton(): JetCallableDeclaration {
|
||||||
@@ -474,6 +538,16 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
func.getBodyExpression()!!.replace(newBodyExpression)
|
func.getBodyExpression()!!.replace(newBodyExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setupCallTypeArguments(callExpr: JetCallExpression, typeParameters: List<TypeParameterDescriptor>) {
|
||||||
|
val oldTypeArgumentList = callExpr.getTypeArgumentList() ?: return
|
||||||
|
val renderedTypeArgs = typeParameters.map { typeParameter ->
|
||||||
|
val type = substitutions.first { it.byType.getConstructor().getDeclarationDescriptor() == typeParameter }.forType
|
||||||
|
IdeDescriptorRenderers.SOURCE_CODE.renderType(type)
|
||||||
|
}
|
||||||
|
oldTypeArgumentList.replace(JetPsiFactory(callExpr).createTypeArguments(renderedTypeArgs.joinToString(", ", "<", ">")))
|
||||||
|
elementsToShorten.add(callExpr.getTypeArgumentList())
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupReturnTypeTemplate(builder: TemplateBuilder, declaration: JetCallableDeclaration): TypeExpression? {
|
private fun setupReturnTypeTemplate(builder: TemplateBuilder, declaration: JetCallableDeclaration): TypeExpression? {
|
||||||
val returnTypeRef = declaration.getTypeReference() ?: return null
|
val returnTypeRef = declaration.getTypeReference() ?: return null
|
||||||
val candidates = typeCandidates[callableInfo.returnTypeInfo]!!
|
val candidates = typeCandidates[callableInfo.returnTypeInfo]!!
|
||||||
@@ -500,16 +574,16 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTypeParameterListTemplate(builder: TemplateBuilderImpl, declaration: JetCallableDeclaration): TypeParameterListExpression {
|
private fun setupTypeParameterListTemplate(builder: TemplateBuilderImpl, declaration: JetCallableDeclaration): TypeParameterListExpression {
|
||||||
val typeParameterMap = HashMap<String, Array<String>>()
|
val typeParameterMap = HashMap<String, List<RenderedTypeParameter>>()
|
||||||
val receiverTypeParameterNames = receiverTypeCandidate?.let { it.typeParameterNames!! } ?: ArrayUtil.EMPTY_STRING_ARRAY
|
val receiverTypeParameterNames = receiverTypeCandidate?.let { it.renderedTypeParameters!! } ?: Collections.emptyList()
|
||||||
|
|
||||||
callableInfo.parameterInfos.stream().flatMap { typeCandidates[it.typeInfo]!!.stream() }.forEach {
|
callableInfo.parameterInfos.stream().flatMap { typeCandidates[it.typeInfo]!!.stream() }.forEach {
|
||||||
typeParameterMap[it.renderedType!!] = it.typeParameterNames!!
|
typeParameterMap[it.renderedType!!] = it.renderedTypeParameters!!
|
||||||
}
|
}
|
||||||
|
|
||||||
if (declaration.getTypeReference() != null) {
|
if (declaration.getTypeReference() != null) {
|
||||||
typeCandidates[callableInfo.returnTypeInfo]!!.forEach {
|
typeCandidates[callableInfo.returnTypeInfo]!!.forEach {
|
||||||
typeParameterMap[it.renderedType!!] = it.typeParameterNames!!
|
typeParameterMap[it.renderedType!!] = it.renderedTypeParameters!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ((3, 3) is after "fun")
|
// ((3, 3) is after "fun")
|
||||||
@@ -618,6 +692,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
// file templates
|
// file templates
|
||||||
if (newDeclaration is JetNamedFunction) {
|
if (newDeclaration is JetNamedFunction) {
|
||||||
setupFunctionBody(newDeclaration)
|
setupFunctionBody(newDeclaration)
|
||||||
|
(config.originalExpression as? JetCallExpression)?.let {
|
||||||
|
setupCallTypeArguments(it, expression.currentTypeParameters)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// change short type names to fully qualified ones (to be shortened below)
|
// change short type names to fully qualified ones (to be shortened below)
|
||||||
|
|||||||
+17
-7
@@ -14,6 +14,7 @@ import org.jetbrains.jet.lang.types.TypeUtils
|
|||||||
import org.jetbrains.jet.lang.types.ErrorUtils
|
import org.jetbrains.jet.lang.types.ErrorUtils
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||||
import org.jetbrains.jet.lang.psi.JetElement
|
import org.jetbrains.jet.lang.psi.JetElement
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a concrete type or a set of types yet to be inferred from an expression.
|
* Represents a concrete type or a set of types yet to be inferred from an expression.
|
||||||
@@ -32,6 +33,11 @@ abstract class TypeInfo(val variance: Variance) {
|
|||||||
expression.guessTypes(builder.currentFileContext, builder.currentFileModule).flatMap { it.getPossibleSupertypes(variance) }
|
expression.guessTypes(builder.currentFileContext, builder.currentFileModule).flatMap { it.getPossibleSupertypes(variance) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ByTypeReference(val typeReference: JetTypeReference, variance: Variance): TypeInfo(variance) {
|
||||||
|
override fun getPossibleTypes(builder: CallableBuilder): List<JetType> =
|
||||||
|
builder.currentFileContext[BindingContext.TYPE, typeReference].getPossibleSupertypes(variance)
|
||||||
|
}
|
||||||
|
|
||||||
class ByType(val theType: JetType, variance: Variance, val keepUnsubstituted: Boolean = false): TypeInfo(variance) {
|
class ByType(val theType: JetType, variance: Variance, val keepUnsubstituted: Boolean = false): TypeInfo(variance) {
|
||||||
override fun getPossibleTypes(builder: CallableBuilder): List<JetType> =
|
override fun getPossibleTypes(builder: CallableBuilder): List<JetType> =
|
||||||
theType.getPossibleSupertypes(variance)
|
theType.getPossibleSupertypes(variance)
|
||||||
@@ -45,8 +51,8 @@ abstract class TypeInfo(val variance: Variance) {
|
|||||||
open val possibleNamesFromExpression: Array<String> get() = ArrayUtil.EMPTY_STRING_ARRAY
|
open val possibleNamesFromExpression: Array<String> get() = ArrayUtil.EMPTY_STRING_ARRAY
|
||||||
abstract fun getPossibleTypes(builder: CallableBuilder): List<JetType>
|
abstract fun getPossibleTypes(builder: CallableBuilder): List<JetType>
|
||||||
|
|
||||||
protected fun JetType.getPossibleSupertypes(variance: Variance): List<JetType> {
|
protected fun JetType?.getPossibleSupertypes(variance: Variance): List<JetType> {
|
||||||
if (ErrorUtils.containsErrorType(this)) return Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType())
|
if (this == null || ErrorUtils.containsErrorType(this)) return Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType())
|
||||||
val single = Collections.singletonList(this)
|
val single = Collections.singletonList(this)
|
||||||
return when (variance) {
|
return when (variance) {
|
||||||
Variance.IN_VARIANCE -> single + supertypes()
|
Variance.IN_VARIANCE -> single + supertypes()
|
||||||
@@ -56,6 +62,7 @@ abstract class TypeInfo(val variance: Variance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun TypeInfo(expressionOfType: JetExpression, variance: Variance): TypeInfo = TypeInfo.ByExpression(expressionOfType, variance)
|
fun TypeInfo(expressionOfType: JetExpression, variance: Variance): TypeInfo = TypeInfo.ByExpression(expressionOfType, variance)
|
||||||
|
fun TypeInfo(typeReference: JetTypeReference, variance: Variance): TypeInfo = TypeInfo.ByTypeReference(typeReference, variance)
|
||||||
fun TypeInfo(theType: JetType, variance: Variance): TypeInfo = TypeInfo.ByType(theType, variance)
|
fun TypeInfo(theType: JetType, variance: Variance): TypeInfo = TypeInfo.ByType(theType, variance)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,7 +82,8 @@ abstract class CallableInfo (
|
|||||||
val name: String,
|
val name: String,
|
||||||
val receiverTypeInfo: TypeInfo,
|
val receiverTypeInfo: TypeInfo,
|
||||||
val returnTypeInfo: TypeInfo,
|
val returnTypeInfo: TypeInfo,
|
||||||
val possibleContainers: List<JetElement>
|
val possibleContainers: List<JetElement>,
|
||||||
|
val typeParameterInfos: List<TypeInfo>
|
||||||
) {
|
) {
|
||||||
abstract val kind: CallableKind
|
abstract val kind: CallableKind
|
||||||
abstract val parameterInfos: List<ParameterInfo>
|
abstract val parameterInfos: List<ParameterInfo>
|
||||||
@@ -85,8 +93,9 @@ class FunctionInfo(name: String,
|
|||||||
receiverTypeInfo: TypeInfo,
|
receiverTypeInfo: TypeInfo,
|
||||||
returnTypeInfo: TypeInfo,
|
returnTypeInfo: TypeInfo,
|
||||||
possibleContainers: List<JetElement> = Collections.emptyList(),
|
possibleContainers: List<JetElement> = Collections.emptyList(),
|
||||||
override val parameterInfos: List<ParameterInfo> = Collections.emptyList()
|
override val parameterInfos: List<ParameterInfo> = Collections.emptyList(),
|
||||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers) {
|
typeParameterInfos: List<TypeInfo> = Collections.emptyList()
|
||||||
|
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos) {
|
||||||
override val kind: CallableKind get() = CallableKind.FUNCTION
|
override val kind: CallableKind get() = CallableKind.FUNCTION
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,8 +103,9 @@ class PropertyInfo(name: String,
|
|||||||
receiverTypeInfo: TypeInfo,
|
receiverTypeInfo: TypeInfo,
|
||||||
returnTypeInfo: TypeInfo,
|
returnTypeInfo: TypeInfo,
|
||||||
val writable: Boolean,
|
val writable: Boolean,
|
||||||
possibleContainers: List<JetElement> = Collections.emptyList()
|
possibleContainers: List<JetElement> = Collections.emptyList(),
|
||||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers) {
|
typeParameterInfos: List<TypeInfo> = Collections.emptyList()
|
||||||
|
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos) {
|
||||||
override val kind: CallableKind get() = CallableKind.PROPERTY
|
override val kind: CallableKind get() = CallableKind.PROPERTY
|
||||||
override val parameterInfos: List<ParameterInfo> get() = Collections.emptyList()
|
override val parameterInfos: List<ParameterInfo> get() = Collections.emptyList()
|
||||||
}
|
}
|
||||||
+17
-7
@@ -17,6 +17,8 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder
|
|||||||
import org.jetbrains.jet.lang.types.JetType
|
import org.jetbrains.jet.lang.types.JetType
|
||||||
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
|
import org.jetbrains.jet.lang.psi.JetCallableDeclaration
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
|
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special <code>Expression</code> for parameter names based on its type.
|
* Special <code>Expression</code> for parameter names based on its type.
|
||||||
@@ -97,8 +99,10 @@ private class TypeExpression(public val typeCandidates: List<TypeCandidate>) : E
|
|||||||
/**
|
/**
|
||||||
* A sort-of dummy <code>Expression</code> for parameter lists, to allow us to update the parameter list as the user makes selections.
|
* A sort-of dummy <code>Expression</code> for parameter lists, to allow us to update the parameter list as the user makes selections.
|
||||||
*/
|
*/
|
||||||
private class TypeParameterListExpression(private val typeParameterNamesFromReceiverType: Array<String>,
|
private class TypeParameterListExpression(private val typeParameterNamesFromReceiverType: List<RenderedTypeParameter>,
|
||||||
private val parameterTypeToTypeParameterNamesMap: Map<String, Array<String>>) : Expression() {
|
private val parameterTypeToTypeParameterNamesMap: Map<String, List<RenderedTypeParameter>>) : Expression() {
|
||||||
|
public var currentTypeParameters: List<TypeParameterDescriptor> = Collections.emptyList()
|
||||||
|
private set
|
||||||
|
|
||||||
override fun calculateResult(context: ExpressionContext?): Result {
|
override fun calculateResult(context: ExpressionContext?): Result {
|
||||||
context!!
|
context!!
|
||||||
@@ -112,14 +116,14 @@ private class TypeParameterListExpression(private val typeParameterNamesFromRece
|
|||||||
val callable = PsiTreeUtil.getParentOfType(elementAt, javaClass<JetCallableDeclaration>()) ?: return TextResult("")
|
val callable = PsiTreeUtil.getParentOfType(elementAt, javaClass<JetCallableDeclaration>()) ?: return TextResult("")
|
||||||
val parameters = callable.getValueParameterList()?.getParameters() ?: Collections.emptyList<JetParameter>()
|
val parameters = callable.getValueParameterList()?.getParameters() ?: Collections.emptyList<JetParameter>()
|
||||||
|
|
||||||
val typeParameterNames = LinkedHashSet<String>()
|
val renderedTypeParameters = LinkedHashSet<RenderedTypeParameter>()
|
||||||
typeParameterNames.addAll(typeParameterNamesFromReceiverType)
|
renderedTypeParameters.addAll(typeParameterNamesFromReceiverType)
|
||||||
for (parameter in parameters) {
|
for (parameter in parameters) {
|
||||||
val parameterTypeRef = parameter.getTypeReference()
|
val parameterTypeRef = parameter.getTypeReference()
|
||||||
if (parameterTypeRef != null) {
|
if (parameterTypeRef != null) {
|
||||||
val typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap[parameterTypeRef.getText()]
|
val typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap[parameterTypeRef.getText()]
|
||||||
if (typeParameterNamesFromParameter != null) {
|
if (typeParameterNamesFromParameter != null) {
|
||||||
typeParameterNames.addAll(typeParameterNamesFromParameter)
|
renderedTypeParameters.addAll(typeParameterNamesFromParameter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,11 +131,17 @@ private class TypeParameterListExpression(private val typeParameterNamesFromRece
|
|||||||
if (returnTypeRef != null) {
|
if (returnTypeRef != null) {
|
||||||
val typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap[returnTypeRef.getText()]
|
val typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap[returnTypeRef.getText()]
|
||||||
if (typeParameterNamesFromReturnType != null) {
|
if (typeParameterNamesFromReturnType != null) {
|
||||||
typeParameterNames.addAll(typeParameterNamesFromReturnType)
|
renderedTypeParameters.addAll(typeParameterNamesFromReturnType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextResult(if (typeParameterNames.empty) "" else typeParameterNames.joinToString(", ", " <", ">"))
|
|
||||||
|
val sortedRenderedTypeParameters = renderedTypeParameters.sortBy { if (it.fake) it.typeParameter.getIndex() else -1}
|
||||||
|
currentTypeParameters = sortedRenderedTypeParameters.map { it.typeParameter }
|
||||||
|
|
||||||
|
return TextResult(
|
||||||
|
if (sortedRenderedTypeParameters.empty) "" else sortedRenderedTypeParameters.map { it.text }.joinToString(", ", " <", ">")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun calculateQuickResult(context: ExpressionContext?): Result = calculateResult(context)
|
override fun calculateQuickResult(context: ExpressionContext?): Result = calculateResult(context)
|
||||||
|
|||||||
+1
-1
@@ -59,7 +59,7 @@ public class CreateCallableFromUsageFix(
|
|||||||
// TODO: Support generation of Java class members
|
// TODO: Support generation of Java class members
|
||||||
val containers = receiverTypeCandidates
|
val containers = receiverTypeCandidates
|
||||||
.map { candidate ->
|
.map { candidate ->
|
||||||
val descriptor = DescriptorUtils.getClassDescriptorForType(candidate.theType)
|
val descriptor = candidate.theType.getConstructor().getDeclarationDescriptor()
|
||||||
(DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as? JetClassOrObject)?.let { candidate to it }
|
(DescriptorToDeclarationUtil.getDeclaration(file, descriptor) as? JetClassOrObject)?.let { candidate to it }
|
||||||
}
|
}
|
||||||
.filterNotNull()
|
.filterNotNull()
|
||||||
|
|||||||
+2
-1
@@ -84,8 +84,9 @@ object CreateFunctionOrPropertyFromCallActionFactory : JetSingleIntentionActionF
|
|||||||
it.getArgumentName()?.getReferenceExpression()?.getReferencedName()
|
it.getArgumentName()?.getReferenceExpression()?.getReferencedName()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val typeParameters = callExpr.getTypeArguments().map { TypeInfo(it.getTypeReference(), Variance.INVARIANT) }
|
||||||
val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE)
|
val returnType = TypeInfo(fullCallExpr, Variance.OUT_VARIANCE)
|
||||||
FunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters)
|
FunctionInfo(calleeExpr.getReferencedName(), receiverType, returnType, possibleContainers, parameters, typeParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetSimpleNameExpression -> {
|
is JetSimpleNameExpression -> {
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
fun <T1, T2> foo(arg: T1, arg1: T2): T1 {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
fun <T1> foo(i: Int, arg: T1): Int {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.foo<String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
fun <T1, T2> foo(arg: T1, arg1: T2): T1 {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E, T, T1> List<E>.foo(arg: T, arg1: T1): T {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.foo<T, Int>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E, T> List<E>.foo(arg: T, s: String): T {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <E, T, T1> List<E>.foo(arg: T, arg1: T1): T {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return foo<String, Int>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, T1> foo(arg: T1, arg1: T): T1 {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return foo<String, Int>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, T1> foo(arg: T1, arg1: T): T1 {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return foo<String, Int>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, T1> foo(arg: T1, arg1: T): T1 {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return foo<Int>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> foo(arg: T, s: String): T {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.<caret>foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.<caret>foo<String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class B<T>(val t: T) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return b.<caret>foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.<caret>foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.<caret>foo<Int>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
class A<T>(val items: List<T>) {
|
||||||
|
fun test(): Int {
|
||||||
|
return items.<caret>foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return <caret>foo<String, Int>(2, "2")
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return <caret>foo<String, Int, Boolean>(2, "2")
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return <caret>foo<kotlin.String, Int>(2, "2")
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create function 'foo' from usage" "true"
|
||||||
|
|
||||||
|
fun test(): Int {
|
||||||
|
return <caret>foo<Int>(2, "2")
|
||||||
|
}
|
||||||
@@ -239,6 +239,7 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@InnerTestClasses({})
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Call extends AbstractQuickFixMultiFileTest {
|
public static class Call extends AbstractQuickFixMultiFileTest {
|
||||||
public void testAllFilesPresentInCall() throws Exception {
|
public void testAllFilesPresentInCall() throws Exception {
|
||||||
@@ -250,6 +251,7 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/funOnJavaType.before.Main.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/funOnJavaType.before.Main.kt");
|
||||||
doTestWithExtraFile(fileName);
|
doTestWithExtraFile(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -730,6 +730,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@InnerTestClasses({Call.TypeArguments.class})
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public static class Call extends AbstractQuickFixTest {
|
public static class Call extends AbstractQuickFixTest {
|
||||||
public void testAllFilesPresentInCall() throws Exception {
|
public void testAllFilesPresentInCall() throws Exception {
|
||||||
@@ -933,6 +934,75 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeUnresolvedSupertype.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeUnresolvedSupertype.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class TypeArguments extends AbstractQuickFixTest {
|
||||||
|
public void testAllFilesPresentInTypeArguments() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments"), Pattern.compile("^before(\\w+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeClassMember.kt")
|
||||||
|
public void testClassMember() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMember.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeClassMemberPartialSubstitution.kt")
|
||||||
|
public void testClassMemberPartialSubstitution() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMemberPartialSubstitution.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeClassMemberWithReceiverArg.kt")
|
||||||
|
public void testClassMemberWithReceiverArg() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeClassMemberWithReceiverArg.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeExtension.kt")
|
||||||
|
public void testExtension() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeExtension.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeExtensionPartialSubstitution.kt")
|
||||||
|
public void testExtensionPartialSubstitution() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeExtensionPartialSubstitution.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeExtensionWithReceiverArg.kt")
|
||||||
|
public void testExtensionWithReceiverArg() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeExtensionWithReceiverArg.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeNoReceiver.kt")
|
||||||
|
public void testNoReceiver() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeNoReceiver.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeNoReceiverExtraArgs.kt")
|
||||||
|
public void testNoReceiverExtraArgs() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeNoReceiverExtraArgs.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeNoReceiverLongName.kt")
|
||||||
|
public void testNoReceiverLongName() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeNoReceiverLongName.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeNoReceiverPartialSubstitution.kt")
|
||||||
|
public void testNoReceiverPartialSubstitution() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/typeArguments/beforeNoReceiverPartialSubstitution.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/component")
|
@TestMetadata("idea/testData/quickfix/createFromUsage/createFunction/component")
|
||||||
|
|||||||
Reference in New Issue
Block a user