Completion for evaluate expression: add only imports from code fragment to scope when analyzing it

This commit is contained in:
Natalia Ukhorskaya
2015-10-08 17:05:22 +03:00
parent 7e2c2ef678
commit ccbb015606
4 changed files with 41 additions and 32 deletions
@@ -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)
}
}
}
@@ -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
}
}