Cannot find classes after change branches

Answered

I have custom language plugin with language which based on Java language. In Java syntax just added new keywords. Therefore, most features of java implementation reuse.

final public class CustomLanguage extends Language {
public static final String LANGUAGE_ID = "CustomJava";
public static final CustomLanguage INSTANCE = new CustomLanguage();

private CustomLanguage() {
super(JavaLanguage.INSTANCE, LANGUAGE_ID, "text/x-java-source", "text/java", "application/x-java", "text/x-java");
}
}

And I have a project written in this Custom language. I have two committed versions: in one, the source code is stored in a directory "src/java", in another - "src".

I checkout branch from "src/java" to "src" and I lost mark source directory (as expected) so I marked it manually. After I opened file written on custom language, and all imports on custom language classes is invalid (could not resolve) but all java classes are valid. Before the checkout all classes was valid (resolved).

JavaFileManagerImpl cannot find custom class (file). com.intellij.psi.impl.file.impl.JavaFileManagerImpl#doFindClasses

final Collection<PsiClass> classes = JavaFullClassNameIndex.getInstance().get(qName.hashCode(), myManager.getProject(), scope);

Method call returns empty collection.

 

Are there any ideas why after the checkout (and mark source directory) the JavaFileManager can not find the file (class)?

Thanks for any help!

 

10 comments
Comment actions Permalink

Were your files reindexed after you switched branches? Can you reproduce this reliably in a debug IDEA instance so that you can put breakpoints?

0
Comment actions Permalink

I saw a message on indexation in the bottom of the IDE.

Where do I must put the breakpoint to find out reindex or not?

Yes, I can reproduce it in the debug mode.

0
Comment actions Permalink

In "map" in com.intellij.psi.stubs.StubUpdatingIndex#getIndexer, you can check if inputData.getFile() is one of yours.

0
Comment actions Permalink

Only java files reindexed after switched branches (after marked directory src as source directory).

UPD

Thanks for the reference!

0
Comment actions Permalink

Do you have your own file element type? Does it extend IStubFileElementType and override shouldBuildStubFor like JavaFileElementType does? Is this shouldBuildStubFor called during reindexing?

0
Comment actions Permalink

Yes, I have. And no, shouldBuildStubFor didn't call during reindexing. It extends JavaFiledElementType.

final public class CustomFileElementType extends JavaFileElementType {

@NotNull
public PsiJavaFileStub deserialize(@NotNull StubInputStream dataStream, nullable StubElement parentStub) throws IOException {
boolean compiled = dataStream.readBoolean();
int level = dataStream.readByte();
val packageName = dataStream.readName();
return new CustomPsiFileStubImpl(null, StringRef.toString(packageName), level >= 0 ? LanguageLevel.values()[level] : null, compiled);
}

public boolean shouldBuildStubFor(VirtualFile file) {
return isInSourceContent(file);
}

// ..

public LightStubBuilder getBuilder() {
return new CustomLightStubBuilder();
}

@NotNull
public Language getLanguage() {
return CustomLanguage.INSTANCE;
}

@NotNull
public String getExternalId() {
return "custom.FILE";
}

public String toString() {
return "custom.FILE";
}
}
0
Comment actions Permalink

I believe the cause is that we have JavaLanguageLevelPusher#persistAttribute which only schedules for reindexing java files. You could try to copy this class, register as an extension and modify so that it handles your files. If this helps, we can think of a way to generalize it to process your files out of the box.

0
Comment actions Permalink

Thank you, it works!

I register extension as first and handle custom and java files. IDEA doesn't call JavaLanguageLevelPusher after my pusher.

It would be cool to get a way to make it out of the box.

final public class CustomFilePusher extends JavaLanguageLevelPusher {
private static final FileAttribute PERSISTENCE = new FileAttribute("language_level_persistence_2", 3, true);

@Override
public implement void persistAttribute(@NotNull Project project, @NotNull VirtualFile fileOrDir, @NotNull LanguageLevel level) throws IOException {
final DataInputStream iStream = PERSISTENCE.readAttribute(fileOrDir);
if (iStream != null) {
try {
final int oldLevelOrdinal = DataInputOutputUtil.readINT(iStream);
if (oldLevelOrdinal == level.ordinal()) return;
} finally {
iStream.close();
}
}

final DataOutputStream oStream = PERSISTENCE.writeAttribute(fileOrDir);
DataInputOutputUtil.writeINT(oStream, level.ordinal());
oStream.close();

for (VirtualFile child : fileOrDir.getChildren()) {
if (!child.isDirectory() && (StdFileTypes.JAVA.equals(child.getFileType()) || CustomFileType.INSTANCE.equals(child.getFileType()))) {
PushedFilePropertiesUpdater.getInstance(project).filePropertiesChanged(child);
}
}
}
}
0
Comment actions Permalink

Pushed a fix into master

0

Please sign in to leave a comment.