Skip to content

Nested function calls have ) token in the wrong place #26

@vjeux

Description

@vjeux

When parsing

a(b(c(d())))

The ) isn't placed in the proper place: the last three ) tokens are placed in the before-last function node instead of the corresponding opening.

Root {
  type: 'root',
  nodes:
   [ Value {
       type: 'value',
       nodes:
        [ FunctionNode {
            type: 'func',
            value: 'a',
            nodes:
             [ Parenthesis { type: 'paren', value: '(' },
               FunctionNode {
                 type: 'func',
                 value: 'b',
                 nodes:
                  [ Parenthesis { type: 'paren', value: '(' },
                    FunctionNode {
                      type: 'func',
                      value: 'c',
                      nodes:
                       [ Parenthesis { type: 'paren', value: '(' },
                         FunctionNode {
                           type: 'func',
                           value: 'd',
                           nodes:
                            [ Parenthesis { type: 'paren', value: '(' },
                              Parenthesis { type: 'paren', value: ')' } ] },
                         Parenthesis { type: 'paren', value: ')' },
                         Parenthesis { type: 'paren', value: ')' },
                         Parenthesis { type: 'paren', value: ')' } ] } ] } ] } ] } ] }

Program to reproduce:

const parser = require('postcss-values-parser')
const str = 'a(b(c(d())))';
const value = parser(str).parse();

log(clean(value));

function log(node) {
  console.log(require('util').inspect(node, false, null));
}

function clean(node) {
  if (Array.isArray(node)) {
    node.forEach(clean);
  } else if (node && typeof node === "object") {
    const type = node.type;
    const value = node.value;
    const nodes = node.nodes;
    for (let key in node) {
      if (key !== "parent") {
        clean(node[key]);
      }
      delete node[key];
    }
    if (type) node.type = type;
    if (value) node.value = value;
    if (nodes) node.nodes = nodes;
  }
  return node;
}

For context, I'm trying to use this to build a CSS pretty printer: prettier/prettier#1636

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions