Внутренний класс ломает завершение кода Eclipse
У меня серьезная проблема с отключением Eclipse всех дополнений кода в классе Java, который импортирует двоичный файл. Двоичный файл был скомпилирован специальным компилятором для пользовательского языка программирования на основе JVM, и код выглядит следующим образом:
package dyvil.dyn
import dyvil.lang.Map.Entry
public class Test[A, B] implements Entry[A, B]
{
public A getKey() = null
public B getValue() = null
}
Entry
это интерфейс внутри Map
интерфейс, и оба написаны на Java. Компилятор, очевидно, не имеет проблем с этим кодом и выдает следующий байт-код (из javap
):
public class dyvil.dyn.Test<A extends java.lang.Object, B extends java.lang.Object> extends java.lang.Object implements dyvil.lang.Map$Entry<A, B>
Signature: #3 // <A:Ljava/lang/Object;B:Ljava/lang/Object;>Ljava/lang/Object;Ldyvil/lang/Map$Entry<TA;TB;>;
InnerClasses:
public static #10= #7 of #9; //Entry=class dyvil/lang/Map$Entry of class dyvil/lang/Map
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Utf8 dyvil/dyn/Test
#2 = Class #1 // dyvil/dyn/Test
#3 = Utf8 <A:Ljava/lang/Object;B:Ljava/lang/Object;>Ljava/lang/Object;Ldyvil/lang/Map$Entry<TA;TB;>;
#4 = Utf8 java/lang/Object
#5 = Class #4 // java/lang/Object
#6 = Utf8 dyvil/lang/Map$Entry
#7 = Class #6 // dyvil/lang/Map$Entry
#8 = Utf8 dyvil/lang/Map
#9 = Class #8 // dyvil/lang/Map
#10 = Utf8 Entry
#11 = Utf8 <init>
#12 = Utf8 ()V
#13 = NameAndType #11:#12 // "<init>":()V
#14 = Methodref #5.#13 // java/lang/Object."<init>":()V
#15 = Utf8 this
#16 = Utf8 Ldyvil/dyn/Test<TA;TB;>;
#17 = Utf8 Ldyvil/dyn/Test;
#18 = Utf8 getKey
#19 = Utf8 ()Ljava/lang/Object;
#20 = Utf8 getValue
#21 = Utf8 Code
#22 = Utf8 LocalVariableTable
#23 = Utf8 LocalVariableTypeTable
#24 = Utf8 Signature
#25 = Utf8 ()TA;
#26 = Utf8 ()TB;
#27 = Utf8 InnerClasses
{
public dyvil.dyn.Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: return
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 this Ldyvil/dyn/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 4 0 this Ldyvil/dyn/Test<TA;TB;>;
Signature: #12 // ()V
public A getKey();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aconst_null
1: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Ldyvil/dyn/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 1 0 this Ldyvil/dyn/Test<TA;TB;>;
Signature: #25 // ()TA;
public B getValue();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aconst_null
1: areturn
LocalVariableTable:
Start Length Slot Name Signature
0 1 0 this Ldyvil/dyn/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 1 0 this Ldyvil/dyn/Test<TA;TB;>;
Signature: #26 // ()TB;
}
Импорт Test
класс из любого Java-класса заставляет Eclipse жаловаться No completions available
, а также CTRL-Hover
больше не работает. Чтобы найти проблему, я создал и javap
Редактировал Java-эквивалент вышеупомянутого класса, получив следующие результаты:
Test.java:
package dyvil.test;
import dyvil.lang.Map.Entry;
public class Test<A, B> implements Entry<A, B>
{
@Override
public A getKey()
{
return null;
}
@Override
public B getValue()
{
return null;
}
}
Выходные данные javap:
public class dyvil.test.Test<A extends java.lang.Object, B extends java.lang.Object> extends java.lang.Object implements dyvil.lang.Map$Entry<A, B>
SourceFile: "Test.java"
Signature: #26 // <A:Ljava/lang/Object;B:Ljava/lang/Object;>Ljava/lang/Object;Ldyvil/lang/Map$Entry<TA;TB;>;
InnerClasses:
public static #30= #5 of #28; //Entry=class dyvil/lang/Map$Entry of class dyvil/lang/Map
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Class #2 // dyvil/test/Test
#2 = Utf8 dyvil/test/Test
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Class #6 // dyvil/lang/Map$Entry
#6 = Utf8 dyvil/lang/Map$Entry
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Methodref #3.#11 // java/lang/Object."<init>":()V
#11 = NameAndType #7:#8 // "<init>":()V
#12 = Utf8 LineNumberTable
#13 = Utf8 LocalVariableTable
#14 = Utf8 this
#15 = Utf8 Ldyvil/test/Test;
#16 = Utf8 LocalVariableTypeTable
#17 = Utf8 Ldyvil/test/Test<TA;TB;>;
#18 = Utf8 getKey
#19 = Utf8 ()Ljava/lang/Object;
#20 = Utf8 Signature
#21 = Utf8 ()TA;
#22 = Utf8 getValue
#23 = Utf8 ()TB;
#24 = Utf8 SourceFile
#25 = Utf8 Test.java
#26 = Utf8 <A:Ljava/lang/Object;B:Ljava/lang/Object;>Ljava/lang/Object;Ldyvil/lang/Map$Entry<TA;TB;>;
#27 = Utf8 InnerClasses
#28 = Class #29 // dyvil/lang/Map
#29 = Utf8 dyvil/lang/Map
#30 = Utf8 Entry
{
public dyvil.test.Test();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #10 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Ldyvil/test/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 5 0 this Ldyvil/test/Test<TA;TB;>;
public A getKey();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC
Signature: #21 // ()TA;
Code:
stack=1, locals=1, args_size=1
0: aconst_null
1: areturn
LineNumberTable:
line 10: 0
LocalVariableTable:
Start Length Slot Name Signature
0 2 0 this Ldyvil/test/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 2 0 this Ldyvil/test/Test<TA;TB;>;
public B getValue();
descriptor: ()Ljava/lang/Object;
flags: ACC_PUBLIC
Signature: #23 // ()TB;
Code:
stack=1, locals=1, args_size=1
0: aconst_null
1: areturn
LineNumberTable:
line 16: 0
LocalVariableTable:
Start Length Slot Name Signature
0 2 0 this Ldyvil/test/Test;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 2 0 this Ldyvil/test/Test<TA;TB;>;
}
Мне удалось отследить проблему, вызванную тем, что класс implements Entry[A, B]
, но я еще не смог определить фактическую проблему в байт-коде. Что-то не так с байт-кодом, сгенерированным моим компилятором? Помимо названий пакетов и номеров строк и прочего я не могу найти существенную разницу между байт-кодом двух классов.
Если это не ошибка компилятора, у меня есть только ANTLR 4
, Bytecode Outline
а также Eclipse Class Decompiler
плагины.