diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisGist.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisGist.java new file mode 100644 index 000000000000..26e19928f714 --- /dev/null +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisGist.java @@ -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. + *

+ * 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> 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> getGist() { + return gist; + } +} diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java index 2c1d1f8e6704..1975ed724d09 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/bytecodeAnalysis/ClassDataIndexer.java @@ -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 String.valueOf(ep.getVersion())).collect(Collectors.joining("-")), 31); - private static final VirtualFileGist> ourGist = GistManager.getInstance().newVirtualFileGist( - "BytecodeAnalysisIndex", FINAL_VERSION, new BytecodeAnalysisIndex.EquationsExternalizer(), new ClassDataIndexer()); @Override public @Nullable Map calcData(Project project, @NotNull VirtualFile file) { @@ -273,7 +271,7 @@ public final class ClassDataIndexer implements VirtualFileGist.GistCalculator { CachedValue> 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); }); }