Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 278172

Summary: [exceptions] ClassCastException (BaseTypeBinding can't be cast to ReferenceBinding) on incorrect JSDoc
Product: [WebTools] JSDT Reporter: Luke Maurer <Luke.Maurer>
Component: GeneralAssignee: Chris Jaun <cmjaun>
Status: RESOLVED FIXED QA Contact: Nitin Dahyabhai <thatnitind>
Severity: normal    
Priority: P3 CC: cmjaun, david_williams, eni.kao, ganoro, jacek.pospychala, myassin, neil.hauge, to.kandy
Version: unspecifiedFlags: thatnitind: pmc_approved? (david_williams)
thatnitind: pmc_approved? (raghunathan.srinivasan)
thatnitind: pmc_approved? (naci.dai)
deboer: pmc_approved+
neil.hauge: pmc_approved+
thatnitind: pmc_approved? (kaloyan)
thatnitind: review+
cmjaun: review+
Target Milestone: 3.2 RC3   
Hardware: PC   
OS: Windows XP   
Whiteboard: PMC_approved
Attachments:
Description Flags
Isolated test case
none
Original file exposing bug
none
Patch for bug 278172
none
updated patch
none
junit patch
none
patch for OperatorExpression
none
updated patch, includes JUnit and operator change none

Description Luke Maurer CLA 2009-05-28 04:45:40 EDT
Created attachment 137449 [details]
Isolated test case

Build ID: I20090430-2300

Steps To Reproduce:
1. Create a clean JavaScript project with only a script with the following:

/**
 * @param {boolean} options
 */
function foo(options) {
    options = options || {};
    if (!options.bar)
        options.bar = 42;
}

2. Let the validator run.


More information:
Any of various messages will show up in the error log, with a traceback always beginning:

java.lang.ClassCastException: org.eclipse.wst.jsdt.internal.compiler.lookup.BaseTypeBinding cannot be cast to org.eclipse.wst.jsdt.internal.compiler.lookup.ReferenceBinding
	at org.eclipse.wst.jsdt.core.infer.InferredType.resolveSuperType(InferredType.java:330)
	at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.findInferredSupertype(ClassScope.java:1160)
	at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.connectSuperclass(ClassScope.java:840)
	at org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope.connectTypeHierarchy(ClassScope.java:1000)
	at org.eclipse.wst.jsdt.internal.compiler.lookup.CompilationUnitScope.connectTypeHierarchy(CompilationUnitScope.java:696)
	at org.eclipse.wst.jsdt.internal.compiler.lookup.LookupEnvironment.completeTypeBindings(LookupEnvironment.java:316)
	at org.eclipse.wst.jsdt.internal.compiler.Compiler.internalBeginToCompile(Compiler.java:576)
	at org.eclipse.wst.jsdt.internal.compiler.Compiler.beginToCompile(Compiler.java:321)

I found this bug after having worked in a project that uses ExtJS 2.2.1, which contains the above error (object misidentified in the JSDoc as boolean) and would cause errors in several different places - code completion, validation, etc. I was using up-to-date Eclipse 3.4 when I first found the problem; currently I'm running Eclipse 3.5 with the same symptoms.
Comment 1 Luke Maurer CLA 2009-05-28 04:48:26 EDT
Created attachment 137450 [details]
Original file exposing bug

When I originally encountered the bug, it was in line 306 of the attached file from ExtJS 2.2.1.
Comment 2 Chris Jaun CLA 2009-05-28 10:49:52 EDT
It looks like JSDT is not correctly converting between the primitive boolean you specified in the JSDoc and the Boolean object. That is why it is returning a BaseTypeBinding(primitive) object when it is expecting a ReferenceBinding because you are using it in an object context.

It probably makes sense to always treat primitives in JSDT as the wrapping object type. 
Comment 3 Luke Maurer CLA 2009-05-28 14:58:04 EDT
(In reply to comment #2)
> It looks like JSDT is not correctly converting between the primitive boolean
> you specified in the JSDoc and the Boolean object. That is why it is returning
> a BaseTypeBinding(primitive) object when it is expecting a ReferenceBinding
> because you are using it in an object context.

It seems to be subtler than that. For instance, if I take out the body of the if statement ("options.bar = 42"), there's no crash, even though the condition itself ("!options.bar") makes the apparent error of getting a property of a primitive boolean.

> It probably makes sense to always treat primitives in JSDT as the wrapping
> object type.

IIUC, there's no functional difference at all to the programmer between boolean and Boolean in JavaScript, so this seems sensible to me.
Comment 4 Chris Jaun CLA 2009-07-24 11:49:47 EDT
*** Bug 284497 has been marked as a duplicate of this bug. ***
Comment 5 Chris Jaun CLA 2009-09-15 13:23:44 EDT
Categorizing JSDT bugzillas for planning purposes.
Comment 6 Chris Jaun CLA 2009-10-29 17:17:25 EDT
*** Bug 290266 has been marked as a duplicate of this bug. ***
Comment 7 Musa CLA 2010-04-27 18:02:49 EDT
Created attachment 166271 [details]
Patch for bug 278172
Comment 8 Chris Jaun CLA 2010-05-18 14:07:09 EDT
Comment on attachment 166271 [details]
Patch for bug 278172

Made some updates to the patch
Comment 9 Chris Jaun CLA 2010-05-18 14:07:43 EDT
Created attachment 168988 [details]
updated patch
Comment 10 Chris Jaun CLA 2010-05-18 14:08:48 EDT
*** Bug 313252 has been marked as a duplicate of this bug. ***
Comment 11 Chris Jaun CLA 2010-05-19 10:27:14 EDT
Created attachment 169117 [details]
junit patch
Comment 12 Chris Jaun CLA 2010-05-19 10:27:34 EDT
Add a junit....ready for your review Nitin.
Comment 13 Nitin Dahyabhai CLA 2010-05-19 17:30:35 EDT
* Explain why you believe this is a stop-ship defect. Or, if it is a "hotbug" (requested by an adopter) please document it as such. 
The CCE stops our "compiler" from being able to construct a model for the file.  Depending on the number of compilation units (files) set into the Compiler at that moment, an unpredictable number of seemingly random files may fail validation or not be available in content assist.

* Is there a work-around? If so, why do you believe the work-around is insufficient? 

Other than changing the user's source, or in one case the ExtJS library source, there is no workaround.

* How has the fix been tested? Is there a test case attached to the bugzilla record? Has a JUnit Test been added?
 
JUnit attached.

* Give a brief technical overview. Who has reviewed this fix?

JavaScript doesn't have primitive types, but we still have binding support for them left over from the JDT codebase.  Problematic for us is that the model doesn't expect to work with primitives, taking the documentation at face-value for choosing the type names.  "boolean" ends up resolving to a primitive, but since it's not a type, we get a CCE.  The long-term fix would be to eliminate BaseTypeBinding altogether and always use ReferenceBindings, but it's simpler just to code a workaround into the InferEngine for this release.

* What is the risk associated with this fix?

Low, as this will alter the interpretation of the documented parameter type when it is first consumed so that it is treated as the proper Boolean type.
Comment 14 Nitin Dahyabhai CLA 2010-05-19 21:29:33 EDT
Committed.
Comment 15 Nitin Dahyabhai CLA 2010-05-19 23:43:11 EDT
Reopening and reverting from HEAD.  Test fails when run as part of suite.
Comment 16 Nitin Dahyabhai CLA 2010-05-19 23:44:49 EDT
Created attachment 169259 [details]
patch for OperatorExpression

Adding an additional patch for OperatorExpression.  I don't think it adequately covers the weirdness that happens with you || a boolean and an Object, or a sequence of Objects looking for the first one that reduces to "not false".
Comment 17 Nitin Dahyabhai CLA 2010-05-19 23:51:01 EDT
Created attachment 169260 [details]
updated patch, includes JUnit and operator change
Comment 18 Chris Jaun CLA 2010-05-20 10:24:55 EDT
What test did you see fail? I had run this against the full suite.
Comment 19 Nitin Dahyabhai CLA 2010-05-20 12:47:17 EDT
(In reply to comment #18)
> What test did you see fail? I had run this against the full suite.

The new one:

----------\n
1. ERROR in Z.js (at line 5)\n
	options = options || {};\n
	          ^^^^^^^^^^^^^\n
The operator || is undefined for the argument type(s) Boolean, ___anonymous79_80\n
----------\n
2. WARNING in Z.js (at line 6)\n
	if (!options.bar)\n
	             ^^^\n
bar cannot be resolved or is not a field\n
----------\n
Comment 20 Chris Jaun CLA 2010-05-24 10:07:12 EDT
I will fix that junit failure today and re-submit for approval in RC3.
Comment 21 Chris Jaun CLA 2010-05-24 17:40:00 EDT
With Nitin's updated patch I do not see any related test failures.

The operator fix looks correct to me.
Comment 22 Nitin Dahyabhai CLA 2010-05-25 01:13:10 EDT
See comment 13 for PMC Review questionnaire.
Comment 23 Chris Jaun CLA 2010-05-25 11:29:19 EDT
*** Bug 314224 has been marked as a duplicate of this bug. ***
Comment 24 Chris Jaun CLA 2010-05-25 17:32:11 EDT
Patch applied.