vrischmann / tree-sitter-templ

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Self-closing style tag is a syntax error

danderson opened this issue · comments

A self-closing <style /> element in a templ component is a parse error, instead of a self_closing_tag. With this additional test case:

===
Self closing script block
===

package main

templ Foobar() {
  <script src="/app.js" />
}

---

(source_file
  (package_clause
    (package_identifier))
  (component_declaration
    name: (component_identifier)
    (parameter_list)
    (component_block
      (self_closing_tag
        (attribute
          name: (attribute_name)
          value: (quoted_attribute_value
            (attribute_value)))))))

The test fails:

  1. Self closing script block:

    (source_file
      (package_clause
        (package_identifier))
      (component_declaration
        name: (component_identifier)
        (parameter_list)
        (component_block
<         (ERROR
>         (self_closing_tag
            (attribute
              name: (attribute_name)
              value: (quoted_attribute_value
                (attribute_value)))))))

I tried to go into the grammar and fix this, but... I don't understand why this fails :/

_component_node includes choices for element and script_element, and element defines self_closing_tag as a valid parse. So, my assumption was that tree-sitter would handle the ambiguity and discover the correct branch of the parse tree... but it seems to get fixated on parsing as a script_element, and never goes back to try a parse as element instead.

I assumed that maybe we need to add/modify the conflicts between tag_start and self_closing_tag, but if that's the problem then the generate phase should be failing with a conflict, instead of generating a parser that never explores the self_closing_tag option :/

Any ideas?

I took a quick look and I'm not sure either.

Self-closing tags that are not style or script seem to work fine, it could be there's something wrong in the scanner functions used to handle style_element_text, script_element_text or script_block_text; something like this already happened.

I'll look into it further.

Aah, good point. I don't know much about custom scanner functions in tree-sitter, but I guess it needs to return appropriate token/state info to the parser. I will also try to investigate in that direction a bit later, thank you for the info!

So, I spent a bit of time looking into it and I don't think it's related to the scanner.

By changing $.style_element to

        style_element: $ => seq(
            '<',
            'style',
            repeat($._attribute),
            '>',
            'foo',
            '</',
            'style',
            '>'
        ),

so that the scanner is not called, it doesn't work either, I still get an error.

Looking at the output from tree-sitter parse -D foo.templ and searching around, I'm thinking this is supposed to not work. I think I'll have to try to make a minimal reproducer.

This change "fixes" the problem eb82739

but now it breaks a bunch of other unrelated tests because style_element doesn't get used.

I'm not sure if it's possible to fix it but we can work around the problem: we can simply make style_element and script_element handle self closing tags themselves; I've tested it and it works.