Extract Function: Infer parameter type candidates

#KT-4940 Fixed
This commit is contained in:
Alexey Sedunov
2014-06-20 17:33:57 +04:00
parent 96557e6d3f
commit ca16f4231f
143 changed files with 759 additions and 78 deletions
@@ -376,9 +376,13 @@ public class TypeUtils {
} }
private static void collectImmediateSupertypes(@NotNull JetType type, @NotNull Collection<JetType> result) { private static void collectImmediateSupertypes(@NotNull JetType type, @NotNull Collection<JetType> result) {
boolean isNullable = type.isNullable();
TypeSubstitutor substitutor = TypeSubstitutor.create(type); TypeSubstitutor substitutor = TypeSubstitutor.create(type);
for (JetType supertype : type.getConstructor().getSupertypes()) { for (JetType supertype : type.getConstructor().getSupertypes()) {
result.add(substitutor.substitute(supertype, Variance.INVARIANT)); JetType substitutedType = substitutor.substitute(supertype, Variance.INVARIANT);
if (substitutedType != null) {
result.add(makeNullableIfNeeded(substitutedType, isNullable));
}
} }
} }
@@ -59,7 +59,8 @@ public class ExtractKotlinFunctionHandler(public val allContainersEnabled: Boole
editor: Editor, editor: Editor,
file: JetFile, file: JetFile,
elements: List<PsiElement>, elements: List<PsiElement>,
targetSibling: PsiElement targetSibling: PsiElement,
preprocessor: ((ExtractionDescriptor) -> Unit)? = null
) { ) {
val project = file.getProject() val project = file.getProject()
@@ -83,7 +84,7 @@ public class ExtractKotlinFunctionHandler(public val allContainersEnabled: Boole
dialog.getCurrentDescriptor() dialog.getCurrentDescriptor()
} }
preprocessor?.invoke(descriptor)
project.executeWriteCommand(EXTRACT_FUNCTION) { descriptor.generateFunction() } project.executeWriteCommand(EXTRACT_FUNCTION) { descriptor.generateFunction() }
} }
@@ -31,19 +31,21 @@ import org.jetbrains.jet.lang.psi.psiUtil.replaced
import org.jetbrains.jet.lang.psi.JetQualifiedExpression import org.jetbrains.jet.lang.psi.JetQualifiedExpression
import org.jetbrains.jet.lang.psi.JetTypeParameter import org.jetbrains.jet.lang.psi.JetTypeParameter
import org.jetbrains.jet.lang.psi.JetTypeConstraint import org.jetbrains.jet.lang.psi.JetTypeConstraint
import kotlin.properties.Delegates
import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.Status import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.Status
import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle import org.jetbrains.jet.plugin.refactoring.JetRefactoringBundle
import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.ErrorMessage import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.ErrorMessage
data class Parameter( trait Parameter {
val argumentText: String, val argumentText: String
val name: String, val name: String
var mirrorVarName: String?, val mirrorVarName: String?
val parameterType: JetType, val parameterType: JetType
val receiverCandidate: Boolean val parameterTypeCandidates: List<JetType>
) { val receiverCandidate: Boolean
val nameForRef: String get() = mirrorVarName ?: name val nameForRef: String get() = mirrorVarName ?: name
fun copy(name: String): Parameter
} }
data class TypeParameter( data class TypeParameter(
@@ -38,7 +38,6 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory.FunctionBuilder
import org.jetbrains.jet.plugin.refactoring.JetNameValidatorImpl import org.jetbrains.jet.plugin.refactoring.JetNameValidatorImpl
import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil
import org.jetbrains.jet.plugin.imports.canBeReferencedViaImport import org.jetbrains.jet.plugin.imports.canBeReferencedViaImport
import org.jetbrains.jet.lang.types.checker.JetTypeChecker
import org.jetbrains.jet.lang.resolve.DescriptorUtils import org.jetbrains.jet.lang.resolve.DescriptorUtils
import com.intellij.psi.PsiNamedElement import com.intellij.psi.PsiNamedElement
import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor import org.jetbrains.jet.lang.descriptors.impl.LocalVariableDescriptor
@@ -56,14 +55,7 @@ import org.jetbrains.jet.lang.diagnostics.Errors
import org.jetbrains.jet.lang.psi.psiUtil.replaced import org.jetbrains.jet.lang.psi.psiUtil.replaced
import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.Status import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.Status
import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.ErrorMessage import org.jetbrains.jet.plugin.refactoring.extractFunction.AnalysisResult.ErrorMessage
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.*
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction import org.jetbrains.jet.lang.cfg.pseudocode.instructions.special.LocalFunctionDeclarationInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.WriteValueInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.Instruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.CallInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.JetElementInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.OperationInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.ReadValueInstruction
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.* import org.jetbrains.jet.lang.cfg.pseudocode.instructions.*
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.* import org.jetbrains.jet.lang.cfg.pseudocode.instructions.eval.*
import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.* import org.jetbrains.jet.lang.cfg.pseudocode.instructions.jumps.*
@@ -72,6 +64,7 @@ import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.traverse
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getTargetFunctionDescriptor import org.jetbrains.jet.lang.resolve.bindingContextUtil.getTargetFunctionDescriptor
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.jet.lang.resolve.OverridingUtil
private val DEFAULT_FUNCTION_NAME = "myFun" private val DEFAULT_FUNCTION_NAME = "myFun"
private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType() private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType()
@@ -325,13 +318,57 @@ private fun JetType.processTypeIfExtractable(
} }
} }
private fun ExtractionData.inferParametersInfo(commonParent: PsiElement, private class MutableParameter(
localInstructions: List<Instruction>, override val argumentText: String,
bindingContext: BindingContext, override val name: String,
replacementMap: MutableMap<Int, Replacement>, override val mirrorVarName: String?,
parameters: MutableSet<Parameter>, override val receiverCandidate: Boolean
typeParameters: MutableSet<TypeParameter>, ): Parameter {
nonDenotableTypes: MutableSet<JetType>): ErrorMessage? { // All modifications happen in the same thread
private var writable: Boolean = true
private val defaultTypes = HashSet<JetType>()
private val typePredicates = HashSet<TypePredicate>()
fun addDefaultType(jetType: JetType) {
assert(writable, "Can't add type to non-writable parameter $name")
defaultTypes.add(jetType)
}
fun addTypePredicate(predicate: TypePredicate) {
assert(writable, "Can't add type predicate to non-writable parameter $name")
typePredicates.add(predicate)
}
override val parameterTypeCandidates: List<JetType> by Delegates.lazy {
writable = false
listOf(parameterType) + TypeUtils.getAllSupertypes(parameterType).filter(and(typePredicates))
}
override val parameterType: JetType by Delegates.lazy {
writable = false
CommonSupertypes.commonSupertype(defaultTypes)
}
override fun copy(name: String): Parameter = DelegatingParameter(this, name)
}
private class DelegatingParameter(
val original: Parameter,
override val name: String
): Parameter by original {
override fun copy(name: String): Parameter = DelegatingParameter(original, name)
}
private fun ExtractionData.inferParametersInfo(
commonParent: PsiElement,
pseudocode: Pseudocode,
localInstructions: List<Instruction>,
bindingContext: BindingContext,
replacementMap: MutableMap<Int, Replacement>,
parameters: MutableSet<Parameter>,
typeParameters: MutableSet<TypeParameter>,
nonDenotableTypes: MutableSet<JetType>
): ErrorMessage? {
val varNameValidator = JetNameValidatorImpl( val varNameValidator = JetNameValidatorImpl(
commonParent.getParentByType(javaClass<JetExpression>()), commonParent.getParentByType(javaClass<JetExpression>()),
originalElements.first, originalElements.first,
@@ -339,7 +376,9 @@ private fun ExtractionData.inferParametersInfo(commonParent: PsiElement,
) )
val modifiedVarDescriptors = localInstructions.getModifiedVarDescriptors(bindingContext) val modifiedVarDescriptors = localInstructions.getModifiedVarDescriptors(bindingContext)
val extractedDescriptorToParameter = HashMap<DeclarationDescriptor, Parameter>() val extractedDescriptorToParameter = HashMap<DeclarationDescriptor, MutableParameter>()
val valueUsageMap = pseudocode.collectValueUsages()
for (refInfo in getBrokenReferencesInfo(createTemporaryCodeBlock())) { for (refInfo in getBrokenReferencesInfo(createTemporaryCodeBlock())) {
val (originalRef, originalDeclaration, originalDescriptor, resolvedCall) = refInfo.resolveResult val (originalRef, originalDeclaration, originalDescriptor, resolvedCall) = refInfo.resolveResult
@@ -397,57 +436,40 @@ private fun ExtractionData.inferParametersInfo(commonParent: PsiElement,
if (extractParameter) { if (extractParameter) {
val parameterType = when { val parameterType = when {
receiver.exists() -> receiver.getType() receiver.exists() -> receiver.getType()
else -> bindingContext[BindingContext.EXPRESSION_TYPE, originalRef] ?: DEFAULT_PARAMETER_TYPE else -> bindingContext[BindingContext.AUTOCAST, originalRef]
?: bindingContext[BindingContext.EXPRESSION_TYPE, originalRef]
?: DEFAULT_PARAMETER_TYPE
} }
if (!parameterType.processTypeIfExtractable(bindingContext, typeParameters, nonDenotableTypes)) continue if (!parameterType.processTypeIfExtractable(bindingContext, typeParameters, nonDenotableTypes)) continue
val existingParameter = extractedDescriptorToParameter[descriptorToExtract] val parameterTypePredicate =
val parameter: Parameter = pseudocode.getElementValue(originalRef)?.let { getExpectedTypePredicate(it, valueUsageMap, bindingContext) } ?: AllTypes
if (existingParameter != null) {
if (!JetTypeChecker.INSTANCE.equalTypes(existingParameter.parameterType, parameterType)) {
val newParameter = existingParameter.copy(
parameterType = CommonSupertypes.commonSupertype(listOf(existingParameter.parameterType, parameterType))
)
extractedDescriptorToParameter[descriptorToExtract] = newParameter val parameter = extractedDescriptorToParameter.getOrPut(descriptorToExtract) {
val parameterName =
for ((offset, replacement) in replacementMap) { if (extractThis) {
if (replacement is ParameterReplacement && replacement.parameter == existingParameter) { JetNameSuggester.suggestNames(parameterType, varNameValidator, null).first()
replacementMap[offset] = replacement.copy(newParameter)
}
}
newParameter
} }
else existingParameter else originalDeclaration.getName()!!
}
else {
val parameterName =
if (extractThis) {
JetNameSuggester.suggestNames(parameterType, varNameValidator, null).first()
}
else originalDeclaration.getName()!!
val mirrorVarName = if (descriptorToExtract in modifiedVarDescriptors) val mirrorVarName =
varNameValidator.validateName(parameterName)!! if (descriptorToExtract in modifiedVarDescriptors) varNameValidator.validateName(parameterName)!! else null
else null
val argumentText = val argumentText =
if (hasThisReceiver && extractThis) if (hasThisReceiver && extractThis)
"this@${parameterType.getConstructor().getDeclarationDescriptor()!!.getName().asString()}" "this@${parameterType.getConstructor().getDeclarationDescriptor()!!.getName().asString()}"
else else
(thisExpr ?: ref).getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = ${getCodeFragmentText()}") (thisExpr ?: ref).getText() ?: throw AssertionError("'this' reference shouldn't be empty: code fragment = ${getCodeFragmentText()}")
val parameter = Parameter(argumentText, parameterName, mirrorVarName, parameterType, extractThis) MutableParameter(argumentText, parameterName, mirrorVarName, extractThis)
}
extractedDescriptorToParameter[descriptorToExtract] = parameter parameter.addDefaultType(parameterType)
parameter.addTypePredicate(parameterTypePredicate)
parameter
}
replacementMap[refInfo.offsetInBody] = replacementMap[refInfo.offsetInBody] =
if (hasThisReceiver && extractThis) AddPrefixReplacement(parameter) else RenameReplacement(parameter) if (hasThisReceiver && extractThis) AddPrefixReplacement(parameter) else RenameReplacement(parameter)
} }
} }
} }
@@ -543,7 +565,9 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
val parameters = HashSet<Parameter>() val parameters = HashSet<Parameter>()
val typeParameters = HashSet<TypeParameter>() val typeParameters = HashSet<TypeParameter>()
val nonDenotableTypes = HashSet<JetType>() val nonDenotableTypes = HashSet<JetType>()
val parameterError = inferParametersInfo(commonParent, localInstructions, bindingContext, replacementMap, parameters, typeParameters, nonDenotableTypes) val parameterError = inferParametersInfo(
commonParent, pseudocode, localInstructions, bindingContext, replacementMap, parameters, typeParameters, nonDenotableTypes
)
if (parameterError != null) { if (parameterError != null) {
return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(parameterError)) return AnalysisResult(null, Status.CRITICAL_ERROR, listOf(parameterError))
} }
@@ -624,7 +648,7 @@ fun ExtractionDescriptor.validate(): ExtractionDescriptorWithConflicts {
if (diagnostics.any { it.getFactory() == Errors.UNRESOLVED_REFERENCE } if (diagnostics.any { it.getFactory() == Errors.UNRESOLVED_REFERENCE }
|| (currentDescriptor != null || (currentDescriptor != null
&& !ErrorUtils.isError(currentDescriptor) && !ErrorUtils.isError(currentDescriptor)
&& !compareDescriptors(currentDescriptor, resolveResult.descriptor))) { && !comparePossiblyOverridingDescriptors(currentDescriptor, resolveResult.descriptor))) {
conflicts.putValue( conflicts.putValue(
currentRefExpr, currentRefExpr,
JetRefactoringBundle.message( JetRefactoringBundle.message(
@@ -649,6 +673,15 @@ fun ExtractionDescriptor.validate(): ExtractionDescriptorWithConflicts {
return ExtractionDescriptorWithConflicts(this, conflicts) return ExtractionDescriptorWithConflicts(this, conflicts)
} }
private fun comparePossiblyOverridingDescriptors(currentDescriptor: DeclarationDescriptor?, originalDescriptor: DeclarationDescriptor?): Boolean {
if (compareDescriptors(currentDescriptor, originalDescriptor)) return true
if (originalDescriptor is CallableDescriptor) {
if (!OverridingUtil.traverseOverridenDescriptors(originalDescriptor) { !compareDescriptors(currentDescriptor, it) }) return true
}
return false
}
fun ExtractionDescriptor.getFunctionText( fun ExtractionDescriptor.getFunctionText(
withBody: Boolean = true, withBody: Boolean = true,
descriptorRenderer: DescriptorRenderer = DescriptorRenderer.FQ_NAMES_IN_TYPES descriptorRenderer: DescriptorRenderer = DescriptorRenderer.FQ_NAMES_IN_TYPES
@@ -70,17 +70,11 @@ public class KotlinParameterTablePanel extends JPanel {
} }
public String getTypeAsString() { public String getTypeAsString() {
return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getOriginalParameter().getParameterType()); return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getOriginalParameter().getParameterTypeCandidates().get(0));
} }
public Parameter toParameter() { public Parameter toParameter() {
return new Parameter( return originalParameter.copy(name);
originalParameter.getArgumentText(),
name,
originalParameter.getMirrorVarName(),
originalParameter.getParameterType(),
originalParameter.getReceiverCandidate()
);
} }
} }
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
<selection>// test <selection>// test
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
if (b(a)) return a if (b(a)) return a
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
<selection>/* <selection>/*
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
if (b(a)) return a if (b(a)) return a
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
<selection>println(a) <selection>println(a)
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
if (b(a)) return a if (b(a)) return a
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int, Number, Comparable<Int>, Any
fun bar(a: Int): Int { fun bar(a: Int): Int {
println(a) println(a)
return a + 10 return a + 10
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,2 +1,4 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int, b: Int): Int = <selection>a + b</selection> fun foo(a: Int, b: Int): Int = <selection>a + b</selection>
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int, b: Int): Int = i(a, b) fun foo(a: Int, b: Int): Int = i(a, b)
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int, Comparable<Int>
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int) { fun foo(a: Int) {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,4 @@
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
var b: Int = 1 var b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
// SIBLING: // SIBLING:
fun foo(a: Int): Int { fun foo(a: Int): Int {
val b: Int = 1 val b: Int = 1
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
class A { class A {
class B { class B {
fun foo(a: Int, b: Int): Int { fun foo(a: Int, b: Int): Int {
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
class A { class A {
class B { class B {
fun foo(a: Int, b: Int): Int { fun foo(a: Int, b: Int): Int {
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
fun foo(a: Int, b: Int): Int { fun foo(a: Int, b: Int): Int {
return <selection>a + b - 1</selection> return <selection>a + b - 1</selection>
} }
@@ -1,3 +1,5 @@
// PARAM_TYPES: kotlin.Int
// PARAM_TYPES: kotlin.Int
fun foo(a: Int, b: Int): Int { fun foo(a: Int, b: Int): Int {
return i(a, b) return i(a, b)
} }
@@ -0,0 +1,14 @@
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, kotlin.Any
// PARAM_TYPES: X<kotlin.Any>
class X<T> {
fun add(t: T) {
}
}
// SIBLING:
fun foo(s: String?, x: X<Any>) {
when {
s != null -> <selection>x.add(s)</selection>
}
}
@@ -0,0 +1,18 @@
// PARAM_TYPES: kotlin.String, Comparable<String>, CharSequence, kotlin.Any
// PARAM_TYPES: X<kotlin.Any>
class X<T> {
fun add(t: T) {
}
}
// SIBLING:
fun foo(s: String?, x: X<Any>) {
when {
s != null -> unit(s, x)
}
}
fun unit(s: String, x: X<Any>) {
x.add(s)
}
@@ -0,0 +1,14 @@
// PARAM_TYPES: kotlin.String?, kotlin.Comparable<String>?, kotlin.CharSequence?, kotlin.Any?
// PARAM_TYPES: X<kotlin.Any?>
class X<T> {
fun add(t: T) {
}
}
// SIBLING:
fun foo(s: String?, x: X<Any?>) {
when {
s != null -> <selection>x.add(s)</selection>
}
}
@@ -0,0 +1,18 @@
// PARAM_TYPES: kotlin.String?, kotlin.Comparable<String>?, kotlin.CharSequence?, kotlin.Any?
// PARAM_TYPES: X<kotlin.Any?>
class X<T> {
fun add(t: T) {
}
}
// SIBLING:
fun foo(s: String?, x: X<Any?>) {
when {
s != null -> unit(s, x)
}
}
fun unit(s: String?, x: X<Any?>) {
x.add(s)
}
@@ -0,0 +1,35 @@
//PARAM_TYPES: C, AImpl, A
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
<selection>c.doA()</selection>
c.doB()
c.doC()
}
@@ -0,0 +1,39 @@
//PARAM_TYPES: C, AImpl, A
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
unit(c)
c.doB()
c.doC()
}
fun unit(c: C) {
c.doA()
}
@@ -0,0 +1,35 @@
//PARAM_TYPES: C, B
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
c.doA()
<selection>c.doB()</selection>
c.doC()
}
@@ -0,0 +1,39 @@
//PARAM_TYPES: C, B
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
c.doA()
unit(c)
c.doC()
}
fun unit(c: C) {
c.doB()
}
@@ -0,0 +1,35 @@
//PARAM_TYPES: C
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
c.doA()
c.doB()
<selection>c.doC()</selection>
}
@@ -0,0 +1,39 @@
//PARAM_TYPES: C
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
c.doA()
c.doB()
unit(c)
}
fun unit(c: C) {
c.doC()
}
@@ -0,0 +1,35 @@
//PARAM_TYPES: C
trait A {
fun doA()
}
open class AImpl: A {
override fun doA() {
throw UnsupportedOperationException()
}
}
trait B {
fun doB()
}
class C: AImpl(), B {
override fun doA() {
throw UnsupportedOperationException()
}
override fun doB() {
throw UnsupportedOperationException()
}
fun doC() {
throw UnsupportedOperationException()
}
}
// SIBLING:
fun foo(c: C) {
<selection>c.doA()
c.doB()</selection>
c.doC()
}

Some files were not shown because too many files have changed in this diff Show More