Supported case when explicit function type is used
This commit is contained in:
+7
-5
@@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||
import java.util.*
|
||||
|
||||
@@ -49,13 +51,14 @@ class ReplacementBuilder(
|
||||
fun buildReplacementExpression(
|
||||
expression: KtExpression,
|
||||
resolutionScope: LexicalScope,
|
||||
expectedType: KotlinType = TypeUtils.NO_EXPECTED_TYPE,
|
||||
importFqNames: Collection<FqName> = emptyList(),
|
||||
copyExpression: Boolean = true
|
||||
): ReplacementExpression {
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var expression = if (copyExpression) expression.copied() else expression
|
||||
|
||||
var bindingContext = analyzeInContext(expression, resolutionScope)
|
||||
var bindingContext = analyzeInContext(expression, resolutionScope, expectedType)
|
||||
|
||||
val typeArgsToAdd = ArrayList<Pair<KtCallExpression, KtTypeArgumentList>>()
|
||||
expression.forEachDescendantOfType<KtCallExpression> {
|
||||
@@ -70,7 +73,7 @@ class ReplacementBuilder(
|
||||
}
|
||||
|
||||
// reanalyze expression - new usages of type parameters may be added
|
||||
bindingContext = analyzeInContext(expression, resolutionScope)
|
||||
bindingContext = analyzeInContext(expression, resolutionScope, expectedType)
|
||||
}
|
||||
|
||||
val receiversToAdd = ArrayList<Pair<KtExpression, KtExpression>>()
|
||||
@@ -122,8 +125,7 @@ class ReplacementBuilder(
|
||||
return ReplacementExpression(expression, resultImportFqNames)
|
||||
}
|
||||
|
||||
//TODO: there can be expected type and maybe something else
|
||||
private fun analyzeInContext(expression: KtExpression, scope: LexicalScope): BindingContext {
|
||||
private fun analyzeInContext(expression: KtExpression, scope: LexicalScope, expectedType: KotlinType): BindingContext {
|
||||
val module = scope.ownerDescriptor.module
|
||||
val frontendService = if (module.builtIns.builtInsModule == module) {
|
||||
// TODO: doubtful place, do we require this module or not? Built-ins module doesn't have some necessary components...
|
||||
@@ -132,6 +134,6 @@ class ReplacementBuilder(
|
||||
else {
|
||||
resolutionFacade.getFrontendService(module, ExpressionTypingServices::class.java)
|
||||
}
|
||||
return expression.analyzeInContext(scope, expressionTypingServices = frontendService)
|
||||
return expression.analyzeInContext(scope, expectedType = expectedType, expressionTypingServices = frontendService)
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -76,7 +76,7 @@ object ReplaceWithAnnotationAnalyzer {
|
||||
listOf(explicitImportsScope) + defaultImportsScopes) ?: return null
|
||||
|
||||
return ReplacementBuilder(symbolDescriptor, resolutionFacade)
|
||||
.buildReplacementExpression(expression, scope, importFqNames(annotation), copyExpression = false)
|
||||
.buildReplacementExpression(expression, scope, importFqNames = importFqNames(annotation), copyExpression = false)
|
||||
}
|
||||
|
||||
fun analyzeClassReplacement(
|
||||
|
||||
+6
-1
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.replacement.ReplacementBuilder
|
||||
import org.jetbrains.kotlin.idea.replacement.replaceUsagesInWholeProject
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
class KotlinInlineFunctionHandler: InlineActionHandler() {
|
||||
override fun isEnabledForLanguage(language: Language) = language == KotlinLanguage.INSTANCE
|
||||
@@ -48,8 +49,12 @@ class KotlinInlineFunctionHandler: InlineActionHandler() {
|
||||
val descriptor = element.resolveToDescriptor() as SimpleFunctionDescriptor
|
||||
|
||||
val bodyExpression = element.bodyExpression!!
|
||||
val expectedType = if (element.hasDeclaredReturnType())
|
||||
descriptor.returnType ?: TypeUtils.NO_EXPECTED_TYPE
|
||||
else
|
||||
TypeUtils.NO_EXPECTED_TYPE
|
||||
val replacement = ReplacementBuilder(descriptor, element.getResolutionFacade())
|
||||
.buildReplacementExpression(bodyExpression, bodyExpression.getResolutionScope())
|
||||
.buildReplacementExpression(bodyExpression, bodyExpression.getResolutionScope(), expectedType)
|
||||
|
||||
val commandName = RefactoringBundle.message("inline.command", element.name)
|
||||
CallableUsageReplacementStrategy(replacement)
|
||||
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
fun <caret>f(): List<String> = emptyList()
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val list1 = f()
|
||||
val list2: List<String> = f()
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fun main(args: Array<String>) {
|
||||
val list1 = emptyList<String>()
|
||||
val list2: List<String> = emptyList()
|
||||
}
|
||||
@@ -69,6 +69,12 @@ public class InlineTestGenerated extends AbstractInlineTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExplicitReturnType.kt")
|
||||
public void testExplicitReturnType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/ExplicitReturnType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("FromUsage.kt")
|
||||
public void testFromUsage() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/inline/function/expressionBody/FromUsage.kt");
|
||||
|
||||
Reference in New Issue
Block a user