Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

periscopic

Rich-Harris5.8mMIT4.0.2TypeScript support: included

periscopic

readme

periscopic

Utility for analyzing scopes belonging to an ESTree-compliant AST.

API

import { analyze } from 'periscopic';

const ast = acorn.parse(`
const a = b;
console.log(a);
`);

const { map, globals, scope } = analyze(ast);
  • map is a WeakMap<Node, Scope>, where the keys are the nodes of your AST that create a scope
  • globals is a Map<string, Node> of all the identifiers that are referenced without being declared anywhere in the program (in this case, b and console)
  • scope is the top-level Scope belonging to the program

Scope

Each Scope instance has the following properties:

  • scope.block — true if the scope is created by a block statement (i.e. let, const and class are contained to it), false otherwise
  • scope.parent — the parent scope object
  • scope.declarations — a Map<string, Node> of all the variables declared in this scope, the node value referes to the declaration statement
  • scope.initialised_declarations — a Set<string> of all the variables declared and initialised in this scope
  • scope.references — a Set<string> of all the names referenced in this scope (or child scopes)

It also has two methods:

  • scope.has(name) — returns true if name is declared in this scope or an ancestor scope
  • scope.find_owner(name) — returns the scope object in which name is declared (or null if it is not declared)

extract_identifiers and extract_names

This package also exposes utilities for extracting the identifiers contained in a declaration or a function parameter:

import { extract_identifiers, extract_names } from 'periscopic';

const ast = acorn.parse(`
const { a, b: [c, d] = e } = opts;
`);

const lhs = ast.body[0].declarations[0].id;

extract_identifiers(lhs);
/*
[
    { type: 'Identifier', name: 'a', start: 9, end: 10 },
    { type: 'Identifier', name: 'c', start: 16, end: 17 },
    { type: 'Identifier', name: 'd', start: 19, end: 20 }
]
*/

extract_names(lhs);
/*
['a', 'c', 'd']
*/

License

MIT

changelog

periscopic changelog

4.0.2

  • Fix bugs

4.0.1

  • Bump deps

4.0.0

  • Switch from estree-walker to zimmerframe (#20)
  • Create scope for SwitchStatement (#18)
  • Expose default key in pkg.exports rather than import (#17)
  • Don't treat export-from specifiers as global references (#16)

3.1.0

  • Add types export (#19)
  • Promote @types/estree to dependencies (#19)
  • Update dependencies

3.0.4

  • Update is-reference (#15)
  • Work around broken eslintplugin-import (#14)

3.0.3

  • Fix global detection (#12)

3.0.2

  • Tidy up types

3.0.1

  • Update estree-walker to 3.0.0 to solve transitive dependency issues (#11)

3.0.0

  • Remove CommonJS vestiges

2.0.3

  • Convert to JavaScript

2.0.2

  • Performance improvements (#5)

2.0.1

  • Fix reference extraction

2.0.0

  • Match API used by Svelte's internal helpers (#4)
    • Change globals to a Map<string, Node>
    • Change value of scope.declarations to the variable declaration, not declarator

1.1.0

  • Add add_declaration method and initialised_declarations set to Scope (#2)
  • Fix false positive global detection (#1)

1.0.2

  • Handle parameter-less catch clauses

1.0.1

  • Only attach scope-creating nodes to the scope map

1.0.0

  • First release