diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompositeBindingContext.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompositeBindingContext.kt index adb1665f38d..ec63b349312 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompositeBindingContext.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompositeBindingContext.kt @@ -45,11 +45,10 @@ public class CompositeBindingContext private ( } override fun getSliceContents(slice: ReadOnlySlice): ImmutableMap { - val builder = ImmutableMap.builder()!! - for (delegate in delegates) { - builder.putAll(delegate.getSliceContents(slice)) - } - return builder.build()!! + //we need intermediate map cause ImmutableMap doesn't support same entries obtained from different slices + var map = hashMapOf() + delegates.forEach { map.putAll(it.getSliceContents(slice)) } + return ImmutableMap.builder().putAll(map).build() } override fun getDiagnostics(): Diagnostics { diff --git a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java index ffb3c5b44e1..56dfe9d48eb 100644 --- a/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java +++ b/idea/src/org/jetbrains/kotlin/idea/internal/KotlinBytecodeToolWindow.java @@ -31,6 +31,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.ToolWindow; import com.intellij.openapi.wm.ToolWindowFactory; +import com.intellij.psi.PsiElement; import com.intellij.ui.content.ContentFactory; import com.intellij.ui.content.ContentManager; import com.intellij.util.Alarm; @@ -43,21 +44,28 @@ import org.jetbrains.kotlin.codegen.CompilationErrorHandler; import org.jetbrains.kotlin.codegen.KotlinCodegenFacade; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.Progress; +import org.jetbrains.kotlin.descriptors.CallableDescriptor; +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor; import org.jetbrains.kotlin.diagnostics.DiagnosticSink; +import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService; import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToDeclarationUtil; 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.psi.Call; +import org.jetbrains.kotlin.psi.JetElement; import org.jetbrains.kotlin.psi.JetFile; +import org.jetbrains.kotlin.resolve.BindingContext; +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall; +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor; import javax.swing.*; import java.awt.*; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.ArrayList; -import java.util.Collections; +import java.util.*; import java.util.List; -import java.util.Scanner; public class KotlinBytecodeToolWindow extends JPanel implements Disposable { private static final int UPDATE_DELAY = 1000; @@ -108,14 +116,21 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { GenerationState state; try { AnalysisResult result = ResolvePackage.analyzeFullyAndGetResult(jetFile); + boolean disableInline = !enableInline.isSelected(); + + if (!disableInline) { + result = processInlinedDeclarations(jetFile.getProject(), result, Collections.singleton(jetFile), 1); + } + if (result.isError()) { return printStackTraceToString(result.getError()); } + state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF, result.getModuleDescriptor(), result.getBindingContext(), Collections.singletonList(jetFile), !enableAssertions.isSelected(), !enableAssertions.isSelected(), GenerationState.GenerateClassFilter.GENERATE_ALL, - !enableInline.isSelected(), !enableOptimization.isSelected(), null, null, + disableInline, !enableOptimization.isSelected(), null, null, DiagnosticSink.DO_NOTHING, null); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); } @@ -139,6 +154,34 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable { return answer.toString(); } + private AnalysisResult processInlinedDeclarations(Project project, AnalysisResult result, Set originalElements, int deep) { + if (deep >= 10 || result.isError()) { + return result; + } + Set collectedElements = new HashSet(); + collectedElements.addAll(originalElements); + Map> contents = result.getBindingContext().getSliceContents(BindingContext.RESOLVED_CALL); + Collection> values = contents.values(); + for (ResolvedCall call : values) { + CallableDescriptor descriptor = call.getResultingDescriptor(); + if (!(descriptor instanceof DeserializedSimpleFunctionDescriptor)) { + if (descriptor instanceof SimpleFunctionDescriptor && + ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline()) { + PsiElement declaration = + DescriptorToDeclarationUtil.INSTANCE$.getDeclaration(project, descriptor); + if (declaration != null && declaration instanceof JetElement) { + collectedElements.add((JetElement) declaration); + } + } + } + } + if (collectedElements.size() != originalElements.size()) { + AnalysisResult newResult = KotlinCacheService.getInstance(project).getAnalysisResults(collectedElements); + return processInlinedDeclarations(project, newResult, collectedElements, deep + 1); + } + return result; + } + @Override protected void onResultReady(@NotNull Location requestInfo, String resultText) { Editor editor = requestInfo.getEditor();