Skip to content

Commit e4af4c6

Browse files
committed
Fix BEAM Stub Indexing and Platform compatibility
- Refactor `ModuleStubElementTypes` to an interface with top-level Kotlin classes to satisfy `StubElementTypeHolderEP` requirements. - Update `ModuleStubElementType` to use the correct `BEAM` Language instance. - Align External IDs with field names (UPPER_CASE) to enable the `externalIdPrefix` optimization. - Increment `STUB_VERSION` to force re-indexing of incompatible data.
1 parent 0a7cf3b commit e4af4c6

File tree

7 files changed

+153
-147
lines changed

7 files changed

+153
-147
lines changed

resources/META-INF/plugin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
<fileType name="BEAM" implementationClass="org.elixir_lang.beam.FileType" fieldName="INSTANCE" language="BEAM"
150150
extensions="beam"/>
151151
<structureViewBuilder key="BEAM" factoryClass="org.elixir_lang.beam.StructureViewBuilderProvider"/>
152-
<stubElementTypeHolder class="org.elixir_lang.beam.psi.stubs.ModuleStubElementTypes" externalIdPrefix="elixir.implementedProtocolName"/>
152+
<stubElementTypeHolder class="org.elixir_lang.beam.psi.stubs.ModuleStubElementTypes" externalIdPrefix="beam."/>
153153
<syntaxHighlighter key="BEAM" factoryClass="org.elixir_lang.ElixirSyntaxHighlighterFactory"/>
154154

155155
<!-- `.beam.asm` -->

src/org/elixir_lang/beam/StubBuilder.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ class StubBuilder : BinaryFileStubBuilder {
3030

3131
companion object {
3232
private val LOGGER = Logger.getInstance(StubBuilder::class.java)
33-
private const val STUB_VERSION = 1
33+
private const val STUB_VERSION = 2
3434
}
3535
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.elixir_lang.beam.psi.stubs
2+
3+
import com.intellij.lang.ASTNode
4+
import com.intellij.psi.stubs.IndexSink
5+
import com.intellij.psi.stubs.StubElement
6+
import com.intellij.psi.stubs.StubInputStream
7+
import com.intellij.psi.stubs.StubOutputStream
8+
import org.elixir_lang.beam.psi.CallDefinition
9+
import org.elixir_lang.beam.psi.CallDefinitionElement
10+
import org.elixir_lang.beam.psi.impl.CallDefinitionImpl
11+
import org.elixir_lang.beam.psi.impl.CallDefinitionStubImpl
12+
import org.elixir_lang.psi.stub.call.Deserialized
13+
import org.elixir_lang.psi.stub.type.Named.Companion.indexStubbic
14+
import java.io.IOException
15+
16+
class CallDefinitionType(debugName: String) : ModuleElementType<CallDefinitionStub<*>, CallDefinition>(debugName) {
17+
override fun createCompositeNode(): ASTNode = CallDefinitionElement(this)
18+
19+
override fun createPsi(stub: CallDefinitionStub<*>): CallDefinition = CallDefinitionImpl(stub)
20+
21+
@Throws(IOException::class)
22+
override fun deserialize(stubInputStream: StubInputStream, parentStub: StubElement<*>): CallDefinitionStub<*> {
23+
val deserialized = Deserialized.deserialize(stubInputStream)
24+
val callDefinitionClauseArity = deserializeCallDefinitionClauseArity(stubInputStream)
25+
26+
return CallDefinitionStubImpl<CallDefinition>(
27+
parentStub as ModuleStub<*>,
28+
deserialized,
29+
callDefinitionClauseArity
30+
)
31+
}
32+
33+
@Throws(IOException::class)
34+
private fun deserializeCallDefinitionClauseArity(stubInputStream: StubInputStream): Int {
35+
return Deserialized.readGuarded(stubInputStream) { it.readVarInt() }
36+
}
37+
38+
@Throws(IOException::class)
39+
override fun serialize(stub: CallDefinitionStub<*>, stubOutputStream: StubOutputStream) {
40+
Deserialized.serialize(stubOutputStream, stub)
41+
Deserialized.writeGuarded(stubOutputStream) { guardedStream ->
42+
guardedStream.writeVarInt(stub.callDefinitionClauseHeadArity())
43+
}
44+
}
45+
46+
override fun indexStub(stub: CallDefinitionStub<*>, sink: IndexSink) {
47+
indexStubbic(stub, sink)
48+
}
49+
}

src/org/elixir_lang/beam/psi/stubs/ModuleStubElementType.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22

33
import com.intellij.lang.ASTNode;
44
import com.intellij.psi.PsiElement;
5-
import com.intellij.psi.stubs.*;
5+
import com.intellij.psi.stubs.ILightStubElementType;
6+
import com.intellij.psi.stubs.StubElement;
67
import com.intellij.psi.tree.ICompositeElementType;
7-
import org.elixir_lang.ElixirLanguage;
8+
import org.elixir_lang.beam.Language;
89
import org.jetbrains.annotations.NonNls;
910
import org.jetbrains.annotations.NotNull;
1011

1112
public abstract class ModuleStubElementType<S extends StubElement<?>, P extends PsiElement>
1213
extends ILightStubElementType<S, P> implements ICompositeElementType {
1314
protected ModuleStubElementType(@NotNull @NonNls String debugName) {
14-
super(debugName, ElixirLanguage.INSTANCE);
15+
super(debugName, Language.INSTANCE);
1516
}
1617

1718
@SuppressWarnings("MethodOverloadsMethodOfSuperclass")
1819
public abstract P createPsi(@NotNull ASTNode node);
1920

2021
@Override
21-
public S createStub(@NotNull P psi, StubElement<?> parentStub) {
22+
public @NotNull S createStub(@NotNull P psi, StubElement<? extends PsiElement> parentStub) {
2223
final String message = "Should not be called. Element=" + psi +
2324
"; class" + psi.getClass() +
2425
"; file=" + (psi.isValid() ? psi.getContainingFile() : "-");
@@ -29,6 +30,6 @@ public S createStub(@NotNull P psi, StubElement<?> parentStub) {
2930
@NotNull
3031
@Override
3132
public String getExternalId() {
32-
return "beam." + toString();
33+
return "beam." + this;
3334
}
3435
}
Lines changed: 6 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -1,145 +1,11 @@
11
package org.elixir_lang.beam.psi.stubs;
22

3-
import com.intellij.lang.ASTNode;
4-
import com.intellij.psi.stubs.IndexSink;
5-
import com.intellij.psi.stubs.StubElement;
6-
import com.intellij.psi.stubs.StubInputStream;
7-
import com.intellij.psi.stubs.StubOutputStream;
8-
import org.elixir_lang.beam.psi.*;
9-
import org.elixir_lang.beam.psi.impl.*;
10-
import org.elixir_lang.psi.stub.call.Deserialized;
11-
import org.elixir_lang.psi.stub.index.AllName;
12-
import org.elixir_lang.type.Visibility;
13-
import org.jetbrains.annotations.NotNull;
3+
import org.elixir_lang.beam.psi.CallDefinition;
4+
import org.elixir_lang.beam.psi.TypeDefinition;
5+
import org.elixir_lang.beam.psi.Module;
146

15-
import java.io.IOException;
16-
17-
import static org.elixir_lang.psi.stub.call.Deserialized.readGuarded;
18-
import static org.elixir_lang.psi.stub.call.Deserialized.writeGuarded;
19-
import static org.elixir_lang.psi.stub.type.Named.indexStubbic;
20-
21-
// See com.intellij.psi.impl.java.stubs.JavaStubElementTypes
227
public interface ModuleStubElementTypes {
23-
/**
24-
* See {@link com.intellij.psi.impl.java.stubs.JavaStubElementTypes#CLASS}
25-
*/
26-
ModuleElementType<ModuleStub<?>, org.elixir_lang.beam.psi.Module> MODULE = new ModuleElementType<ModuleStub<?>, org.elixir_lang.beam.psi.Module>("Module") {
27-
@NotNull
28-
@Override
29-
public ASTNode createCompositeNode() {
30-
return new ModuleElement(this);
31-
}
32-
33-
@Override
34-
public org.elixir_lang.beam.psi.Module createPsi(@NotNull ModuleStub stub) {
35-
return new ModuleImpl<>(stub);
36-
}
37-
38-
@Override
39-
public ModuleStub<?> createStub(@NotNull org.elixir_lang.beam.psi.Module psi, StubElement<?> parentStub) {
40-
return super.createStub(psi, parentStub);
41-
}
42-
43-
@Override
44-
public void serialize(@NotNull ModuleStub<?> stub, @NotNull StubOutputStream stubOutputStream) throws IOException {
45-
Deserialized.serialize(stubOutputStream, stub);
46-
}
47-
48-
@NotNull
49-
@Override
50-
public ModuleStub<?> deserialize(@NotNull StubInputStream stubInputStream,
51-
@NotNull StubElement parentStub) throws IOException {
52-
Deserialized deserialized = Deserialized.deserialize(stubInputStream);
53-
54-
return new ModuleStubImpl(parentStub, deserialized);
55-
}
56-
57-
@Override
58-
public void indexStub(@NotNull ModuleStub<?> stub, @NotNull IndexSink sink) {
59-
indexStubbic(stub, sink);
60-
}
61-
};
62-
63-
ModuleElementType<TypeDefinitionStub<?>, TypeDefinition> TYPE_DEFINITION = new ModuleElementType<TypeDefinitionStub<?>, TypeDefinition>("TypeDefinition") {
64-
@NotNull
65-
@Override
66-
public ASTNode createCompositeNode() {
67-
return new TypeDefinitionElement(this);
68-
}
69-
70-
@Override
71-
public TypeDefinition createPsi(@NotNull TypeDefinitionStub<?> stub) {
72-
return new TypeDefinitionImpl<>(stub);
73-
}
74-
75-
@Override
76-
public TypeDefinitionStub<?> createStub(@NotNull TypeDefinition psi, StubElement<?> parentStub) {
77-
return super.createStub(psi, parentStub);
78-
}
79-
80-
@NotNull
81-
@Override
82-
public TypeDefinitionStub<?> deserialize(@NotNull StubInputStream dataStream, StubElement parentStub) throws IOException {
83-
Visibility visibility = Visibility.valueOf(dataStream.readNameString());
84-
String name = dataStream.readNameString();
85-
int arity = dataStream.readVarInt();
86-
87-
return new TypeDefinitionStubImpl((ModuleStubImpl<ModuleImpl<?>>) parentStub, visibility, name, arity);
88-
}
89-
90-
@Override
91-
public void serialize(@NotNull TypeDefinitionStub<?> stub, @NotNull StubOutputStream stubOutputStream) throws IOException {
92-
stubOutputStream.writeName(stub.getVisibility().toString());
93-
stubOutputStream.writeName(stub.getName());
94-
stubOutputStream.writeVarInt(stub.getArity());
95-
}
96-
97-
@Override
98-
public void indexStub(@NotNull TypeDefinitionStub<?> stub, @NotNull IndexSink sink) {
99-
sink.occurrence(AllName.KEY, stub.getName());
100-
}
101-
};
102-
103-
ModuleElementType<CallDefinitionStub<?>, CallDefinition> CALL_DEFINITION = new ModuleElementType<CallDefinitionStub<?>, CallDefinition>("CallDefinition") {
104-
@NotNull
105-
@Override
106-
public ASTNode createCompositeNode() {
107-
return new CallDefinitionElement(this);
108-
}
109-
110-
@Override
111-
public CallDefinition createPsi(@NotNull CallDefinitionStub stub) {
112-
return new CallDefinitionImpl<>(stub);
113-
}
114-
115-
@NotNull
116-
@Override
117-
public CallDefinitionStub<?> deserialize(@NotNull StubInputStream stubInputStream,
118-
@NotNull StubElement parentStub) throws IOException {
119-
Deserialized deserialized = Deserialized.deserialize(stubInputStream);
120-
int callDefinitionClauseArity = deserializeCallDefinitionClauseArity(stubInputStream);
121-
122-
return new CallDefinitionStubImpl((ModuleStub<?>) parentStub, deserialized, callDefinitionClauseArity);
123-
}
124-
125-
int deserializeCallDefinitionClauseArity(@NotNull StubInputStream stubInputStream) throws IOException {
126-
return readGuarded(stubInputStream, StubInputStream::readVarInt);
127-
}
128-
129-
@Override
130-
public void serialize(@NotNull CallDefinitionStub stub,
131-
@NotNull StubOutputStream stubOutputStream) throws IOException {
132-
Deserialized.serialize(stubOutputStream, stub);
133-
writeGuarded(
134-
stubOutputStream,
135-
guardedStubOutputStream -> guardedStubOutputStream.writeVarInt(stub.callDefinitionClauseHeadArity())
136-
);
137-
}
138-
139-
@Override
140-
public void indexStub(@NotNull CallDefinitionStub<?> stub, @NotNull IndexSink sink) {
141-
indexStubbic(stub, sink);
142-
}
143-
};
144-
8+
ModuleElementType<ModuleStub<?>, Module> MODULE = new ModuleType("MODULE");
9+
ModuleElementType<TypeDefinitionStub<?>, TypeDefinition> TYPE_DEFINITION = new TypeDefinitionType("TYPE_DEFINITION");
10+
ModuleElementType<CallDefinitionStub<?>, CallDefinition> CALL_DEFINITION = new CallDefinitionType("CALL_DEFINITION");
14511
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package org.elixir_lang.beam.psi.stubs
2+
3+
import com.intellij.lang.ASTNode
4+
import com.intellij.psi.PsiElement
5+
import com.intellij.psi.stubs.IndexSink
6+
import com.intellij.psi.stubs.StubElement
7+
import com.intellij.psi.stubs.StubInputStream
8+
import com.intellij.psi.stubs.StubOutputStream
9+
import org.elixir_lang.beam.psi.Module
10+
import org.elixir_lang.beam.psi.ModuleElement
11+
import org.elixir_lang.beam.psi.impl.ModuleImpl
12+
import org.elixir_lang.beam.psi.impl.ModuleStubImpl
13+
import org.elixir_lang.psi.stub.call.Deserialized
14+
import org.elixir_lang.psi.stub.type.Named.Companion.indexStubbic
15+
import java.io.IOException
16+
17+
class ModuleType(debugName: String) : ModuleElementType<ModuleStub<*>, Module>(debugName) {
18+
override fun createCompositeNode(): ASTNode = ModuleElement(this)
19+
20+
override fun createPsi(stub: ModuleStub<*>): Module = ModuleImpl(stub)
21+
22+
override fun createStub(psi: Module, parentStub: StubElement<out PsiElement>): ModuleStub<*> =
23+
super.createStub(psi, parentStub)
24+
25+
@Throws(IOException::class)
26+
override fun serialize(stub: ModuleStub<*>, stubOutputStream: StubOutputStream) {
27+
Deserialized.serialize(stubOutputStream, stub)
28+
}
29+
30+
@Throws(IOException::class)
31+
override fun deserialize(stubInputStream: StubInputStream, parentStub: StubElement<*>): ModuleStub<*> {
32+
val deserialized = Deserialized.deserialize(stubInputStream)
33+
return ModuleStubImpl<Module>(parentStub, deserialized)
34+
}
35+
36+
override fun indexStub(stub: ModuleStub<*>, sink: IndexSink) {
37+
indexStubbic(stub, sink)
38+
}
39+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package org.elixir_lang.beam.psi.stubs
2+
3+
import com.intellij.lang.ASTNode
4+
import com.intellij.psi.PsiElement
5+
import com.intellij.psi.stubs.IndexSink
6+
import com.intellij.psi.stubs.StubElement
7+
import com.intellij.psi.stubs.StubInputStream
8+
import com.intellij.psi.stubs.StubOutputStream
9+
import org.elixir_lang.beam.psi.TypeDefinition
10+
import org.elixir_lang.beam.psi.TypeDefinitionElement
11+
import org.elixir_lang.beam.psi.impl.TypeDefinitionImpl
12+
import org.elixir_lang.beam.psi.impl.TypeDefinitionStubImpl
13+
import org.elixir_lang.psi.stub.index.AllName
14+
import org.elixir_lang.type.Visibility
15+
import java.io.IOException
16+
17+
class TypeDefinitionType(debugName: String) : ModuleElementType<TypeDefinitionStub<*>, TypeDefinition>(debugName) {
18+
override fun createCompositeNode(): ASTNode = TypeDefinitionElement(this)
19+
20+
override fun createPsi(stub: TypeDefinitionStub<*>): TypeDefinition = TypeDefinitionImpl(stub)
21+
22+
override fun createStub(psi: TypeDefinition, parentStub: StubElement<out PsiElement>): TypeDefinitionStub<*> =
23+
super.createStub(psi, parentStub)
24+
25+
@Throws(IOException::class)
26+
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<*>): TypeDefinitionStub<*> {
27+
val visibility = Visibility.valueOf(dataStream.readNameString()!!)
28+
val name = dataStream.readNameString()!!
29+
val arity = dataStream.readVarInt()
30+
31+
// FIX: Explicit generic type <TypeDefinition> and cast parentStub to ModuleStub<*>
32+
@Suppress("UNCHECKED_CAST")
33+
return TypeDefinitionStubImpl<TypeDefinition>(
34+
parentStub as ModuleStub<*>,
35+
visibility,
36+
name,
37+
arity
38+
)
39+
}
40+
41+
@Throws(IOException::class)
42+
override fun serialize(stub: TypeDefinitionStub<*>, stubOutputStream: StubOutputStream) {
43+
stubOutputStream.writeName(stub.visibility.toString())
44+
stubOutputStream.writeName(stub.name)
45+
stubOutputStream.writeVarInt(stub.arity)
46+
}
47+
48+
override fun indexStub(stub: TypeDefinitionStub<*>, sink: IndexSink) {
49+
sink.occurrence(AllName.KEY, stub.name)
50+
}
51+
}

0 commit comments

Comments
 (0)