Giter Site home page Giter Site logo

ast-util's Introduction

ast-util

Utilities for AST transformers.

Install

$ npm install [--save] ast-util

API

# callArraySlice(scope, node[, begin, end])

Returns a call to Array.prototype.slice with node as the context and begin and end as the arguments to slice.

# callFunctionBind(scope, fn, context[, args])

Returns a call to Function.prototype.bind using either call or apply depending on what the value of args is. If args is an expression then apply 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 and property.

# 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 callee is a string then it is treated as a globally-accessible function such as Object.defineProperty 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 and args as the arguments. If callee is a string then it is treated as a globally-accessible function such as Array.prototype.slice 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:

var a;
function b(){ return c; }
b(d);

Then getGlobals will return two identifiers, c and a.

# 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 being created. The expression 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 a var declaration with an optional initial value.

# isReference(path)

Determines whether the given path is a value reference. For example, a and b are references, but c is not:

a(b.c);

Only identifiers count as references.

# isUsed(scope, name)

Determines whether the given name should be considered "used" in the given scope. 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 example while c is not:

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:

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 for any scope 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.

Usage

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 for that purpose. In conjunction with ast-types, here's how you'd write a simple version of a swap macro:

// 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.

Contributing

Build Status

Setup

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.

Pull Requests

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Any contributors to the master ast-util repository must sign the Individual Contributor License Agreement (CLA). It's a short form that covers our bases and makes sure you're eligible to contribute.

When you have a change you'd like to see in the master repository, send a pull request. Before we merge your request, we'll make sure you're in the list of people who have signed a CLA.

Acknowledgements

Huge thanks to Ben Newman for ast-types, on which much of this library depends.

ast-util's People

Contributors

eventualbuddha avatar fdecampredon avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.