Compare commits

...

6 Commits

Author SHA1 Message Date
Pavel V. Talanov
b418e281e8 DRAFT, bytecode toolwindow: show bytecode for actuals when common file is opened int he editor 2018-06-06 19:13:45 +02:00
Pavel V. Talanov
a12032fb8d Fix exception from kotlin bytecode window on common code
#KT-24159 Fixed
2018-06-06 18:27:17 +02:00
Pavel V. Talanov
809105d015 JavaElementFinder: avoid returning fake light class in findClass*
findClass* are supposed to return a single visible class
    from given scope with given fqname
After sorting FakeFileForLightClass would sometimes be first in the list
    leading to exceptions like KT-24704

  #KT-24704 Fixed
2018-06-06 16:32:30 +02:00
Pavel V. Talanov
81d81b6f1e J2K JavaElementFinder: prettify code 2018-06-06 16:32:29 +02:00
Pavel V. Talanov
60eea47f9d J2K JavaElementFinder: autoconvert and fix compilation errors 2018-06-06 16:32:26 +02:00
Pavel V. Talanov
de0abbe9a3 J2K JavaElementFinder: rename file 2018-06-06 16:32:24 +02:00
5 changed files with 246 additions and 260 deletions

View File

@@ -1,243 +0,0 @@
/*
* 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.
*/
package org.jetbrains.kotlin.asJava.finder;
import com.google.common.collect.Collections2;
import com.google.common.collect.Sets;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNamesUtilKt;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.KtEnumEntry;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import static org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass;
public class JavaElementFinder extends PsiElementFinder implements KotlinFinderMarker {
@NotNull
public static JavaElementFinder getInstance(@NotNull Project project) {
PsiElementFinder[] extensions = Extensions.getArea(project).getExtensionPoint(PsiElementFinder.EP_NAME).getExtensions();
for (PsiElementFinder extension : extensions) {
if (extension instanceof JavaElementFinder) {
return (JavaElementFinder) extension;
}
}
throw new IllegalStateException(JavaElementFinder.class.getSimpleName() + " is not found for project " + project);
}
private final Project project;
private final PsiManager psiManager;
private final KotlinAsJavaSupport kotlinAsJavaSupport;
public JavaElementFinder(
@NotNull Project project,
@NotNull KotlinAsJavaSupport kotlinAsJavaSupport
) {
this.project = project;
this.psiManager = PsiManager.getInstance(project);
this.kotlinAsJavaSupport = kotlinAsJavaSupport;
}
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
PsiClass[] allClasses = findClasses(qualifiedName, scope);
return allClasses.length > 0 ? allClasses[0] : null;
}
@NotNull
@Override
public PsiClass[] findClasses(@NotNull String qualifiedNameString, @NotNull GlobalSearchScope scope) {
if (!FqNamesUtilKt.isValidJavaFqName(qualifiedNameString)) {
return PsiClass.EMPTY_ARRAY;
}
List<PsiClass> answer = new SmartList<>();
FqName qualifiedName = new FqName(qualifiedNameString);
findClassesAndObjects(qualifiedName, scope, answer);
answer.addAll(kotlinAsJavaSupport.getFacadeClasses(qualifiedName, scope));
answer.addAll(kotlinAsJavaSupport.getKotlinInternalClasses(qualifiedName, scope));
return sortByClasspath(answer, scope).toArray(new PsiClass[answer.size()]);
}
// Finds explicitly declared classes and objects, not package classes
// Also DefaultImpls classes of interfaces
private void findClassesAndObjects(FqName qualifiedName, GlobalSearchScope scope, List<PsiClass> answer) {
findInterfaceDefaultImpls(qualifiedName, scope, answer);
Collection<KtClassOrObject> classOrObjectDeclarations =
kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName, scope);
for (KtClassOrObject declaration : classOrObjectDeclarations) {
if (!(declaration instanceof KtEnumEntry)) {
PsiClass lightClass = toLightClass(declaration);
if (lightClass != null) {
answer.add(lightClass);
}
}
}
}
private void findInterfaceDefaultImpls(FqName qualifiedName, GlobalSearchScope scope, List<PsiClass> answer) {
if (qualifiedName.isRoot()) return;
if (!qualifiedName.shortName().asString().equals(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) return;
for (KtClassOrObject classOrObject : kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
//NOTE: can't filter out more interfaces right away because decompiled declarations do not have member bodies
if (classOrObject instanceof KtClass && ((KtClass) classOrObject).isInterface()) {
PsiClass interfaceClass = toLightClass(classOrObject);
if (interfaceClass != null) {
PsiClass implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false);
if (implsClass != null) {
answer.add(implsClass);
}
}
}
}
}
@NotNull
@Override
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
Collection<KtClassOrObject> declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
Set<String> answer = Sets.newHashSet();
answer.addAll(kotlinAsJavaSupport.getFacadeNames(packageFQN, scope));
for (KtClassOrObject declaration : declarations) {
String name = declaration.getName();
if (name != null) {
answer.add(name);
}
}
return answer;
}
@Override
public PsiPackage findPackage(@NotNull String qualifiedNameString) {
if (!FqNamesUtilKt.isValidJavaFqName(qualifiedNameString)) {
return null;
}
FqName fqName = new FqName(qualifiedNameString);
// allScope() because the contract says that the whole project
GlobalSearchScope allScope = GlobalSearchScope.allScope(project);
if (kotlinAsJavaSupport.packageExists(fqName, allScope)) {
return new KtLightPackage(psiManager, fqName, allScope);
}
return null;
}
@NotNull
@Override
public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
Collection<FqName> subpackages = kotlinAsJavaSupport.getSubPackages(packageFQN, scope);
Collection<PsiPackage> answer = Collections2.transform(subpackages, input -> new KtLightPackage(psiManager, input, scope));
return answer.toArray(new PsiPackage[answer.size()]);
}
@NotNull
@Override
public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
List<PsiClass> answer = new SmartList<>();
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
answer.addAll(kotlinAsJavaSupport.getFacadeClassesInPackage(packageFQN, scope));
Collection<KtClassOrObject> declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
for (KtClassOrObject declaration : declarations) {
PsiClass aClass = toLightClass(declaration);
if (aClass != null) {
answer.add(aClass);
}
}
return sortByClasspath(answer, scope).toArray(new PsiClass[answer.size()]);
}
@Override
@NotNull
public PsiFile[] getPackageFiles(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
// TODO: this does not take into account JvmPackageName annotation
Collection<KtFile> result = kotlinAsJavaSupport.findFilesForPackage(packageFQN, scope);
return result.toArray(new PsiFile[result.size()]);
}
@Override
@Nullable
public Condition<PsiFile> getPackageFilesFilter(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
return input -> {
if (!(input instanceof KtFile)) {
return true;
}
return psiPackage.getQualifiedName().equals(((KtFile) input).getPackageFqName().asString());
};
}
@NotNull
public static Comparator<PsiElement> byClasspathComparator(@NotNull GlobalSearchScope searchScope) {
return (o1, o2) -> {
VirtualFile f1 = PsiUtilCore.getVirtualFile(o1);
VirtualFile f2 = PsiUtilCore.getVirtualFile(o2);
if (f1 == f2) return 0;
if (f1 == null) return -1;
if (f2 == null) return 1;
return searchScope.compare(f2, f1);
};
}
private static Collection<PsiClass> sortByClasspath(@NotNull List<PsiClass> classes, @NotNull GlobalSearchScope searchScope) {
if (classes.size() > 1) {
ContainerUtil.quickSort(classes, byClasspathComparator(searchScope));
}
return classes;
}
}

View File

@@ -0,0 +1,193 @@
/*
* 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.
*/
package org.jetbrains.kotlin.asJava.finder
import com.google.common.collect.Sets
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Condition
import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.SmartList
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.isValidJavaFqName
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker
import java.util.*
class JavaElementFinder(
private val project: Project,
private val kotlinAsJavaSupport: KotlinAsJavaSupport
) : PsiElementFinder(), KotlinFinderMarker {
private val psiManager = PsiManager.getInstance(project)
override fun findClass(qualifiedName: String, scope: GlobalSearchScope) = findClasses(qualifiedName, scope).firstOrNull()
override fun findClasses(qualifiedNameString: String, scope: GlobalSearchScope): Array<PsiClass> {
if (!isValidJavaFqName(qualifiedNameString)) {
return PsiClass.EMPTY_ARRAY
}
val answer = SmartList<PsiClass>()
val qualifiedName = FqName(qualifiedNameString)
findClassesAndObjects(qualifiedName, scope, answer)
answer.addAll(kotlinAsJavaSupport.getFacadeClasses(qualifiedName, scope))
answer.addAll(kotlinAsJavaSupport.getKotlinInternalClasses(qualifiedName, scope))
return answer.sortByClasspathPreferringNonFakeFiles(scope).toTypedArray()
}
// Finds explicitly declared classes and objects, not package classes
// Also DefaultImpls classes of interfaces
private fun findClassesAndObjects(qualifiedName: FqName, scope: GlobalSearchScope, answer: MutableList<PsiClass>) {
findInterfaceDefaultImpls(qualifiedName, scope, answer)
val classOrObjectDeclarations = kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName, scope)
for (declaration in classOrObjectDeclarations) {
if (declaration !is KtEnumEntry) {
val lightClass = declaration.toLightClass()
if (lightClass != null) {
answer.add(lightClass)
}
}
}
}
private fun findInterfaceDefaultImpls(qualifiedName: FqName, scope: GlobalSearchScope, answer: MutableList<PsiClass>) {
if (qualifiedName.isRoot) return
if (qualifiedName.shortName().asString() != JvmAbi.DEFAULT_IMPLS_CLASS_NAME) return
for (classOrObject in kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
//NOTE: can't filter out more interfaces right away because decompiled declarations do not have member bodies
if (classOrObject is KtClass && classOrObject.isInterface()) {
val interfaceClass = classOrObject.toLightClass() ?: continue
val implsClass = interfaceClass.findInnerClassByName(JvmAbi.DEFAULT_IMPLS_CLASS_NAME, false) ?: continue
answer.add(implsClass)
}
}
}
override fun getClassNames(psiPackage: PsiPackage, scope: GlobalSearchScope): Set<String> {
val packageFQN = FqName(psiPackage.qualifiedName)
val declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope)
val answer = Sets.newHashSet<String>()
answer.addAll(kotlinAsJavaSupport.getFacadeNames(packageFQN, scope))
for (declaration in declarations) {
val name = declaration.name ?: continue
answer.add(name)
}
return answer
}
override fun findPackage(qualifiedNameString: String): PsiPackage? {
if (!isValidJavaFqName(qualifiedNameString)) {
return null
}
val fqName = FqName(qualifiedNameString)
// allScope() because the contract says that the whole project
val allScope = GlobalSearchScope.allScope(project)
return if (kotlinAsJavaSupport.packageExists(fqName, allScope)) {
KtLightPackage(psiManager, fqName, allScope)
} else null
}
override fun getSubPackages(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiPackage> {
val subpackages = kotlinAsJavaSupport.getSubPackages(FqName(psiPackage.qualifiedName), scope)
return subpackages.map { KtLightPackage(psiManager, it, scope) }.toTypedArray()
}
override fun getClasses(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiClass> {
val answer = SmartList<PsiClass>()
val packageFQN = FqName(psiPackage.qualifiedName)
answer.addAll(kotlinAsJavaSupport.getFacadeClassesInPackage(packageFQN, scope))
val declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope)
for (declaration in declarations) {
val aClass = declaration.toLightClass() ?: continue
answer.add(aClass)
}
return answer.sortByClasspathPreferringNonFakeFiles(scope).toTypedArray()
}
override fun getPackageFiles(psiPackage: PsiPackage, scope: GlobalSearchScope): Array<PsiFile> {
val packageFQN = FqName(psiPackage.qualifiedName)
// TODO: this does not take into account JvmPackageName annotation
return kotlinAsJavaSupport.findFilesForPackage(packageFQN, scope).toTypedArray()
}
override fun getPackageFilesFilter(psiPackage: PsiPackage, scope: GlobalSearchScope): Condition<PsiFile>? {
return Condition { input ->
if (input !is KtFile) {
true
} else {
psiPackage.qualifiedName == input.packageFqName.asString()
}
}
}
companion object {
fun getInstance(project: Project): JavaElementFinder {
val extensions = Extensions.getArea(project).getExtensionPoint(PsiElementFinder.EP_NAME).extensions
for (extension in extensions) {
if (extension is JavaElementFinder) {
return extension
}
}
throw IllegalStateException(JavaElementFinder::class.java.simpleName + " is not found for project " + project)
}
fun byClasspathComparator(searchScope: GlobalSearchScope): Comparator<PsiElement> {
return Comparator { o1, o2 ->
val f1 = PsiUtilCore.getVirtualFile(o1)
val f2 = PsiUtilCore.getVirtualFile(o2)
when {
f1 === f2 -> 0
f1 == null -> -1
f2 == null -> 1
else -> searchScope.compare(f2, f1)
}
}
}
private fun List<PsiClass>.sortByClasspathPreferringNonFakeFiles(searchScope: GlobalSearchScope): List<PsiClass> {
return this.sortedWith(byClasspathComparator(searchScope)).sortedBy {
this is FakeLightClassForFileOfPackage
}
}
}
}

View File

@@ -56,7 +56,7 @@ public abstract class KotlinAsJavaTestBase extends KotlinTestWithEnvironment {
super.setUp();
KotlinCoreEnvironment environment = getEnvironment();
KotlinTestUtils.resolveAllKotlinFiles(environment);
finder = JavaElementFinder.getInstance(environment.getProject());
finder = JavaElementFinder.Companion.getInstance(environment.getProject());
}
@Override

View File

@@ -17,11 +17,11 @@ import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.Computable
import com.intellij.openapi.util.Pair
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.wm.ToolWindow
import com.intellij.util.Alarm
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
import org.jetbrains.kotlin.codegen.DefaultCodegenFactory
@@ -29,15 +29,20 @@ import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.InfinitePeriodicalTask
import org.jetbrains.kotlin.idea.util.LongRunningReadTask
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.idea.project.targetPlatform
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.utils.join
import java.awt.BorderLayout
import java.awt.FlowLayout
@@ -234,6 +239,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
val state: GenerationState
try {
state = compileSingleFile(ktFile, configuration)
?: return BytecodeGenerationResult.Error("${ktFile.name} is not under project source root.")
} catch (e: ProcessCanceledException) {
throw e
} catch (e: Exception) {
@@ -271,19 +277,21 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
fun compileSingleFile(
ktFile: KtFile,
configuration: CompilerConfiguration
): GenerationState {
val resolutionFacade = ktFile.getResolutionFacade()
): GenerationState? {
val resolutionFacade = KotlinCacheService.getInstance(ktFile.project)
.getResolutionFacadeByFile(ktFile, JvmPlatform)
?: return null
val bindingContextForFile = resolutionFacade.analyzeWithAllCompilerChecks(listOf(ktFile)).bindingContext
val actuals = findActualDeclarationForExpectedFromThisFile(ktFile)
val (bindingContext, toProcess) = DebuggerUtils.analyzeInlinedFunctions(
resolutionFacade, ktFile, configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE),
bindingContextForFile
)
val allFiles = listOf(ktFile) + actuals.map { it.containingKtFile }.distinct()
val bindingContextForFile = resolutionFacade.analyzeWithAllCompilerChecks(allFiles).bindingContext
val (bindingContext, toProcess) = analyzeInlinedFunctions(resolutionFacade, allFiles, configuration, bindingContextForFile)
val generateClassFilter = object : GenerationState.GenerateClassFilter() {
override fun shouldGeneratePackagePart(@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") file: KtFile): Boolean {
return file === ktFile
return file in allFiles
}
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean {
@@ -291,7 +299,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
}
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject): Boolean {
return processingClassOrObject.containingKtFile === ktFile
return processingClassOrObject.containingKtFile === ktFile || processingClassOrObject in actuals
}
override fun shouldGenerateScript(script: KtScript): Boolean {
@@ -300,7 +308,7 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
}
val state = GenerationState.Builder(
ktFile.project, ClassBuilderFactories.TEST, resolutionFacade.moduleDescriptor, bindingContext, toProcess,
ktFile.project, ClassBuilderFactories.TEST, resolutionFacade.moduleDescriptor, bindingContext, toProcess.distinct(),
configuration
)
.generateDeclaredClassFilter(generateClassFilter)
@@ -317,6 +325,34 @@ class KotlinBytecodeToolWindow(private val myProject: Project, private val toolW
return state
}
private fun analyzeInlinedFunctions(
resolutionFacade: ResolutionFacade,
files: List<KtFile>,
configuration: CompilerConfiguration,
bindingContextForFile: BindingContext
): Pair<BindingContext, List<KtFile>> {
return files.fold(bindingContextForFile to emptyList()) { (bindingContext, filesToProcess), file ->
val (newContext, additionalFiles) = DebuggerUtils.analyzeInlinedFunctions(
resolutionFacade, file, configuration.getBoolean(CommonConfigurationKeys.DISABLE_INLINE),
bindingContextForFile
)
newContext to filesToProcess + additionalFiles
}
}
private fun findActualDeclarationForExpectedFromThisFile(
ktFile: KtFile
): List<KtDeclaration> {
val moduleSourceInfo = ktFile.getModuleInfo() as? ModuleSourceInfo
?: return emptyList()
val jvmImplementation = moduleSourceInfo.module.implementingModules.find { it.targetPlatform is TargetPlatformKind.Jvm }
?: return emptyList()
return ktFile.declarations.filter {
it.isExpectDeclaration()
}.flatMap { it.actualsForExpected(jvmImplementation) }
}
private fun mapLines(text: String, startLine: Int, endLine: Int): Pair<Int, Int> {
@Suppress("NAME_SHADOWING")
var startLine = startLine

View File

@@ -83,7 +83,7 @@ class KotlinDecompilerServiceImpl : KotlinDecompilerService {
val configuration = CompilerConfiguration().apply {
languageVersionSettings = file.languageVersionSettings
}
val generationState = KotlinBytecodeToolWindow.compileSingleFile(file, configuration)
val generationState = KotlinBytecodeToolWindow.compileSingleFile(file, configuration) ?: return emptyMap()
val bytecodeMap = hashMapOf<File, () -> ByteArray>()
generationState.factory.asList().filter { FileUtilRt.extensionEquals(it.relativePath, "class") }.forEach {