Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor: Create a matcher utility to facilitate rule creation #26

Open
thiagomini opened this issue Feb 28, 2024 · 0 comments
Open

Refactor: Create a matcher utility to facilitate rule creation #26

thiagomini opened this issue Feb 28, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@thiagomini
Copy link
Contributor

Description

Manipulating and querying ASTs is inherently a complex problem. Often, we need to perform consecutive checks for children's properties, including their type and value. This leads to repetitive, not-so-readable code. Here's an example of such code:

if (ASTUtils.isVariableDeclarator(parent)) {
    const init = parent.init;
    let type: ProviderType | undefined;
    if (init?.type === AST_NODE_TYPES.ObjectExpression) {
      const properties = init.properties;
      for (const property of properties) {
        if (property.type === AST_NODE_TYPES.Property) {
          type = providerTypeOfProperty(property);
        }
      }
    }

    return type;
  }

And here's how this could be replaced with TS-Pattern

  return match(node)
    .with(
      {
        parent: {
          init: {
            type: AST_NODE_TYPES.ObjectExpression,
            properties: P.select(),
          },
          type: P.when(ASTUtils.isVariableDeclarator),
        },
      },
      (properties) => {
        for (const property of properties) {
          if (property.type === AST_NODE_TYPES.Property) {
            const type = providerTypeOfProperty(property);
            if (type) {
              return type;
            }
          }
        }
      }
    )
    .otherwise(() => undefined);

This second approach is more declarative and makes it easier to grasp the expected node structure. Moreover, we can select parts of the matched node with the P.select() function and make use of it in the following callback function.

Acceptance Criteria

Initially, it would suffice to implement a match(node) function that accepts two additional methods:

with(structure, callback | value) - matches with given object structure, and returns either the value or the callback's returned value
when(function, callback | value) - matches with the given matching function, and returns either the value or the callback's returned value

@thiagomini thiagomini added the enhancement New feature or request label Feb 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant