Détail du package

@rushstack/tree-pattern

microsoft371kMIT0.3.4

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

readme

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

Links

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

changelog

Change Log - @rushstack/tree-pattern

This log was last generated on Sat, 27 Jul 2024 00:10:27 GMT and should not be manually modified.

0.3.4

Sat, 27 Jul 2024 00:10:27 GMT

Patches

  • Include CHANGELOG.md in published releases again

0.3.3

Sat, 17 Feb 2024 06:24:35 GMT

Patches

  • Fix broken link to API documentation

0.3.2

Tue, 16 Jan 2024 18:30:10 GMT

Patches

  • Upgrade build dependencies

0.3.1

Tue, 26 Sep 2023 09:30:33 GMT

Patches

  • Update type-only imports to include the type modifier.

0.3.0

Fri, 15 Sep 2023 00:36:58 GMT

Minor changes

  • Update @types/node from 14 to 18

0.2.4

Fri, 17 Jun 2022 00:16:18 GMT

Patches

  • Add missing types

0.2.3

Sat, 09 Apr 2022 02:24:27 GMT

Patches

  • Rename the "master" branch to "main".

0.2.2

Wed, 27 Oct 2021 00:08:15 GMT

Patches

  • Update the package.json repository field to include the directory property.

0.2.1

Wed, 30 Sep 2020 18:39:17 GMT

Patches

  • Update to build with @rushstack/heft-node-rig

0.2.0

Wed, 30 Sep 2020 06:53:53 GMT

Minor changes

  • Upgrade compiler; the API now requires TypeScript 3.9 or newer

Patches

  • Update README.md

0.1.0

Sat, 19 Sep 2020 03:33:06 GMT

Minor changes

  • Initial release