Analyze inlined declarations in bytecode toolwindow
This commit is contained in:
@@ -45,11 +45,10 @@ public class CompositeBindingContext private (
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun <K, V> getSliceContents(slice: ReadOnlySlice<K, V>): ImmutableMap<K, V> {
|
override fun <K, V> getSliceContents(slice: ReadOnlySlice<K, V>): ImmutableMap<K, V> {
|
||||||
val builder = ImmutableMap.builder<K, V>()!!
|
//we need intermediate map cause ImmutableMap doesn't support same entries obtained from different slices
|
||||||
for (delegate in delegates) {
|
var map = hashMapOf<K, V>()
|
||||||
builder.putAll(delegate.getSliceContents(slice))
|
delegates.forEach { map.putAll(it.getSliceContents(slice)) }
|
||||||
}
|
return ImmutableMap.builder<K, V>().putAll(map).build()
|
||||||
return builder.build()!!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDiagnostics(): Diagnostics {
|
override fun getDiagnostics(): Diagnostics {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.intellij.openapi.util.Pair;
|
|||||||
import com.intellij.openapi.util.text.StringUtil;
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import com.intellij.openapi.wm.ToolWindow;
|
import com.intellij.openapi.wm.ToolWindow;
|
||||||
import com.intellij.openapi.wm.ToolWindowFactory;
|
import com.intellij.openapi.wm.ToolWindowFactory;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.ui.content.ContentFactory;
|
import com.intellij.ui.content.ContentFactory;
|
||||||
import com.intellij.ui.content.ContentManager;
|
import com.intellij.ui.content.ContentManager;
|
||||||
import com.intellij.util.Alarm;
|
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.KotlinCodegenFacade;
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.Progress;
|
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.diagnostics.DiagnosticSink;
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.KotlinCacheService;
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
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.InfinitePeriodicalTask;
|
||||||
import org.jetbrains.kotlin.idea.util.LongRunningReadTask;
|
import org.jetbrains.kotlin.idea.util.LongRunningReadTask;
|
||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil;
|
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.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 javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
|
public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
|
||||||
private static final int UPDATE_DELAY = 1000;
|
private static final int UPDATE_DELAY = 1000;
|
||||||
@@ -108,14 +116,21 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
|
|||||||
GenerationState state;
|
GenerationState state;
|
||||||
try {
|
try {
|
||||||
AnalysisResult result = ResolvePackage.analyzeFullyAndGetResult(jetFile);
|
AnalysisResult result = ResolvePackage.analyzeFullyAndGetResult(jetFile);
|
||||||
|
boolean disableInline = !enableInline.isSelected();
|
||||||
|
|
||||||
|
if (!disableInline) {
|
||||||
|
result = processInlinedDeclarations(jetFile.getProject(), result, Collections.<JetElement>singleton(jetFile), 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (result.isError()) {
|
if (result.isError()) {
|
||||||
return printStackTraceToString(result.getError());
|
return printStackTraceToString(result.getError());
|
||||||
}
|
}
|
||||||
|
|
||||||
state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF,
|
state = new GenerationState(jetFile.getProject(), ClassBuilderFactories.TEST, Progress.DEAF,
|
||||||
result.getModuleDescriptor(), result.getBindingContext(),
|
result.getModuleDescriptor(), result.getBindingContext(),
|
||||||
Collections.singletonList(jetFile), !enableAssertions.isSelected(), !enableAssertions.isSelected(),
|
Collections.singletonList(jetFile), !enableAssertions.isSelected(), !enableAssertions.isSelected(),
|
||||||
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
||||||
!enableInline.isSelected(), !enableOptimization.isSelected(), null, null,
|
disableInline, !enableOptimization.isSelected(), null, null,
|
||||||
DiagnosticSink.DO_NOTHING, null);
|
DiagnosticSink.DO_NOTHING, null);
|
||||||
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
|
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
|
||||||
}
|
}
|
||||||
@@ -139,6 +154,34 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
|
|||||||
return answer.toString();
|
return answer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AnalysisResult processInlinedDeclarations(Project project, AnalysisResult result, Set<JetElement> originalElements, int deep) {
|
||||||
|
if (deep >= 10 || result.isError()) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Set<JetElement> collectedElements = new HashSet<JetElement>();
|
||||||
|
collectedElements.addAll(originalElements);
|
||||||
|
Map<Call, ResolvedCall<?>> contents = result.getBindingContext().getSliceContents(BindingContext.RESOLVED_CALL);
|
||||||
|
Collection<ResolvedCall<?>> 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
|
@Override
|
||||||
protected void onResultReady(@NotNull Location requestInfo, String resultText) {
|
protected void onResultReady(@NotNull Location requestInfo, String resultText) {
|
||||||
Editor editor = requestInfo.getEditor();
|
Editor editor = requestInfo.getEditor();
|
||||||
|
|||||||
Reference in New Issue
Block a user