| Summary: | [exceptions] ClassCastException (BaseTypeBinding can't be cast to ReferenceBinding) on incorrect JSDoc | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Product: | [WebTools] JSDT | Reporter: | Luke Maurer <Luke.Maurer> | ||||||||||||||||
| Component: | General | Assignee: | 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: | unspecified | Flags: | 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: |
|
||||||||||||||||||
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.
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. (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. *** Bug 284497 has been marked as a duplicate of this bug. *** Categorizing JSDT bugzillas for planning purposes. *** Bug 290266 has been marked as a duplicate of this bug. *** Created attachment 166271 [details] Patch for bug 278172 Comment on attachment 166271 [details] Patch for bug 278172 Made some updates to the patch Created attachment 168988 [details]
updated patch
*** Bug 313252 has been marked as a duplicate of this bug. *** Created attachment 169117 [details]
junit patch
Add a junit....ready for your review Nitin. * 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. Committed. Reopening and reverting from HEAD. Test fails when run as part of suite. 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".
Created attachment 169260 [details]
updated patch, includes JUnit and operator change
What test did you see fail? I had run this against the full suite. (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 I will fix that junit failure today and re-submit for approval in RC3. With Nitin's updated patch I do not see any related test failures. The operator fix looks correct to me. See comment 13 for PMC Review questionnaire. *** Bug 314224 has been marked as a duplicate of this bug. *** Patch applied. |
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.