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

Formatter Problem #1649

Open
cdietrich opened this issue Aug 27, 2024 · 0 comments
Open

Formatter Problem #1649

cdietrich opened this issue Aug 27, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@cdietrich
Copy link
Contributor

cdietrich commented Aug 27, 2024

Given the grammar

entry ContextDefinition:
    packages+=ContextPackage+;

ContextPackage:
    'package' packageName=ID '{'
        ('nodes' '{'  '}')?
        ('files' '{'  '}')?
    '}';

hidden terminal WS: /\s+/;
terminal ID: /[_a-zA-Z][\w_]*/;

hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//;
hidden terminal SL_COMMENT: /\/\/[^\n\r]*/;

and formatter

const FormatingOptions = {
    lineBreak: Formatting.newLine({ allowMore: true }),
    lineBreakOne: Formatting.newLines(1, { allowMore: false }),
    emptyLine: Formatting.newLines(2, { allowMore: true }),
    newLineAllowMore: Formatting.newLine({ allowMore: true }),
    oneSpace: Formatting.spaces(1),
    noSpace: Formatting.noSpace(),
    indent: Formatting.indent({ allowMore: true }),
    noIndent: Formatting.noIndent({ allowMore: true }),
    noNewLines: Formatting.newLines(0),
  }

  function formatNestedBody(_: AstNode, formatter: NodeFormatter<AstNode>) {
    console.log("formatNestedBody")
    const opens = formatter.keywords("{")
    const closes = formatter.keywords("}")
    if (opens.nodes.length === closes.nodes.length && opens.nodes.length > 0) {
      const [outerOpen, ...innerOpens] = opens.nodes
      const outerClose = closes.nodes[closes.nodes.length - 1]
      const innerCloses = closes.nodes.slice(0, closes.nodes.length - 1)
  
      // format the outer {}
      console.log(outerOpen.range.start.line, outerClose.range.start.line)
      const bracesOpenOuter = formatter.cst([outerOpen])
      const bracesCloseOuter = formatter.cst([outerClose])
      formatter.interior(bracesOpenOuter, bracesCloseOuter).prepend(FormatingOptions.indent)
      bracesCloseOuter.prepend(FormatingOptions.lineBreakOne)
      bracesOpenOuter.prepend(FormatingOptions.oneSpace)
  
      // format the inner ones inputs {} ...
      for (let i = 0; i < innerOpens.length; i++) {
        const c1 = innerOpens[i]
        const c2 = innerCloses[i]
        console.log(c1.range.start.line, c2.range.start.line)
        const bracesOpen = formatter.cst([c1])
        const bracesClose = formatter.cst([c2])
        formatter.interior(bracesOpen, bracesClose).prepend(FormatingOptions.indent)
        bracesClose.prepend(FormatingOptions.lineBreakOne)
        bracesOpen.prepend(FormatingOptions.oneSpace)
      }
    }
  }

export class CustomFormatter extends AbstractFormatter {
    protected format(node: AstNode): void {
        if (node.$type === 'ContextPackage') {
            const formatter = this.getNodeFormatter(node);
            formatNestedBody(node, formatter)
            formatter
              .keywords(",")
              .append(FormatingOptions.lineBreakOne)
              .prepend(FormatingOptions.noIndent)
              .prepend(FormatingOptions.noNewLines)
              .prepend(FormatingOptions.noSpace)
        }
    }
}

sample file

package sample {
    nodes {} files {}
}

is not formatted as expected (nicely indented)

when i refactor the grammar to use fragments, it suddenly works.
any idea what the problem could be

ContextPackage:
    'package' packageName=ID '{'
        (ContextNodeList)?
        (ContextFileList)?
    '}';

fragment ContextFileList:
    x?='files' '{'  '}';

fragment ContextNodeList*:
    y?='nodes' '{'  '}';

unfortunately the workaround cannot be applied in production cause of the
AST node has no document
bug

@cdietrich cdietrich added the bug Something isn't working label Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant