Methodenaufruf beim Aufruf überladener Methoden teilweise falsch #332
Labels
No Label
Codegen
confirmed
duplicate
Eclipse-Plugin
Feature Request
generics
in progress
invalid
JavaCompilerCore
needs info
Parser
Trash
Type
Unify
won't fix
works for me
No Milestone
No project
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: JavaTX/JavaCompilerCore#332
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Es gab den gleichen Bug schon einmal #307, inzwischen tritt er allerdings nur noch auf, wenn ich Java und Jav Dateien mixe. Zumindest hab ich den alten Bug #307 jetzt einige male ausprobiert und er ist nicht aufgetreten. Aber da der Bug nur manchmal auftritt habe ich vielleicht einfach nicht lange genug getestet.
Der Testaufbau ist ein bisschen umständlich, da es zirkuläre Imports zwischen den Java und Jav Dateien gibt.
Daher muss die Jav Datei zusätzlich auch als Java Datei vorliegen, damit man es initial compilerbar ist.
Ich habe die notwendigen Dateien in den Anhang geladen.
Auf einem unixoiden System sollte mit dem folgenden Befehl der Test automatisiert werden können. Also zip entpacken, in den Ordner gehen und Befehl ausführen.
rm -f *.class && javac Main.java && java -jar JavaTXCompiler.jar Foo.jav && java Main
Achtung, es sollten keine anderen Class Dateien im aktuellen Ordner liegen, sonst werden diese gelöscht!
Die Ausgabe des Befehls variiert wenn man ihn öfter ausführt. Die korrekte Ausgabe wäre "Foo", es wird aber teilweise auch "Object" ausgegeben. Also irgendetwas stimmt wohl in der Typinferenz nicht.
Ich welchen commit gibt es diesen Bug? Bei mir ist die Datei nicht vorhanden
Der Bug ist im aktuellen Commit
974582f7e5
noch vorhanden. Die Dateien sind im Anhang vom Issue alsArchiv 2.zip
.Eigentlich geht es auch nur um die
Foo.jav
Datei, du musst also nur diese Datei mit dem Java-TX-Compiler aufrufen, dann müsste er die visit Methode machmal mit dem Typ Foo und manchmal mit dem Typ Object aufrufen. Die anderen Dateien sollten schon compiliert im Archiv liegen.In der Tat muss das Problem im Bytecodegenerierer liegen. Das Resultset hat zwei Lösungen
class Foo {
Foo()({
})::TPH X
TPH N accept(Bar b)({
((b)::Bar.visit Signature: [TPH P, TPH Q]((this)::TPH O))::TPH R;
return;
})::TPH T
Foo()({
super(()) Signature: [TPH V];
})::TPH W
}
RESULT Final: [
[(TPH R = void), (TPH P = java.lang.Object), (TPH N = void), (TPH O = Foo), (TPH Q = void)],
[(TPH Q = void), (TPH N = void), (TPH P = Foo), (TPH R = void), (TPH O = Foo)]]
Ich kann die Methode nicht überladen weil die dann zweimal die selbe Signatur hat. Sieht so aus als würde ich hier die erste Lösung nehmen und die andere wegschmeißen.
Wieso sollte
TPH P
hier jemalsObject
sein?this
hat doch immer den TypFoo
. Ist die Lösung vielleicht zu generell? Es ist ja beides richtig, nur istFoo
halt der konkretere Typ.Das liegt daran, dass in Bar.java:
public class Bar{
}
visit eine überladene Methode ist und damit P = Object eine Altenative ist.
Habe gerade nochmals mit Julian gesprochen. Es müsste hier in der Tat immer die speziellste Methode ausgesucht werden. Bei der Unifikation wird das schwierig, weil bei ungetypten Überladungen die Typen ja noch nicht bekannt sind. Kann man die speziellste Typisierung bei der Bytecodegenerierung noch feststellen?
Ich kann ohne weiteres feststellen ob eine Methode mit einer anderen kollidieren würde. Ich denke mal man müsste die TPHs der beiden Methoden vergleichen und da irgendwie feststellen welche konkreter ist. Was die Details angeht bin ich mir aber nicht sicher, gibt es eine gute Metrik um festzustellen welche Methode konkreter ist?
Man muss während der Umwandlung vom AST -> TargetAST die TPHs der jeweiligen Methdenaufrufe finden.
Der Methodenaufruf wird nur für den speziellsten Fall generiert
Es werden Überladungen nur den Fällen konstruiert, in denen es keinen speziellsten Fall gibt.