diff --git a/.changeset/stale-pants-relate.md b/.changeset/stale-pants-relate.md new file mode 100644 index 00000000..0eb922df --- /dev/null +++ b/.changeset/stale-pants-relate.md @@ -0,0 +1,5 @@ +--- +"htmljs-parser": minor +--- + +Improve handling ambiguity with tag type args vs type params. Type args must now always be directly adjacent the tag name, otherwise it will become type params. diff --git a/src/__tests__/fixtures/attr-method-shorthand-with-type-parameters/__snapshots__/attr-method-shorthand-with-type-parameters.expected.txt b/src/__tests__/fixtures/attr-method-shorthand-with-type-parameters/__snapshots__/attr-method-shorthand-with-type-parameters.expected.txt index 3dfc078e..4609fa04 100644 --- a/src/__tests__/fixtures/attr-method-shorthand-with-type-parameters/__snapshots__/attr-method-shorthand-with-type-parameters.expected.txt +++ b/src/__tests__/fixtures/attr-method-shorthand-with-type-parameters/__snapshots__/attr-method-shorthand-with-type-parameters.expected.txt @@ -1,11 +1,11 @@ 1╭─ (event: A){ │ ││ ││ ││ ╰─ attrMethod.body "{\n console.log(event.type)\n}" │ ││ ││ │╰─ attrMethod.params.value "event: A" - │ ││ ││ ╰─ attrMethod.params "(event: A)" - │ ││ │╰─ attrMethod.typeParams.value - │ ││ ├─ attrMethod.typeParams "" - │ ││ ├─ attrMethod "(event: A){\n console.log(event.type)\n}" - │ ││ ╰─ attrName + │ ││ ││ ├─ attrMethod.params "(event: A)" + │ ││ ││ ├─ attrMethod "(event: A){\n console.log(event.type)\n}" + │ ││ ││ ╰─ attrName + │ ││ │╰─ tagTypeArgs.value + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 2╭─ console.log(event.type) @@ -16,11 +16,11 @@ 5╭─ (event: A){ │ ││ ││ ││ ╰─ attrMethod.body "{\n console.log(event.type)\n}" │ ││ ││ │╰─ attrMethod.params.value "event: A" - │ ││ ││ ╰─ attrMethod.params "(event: A)" - │ ││ │╰─ attrMethod.typeParams.value - │ ││ ├─ attrMethod.typeParams "" - │ ││ ├─ attrMethod " (event: A){\n console.log(event.type)\n}" - │ ││ ╰─ attrName + │ ││ ││ ├─ attrMethod.params "(event: A)" + │ ││ ││ ├─ attrMethod "(event: A){\n console.log(event.type)\n}" + │ ││ ││ ╰─ attrName + │ ││ │╰─ tagTypeArgs.value + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 6╭─ console.log(event.type) @@ -61,11 +61,11 @@ 17╭─ (event: A & B){ │ ││ ││ ││ ╰─ attrMethod.body "{\n console.log(event.type)\n}" │ ││ ││ │╰─ attrMethod.params.value "event: A & B" - │ ││ ││ ╰─ attrMethod.params "(event: A & B)" - │ ││ │╰─ attrMethod.typeParams.value "A, B = string" - │ ││ ├─ attrMethod.typeParams "" - │ ││ ├─ attrMethod "(event: A & B){\n console.log(event.type)\n}" - │ ││ ╰─ attrName + │ ││ ││ ├─ attrMethod.params "(event: A & B)" + │ ││ ││ ├─ attrMethod "(event: A & B){\n console.log(event.type)\n}" + │ ││ ││ ╰─ attrName + │ ││ │╰─ tagTypeArgs.value "A, B = string" + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 18╭─ console.log(event.type) @@ -76,11 +76,11 @@ 21╭─ (event: A & B){ │ ││ ││ ││ ╰─ attrMethod.body "{\n console.log(event.type)\n}" │ ││ ││ │╰─ attrMethod.params.value "event: A & B" - │ ││ ││ ╰─ attrMethod.params "(event: A & B)" - │ ││ │╰─ attrMethod.typeParams.value "A, B = string" - │ ││ ├─ attrMethod.typeParams "" - │ ││ ├─ attrMethod " (event: A & B){\n console.log(event.type)\n}" - │ ││ ╰─ attrName + │ ││ ││ ├─ attrMethod.params "(event: A & B)" + │ ││ ││ ├─ attrMethod "(event: A & B){\n console.log(event.type)\n}" + │ ││ ││ ╰─ attrName + │ ││ │╰─ tagTypeArgs.value "A, B = string" + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 22╭─ console.log(event.type) diff --git a/src/__tests__/fixtures/attr-name-with-html-chars/__snapshots__/attr-name-with-html-chars.expected.txt b/src/__tests__/fixtures/attr-name-with-html-chars/__snapshots__/attr-name-with-html-chars.expected.txt index 55a28383..eba7c6d2 100644 --- a/src/__tests__/fixtures/attr-name-with-html-chars/__snapshots__/attr-name-with-html-chars.expected.txt +++ b/src/__tests__/fixtures/attr-name-with-html-chars/__snapshots__/attr-name-with-html-chars.expected.txt @@ -1,7 +1,3 @@ 1╭─ tagname hello frank - │ │ ││ │ │ ╰─ error(INVALID_ATTR_TYPE_PARAMS:Attribute cannot contain type parameters unless it is a shorthand method) "/span" - │ │ ││ │ ╰─ attrName "frank" - │ │ ││ ╰─ attrName "hello" - │ │ │╰─ tagTypeArgs.value "span" - │ │ ╰─ tagTypeArgs "" + │ │ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters.) "span" ╰─ ╰─ tagName "tagname" \ No newline at end of file diff --git a/src/__tests__/fixtures/invalid-multiple-tag-type-params/__snapshots__/invalid-multiple-tag-type-params.expected.txt b/src/__tests__/fixtures/invalid-multiple-tag-type-params/__snapshots__/invalid-multiple-tag-type-params.expected.txt index c2c3b42f..9889145e 100644 --- a/src/__tests__/fixtures/invalid-multiple-tag-type-params/__snapshots__/invalid-multiple-tag-type-params.expected.txt +++ b/src/__tests__/fixtures/invalid-multiple-tag-type-params/__snapshots__/invalid-multiple-tag-type-params.expected.txt @@ -1,5 +1,5 @@ 1╭─ /> - │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must follow a tag name and type paremeters must precede a method or tag parameters.) + │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters.) │ ││ │╰─ tagTypeArgs.value │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" diff --git a/src/__tests__/fixtures/invalid-type-args-after-space/__snapshots__/invalid-type-args-after-space.expected.txt b/src/__tests__/fixtures/invalid-type-args-after-space/__snapshots__/invalid-type-args-after-space.expected.txt new file mode 100644 index 00000000..03e38d4b --- /dev/null +++ b/src/__tests__/fixtures/invalid-type-args-after-space/__snapshots__/invalid-type-args-after-space.expected.txt @@ -0,0 +1,7 @@ +1╭─ > + │ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters.) + │ │╰─ tagName "foo" + ╰─ ╰─ openTagStart +2├─ hi +3├─ +4╰─ \ No newline at end of file diff --git a/src/__tests__/fixtures/invalid-type-args-after-space/input.marko b/src/__tests__/fixtures/invalid-type-args-after-space/input.marko new file mode 100644 index 00000000..d911c158 --- /dev/null +++ b/src/__tests__/fixtures/invalid-type-args-after-space/input.marko @@ -0,0 +1,3 @@ +> + hi + diff --git a/src/__tests__/fixtures/invalid-type-params-after-args/__snapshots__/invalid-type-params-after-args.expected.txt b/src/__tests__/fixtures/invalid-type-params-after-args/__snapshots__/invalid-type-params-after-args.expected.txt index cb7159b9..1c3511b0 100644 --- a/src/__tests__/fixtures/invalid-type-params-after-args/__snapshots__/invalid-type-params-after-args.expected.txt +++ b/src/__tests__/fixtures/invalid-type-params-after-args/__snapshots__/invalid-type-params-after-args.expected.txt @@ -1,5 +1,5 @@ 1╭─ /> - │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must follow a tag name and type paremeters must precede a method or tag parameters.) + │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters.) │ ││ │╰─ tagArgs.value │ ││ ╰─ tagArgs "(a)" │ │╰─ tagName "foo" diff --git a/src/__tests__/fixtures/invalid-type-params-after-params/__snapshots__/invalid-type-params-after-params.expected.txt b/src/__tests__/fixtures/invalid-type-params-after-params/__snapshots__/invalid-type-params-after-params.expected.txt index aab1c933..f7c85ea4 100644 --- a/src/__tests__/fixtures/invalid-type-params-after-params/__snapshots__/invalid-type-params-after-params.expected.txt +++ b/src/__tests__/fixtures/invalid-type-params-after-params/__snapshots__/invalid-type-params-after-params.expected.txt @@ -1,5 +1,5 @@ 1╭─ /> - │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must follow a tag name and type paremeters must precede a method or tag parameters.) + │ ││ ││ ╰─ error(INVALID_TAG_TYPES:Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters.) │ ││ │╰─ tagParams.value │ ││ ╰─ tagParams "|a|" │ │╰─ tagName "foo" diff --git a/src/__tests__/fixtures/tag-params-with-type-parameters/__snapshots__/tag-params-with-type-parameters.expected.txt b/src/__tests__/fixtures/tag-params-with-type-parameters/__snapshots__/tag-params-with-type-parameters.expected.txt index a98f1f83..040c8dbf 100644 --- a/src/__tests__/fixtures/tag-params-with-type-parameters/__snapshots__/tag-params-with-type-parameters.expected.txt +++ b/src/__tests__/fixtures/tag-params-with-type-parameters/__snapshots__/tag-params-with-type-parameters.expected.txt @@ -2,8 +2,8 @@ │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagParams.value "data: A" │ ││ ││ ╰─ tagParams "|data: A|" - │ ││ │╰─ tagTypeParams.value - │ ││ ╰─ tagTypeParams "" + │ ││ │╰─ tagTypeArgs.value + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 2╭─ hi @@ -17,8 +17,8 @@ │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagParams.value "data: A" │ ││ ││ ╰─ tagParams "|data: A|" - │ ││ │╰─ tagTypeParams.value - │ ││ ╰─ tagTypeParams "" + │ ││ │╰─ tagTypeArgs.value + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 6╭─ hi @@ -62,8 +62,8 @@ │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagParams.value "data: A & B" │ ││ ││ ╰─ tagParams "|data: A & B|" - │ ││ │╰─ tagTypeParams.value "A, B = string" - │ ││ ╰─ tagTypeParams "" + │ ││ │╰─ tagTypeArgs.value "A, B = string" + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 18╭─ hi @@ -77,8 +77,8 @@ │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagParams.value "data: A & B" │ ││ ││ ╰─ tagParams "|data: A & B|" - │ ││ │╰─ tagTypeParams.value "A, B = string" - │ ││ ╰─ tagTypeParams "" + │ ││ │╰─ tagTypeArgs.value "A, B = string" + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 22╭─ hi @@ -117,4 +117,54 @@ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " |data: A|> + │ ││ ││││ ││ ╰─ openTagEnd + │ ││ ││││ │╰─ tagParams.value "data: A" + │ ││ ││││ ╰─ tagParams "|data: A|" + │ ││ │││╰─ tagTypeParams.value + │ ││ ││╰─ tagTypeParams "" + │ ││ │╰─ tagArgs.value + │ ││ ╰─ tagArgs "()" + │ │╰─ tagName "foo" + ╰─ ╰─ openTagStart +34╭─ hi + ╰─ ╰─ text "\n hi\n" +35╭─ + │ │ ├─ closeTagEnd(foo) + │ │ ╰─ closeTagName + ╰─ ╰─ closeTagStart " |data: A|> + │ ││ ││││ ││ ╰─ openTagEnd + │ ││ ││││ │╰─ tagParams.value "data: A" + │ ││ ││││ ╰─ tagParams "|data: A|" + │ ││ │││╰─ tagTypeParams.value + │ ││ ││╰─ tagTypeParams "" + │ ││ │╰─ tagVar.value + │ ││ ╰─ tagVar "/x" + │ │╰─ tagName "foo" + ╰─ ╰─ openTagStart +38╭─ hi + ╰─ ╰─ text "\n hi\n" +39╭─ + │ │ ├─ closeTagEnd(foo) + │ │ ╰─ closeTagName + ╰─ ╰─ closeTagStart " |data: A|> + │ ││ ││ ││ ││ ╰─ openTagEnd + │ ││ ││ ││ │╰─ tagParams.value "data: A" + │ ││ ││ ││ ╰─ tagParams "|data: A|" + │ ││ ││ │╰─ tagTypeParams.value + │ ││ ││ ╰─ tagTypeParams "" + │ ││ │╰─ tagTypeArgs.value "string" + │ ││ ╰─ tagTypeArgs "" + │ │╰─ tagName "foo" + ╰─ ╰─ openTagStart +42╭─ hi + ╰─ ╰─ text "\n hi\n" +43╭─ + │ │ ├─ closeTagEnd(foo) + │ │ ╰─ closeTagName + ╰─ ╰─ closeTagStart " |data: A & B|> hi + + |data: A|> + hi + + + |data: A|> + hi + + + |data: A|> + hi + \ No newline at end of file diff --git a/src/__tests__/fixtures/tag-with-type-arguments/__snapshots__/tag-with-type-arguments.expected.txt b/src/__tests__/fixtures/tag-with-type-arguments/__snapshots__/tag-with-type-arguments.expected.txt index 9d1f21d9..3b72beaa 100644 --- a/src/__tests__/fixtures/tag-with-type-arguments/__snapshots__/tag-with-type-arguments.expected.txt +++ b/src/__tests__/fixtures/tag-with-type-arguments/__snapshots__/tag-with-type-arguments.expected.txt @@ -24,10 +24,10 @@ │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart "> - │ ││ ││ ╰─ openTagEnd - │ ││ │╰─ tagTypeArgs.value - │ ││ ╰─ tagTypeArgs "" +9╭─ > + │ ││ ││ ╰─ openTagEnd + │ ││ │╰─ tagTypeArgs.value "A, B = string" + │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart 10╭─ hi @@ -37,72 +37,20 @@ │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " > - │ ││ ││ ╰─ openTagEnd - │ ││ │╰─ tagTypeArgs.value - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -14╭─ hi - ╰─ ╰─ text "\n hi\n" -15╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart "> - │ ││ ││ ╰─ openTagEnd - │ ││ │╰─ tagTypeArgs.value "A, B = string" - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -18╭─ hi - ╰─ ╰─ text "\n hi\n" -19╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart " > +13╭─ > │ ││ ││ ╰─ openTagEnd │ ││ │╰─ tagTypeArgs.value "A, B = string" │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -22╭─ hi - ╰─ ╰─ text "\n hi\n" -23╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart "> - │ ││ ││ ╰─ openTagEnd - │ ││ │╰─ tagTypeArgs.value "A, B = string" - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -26╭─ hi - ╰─ ╰─ text "\n hi\n" -27╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart " > - │ ││ ││ ╰─ openTagEnd - │ ││ │╰─ tagTypeArgs.value "A, B = string" - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -30╭─ hi +14╭─ hi ╰─ ╰─ text "\n hi\n" -31╭─ +15╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart "(bar)> +16├─ +17╭─ (bar)> │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagArgs.value "bar" │ ││ ││ ╰─ tagArgs "(bar)" @@ -110,14 +58,14 @@ │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -34╭─ hi +18╭─ hi ╰─ ╰─ text "\n hi\n" -35╭─ +19╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " (bar)> +20├─ +21╭─ (bar)> │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagArgs.value "bar" │ ││ ││ ╰─ tagArgs "(bar)" @@ -125,44 +73,14 @@ │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -38╭─ hi - ╰─ ╰─ text "\n hi\n" -39╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart "(bar)> - │ ││ ││ ││ ╰─ openTagEnd - │ ││ ││ │╰─ tagArgs.value "bar" - │ ││ ││ ╰─ tagArgs "(bar)" - │ ││ │╰─ tagTypeArgs.value - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -42╭─ hi - ╰─ ╰─ text "\n hi\n" -43╭─ - │ │ ├─ closeTagEnd(foo) - │ │ ╰─ closeTagName - ╰─ ╰─ closeTagStart " (bar)> - │ ││ ││ ││ ╰─ openTagEnd - │ ││ ││ │╰─ tagArgs.value "bar" - │ ││ ││ ╰─ tagArgs "(bar)" - │ ││ │╰─ tagTypeArgs.value - │ ││ ╰─ tagTypeArgs "" - │ │╰─ tagName "foo" - ╰─ ╰─ openTagStart -46╭─ hi +22╭─ hi ╰─ ╰─ text "\n hi\n" -47╭─ +23╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart "(bar)> +24├─ +25╭─ (bar)> │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagArgs.value "bar" │ ││ ││ ╰─ tagArgs "(bar)" @@ -170,14 +88,14 @@ │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -50╭─ hi +26╭─ hi ╰─ ╰─ text "\n hi\n" -51╭─ +27╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " (bar)> +28├─ +29╭─ (bar)> │ ││ ││ ││ ╰─ openTagEnd │ ││ ││ │╰─ tagArgs.value "bar" │ ││ ││ ╰─ tagArgs "(bar)" @@ -185,40 +103,74 @@ │ ││ ╰─ tagTypeArgs "" │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -54╭─ hi +30╭─ hi + ╰─ ╰─ text "\n hi\n" +31╭─ + │ │ ├─ closeTagEnd(foo) + │ │ ╰─ closeTagName + ╰─ ╰─ closeTagStart " (bar) { + │ ││ ││ ││ ╰─ attrMethod.body "{\n \n}" + │ ││ ││ │╰─ attrMethod.params.value "bar" + │ ││ ││ ├─ attrMethod.params "(bar)" + │ ││ ││ ├─ attrMethod "(bar) {\n \n}" + │ ││ ││ ╰─ attrName + │ ││ │╰─ tagTypeArgs.value + │ ││ ╰─ tagTypeArgs "" + │ │╰─ tagName "foo" + ╰─ ╰─ openTagStart +35╭─ + ╰─ ╰─ attrMethod.body.value "\n \n" +36╭─ }> + ╰─ ╰─ openTagEnd +37╭─ hi ╰─ ╰─ text "\n hi\n" -55╭─ +38╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart "(bar)> - │ ││ ││ ││ ╰─ openTagEnd - │ ││ ││ │╰─ tagArgs.value "bar" - │ ││ ││ ╰─ tagArgs "(bar)" - │ ││ │╰─ tagTypeArgs.value "A, B = string" - │ ││ ╰─ tagTypeArgs "" +39├─ +40╭─ (bar) { + │ ││ ││ ││ ╰─ attrMethod.body "{\n \n}" + │ ││ ││ │╰─ attrMethod.params.value "bar" + │ ││ ││ ╰─ attrMethod.params "(bar)" + │ ││ │╰─ attrMethod.typeParams.value + │ ││ ├─ attrMethod.typeParams "" + │ ││ ├─ attrMethod " (bar) {\n \n}" + │ ││ ╰─ attrName │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -58╭─ hi +41╭─ + ╰─ ╰─ attrMethod.body.value "\n \n" +42╭─ }> + ╰─ ╰─ openTagEnd +43╭─ hi ╰─ ╰─ text "\n hi\n" -59╭─ +44╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " (bar)> - │ ││ ││ ││ ╰─ openTagEnd - │ ││ ││ │╰─ tagArgs.value "bar" - │ ││ ││ ╰─ tagArgs "(bar)" - │ ││ │╰─ tagTypeArgs.value "A, B = string" - │ ││ ╰─ tagTypeArgs "" +45├─ +46╭─ (bar) { + │ ││ ││ ││ ╰─ attrMethod.body "{\n \n}" + │ ││ ││ │╰─ attrMethod.params.value "bar" + │ ││ ││ ╰─ attrMethod.params "(bar)" + │ ││ │╰─ attrMethod.typeParams.value + │ ││ ├─ attrMethod.typeParams "" + │ ││ ├─ attrMethod "(bar) {\n \n}" + │ ││ ╰─ attrName │ │╰─ tagName "foo" ╰─ ╰─ openTagStart -62╭─ hi +47╭─ + ╰─ ╰─ attrMethod.body.value "\n \n" +48╭─ }> + ╰─ ╰─ openTagEnd +49╭─ hi ╰─ ╰─ text "\n hi\n" -63╭─ +50╭─ │ │ ├─ closeTagEnd(foo) │ │ ╰─ closeTagName ╰─ ╰─ closeTagStart " -> - hi - - - > - hi - - > hi @@ -22,14 +14,6 @@ hi -> - hi - - - > - hi - - (bar)> hi @@ -38,26 +22,29 @@ hi -(bar)> +(bar)> hi - (bar)> + (bar)> hi -(bar)> - hi - - (bar)> + (bar) { + +}> hi -(bar)> + (bar) { + +}> hi - (bar)> +(bar) { + +}> hi diff --git a/src/states/OPEN_TAG.ts b/src/states/OPEN_TAG.ts index bf4f0962..cf67098c 100644 --- a/src/states/OPEN_TAG.ts +++ b/src/states/OPEN_TAG.ts @@ -31,7 +31,7 @@ export interface OpenTagMeta extends Meta { hasArgs: boolean; hasAttrs: boolean; hasParams: boolean; - types: undefined | Ranges.Value; + typeParams: undefined | Ranges.Value; hasShorthandId: boolean; selfClosed: boolean; indent: string; @@ -57,7 +57,7 @@ export const OPEN_TAG: StateDefinition = { hasArgs: false, hasAttrs: false, hasParams: false, - types: undefined, + typeParams: undefined, selfClosed: false, shorthandEnd: -1, tagName: undefined!, @@ -379,7 +379,7 @@ export const OPEN_TAG: StateDefinition = { break; } case TAG_STAGE.ARGUMENT: { - const { types } = tag; + const { typeParams } = tag; const start = child.start - 1; // include ( const end = ++this.pos; // include ) const value = { @@ -390,9 +390,9 @@ export const OPEN_TAG: StateDefinition = { if (this.consumeWhitespaceIfBefore("{")) { const attr = this.enterState(STATE.ATTRIBUTE); - if (types) { - attr.start = types.start; - attr.typeParams = types; + if (typeParams) { + attr.start = typeParams.start; + attr.typeParams = typeParams; } else { attr.start = start; } @@ -401,8 +401,13 @@ export const OPEN_TAG: StateDefinition = { this.forward = 0; tag.hasAttrs = true; } else { - if (types) { - this.options.onTagTypeArgs?.(types); + if (typeParams) { + this.emitError( + child, + ErrorCode.INVALID_TAG_TYPES, + "Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters." + ); + break; } this.options.onTagArgs?.({ @@ -414,9 +419,9 @@ export const OPEN_TAG: StateDefinition = { break; } case TAG_STAGE.TYPES: { - const { types, hasParams, hasArgs } = tag; + const { typeParams, hasParams, hasArgs } = tag; const end = ++this.pos; // include > - const typeArgs: Ranges.Value = { + const types: Ranges.Value = { start: child.start - 1, // include < end, value: { @@ -425,29 +430,27 @@ export const OPEN_TAG: StateDefinition = { }, }; + if (tag.tagName.end === types.start) { + // When we match types just after the tag name then we are dealing with a type argument. + this.options.onTagTypeArgs?.(types); + break; + } + this.consumeWhitespace(); const nextCode = this.lookAtCharCodeAhead(0); - if (!hasParams && nextCode === CODE.PIPE) { - if (types) { - this.options.onTagTypeArgs?.(types); - } - - this.options.onTagTypeParams?.(typeArgs); - } else if (!hasArgs && nextCode === CODE.OPEN_PAREN) { - if (types) { - this.options.onTagTypeArgs?.(types); - } - - tag.types = typeArgs; - } else if (!(types || hasParams || hasArgs)) { - this.options.onTagTypeArgs?.(typeArgs); - tag.types = typeArgs; + if (nextCode === CODE.PIPE && !hasParams) { + this.options.onTagTypeParams?.(types); + } else if ( + nextCode === CODE.OPEN_PAREN && + !(typeParams || hasParams || hasArgs) + ) { + tag.typeParams = types; } else { this.emitError( child, ErrorCode.INVALID_TAG_TYPES, - "Unexpected types. Type arguments must follow a tag name and type paremeters must precede a method or tag parameters." + "Unexpected types. Type arguments must directly follow a tag name and type paremeters must precede a method or tag parameters." ); }