Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@rushstack/tree-pattern

Package Overview
Dependencies
Maintainers
0
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rushstack/tree-pattern

A fast, lightweight pattern matcher for tree structures such as an Abstract Syntax Tree (AST)

  • 0.3.4
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
0
Created
Source

@rushstack/tree-pattern

This is a simple, fast pattern matcher for JavaScript tree structures. It was designed for ESLint rules and transforms that match parse trees such as produced by Esprima. However, it can be used with any JSON-like data structure.

Usage

Suppose we are fixing up obsolete Promise calls, and we need to match an input like this:

Promise.fulfilled(123);

The parsed subtree looks like this:

{
  "type": "Program",
  "body": [
    {
      "type": "ExpressionStatement",
      "expression": {  // <---- expressionNode
        "type": "CallExpression",
        "callee": {
          "type": "MemberExpression",
          "object": {
            "type": "Identifier",
            "name": "Promise"
          },
          "property": {
            "type": "Identifier",
            "name": "fulfilled"
          },
          "computed": false,
          "optional": false
        },
        "arguments": [
          {
            "type": "Literal",
            "value": 123,
            "raw": "123"
          }
        ],
        "optional": false
      }
    }
  ],
  "sourceType": "module"
}

Throwing away the details that we don't care about, we can specify a pattern expression with the parts that need to be present:

const pattern1: TreePattern = new TreePattern({
  type: 'CallExpression',
  callee: {
    type: 'MemberExpression',
    object: {
      type: 'Identifier',
      name: 'Promise'
    },
    property: {
      type: 'Identifier',
      name: 'fulfilled'
    },
    computed: false
  }
});

Then when our visitor encounters an ExpressionStatement, we can match the expressionNode like this:

if (pattern1.match(expressionNode)) {
  console.log('Success!');
}

Capturing matched subtrees

Suppose we want to generalize this to match any API such as Promise.thing(123); or Promise.otherThing(123);. We can use a "tag" to extract the matching identifier:

const pattern2: TreePattern = new TreePattern({
  type: 'CallExpression',
  callee: {
    type: 'MemberExpression',
    object: {
      type: 'Identifier',
      name: 'Promise'
    },
    property: TreePattern.tag('promiseMethod', {
      type: 'Identifier'
    }),
    computed: false
  }
});

On a successful match, the tagged promiseMethod subtree can be retrieved like this:

interface IMyCaptures {
  // Captures the "promiseMethod" tag specified using TreePattern.tag()
  promiseMethod?: { name?: string }; // <--- substitute your real AST interface here
}

const captures: IMyCaptures = {};

if (pattern2.match(node, captures)) {
  // Prints: "Matched fulfilled"
  console.log('Matched ' + captures?.promiseMethod?.name);
}

Alternative subtrees

The oneOf API enables you to write patterns that match alternative subtrees.

const pattern3: TreePattern = new TreePattern({
  animal: TreePattern.oneOf([
    { kind: 'dog', bark: 'loud' },
    { kind: 'cat', meow: 'quiet' }
  ])
});

if (pattern3.match({ animal: { kind: 'dog', bark: 'loud' } })) {
  console.log('I can match dog.');
}

if (pattern3.match({ animal: { kind: 'cat', meow: 'quiet' } })) {
  console.log('I can match cat, too.');
}

For example, maybe we want to match Promise['fulfilled'](123); as well as Promise.fulfilled(123);. If the structure of the expressions is similar enough, TreePattern.oneOf avoids having to create two separate patterns.

@rushstack/tree-pattern is part of the Rush Stack family of projects.

FAQs

Package last updated on 27 Jul 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc