Evaluator: Don't rely on moduleDescriptor presence in DebugLabel descriptor generation

The containing moduleDescriptor may not exist for the Java context.
This commit is contained in:
Yan Zhulanow
2019-02-20 03:09:48 +03:00
parent a21802ee51
commit 1edacbbb5e
3 changed files with 67 additions and 13 deletions
@@ -40,7 +40,6 @@ import org.jetbrains.annotations.TestOnly
import org.jetbrains.eval4j.jdi.asValue import org.jetbrains.eval4j.jdi.asValue
import org.jetbrains.kotlin.asJava.classes.KtLightClass import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider import org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider
import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.DebugLabelPropertyDescriptorProvider import org.jetbrains.kotlin.idea.debugger.evaluate.compilation.DebugLabelPropertyDescriptorProvider
@@ -70,12 +69,7 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() {
} }
val codeFragment = constructor(project, "fragment.kt", item.text, initImports(item.imports), contextElement) val codeFragment = constructor(project, "fragment.kt", item.text, initImports(item.imports), contextElement)
supplyDebugLabels(codeFragment, context)
val moduleDescriptor = codeFragment.getResolutionFacade().moduleDescriptor
val debugProcess = getDebugProcess(project, contextElement)
if (debugProcess != null) {
DebugLabelPropertyDescriptorProvider(codeFragment, moduleDescriptor, debugProcess).supplyDebugLabels()
}
codeFragment.putCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR, { expression: KtExpression -> codeFragment.putCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR, { expression: KtExpression ->
val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context
@@ -146,6 +140,12 @@ class KotlinCodeFragmentFactory : CodeFragmentFactory() {
return codeFragment return codeFragment
} }
private fun supplyDebugLabels(codeFragment: KtCodeFragment, context: PsiElement?) {
val project = codeFragment.project
val debugProcess = getDebugProcess(project, context) ?: return
DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels()
}
private fun getDebugProcess(project: Project, context: PsiElement?): DebugProcessImpl? { private fun getDebugProcess(project: Project, context: PsiElement?): DebugProcessImpl? {
return if (ApplicationManager.getApplication().isUnitTestMode) { return if (ApplicationManager.getApplication().isUnitTestMode) {
context?.getCopyableUserData(DEBUG_CONTEXT_FOR_TESTS)?.debugProcess context?.getCopyableUserData(DEBUG_CONTEXT_FOR_TESTS)?.debugProcess
@@ -256,7 +256,7 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
val filesToAnalyze = listOf(codeFragment) val filesToAnalyze = listOf(codeFragment)
val resolutionFacade = KotlinCacheService.getInstance(codeFragment.project).getResolutionFacade(filesToAnalyze) val resolutionFacade = KotlinCacheService.getInstance(codeFragment.project).getResolutionFacade(filesToAnalyze)
DebugLabelPropertyDescriptorProvider(codeFragment, resolutionFacade.moduleDescriptor, debugProcess).supplyDebugLabels() DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels()
val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(filesToAnalyze) val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(filesToAnalyze)
@@ -15,8 +15,11 @@ import org.jetbrains.kotlin.builtins.PrimitiveType
import com.sun.jdi.* import com.sun.jdi.*
import com.sun.jdi.Type as JdiType import com.sun.jdi.Type as JdiType
import org.jetbrains.kotlin.backend.common.lower.SimpleMemberScope import org.jetbrains.kotlin.backend.common.lower.SimpleMemberScope
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
@@ -25,15 +28,12 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtCodeFragment import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.externalDescriptors import org.jetbrains.kotlin.psi.externalDescriptors
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import org.jetbrains.org.objectweb.asm.Type as AsmType import org.jetbrains.org.objectweb.asm.Type as AsmType
class DebugLabelPropertyDescriptorProvider( class DebugLabelPropertyDescriptorProvider(val codeFragment: KtCodeFragment, val debugProcess: DebugProcessImpl) {
val codeFragment: KtCodeFragment,
val moduleDescriptor: ModuleDescriptor,
val debugProcess: DebugProcessImpl
) {
companion object { companion object {
fun getMarkupMap(debugProcess: DebugProcessImpl) = doGetMarkupMap(debugProcess) ?: emptyMap() fun getMarkupMap(debugProcess: DebugProcessImpl) = doGetMarkupMap(debugProcess) ?: emptyMap()
@@ -49,6 +49,8 @@ class DebugLabelPropertyDescriptorProvider(
} }
} }
private val moduleDescriptor = DebugLabelModuleDescriptor
fun supplyDebugLabels() { fun supplyDebugLabels() {
val packageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName.ROOT) { val packageFragment = object : PackageFragmentDescriptorImpl(moduleDescriptor, FqName.ROOT) {
val properties = createDebugLabelDescriptors(this) val properties = createDebugLabelDescriptors(this)
@@ -140,6 +142,58 @@ class DebugLabelPropertyDescriptorProvider(
} }
} }
private object DebugLabelModuleDescriptor
: DeclarationDescriptorImpl(Annotations.EMPTY, Name.identifier("DebugLabelExtensions")),
ModuleDescriptor
{
override val builtIns: KotlinBuiltIns
get() = DefaultBuiltIns.Instance
override val stableName: Name?
get() = name
override fun shouldSeeInternalsOf(targetModule: ModuleDescriptor) = false
override fun getPackage(fqName: FqName): PackageViewDescriptor {
return object : PackageViewDescriptor, DeclarationDescriptorImpl(Annotations.EMPTY, FqName.ROOT.shortNameOrSpecial()) {
override fun getContainingDeclaration(): PackageViewDescriptor? = null
override val fqName: FqName
get() = FqName.ROOT
override val memberScope: MemberScope
get() = MemberScope.Empty
override val module: ModuleDescriptor
get() = this@DebugLabelModuleDescriptor
override val fragments: List<PackageFragmentDescriptor>
get() = emptyList()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitPackageViewDescriptor(this, data)
}
}
}
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
return emptyList()
}
override val allDependencyModules: List<ModuleDescriptor>
get() = emptyList()
override val expectedByModules: List<ModuleDescriptor>
get() = emptyList()
override fun <T> getCapability(capability: ModuleDescriptor.Capability<T>): T? = null
override val isValid: Boolean
get() = true
override fun assertValid() {}
}
internal class DebugLabelPropertyDescriptor( internal class DebugLabelPropertyDescriptor(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
val labelName: String val labelName: String