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

Bug 430416

Summary: Content assist throws error and fails
Product: [ECD] Orion Reporter: Mark Macdonald <mamacdon>
Component: JS ToolsAssignee: Michael Rennie <Michael_Rennie>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: Michael_Rennie
Version: 5.0   
Target Milestone: 6.0 M1   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
broken file none

Description Mark Macdonald CLA 2014-03-14 13:38:21 EDT
Created attachment 240917 [details]
broken file

1. Open the attached file using the Orion editor.
2. When the JS content assist initializes, it throws an error. This prevents you from getting any typed proposals for this file.

Stack trace showing where the error is thrown:
> TypeError: Cannot read property 'split' of undefined
>     at Object.promise.then.lookupQualifiedType (http://localhost:8080/javascript/contentAssist/typeEnvironment.js:479:27)
>     at Object.promise.then.lookupTypeObj (http://localhost:8080/javascript/contentAssist/typeEnvironment.js:495:28)
>     at inferencerPostOp (http://localhost:8080/javascript/contentAssist/typeInference.js:1079:21)
>     at Object.visit (http://localhost:8080/javascript/contentAssist/esprimaVisitor.js:83:6)
>        ...
>     at inferTypes (http://localhost:8080/javascript/contentAssist/typeInference.js:1205:13)

See bug also 429489 comment 2.
Comment 1 Mark Macdonald CLA 2014-03-14 14:06:35 EDT
A bit more debugging. The trouble starts in typeEnvironment.scope(target), which is incorrectly returning undefined.

When that happens, 'target' has this shape:
> {   "type": "Identifier",
>     "name": "parentId",
>     "range": [5741, 5749],
>     "extras": {
>         "inferredTypeObj": {
>             "type": "UnionType",
>             "elements": [
>                 {   "type": "NameExpression",
>                     "name": "String"
>                 },
>                 {   "type": "NameExpression",
>                     "name": "Element"
>                 }
>             ]
>         }
>     }
> }

"UnionType" is not one of the inferredTypeObj types handled in scope(). Control reaches the end of the function (which shouldn't happen) so we get 'undefined'.
Comment 2 Michael Rennie CLA 2014-03-18 15:32:56 EDT
Here is a condensed snippet that causes the problem:

var foo  = {
 /**
  * @param {String|Object} union
  */
 bar: function(union) {
  union = typeof union === "string" ? union : (union.id || union);
 }
};

Put the cursor after 'union' in the assignment and activate content assist.

Looks like we don't properly handle the UnionType from doctrine, as noted in comment #1
Comment 3 Michael Rennie CLA 2014-03-18 17:19:01 EDT
(In reply to Michael Rennie from comment #2)
> Here is a condensed snippet that causes the problem:

An even more condensed snippet:

/**
 * @param {String|Object} union
 */
function f(union) {
  union = union ? union.id : 'baz';
}
Comment 4 Michael Rennie CLA 2014-03-24 15:45:07 EDT
I opened bug 431053 to track the work of actually making union types work properly. For now I committed a fix to stop it from blowing up when a union type is encountered.

Pushed to: http://git.eclipse.org/c/orion/org.eclipse.orion.client.git/commit/?id=fd758a579051a8ea5f17965b8df87fa891893ec3