Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 340059 - [1.7] IAE when dealing with Signature of disjunctive type
Summary: [1.7] IAE when dealing with Signature of disjunctive type
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.7   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: 3.7.1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 341485
  Show dependency tree
 
Reported: 2011-03-15 13:11 EDT by Markus Keller CLA
Modified: 2011-08-05 02:54 EDT (History)
5 users (show)

See Also:


Attachments
Proposed fix (11.18 KB, patch)
2011-04-07 15:10 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix + regression tests (13.97 KB, patch)
2011-04-08 11:23 EDT, Olivier Thomann CLA
no flags Details | Diff
Proposed fix + regression tests (172.78 KB, patch)
2011-04-08 13:37 EDT, Olivier Thomann CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2011-03-15 13:11:47 EDT

    
Comment 1 Markus Keller CLA 2011-03-15 13:18:57 EDT
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)
Comment 2 Markus Keller CLA 2011-03-15 13:26:06 EDT
... 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.
Comment 3 Olivier Thomann CLA 2011-03-15 13:28:26 EDT
I'll take a look.
Comment 4 Olivier Thomann CLA 2011-03-15 13:39:51 EDT
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 ?
Comment 5 Markus Keller CLA 2011-03-16 08:24:28 EDT
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.
Comment 6 Olivier Thomann CLA 2011-03-18 09:21:23 EDT
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.
Comment 7 Markus Keller CLA 2011-03-18 14:29:50 EDT
(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()");
	}
}
Comment 8 Markus Keller CLA 2011-04-06 14:47:05 EDT
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.
Comment 9 Olivier Thomann CLA 2011-04-07 15:10:04 EDT
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.
Comment 10 Olivier Thomann CLA 2011-04-08 11:23:44 EDT
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.
Comment 11 Markus Keller CLA 2011-04-08 12:51:21 EDT
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.
Comment 12 Olivier Thomann CLA 2011-04-08 12:55:20 EDT
(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 ?
Comment 13 Markus Keller CLA 2011-04-08 13:20:22 EDT
> 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.
Comment 14 Olivier Thomann CLA 2011-04-08 13:37:20 EDT
Created attachment 192864 [details]
Proposed fix + regression tests

Fixes all reported issues.
Comment 15 Olivier Thomann CLA 2011-04-08 13:47:57 EDT
Released in BETA_JAVA7 branch only all changes related to JDT/Core. Further changes will be done if needed in separate bug reports.
Comment 16 Jay Arthanareeswaran CLA 2011-06-28 05:15:13 EDT
Verified.