From b3e80e6a14ac1e268066197c8e8dfdb93a61f4b5 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 24 Jul 2019 18:11:29 +0300 Subject: [PATCH] Look for classfile in implementing modules when building inline function hyperlinks. #KT-32864 Fixed --- .../debugger/NoStrataPositionManagerHelper.kt | 64 ++++++++++--------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt b/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt index 7c3bf7f11ad..8df6e171f60 100644 --- a/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt +++ b/idea/jvm-debugger/jvm-debugger-util/src/org/jetbrains/kotlin/idea/debugger/NoStrataPositionManagerHelper.kt @@ -1,17 +1,6 @@ /* - * Copyright 2010-2016 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. + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.idea.debugger @@ -22,6 +11,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.compiler.CompilerPaths import com.intellij.openapi.compiler.ex.CompilerPathsEx +import com.intellij.openapi.module.Module import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ProjectFileIndex import com.intellij.openapi.vfs.VirtualFile @@ -30,6 +20,7 @@ import com.intellij.util.containers.ConcurrentFactoryMap import com.sun.jdi.Location import com.sun.jdi.ReferenceType import com.sun.jdi.VirtualMachine +import org.jetbrains.kotlin.idea.caches.project.implementingModules import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches import org.jetbrains.kotlin.idea.core.util.getLineCount @@ -143,30 +134,41 @@ private fun readClassFileImpl(project: Project, } fun readFromOutput(isForTestClasses: Boolean): ByteArray? { + fun readFromOutputOfModule(module: Module): File? { + val outputPaths = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList() + val className = fqNameWithInners.asString().replace('.', '$') + var classFile = findClassFileByPaths(jvmName.packageFqName.asString(), className, outputPaths) + + if (classFile == null) { + if (!isForTestClasses) { + return null + } + + val outputDir = CompilerPaths.getModuleOutputDirectory(module, /*forTests = */ isForTestClasses) ?: return null + + val outputModeDirName = outputDir.name + // FIXME: It looks like this doesn't work anymore after Kotlin gradle plugin have stopped generating Kotlin classes in java output dir + // Originally this code did mapping like 'path/classes/test/debug' -> 'path/classes/androidTest/debug' + val androidTestOutputDir = outputDir.parent?.parent?.findChild("androidTest")?.findChild(outputModeDirName) ?: return null + + classFile = findClassFileByPath(jvmName.packageFqName.asString(), className, androidTestOutputDir.path) ?: return null + } + return classFile + } + if (!ProjectRootsUtil.isProjectSourceFile(project, file)) return null val module = ProjectFileIndex.SERVICE.getInstance(project).getModuleForFile(file) ?: return null - val outputPaths = CompilerPathsEx.getOutputPaths(arrayOf(module)).toList() - val className = fqNameWithInners.asString().replace('.', '$') - var classFile = findClassFileByPaths(jvmName.packageFqName.asString(), className, outputPaths) - - if (classFile == null) { - if (!isForTestClasses) { - return null + val classFile = readFromOutputOfModule(module) + return if (classFile == null) { + for (implementing in module.implementingModules) { + readFromOutputOfModule(implementing)?.let { return it.readBytes() } } - - val outputDir = CompilerPaths.getModuleOutputDirectory(module, /*forTests = */ isForTestClasses) ?: return null - - val outputModeDirName = outputDir.name - // FIXME: It looks like this doesn't work anymore after Kotlin gradle plugin have stopped generating Kotlin classes in java output dir - // Originally this code did mapping like 'path/classes/test/debug' -> 'path/classes/androidTest/debug' - val androidTestOutputDir = outputDir.parent?.parent?.findChild("androidTest")?.findChild(outputModeDirName) ?: return null - - classFile = findClassFileByPath(jvmName.packageFqName.asString(), className, androidTestOutputDir.path) ?: return null + null + } else { + classFile.readBytes() } - - return classFile.readBytes() } fun readFromSourceOutput(): ByteArray? = readFromOutput(false)