LSP-390 ClassDataIndexer: extract bytecode analysis gist to a service class

GitOrigin-RevId: d025f80292cca8a7ca9961be1e7318961a9dc3cf
This commit is contained in:
Bartek Pacia
2026-01-13 18:51:52 +00:00
committed by intellij-monorepo-bot
parent d48d17524e
commit fa34bb71df
2 changed files with 43 additions and 6 deletions
@@ -0,0 +1,39 @@
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.bytecodeAnalysis;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.Service;
import com.intellij.util.gist.GistManager;
import com.intellij.util.gist.VirtualFileGist;
import org.jetbrains.annotations.NotNull;
import java.util.Map;
/**
* Holds the {@link VirtualFileGist} for bytecode analysis.
* <p>
* This is a separate service to avoid accessing {@link GistManager} during static class initialization of {@link ClassDataIndexer},
* which violates platform rules (class initialization must not depend on services).
* See LSP-390 to learn more.
*/
@Service
public final class BytecodeAnalysisGist {
private final VirtualFileGist<Map<HMember, Equations>> gist;
public BytecodeAnalysisGist() {
gist = GistManager.getInstance().newVirtualFileGist(
"BytecodeAnalysisIndex",
ClassDataIndexer.FINAL_VERSION,
new BytecodeAnalysisIndex.EquationsExternalizer(),
new ClassDataIndexer()
);
}
public static @NotNull BytecodeAnalysisGist getInstance() {
return ApplicationManager.getApplication().getService(BytecodeAnalysisGist.class);
}
public @NotNull VirtualFileGist<Map<HMember, Equations>> getGist() {
return gist;
}
}
@@ -13,10 +13,10 @@ import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.util.CachedValueImpl;
import com.intellij.util.gist.VirtualFileGist;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.gist.GistManager;
import com.intellij.util.gist.VirtualFileGist;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.io.UnsyncByteArrayOutputStream;
import one.util.streamex.StreamEx;
@@ -62,11 +62,9 @@ public final class ClassDataIndexer implements VirtualFileGist.GistCalculator<Ma
private static final int VERSION = 19; // change when inference algorithm changes
private static final int VERSION_MODIFIER = HardCodedPurity.AGGRESSIVE_HARDCODED_PURITY ? 1 : 0;
private static final int FINAL_VERSION = VERSION * 2 + VERSION_MODIFIER + StringHash.murmur(
static final int FINAL_VERSION = VERSION * 2 + VERSION_MODIFIER + StringHash.murmur(
BytecodeAnalysisSuppressor.EP_NAME.getExtensionList().stream().map(ep -> String.valueOf(ep.getVersion())).collect(Collectors.joining("-")),
31);
private static final VirtualFileGist<Map<HMember, Equations>> ourGist = GistManager.getInstance().newVirtualFileGist(
"BytecodeAnalysisIndex", FINAL_VERSION, new BytecodeAnalysisIndex.EquationsExternalizer(), new ClassDataIndexer());
@Override
public @Nullable Map<HMember, Equations> calcData(Project project, @NotNull VirtualFile file) {
@@ -273,7 +271,7 @@ public final class ClassDataIndexer implements VirtualFileGist.GistCalculator<Ma
FileBasedIndex.getInstance().getContainingFiles(BytecodeAnalysisIndex.NAME, key, scope),
file -> {
CachedValue<Map<HMember, Equations>> equations = ConcurrencyUtil.computeIfAbsent(file, EQUATIONS, () ->
new CachedValueImpl<>(() -> CachedValueProvider.Result.create(ourGist.getFileData(null, file), file)));
new CachedValueImpl<>(() -> CachedValueProvider.Result.create(BytecodeAnalysisGist.getInstance().getGist().getFileData(null, file), file)));
return equations.getValue().get(key);
});
}