CadixDev / Mercury

A source transformation and -remapping framework for Java.
Eclipse Public License 2.0
54 stars 23 forks source link

The behavior when resolving bindings is different from `javac` #42

Open CaveNightingale opened 3 years ago

CaveNightingale commented 3 years ago

The inner class Entry is defined in it.unimi.dsi.fastutil.longs.Long2ObjectMap and java.util.Map.Entry, but it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap extends it.unimi.dsi.fastutil.longs.Long2ObjectMap.

So someone wrote the following code.

import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
...
        for(Long2ObjectLinkedOpenHashMap.Entry entry : map.entries())
...

This lead to crash because mercury can't resolve Long2ObjectLinkedOpenHashMap.Entry. However, javac resolves this as it.unimi.dsi.fastutil.longs.Long2ObjectMap$Entry.

CaveNightingale commented 3 years ago

I have checked The Java® Language Specification Java SE 11 Edition and found that the Specification is not clear, they said:

A class inherits from its direct superclass and direct superinterfaces all the non-private member classes and interfaces of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class.

It is possible for a class to inherit more than one member class or interface with the same name, either from its superclass and superinterfaces or from its superinterfaces alone. Such a situation does not in itself cause a compile-time error. However, any attempt within the body of the class to refer to any such member class or interface by its simple name will result in a compile-time error, because the reference is ambiguous.

There might be several paths by which the same member class or interface declaration is inherited from an interface. In such a situation, the member class or interface is considered to be inherited only once, and it may be referred to by its simple name without ambiguity. 

They did not mentioned what to do if a qualified name is ambiguous.

jamierocks commented 3 years ago

Okay, let's clarify a few bits here - just to make sure I'm understanding you correctly.

What class is Mercury failing to remap? Could I have the stack trace?

Beyond that you've provided a helpful analysis, thank you :)

CaveNightingale commented 3 years ago

Okay, let's clarify a few bits here - just to make sure I'm understanding you correctly.

What class is Mercury failing to remap? Could I have the stack trace?

Beyond that you've provided a helpful analysis, thank you :)

It's Paper's Paper-Server/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java that can't be remapped. And the stack trace is

java.lang.RuntimeException: Failed to process: /home/billy/Projects/Paper/Paper-Server/src/main/java/com/destroystokyo/paper/util/misc/AreaMap.java
    at org.cadixdev.mercury.Mercury.accept(Mercury.java:250)
    at org.cadixdev.mercury.Mercury$Requestor.acceptAST(Mercury.java:273)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:1065)
    at org.eclipse.jdt.core.dom.CompilationUnitResolver.resolve(CompilationUnitResolver.java:661)
    at org.eclipse.jdt.core.dom.ASTParser.createASTs(ASTParser.java:1001)
    at org.cadixdev.mercury.Mercury.run(Mercury.java:225)
    at org.cadixdev.mercury.Mercury.rewrite(Mercury.java:180)
    at org.serverct.cavenightingale.psr.Main.main(Main.java:31)
Caused by: java.lang.IllegalStateException: No binding for qualified name node Long2ObjectLinkedOpenHashMap.Entry
    at org.cadixdev.mercury.remapper.RemapperVisitor.visit(RemapperVisitor.java:231)
    at org.eclipse.jdt.core.dom.QualifiedName.accept0(QualifiedName.java:159)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
Caused by: java.lang.IllegalStateException: No binding for qualified name node Long2ObjectLinkedOpenHashMap.Entry

    at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:3060)
    at org.eclipse.jdt.core.dom.SimpleType.accept0(SimpleType.java:195)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:3060)
    at org.eclipse.jdt.core.dom.ParameterizedType.accept0(ParameterizedType.java:164)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:3083)
    at org.eclipse.jdt.core.dom.ParameterizedType.accept0(ParameterizedType.java:165)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:3060)
    at org.eclipse.jdt.core.dom.VariableDeclarationExpression.accept0(VariableDeclarationExpression.java:250)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:3083)
    at org.eclipse.jdt.core.dom.ForStatement.accept0(ForStatement.java:215)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:3083)
    at org.eclipse.jdt.core.dom.Block.accept0(Block.java:128)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChild(ASTNode.java:3060)
    at org.eclipse.jdt.core.dom.MethodDeclaration.accept0(MethodDeclaration.java:698)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:3083)
    at org.eclipse.jdt.core.dom.TypeDeclaration.accept0(TypeDeclaration.java:526)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.eclipse.jdt.core.dom.ASTNode.acceptChildren(ASTNode.java:3083)
    at org.eclipse.jdt.core.dom.CompilationUnit.accept0(CompilationUnit.java:258)
    at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:3012)
    at org.cadixdev.mercury.remapper.MercuryRemapper.rewrite(MercuryRemapper.java:54)
    at org.cadixdev.mercury.SourceRewriter.process(SourceRewriter.java:20)
    at org.cadixdev.mercury.SourceContext.process(SourceContext.java:82)
    at org.cadixdev.mercury.RewriteContext.process(RewriteContext.java:111)
    at org.cadixdev.mercury.Mercury.accept(Mercury.java:248)
    ... 7 more

The main problem is that ecj think Long2ObjectLinkedOpenHashMap.Entry is ambiguous and can't be resolved but javac think it means Long2ObjectMap.Entry.

CaveNightingale commented 3 years ago

No reply?

jamierocks commented 3 years ago

I'm not sure there's anything we could do to resolve this, it appears to be an upstream bug.