Utilities for AST transformers.
npm install ast-utilUtilities for AST transformers.
```
$ npm install [--save] ast-util
# callArraySlice(scope, node[, begin, end])
Returns a call to Array.prototype.slice with node as the context andbegin and end as the arguments to slice.
# callFunctionBind(scope, fn, context[, args])
Returns a call to Function.prototype.bind using either call or applyargs
depending on what the value of is. If args is an expression thenapply is used. If args is an array of expressions, then call.
# callGet(scope, object, property, receiver)
The [[Get]] internal method on objects would look something like
helpers/get.js.
# callGetOwnPropertyDescriptor(scope, object, property)
Returns a call to Object.getOwnPropertyDescriptor with the given object andproperty.
# callGetPrototypeOf(scope, object)
Returns a call to Object.getPrototypeOf with the given object.
# callHasOwnProperty(scope, node, property)
Returns a call to hasOwnProperty with node as the context and property as
the property to check.
# callSharedMethod(scope, callee, args)
Returns a call to the given callee with args as the arguments. If calleeObject.defineProperty
is a string then it is treated as a globally-accessible function such as which will be stored in a unique temporary variable.
Subsequent calls to this function will re-use the same temporary variable.
# callSharedMethodWithContext(scope, callee, context, args)
Returns a call to the given callee with context as the method context andargs as the arguments. If callee is a string then it is treated as aArray.prototype.slice
globally-accessible function such as which will be
stored in a unique temporary variable. Subsequent calls to this function will
re-use the same temporary variable.
# getGlobals(ast)
Gets a list of identifiers referencing global variables anywhere within the
given ast. Assuming the ast is for this code:
`js`
var a;
function b(){ return c; }
b(d);
Then getGlobals will return two identifiers, c and d.
# identifierForString(string)
Generate a safe JavaScript identifier for the given string.
# injectShared(scope, name, expression)
Injects a shared variable with a unique identifier. Only the first call with
the same scope and name will result in a variable declaration beingexpression
created. The passed in can either be an AST node or a function to
generate one. This function is generally used to inject repeatedly-used values
and prevent repeated execution.
# injectVariable(scope, identifier[, init])
Injects a variable with the given identifier into the given scope as avar declaration with an optional initial value.
# isReference(path)
Determines whether the given path is a value reference. For example, a andb are references, but c is not:
`js`
a(b.c);
Only identifiers count as references.
# isUsed(scope, name)
Determines whether the given name should be considered "used" in the givenscope. For a name to be used, it should either:
1. Be declared in this scope or a parent scope.
2. Be referenced in this scope, a parent scope, or any child scopes.
For example, a, b, and d are used in the global scope of this examplec
while is not:
`js
var a;
function b() {}
try {
a = b(d);
} catch (c) {
}
`
# sharedFor(scope, name)
Injects a shared variable by getting the named value from a dotted path. For
example, this will return an identifier that can be used in place of the named
expression:
`js`
sharedFor(scope, 'Object.defineProperty')
Subsequent calls to sharedFor in the same scope will return the same
identifier.
# uniqueIdentifier(scope[, name])
Generates an identifier guaranteed not to collide with any others in the given
scope. This function will also never generate the same identifier twice forscope
any whose global scope already got that identifier.
Called in a scope with no global references and no variables, the first time
this function is called it will return an identifier named $__0.
When called with a name that name will be used with a prefix, "$\_\_", if
possible. If that name is already used then it will append incrementing numbers
until it finds a name that isn't used.
These methods are useful to source transforms, such as transpilers or macros.
Such transforms often have to insert variables into scopes and replace
expressions. Using injectVariable and injectShared are specifically forast-types
that purpose. In conjunction with , here's how you'd write a simpleswap
version of a macro:
`js
// var tmp;
var tmp = util.injectVariable(
this.scope,
util.uniqueIdentifier(this.scope)
);
this.replace(
b.sequenceExpression([
// tmp = left
b.assignmentExpression(
'=',
tmp,
left
),
// left = right
b.assignmentExpression(
'=',
left,
right
),
// right = tmp
b.assignmentExpression(
'=',
right,
tmp
)
])
);
`
See examples/swap-macro.js for a more complete
example.

First, install the development dependencies:
``
$ npm install
Then, try running the tests:
``
$ make test
If you're adding or editing code that injects helpers into a scope, you'll need
to edit and run the Makefile to have it generate the files in lib/helpers from
the files in helpers.
1. Fork it
2. Create your feature branch (git checkout -b my-new-feature)git commit -am 'Add some feature'
3. Commit your changes ()git push origin my-new-feature`)
4. Push to the branch (
5. Create new Pull Request
Huge thanks to [Ben Newman][benjamn] for [ast-types][ast-types], on which much
of this library depends.
[benjamn]: https://github.com/benjamn
[ast-types]: https://github.com/benjamn/ast-types