= Tern Reference Manual =

Tern consists of several components. Depending on what you are trying
to do with it, you will be interested in a different layer. At the
very top are the <<editor,editor plugins>>. These talk to a
<<server,Tern server>>, which is implemented on top of the
<<server_api,server module>>, which uses the <<infer,inference
engine>> to do the actual type inference.

[[contents]]
== Contents ==

* <<server,The Tern server>>
** <<protocol,JSON protocol>>
** <<server_api,Programming interface>>
** <<typedef,JSON type definitions>>
** <<plugins,Server plugins>>
*** <<plugin_doc_comment,Doc comments>>
*** <<plugin_complete_strings,String completion>>
*** <<plugin_commonjs,CommonJS modules>>
*** <<plugin_node,node>>
*** <<plugin_node_resolve,node-style module resolution>>
*** <<plugin_modules,Module-loading infrastructure>>
*** <<plugin_es_modules,ES6 module support>>
*** <<plugin_requirejs,RequireJS>>
*** <<plugin_angular,Angular.js>>
*** <<plugin_third_party,Third-party plugins>>
** <<configuration,Project configuration>>
** <<utils,Utilities>>
* <<infer,Inference engine>>
** <<infer_context,Context>>
** <<infer_analysis,Analysis>>
** <<infer_types,Types>>
** <<infer_aval,Abstract values>>
** <<infer_constraint,Constraints>>
** <<infer_scopes,Scopes>>
** <<infer_util,Utilities>>
* <<editor,Editor plugins>>
** <<emacs,Emacs>>
** <<vim,Vim>>
** <<sublime_text,Sublime Text>>
** <<tern_java,Eclipse>>
** <<tern_for_gedit,Gedit>>
* <<software,Related Software>>

[[server]]
== The Tern server ==

The `bin/tern` 'binary' (http://nodejs.org[node.js] script, really),
is used to start a Tern server. You will usually want to let an
<<plugins,editor plugin>> start it for you, but it can be started
manually, which can be useful for debugging.

(Note that the basic structure of the server is also available through
a <<server_api,programming interface>>, and that some project,
especially those running client-side in a browser, will want to use
that instead of the HTTP server described here.)

[[project_file]]
When started, the server will look for a `.tern-project` file in the
current directory or one of the directories above that, and use it for
its <<configuration,configuration>>. If no project file is found,
it'll fall back to a default configuration. You can change this
default configuration by putting a `.tern-config` file, with the same
format as `.tern-project`, in your home directory.

A server write the port it is listening on (which is random) to
standard output on startup. It will serve a <<protocol,simple JSON
protocol>> via HTTP on that port. Clients can upload code and ask
questions about the code through this protocol.

The following command-line flags are supported:

`--port <number>`:: Specify a port to listen on, instead of the
default behavior of letting the OS pick a random unused port.

`--host <host>`:: Specify a host to listen on. Defaults to 127.0.0.1.
Pass `null` or `any` to listen on all available hosts.

`--persistent`:: By default, the server will shut itself down after
five minutes of inactivity. Pass it a this option to disable
auto-shutdown.

`--verbose`:: Will cause the server to spit out information about the
requests and responses that it handles, and any errors that are
raised. Useful for debugging.

`--no-port-file`:: The server won't write a `.tern-port` file. Can be
used if the port files are a problem for you. Will prevent other
clients from finding the server (and may thus result in multiple
servers for the same project).

[[protocol]]
=== JSON protocol ===

Sending queries to a Tern server is done by making `POST` requests to
the server's port (using `/` as the requests's path) with a
http://json.org[JSON] document in the body of the request.

This document should be an object, with three optional fields,
`query`, `files`, and `timeout`.

The first (`query`) describes the kind of information you are
requesting. It may be omitted if the request is only used to push new
code to the server (in which case you'll get an empty object, `{}` as
response). The `files` property, if given, contains an array of file
specifications, as described below. It may be omitted when the query
should operate on the code that the server already has, without adding
anything new. When the `timeout` field is set, it should contain a
number, which is interpreted as the maximum amount of milliseconds to
work (CPU work, ignoring I/O) on this request before returning with a
timeout error.

A query is an object with at least a `type` property, which determines
what kind of query it is. Depending on the type, other properties must
or may be present in order to provide further details.

These are the queries that a Tern server understands by default.
(Plug-ins may add custom query types.)

[[req_completions]]`completions`:: Asks the server for a set of completions at the given point.
+
Accepted fields are:

`file`, `end` (required);; Specify the location to complete at.
<<loc_spec,See below>>.

`types` (optional, default `false`);; Whether to include the types of
the completions in the result data.

`depths` (optional, default `false`);; Whether to include the distance
(in scopes for variables, in prototypes for properties) between the
completions and the origin position in the result data.

`docs`, `urls`, `origins` (optional, default `false`);; Whether to
include documentation strings, urls, and origin files (if found) in
the result data.

`filter` (optional, default `true`);; When on, only completions that
match the current word at the given point will be returned. Turn this
off to get all results, so that you can filter on the client side.

`caseInsensitive` (optional, default `false`);; Whether to use a
case-insensitive compare between the current word and potential
completions.

`guess` (optional, default `true`);; When completing a property and no
completions are found, Tern will use some heuristics to try and return
some properties anyway. Set this to `false` to turn that off.

`sort` (optional, default `true`);; Determines whether the result set
will be sorted.

`expandWordForward` (optional, default `true`);; When disabled, only
the text _before_ the given position is considered part of the word.
When enabled (the default), the whole variable name that the cursor is
on will be included.

`omitObjectPrototype` (optional, default `true`);; Whether to ignore
the properties of `Object.prototype` unless they have been spelled out
by at least to characters.

`includeKeywords` (optional, default `false`);; Whether to include
JavaScript keywords when completing something that is not a property.

+
The result returned will be an object with `start` and `end`
properties, which give the start and end <<offsets,offsets>> of the
word that was completed, an `isProperty` property that holds a boolean
indicating whether the completion is for a property or a variable, and
a `completions` property holding an array of completions. When one of
the `types`, `depths`, `docs`, `urls`, or `origins` options was
passed, the array will hold objects with a `name` property (the
completion text), and, depending on the options, `type`, `depth`,
`doc`, `url`, and `origin` properties. When none of these options are
enabled, the result array will hold plain strings.

[[req_type]]`type`:: Query the type of something.

`file`, `end` (required), `start` (optional);; Specify the expression
we want the type of. <<loc_spec,See below>>.

`preferFunction` (optional, default `false`);; Set to `true` when you
are interested in a function type. This will cause function types to
win when something has multiple types.

`depth` (optional, default `0`);; Determines how deep the type string
must be expanded. Nested objects will only display property types up
to this depth, and be represented by their type name or a
representation showing only property names below it.

+
The returned object will have the following properties:

`type` (string);; A description of the type of the value. May be `"?"`
when no type was found.

`guess` (bool);; Whether the given type was guessed, or should be
considered reliable.

`name` (string, optional);; The name associated with the type.

`exprName` (string, optional);; When the inspected expression was an
identifier or a property access, this will hold the name of the
variable or property.

`doc`, `url`, `origin` (strings, optional);; If the type had
documentation and origin information associated with it, these will
also be returned.

[[req_definition]]`definition`:: Asks for the definition of something.
This will try, for a variable or property, to return the point at
which it was defined. If that fails, or the chosen expression is not
an identifier or property reference, it will try to return the
definition site of the type the expression has. If no type is found,
or the type is not an object or function (other types don't store
their definition site), it will fail to return useful information.
+
Only takes `file`, `end` (required), and `start` (optional) fields to
specify the expression you want the definition of. <<loc_spec,See
below>>.
+
The returned object will have the following properties:

`start`, `end` (<<offsets,offsets>>, optional);; The start and end positions of
the definition.

`file` (string, optional);; The file in which the definition was
defined.

`context` (string, optional), `contextOffset` (number, optional);; A
slice of the code in front of the definition, and the offset from the
start of the context to the actual definition. Can be used to find a
definition's location in a modified file.

`doc`, `url`, `origin` (strings, optional);; If the definition had
documentation or an origin associated with it, it will be returned.

[[req_documentation]]`documentation`:: Get the documentation string
and URL for a given expression, if any.
+
Takes `file`, `end` (required), and `start` (optional) fields to
specify the expression we are interested in. <<loc_spec,See below>>.
+
Returns an object with the following properties:

`doc`, `url`, `origin` (strings, optional);; The documentation string,
url, and the origin of the definition or value, if any.

[[req_refs]]`refs`:: Used to find all references to a given variable
or property.
+
Takes `file`, `end` (required), and `start` (optional) fields to
specify the expression we are interested in. <<loc_spec,See below>>.
+
Returns an object with a `name` property holding the name of the
variable or property, a `refs` property holding an array of `{file,
start, end}` objects, and, for variables, a `type` property holding
either `"global"` or `"local"`.

[[req_rename]]`rename`:: Rename a variable in a scope-aware way.
+
Takes `file`, `end` (required), and `start` (optional) fields to
specify the variable we want to rename (<<loc_spec,see below>>), and a
`newName` property that gives the new name of the variable.
+
Returns an object whose `changes` property holds an array of `{file,
start, end, text}` objects, which give the changes that must be
performed to apply the rename. The client is responsible for doing the
actual modification.

[[req_properties]]`properties`:: Get a list of all known object
property names (for _any_ object).

`prefix` (string, optional);; Causes the server to only return
properties that start with the given string.

`sort` (optional, default `true`);; Whether the result should be sorted.

+
The returned object will have a `completions` property holding an
array of strings, which are the property names.

[[req_files]]`files`:: Get the files that the server currently holds
in its set of analyzed files.
+
Does not take any parameters. Returns an object with a `files`
property holding an array of strings (the file names).

[[loc_spec]] When specifying a location, which is needed for most of
the query types, the required `file` field may hold either a filename,
or a string in the form `"#N"`, where `N` should be an integer
referring to one of the files included in the request (more on that
<<protocol_files,later>>). The required `end` field is an offset into
this file, either a number or a `{line, ch}` object. It should point
at the end of the expression the request is interested in, or
somewhere inside of it if that doesn't end up pointing inside a
sub-expression (in which case the inner expression would be used). An
optional `start` field can be used to disambiguate between
expressions—if given, the innermost expression that spans the range
between start and end will be used.

[[offsets]] Offsets into a file can be either (zero-based) integers, or `{line,
ch}` objects, where both `line` and `ch` are zero-based integers.
Offsets returned by the server will be integers, unless the
`lineCharPositions` field in the request was set to `true`, in which
case they will be `{line, ch}` objects.

The format of the `doc` field in responses will, by default, only
contain the first few sentences of the documentation string, and have
newlines stripped. To get the full string, with newlines intact, you
can add a `docFormat` field to your query with the value `"full"`.

[[variable]] Requests that take an input expression also accept a
`variable` field which, when given, will cause the server to not look
for an expression in the code, but to make up a variable expression
with the given name. This does not remove the need to pass in an
`end`, since that will be used to determine the scope in which the
variable is interpreted.

[[protocol_files]] The `files` property of a request must, if present,
hold an array of file descriptions. These can be complete files, which
have a `type` property holding `"full"` and `name` and `text`
properties holding strings. Complete files will be stored by the
server and can be reused in later requests.

Alternatively, you can pass in partial files. This is useful when
needing to perform a query on a large file without re-uploading and
re-analyzing the whole file. A partial file has a `type` property
holding the string `"part"`, a `text` property holding some slice of
the file (starting at a line boundary), a `name` property referring to
an existing file, and an `offset` property, either an integer or a
`{line, ch}` object, indicating the approximate position of the
fragment in the file.

To remove a file from the server's model of the project, you can
include an object with a `name` property that identifies the file and
a `type` property of `"delete"`.

[[server_api]]
=== Programming interface ===

[[tern.Server]] The base server (without HTTP or configuration-file
reading) is implemented in `lib/tern.js`. That package exposes a
`Server` constructor that can be used to create a server. It takes an
object holding configuration options as argument. These are
recognized (all have a default):

[[option_defs]] `defs` (array of strings):: The <<typedef,definition>>
objects to load into the server's environment.

[[option_plugins]] `plugins` (object):: Specifies the set of
<<plugins,plugins>> that the server should load. The property names of
the object name the plugins, and their values hold options that will
be passed to them.

[[option_ecmaVersion]] `ecmaVersion` (number):: The ECMAScript version
to parse. Should be either 5 or 6. Default is 6.

[[option_getFile]] `getFile` (function):: Provides a way for the
server to try and fetch the content of files. Depending on the `async`
option, this is either a function that takes a filename and returns a
string (when not `async`), or a function that takes a filename and a
callback, and calls the callback with an optional error as the first
argument, and the content string (if no error) as the second.

[[option_async]] `async` (bool):: Indicates whether `getFile` is
asynchronous. Default is `false`.

[[option_fetchTimeout]] `fetchTimeout` (number):: Indicates the
maximum amount of milliseconds to wait for an asynchronous `getFile`
before giving up on it. Defaults to `1000`.

A server object has the following methods:

[[tern.Server.addFile]] `addFile(name: string, text?: string, parent?: string)`::
Register a file with the server. Note that files can also be
<<protocol_files,included>> in requests. When using this to
automatically load a dependency, specify the name of the file (as Tern
knows it) as the third argument. That way, the file is counted towards
the <<dependency_budget,dependency budget>> of the root of its
dependency graph.

[[tern.Server.delFile]] `delFile(name: string)`:: Unregister a file.

[[tern.Server.request]] `request(doc: object, callback: fn(error, response))`::
Perform a request. `doc` is a (parsed) JSON document as described in
the <<protocol,protocol documentation>>. The `callback` function will
be called when the request completes. If an error occurred, it will be
passed as a first argument. Otherwise, the resonse (parsed) JSON
object will be passed as second argument.
+
When the server hasn't been configured to be
<<option_async,asynchronous>>, the callback will be called before
`request` returns.

[[tern.Server.flush]] `flush(callback: fn())`:: Forces all files to be
fetched an analyzed, and then calls the callback function.

[[tern.Server.on]] `on(eventType: string, handler: fn())`:: Register
an event handler for the named type of event.

[[tern.Server.off]] `off(eventType: string, handler: fn())`::
Unregister an event handler.

[[tern.Server.addDefs]] `addDefs(defs: object, atFront?: bool)`:: Add
a set of <<typedef,type definitions>> to the server. If `atFront` is
true, they will be added before all other existing definitions.
Otherwise, they are added at the back.

[[tern.Server.deleteDefs]] `deleteDefs(name: string)`:: Delete
a set of <<typedef,type definitions>> from the server, by providing the name, 
taken from `defs[!name]` property from the definitions. If that property is not 
available in the current type definitions, it can't be removed.

[[tern.Server.loadPlugin]] `loadPlugin(name: string, options?: object)`::
Load a <<plugins,server plugin>> (or don't do anything, if the plugin
is already loaded).

[[events]] The server fires the following type of events (mostly
useful for plugins):

[[event_reset]] `"reset" ()`:: When the server throws away its current
analysis data and starts a fresh run.

[[event_beforeLoad]] `"beforeLoad" (file)`:: Before analyzing a file.
`file` is an object holding `{name, text, scope}` properties.

[[event_afterLoad]] `"afterLoad" (file)`:: After analyzing a file.

[[event_preParse]] `"preParse" (text, options)`:: Will be run right
before a file is parsed, and passed the given text and options. If a
handler returns a new text value, the origin text will be overriden.
This is useful for instance when a plugin is able to extract
JavaScript content from an HTML file.

[[event_postParse]] `"postParse" (ast, text)`:: Run right after a file
is parsed, and passed the parse tree and the parsed file as arguments.

[[event_preInfer]] `"preInfer" (ast, scope)`:: Run right before the
type inference pass, passing the syntax tree and a
<<infer_scope,scope>> object.

[[event_postInfer]] `"postInfer" (ast, scope)`:: Run after the type
inference pass.

[[event_typeAt]] `"typeAt" (file, end, expr, type)`:: Run after Tern
attempts to find the type at the position `end` in the given file. A
handler may return either the given type (already calculated by Tern
and earlier `"typeAt"` passes) or an alternate type to be used
instead. This is useful when a plugin can provide a more helpful type
than Tern (e.g. within comments).

[[event_completion]] `"completion" (file, query)`:: Run at the start
of a completion query. May return a <<req_completions,valid completion
result>> to replace the default completion algorithm.

[[typedef]]
=== JSON type definitions ===

To be able to specify the types of things without actually analyzing
source code, either because there is no JavaScript source code (as for
the built-in types) or because the source code is too big, or because
Tern is unable to construct the correct types from the source code,
Tern defines a JSON data format for specifying types. A few examples
of files in this format can be found in the `defs/` directory in the
distribution.

A type definition data structure is basically a tree of objects, where
the top-level object specifies variables in the global scope, and the
nested objects specify properties of object types. Properties prefixed
with an exclamation point (`!`) hold special directives, all other
properties refer to variable or property names.

Here is an example:

[source,application/x-json]
----
{
  "!name": "mylibrary",
  "!define": {
    "point": {
      "x": "number",
      "y": "number"
    }
  },
  "MyConstructor": {
    "!type": "fn(arg: string)",
    "staticFunction": "fn() -> bool",
    "prototype": {
      "property": "[number]",
      "clone": "fn() -> +MyConstructor",
      "getPoint": "fn(i: number) -> point"
    }
  },
  "someOtherGlobal": "string"
}
----

This defines a library that sets two globals, `MyConstructor` holding
a constructor function, and `someOtherGlobal` holding a string. The
origin of the types, variables, and properties defined by this
document will be `"mylibrary"`, as set by the `!name` property.

The value of a variable or property can be either a string or an
object. Strings can be one of the built-in types (`"number"`,
`"string"`, `"bool"`), a function type (`"fn(arg1: type1, arg2: type2)
-> rettype"`, where `-> rettype` is optional), or an array type
(`"[type]"`). Strings can also name types, either by describing the
path to the type in the global scope (`"Date.prototype"`) or by
referring to one of the local definitions in the `!define` property of
the document. Finally, a type can be prefixed with a `+` to indicate
an instance of a constructor (`+Date`).

Objects describe types by enumerating their properties. By default,
their type will simply be an instance of `Object`, but a `!type`
property can be used to make the type a function or array type, as the
example does for `MyConstructor`. Alternatively, a `!proto` property
can be used to give the object a custom prototype, for example
`"!proto": Element.prototype`.

Documentation can be attached to a type using `!doc`, which should
hold a (short) documentation string and `!url`, which should hold a
URL that has the full documentation of the type or function being
defined.

Finally, a function can be annotated with effects that it has. These
aren't currently documented, but you can search for `!effects` in
`defs/ecma5.json` to see some examples. Similarly, a function type
string's return type may contain the variables `!0` (the first
argument's type, `!N` for the N-1th), `!this` (the self type of the
call), and a special property `!ret` (the return type of a function).

[[plugins]]
=== Server plugins ===

Plugins are JavaScript programs that add extra functionality to a
server. The distribution currently comes plugins for parsing
<<plugin_doc_comment,doc comments>>, and plugins for
<<plugin_node,node.js>> and <<plugin_requirejs,RequireJS>>, which
teach the Tern server about the dependency management mechanisms
defined by those systems (as well as, for node.js, including types for
the built-in libraries).

A plugin can use several hooks to add custom behavior.

[[infer.registerFunction]]`infer.registerFunction(name: string, f: fn(self, args, argnodes))`::
This is a function in the <<infer,inference engine module>> that
allows custom ways to compute function return types or effects. When a
function is specified to return `!custom:myname` or has an effect
`"custom myname"`, a call to the function will cause the function
registered under `"myname"` to be called with the argument types and
argument AST nodes given to the call. This is used, for example, to
make calls to `require` trigger the necessary machinations to fetch a
dependency and return its type.

[[tern.registerPlugin]]`tern.registerPlugin(name: string, fn(Server, options))`::
This can be used to register an initialization function
for the plugin with the given name. A Tern server, when
<<option_plugins,configured>> to load this plugin, will call this
initialization function, passing in the server instance and the
options specified for the plugin (if any). This is the place where you
register <<tern.Server.on,event handlers>> on the server, <<tern.Server.addDefs,add>>
type definitions, <<tern.Server.loadPlugin,load>> other plugins as dependencies,
and/or initialize the plugin's state.
+
See the server's <<events,list of events>> for ways to wire up plugin behavior.

[[tern.defineQueryType]]`tern.defineQueryType(name: string, desc: object)`::
Defines a new type of query with the server. The `desc` object is a
property describing the request. It should at least have a `run`
property, which holds a function `fn(Server, query)` that will be
called to handle queries with a `type` property that matches the given
name. It may also have a `takesFile` property which, if true, will
cause the server to try and resolve the file on which the query
operates (from its `file` property) and pass that (a `{name, text,
scope, ast}` object) as a third argument to the `run` function. You
will probably need to use the <<infer,inference module's API>> to
do someting useful in this function.

[[plugin_doc_comment]]
==== Doc comments plugin ====

This plugin, which is enabled by default in the `bin/tern` server,
parses comments before function declarations, variable declarations,
and object properties. It will look for
http://usejsdoc.org/[JSDoc]-style type declarations, and try to parse
them and add them to the inferred types, and it will treat the first
sentence of comment text as the docstring for the defined variable or
property.

To turn this plugin off, set `doc_comment: null` in your
<<option_plugins,plugin option>>.

The plugin understands the following configuration parameters:

`strong`:: When enabled, types specified in comments take precedence
over inferred types.

[[plugin_complete_strings]]
==== String completion plugin ====

When enabled, this plugin will gather (short) strings in your code,
and completing when inside a string will try to complete to previously
seen strings. Takes a single option, `maxLength`, which controls the
maximum length of string values to gather, and defaults to 15.

[[plugin_commonjs]]
==== CommonJS module plugin ====

This plugin implements CommonJS-style (`require("foo")`) modules. It
will wrap files in a file-local scope, and bind `require`, `module`,
and `exports` in this scope. Does not implement a module resolution
strategy (see for example <<plugin_node_resolve,the `node_resolve`
plugin>>). Depends on the <<plugin_modules,`modules`>> plugin.

[[plugin_node]]
==== Node.js plugin ====

The http://nodejs.org[node.js] plugin, called `"node"`, provides
variables that are part of the node environment, such as `process` and
`__dirname`, and loads the <<plugin_commonjs,`commonjs`>> and
<<plugin_node_resolve,`node_resolve`>> plugins to allow node-style
module loading. It defines types for the built-in modules that node.js
provides (`"fs"`, `"http"`, etc).

[[plugin_node_resolve]]
==== Node.js resolve plugin ===

This plugin defines the node.js module resolution strategy—things like
defaulting to `index.js` when requiring a directory and searching
`node_modules` directories. It depends on the
<<plugin_modules,`modules` plugin>>. Note that this plugin only does
something meaningful when the Tern server is running on node.js
itself.

[[plugin_modules]]
==== Modules plugin ====

This is a supporting plugin to act as a dependency for other
module-loading and module-resolving plugins. It understands the
following configuration parameters:

`dontLoad`:: Can be set to `true` to disable dynamic loading of
required modules entirely, or to a regular expression to disable
loading of files that match the expression.

`load`:: If `dontLoad` isn't given, this setting is checked. If it is
a regular expression, the plugin will only load files that match the
expression.

`modules`:: Can be used to assign <<typedef,JSON type definitions>> to
certain modules, so that those are loaded instead of the source code
itself. If given, should be an object mapping module names to either
JSON objects defining the types in the module, or a string referring
to a file name (relative to the project directory) that contains the
JSON data.

[[plugin_es_modules]]
==== ES modules plugin ====

Builds on top of the <<plugin_modules,`modules` plugin>> to support
ECMAScript 6's `import` and `export` based module inclusion.

[[plugin_requirejs]]
==== RequireJS plugin ====

This plugin (`"requirejs"`) teaches the server to understand
http://requirejs.org[RequireJS]-style dependency management. It
defines the global functions `define` and `requirejs`, and will do its
best to resolve dependencies and give them their proper types.

These options are understood:

`baseURL`:: The base path to prefix to dependency filenames.

`paths`:: An object mapping filename prefixes to specific paths. For
example `{"acorn": "lib/acorn/"}`.

`override`:: An object that can be used to override some dependency
names to refer to predetermined types. The value associated with a
name can be a string starting with the character `=`, in which case
the part after the `=` will be interpreted as a global variable (or
dot-separated path) that contains the proper type. If it is a string
not starting with `=`, it is interpreted as the path to the file that
contains the code for the module. If it is an object, it is
interpreted as <<typedef,JSON type definition>>.

[[plugin_angular]]
==== Angular.js plugin ====

Adds the `angular` object to the top-level environment, and tries to
wire up some of the bizarre dependency management scheme from this
library, so that dependency injections get the right types. Enabled
with the name `"angular"`.

[[plugin_third_party]]
==== Third-party plugins ====

It is possible to write third-party plugins or JSON type definitions
and distribute them independently, either as packages using
https://www.npmjs.org[npm] or as raw JavaScript files.

When a _name_ attribute is specified in the `libs` section of the
project configuration, Tern first searches for a file '`name`'`.json` in
its distribution `defs` directory, then for a file '`name`'`.json` in
the user's project directory, and finally for an installed package
named `"tern-`'`name`'`"` to load as a JSON Type Definition. A JSON Type
Definition distributed as an npm package must have a package name
matching the pattern `"tern-`'`name`'`"`.

When a 'name' attribute is specified in the `plugins` section of the
project configuration, Tern first searches for a file '`name`'`.js` in its
distribution `plugin` directory, then for a file '`name`'`.js` in the
user's project directory, and finally for an installed package named
`"tern-`'`name`'`"` to load as a plugin. A plugin distributed as an npm package
must have a package name matching the pattern `"tern-`'`name`'`"`.

The main module for a third-party plugin that will be installed outside of
the Tern distribution should export a single method `initialize(ternDir:
string)` which takes the location of the Tern distribution loading the
plugin as an argument. Tern will call this method immediately after loading
the plugin to tell the plugin where to find Tern modules. A plugin with
this method will work regardless of its install location relative to the
Tern distribution, but plugins without it may fail to find Tern modules or
even silently load the wrong Tern modules depending on install location.

Plugin packages can specify the Tern version required as a
http://blog.nodejs.org/2013/02/07/peer-dependencies[peer dependency].

[[configuration]]
=== Project configuration ===

A `.tern-project` file is a http://json.org[JSON] file in a format
like this:

[source,application/x-json]
----
{
  "libs": [
    "browser",
    "jquery"
  ],
  "loadEagerly": [
    "importantfile.js"
  ],
  "plugins": {
    "requirejs": {
      "baseURL": "./",
      "paths": {}
    }
  }
}
----

The `libs` property refers to the <<typedef,JSON type descriptions>>
that should be loaded into the environment for this project. See the
`defs/` directory for examples. The strings given here will be
suffixed with `.json`, and searched for first in the project's own
dir, and then in the `defs/` directory of the Tern distribution.

By default, local files are loaded into the Tern server when queries
are run on them the editor. `loadEagerly` allows you to force some
files to always be loaded, it may be an array of filenames or glob
patterns (i.e. `foo/bar/*.js`). The `dontLoad` option can be used to
prevent Tern from loading certain files. It also takes an array of
file names or glob patterns.

The `plugins` field may hold object used to load and configure Tern
plugins. The names of the properties refer to files that implement
plugins, either in the project dir or under `plugin/` in the Tern
directory. Their values are configuration objects that will be passed
to the plugins. You can leave them at `{}` when you don't need to pass
any options.

You can specify an `ecmaVersion` field to configure the version of
ECMAScript that Tern parses. The default is 6, and leaving it at that
should be safe even for ECMAScript 5 code, but you can set it to 5 as
well.

[[dependency_budget]]
To configure the amount of work Tern is prepared to do to load a
single dependency, the `dependencyBudget` option can be added to a
project file. It indicates the maximum size of the files loaded in
response to a single dependency (through plugins that load
dependencies, such as the <<plugin_node,node>> and
<<plugin_requirejs,RequireJS>> plugins), counted in expressions. The
default value is 20 000. Files loaded as dependencies of dependencies
count towards the budget of the original dependency.

[[utils]]
=== Utilities ===

`bin/test`::

Runs Tern's own testsuite. Tests are defined in the `test/`
directory, as code interspersed with comments that indicate the
types and conditions to check for.

[[condense]]`bin/condense`::

Utility for condensing source code down to a <<typedef,JSON type
definition>> file. Takes a list of files to condense, optionally
interleaved with filenames prefixed with a `+`, which will be loaded
(to provide type information) but not included in the output.
+
Pass `--plugin name` or `--plugin name={jsonconfig}` to load
plugins. Use `--def file` to load <<typedef,JSON definitions>>.

`bin/from_ts`::

Given a typescript `.def.ts` file, will attempt to convert it to a
Tern-style <<typedef,JSON definition>> file.

[[infer]]
== Inference engine ==

The inference engine module (`lib/infer.js`) implements a system that,
given a context and an abstract syntax tree (parsed representation of
the code), tries to infer the types of the variables and properties in
the code.

The parser is implemented in a separate module,
http://marijnhaverbeke.nl/acorn[Acorn], which provides a regular
JavaScript parser, an error-tolerant parser, and a number of utilities
for iterating through and searching in abstract syntax trees. The
syntax tree format used by Acorn and Tern is described in the
https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API[Mozilla
parser API] document (though support for features that are not in
ECMAScript 5, such as `let`, is omitted).

A high-level description of the way Tern's type inference algorithm
works can be found in a http://marijnhaverbeke.nl/blog/tern.html[blog
post] I wrote on the subject.

This module also exposes some utility functions that are useful to
implement the <<protocol,services>> the server exposes.

[[infer_context]]
=== Context ===

A context is an object that holds a global JavaScript scope, as well
as some meta-information and state used by the type inference process.
Almost all operations in the inference module require a context.

To prevent having to pass the context around through every function, a
form of dynamic binding is used—the `withContext` function executes a
function body with a given object used as the current context.

[[infer.Context]]`infer.Context(defs: [object])`:: A constructor
function for contexts. `defs` should be an array of <<typedef,type
definition objects>>, which will be used to initialize the
global scope.

[[infer.withContext]]`infer.withContext(context: Context, f: fn())`::
Calls `f` with the current context bound to `context`. Basically, all
code that does something with the inference engine should be wrapped
in such a call.

[[infer.cx]]`infer.cx() → Context`:: Returns the current context
object.

[[infer.Context.topScope]]`context.topScope`:: The top-level
<<infer_scopes,scope>> of the context.

[[infer_analysis]]
=== Analysis ===

To push code into a context, you first parse it, yielding a syntax
tree, and then tell Tern to analyze that.

[[infer.parse]]`infer.parse(text: string, options?: {}) → AST`:: Parse a piece of
code for use by Tern. Will automatically fall back to the
error-tolerant parser if the regular parser can't parse the code.

[[infer.analyze]]`infer.analyze(ast: AST, name: string, scope?: Scope)`::
Analyze a syntax tree. `name` will be used to set the origin of types,
properties, and variables produced by this code. The optional `scope`
argument can be used to specify a <<infer_scopes,scope>> in which the
code should be analyzed. It will default to the top-level scope.

The same code, or slightly modified variants of the same code, can be
analyzed in a context multiple times. The variables and properties
that the context knows, as well as the types it assigns to them, will
become the union of the variables and types created by the various
forms of the code. When incrementally re-analyzing code as it is being
edited, this leads to a degradation in the preciseness of the
results. To prevent that, it is possible to _purge_ all elements that
come from a specific origin from a context.

[[infer.purgeTypes]]`infer.purgeTypes(origins: [string], start?: number, end?: number)`::
Purges the types that have one of the origins given from the context.
`start` and `end` can be given to only purge types that occurred in
the source code between those offsets. This is not entirely
precise—the state of the context won't be back where it was before the
file was analyzed—but it prevents most of the noticeable inaccuracies
that re-analysis tends to produce.

[[infer.markVariablesDefinedBy]]`infer.markVariablesDefinedBy(scope: Scope, origins: [string], start?: number, end?: number)`::
Cleaning up variables is slightly trickier than cleaning up types.
This does a first pass over the given scope, and marks variables
defined by the given origins. This is indended to be followed by a
call to <<infer.analyze,`analyze`>> and then a call to
<<infer.purgeMarkedVariables,`purgeMarkedVariables`>>.

[[infer.purgeMarkedVariables]]`infer.purgeMarkedVariables`:: Purges
variables that were marked by a call to
<<infer.markVariablesDefinedBy,`markVariablesDefinedBy`>> and not
re-defined in the meantime.

[[infer_types]]
=== Types ===

Tern has a more or less complete implementation of the JavaScript type
system.

[[infer.Obj]]`infer.Obj(proto, name?: string)`:: Constructor for the
type that represents JavaScript objects. `proto` may be another
object, or `true` as a short-hand for `Object.prototype`, or `null`
for prototype-less objects.

[[infer.Fn]]`infer.Fn(name: string?, self: AVal, args: [AVal], argNames: [string], retval: AVal)`::
Constructor for the type that implements functions. Inherits from
<<infer.Obj,Obj>>. The <<infer_aval,`AVal`>> types are used to track
the input and output types of the function.

[[infer.Arr]]`infer.Arr(contentType: AVal)`:: Constructor that creates
an array type with the given content type.

[[infer.Context.num]]`context.num`:: The primitive number type.

[[infer.Context.str]]`context.str`:: The primitive string type.

[[infer.Context.bool]]`context.bool`:: The primitive boolean type.

Types expose the following interface (plus some `AVal`-compatibility
methods, see <<type_is_aval,below>>).

[[infer.Type.name]]`type.name: string`:: The name of the type, if any.

[[infer.Type.origin]]`type.origin: string`:: The origin file of the type.

[[infer.Type.originNode]]`type.originNode: AST`:: The syntax node that
defined the type. Only present for object and function types, and even
for those it may be missing (if the type was created by a type
definition file, or synthesized in some other way).

[[infer.Type.toString]]`type.toString(maxDepth: number) → string`:: Return
a string that describes the type. `maxDepth` indicates the depth to
which inner types should be shown.

[[infer.Type.getProp]]`type.getProp(prop: string) → AVal`:: Get an
<<infer_aval,`AVal`>> that represents the named property of this type.

[[infer.Type.forAllProps]]`type.forAllProps(f: fn(prop: string, val: AVal, local: bool))`::
Call the given function for all properties of the object, including
properties that are added in the future.

Object types have a few extra methods and properties.

[[infer.Obj.proto]]`obj.proto`:: The prototype of the object, or `null`.

[[infer.Obj.props]]`obj.props`:: An object mapping the object's known
properties to AVals. Don't manipulate this directly (ever), only use
it if you have to iterate over the properties.

[[infer.Obj.hasProp]]`obj.hasProp(prop: string) → AVal?`:: Looks up
the AVal associated with the given property, or returns `null` if it
doesn't exist.

[[infer.Obj.defProp]]`obj.defProp(prop: string, originNode?: AST) → AVal`:: Looks up the
given property, or defines it if it did not yet exist (in which case
it will be associated with the given AST node).

[[infer_aval]]
=== Abstract values ===

Abstract values are objects used to represent sets of types. Each
variable and property has an abstract value associated with it, but
they are also used for other purposes, such as tracking the return
type of a function, or building up the type for some kinds of
expressions.

In a cleanly typed program where each thing has only a single type,
abstract values will all have one type associated with them. When, for
example, a variable can hold two different types of values, the
associated abstract value will hold both these types. In some cases,
no type can be assigned to something at all, in which case the
abstract value remains empty.

Abstract values expose the following interface:

[[infer.AVal]]`infer.AVal()`:: Constructor. Creates an empty AVal.

[[infer.AVal.addType]]`aval.addType(type: Type, weight?: number)`::
Add a type to this abstract value. If the type is already in there,
this is a no-op. `weight` can be given to give this type a non-default
weight, which is mostly useful when adding a provisionary type that
should be overridden later if a real type is found. The default weight
is `100`, and passing a weight lower than that will make the type
assignment ``weak''.

[[infer.AVal.propagate]]`aval.propagate(target: Constraint)`:: Sets
this AVal to propagate all types it receives to the given
<<infer_constraint,constraint>>. This is the mechanism by which types
are propagated through the type graph.

[[infer.AVal.hasType]]`aval.hasType(type: Type) → bool`:: Queries whether the
AVal _currently_ holds the given type.

[[infer.AVal.isEmpty]]`aval.isEmpty() → bool`:: Queries whether the
AVal is empty.

[[infer.AVal.getType]]`aval.getType(guess?: bool) → Type?`:: Asks the
abstract value for its current type. May return `null` when there is
no type, or conflicting types are present. When `guess` is `true` or
not given, an empty AVal will try to use heuristics based on its
propagation edges to guess a type.

[[infer.AVal.getFunctionType]]`aval.getFunctionType() → Type?`:: Asks
the AVal if it contains a function type. Useful when you aren't
interested in other kinds of types.

Abstract values that are used to represent variables or properties
will have, when possible, an `originNode` property pointing to an AST
node.

[[type_is_aval]] As a memory-consuming hack, <<infer_types,types>>
also expose the interface of abstact values, so that in cases where an
AVal is expected, but the precise type is known, the type object can
simply be used.

[[infer.ANull]]The `infer.ANull` value is a special AVal-like object
that never holds any types, and discards types added to it. It can be
used as a placeholder in situations where we either aren't interested
in the types, or there simply are no types.

[[infer_constraint]]
=== Constraints ===

Constraints are things that can receive values. They use the same
`addType` method to receive them, which causes all AVals to also be
useable as constraints. The inference engine defines a number of
additional constraints to propagate values in more indirect ways. See
the http://marijnhaverbeke.nl/blog/tern.html[blog post] on the
inference algorithm for some examples.

[[infer.constraint]]`infer.constraint(methods: object) → constructor`::
This is a constructor-constructor for constraints. It'll create a
constructor with all the given methods copied into its prototype,
which will run its `construct` method on its arguments when
instantiated.

Beyond <<infer.AVal.addType,`addType`>>, there are a few optional
methods that constraints can expose to tell the system something about
itself.

[[infer.Constraint.typeHint]]`constraint.typeHint() → Type?`:: May return a type
that <<infer.AVal.getType,`getType`>> can use to ``guess'' its type
based on the fact that it propagates to this constraint.

[[infer.Constraint.propHint]]`constraint.propHint() → string?`:: May return a
string when this constraint is indicative of the presence of a
specific property in the source AVal.

[[infer_scopes]]
=== Scopes ===

Scopes are derived from the <<infer.Obj,`Obj`>> type, and variables
are represented the same way as properties.

[[infer.Scope]]`infer.Scope(parent?: Scope)`:: Constructor for scope
objects. The top scope won't have a parent.

[[infer.Scope.defVar]]`scope.defVar(name: string, originNode: AST) → AVal`::
Ensures that this scope or some scope above it has a property by the
given name (defining it in the top scope if it is missing), and, if
the property doesn't already have an
<<infer.Type.originNode,`originNode`>>, assigns the given node to it.

[[infer_util]]
=== Utilities ===

These are miscellaneous utilities that come in helpful when doing code
analysis.

[[infer.findExpressionAt]]`infer.findExpressionAt(ast: AST, start: number?, end: number, scope?: Scope) → {node, state}`::
Searches the given syntax tree for an expression that ends at the
given end offset and, if `start` is given, starts at the given start
offset. `scope` can be given to override the outer scope, which
defaults to the context's top scope. Will return a `{node, state}`
object if successful, where `node` is AST node, and `state` is the
scope at that point. Returns `null` if unsuccessful.

[[infer.findExpressionAround]]`infer.findExpressionAround(ast: AST, start: number?, end: number, scope?: Scope) → {node, state}`::
Similar to <<infer.findExpressionAround,`findExpressionAround`>>,
except that it will return the innermost expression node that spans
the given range, rather than only exact matches.

[[infer.expressionType]]`infer.expressionType(expr: {node, state}) → AVal`::
Determine an expression for the given node and scope (as returned by
the functions above). Will return an <<infer_aval,`AVal`>> or plain
<<infer_types,`Type`>>.

[[infer.scopeAt]]`infer.scopeAt(ast: AST, pos: number, scope?: Scope) → Scope`::
Find the scope at a given position in the syntax tree. The `scope`
parameter can be used to override the scope used for code that isn't
wrapped in any function.

[[infer.findRefs]]`infer.findRefs(ast: AST, scope: Scope, name: string, refScope: Scope, f: fn(AST, Scope))`::
Will traverse the given syntax tree, using `scope` as the starting
scope, looking for references to variable `name` that resolve to scope
`refScope`, and call `f` with the node of the reference and its local
scope for each of them.

[[infer.findPropRefs]]`infer.findPropRefs(ast: AST, scope: Scope, objType: Obj, propName: string, f: fn(AST))`::
Analogous to <<infer.findRefs,`findRefs`>>, but used to look for
references to a specific property instead. Whereas `findRefs` is
precise, this is dependent on type inference, and thus can not be
relied on to be precise.

Whenever the code in `lib/infer.js` guesses a type through fuzzy
heuristics (through <<infer.AVal.getType,`getType`>> or
<<infer.expressionType,`expressionType`>>), it sets a flag. The
following two function allow access to this flag:

[[infer.didGuess]]`infer.didGuess() → bool`:: Test whether the
guessing flag is set.

[[infer.resetGuessing]]`infer.resetGuessing(val?: bool)`:: Reset the
guessing flag.

[[editor]]
== Editor plugins ==

If your editor of choice is not yet supported, you are encouraged to
try and port one of the existing plugins to it. When figuring out how
things work, the code powering the demo, in `doc/demo/demo.js`, might
also come in useful.

All these plugins use the http://nodejs.org[node.js]-based server, and
thus require that (as well as http://npmjs.org[npm]) to be installed.

[[emacs]]
=== Emacs ===

The Emacs mode is part of the main tern
https://github.com/ternjs/tern[repository]. It can be installed as
follows:

. Make sure you are using Emacs 24 or later. The Tern mode requires
  lexical scoping.

. Clone this repository somewhere. Do `npm install` to get the
  dependencies.

. Make Emacs aware of `emacs/tern.el`. For example by adding this to
  your `.emacs` file:
+
[source,commonlisp]
----
(add-to-list 'load-path "/path/to/tern/emacs/")
(autoload 'tern-mode "tern.el" nil t)
----

. Optionally set `tern-mode` to be automatically enabled for your
  JavaScript mode of choice. Here's the snippet for `js-mode`:
+
[source,commonlisp]
----
(add-hook 'js-mode-hook (lambda () (tern-mode t)))
----

The Emacs mode uses the `bin/tern` server, and project configuration
is done with a <<project_file,`.tern-project`>> file.

Buffers in `tern-mode` add a `completion-at-point` function that
activates Tern's completion. So, unless you rebound the key, `M-tab`
(or `C-M-i`) will trigger completion.

When the point is in an argument list, Tern will show argument names
and types at the bottom of the screen.

The following additional keys are bound:

`M-.`:: Jump to the definition of the thing under the cursor.

`M-,`:: Brings you back to last place you were when you pressed `M-.`.

`C-c C-r`:: Rename the variable under the cursor.

`C-c C-c`:: Find the type of the thing under the cursor.

`C-c C-d`:: Find docs of the thing under the cursor. Press again to
open the associated URL (if any).

==== Auto-Complete ====

If you want to use `auto-complete.el` for completion, append following codes:

[source,commonlisp]
----
(eval-after-load 'tern
   '(progn
      (require 'tern-auto-complete)
      (tern-ac-setup)))
----

If `tern-ac-on-dot` is non-nil (default), typing `.`(dot) invokes auto-complete to select completions.
Calling the command `tern-ac-complete`, one can invoke auto-complete manually.

[[vim]]
=== Vim ===

The Vim plugin is maintained in a
https://github.com/ternjs/tern_for_vim[separate repository]. Please
see its README for details.

[[sublime_text]]
=== Sublime Text ===

There are two implementations of Sublime Text modules for Tern. One
written by me, at <https://github.com/ternjs/tern_for_sublime>. This
one uses the node.js-based server. The other is written by Sergey
Chikuyonok, and can be found at
<https://github.com/emmetio/sublime-tern>. It uses a Python V8 bridge
to run the server.

See the readme files in those repositories for details.

[[tern_java]]
=== Eclipse / Java ===

https://github.com/angelozerr/tern.java[tern.java] is a Tern client
written in Java. It includes Eclipse integration.

[[tern_for_gedit]]
=== gedit ===

https://github.com/Swatinem/tern_for_gedit[tern_for_gedit] integrates
Tern with the https://github.com/Swatinem/tern_for_gedit[gedit]
editor.

[[software]]
== Related Software ==

This is a place to gather links to software that is built on Tern.
Drop me an mailto:marijnh@gmail.com[email] if you want to suggest a
link.

=== jsctags ===

https://github.com/ramitos/jsctags[jsctags] is a tool that generates
ctags files from JavaScript code by using Tern's inference engine.

=== CodeMirror Tern addon ===

The http://codemirror.net[CodeMirror] browser-based editor has an
http://codemirror.net/demo/tern.html[addon] for integrating with Tern.

=== tern.ace ===

https://github.com/angelozerr/tern.ace[tern.ace] integrates Tern in
the http://ace.c9.io/[ACE] editor.

=== tern.orion ===

https://github.com/angelozerr/tern.orion[tern.orion] integrates Tern in
the http://www.eclipse.org/orion/[Orion] editor.
