Completion for evaluate expression: add only imports from code fragment to scope when analyzing it
This commit is contained in:
@@ -90,7 +90,10 @@ public fun LexicalScope.getDescriptorsFiltered(
|
||||
@Deprecated("Use getOwnProperties instead")
|
||||
public fun LexicalScope.getLocalVariable(name: Name): VariableDescriptor? {
|
||||
processForMeAndParent {
|
||||
if (it is LazyFileScope) {
|
||||
if (it is LexicalScopeWrapper) {
|
||||
return it.delegate.getLocalVariable(name)
|
||||
}
|
||||
else if (it is LazyFileScope) {
|
||||
return it.getLocalVariable(name) // todo: remove hack for repl interpreter
|
||||
}
|
||||
else if (it is MemberScopeToFileScopeAdapter) { // todo remove hack
|
||||
@@ -273,3 +276,21 @@ internal inline fun <T: Any> LexicalScope.collectAllFromMeAndParent(
|
||||
processForMeAndParent { result = result.concat(collect(it)) }
|
||||
return result ?: emptySet()
|
||||
}
|
||||
|
||||
public fun LexicalScope.addImportScope(importScope: JetScope): LexicalScope {
|
||||
val fileScope = getFileScope()
|
||||
val scopeWithAdditionImport =
|
||||
LexicalChainedScope(fileScope, fileScope.ownerDescriptor, false, null, "Scope with addition import", importScope)
|
||||
return LexicalScopeWrapper(this, scopeWithAdditionImport)
|
||||
}
|
||||
|
||||
private class LexicalScopeWrapper(val delegate: LexicalScope, val fileScopeReplace: LexicalScope): LexicalScope by delegate {
|
||||
override val parent: LexicalScope? by lazy(LazyThreadSafetyMode.NONE) {
|
||||
if (delegate is FileScope) {
|
||||
fileScopeReplace
|
||||
}
|
||||
else {
|
||||
LexicalScopeWrapper(delegate.parent!!, fileScopeReplace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.scopes.ExplicitImportsScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.addImportScope
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.util.descriptorsEqualWithSubstitution
|
||||
import java.util.*
|
||||
|
||||
@@ -22,11 +22,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.FileScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getFileScope
|
||||
|
||||
|
||||
public fun JetScope.getAllAccessibleVariables(name: Name): Collection<VariableDescriptor>
|
||||
@@ -45,22 +41,4 @@ public fun JetScope.getVariableFromImplicitReceivers(name: Name): VariableDescri
|
||||
it.type.memberScope.getProperties(name, NoLookupLocation.FROM_IDE).singleOrNull()?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
public fun LexicalScope.addImportScope(importScope: JetScope): LexicalScope {
|
||||
val fileScope = getFileScope()
|
||||
val scopeWithAdditionImport =
|
||||
LexicalChainedScope(fileScope, fileScope.ownerDescriptor, false, null, "Scope with addition import", importScope)
|
||||
return LexicalScopeWrapper(this, scopeWithAdditionImport)
|
||||
}
|
||||
|
||||
private class LexicalScopeWrapper(val delegate: LexicalScope, val fileScopeReplace: LexicalScope): LexicalScope by delegate {
|
||||
override val parent: LexicalScope? by lazy(LazyThreadSafetyMode.NONE) {
|
||||
if (delegate is FileScope) {
|
||||
fileScopeReplace
|
||||
}
|
||||
else {
|
||||
LexicalScopeWrapper(delegate.parent!!, fileScopeReplace)
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-9
@@ -24,13 +24,14 @@ import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.QualifiedExpressionResolver
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.addImportScope
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
@@ -38,6 +39,7 @@ import javax.inject.Inject
|
||||
|
||||
public class CodeFragmentAnalyzer(
|
||||
private val resolveSession: ResolveSession,
|
||||
private val qualifierResolver: QualifiedExpressionResolver,
|
||||
private val expressionTypingServices: ExpressionTypingServices
|
||||
) {
|
||||
|
||||
@@ -130,13 +132,20 @@ public class CodeFragmentAnalyzer(
|
||||
|
||||
if (scopeForContextElement == null) return null
|
||||
|
||||
val codeFragmentScope = resolveSession.getFileScopeProvider().getFileScope(codeFragment)
|
||||
val chainedScope = LexicalChainedScope(
|
||||
scopeForContextElement, scopeForContextElement.ownerDescriptor,
|
||||
false, null,
|
||||
"Scope for resolve code fragment",
|
||||
codeFragmentScope)
|
||||
val importList = codeFragment.importsAsImportList()
|
||||
if (importList == null || importList.imports.isEmpty()) {
|
||||
return scopeForContextElement to dataFlowInfo
|
||||
}
|
||||
|
||||
return chainedScope to dataFlowInfo
|
||||
val importScopes = importList.imports.map {
|
||||
qualifierResolver.processImportReference(it, resolveSession.moduleDescriptor, resolveSession.trace, null)
|
||||
}.filterNotNull()
|
||||
|
||||
val chainedScope = ChainedScope(
|
||||
scopeForContextElement.ownerDescriptor,
|
||||
"Scope for resolve code fragment",
|
||||
*importScopes.toTypedArray())
|
||||
|
||||
return scopeForContextElement.addImportScope(chainedScope) to dataFlowInfo
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user