marijnh/tern — pull request #220 by sqs (2013-08-14 12:29:30+00:00)
Title: [node plugin] Instantiate an AVal instead of failing for node.js stdlib modules that are not predefined

Currently, tern throws an exception if you require a node.js module that `_resolveFilename` resolves successfully to a file that doesn't exist. This occurs for node.js stdlib modules that we haven't predefined, whether because they are not part of the public API (like `_stream_readable`) or because our predefs are not comprehensive (as in #213).

The exception is this (for `require("_stream_readable")`):
```
fs.js:427
return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
^
Error: ENOENT, no such file or directory '/home/sqs/src/tern/test/cases/node/_stream_readable'
at Object.fs.openSync (fs.js:427:18)
at Object.fs.readFileSync (fs.js:284:15)
at Object.getFile (/home/sqs/src/tern/test/runcases.js:50:41)
at ensureFile (/home/sqs/src/tern/lib/tern.js:229:36)
at Object.signal.mixin.addFile (/home/sqs/src/tern/lib/tern.js:103:7)
at resolveModule (/home/sqs/src/tern/plugin/node.js:70:16)
at /home/sqs/src/tern/plugin/node.js:97:16
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)
```

This PR adds a check for file existence before adding the file to avoid throwing an exception in these cases. Instead, a new AVal is returned. Since `_resolveFilename` will only succeed if the module name is valid, this change will only apply to valid modules; it will still return ANull for nonexistent modules.

With this PR, you can use tern on the node.js stdlib itself (since it imports its own private API modules), on code that requires node.js modules that the predefined list doesn't include (perhaps stdlib modules from dev releases of node.js), and on code that imports node.js stdlib private modules.