Create from Usage: Support accessors for local delegated properties

#KT-19730 Fixed
This commit is contained in:
Alexey Sedunov
2018-02-27 20:46:36 +03:00
parent 2eddce57ff
commit 96de29dfcb
7 changed files with 71 additions and 10 deletions
@@ -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) } }
@@ -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