Debugger: Fix 'expect fun' evaluation from common code (KT-26742)

This commit is contained in:
Yan Zhulanow
2019-06-14 22:33:27 +09:00
parent 873f4a1b08
commit 6d7d524b9b
4 changed files with 29 additions and 13 deletions
@@ -31,6 +31,7 @@ interface KotlinCacheService {
} }
fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade
fun getResolutionFacade(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade
fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade? fun getResolutionFacadeByFile(file: PsiFile, platform: TargetPlatform): ResolutionFacade?
fun getSuppressionCache(): KotlinSuppressCache fun getSuppressionCache(): KotlinSuppressCache
@@ -75,11 +75,22 @@ data class PlatformAnalysisSettings(
class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService { class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade { override fun getResolutionFacade(elements: List<KtElement>): ResolutionFacade {
return getFacadeToAnalyzeFiles(elements.map { val files = getFilesForElements(elements)
val platform = TargetPlatformDetector.getPlatform(files.first())
return getFacadeToAnalyzeFiles(files, platform)
}
override fun getResolutionFacade(elements: List<KtElement>, platform: TargetPlatform): ResolutionFacade {
val files = getFilesForElements(elements)
return getFacadeToAnalyzeFiles(files, platform)
}
private fun getFilesForElements(elements: List<KtElement>): List<KtFile> {
return elements.map {
// in theory `containingKtFile` is `@NotNull` but in practice EA-114080 // in theory `containingKtFile` is `@NotNull` but in practice EA-114080
@Suppress("USELESS_ELVIS") @Suppress("USELESS_ELVIS")
it.containingKtFile ?: throw IllegalStateException("containingKtFile was null for $it of ${it.javaClass}") it.containingKtFile ?: throw IllegalStateException("containingKtFile was null for $it of ${it.javaClass}")
}) }
} }
override fun getSuppressionCache(): KotlinSuppressCache = kotlinSuppressCache.value override fun getSuppressionCache(): KotlinSuppressCache = kotlinSuppressCache.value
@@ -416,7 +427,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
} }
} }
private fun getFacadeToAnalyzeFiles(files: Collection<KtFile>): ResolutionFacade { private fun getFacadeToAnalyzeFiles(files: Collection<KtFile>, platform: TargetPlatform): ResolutionFacade {
val file = files.first() val file = files.first()
val moduleInfo = file.getModuleInfo() val moduleInfo = file.getModuleInfo()
val specialFiles = files.filterNotInProjectSource(moduleInfo) val specialFiles = files.filterNotInProjectSource(moduleInfo)
@@ -431,7 +442,6 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
return ModuleResolutionFacadeImpl(projectFacade, moduleInfo).createdFor(specialFiles, moduleInfo) return ModuleResolutionFacadeImpl(projectFacade, moduleInfo).createdFor(specialFiles, moduleInfo)
} }
val platform = TargetPlatformDetector.getPlatform(file)
return getResolutionFacadeByModuleInfo(moduleInfo, platform).createdFor(emptyList(), moduleInfo, platform) return getResolutionFacadeByModuleInfo(moduleInfo, platform).createdFor(emptyList(), moduleInfo, platform)
} }
@@ -69,6 +69,8 @@ import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.tree.ClassNode import org.jetbrains.org.objectweb.asm.tree.ClassNode
import org.jetbrains.kotlin.idea.debugger.evaluate.EvaluationStatus.EvaluationContextLanguage import org.jetbrains.kotlin.idea.debugger.evaluate.EvaluationStatus.EvaluationContextLanguage
import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.ClassLoadingResult import org.jetbrains.kotlin.idea.debugger.evaluate.compilingEvaluator.ClassLoadingResult
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import java.util.* import java.util.*
internal val LOG = Logger.getInstance(KotlinEvaluator::class.java) internal val LOG = Logger.getInstance(KotlinEvaluator::class.java)
@@ -209,10 +211,8 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
} }
val (bindingContext) = runReadAction { val (bindingContext) = runReadAction {
DebuggerUtils.analyzeInlinedFunctions( val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
KotlinCacheService.getInstance(codeFragment.project).getResolutionFacade(listOf(codeFragment)), DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, codeFragment, false, analysisResult.bindingContext)
codeFragment, false, analysisResult.bindingContext
)
} }
val moduleDescriptor = analysisResult.moduleDescriptor val moduleDescriptor = analysisResult.moduleDescriptor
@@ -263,12 +263,11 @@ class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: Sour
evaluationException(e.message ?: e.toString()) evaluationException(e.message ?: e.toString())
} }
val filesToAnalyze = listOf(codeFragment) val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
val resolutionFacade = KotlinCacheService.getInstance(codeFragment.project).getResolutionFacade(filesToAnalyze)
DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels() DebugLabelPropertyDescriptorProvider(codeFragment, debugProcess).supplyDebugLabels()
val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(filesToAnalyze) val analysisResult = resolutionFacade.analyzeWithAllCompilerChecks(listOf(codeFragment))
if (analysisResult.isError()) { if (analysisResult.isError()) {
status.error(EvaluationError.FrontendException) status.error(EvaluationError.FrontendException)
@@ -509,3 +508,9 @@ fun createCompiledDataDescriptor(result: CodeFragmentCompiler.CompilationResult,
private fun evaluationException(msg: String): Nothing = throw EvaluateExceptionUtil.createEvaluateException(msg) private fun evaluationException(msg: String): Nothing = throw EvaluateExceptionUtil.createEvaluateException(msg)
private fun evaluationException(e: Throwable): Nothing = throw EvaluateExceptionUtil.createEvaluateException(e) private fun evaluationException(e: Throwable): Nothing = throw EvaluateExceptionUtil.createEvaluateException(e)
internal fun getResolutionFacadeForCodeFragment(codeFragment: KtCodeFragment): ResolutionFacade {
val filesToAnalyze = listOf(codeFragment)
val kotlinCacheService = KotlinCacheService.getInstance(codeFragment.project)
return kotlinCacheService.getResolutionFacade(filesToAnalyze, JvmPlatforms.unspecifiedJvmPlatform)
}
@@ -65,7 +65,7 @@ class CodeFragmentCompiler(private val executionContext: ExecutionContext) {
} }
val project = codeFragment.project val project = codeFragment.project
val resolutionFacade = KotlinCacheService.getInstance(project).getResolutionFacade(listOf(codeFragment)) val resolutionFacade = getResolutionFacadeForCodeFragment(codeFragment)
val resolveSession = resolutionFacade.getFrontendService(ResolveSession::class.java) val resolveSession = resolutionFacade.getFrontendService(ResolveSession::class.java)
val moduleDescriptorWrapper = EvaluatorModuleDescriptor(codeFragment, moduleDescriptor, resolveSession) val moduleDescriptorWrapper = EvaluatorModuleDescriptor(codeFragment, moduleDescriptor, resolveSession)