marijnh/tern — pull request #225 by sqs (2013-08-24 01:03:34+00:00)
Title: Fix type propagation when reassigning module.exports to a require()'d module

This pattern currently breaks the type inferencer:

```javascript
module.exports = require('./a');
```

It seems to work if `./a` has previously been required (which is why I didn't reuse `secondfile.js`), but otherwise the tests fail with:

```
node, line #: Expression has type
{}
instead of expected type
{A: number}

```

I dug a little bit into the issue but I couldn't find a fix. I did notice that it seemed to be adding a reflexive type constraint on reassign_exports_to_required.js's `module.exports`. I set a breakpoint at plugin/node.js:84, and it was called twice for the `require("mod1/reassign_exports_to_required")` statement, once before `./a` was required and once after. Here is the stack trace for the second time that statement was called, in case it helps:

```
Error: a
at /home/sqs/src/tern/plugin/node.js:84:25
at Object.exports.IsCallee.constraint.addType (/home/sqs/src/tern/lib/infer.js:274:9)
at withWorklist (/home/sqs/src/tern/lib/infer.js:651:21)
at Object.extend.propagate (/home/sqs/src/tern/lib/infer.js:88:25)
at inferExprVisitor.CallExpression (/home/sqs/src/tern/lib/infer.js:1018:16)
at Object.CallExpression (/home/sqs/src/tern/lib/infer.js:865:7)
at infer (/home/sqs/src/tern/lib/infer.js:1050:39)
at inferExprVisitor.AssignmentExpression (/home/sqs/src/tern/lib/infer.js:950:15)
at Object.AssignmentExpression (/home/sqs/src/tern/lib/infer.js:857:15)
at infer (/home/sqs/src/tern/lib/infer.js:1050:39)
```

I will post an update if I find a fix.

(I discovered this problem in socket.io's [index.js](https://github.com/LearnBoost/socket.io/blob/64f6b244b6bd79880ba2e0ba00778a2309b39d0b/index.js).)