Create from Usage: Support accessors for local delegated properties
#KT-19730 Fixed
This commit is contained in:
+15
-6
@@ -41,9 +41,8 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
@@ -138,13 +137,19 @@ sealed class CallablePlacement {
|
||||
class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
private var finished: Boolean = false
|
||||
|
||||
val currentFileContext: BindingContext
|
||||
val currentFileContext = config.currentFile.analyzeWithContent()
|
||||
|
||||
private lateinit var _currentFileModule: ModuleDescriptor
|
||||
val currentFileModule: ModuleDescriptor
|
||||
get() {
|
||||
if (!_currentFileModule.isValid) {
|
||||
updateCurrentModule()
|
||||
}
|
||||
return _currentFileModule
|
||||
}
|
||||
|
||||
init {
|
||||
val result = config.currentFile.analyzeFullyAndGetResult()
|
||||
currentFileContext = result.bindingContext
|
||||
currentFileModule = result.moduleDescriptor
|
||||
updateCurrentModule()
|
||||
}
|
||||
|
||||
val pseudocode: Pseudocode? by lazy { config.originalElement.getContainingPseudocode(currentFileContext) }
|
||||
@@ -155,6 +160,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
private val elementsToShorten = ArrayList<KtElement>()
|
||||
|
||||
private fun updateCurrentModule() {
|
||||
_currentFileModule = config.currentFile.analyzeFullyAndGetResult().moduleDescriptor
|
||||
}
|
||||
|
||||
fun computeTypeCandidates(typeInfo: TypeInfo): List<TypeCandidate> =
|
||||
typeCandidates.getOrPut(typeInfo) { typeInfo.getPossibleTypes(this).map { TypeCandidate(it) } }
|
||||
|
||||
|
||||
+12
-4
@@ -18,10 +18,13 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable
|
||||
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.CallableInfo
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.FunctionInfo
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.ParameterInfo
|
||||
@@ -45,13 +48,18 @@ object CreatePropertyDelegateAccessorsActionFactory : CreateCallableMemberFromUs
|
||||
override fun extractFixData(element: KtExpression, diagnostic: Diagnostic): List<CallableInfo> {
|
||||
val context = element.analyze()
|
||||
|
||||
fun isApplicableForAccessor(accessor: PropertyAccessorDescriptor?): Boolean =
|
||||
fun isApplicableForAccessor(accessor: VariableAccessorDescriptor?): Boolean =
|
||||
accessor != null && context[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, accessor] == null
|
||||
|
||||
val property = element.getNonStrictParentOfType<KtProperty>() ?: return emptyList()
|
||||
val propertyDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? PropertyDescriptor
|
||||
val propertyDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, property] as? VariableDescriptorWithAccessors
|
||||
?: return emptyList()
|
||||
|
||||
if (propertyDescriptor is LocalVariableDescriptor
|
||||
&& !element.languageVersionSettings.supportsFeature(LanguageFeature.LocalDelegatedProperties)) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
val propertyReceiver = propertyDescriptor.extensionReceiverParameter ?: propertyDescriptor.dispatchReceiverParameter
|
||||
val propertyType = propertyDescriptor.type
|
||||
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Create extension function 'String.getValue'" "true"
|
||||
fun x(parameters: String) {
|
||||
val n by <caret>parameters
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
// "Create extension function 'String.getValue'" "true"
|
||||
fun x(parameters: String) {
|
||||
val n by parameters
|
||||
}
|
||||
|
||||
private operator fun String.getValue(nothing: Nothing?, property: KProperty<*>): Any {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// "Create extension function 'String.getValue', function 'String.setValue'" "true"
|
||||
fun x(parameters: String) {
|
||||
var n by <caret>parameters
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
// "Create extension function 'String.getValue', function 'String.setValue'" "true"
|
||||
fun x(parameters: String) {
|
||||
var n by parameters
|
||||
}
|
||||
|
||||
private operator fun String.setValue(nothing: Nothing?, property: KProperty<*>, any: Any) {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
private operator fun String.getValue(nothing: Nothing?, property: KProperty<*>): Any {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
@@ -3571,6 +3571,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("localVal.kt")
|
||||
public void testLocalVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/localVal.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("localVar.kt")
|
||||
public void testLocalVar() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/localVar.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("val.kt")
|
||||
public void testVal() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/delegateAccessors/val.kt");
|
||||
|
||||
Reference in New Issue
Block a user