Refactoring: move similar part for obtaining scope for codeFragment to JetCodeFragment
This commit is contained in:
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.context.withProject
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.frontend.di.createContainerForBodyResolve
|
||||
import org.jetbrains.kotlin.resolve.util.getScopeAndDataFlowForAnalyzeFragment
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -206,53 +207,22 @@ public abstract class ElementResolver protected constructor(
|
||||
val trace = createDelegatingTrace(codeFragment)
|
||||
|
||||
val codeFragmentExpression = codeFragment.getContentElement() as? JetExpression ?: return trace
|
||||
val contextElement = codeFragment.correctedContext
|
||||
|
||||
val scopeForContextElement: JetScope?
|
||||
val dataFlowInfoForContextElement: DataFlowInfo
|
||||
when (contextElement) {
|
||||
is JetClassOrObject -> {
|
||||
val descriptor = resolveSession.resolveToDescriptor(contextElement) as LazyClassDescriptor
|
||||
scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution()
|
||||
dataFlowInfoForContextElement = DataFlowInfo.EMPTY
|
||||
}
|
||||
val (scopeForContextElement, dataFlowInfoForContextElement) = codeFragment.getScopeAndDataFlowForAnalyzeFragment(resolveSession) {
|
||||
val contextResolveMode = if (bodyResolveMode == BodyResolveMode.PARTIAL)
|
||||
BodyResolveMode.PARTIAL_FOR_COMPLETION
|
||||
else
|
||||
bodyResolveMode
|
||||
|
||||
is JetExpression -> {
|
||||
// do not use PARTIAL body resolve mode because because it does not know about names used in our fragment
|
||||
val contextResolveMode = if (bodyResolveMode == BodyResolveMode.PARTIAL)
|
||||
BodyResolveMode.PARTIAL_FOR_COMPLETION
|
||||
else
|
||||
bodyResolveMode
|
||||
val contextForElement = resolveToElement(contextElement, contextResolveMode)
|
||||
scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, contextElement]
|
||||
dataFlowInfoForContextElement = contextForElement.getDataFlowInfo(contextElement)
|
||||
}
|
||||
resolveToElement(it, contextResolveMode)
|
||||
} ?: return trace
|
||||
|
||||
else -> return trace
|
||||
}
|
||||
|
||||
if (scopeForContextElement == null) return trace
|
||||
|
||||
val codeFragmentScope = resolveSession.getFileScopeProvider().getFileScope(codeFragment)
|
||||
val chainedScope = ChainedScope(scopeForContextElement.getContainingDeclaration(),
|
||||
"Scope for resolve code fragment", scopeForContextElement, codeFragmentScope)
|
||||
|
||||
codeFragmentExpression.computeTypeInContext(chainedScope, trace, dataFlowInfoForContextElement,
|
||||
codeFragmentExpression.computeTypeInContext(scopeForContextElement, trace, dataFlowInfoForContextElement,
|
||||
TypeUtils.NO_EXPECTED_TYPE, resolveSession.getModuleDescriptor())
|
||||
|
||||
return trace
|
||||
}
|
||||
|
||||
//TODO: this code should be moved into debugger which should set correct context for its code fragment
|
||||
private val JetCodeFragment.correctedContext: PsiElement?
|
||||
get() {
|
||||
val context = getContext()
|
||||
if (context is JetBlockExpression) {
|
||||
return context.getStatements().lastOrNull() ?: context
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
private fun annotationAdditionalResolve(resolveSession: ResolveSession, jetAnnotationEntry: JetAnnotationEntry): BindingTrace {
|
||||
val modifierList = jetAnnotationEntry.getParentOfType<JetModifierList>(true)
|
||||
val declaration = modifierList?.getParentOfType<JetDeclaration>(true)
|
||||
@@ -397,7 +367,7 @@ public abstract class ElementResolver protected constructor(
|
||||
|
||||
val bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter)
|
||||
bodyResolver.resolveAnonymousInitializer(DataFlowInfo.EMPTY, classInitializer, classOrObjectDescriptor)
|
||||
|
||||
|
||||
return trace
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.util
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
|
||||
//TODO: this code should be moved into debugger which should set correct context for its code fragment
|
||||
private fun correctContext(oldContext: PsiElement?): PsiElement? {
|
||||
if (oldContext is JetBlockExpression) {
|
||||
return oldContext.getStatements().lastOrNull() ?: oldContext
|
||||
}
|
||||
return oldContext
|
||||
}
|
||||
|
||||
public fun JetCodeFragment.getScopeAndDataFlowForAnalyzeFragment(
|
||||
resolveSession: KotlinCodeAnalyzer,
|
||||
resolveToElement: (JetElement) -> BindingContext
|
||||
): Pair<JetScope, DataFlowInfo>? {
|
||||
val context = correctContext(getContext())
|
||||
if (context !is JetExpression) return null
|
||||
|
||||
val scopeForContextElement: JetScope?
|
||||
val dataFlowInfo: DataFlowInfo
|
||||
|
||||
when (context) {
|
||||
is JetClassOrObject -> {
|
||||
val descriptor = resolveSession.getClassDescriptor(context) as ClassDescriptorWithResolutionScopes
|
||||
|
||||
scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution()
|
||||
dataFlowInfo = DataFlowInfo.EMPTY
|
||||
}
|
||||
is JetExpression -> {
|
||||
val contextForElement = resolveToElement(context)
|
||||
|
||||
scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, context]
|
||||
dataFlowInfo = contextForElement.getDataFlowInfo(context)
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
|
||||
if (scopeForContextElement == null) return null
|
||||
|
||||
val codeFragmentScope = resolveSession.getFileScopeProvider().getFileScope(this)
|
||||
val chainedScope = ChainedScope(
|
||||
scopeForContextElement.getContainingDeclaration(),
|
||||
"Scope for resolve code fragment",
|
||||
scopeForContextElement, codeFragmentScope)
|
||||
|
||||
return chainedScope to dataFlowInfo
|
||||
}
|
||||
+5
-35
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.resolve.util.getScopeAndDataFlowForAnalyzeFragment
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.util.HashMap
|
||||
|
||||
@@ -270,44 +271,13 @@ private object KotlinResolveDataProvider {
|
||||
val codeFragmentExpression = codeFragment.getContentElement()
|
||||
if (codeFragmentExpression !is JetExpression) return BindingContext.EMPTY
|
||||
|
||||
val contextElement = codeFragment.getContext()
|
||||
val (scopeForContextElement, dataFlowInfo) = codeFragment.getScopeAndDataFlowForAnalyzeFragment(resolveSession) {
|
||||
resolveSession.resolveToElement(it, BodyResolveMode.PARTIAL_FOR_COMPLETION) //TODO: discuss it
|
||||
} ?: return BindingContext.EMPTY
|
||||
|
||||
val scopeForContextElement: JetScope?
|
||||
val dataFlowInfo: DataFlowInfo
|
||||
if (contextElement is JetClassOrObject) {
|
||||
val descriptor = resolveSession.resolveToDescriptor(contextElement) as LazyClassDescriptor
|
||||
|
||||
scopeForContextElement = descriptor.getScopeForMemberDeclarationResolution()
|
||||
dataFlowInfo = DataFlowInfo.EMPTY
|
||||
}
|
||||
else if (contextElement is JetBlockExpression) {
|
||||
val newContextElement = contextElement.getStatements().lastOrNull()
|
||||
if (newContextElement !is JetExpression) return BindingContext.EMPTY
|
||||
|
||||
val contextForElement = newContextElement.getResolutionFacade().analyze(newContextElement, BodyResolveMode.FULL)
|
||||
|
||||
scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, newContextElement]
|
||||
dataFlowInfo = contextForElement.getDataFlowInfo(newContextElement)
|
||||
}
|
||||
else {
|
||||
if (contextElement !is JetExpression) return BindingContext.EMPTY
|
||||
|
||||
val contextForElement = contextElement.getResolutionFacade().analyze(contextElement, BodyResolveMode.PARTIAL_FOR_COMPLETION) //TODO: discuss it
|
||||
|
||||
scopeForContextElement = contextForElement[BindingContext.RESOLUTION_SCOPE, contextElement]
|
||||
dataFlowInfo = contextForElement.getDataFlowInfo(contextElement)
|
||||
}
|
||||
|
||||
if (scopeForContextElement == null) return BindingContext.EMPTY
|
||||
|
||||
val codeFragmentScope = resolveSession.getFileScopeProvider().getFileScope(codeFragment)
|
||||
val chainedScope = ChainedScope(
|
||||
scopeForContextElement.getContainingDeclaration(),
|
||||
"Scope for resolve code fragment",
|
||||
scopeForContextElement, codeFragmentScope)
|
||||
|
||||
return codeFragmentExpression.analyzeInContext(
|
||||
chainedScope,
|
||||
scopeForContextElement,
|
||||
BindingTraceContext(),
|
||||
dataFlowInfo,
|
||||
TypeUtils.NO_EXPECTED_TYPE,
|
||||
|
||||
Reference in New Issue
Block a user