Community
Participate
Working Groups
Wow, Firefox stole my comment! BETA_JAVA7, after fix for bug 339864 The SelectionEngine needs to handle 1.7 constructs in 1.6 projects gracefully. E.g. when I hover over err here, no IAE should be thrown: package p; import java.io.*; public class Test17 { public static void main(String[] args) { File file = new File(args[0]); try { FileInputStream fis = new FileInputStream(file); fis.read(); } catch (FileNotFoundException | IOException err) { err.printStackTrace(); } } } java.lang.IllegalArgumentException: at org.eclipse.jdt.core.Signature.createCharArrayTypeSignature(Signature.java:631) at org.eclipse.jdt.core.Signature.createTypeSignature(Signature.java:607) at org.eclipse.jdt.internal.core.util.Util.typeSignature(Util.java:2659) at org.eclipse.jdt.internal.core.SelectionRequestor.acceptLocalVariable(SelectionRequestor.java:454) at org.eclipse.jdt.internal.codeassist.SelectionEngine.selectFrom(SelectionEngine.java:1229) at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:944) at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:162) at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:377) at org.eclipse.jdt.internal.core.CompilationUnit.codeSelect(CompilationUnit.java:371) at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:118) at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:562) at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:558) at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:142) at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:85) at org.eclipse.jface.text.TextViewerHoverManager$4.run(TextViewerHoverManager.java:166)
... and my initial analysis was wrong. This also happens in a 1.7 project and seems to be a bug in Util#typeSignature(..). Looks like org.eclipse.jdt.core.Signature needs a new typeSignatureKind.
I'll take a look.
This is related to the method getTypeName() method defined on DisjunctiveTypeReference that returns null. Returning the type name of the first type reference looks wrong. It would be better to return the type name of the lub of all type references, but I don't think we can expect that to be resolved. Srikanth, do you have any idea what would be the best answer here ?
The ILocalVariable 'err' should have a meaningful getTypeSignature(), so I don't think you have much choice other than adding a Signature#DISJUNCTIVE_TYPE_SIGNATURE kind.
I agree with this. We need to come up with a meaningful type name for disjunctive types. I hacked the code so that it won't blow up with an exception during live demos.
(In reply to comment #4) Hmm, I missed the lub when reading the spec the first time. If I understood it right this time, the type of the variable 'err' is always a defined type if the code compiles. So I guess the best solution would be to just use that type. Unfortunately, the type can also be an intersection type and those are currently not surfaced, see bug 99931. Here's a more involved example: package p; public class TestDisjunctiveType { public static void main(String[] args) { try { int option= 1; throw option == 1 ? new ExceptionA() : new ExceptionB(); } catch (/*final*/ ExceptionA | ExceptionB ex) { System.out.println("type of ex: " + ex.getClass()); // next 2 methods on 'ex' use different parts of lub: ex.myMethod(); ex.getCause(); // ex.onlyA(); // undefined for type RuntimeException&Mix throw ex; } } } interface Mix { public void myMethod(); //comment this to make ex.myMethod() fail } class ExceptionA extends RuntimeException implements Mix { public void myMethod() { System.out.println("ExceptionA.myMethod()"); } public void onlyA() { System.out.println("ExceptionA.onlyA()"); } } class ExceptionB extends RuntimeException implements Mix { public void myMethod() { System.out.println("ExceptionB.myMethod()"); } public void onlyB() { System.out.println("ExceptionA.onlyB()"); } }
The signature of a disjunctive type should eventually also show up in the LocalVariableTypeTable attribute in the classfile. Unfortunately, the JSR 334 Draft v0.875 doesn't contain amendments to the VM spec (yet). I expect that the disjunctive type of the exception variable will eventually show up in the LocalVariableTypeTable. Currently, I don't see such an entry neither in class files generated by javac nor from the Eclipse compiler. They both use the lub type for the variable and if that's an intersection type, they take the first bound (which is always a subclass of Throwable). For binary variables, the signature should correspond to the information from the class file.
Created attachment 192772 [details] Proposed fix Needs more work, but it gives an idea on how this would help in the test case described above.
Created attachment 192845 [details] Proposed fix + regression tests Previous patch had wrong references from the model code into the compiler code. This should fix it. It also contains the UI changes to reflect the new type signature kind to display the right value in the hover. More changes might be required in the UI.
Signature#createIntersectionTypeSignature(..): - should be next to the other create*Signature(..) methods - should have a String[] variant Signature should also declare methods getIntersectionTypeBounds(String intersectionTypeSignature) and the char[] equivalent, similar to getTypeArguments(..). JavaElementLabelComposer will use this to extract the individual types and turn them into hyperlinks.
(In reply to comment #11) > Signature#createIntersectionTypeSignature(..): > - should be next to the other create*Signature(..) methods > - should have a String[] variant > > Signature should also declare methods getIntersectionTypeBounds(String > intersectionTypeSignature) and the char[] equivalent, similar to > getTypeArguments(..). JavaElementLabelComposer will use this to extract the > individual types and turn them into hyperlinks. Ok, I'll take care of these. Do you like the way the new type signature kind has been added ?
> Ok, I'll take care of these. Do you like the way the new type signature kind > has been added ? Yes. I first thought the grammar was problematic since there's no clear end token for the list of intersected types. But a parser actually just has to check the next character after a type; if it's not ":", then the intersection type is finished. The Javadoc of getTypeSignatureKind(..) also needs to tell about the new kind.
Created attachment 192864 [details] Proposed fix + regression tests Fixes all reported issues.
Released in BETA_JAVA7 branch only all changes related to JDT/Core. Further changes will be done if needed in separate bug reports.
Verified.