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> {
|
||||
val builder = ImmutableMap.builder<K, V>()!!
|
||||
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<K, V>()
|
||||
delegates.forEach { map.putAll(it.getSliceContents(slice)) }
|
||||
return ImmutableMap.builder<K, V>().putAll(map).build()
|
||||
}
|
||||
|
||||
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.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.<JetElement>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<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
|
||||
protected void onResultReady(@NotNull Location requestInfo, String resultText) {
|
||||
Editor editor = requestInfo.getEditor();
|
||||
|
||||
Reference in New Issue
Block a user