1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package com.intellij.psi.impl.compiled;
4 import com.intellij.openapi.diagnostic.Logger;
5 import com.intellij.openapi.vfs.VirtualFile;
6 import com.intellij.psi.compiled.ClassFileDecompilers;
7 import com.intellij.psi.impl.source.JavaFileElementType;
8 import com.intellij.psi.stubs.BinaryFileStubBuilder;
9 import com.intellij.psi.stubs.PsiFileStub;
10 import com.intellij.psi.stubs.Stub;
11 import com.intellij.util.cls.ClsFormatException;
12 import com.intellij.util.indexing.FileContent;
13 import org.jetbrains.annotations.NotNull;
14 import org.jetbrains.annotations.Nullable;
16 import java.util.stream.Stream;
18 import static com.intellij.psi.compiled.ClassFileDecompilers.Full;
20 public class ClassFileStubBuilder implements BinaryFileStubBuilder.CompositeBinaryFileStubBuilder<ClassFileDecompilers.Decompiler> {
21 private static final Logger LOG = Logger.getInstance(ClassFileStubBuilder.class);
23 public static final int STUB_VERSION = 25 + JavaFileElementType.STUB_VERSION;
26 public boolean acceptsFile(@NotNull VirtualFile file) {
31 public @NotNull Stream<ClassFileDecompilers.Decompiler> getAllSubBuilders() {
32 return ClassFileDecompilers.getInstance().EP_NAME.extensions().filter(decompiler -> decompiler instanceof Full);
36 public @Nullable ClassFileDecompilers.Decompiler getSubBuilder(@NotNull FileContent fileContent) {
37 return fileContent.getFile()
38 .computeWithPreloadedContentHint(fileContent.getContent(), () -> ClassFileDecompilers.getInstance().find(fileContent.getFile()));
42 public @NotNull String getSubBuilderVersion(@Nullable ClassFileDecompilers.Decompiler decompiler) {
43 if (decompiler == null) return "default";
44 int version = decompiler instanceof Full ? ((Full)decompiler).getStubBuilder().getStubVersion() : 0;
45 return decompiler.getClass().getName() + ":" + version;
49 public @Nullable Stub buildStubTree(@NotNull FileContent fileContent, @Nullable ClassFileDecompilers.Decompiler decompiler) {
50 return fileContent.getFile().computeWithPreloadedContentHint(fileContent.getContent(), () -> {
51 VirtualFile file = fileContent.getFile();
53 if (decompiler instanceof Full) {
54 return ((Full)decompiler).getStubBuilder().buildFileStub(fileContent);
57 catch (ClsFormatException e) {
58 if (LOG.isDebugEnabled()) LOG.debug(file.getPath(), e);
59 else LOG.info(file.getPath() + ": " + e.getMessage());
63 PsiFileStub<?> stub = ClsFileImpl.buildFileStub(file, fileContent.getContent());
64 if (stub == null && fileContent.getFileName().indexOf('$') < 0) {
65 LOG.info("No stub built for the file " + fileContent);
69 catch (ClsFormatException e) {
70 if (LOG.isDebugEnabled()) LOG.debug(file.getPath(), e);
71 else LOG.info(file.getPath() + ": " + e.getMessage());
79 public int getStubVersion() {