From e320d95a98120d0de9f13ecd9c7b374ad671c835 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Mon, 19 Feb 2024 21:53:44 -0600 Subject: [PATCH 01/21] feat: add Expression to attribute/element structs --- .version | 2 +- parser/v2/elementparser.go | 2 ++ parser/v2/types.go | 72 ++++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/.version b/.version index e78210a00..fedfd6bd7 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.569 \ No newline at end of file +0.2.572 \ No newline at end of file diff --git a/parser/v2/elementparser.go b/parser/v2/elementparser.go index ebaaa88e5..54d1ab2b1 100644 --- a/parser/v2/elementparser.go +++ b/parser/v2/elementparser.go @@ -120,6 +120,8 @@ var ( return } + attr.AttributeExpression = NewExpression(attr.Name, pi.Position(), pi.PositionAt(pi.Index()+len(attr.Name))) + // =" result, ok, err := parse.Or(parse.String(`="`), parse.String(`='`)).Parse(pi) if err != nil || !ok { diff --git a/parser/v2/types.go b/parser/v2/types.go index 6eba4caa9..06385c696 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -405,6 +405,17 @@ type WhitespaceTrailer interface { Trailing() TrailingSpace } +type HTMLExpression interface { + HTMLExpression() Expression +} + +var ( + _ HTMLExpression = Element{} + _ HTMLExpression = BoolConstantAttribute{} + _ HTMLExpression = BoolExpressionAttribute{} + _ HTMLExpression = ConstantAttribute{} +) + var ( _ WhitespaceTrailer = Element{} _ WhitespaceTrailer = Text{} @@ -430,18 +441,23 @@ func (t Text) Write(w io.Writer, indent int) error { // or
...
type Element struct { - Name string - Attributes []Attribute - IndentAttrs bool - Children []Node - IndentChildren bool - TrailingSpace TrailingSpace + Name string + Attributes []Attribute + IndentAttrs bool + Children []Node + IndentChildren bool + TrailingSpace TrailingSpace + ElementExpression Expression } func (e Element) Trailing() TrailingSpace { return e.TrailingSpace } +func (e Element) HTMLExpression() Expression { + return e.ElementExpression +} + var voidElements = map[string]struct{}{ "area": {}, "base": {}, "br": {}, "col": {}, "command": {}, "embed": {}, "hr": {}, "img": {}, "input": {}, "keygen": {}, "link": {}, "meta": {}, "param": {}, "source": {}, "track": {}, "wbr": {}, } @@ -691,7 +707,8 @@ type Attribute interface { //
type BoolConstantAttribute struct { - Name string + Name string + AttributeExpression Expression } func (bca BoolConstantAttribute) String() string { @@ -702,11 +719,16 @@ func (bca BoolConstantAttribute) Write(w io.Writer, indent int) error { return writeIndent(w, indent, bca.String()) } +func (bca BoolConstantAttribute) HTMLExpression() Expression { + return bca.AttributeExpression +} + // href="" type ConstantAttribute struct { - Name string - Value string - SingleQuote bool + Name string + Value string + SingleQuote bool + AttributeExpression Expression } func (ca ConstantAttribute) String() string { @@ -721,24 +743,34 @@ func (ca ConstantAttribute) Write(w io.Writer, indent int) error { return writeIndent(w, indent, ca.String()) } +func (ca ConstantAttribute) HTMLExpression() Expression { + return ca.AttributeExpression +} + // noshade={ templ.Bool(...) } type BoolExpressionAttribute struct { - Name string - Expression Expression + Name string + Expression Expression + AttributeExpression Expression +} + +func (bea BoolExpressionAttribute) String() string { + return bea.Name + `?={ ` + bea.Expression.Value + ` }` } -func (ea BoolExpressionAttribute) String() string { - return ea.Name + `?={ ` + ea.Expression.Value + ` }` +func (bea BoolExpressionAttribute) Write(w io.Writer, indent int) error { + return writeIndent(w, indent, bea.String()) } -func (ea BoolExpressionAttribute) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, ea.String()) +func (bea BoolExpressionAttribute) HTMLExpression() Expression { + return bea.AttributeExpression } // href={ ... } type ExpressionAttribute struct { - Name string - Expression Expression + Name string + Expression Expression + AttributeExpression Expression } func (ea ExpressionAttribute) String() string { @@ -793,6 +825,10 @@ func (ea ExpressionAttribute) Write(w io.Writer, indent int) (err error) { return writeIndent(w, indent, "}") } +func (ea ExpressionAttribute) HTMLExpression() Expression { + return ea.AttributeExpression +} + //
type SpreadAttributes struct { Expression Expression From 71e3a345564f4c7e62b6a139d4a2613cd15c7692 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Wed, 21 Feb 2024 22:20:53 -0600 Subject: [PATCH 02/21] add position setters and update unit tests --- .version | 2 +- parser/v2/elementparser.go | 8 +- parser/v2/elementparser_test.go | 175 ++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 3 deletions(-) diff --git a/.version b/.version index 491638239..149e2ffcc 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.571 +0.2.574 \ No newline at end of file diff --git a/parser/v2/elementparser.go b/parser/v2/elementparser.go index 54d1ab2b1..62c2540fe 100644 --- a/parser/v2/elementparser.go +++ b/parser/v2/elementparser.go @@ -119,8 +119,7 @@ var ( pi.Seek(start) return } - - attr.AttributeExpression = NewExpression(attr.Name, pi.Position(), pi.PositionAt(pi.Index()+len(attr.Name))) + attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // =" result, ok, err := parse.Or(parse.String(`="`), parse.String(`='`)).Parse(pi) @@ -173,6 +172,7 @@ var boolConstantAttributeParser = parse.Func(func(pi *parse.Input) (attr BoolCon pi.Seek(start) return } + attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // We have a name, but if we have an equals sign, it's not a constant boolean attribute. next, ok := pi.Peek(1) @@ -210,6 +210,7 @@ var boolExpressionAttributeParser = parse.Func(func(pi *parse.Input) (r BoolExpr pi.Seek(start) return } + r.AttributeExpression = NewExpression(r.Name, pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) // Check whether this is a boolean expression attribute. if _, ok, err = boolExpressionStart.Parse(pi); err != nil || !ok { @@ -245,6 +246,7 @@ var expressionAttributeParser = parse.Func(func(pi *parse.Input) (attr Expressio pi.Seek(start) return } + attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // ={ if _, ok, err = parse.Or(parse.String("={ "), parse.String("={")).Parse(pi); err != nil || !ok { @@ -391,6 +393,7 @@ func (elementOpenCloseParser) Parse(pi *parse.Input) (r Element, ok bool, err er r.Name = ot.Name r.Attributes = ot.Attributes r.IndentAttrs = ot.IndentAttrs + r.ElementExpression = NewExpression(r.Name, pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) // Once we've got an open tag, the rest must be present. l := pi.Position().Line @@ -448,6 +451,7 @@ var selfClosingElement = parse.Func(func(pi *parse.Input) (e Element, ok bool, e pi.Seek(start) return } + e.ElementExpression = NewExpression(e.Name, pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 3d673e83e..0e3addb99 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -43,6 +43,13 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "_", Value: "show = true", + AttributeExpression: Expression{ + Value: "_", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, }, }, }, @@ -57,10 +64,24 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "@click", Value: "show = true", + AttributeExpression: Expression{ + Value: "@click", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 11, Line: 0, Col: 11}, + }, + }, }, ConstantAttribute{ Name: ":class", Value: "{'foo': true}", + AttributeExpression: Expression{ + Value: ":class", + Range: Range{ + From: Position{Index: 26, Line: 0, Col: 26}, + To: Position{Index: 32, Line: 0, Col: 32}, + }, + }, }, }, }, @@ -75,10 +96,24 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "id", Value: "123", + AttributeExpression: Expression{ + Value: "id", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, }, ConstantAttribute{ Name: "style", Value: "padding: 10px", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 14, Line: 0, Col: 14}, + To: Position{Index: 19, Line: 0, Col: 19}, + }, + }, }, }, }, @@ -111,6 +146,13 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 23, Line: 2, Col: 3}, + To: Position{Index: 28, Line: 2, Col: 8}, + }, + }, }, }, }, @@ -145,12 +187,33 @@ if test { ConstantAttribute{ Name: "class", Value: "itIsTrue", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 13, Line: 2, Col: 1}, + To: Position{Index: 18, Line: 2, Col: 6}, + }, + }, }, BoolConstantAttribute{ Name: "noshade", + AttributeExpression: Expression{ + Value: "noshade", + Range: Range{ + From: Position{Index: 31, Line: 3, Col: 1}, + To: Position{Index: 38, Line: 3, Col: 8}, + }, + }, }, ExpressionAttribute{ Name: "name", + AttributeExpression: Expression{ + Value: "name", + Range: Range{ + From: Position{Index: 40, Line: 4, Col: 1}, + To: Position{Index: 44, Line: 4, Col: 5}, + }, + }, Expression: Expression{ Value: `"other"`, Range: Range{ @@ -176,6 +239,13 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", + AttributeExpression: Expression{ + Value: "noshade", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, + }, + }, Expression: Expression{ Value: "true", Range: Range{ @@ -199,6 +269,13 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", + AttributeExpression: Expression{ + Value: "noshade", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, + }, + }, Expression: Expression{ Value: "true", Range: Range{ @@ -222,6 +299,13 @@ if test { parser: StripType[Attribute](attributeParser{}), expected: BoolExpressionAttribute{ Name: "noshade", + AttributeExpression: Expression{ + Value: "noshade", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, + }, + }, Expression: Expression{ Value: "true", Range: Range{ @@ -268,6 +352,13 @@ if test { expected: ConstantAttribute{ Name: "href", Value: "test", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -278,6 +369,13 @@ if test { Name: "href", Value: `no double quote in value`, SingleQuote: false, + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -288,6 +386,13 @@ if test { Name: "href", Value: `"test"`, SingleQuote: true, + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -297,6 +402,13 @@ if test { expected: ConstantAttribute{ Name: "data-turbo-permanent", Value: "value", + AttributeExpression: Expression{ + Value: "data-turbo-permanent", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 21, Line: 0, Col: 21}, + }, + }, }, }, { @@ -306,6 +418,13 @@ if test { expected: ConstantAttribute{ Name: "data", Value: "", + AttributeExpression: Expression{ + Value: "data", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -318,6 +437,13 @@ if test { expected: ConstantAttribute{ Name: "data-script", Value: "on click\n do something\n end", + AttributeExpression: Expression{ + Value: "data-script", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, + }, + }, }, }, { @@ -329,6 +455,13 @@ if test { Attributes: []Attribute{ BoolConstantAttribute{ Name: "data", + AttributeExpression: Expression{ + Value: "data", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 9, Line: 0, Col: 9}, + }, + }, }, }, }, @@ -340,9 +473,23 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", + AttributeExpression: Expression{ + Value: "required", + Range: Range{ + From: Position{Index: 9, Line: 1, Col: 2}, + To: Position{Index: 17, Line: 1, Col: 10}, + }, + }, }, }, }, @@ -354,9 +501,23 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", + AttributeExpression: Expression{ + Value: "required", + Range: Range{ + From: Position{Index: 10, Line: 1, Col: 2}, + To: Position{Index: 18, Line: 1, Col: 10}, + }, + }, }, }, }, @@ -368,6 +529,13 @@ if test { expected: ConstantAttribute{ Name: "href", Value: `<">`, + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -377,6 +545,13 @@ if test { expected: ConstantAttribute{ Name: "hx-target-*", Value: `#errors`, + AttributeExpression: Expression{ + Value: `hx-target-*`, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, + }, + }, }, }, } From 6ae9a5e6f5ab6aeb7205da51749b4cd3d30734ce Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Thu, 22 Feb 2024 21:56:31 -0600 Subject: [PATCH 03/21] chore: fix unit tests with position expressions --- parser/v2/elementparser.go | 10 +- parser/v2/elementparser_test.go | 222 +++++++++++++++++++++++ parser/v2/forexpressionparser_test.go | 14 ++ parser/v2/ifexpressionparser_test.go | 21 +++ parser/v2/raw_test.go | 21 +++ parser/v2/switchexpressionparser_test.go | 14 ++ parser/v2/templateparser_test.go | 111 +++++++++++- parser/v2/templelementparser_test.go | 25 ++- 8 files changed, 425 insertions(+), 13 deletions(-) diff --git a/parser/v2/elementparser.go b/parser/v2/elementparser.go index 62c2540fe..51893d09e 100644 --- a/parser/v2/elementparser.go +++ b/parser/v2/elementparser.go @@ -13,9 +13,10 @@ import ( // Element open tag. type elementOpenTag struct { - Name string - Attributes []Attribute - IndentAttrs bool + Name string + Attributes []Attribute + IndentAttrs bool + ElementExpression Expression } var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, ok bool, err error) { @@ -32,6 +33,7 @@ var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, o pi.Seek(start) return } + e.ElementExpression = NewExpression(e.Name, pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) @@ -393,7 +395,7 @@ func (elementOpenCloseParser) Parse(pi *parse.Input) (r Element, ok bool, err er r.Name = ot.Name r.Attributes = ot.Attributes r.IndentAttrs = ot.IndentAttrs - r.ElementExpression = NewExpression(r.Name, pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) + r.ElementExpression = ot.ElementExpression // Once we've got an open tag, the rest must be present. l := pi.Position().Line diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 0e3addb99..773cd6132 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -944,10 +944,24 @@ func TestElementParser(t *testing.T) { >Test

`, expected: Element{ Name: "p", + ElementExpression: Expression{ + Value: "p", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 8, Line: 0, Col: 8}, + }, + }, }, ConditionalAttribute{ Expression: Expression{ @@ -969,6 +983,13 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 43, Line: 2, Col: 4}, + To: Position{Index: 48, Line: 2, Col: 9}, + }, + }, }, }, }, @@ -984,6 +1005,13 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, }, }, { @@ -991,6 +1019,13 @@ func TestElementParser(t *testing.T) { input: `The text`, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Children: []Node{ Text{ Value: "The text", @@ -1003,9 +1038,23 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Children: []Node{ Element{ Name: "b", + ElementExpression: Expression{ + Value: "b", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, }, @@ -1015,9 +1064,23 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Children: []Node{ Element{ Name: "b", + ElementExpression: Expression{ + Value: "b", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, }, }, }, @@ -1027,10 +1090,24 @@ func TestElementParser(t *testing.T) { input: ` `, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Children: []Node{ Whitespace{Value: " "}, Element{ Name: "b", + ElementExpression: Expression{ + Value: "b", + Range: Range{ + From: Position{Index: 6, Line: 0, Col: 6}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, Children: []Node{ Whitespace{Value: " "}, }, @@ -1044,15 +1121,43 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Children: []Node{ Element{ Name: "b", + ElementExpression: Expression{ + Value: "b", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, }, Element{ Name: "c", + ElementExpression: Expression{ + Value: "c", + Range: Range{ + From: Position{Index: 12, Line: 0, Col: 12}, + To: Position{Index: 13, Line: 0, Col: 13}, + }, + }, Children: []Node{ Element{ Name: "d", + ElementExpression: Expression{ + Value: "d", + Range: Range{ + From: Position{Index: 14, Line: 0, Col: 14}, + To: Position{Index: 15, Line: 0, Col: 15}, + }, + }, }, }, }, @@ -1064,6 +1169,13 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, }, }, { @@ -1071,6 +1183,13 @@ func TestElementParser(t *testing.T) { input: `
{ "test" }
`, expected: Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 2, Line: 0, Col: 2}, + To: Position{Index: 5, Line: 0, Col: 5}, + }, + }, Children: []Node{ StringExpression{ Expression: Expression{ @@ -1097,21 +1216,56 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "input", + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "type", Value: "email", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 8, Line: 0, Col: 8}, + To: Position{Index: 12, Line: 0, Col: 12}, + }, + }, }, ConstantAttribute{ Name: "id", Value: "email", + AttributeExpression: Expression{ + Value: "id", + Range: Range{ + From: Position{Index: 21, Line: 0, Col: 21}, + To: Position{Index: 23, Line: 0, Col: 23}, + }, + }, }, ConstantAttribute{ Name: "name", Value: "email", + AttributeExpression: Expression{ + Value: "name", + Range: Range{ + From: Position{Index: 32, Line: 0, Col: 32}, + To: Position{Index: 36, Line: 0, Col: 36}, + }, + }, }, ExpressionAttribute{ Name: "class", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 45, Line: 0, Col: 45}, + To: Position{Index: 50, Line: 0, Col: 50}, + }, + }, Expression: Expression{ Value: `"a", "b", "c", templ.KV("c", false)`, Range: Range{ @@ -1131,10 +1285,78 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "placeholder", Value: "your@email.com", + AttributeExpression: Expression{ + Value: "placeholder", + Range: Range{ + From: Position{Index: 91, Line: 0, Col: 91}, + To: Position{Index: 102, Line: 0, Col: 102}, + }, + }, }, ConstantAttribute{ Name: "autocomplete", Value: "off", + AttributeExpression: Expression{ + Value: "autocomplete", + Range: Range{ + From: Position{Index: 120, Line: 0, Col: 120}, + To: Position{Index: 132, Line: 0, Col: 132}, + }, + }, + }, + }, + }, + }, + { + name: "element: with multi-line attributes", + input: ``, + expected: Element{ + Name: "input", + IndentAttrs: true, + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, + }, + }, + Attributes: []Attribute{ + ConstantAttribute{ + Name: "type", + Value: "email", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 8, Line: 1, Col: 1}, + To: Position{Index: 12, Line: 1, Col: 5}, + }, + }, + }, + ConstantAttribute{ + Name: "id", + Value: "email", + AttributeExpression: Expression{ + Value: "id", + Range: Range{ + From: Position{Index: 23, Line: 2, Col: 1}, + To: Position{Index: 25, Line: 2, Col: 3}, + }, + }, + }, + ConstantAttribute{ + Name: "name", + Value: "email", + AttributeExpression: Expression{ + Value: "name", + Range: Range{ + From: Position{Index: 36, Line: 3, Col: 1}, + To: Position{Index: 40, Line: 3, Col: 5}, + }, + }, }, }, }, diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index a316c5a88..60b611139 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -38,6 +38,13 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 38, Line: 1, Col: 7}, + To: Position{Index: 41, Line: 1, Col: 10}, + }, + }, Children: []Node{ StringExpression{ Expression: Expression{ @@ -87,6 +94,13 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 37, Line: 1, Col: 7}, + To: Position{Index: 40, Line: 1, Col: 10}, + }, + }, Children: []Node{ StringExpression{ Expression: Expression{ diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index 475c9a3c3..bde31bd9e 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -40,6 +40,13 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 14, Line: 1, Col: 2}, + To: Position{Index: 18, Line: 1, Col: 6}, + }, + }, Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ @@ -188,6 +195,13 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 14, Line: 1, Col: 2}, + To: Position{Index: 18, Line: 1, Col: 6}, + }, + }, Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ @@ -326,6 +340,13 @@ func TestIfExpression(t *testing.T) { Whitespace{Value: "\t\t\t\t\t\t"}, Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 31, Line: 2, Col: 8}, + To: Position{Index: 34, Line: 2, Col: 11}, + }, + }, Children: []Node{ StringExpression{ Expression: Expression{ diff --git a/parser/v2/raw_test.go b/parser/v2/raw_test.go index ff6de94aa..5b6ee9975 100644 --- a/parser/v2/raw_test.go +++ b/parser/v2/raw_test.go @@ -27,6 +27,13 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 7, Line: 0, Col: 7}, + To: Position{Index: 11, Line: 0, Col: 11}, + }, + }, }, }, Contents: "contents", @@ -41,6 +48,13 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 7, Line: 0, Col: 7}, + To: Position{Index: 11, Line: 0, Col: 11}, + }, + }, }, }, Contents: ignoredContent, @@ -55,6 +69,13 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "vbscript", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 8, Line: 0, Col: 8}, + To: Position{Index: 12, Line: 0, Col: 12}, + }, + }, }, }, Contents: "dim x = 1", diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index 8171efa44..4ba75e5bb 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -80,6 +80,13 @@ default: Whitespace{Value: "\t"}, Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 31, Line: 2, Col: 3}, + To: Position{Index: 35, Line: 2, Col: 7}, + }, + }, Children: []Node{ Whitespace{Value: "\n\t "}, StringExpression{ @@ -153,6 +160,13 @@ default: Children: []Node{ Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 38, Line: 2, Col: 2}, + To: Position{Index: 42, Line: 2, Col: 6}, + }, + }, Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index a2fbe3cd3..36f49a640 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -150,6 +150,13 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 28, Line: 1, Col: 2}, + To: Position{Index: 32, Line: 1, Col: 6}, + }, + }, Children: []Node{ StringExpression{ Expression: Expression{ @@ -203,6 +210,13 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 28, Line: 1, Col: 2}, + To: Position{Index: 31, Line: 1, Col: 5}, + }, + }, Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ @@ -225,6 +239,13 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 56, Line: 3, Col: 4}, + To: Position{Index: 60, Line: 3, Col: 8}, + }, + }, Children: []Node{ Whitespace{Value: "\n\t"}, StringExpression{ @@ -303,6 +324,13 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 43, Line: 2, Col: 4}, + To: Position{Index: 47, Line: 2, Col: 8}, + }, + }, Children: []Node{ Whitespace{"\n\t\t\t"}, StringExpression{ @@ -361,17 +389,71 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t"}, Element{ Name: "input", + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 28, Line: 1, Col: 2}, + To: Position{Index: 33, Line: 1, Col: 7}, + }, + }, Attributes: []Attribute{ - ConstantAttribute{Name: "type", Value: "text"}, - ConstantAttribute{Name: "value", Value: "a"}, + ConstantAttribute{ + Name: "type", + Value: "text", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 34, Line: 1, Col: 8}, + To: Position{Index: 38, Line: 1, Col: 12}, + }, + }, + }, + ConstantAttribute{ + Name: "value", + Value: "a", + AttributeExpression: Expression{ + Value: "value", + Range: Range{ + From: Position{Index: 46, Line: 1, Col: 20}, + To: Position{Index: 51, Line: 1, Col: 25}, + }, + }, + }, }, TrailingSpace: SpaceVertical, }, Element{ Name: "input", + ElementExpression: Expression{ + Value: "input", + Range: Range{ + From: Position{Index: 61, Line: 2, Col: 2}, + To: Position{Index: 66, Line: 2, Col: 7}, + }, + }, Attributes: []Attribute{ - ConstantAttribute{Name: "type", Value: "text"}, - ConstantAttribute{Name: "value", Value: "b"}, + ConstantAttribute{ + Name: "type", + Value: "text", + AttributeExpression: Expression{ + Value: "type", + Range: Range{ + From: Position{Index: 67, Line: 2, Col: 8}, + To: Position{Index: 71, Line: 2, Col: 12}, + }, + }, + }, + ConstantAttribute{ + Name: "value", + Value: "b", + AttributeExpression: Expression{ + Value: "value", + Range: Range{ + From: Position{Index: 79, Line: 2, Col: 20}, + To: Position{Index: 84, Line: 2, Col: 25}, + }, + }, + }, }, TrailingSpace: SpaceVertical, }, @@ -444,10 +526,24 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 24, Line: 1, Col: 12}, + To: Position{Index: 25, Line: 1, Col: 13}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "/", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 16, Line: 1, Col: 4}, + To: Position{Index: 20, Line: 1, Col: 8}, + }, + }, }, }, Children: []Node{ @@ -590,6 +686,13 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", + ElementExpression: Expression{ + Value: "span", + Range: Range{ + From: Position{Index: 60, Line: 1, Col: 20}, + To: Position{Index: 64, Line: 1, Col: 24}, + }, + }, Attributes: []Attribute{SpreadAttributes{ Expression{ Value: "children", diff --git a/parser/v2/templelementparser_test.go b/parser/v2/templelementparser_test.go index 5499cedb5..3ac5a9bfb 100644 --- a/parser/v2/templelementparser_test.go +++ b/parser/v2/templelementparser_test.go @@ -134,12 +134,27 @@ func TestTemplElementExpressionParser(t *testing.T) { }, Children: []Node{ Whitespace{Value: "\n\t\t\t"}, - Element{Name: "a", Attributes: []Attribute{ - ConstantAttribute{ - Name: "href", - Value: "someurl", + Element{Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 20, Line: 1, Col: 4}, + To: Position{Index: 21, Line: 1, Col: 5}, + }, + }, + Attributes: []Attribute{ + ConstantAttribute{ + Name: "href", + Value: "someurl", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 22, Line: 1, Col: 6}, + To: Position{Index: 26, Line: 1, Col: 10}, + }, + }, + }, }, - }, TrailingSpace: SpaceVertical, }, }, From bc5092f152ce95b57cc6bd5d3c903e112e320475 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Fri, 23 Feb 2024 20:22:14 -0600 Subject: [PATCH 04/21] fix remaining parser unit tests --- parser/v2/elementparser_test.go | 311 +++++++++++++++++++++-- parser/v2/forexpressionparser_test.go | 8 +- parser/v2/ifexpressionparser_test.go | 12 +- parser/v2/switchexpressionparser_test.go | 8 +- parser/v2/templateparser_test.go | 24 +- 5 files changed, 311 insertions(+), 52 deletions(-) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 773cd6132..8c3c96e31 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -23,6 +23,13 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, }, }, { @@ -31,6 +38,13 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "turbo-frame", + ElementExpression: Expression{ + Value: "turbo-frame", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, + }, + }, }, }, { @@ -39,6 +53,13 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "_", @@ -60,6 +81,13 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "@click", @@ -92,6 +120,13 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "id", @@ -452,6 +487,13 @@ if test { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, + }, + }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "data", @@ -584,10 +626,24 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, }, }, }, @@ -597,9 +653,23 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ BoolExpressionAttribute{ Name: "noshade", + AttributeExpression: Expression{ + Value: "noshade", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 11, Line: 0, Col: 11}, + }, + }, Expression: Expression{ Value: `true`, Range: Range{ @@ -624,9 +694,23 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, Attributes: []Attribute{ ExpressionAttribute{ Name: "href", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, Expression: Expression{ Value: `"test"`, Range: Range{ @@ -651,14 +735,35 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, }, ConstantAttribute{ Name: "style", Value: "text-underline: auto", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 15, Line: 0, Col: 15}, + To: Position{Index: 20, Line: 0, Col: 20}, + }, + }, }, }, }, @@ -668,6 +773,13 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, Attributes: []Attribute{ SpreadAttributes{ Expression: Expression{ @@ -711,12 +823,33 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "optionA", + AttributeExpression: Expression{ + Value: "optionA", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 11, Line: 0, Col: 11}, + }, + }, }, BoolExpressionAttribute{ Name: "optionB", + AttributeExpression: Expression{ + Value: "optionB", + Range: Range{ + From: Position{Index: 12, Line: 0, Col: 12}, + To: Position{Index: 19, Line: 0, Col: 19}, + }, + }, Expression: Expression{ Value: `true`, Range: Range{ @@ -736,6 +869,13 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "optionC", Value: "other", + AttributeExpression: Expression{ + Value: "optionC", + Range: Range{ + From: Position{Index: 30, Line: 0, Col: 30}, + To: Position{Index: 37, Line: 0, Col: 37}, + }, + }, }, }, }, @@ -745,13 +885,34 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", + ElementExpression: Expression{ + Value: "a", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", + AttributeExpression: Expression{ + Value: "href", + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, + }, + }, }, ExpressionAttribute{ Name: "title", + AttributeExpression: Expression{ + Value: "title", + Range: Range{ + From: Position{Index: 15, Line: 0, Col: 15}, + To: Position{Index: 20, Line: 0, Col: 20}, + }, + }, Expression: Expression{ Value: `localisation.Get("a_title")`, Range: Range{ @@ -771,6 +932,13 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "text-underline: auto", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 53, Line: 0, Col: 53}, + To: Position{Index: 58, Line: 0, Col: 58}, + }, + }, }, }, }, @@ -787,10 +955,24 @@ func TestElementParser(t *testing.T) { `, expected: Element{ Name: "div", + ElementExpression: Expression{ + Value: "div", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "width: 100;", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 10, Line: 0, Col: 10}, + }, + }, }, ConditionalAttribute{ Expression: Expression{ @@ -812,6 +994,13 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 47, Line: 2, Col: 3}, + To: Position{Index: 52, Line: 2, Col: 8}, + }, + }, }, }, }, @@ -830,6 +1019,13 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, }, }, { @@ -837,10 +1033,24 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, + }, + }, }, }, }, @@ -854,10 +1064,24 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, + }, + }, }, ConditionalAttribute{ Expression: Expression{ @@ -879,6 +1103,13 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 44, Line: 2, Col: 4}, + To: Position{Index: 49, Line: 2, Col: 9}, + }, + }, }, }, }, @@ -897,10 +1128,24 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", + ElementExpression: Expression{ + Value: "hr", + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, + }, + }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", + AttributeExpression: Expression{ + Value: "style", + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, + }, + }, }, ConditionalAttribute{ Expression: Expression{ @@ -922,12 +1167,26 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 44, Line: 2, Col: 4}, + To: Position{Index: 49, Line: 2, Col: 9}, + }, + }, }, }, Else: []Attribute{ ConstantAttribute{ Name: "class", Value: "itIsNotTrue", + AttributeExpression: Expression{ + Value: "class", + Range: Range{ + From: Position{Index: 77, Line: 4, Col: 4}, + To: Position{Index: 82, Line: 4, Col: 9}, + }, + }, }, }, }, @@ -947,8 +1206,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "p", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Attributes: []Attribute{ @@ -1008,8 +1267,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, }, @@ -1022,8 +1281,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Children: []Node{ @@ -1041,8 +1300,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Children: []Node{ @@ -1067,8 +1326,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Children: []Node{ @@ -1077,8 +1336,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "b", Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 6, Line: 0, Col: 6}, + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -1093,8 +1352,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Children: []Node{ @@ -1104,8 +1363,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "b", Range: Range{ - From: Position{Index: 6, Line: 0, Col: 6}, - To: Position{Index: 7, Line: 0, Col: 7}, + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, }, }, Children: []Node{ @@ -1124,8 +1383,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 3, Line: 0, Col: 3}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, Children: []Node{ @@ -1134,8 +1393,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "b", Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 6, Line: 0, Col: 6}, + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -1144,8 +1403,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "c", Range: Range{ - From: Position{Index: 12, Line: 0, Col: 12}, - To: Position{Index: 13, Line: 0, Col: 13}, + From: Position{Index: 11, Line: 0, Col: 11}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, Children: []Node{ @@ -1172,8 +1431,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 5, Line: 0, Col: 5}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, }, }, @@ -1186,8 +1445,8 @@ func TestElementParser(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 2, Line: 0, Col: 2}, - To: Position{Index: 5, Line: 0, Col: 5}, + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, }, Children: []Node{ diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index 60b611139..e27969d97 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -41,8 +41,8 @@ func TestForExpressionParser(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 38, Line: 1, Col: 7}, - To: Position{Index: 41, Line: 1, Col: 10}, + From: Position{Index: 37, Line: 1, Col: 6}, + To: Position{Index: 40, Line: 1, Col: 9}, }, }, Children: []Node{ @@ -97,8 +97,8 @@ func TestForExpressionParser(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 37, Line: 1, Col: 7}, - To: Position{Index: 40, Line: 1, Col: 10}, + From: Position{Index: 36, Line: 1, Col: 6}, + To: Position{Index: 39, Line: 1, Col: 9}, }, }, Children: []Node{ diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index bde31bd9e..59272d7f5 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -43,8 +43,8 @@ func TestIfExpression(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 14, Line: 1, Col: 2}, - To: Position{Index: 18, Line: 1, Col: 6}, + From: Position{Index: 13, Line: 1, Col: 1}, + To: Position{Index: 17, Line: 1, Col: 5}, }, }, Children: []Node{ @@ -198,8 +198,8 @@ func TestIfExpression(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 14, Line: 1, Col: 2}, - To: Position{Index: 18, Line: 1, Col: 6}, + From: Position{Index: 13, Line: 1, Col: 1}, + To: Position{Index: 17, Line: 1, Col: 5}, }, }, Children: []Node{ @@ -343,8 +343,8 @@ func TestIfExpression(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 31, Line: 2, Col: 8}, - To: Position{Index: 34, Line: 2, Col: 11}, + From: Position{Index: 30, Line: 2, Col: 7}, + To: Position{Index: 33, Line: 2, Col: 10}, }, }, Children: []Node{ diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index 4ba75e5bb..fadb84cc8 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -83,8 +83,8 @@ default: ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 31, Line: 2, Col: 3}, - To: Position{Index: 35, Line: 2, Col: 7}, + From: Position{Index: 30, Line: 2, Col: 2}, + To: Position{Index: 34, Line: 2, Col: 6}, }, }, Children: []Node{ @@ -163,8 +163,8 @@ default: ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 38, Line: 2, Col: 2}, - To: Position{Index: 42, Line: 2, Col: 6}, + From: Position{Index: 37, Line: 2, Col: 1}, + To: Position{Index: 41, Line: 2, Col: 5}, }, }, Children: []Node{ diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index 36f49a640..e31325e4c 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -153,8 +153,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 28, Line: 1, Col: 2}, - To: Position{Index: 32, Line: 1, Col: 6}, + From: Position{Index: 27, Line: 1, Col: 1}, + To: Position{Index: 31, Line: 1, Col: 5}, }, }, Children: []Node{ @@ -213,8 +213,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "div", Range: Range{ - From: Position{Index: 28, Line: 1, Col: 2}, - To: Position{Index: 31, Line: 1, Col: 5}, + From: Position{Index: 27, Line: 1, Col: 1}, + To: Position{Index: 30, Line: 1, Col: 4}, }, }, Children: []Node{ @@ -242,8 +242,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 56, Line: 3, Col: 4}, - To: Position{Index: 60, Line: 3, Col: 8}, + From: Position{Index: 55, Line: 3, Col: 3}, + To: Position{Index: 59, Line: 3, Col: 7}, }, }, Children: []Node{ @@ -327,8 +327,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 43, Line: 2, Col: 4}, - To: Position{Index: 47, Line: 2, Col: 8}, + From: Position{Index: 42, Line: 2, Col: 3}, + To: Position{Index: 46, Line: 2, Col: 7}, }, }, Children: []Node{ @@ -529,8 +529,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "a", Range: Range{ - From: Position{Index: 24, Line: 1, Col: 12}, - To: Position{Index: 25, Line: 1, Col: 13}, + From: Position{Index: 14, Line: 1, Col: 2}, + To: Position{Index: 15, Line: 1, Col: 3}, }, }, Attributes: []Attribute{ @@ -689,8 +689,8 @@ func TestTemplateParser(t *testing.T) { ElementExpression: Expression{ Value: "span", Range: Range{ - From: Position{Index: 60, Line: 1, Col: 20}, - To: Position{Index: 64, Line: 1, Col: 24}, + From: Position{Index: 43, Line: 1, Col: 3}, + To: Position{Index: 47, Line: 1, Col: 7}, }, }, Attributes: []Attribute{SpreadAttributes{ From 7891bdaaeb3eaece36616671ee5f2547108f4221 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Fri, 23 Feb 2024 20:31:46 -0600 Subject: [PATCH 05/21] chore: build version --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index 149e2ffcc..f9af416a8 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.574 \ No newline at end of file +0.2.575 \ No newline at end of file From da94fcfa9ce6af8af8277ed0402446db833df2aa Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Mon, 26 Feb 2024 08:31:26 -0600 Subject: [PATCH 06/21] chore: remove HTMLExpression interface --- .version | 2 +- parser/v2/types.go | 31 ------------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/.version b/.version index c9c86473b..f803aec03 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.590 +0.2.592 \ No newline at end of file diff --git a/parser/v2/types.go b/parser/v2/types.go index 06385c696..26e52b6aa 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -405,17 +405,6 @@ type WhitespaceTrailer interface { Trailing() TrailingSpace } -type HTMLExpression interface { - HTMLExpression() Expression -} - -var ( - _ HTMLExpression = Element{} - _ HTMLExpression = BoolConstantAttribute{} - _ HTMLExpression = BoolExpressionAttribute{} - _ HTMLExpression = ConstantAttribute{} -) - var ( _ WhitespaceTrailer = Element{} _ WhitespaceTrailer = Text{} @@ -454,10 +443,6 @@ func (e Element) Trailing() TrailingSpace { return e.TrailingSpace } -func (e Element) HTMLExpression() Expression { - return e.ElementExpression -} - var voidElements = map[string]struct{}{ "area": {}, "base": {}, "br": {}, "col": {}, "command": {}, "embed": {}, "hr": {}, "img": {}, "input": {}, "keygen": {}, "link": {}, "meta": {}, "param": {}, "source": {}, "track": {}, "wbr": {}, } @@ -719,10 +704,6 @@ func (bca BoolConstantAttribute) Write(w io.Writer, indent int) error { return writeIndent(w, indent, bca.String()) } -func (bca BoolConstantAttribute) HTMLExpression() Expression { - return bca.AttributeExpression -} - // href="" type ConstantAttribute struct { Name string @@ -743,10 +724,6 @@ func (ca ConstantAttribute) Write(w io.Writer, indent int) error { return writeIndent(w, indent, ca.String()) } -func (ca ConstantAttribute) HTMLExpression() Expression { - return ca.AttributeExpression -} - // noshade={ templ.Bool(...) } type BoolExpressionAttribute struct { Name string @@ -762,10 +739,6 @@ func (bea BoolExpressionAttribute) Write(w io.Writer, indent int) error { return writeIndent(w, indent, bea.String()) } -func (bea BoolExpressionAttribute) HTMLExpression() Expression { - return bea.AttributeExpression -} - // href={ ... } type ExpressionAttribute struct { Name string @@ -825,10 +798,6 @@ func (ea ExpressionAttribute) Write(w io.Writer, indent int) (err error) { return writeIndent(w, indent, "}") } -func (ea ExpressionAttribute) HTMLExpression() Expression { - return ea.AttributeExpression -} - //
type SpreadAttributes struct { Expression Expression From a04c72551565133e5d754c921a8f6c1b3735beb4 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Wed, 28 Feb 2024 19:55:51 -0600 Subject: [PATCH 07/21] replace Expression with Range in all HTML types --- parser/v2/elementparser.go | 22 +- parser/v2/elementparser_test.go | 812 ++++++++--------------- parser/v2/forexpressionparser_test.go | 18 +- parser/v2/ifexpressionparser_test.go | 30 +- parser/v2/raw_test.go | 27 +- parser/v2/switchexpressionparser_test.go | 18 +- parser/v2/templateparser_test.go | 117 ++-- parser/v2/templelementparser_test.go | 18 +- parser/v2/types.go | 54 +- 9 files changed, 396 insertions(+), 720 deletions(-) diff --git a/parser/v2/elementparser.go b/parser/v2/elementparser.go index 51893d09e..16c29ee00 100644 --- a/parser/v2/elementparser.go +++ b/parser/v2/elementparser.go @@ -13,10 +13,10 @@ import ( // Element open tag. type elementOpenTag struct { - Name string - Attributes []Attribute - IndentAttrs bool - ElementExpression Expression + Name string + Attributes []Attribute + IndentAttrs bool + Range Range } var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, ok bool, err error) { @@ -33,7 +33,7 @@ var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, o pi.Seek(start) return } - e.ElementExpression = NewExpression(e.Name, pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) + e.Range = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) @@ -121,7 +121,7 @@ var ( pi.Seek(start) return } - attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // =" result, ok, err := parse.Or(parse.String(`="`), parse.String(`='`)).Parse(pi) @@ -174,7 +174,7 @@ var boolConstantAttributeParser = parse.Func(func(pi *parse.Input) (attr BoolCon pi.Seek(start) return } - attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // We have a name, but if we have an equals sign, it's not a constant boolean attribute. next, ok := pi.Peek(1) @@ -212,7 +212,7 @@ var boolExpressionAttributeParser = parse.Func(func(pi *parse.Input) (r BoolExpr pi.Seek(start) return } - r.AttributeExpression = NewExpression(r.Name, pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) + r.Range = NewRange(pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) // Check whether this is a boolean expression attribute. if _, ok, err = boolExpressionStart.Parse(pi); err != nil || !ok { @@ -248,7 +248,7 @@ var expressionAttributeParser = parse.Func(func(pi *parse.Input) (attr Expressio pi.Seek(start) return } - attr.AttributeExpression = NewExpression(attr.Name, pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // ={ if _, ok, err = parse.Or(parse.String("={ "), parse.String("={")).Parse(pi); err != nil || !ok { @@ -395,7 +395,7 @@ func (elementOpenCloseParser) Parse(pi *parse.Input) (r Element, ok bool, err er r.Name = ot.Name r.Attributes = ot.Attributes r.IndentAttrs = ot.IndentAttrs - r.ElementExpression = ot.ElementExpression + r.Range = ot.Range // Once we've got an open tag, the rest must be present. l := pi.Position().Line @@ -453,7 +453,7 @@ var selfClosingElement = parse.Func(func(pi *parse.Input) (e Element, ok bool, e pi.Seek(start) return } - e.ElementExpression = NewExpression(e.Name, pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) + e.Range = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 8c3c96e31..9492d3c36 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -23,12 +23,9 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, }, @@ -38,12 +35,9 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "turbo-frame", - ElementExpression: Expression{ - Value: "turbo-frame", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, }, @@ -53,23 +47,17 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "_", Value: "show = true", - AttributeExpression: Expression{ - Value: "_", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, }, }, }, @@ -81,34 +69,25 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "@click", Value: "show = true", - AttributeExpression: Expression{ - Value: "@click", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 11, Line: 0, Col: 11}, - }, + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 11, Line: 0, Col: 11}, }, }, ConstantAttribute{ Name: ":class", Value: "{'foo': true}", - AttributeExpression: Expression{ - Value: ":class", - Range: Range{ - From: Position{Index: 26, Line: 0, Col: 26}, - To: Position{Index: 32, Line: 0, Col: 32}, - }, + Range: Range{ + From: Position{Index: 26, Line: 0, Col: 26}, + To: Position{Index: 32, Line: 0, Col: 32}, }, }, }, @@ -120,34 +99,25 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "id", Value: "123", - AttributeExpression: Expression{ - Value: "id", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 7, Line: 0, Col: 7}, - }, + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 7, Line: 0, Col: 7}, }, }, ConstantAttribute{ Name: "style", Value: "padding: 10px", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 14, Line: 0, Col: 14}, - To: Position{Index: 19, Line: 0, Col: 19}, - }, + Range: Range{ + From: Position{Index: 14, Line: 0, Col: 14}, + To: Position{Index: 19, Line: 0, Col: 19}, }, }, }, @@ -181,12 +151,9 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 23, Line: 2, Col: 3}, - To: Position{Index: 28, Line: 2, Col: 8}, - }, + Range: Range{ + From: Position{Index: 23, Line: 2, Col: 3}, + To: Position{Index: 28, Line: 2, Col: 8}, }, }, }, @@ -222,32 +189,23 @@ if test { ConstantAttribute{ Name: "class", Value: "itIsTrue", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 13, Line: 2, Col: 1}, - To: Position{Index: 18, Line: 2, Col: 6}, - }, + Range: Range{ + From: Position{Index: 13, Line: 2, Col: 1}, + To: Position{Index: 18, Line: 2, Col: 6}, }, }, BoolConstantAttribute{ Name: "noshade", - AttributeExpression: Expression{ - Value: "noshade", - Range: Range{ - From: Position{Index: 31, Line: 3, Col: 1}, - To: Position{Index: 38, Line: 3, Col: 8}, - }, + Range: Range{ + From: Position{Index: 31, Line: 3, Col: 1}, + To: Position{Index: 38, Line: 3, Col: 8}, }, }, ExpressionAttribute{ Name: "name", - AttributeExpression: Expression{ - Value: "name", - Range: Range{ - From: Position{Index: 40, Line: 4, Col: 1}, - To: Position{Index: 44, Line: 4, Col: 5}, - }, + Range: Range{ + From: Position{Index: 40, Line: 4, Col: 1}, + To: Position{Index: 44, Line: 4, Col: 5}, }, Expression: Expression{ Value: `"other"`, @@ -274,12 +232,9 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", - AttributeExpression: Expression{ - Value: "noshade", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 8, Line: 0, Col: 8}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, }, Expression: Expression{ Value: "true", @@ -304,12 +259,9 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", - AttributeExpression: Expression{ - Value: "noshade", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 8, Line: 0, Col: 8}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, }, Expression: Expression{ Value: "true", @@ -334,12 +286,9 @@ if test { parser: StripType[Attribute](attributeParser{}), expected: BoolExpressionAttribute{ Name: "noshade", - AttributeExpression: Expression{ - Value: "noshade", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 8, Line: 0, Col: 8}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, }, Expression: Expression{ Value: "true", @@ -387,12 +336,9 @@ if test { expected: ConstantAttribute{ Name: "href", Value: "test", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -404,12 +350,9 @@ if test { Name: "href", Value: `no double quote in value`, SingleQuote: false, - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -421,12 +364,9 @@ if test { Name: "href", Value: `"test"`, SingleQuote: true, - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -437,12 +377,9 @@ if test { expected: ConstantAttribute{ Name: "data-turbo-permanent", Value: "value", - AttributeExpression: Expression{ - Value: "data-turbo-permanent", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 21, Line: 0, Col: 21}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 21, Line: 0, Col: 21}, }, }, }, @@ -453,12 +390,9 @@ if test { expected: ConstantAttribute{ Name: "data", Value: "", - AttributeExpression: Expression{ - Value: "data", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -472,12 +406,9 @@ if test { expected: ConstantAttribute{ Name: "data-script", Value: "on click\n do something\n end", - AttributeExpression: Expression{ - Value: "data-script", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, }, @@ -487,22 +418,17 @@ if test { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "data", - AttributeExpression: Expression{ - Value: "data", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 9, Line: 0, Col: 9}, - }, + + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 9, Line: 0, Col: 9}, }, }, }, @@ -515,22 +441,16 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", - AttributeExpression: Expression{ - Value: "required", - Range: Range{ - From: Position{Index: 9, Line: 1, Col: 2}, - To: Position{Index: 17, Line: 1, Col: 10}, - }, + Range: Range{ + From: Position{Index: 9, Line: 1, Col: 2}, + To: Position{Index: 17, Line: 1, Col: 10}, }, }, }, @@ -543,22 +463,16 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", - AttributeExpression: Expression{ - Value: "required", - Range: Range{ - From: Position{Index: 10, Line: 1, Col: 2}, - To: Position{Index: 18, Line: 1, Col: 10}, - }, + Range: Range{ + From: Position{Index: 10, Line: 1, Col: 2}, + To: Position{Index: 18, Line: 1, Col: 10}, }, }, }, @@ -571,12 +485,9 @@ if test { expected: ConstantAttribute{ Name: "href", Value: `<">`, - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -587,12 +498,9 @@ if test { expected: ConstantAttribute{ Name: "hx-target-*", Value: `#errors`, - AttributeExpression: Expression{ - Value: `hx-target-*`, - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, }, @@ -626,23 +534,17 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 3, Line: 0, Col: 3}, - To: Position{Index: 7, Line: 0, Col: 7}, - }, + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, }, }, }, @@ -653,22 +555,16 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ BoolExpressionAttribute{ Name: "noshade", - AttributeExpression: Expression{ - Value: "noshade", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 11, Line: 0, Col: 11}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 11, Line: 0, Col: 11}, }, Expression: Expression{ Value: `true`, @@ -694,22 +590,16 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ExpressionAttribute{ Name: "href", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 3, Line: 0, Col: 3}, - To: Position{Index: 7, Line: 0, Col: 7}, - }, + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, }, Expression: Expression{ Value: `"test"`, @@ -735,34 +625,25 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 3, Line: 0, Col: 3}, - To: Position{Index: 7, Line: 0, Col: 7}, - }, + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, }, }, ConstantAttribute{ Name: "style", Value: "text-underline: auto", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 15, Line: 0, Col: 15}, - To: Position{Index: 20, Line: 0, Col: 20}, - }, + Range: Range{ + From: Position{Index: 15, Line: 0, Col: 15}, + To: Position{Index: 20, Line: 0, Col: 20}, }, }, }, @@ -773,12 +654,9 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ SpreadAttributes{ @@ -823,32 +701,23 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "optionA", - AttributeExpression: Expression{ - Value: "optionA", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 11, Line: 0, Col: 11}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 11, Line: 0, Col: 11}, }, }, BoolExpressionAttribute{ Name: "optionB", - AttributeExpression: Expression{ - Value: "optionB", - Range: Range{ - From: Position{Index: 12, Line: 0, Col: 12}, - To: Position{Index: 19, Line: 0, Col: 19}, - }, + Range: Range{ + From: Position{Index: 12, Line: 0, Col: 12}, + To: Position{Index: 19, Line: 0, Col: 19}, }, Expression: Expression{ Value: `true`, @@ -869,12 +738,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "optionC", Value: "other", - AttributeExpression: Expression{ - Value: "optionC", - Range: Range{ - From: Position{Index: 30, Line: 0, Col: 30}, - To: Position{Index: 37, Line: 0, Col: 37}, - }, + Range: Range{ + From: Position{Index: 30, Line: 0, Col: 30}, + To: Position{Index: 37, Line: 0, Col: 37}, }, }, }, @@ -885,33 +751,24 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "test", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 3, Line: 0, Col: 3}, - To: Position{Index: 7, Line: 0, Col: 7}, - }, + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 7, Line: 0, Col: 7}, }, }, ExpressionAttribute{ Name: "title", - AttributeExpression: Expression{ - Value: "title", - Range: Range{ - From: Position{Index: 15, Line: 0, Col: 15}, - To: Position{Index: 20, Line: 0, Col: 20}, - }, + Range: Range{ + From: Position{Index: 15, Line: 0, Col: 15}, + To: Position{Index: 20, Line: 0, Col: 20}, }, Expression: Expression{ Value: `localisation.Get("a_title")`, @@ -932,12 +789,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "text-underline: auto", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 53, Line: 0, Col: 53}, - To: Position{Index: 58, Line: 0, Col: 58}, - }, + Range: Range{ + From: Position{Index: 53, Line: 0, Col: 53}, + To: Position{Index: 58, Line: 0, Col: 58}, }, }, }, @@ -955,23 +809,17 @@ func TestElementParser(t *testing.T) { `, expected: Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "width: 100;", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 10, Line: 0, Col: 10}, - }, + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 10, Line: 0, Col: 10}, }, }, ConditionalAttribute{ @@ -994,12 +842,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 47, Line: 2, Col: 3}, - To: Position{Index: 52, Line: 2, Col: 8}, - }, + Range: Range{ + From: Position{Index: 47, Line: 2, Col: 3}, + To: Position{Index: 52, Line: 2, Col: 8}, }, }, }, @@ -1019,12 +864,9 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, }, }, @@ -1033,23 +875,17 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 9, Line: 0, Col: 9}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, }, }, }, @@ -1064,23 +900,17 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 9, Line: 0, Col: 9}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, }, }, ConditionalAttribute{ @@ -1103,12 +933,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 44, Line: 2, Col: 4}, - To: Position{Index: 49, Line: 2, Col: 9}, - }, + Range: Range{ + From: Position{Index: 44, Line: 2, Col: 4}, + To: Position{Index: 49, Line: 2, Col: 9}, }, }, }, @@ -1128,23 +955,17 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", - ElementExpression: Expression{ - Value: "hr", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 3, Line: 0, Col: 3}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 9, Line: 0, Col: 9}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 9, Line: 0, Col: 9}, }, }, ConditionalAttribute{ @@ -1167,12 +988,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 44, Line: 2, Col: 4}, - To: Position{Index: 49, Line: 2, Col: 9}, - }, + Range: Range{ + From: Position{Index: 44, Line: 2, Col: 4}, + To: Position{Index: 49, Line: 2, Col: 9}, }, }, }, @@ -1180,12 +998,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsNotTrue", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 77, Line: 4, Col: 4}, - To: Position{Index: 82, Line: 4, Col: 9}, - }, + Range: Range{ + From: Position{Index: 77, Line: 4, Col: 4}, + To: Position{Index: 82, Line: 4, Col: 9}, }, }, }, @@ -1203,23 +1018,17 @@ func TestElementParser(t *testing.T) { >Test

`, expected: Element{ Name: "p", - ElementExpression: Expression{ - Value: "p", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "style", Value: "padding: 10px", - AttributeExpression: Expression{ - Value: "style", - Range: Range{ - From: Position{Index: 3, Line: 0, Col: 3}, - To: Position{Index: 8, Line: 0, Col: 8}, - }, + Range: Range{ + From: Position{Index: 3, Line: 0, Col: 3}, + To: Position{Index: 8, Line: 0, Col: 8}, }, }, ConditionalAttribute{ @@ -1242,12 +1051,9 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 43, Line: 2, Col: 4}, - To: Position{Index: 48, Line: 2, Col: 9}, - }, + Range: Range{ + From: Position{Index: 43, Line: 2, Col: 4}, + To: Position{Index: 48, Line: 2, Col: 9}, }, }, }, @@ -1264,12 +1070,9 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, }, }, @@ -1278,12 +1081,9 @@ func TestElementParser(t *testing.T) { input: `The text`, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Text{ @@ -1297,22 +1097,16 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - ElementExpression: Expression{ - Value: "b", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -1323,22 +1117,16 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - ElementExpression: Expression{ - Value: "b", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, }, @@ -1349,24 +1137,19 @@ func TestElementParser(t *testing.T) { input: ` `, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Whitespace{Value: " "}, Element{ Name: "b", - ElementExpression: Expression{ - Value: "b", - Range: Range{ - From: Position{Index: 5, Line: 0, Col: 5}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 5, Line: 0, Col: 5}, + To: Position{Index: 6, Line: 0, Col: 6}, }, + Children: []Node{ Whitespace{Value: " "}, }, @@ -1380,42 +1163,30 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 2, Line: 0, Col: 2}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - ElementExpression: Expression{ - Value: "b", - Range: Range{ - From: Position{Index: 4, Line: 0, Col: 4}, - To: Position{Index: 5, Line: 0, Col: 5}, - }, + Range: Range{ + From: Position{Index: 4, Line: 0, Col: 4}, + To: Position{Index: 5, Line: 0, Col: 5}, }, }, Element{ Name: "c", - ElementExpression: Expression{ - Value: "c", - Range: Range{ - From: Position{Index: 11, Line: 0, Col: 11}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 11, Line: 0, Col: 11}, + To: Position{Index: 12, Line: 0, Col: 12}, }, Children: []Node{ Element{ Name: "d", - ElementExpression: Expression{ - Value: "d", - Range: Range{ - From: Position{Index: 14, Line: 0, Col: 14}, - To: Position{Index: 15, Line: 0, Col: 15}, - }, + Range: Range{ + From: Position{Index: 14, Line: 0, Col: 14}, + To: Position{Index: 15, Line: 0, Col: 15}, }, }, }, @@ -1428,12 +1199,9 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, }, }, @@ -1442,12 +1210,9 @@ func TestElementParser(t *testing.T) { input: `
{ "test" }
`, expected: Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 4, Line: 0, Col: 4}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 4, Line: 0, Col: 4}, }, Children: []Node{ StringExpression{ @@ -1475,55 +1240,40 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "input", - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "type", Value: "email", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 8, Line: 0, Col: 8}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 8, Line: 0, Col: 8}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, ConstantAttribute{ Name: "id", Value: "email", - AttributeExpression: Expression{ - Value: "id", - Range: Range{ - From: Position{Index: 21, Line: 0, Col: 21}, - To: Position{Index: 23, Line: 0, Col: 23}, - }, + Range: Range{ + From: Position{Index: 21, Line: 0, Col: 21}, + To: Position{Index: 23, Line: 0, Col: 23}, }, }, ConstantAttribute{ Name: "name", Value: "email", - AttributeExpression: Expression{ - Value: "name", - Range: Range{ - From: Position{Index: 32, Line: 0, Col: 32}, - To: Position{Index: 36, Line: 0, Col: 36}, - }, + Range: Range{ + From: Position{Index: 32, Line: 0, Col: 32}, + To: Position{Index: 36, Line: 0, Col: 36}, }, }, ExpressionAttribute{ Name: "class", - AttributeExpression: Expression{ - Value: "class", - Range: Range{ - From: Position{Index: 45, Line: 0, Col: 45}, - To: Position{Index: 50, Line: 0, Col: 50}, - }, + Range: Range{ + From: Position{Index: 45, Line: 0, Col: 45}, + To: Position{Index: 50, Line: 0, Col: 50}, }, Expression: Expression{ Value: `"a", "b", "c", templ.KV("c", false)`, @@ -1544,23 +1294,17 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "placeholder", Value: "your@email.com", - AttributeExpression: Expression{ - Value: "placeholder", - Range: Range{ - From: Position{Index: 91, Line: 0, Col: 91}, - To: Position{Index: 102, Line: 0, Col: 102}, - }, + Range: Range{ + From: Position{Index: 91, Line: 0, Col: 91}, + To: Position{Index: 102, Line: 0, Col: 102}, }, }, ConstantAttribute{ Name: "autocomplete", Value: "off", - AttributeExpression: Expression{ - Value: "autocomplete", - Range: Range{ - From: Position{Index: 120, Line: 0, Col: 120}, - To: Position{Index: 132, Line: 0, Col: 132}, - }, + Range: Range{ + From: Position{Index: 120, Line: 0, Col: 120}, + To: Position{Index: 132, Line: 0, Col: 132}, }, }, }, @@ -1576,45 +1320,33 @@ func TestElementParser(t *testing.T) { expected: Element{ Name: "input", IndentAttrs: true, - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 1, Line: 0, Col: 1}, - To: Position{Index: 6, Line: 0, Col: 6}, - }, + Range: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "type", Value: "email", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 8, Line: 1, Col: 1}, - To: Position{Index: 12, Line: 1, Col: 5}, - }, + Range: Range{ + From: Position{Index: 8, Line: 1, Col: 1}, + To: Position{Index: 12, Line: 1, Col: 5}, }, }, ConstantAttribute{ Name: "id", Value: "email", - AttributeExpression: Expression{ - Value: "id", - Range: Range{ - From: Position{Index: 23, Line: 2, Col: 1}, - To: Position{Index: 25, Line: 2, Col: 3}, - }, + Range: Range{ + From: Position{Index: 23, Line: 2, Col: 1}, + To: Position{Index: 25, Line: 2, Col: 3}, }, }, ConstantAttribute{ Name: "name", Value: "email", - AttributeExpression: Expression{ - Value: "name", - Range: Range{ - From: Position{Index: 36, Line: 3, Col: 1}, - To: Position{Index: 40, Line: 3, Col: 5}, - }, + Range: Range{ + From: Position{Index: 36, Line: 3, Col: 1}, + To: Position{Index: 40, Line: 3, Col: 5}, }, }, }, diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index e27969d97..3fa51d734 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -38,12 +38,9 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 37, Line: 1, Col: 6}, - To: Position{Index: 40, Line: 1, Col: 9}, - }, + Range: Range{ + From: Position{Index: 37, Line: 1, Col: 6}, + To: Position{Index: 40, Line: 1, Col: 9}, }, Children: []Node{ StringExpression{ @@ -94,12 +91,9 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 36, Line: 1, Col: 6}, - To: Position{Index: 39, Line: 1, Col: 9}, - }, + Range: Range{ + From: Position{Index: 36, Line: 1, Col: 6}, + To: Position{Index: 39, Line: 1, Col: 9}, }, Children: []Node{ StringExpression{ diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index 59272d7f5..79e878f1e 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -40,13 +40,11 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 13, Line: 1, Col: 1}, - To: Position{Index: 17, Line: 1, Col: 5}, - }, + Range: Range{ + From: Position{Index: 13, Line: 1, Col: 1}, + To: Position{Index: 17, Line: 1, Col: 5}, }, + Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ @@ -195,13 +193,11 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 13, Line: 1, Col: 1}, - To: Position{Index: 17, Line: 1, Col: 5}, - }, + Range: Range{ + From: Position{Index: 13, Line: 1, Col: 1}, + To: Position{Index: 17, Line: 1, Col: 5}, }, + Children: []Node{ Whitespace{Value: "\n "}, StringExpression{ @@ -340,13 +336,11 @@ func TestIfExpression(t *testing.T) { Whitespace{Value: "\t\t\t\t\t\t"}, Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 30, Line: 2, Col: 7}, - To: Position{Index: 33, Line: 2, Col: 10}, - }, + Range: Range{ + From: Position{Index: 30, Line: 2, Col: 7}, + To: Position{Index: 33, Line: 2, Col: 10}, }, + Children: []Node{ StringExpression{ Expression: Expression{ diff --git a/parser/v2/raw_test.go b/parser/v2/raw_test.go index 5b6ee9975..89646f206 100644 --- a/parser/v2/raw_test.go +++ b/parser/v2/raw_test.go @@ -27,12 +27,9 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 7, Line: 0, Col: 7}, - To: Position{Index: 11, Line: 0, Col: 11}, - }, + Range: Range{ + From: Position{Index: 7, Line: 0, Col: 7}, + To: Position{Index: 11, Line: 0, Col: 11}, }, }, }, @@ -48,12 +45,9 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 7, Line: 0, Col: 7}, - To: Position{Index: 11, Line: 0, Col: 11}, - }, + Range: Range{ + From: Position{Index: 7, Line: 0, Col: 7}, + To: Position{Index: 11, Line: 0, Col: 11}, }, }, }, @@ -69,12 +63,9 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "vbscript", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 8, Line: 0, Col: 8}, - To: Position{Index: 12, Line: 0, Col: 12}, - }, + Range: Range{ + From: Position{Index: 8, Line: 0, Col: 8}, + To: Position{Index: 12, Line: 0, Col: 12}, }, }, }, diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index fadb84cc8..d0b6012f2 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -80,12 +80,9 @@ default: Whitespace{Value: "\t"}, Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 30, Line: 2, Col: 2}, - To: Position{Index: 34, Line: 2, Col: 6}, - }, + Range: Range{ + From: Position{Index: 30, Line: 2, Col: 2}, + To: Position{Index: 34, Line: 2, Col: 6}, }, Children: []Node{ Whitespace{Value: "\n\t "}, @@ -160,12 +157,9 @@ default: Children: []Node{ Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 37, Line: 2, Col: 1}, - To: Position{Index: 41, Line: 2, Col: 5}, - }, + Range: Range{ + From: Position{Index: 37, Line: 2, Col: 1}, + To: Position{Index: 41, Line: 2, Col: 5}, }, Children: []Node{ Whitespace{Value: "\n "}, diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index e31325e4c..a2a41e7cc 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -150,12 +150,9 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 27, Line: 1, Col: 1}, - To: Position{Index: 31, Line: 1, Col: 5}, - }, + Range: Range{ + From: Position{Index: 27, Line: 1, Col: 1}, + To: Position{Index: 31, Line: 1, Col: 5}, }, Children: []Node{ StringExpression{ @@ -210,12 +207,9 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "div", - ElementExpression: Expression{ - Value: "div", - Range: Range{ - From: Position{Index: 27, Line: 1, Col: 1}, - To: Position{Index: 30, Line: 1, Col: 4}, - }, + Range: Range{ + From: Position{Index: 27, Line: 1, Col: 1}, + To: Position{Index: 30, Line: 1, Col: 4}, }, Children: []Node{ Whitespace{Value: "\n "}, @@ -239,12 +233,9 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 55, Line: 3, Col: 3}, - To: Position{Index: 59, Line: 3, Col: 7}, - }, + Range: Range{ + From: Position{Index: 55, Line: 3, Col: 3}, + To: Position{Index: 59, Line: 3, Col: 7}, }, Children: []Node{ Whitespace{Value: "\n\t"}, @@ -324,12 +315,9 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 42, Line: 2, Col: 3}, - To: Position{Index: 46, Line: 2, Col: 7}, - }, + Range: Range{ + From: Position{Index: 42, Line: 2, Col: 3}, + To: Position{Index: 46, Line: 2, Col: 7}, }, Children: []Node{ Whitespace{"\n\t\t\t"}, @@ -389,34 +377,25 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t"}, Element{ Name: "input", - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 28, Line: 1, Col: 2}, - To: Position{Index: 33, Line: 1, Col: 7}, - }, + Range: Range{ + From: Position{Index: 28, Line: 1, Col: 2}, + To: Position{Index: 33, Line: 1, Col: 7}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "type", Value: "text", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 34, Line: 1, Col: 8}, - To: Position{Index: 38, Line: 1, Col: 12}, - }, + Range: Range{ + From: Position{Index: 34, Line: 1, Col: 8}, + To: Position{Index: 38, Line: 1, Col: 12}, }, }, ConstantAttribute{ Name: "value", Value: "a", - AttributeExpression: Expression{ - Value: "value", - Range: Range{ - From: Position{Index: 46, Line: 1, Col: 20}, - To: Position{Index: 51, Line: 1, Col: 25}, - }, + Range: Range{ + From: Position{Index: 46, Line: 1, Col: 20}, + To: Position{Index: 51, Line: 1, Col: 25}, }, }, }, @@ -424,34 +403,25 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "input", - ElementExpression: Expression{ - Value: "input", - Range: Range{ - From: Position{Index: 61, Line: 2, Col: 2}, - To: Position{Index: 66, Line: 2, Col: 7}, - }, + Range: Range{ + From: Position{Index: 61, Line: 2, Col: 2}, + To: Position{Index: 66, Line: 2, Col: 7}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "type", Value: "text", - AttributeExpression: Expression{ - Value: "type", - Range: Range{ - From: Position{Index: 67, Line: 2, Col: 8}, - To: Position{Index: 71, Line: 2, Col: 12}, - }, + Range: Range{ + From: Position{Index: 67, Line: 2, Col: 8}, + To: Position{Index: 71, Line: 2, Col: 12}, }, }, ConstantAttribute{ Name: "value", Value: "b", - AttributeExpression: Expression{ - Value: "value", - Range: Range{ - From: Position{Index: 79, Line: 2, Col: 20}, - To: Position{Index: 84, Line: 2, Col: 25}, - }, + Range: Range{ + From: Position{Index: 79, Line: 2, Col: 20}, + To: Position{Index: 84, Line: 2, Col: 25}, }, }, }, @@ -526,23 +496,17 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 14, Line: 1, Col: 2}, - To: Position{Index: 15, Line: 1, Col: 3}, - }, + Range: Range{ + From: Position{Index: 14, Line: 1, Col: 2}, + To: Position{Index: 15, Line: 1, Col: 3}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "/", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 16, Line: 1, Col: 4}, - To: Position{Index: 20, Line: 1, Col: 8}, - }, + Range: Range{ + From: Position{Index: 16, Line: 1, Col: 4}, + To: Position{Index: 20, Line: 1, Col: 8}, }, }, }, @@ -686,12 +650,9 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", - ElementExpression: Expression{ - Value: "span", - Range: Range{ - From: Position{Index: 43, Line: 1, Col: 3}, - To: Position{Index: 47, Line: 1, Col: 7}, - }, + Range: Range{ + From: Position{Index: 43, Line: 1, Col: 3}, + To: Position{Index: 47, Line: 1, Col: 7}, }, Attributes: []Attribute{SpreadAttributes{ Expression{ diff --git a/parser/v2/templelementparser_test.go b/parser/v2/templelementparser_test.go index 3ac5a9bfb..ec88d7b42 100644 --- a/parser/v2/templelementparser_test.go +++ b/parser/v2/templelementparser_test.go @@ -135,23 +135,17 @@ func TestTemplElementExpressionParser(t *testing.T) { Children: []Node{ Whitespace{Value: "\n\t\t\t"}, Element{Name: "a", - ElementExpression: Expression{ - Value: "a", - Range: Range{ - From: Position{Index: 20, Line: 1, Col: 4}, - To: Position{Index: 21, Line: 1, Col: 5}, - }, + Range: Range{ + From: Position{Index: 20, Line: 1, Col: 4}, + To: Position{Index: 21, Line: 1, Col: 5}, }, Attributes: []Attribute{ ConstantAttribute{ Name: "href", Value: "someurl", - AttributeExpression: Expression{ - Value: "href", - Range: Range{ - From: Position{Index: 22, Line: 1, Col: 6}, - To: Position{Index: 26, Line: 1, Col: 10}, - }, + Range: Range{ + From: Position{Index: 22, Line: 1, Col: 6}, + To: Position{Index: 26, Line: 1, Col: 10}, }, }, }, diff --git a/parser/v2/types.go b/parser/v2/types.go index 26e52b6aa..cf5cec2be 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -86,6 +86,22 @@ func NewExpression(value string, from, to parse.Position) Expression { } } +// NewRange creates a Range expression. +func NewRange(from, to parse.Position) Range { + return Range{ + From: Position{ + Index: int64(from.Index), + Line: uint32(from.Line), + Col: uint32(from.Col), + }, + To: Position{ + Index: int64(to.Index), + Line: uint32(to.Line), + Col: uint32(to.Col), + }, + } +} + // Range of text within a file. type Range struct { From Position @@ -430,13 +446,13 @@ func (t Text) Write(w io.Writer, indent int) error { // or
...
type Element struct { - Name string - Attributes []Attribute - IndentAttrs bool - Children []Node - IndentChildren bool - TrailingSpace TrailingSpace - ElementExpression Expression + Name string + Attributes []Attribute + IndentAttrs bool + Children []Node + IndentChildren bool + TrailingSpace TrailingSpace + Range Range } func (e Element) Trailing() TrailingSpace { @@ -692,8 +708,8 @@ type Attribute interface { //
type BoolConstantAttribute struct { - Name string - AttributeExpression Expression + Name string + Range Range } func (bca BoolConstantAttribute) String() string { @@ -706,10 +722,10 @@ func (bca BoolConstantAttribute) Write(w io.Writer, indent int) error { // href="" type ConstantAttribute struct { - Name string - Value string - SingleQuote bool - AttributeExpression Expression + Name string + Value string + SingleQuote bool + Range Range } func (ca ConstantAttribute) String() string { @@ -726,9 +742,9 @@ func (ca ConstantAttribute) Write(w io.Writer, indent int) error { // noshade={ templ.Bool(...) } type BoolExpressionAttribute struct { - Name string - Expression Expression - AttributeExpression Expression + Name string + Expression Expression + Range Range } func (bea BoolExpressionAttribute) String() string { @@ -741,9 +757,9 @@ func (bea BoolExpressionAttribute) Write(w io.Writer, indent int) error { // href={ ... } type ExpressionAttribute struct { - Name string - Expression Expression - AttributeExpression Expression + Name string + Expression Expression + Range Range } func (ea ExpressionAttribute) String() string { From e153d93add2df2ae3108bb483113f582e6e621c5 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Wed, 28 Feb 2024 19:57:08 -0600 Subject: [PATCH 08/21] chore: get-version --- .version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.version b/.version index f803aec03..ead13c31d 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.592 \ No newline at end of file +0.2.593 \ No newline at end of file From 96566418b7c791eff16a4fb6dd8f75cacb762516 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Tue, 5 Mar 2024 20:21:44 -0600 Subject: [PATCH 09/21] chore: rename field as NameRange --- .version | 2 +- parser/v2/elementparser.go | 16 +- parser/v2/elementparser_test.go | 184 ++++++++++++----------- parser/v2/forexpressionparser_test.go | 4 +- parser/v2/ifexpressionparser_test.go | 6 +- parser/v2/raw_test.go | 6 +- parser/v2/switchexpressionparser_test.go | 4 +- parser/v2/templateparser_test.go | 30 ++-- parser/v2/templelementparser_test.go | 8 +- parser/v2/types.go | 12 +- 10 files changed, 142 insertions(+), 130 deletions(-) diff --git a/.version b/.version index ffcb20e7c..f94611877 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.608 +0.2.610 \ No newline at end of file diff --git a/parser/v2/elementparser.go b/parser/v2/elementparser.go index 16c29ee00..18b12b6f9 100644 --- a/parser/v2/elementparser.go +++ b/parser/v2/elementparser.go @@ -16,7 +16,7 @@ type elementOpenTag struct { Name string Attributes []Attribute IndentAttrs bool - Range Range + NameRange Range } var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, ok bool, err error) { @@ -33,7 +33,7 @@ var elementOpenTagParser = parse.Func(func(pi *parse.Input) (e elementOpenTag, o pi.Seek(start) return } - e.Range = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) + e.NameRange = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) @@ -121,7 +121,7 @@ var ( pi.Seek(start) return } - attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.NameRange = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // =" result, ok, err := parse.Or(parse.String(`="`), parse.String(`='`)).Parse(pi) @@ -174,7 +174,7 @@ var boolConstantAttributeParser = parse.Func(func(pi *parse.Input) (attr BoolCon pi.Seek(start) return } - attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.NameRange = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // We have a name, but if we have an equals sign, it's not a constant boolean attribute. next, ok := pi.Peek(1) @@ -212,7 +212,7 @@ var boolExpressionAttributeParser = parse.Func(func(pi *parse.Input) (r BoolExpr pi.Seek(start) return } - r.Range = NewRange(pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) + r.NameRange = NewRange(pi.PositionAt(pi.Index()-len(r.Name)), pi.Position()) // Check whether this is a boolean expression attribute. if _, ok, err = boolExpressionStart.Parse(pi); err != nil || !ok { @@ -248,7 +248,7 @@ var expressionAttributeParser = parse.Func(func(pi *parse.Input) (attr Expressio pi.Seek(start) return } - attr.Range = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) + attr.NameRange = NewRange(pi.PositionAt(pi.Index()-len(attr.Name)), pi.Position()) // ={ if _, ok, err = parse.Or(parse.String("={ "), parse.String("={")).Parse(pi); err != nil || !ok { @@ -395,7 +395,7 @@ func (elementOpenCloseParser) Parse(pi *parse.Input) (r Element, ok bool, err er r.Name = ot.Name r.Attributes = ot.Attributes r.IndentAttrs = ot.IndentAttrs - r.Range = ot.Range + r.NameRange = ot.NameRange // Once we've got an open tag, the rest must be present. l := pi.Position().Line @@ -453,7 +453,7 @@ var selfClosingElement = parse.Func(func(pi *parse.Input) (e Element, ok bool, e pi.Seek(start) return } - e.Range = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) + e.NameRange = NewRange(pi.PositionAt(pi.Index()-len(e.Name)), pi.Position()) if e.Attributes, ok, err = (attributesParser{}).Parse(pi); err != nil || !ok { pi.Seek(start) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 184fbc7e6..6bb695aa3 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -23,7 +23,7 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -35,7 +35,7 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "turbo-frame", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 12, Line: 0, Col: 12}, }, @@ -47,7 +47,7 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -55,7 +55,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "_", Value: "show = true", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 6, Line: 0, Col: 6}, }, @@ -69,7 +69,7 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -77,7 +77,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "@click", Value: "show = true", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 11, Line: 0, Col: 11}, }, @@ -85,7 +85,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: ":class", Value: "{'foo': true}", - Range: Range{ + NameRange: Range{ From: Position{Index: 26, Line: 0, Col: 26}, To: Position{Index: 32, Line: 0, Col: 32}, }, @@ -99,7 +99,7 @@ func TestAttributeParser(t *testing.T) { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -107,7 +107,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "id", Value: "123", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 7, Line: 0, Col: 7}, }, @@ -115,7 +115,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "padding: 10px", - Range: Range{ + NameRange: Range{ From: Position{Index: 14, Line: 0, Col: 14}, To: Position{Index: 19, Line: 0, Col: 19}, }, @@ -151,7 +151,7 @@ func TestAttributeParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", - Range: Range{ + NameRange: Range{ From: Position{Index: 23, Line: 2, Col: 3}, To: Position{Index: 28, Line: 2, Col: 8}, }, @@ -189,21 +189,21 @@ if test { ConstantAttribute{ Name: "class", Value: "itIsTrue", - Range: Range{ + NameRange: Range{ From: Position{Index: 13, Line: 2, Col: 1}, To: Position{Index: 18, Line: 2, Col: 6}, }, }, BoolConstantAttribute{ Name: "noshade", - Range: Range{ + NameRange: Range{ From: Position{Index: 31, Line: 3, Col: 1}, To: Position{Index: 38, Line: 3, Col: 8}, }, }, ExpressionAttribute{ Name: "name", - Range: Range{ + NameRange: Range{ From: Position{Index: 40, Line: 4, Col: 1}, To: Position{Index: 44, Line: 4, Col: 5}, }, @@ -232,7 +232,7 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 8, Line: 0, Col: 8}, }, @@ -259,7 +259,7 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 8, Line: 0, Col: 8}, }, @@ -286,7 +286,7 @@ if test { parser: StripType[Attribute](attributeParser{}), expected: BoolExpressionAttribute{ Name: "noshade", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 8, Line: 0, Col: 8}, }, @@ -313,6 +313,10 @@ if test { parser: StripType(boolExpressionAttributeParser), expected: BoolExpressionAttribute{ Name: "noshade", + NameRange: Range{ + From: Position{Index: 1, Line: 0, Col: 1}, + To: Position{Index: 8, Line: 0, Col: 8}, + }, Expression: Expression{ Value: "true", Range: Range{ @@ -359,7 +363,7 @@ if test { expected: ConstantAttribute{ Name: "href", Value: "test", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -373,7 +377,7 @@ if test { Name: "href", Value: `no double quote in value`, SingleQuote: false, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -387,7 +391,7 @@ if test { Name: "href", Value: `"test"`, SingleQuote: true, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -400,7 +404,7 @@ if test { expected: ConstantAttribute{ Name: "data-turbo-permanent", Value: "value", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 21, Line: 0, Col: 21}, }, @@ -413,7 +417,7 @@ if test { expected: ConstantAttribute{ Name: "data", Value: "", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -429,7 +433,7 @@ if test { expected: ConstantAttribute{ Name: "data-script", Value: "on click\n do something\n end", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 12, Line: 0, Col: 12}, }, @@ -441,7 +445,7 @@ if test { parser: StripType(elementOpenTagParser), expected: elementOpenTag{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -449,7 +453,7 @@ if test { BoolConstantAttribute{ Name: "data", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 9, Line: 0, Col: 9}, }, @@ -464,14 +468,14 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", - Range: Range{ + NameRange: Range{ From: Position{Index: 9, Line: 1, Col: 2}, To: Position{Index: 17, Line: 1, Col: 10}, }, @@ -486,14 +490,14 @@ if test { expected: Element{ Name: "input", IndentAttrs: true, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 6, Line: 0, Col: 6}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "required", - Range: Range{ + NameRange: Range{ From: Position{Index: 10, Line: 1, Col: 2}, To: Position{Index: 18, Line: 1, Col: 10}, }, @@ -508,7 +512,7 @@ if test { expected: ConstantAttribute{ Name: "href", Value: `<">`, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -521,7 +525,7 @@ if test { expected: ConstantAttribute{ Name: "hx-target-*", Value: `#errors`, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 12, Line: 0, Col: 12}, }, @@ -557,7 +561,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -565,7 +569,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "href", Value: "test", - Range: Range{ + NameRange: Range{ From: Position{Index: 3, Line: 0, Col: 3}, To: Position{Index: 7, Line: 0, Col: 7}, }, @@ -578,14 +582,14 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ BoolExpressionAttribute{ Name: "noshade", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 11, Line: 0, Col: 11}, }, @@ -613,14 +617,14 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, Attributes: []Attribute{ ExpressionAttribute{ Name: "href", - Range: Range{ + NameRange: Range{ From: Position{Index: 3, Line: 0, Col: 3}, To: Position{Index: 7, Line: 0, Col: 7}, }, @@ -648,7 +652,7 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -656,7 +660,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "href", Value: "test", - Range: Range{ + NameRange: Range{ From: Position{Index: 3, Line: 0, Col: 3}, To: Position{Index: 7, Line: 0, Col: 7}, }, @@ -664,7 +668,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "text-underline: auto", - Range: Range{ + NameRange: Range{ From: Position{Index: 15, Line: 0, Col: 15}, To: Position{Index: 20, Line: 0, Col: 20}, }, @@ -677,7 +681,7 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -724,21 +728,21 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, Attributes: []Attribute{ BoolConstantAttribute{ Name: "optionA", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 11, Line: 0, Col: 11}, }, }, BoolExpressionAttribute{ Name: "optionB", - Range: Range{ + NameRange: Range{ From: Position{Index: 12, Line: 0, Col: 12}, To: Position{Index: 19, Line: 0, Col: 19}, }, @@ -761,7 +765,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "optionC", Value: "other", - Range: Range{ + NameRange: Range{ From: Position{Index: 30, Line: 0, Col: 30}, To: Position{Index: 37, Line: 0, Col: 37}, }, @@ -774,7 +778,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -782,14 +786,14 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "href", Value: "test", - Range: Range{ + NameRange: Range{ From: Position{Index: 3, Line: 0, Col: 3}, To: Position{Index: 7, Line: 0, Col: 7}, }, }, ExpressionAttribute{ Name: "title", - Range: Range{ + NameRange: Range{ From: Position{Index: 15, Line: 0, Col: 15}, To: Position{Index: 20, Line: 0, Col: 20}, }, @@ -812,7 +816,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "text-underline: auto", - Range: Range{ + NameRange: Range{ From: Position{Index: 53, Line: 0, Col: 53}, To: Position{Index: 58, Line: 0, Col: 58}, }, @@ -832,7 +836,7 @@ func TestElementParser(t *testing.T) { `, expected: Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -840,7 +844,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "width: 100;", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 10, Line: 0, Col: 10}, }, @@ -865,7 +869,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "important", - Range: Range{ + NameRange: Range{ From: Position{Index: 47, Line: 2, Col: 3}, To: Position{Index: 52, Line: 2, Col: 8}, }, @@ -887,7 +891,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, @@ -898,7 +902,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, @@ -906,7 +910,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "padding: 10px", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 9, Line: 0, Col: 9}, }, @@ -923,7 +927,7 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, @@ -931,7 +935,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "padding: 10px", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 9, Line: 0, Col: 9}, }, @@ -956,7 +960,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - Range: Range{ + NameRange: Range{ From: Position{Index: 44, Line: 2, Col: 4}, To: Position{Index: 49, Line: 2, Col: 9}, }, @@ -978,7 +982,7 @@ func TestElementParser(t *testing.T) { />`, expected: Element{ Name: "hr", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 3, Line: 0, Col: 3}, }, @@ -986,7 +990,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "padding: 10px", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 9, Line: 0, Col: 9}, }, @@ -1011,7 +1015,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - Range: Range{ + NameRange: Range{ From: Position{Index: 44, Line: 2, Col: 4}, To: Position{Index: 49, Line: 2, Col: 9}, }, @@ -1021,7 +1025,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsNotTrue", - Range: Range{ + NameRange: Range{ From: Position{Index: 77, Line: 4, Col: 4}, To: Position{Index: 82, Line: 4, Col: 9}, }, @@ -1041,7 +1045,7 @@ func TestElementParser(t *testing.T) { >Test

`, expected: Element{ Name: "p", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -1049,7 +1053,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "style", Value: "padding: 10px", - Range: Range{ + NameRange: Range{ From: Position{Index: 3, Line: 0, Col: 3}, To: Position{Index: 8, Line: 0, Col: 8}, }, @@ -1074,7 +1078,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "class", Value: "itIsTrue", - Range: Range{ + NameRange: Range{ From: Position{Index: 43, Line: 2, Col: 4}, To: Position{Index: 48, Line: 2, Col: 9}, }, @@ -1093,7 +1097,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -1104,7 +1108,7 @@ func TestElementParser(t *testing.T) { input: `The text`, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -1120,14 +1124,14 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -1140,14 +1144,14 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 5, Line: 0, Col: 5}, }, @@ -1160,7 +1164,7 @@ func TestElementParser(t *testing.T) { input: ` `, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, @@ -1168,7 +1172,7 @@ func TestElementParser(t *testing.T) { Whitespace{Value: " "}, Element{ Name: "b", - Range: Range{ + NameRange: Range{ From: Position{Index: 5, Line: 0, Col: 5}, To: Position{Index: 6, Line: 0, Col: 6}, }, @@ -1186,28 +1190,28 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 2, Line: 0, Col: 2}, }, Children: []Node{ Element{ Name: "b", - Range: Range{ + NameRange: Range{ From: Position{Index: 4, Line: 0, Col: 4}, To: Position{Index: 5, Line: 0, Col: 5}, }, }, Element{ Name: "c", - Range: Range{ + NameRange: Range{ From: Position{Index: 11, Line: 0, Col: 11}, To: Position{Index: 12, Line: 0, Col: 12}, }, Children: []Node{ Element{ Name: "d", - Range: Range{ + NameRange: Range{ From: Position{Index: 14, Line: 0, Col: 14}, To: Position{Index: 15, Line: 0, Col: 15}, }, @@ -1222,7 +1226,7 @@ func TestElementParser(t *testing.T) { input: `
`, expected: Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -1233,7 +1237,7 @@ func TestElementParser(t *testing.T) { input: `
{ "test" }
`, expected: Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 4, Line: 0, Col: 4}, }, @@ -1263,7 +1267,7 @@ func TestElementParser(t *testing.T) { input: ``, expected: Element{ Name: "input", - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 6, Line: 0, Col: 6}, }, @@ -1271,7 +1275,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 8, Line: 0, Col: 8}, To: Position{Index: 12, Line: 0, Col: 12}, }, @@ -1279,7 +1283,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "id", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 21, Line: 0, Col: 21}, To: Position{Index: 23, Line: 0, Col: 23}, }, @@ -1287,14 +1291,14 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "name", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 32, Line: 0, Col: 32}, To: Position{Index: 36, Line: 0, Col: 36}, }, }, ExpressionAttribute{ Name: "class", - Range: Range{ + NameRange: Range{ From: Position{Index: 45, Line: 0, Col: 45}, To: Position{Index: 50, Line: 0, Col: 50}, }, @@ -1317,7 +1321,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "placeholder", Value: "your@email.com", - Range: Range{ + NameRange: Range{ From: Position{Index: 91, Line: 0, Col: 91}, To: Position{Index: 102, Line: 0, Col: 102}, }, @@ -1325,7 +1329,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "autocomplete", Value: "off", - Range: Range{ + NameRange: Range{ From: Position{Index: 120, Line: 0, Col: 120}, To: Position{Index: 132, Line: 0, Col: 132}, }, @@ -1343,7 +1347,7 @@ func TestElementParser(t *testing.T) { expected: Element{ Name: "input", IndentAttrs: true, - Range: Range{ + NameRange: Range{ From: Position{Index: 1, Line: 0, Col: 1}, To: Position{Index: 6, Line: 0, Col: 6}, }, @@ -1351,7 +1355,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 8, Line: 1, Col: 1}, To: Position{Index: 12, Line: 1, Col: 5}, }, @@ -1359,7 +1363,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "id", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 23, Line: 2, Col: 1}, To: Position{Index: 25, Line: 2, Col: 3}, }, @@ -1367,7 +1371,7 @@ func TestElementParser(t *testing.T) { ConstantAttribute{ Name: "name", Value: "email", - Range: Range{ + NameRange: Range{ From: Position{Index: 36, Line: 3, Col: 1}, To: Position{Index: 40, Line: 3, Col: 5}, }, diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index 3fa51d734..793bb6f3f 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -38,7 +38,7 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 37, Line: 1, Col: 6}, To: Position{Index: 40, Line: 1, Col: 9}, }, @@ -91,7 +91,7 @@ func TestForExpressionParser(t *testing.T) { Whitespace{Value: "\t\t\t\t\t"}, Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 36, Line: 1, Col: 6}, To: Position{Index: 39, Line: 1, Col: 9}, }, diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index 79e878f1e..de3f3fcd8 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -40,7 +40,7 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 13, Line: 1, Col: 1}, To: Position{Index: 17, Line: 1, Col: 5}, }, @@ -193,7 +193,7 @@ func TestIfExpression(t *testing.T) { Then: []Node{ Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 13, Line: 1, Col: 1}, To: Position{Index: 17, Line: 1, Col: 5}, }, @@ -336,7 +336,7 @@ func TestIfExpression(t *testing.T) { Whitespace{Value: "\t\t\t\t\t\t"}, Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 30, Line: 2, Col: 7}, To: Position{Index: 33, Line: 2, Col: 10}, }, diff --git a/parser/v2/raw_test.go b/parser/v2/raw_test.go index 89646f206..7888e37c3 100644 --- a/parser/v2/raw_test.go +++ b/parser/v2/raw_test.go @@ -27,7 +27,7 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", - Range: Range{ + NameRange: Range{ From: Position{Index: 7, Line: 0, Col: 7}, To: Position{Index: 11, Line: 0, Col: 11}, }, @@ -45,7 +45,7 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text/css", - Range: Range{ + NameRange: Range{ From: Position{Index: 7, Line: 0, Col: 7}, To: Position{Index: 11, Line: 0, Col: 11}, }, @@ -63,7 +63,7 @@ func TestRawElementParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "vbscript", - Range: Range{ + NameRange: Range{ From: Position{Index: 8, Line: 0, Col: 8}, To: Position{Index: 12, Line: 0, Col: 12}, }, diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index d0b6012f2..e17cae717 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -80,7 +80,7 @@ default: Whitespace{Value: "\t"}, Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 30, Line: 2, Col: 2}, To: Position{Index: 34, Line: 2, Col: 6}, }, @@ -157,7 +157,7 @@ default: Children: []Node{ Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 37, Line: 2, Col: 1}, To: Position{Index: 41, Line: 2, Col: 5}, }, diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index f40dc246e..56caec5a7 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -150,7 +150,7 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 27, Line: 1, Col: 1}, To: Position{Index: 31, Line: 1, Col: 5}, }, @@ -200,6 +200,10 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "span", + NameRange: Range{ + From: Position{Index: 27, Line: 0, Col: 27}, + To: Position{Index: 31, Line: 0, Col: 31}, + }, Children: []Node{ StringExpression{ Expression: Expression{ @@ -253,7 +257,7 @@ func TestTemplateParser(t *testing.T) { Children: []Node{ Element{ Name: "div", - Range: Range{ + NameRange: Range{ From: Position{Index: 27, Line: 1, Col: 1}, To: Position{Index: 30, Line: 1, Col: 4}, }, @@ -279,7 +283,7 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 55, Line: 3, Col: 3}, To: Position{Index: 59, Line: 3, Col: 7}, }, @@ -361,7 +365,7 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 42, Line: 2, Col: 3}, To: Position{Index: 46, Line: 2, Col: 7}, }, @@ -423,7 +427,7 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t"}, Element{ Name: "input", - Range: Range{ + NameRange: Range{ From: Position{Index: 28, Line: 1, Col: 2}, To: Position{Index: 33, Line: 1, Col: 7}, }, @@ -431,7 +435,7 @@ func TestTemplateParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text", - Range: Range{ + NameRange: Range{ From: Position{Index: 34, Line: 1, Col: 8}, To: Position{Index: 38, Line: 1, Col: 12}, }, @@ -439,7 +443,7 @@ func TestTemplateParser(t *testing.T) { ConstantAttribute{ Name: "value", Value: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 46, Line: 1, Col: 20}, To: Position{Index: 51, Line: 1, Col: 25}, }, @@ -449,7 +453,7 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "input", - Range: Range{ + NameRange: Range{ From: Position{Index: 61, Line: 2, Col: 2}, To: Position{Index: 66, Line: 2, Col: 7}, }, @@ -457,7 +461,7 @@ func TestTemplateParser(t *testing.T) { ConstantAttribute{ Name: "type", Value: "text", - Range: Range{ + NameRange: Range{ From: Position{Index: 67, Line: 2, Col: 8}, To: Position{Index: 71, Line: 2, Col: 12}, }, @@ -465,7 +469,7 @@ func TestTemplateParser(t *testing.T) { ConstantAttribute{ Name: "value", Value: "b", - Range: Range{ + NameRange: Range{ From: Position{Index: 79, Line: 2, Col: 20}, To: Position{Index: 84, Line: 2, Col: 25}, }, @@ -542,7 +546,7 @@ func TestTemplateParser(t *testing.T) { }, Element{ Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 14, Line: 1, Col: 2}, To: Position{Index: 15, Line: 1, Col: 3}, }, @@ -550,7 +554,7 @@ func TestTemplateParser(t *testing.T) { ConstantAttribute{ Name: "href", Value: "/", - Range: Range{ + NameRange: Range{ From: Position{Index: 16, Line: 1, Col: 4}, To: Position{Index: 20, Line: 1, Col: 8}, }, @@ -696,7 +700,7 @@ func TestTemplateParser(t *testing.T) { Whitespace{Value: "\t\t"}, Element{ Name: "span", - Range: Range{ + NameRange: Range{ From: Position{Index: 43, Line: 1, Col: 3}, To: Position{Index: 47, Line: 1, Col: 7}, }, diff --git a/parser/v2/templelementparser_test.go b/parser/v2/templelementparser_test.go index c30bf5187..6640802f9 100644 --- a/parser/v2/templelementparser_test.go +++ b/parser/v2/templelementparser_test.go @@ -135,7 +135,7 @@ func TestTemplElementExpressionParser(t *testing.T) { Children: []Node{ Whitespace{Value: "\n\t\t\t"}, Element{Name: "a", - Range: Range{ + NameRange: Range{ From: Position{Index: 20, Line: 1, Col: 4}, To: Position{Index: 21, Line: 1, Col: 5}, }, @@ -143,7 +143,7 @@ func TestTemplElementExpressionParser(t *testing.T) { ConstantAttribute{ Name: "href", Value: "someurl", - Range: Range{ + NameRange: Range{ From: Position{Index: 22, Line: 1, Col: 6}, To: Position{Index: 26, Line: 1, Col: 10}, }, @@ -389,6 +389,10 @@ func TestTemplElementExpressionParser(t *testing.T) { Whitespace{Value: "\n "}, Element{ Name: "div", + NameRange: Range{ + From: Position{Index: 39, Line: 1, Col: 3}, + To: Position{Index: 42, Line: 1, Col: 6}, + }, Children: []Node{ Text{Value: "hello"}, }, diff --git a/parser/v2/types.go b/parser/v2/types.go index cf5cec2be..7ff842b24 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -452,7 +452,7 @@ type Element struct { Children []Node IndentChildren bool TrailingSpace TrailingSpace - Range Range + NameRange Range } func (e Element) Trailing() TrailingSpace { @@ -708,8 +708,8 @@ type Attribute interface { //
type BoolConstantAttribute struct { - Name string - Range Range + Name string + NameRange Range } func (bca BoolConstantAttribute) String() string { @@ -725,7 +725,7 @@ type ConstantAttribute struct { Name string Value string SingleQuote bool - Range Range + NameRange Range } func (ca ConstantAttribute) String() string { @@ -744,7 +744,7 @@ func (ca ConstantAttribute) Write(w io.Writer, indent int) error { type BoolExpressionAttribute struct { Name string Expression Expression - Range Range + NameRange Range } func (bea BoolExpressionAttribute) String() string { @@ -759,7 +759,7 @@ func (bea BoolExpressionAttribute) Write(w io.Writer, indent int) error { type ExpressionAttribute struct { Name string Expression Expression - Range Range + NameRange Range } func (ea ExpressionAttribute) String() string { From ec259fd534789ecbadcc13f25363a365f74c8dc6 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Tue, 12 Mar 2024 21:56:38 -0500 Subject: [PATCH 10/21] feat: refactor all Write methods with new ContextWriter --- .version | 2 +- cmd/templ/fmtcmd/main.go | 3 +- cmd/templ/lspcmd/proxy/server.go | 3 +- cmd/templ/migratecmd/main.go | 3 +- parser/v2/format_test.go | 3 +- parser/v2/templatefile_test.go | 3 +- parser/v2/types.go | 321 +++++++++++++++++-------------- parser/v2/types_test.go | 3 +- 8 files changed, 187 insertions(+), 154 deletions(-) diff --git a/.version b/.version index f94611877..e6bc2cfa6 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.2.610 \ No newline at end of file +0.2.613 \ No newline at end of file diff --git a/cmd/templ/fmtcmd/main.go b/cmd/templ/fmtcmd/main.go index e460f2e02..fdb3d8c84 100644 --- a/cmd/templ/fmtcmd/main.go +++ b/cmd/templ/fmtcmd/main.go @@ -144,7 +144,8 @@ func format(write writer, read reader) (err error) { return err } w := new(bytes.Buffer) - if err = t.Write(w); err != nil { + cw := parser.NewContextWriter(w) + if err = t.Write(cw); err != nil { return fmt.Errorf("formatting error: %w", err) } return write(fileName, w.String()) diff --git a/cmd/templ/lspcmd/proxy/server.go b/cmd/templ/lspcmd/proxy/server.go index 662b689e2..26ea6e4ba 100644 --- a/cmd/templ/lspcmd/proxy/server.go +++ b/cmd/templ/lspcmd/proxy/server.go @@ -734,7 +734,8 @@ func (p *Server) Formatting(ctx context.Context, params *lsp.DocumentFormattingP return } w := new(strings.Builder) - err = template.Write(w) + cw := parser.NewContextWriter(w) + err = template.Write(cw) if err != nil { p.Log.Error("handleFormatting: faled to write template", zap.Error(err)) return diff --git a/cmd/templ/migratecmd/main.go b/cmd/templ/migratecmd/main.go index bf6e9fbb3..e110e2047 100644 --- a/cmd/templ/migratecmd/main.go +++ b/cmd/templ/migratecmd/main.go @@ -94,7 +94,8 @@ func migrate(fileName string) (err error) { // Write the updated file. w := new(bytes.Buffer) - err = v2Template.Write(w) + cw := v2.NewContextWriter(w) + err = v2Template.Write(cw) if err != nil { return fmt.Errorf("%s formatting error: %w", fileName, err) } diff --git a/parser/v2/format_test.go b/parser/v2/format_test.go index 64b69f1c3..deca1423c 100644 --- a/parser/v2/format_test.go +++ b/parser/v2/format_test.go @@ -28,7 +28,8 @@ func TestFormat(t *testing.T) { t.Fatal(err) } var actual bytes.Buffer - if err := tem.Write(&actual); err != nil { + cw := NewContextWriter(&actual) + if err := tem.Write(cw); err != nil { t.Fatalf("unexpected error: %v", err) } if diff := cmp.Diff(string(a.Files[1].Data), actual.String()); diff != "" { diff --git a/parser/v2/templatefile_test.go b/parser/v2/templatefile_test.go index cd0b91aa9..21266d834 100644 --- a/parser/v2/templatefile_test.go +++ b/parser/v2/templatefile_test.go @@ -291,7 +291,8 @@ templ Hello() { } sb := new(strings.Builder) - err = tf.Write(sb) + cw := NewContextWriter(sb) + err = tf.Write(cw) if err != nil { t.Fatalf("failed to write template file: %v", err) } diff --git a/parser/v2/types.go b/parser/v2/types.go index 7ff842b24..b8f6d5f3c 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -46,6 +46,45 @@ import ( // // } +type WriteContext int + +func (wc WriteContext) IsSet(flag WriteContext) bool { + return wc&flag == flag +} + +const WriteContextGo WriteContext = 0b0001 +const WriteContextHTML WriteContext = 0b0010 +const WriteContextCSS WriteContext = 0b0100 +const WriteContextJS WriteContext = 0b1000 +const WriteContextAll WriteContext = 0b1111 + +type ContextWriter struct { + IndexToContext map[int]WriteContext + wc WriteContext + w io.Writer +} + +func NewContextWriter(w io.Writer) ContextWriter { + return ContextWriter{ + IndexToContext: make(map[int]WriteContext), + wc: WriteContextAll, + w: w, + } +} + +func (cw ContextWriter) Write(wc WriteContext, s string) (err error) { + if cw.wc.IsSet(wc) { + //TODO: Keep a map of indices to the writecontext, so we can look up in the LSP what type of context (HTML, CSS, JS etc. should be used) + _, err := io.WriteString(cw.w, s) + return err + } + // Render an empty string of the same length as s. + // This is to keep the indices in sync with the original string. + s = strings.Repeat(" ", len(s)) + _, err = io.WriteString(cw.w, s) + return +} + // Source mapping to map from the source code of the template to the // in-memory representation. type Position struct { @@ -123,24 +162,24 @@ type TemplateFile struct { Nodes []TemplateFileNode } -func (tf TemplateFile) Write(w io.Writer) error { +func (tf TemplateFile) Write(cw ContextWriter) error { for _, n := range tf.Header { - if err := n.Write(w, 0); err != nil { + if err := n.Write(cw, 0); err != nil { return err } } var indent int - if err := tf.Package.Write(w, indent); err != nil { + if err := tf.Package.Write(cw, indent); err != nil { return err } - if _, err := io.WriteString(w, "\n\n"); err != nil { + if _, err := io.WriteString(cw.w, "\n\n"); err != nil { return err } for i := 0; i < len(tf.Nodes); i++ { - if err := tf.Nodes[i].Write(w, indent); err != nil { + if err := tf.Nodes[i].Write(cw, indent); err != nil { return err } - if _, err := io.WriteString(w, getNodeWhitespace(tf.Nodes, i)); err != nil { + if _, err := io.WriteString(cw.w, getNodeWhitespace(tf.Nodes, i)); err != nil { return err } } @@ -167,7 +206,7 @@ func endsWithComment(s string) bool { // TemplateFileNode can be a Template, CSS, Script or Go. type TemplateFileNode interface { IsTemplateFileNode() bool - Write(w io.Writer, indent int) error + Write(cw ContextWriter, indent int) error } // TemplateFileGoExpression within a TemplateFile @@ -176,36 +215,37 @@ type TemplateFileGoExpression struct { } func (exp TemplateFileGoExpression) IsTemplateFileNode() bool { return true } -func (exp TemplateFileGoExpression) Write(w io.Writer, indent int) error { +func (exp TemplateFileGoExpression) Write(cw ContextWriter, indent int) error { data, err := format.Source([]byte(exp.Expression.Value)) if err != nil { - return writeIndent(w, indent, exp.Expression.Value) + return writeIndent(cw, WriteContextGo, indent, exp.Expression.Value) } - _, err = w.Write(data) - return err + if err := cw.Write(WriteContextGo, string(data)); err != nil { + return err + } + return nil } -func writeLinesIndented(w io.Writer, level int, s string) (err error) { +func writeLinesIndented(cw ContextWriter, wc WriteContext, level int, s string) (err error) { indent := strings.Repeat("\t", level) lines := strings.Split(s, "\n") indented := strings.Join(lines, "\n"+indent) - if _, err = io.WriteString(w, indent); err != nil { + if err := cw.Write(WriteContextAll, indent); err != nil { return err } - _, err = io.WriteString(w, indented) - if err != nil { - return + if err := cw.Write(wc, indented); err != nil { + return err } - return + return nil } -func writeIndent(w io.Writer, level int, s ...string) (err error) { +func writeIndent(cw ContextWriter, wc WriteContext, level int, s ...string) (err error) { indent := strings.Repeat("\t", level) - if _, err = io.WriteString(w, indent); err != nil { + if err = cw.Write(WriteContextAll, indent); err != nil { return err } for _, ss := range s { - _, err = io.WriteString(w, ss) + err = cw.Write(wc, ss) if err != nil { return } @@ -217,8 +257,8 @@ type Package struct { Expression Expression } -func (p Package) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, p.Expression.Value) +func (p Package) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextGo, indent, p.Expression.Value) } // Whitespace. @@ -228,7 +268,7 @@ type Whitespace struct { func (ws Whitespace) IsNode() bool { return true } -func (ws Whitespace) Write(w io.Writer, indent int) error { +func (ws Whitespace) Write(cw ContextWriter, indent int) error { if ws.Value == "" || !strings.Contains(ws.Value, "\n") { return nil } @@ -243,8 +283,7 @@ func (ws Whitespace) Write(w io.Writer, indent int) error { // Since any space following another space is ignored, we can collapse to a single rule. // So, the rule is... if there's a newline, it becomes a single space, or it's stripped. // We have to remove the start and end space elsewhere. - _, err := io.WriteString(w, " ") - return err + return cw.Write(WriteContextAll, " ") } // CSS definition. @@ -261,17 +300,17 @@ type CSSTemplate struct { } func (css CSSTemplate) IsTemplateFileNode() bool { return true } -func (css CSSTemplate) Write(w io.Writer, indent int) error { +func (css CSSTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(css.Expression.Value) - if err := writeIndent(w, indent, "css ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "css ", string(source), " {\n"); err != nil { return err } for _, p := range css.Properties { - if err := p.Write(w, indent+1); err != nil { + if err := p.Write(cw, indent+1); err != nil { return err } } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -280,7 +319,7 @@ func (css CSSTemplate) Write(w io.Writer, indent int) error { // CSSProperty is a CSS property and value pair. type CSSProperty interface { IsCSSProperty() bool - Write(w io.Writer, indent int) error + Write(cw ContextWriter, indent int) error } // color: #ffffff; @@ -290,8 +329,8 @@ type ConstantCSSProperty struct { } func (c ConstantCSSProperty) IsCSSProperty() bool { return true } -func (c ConstantCSSProperty) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, c.String(false)); err != nil { +func (c ConstantCSSProperty) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextCSS, indent, c.String(false)); err != nil { return err } return nil @@ -320,14 +359,14 @@ type ExpressionCSSProperty struct { } func (c ExpressionCSSProperty) IsCSSProperty() bool { return true } -func (c ExpressionCSSProperty) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, c.Name, ": "); err != nil { +func (c ExpressionCSSProperty) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextCSS, indent, c.Name, ": "); err != nil { return err } - if err := c.Value.Write(w, 0); err != nil { + if err := c.Value.Write(cw, 0); err != nil { return err } - if _, err := w.Write([]byte(";\n")); err != nil { + if err := cw.Write(WriteContextCSS, ";\n"); err != nil { return err } return nil @@ -339,8 +378,8 @@ type DocType struct { } func (dt DocType) IsNode() bool { return true } -func (dt DocType) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, "") +func (dt DocType) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextHTML, indent, "") } // HTMLTemplate definition. @@ -357,15 +396,15 @@ type HTMLTemplate struct { func (t HTMLTemplate) IsTemplateFileNode() bool { return true } -func (t HTMLTemplate) Write(w io.Writer, indent int) error { +func (t HTMLTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(t.Expression.Value) - if err := writeIndent(w, indent, "templ ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "templ ", string(source), " {\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, t.Children); err != nil { + if err := writeNodesIndented(cw, indent+1, t.Children); err != nil { return err } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -409,7 +448,7 @@ type Nodes struct { type Node interface { IsNode() bool // Write out the string. - Write(w io.Writer, indent int) error + Write(cw ContextWriter, indent int) error } type CompositeNode interface { @@ -440,8 +479,8 @@ func (t Text) Trailing() TrailingSpace { } func (t Text) IsNode() bool { return true } -func (t Text) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, t.Value) +func (t Text) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextAll, indent, t.Value) } // or
...
@@ -527,8 +566,8 @@ func (e Element) ChildNodes() []Node { return e.Children } func (e Element) IsNode() bool { return true } -func (e Element) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, "<", e.Name); err != nil { +func (e Element) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextHTML, indent, "<", e.Name); err != nil { return err } for i := 0; i < len(e.Attributes); i++ { @@ -536,71 +575,71 @@ func (e Element) Write(w io.Writer, indent int) error { // Only the conditional attributes get indented. var attrIndent int if e.IndentAttrs { - if _, err := w.Write([]byte("\n")); err != nil { + if err := cw.Write(WriteContextHTML, "\n"); err != nil { return err } attrIndent = indent + 1 } else { - if _, err := w.Write([]byte(" ")); err != nil { + if err := cw.Write(WriteContextAll, " "); err != nil { return err } } - if err := a.Write(w, attrIndent); err != nil { + if err := a.Write(cw, attrIndent); err != nil { return err } } var closeAngleBracketIndent int if e.IndentAttrs { - if _, err := w.Write([]byte("\n")); err != nil { + if err := cw.Write(WriteContextHTML, "\n"); err != nil { return err } closeAngleBracketIndent = indent } if e.hasNonWhitespaceChildren() { if e.IndentChildren { - if err := writeIndent(w, closeAngleBracketIndent, ">\n"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, e.Children); err != nil { + if err := writeNodesIndented(cw, indent+1, e.Children); err != nil { return err } - if err := writeIndent(w, indent, ""); err != nil { + if err := writeIndent(cw, WriteContextHTML, indent, ""); err != nil { return err } return nil } - if err := writeIndent(w, closeAngleBracketIndent, ">"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">"); err != nil { return err } - if err := writeNodesWithoutIndentation(w, e.Children); err != nil { + if err := writeNodesWithoutIndentation(cw, e.Children); err != nil { return err } - if _, err := w.Write([]byte("")); err != nil { + if err := cw.Write(WriteContextHTML, ""); err != nil { return err } return nil } if e.IsVoidElement() { - if err := writeIndent(w, closeAngleBracketIndent, "/>"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, "/>"); err != nil { return err } return nil } - if err := writeIndent(w, closeAngleBracketIndent, ">"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">"); err != nil { return err } return nil } -func writeNodesWithoutIndentation(w io.Writer, nodes []Node) error { - return writeNodes(w, 0, nodes, false) +func writeNodesWithoutIndentation(cw ContextWriter, nodes []Node) error { + return writeNodes(cw, 0, nodes, false) } -func writeNodesIndented(w io.Writer, level int, nodes []Node) error { - return writeNodes(w, level, nodes, true) +func writeNodesIndented(cw ContextWriter, level int, nodes []Node) error { + return writeNodes(cw, level, nodes, true) } -func writeNodes(w io.Writer, level int, nodes []Node, indent bool) error { +func writeNodes(cw ContextWriter, level int, nodes []Node, indent bool) error { startLevel := level for i := 0; i < len(nodes); i++ { _, isWhitespace := nodes[i].(Whitespace) @@ -609,7 +648,7 @@ func writeNodes(w io.Writer, level int, nodes []Node, indent bool) error { if isWhitespace { continue } - if err := nodes[i].Write(w, level); err != nil { + if err := nodes[i].Write(cw, level); err != nil { return err } @@ -630,7 +669,7 @@ func writeNodes(w io.Writer, level int, nodes []Node, indent bool) error { case SpaceVertical: level = startLevel } - if _, err := w.Write([]byte(trailing)); err != nil { + if err := cw.Write(WriteContextAll, string(trailing)); err != nil { return err } } @@ -672,30 +711,30 @@ type RawElement struct { } func (e RawElement) IsNode() bool { return true } -func (e RawElement) Write(w io.Writer, indent int) error { +func (e RawElement) Write(cw ContextWriter, indent int) error { // Start. - if err := writeIndent(w, indent, "<", e.Name); err != nil { + if err := writeIndent(cw, WriteContextHTML, indent, "<", e.Name); err != nil { return err } for i := 0; i < len(e.Attributes); i++ { - if _, err := w.Write([]byte(" ")); err != nil { + if err := cw.Write(WriteContextHTML, " "); err != nil { return err } a := e.Attributes[i] // Don't indent the attributes, only the conditional attributes get indented. - if err := a.Write(w, 0); err != nil { + if err := a.Write(cw, 0); err != nil { return err } } - if _, err := w.Write([]byte(">")); err != nil { + if err := cw.Write(WriteContextHTML, ">"); err != nil { return err } // Contents. - if _, err := w.Write([]byte(e.Contents)); err != nil { + if err := cw.Write(WriteContextAll, e.Contents); err != nil { return err } // Close. - if _, err := w.Write([]byte("")); err != nil { + if err := cw.Write(WriteContextHTML, ""); err != nil { return err } return nil @@ -703,7 +742,7 @@ func (e RawElement) Write(w io.Writer, indent int) error { type Attribute interface { // Write out the string. - Write(w io.Writer, indent int) error + Write(cw ContextWriter, indent int) error } //
@@ -716,8 +755,8 @@ func (bca BoolConstantAttribute) String() string { return bca.Name } -func (bca BoolConstantAttribute) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, bca.String()) +func (bca BoolConstantAttribute) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextHTML, indent, bca.Name) } // href="" @@ -736,8 +775,8 @@ func (ca ConstantAttribute) String() string { return ca.Name + `=` + quote + ca.Value + quote } -func (ca ConstantAttribute) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, ca.String()) +func (ca ConstantAttribute) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextHTML, indent, ca.String()) } // noshade={ templ.Bool(...) } @@ -751,8 +790,8 @@ func (bea BoolExpressionAttribute) String() string { return bea.Name + `?={ ` + bea.Expression.Value + ` }` } -func (bea BoolExpressionAttribute) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, bea.String()) +func (bea BoolExpressionAttribute) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextHTML, indent, bea.String()) } // href={ ... } @@ -762,12 +801,6 @@ type ExpressionAttribute struct { NameRange Range } -func (ea ExpressionAttribute) String() string { - sb := new(strings.Builder) - _ = ea.Write(sb, 0) - return sb.String() -} - func (ea ExpressionAttribute) formatExpression() (exp []string) { trimmed := strings.TrimSpace(ea.Expression.Value) if !strings.Contains(trimmed, "\n") { @@ -797,21 +830,21 @@ func (ea ExpressionAttribute) formatExpression() (exp []string) { return lines[1 : len(lines)-1] } -func (ea ExpressionAttribute) Write(w io.Writer, indent int) (err error) { +func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { lines := ea.formatExpression() if len(lines) == 1 { - return writeIndent(w, indent, ea.Name, `={ `, lines[0], ` }`) + return writeIndent(cw, WriteContextGo, indent, ea.Name, `={ `, lines[0], ` }`) } - if err = writeIndent(w, indent, ea.Name, "={\n"); err != nil { + if err = writeIndent(cw, WriteContextGo, indent, ea.Name, "={\n"); err != nil { return err } for _, line := range lines { - if err = writeIndent(w, indent, line, "\n"); err != nil { + if err = writeIndent(cw, WriteContextGo, indent, line, "\n"); err != nil { return err } } - return writeIndent(w, indent, "}") + return writeIndent(cw, WriteContextGo, indent, "}") } //
@@ -823,8 +856,8 @@ func (sa SpreadAttributes) String() string { return `{ ` + sa.Expression.Value + `... }` } -func (sa SpreadAttributes) Write(w io.Writer, indent int) error { - return writeIndent(w, indent, sa.String()) +func (sa SpreadAttributes) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextGo, indent, sa.String()) } // ") +func (c HTMLComment) Write(cw ContextWriter, indent int) error { + return writeIndent(cw, WriteContextHTML, indent, "") } // Nodes. @@ -929,9 +956,9 @@ type CallTemplateExpression struct { } func (cte CallTemplateExpression) IsNode() bool { return true } -func (cte CallTemplateExpression) Write(w io.Writer, indent int) error { +func (cte CallTemplateExpression) Write(cw ContextWriter, indent int) error { // Rewrite to new call syntax - return writeIndent(w, indent, `@`, cte.Expression.Value) + return writeIndent(cw, WriteContextGo, indent, `@`, cte.Expression.Value) } // TemplElementExpression can be used to create and render a template using data. @@ -949,24 +976,24 @@ func (tee TemplElementExpression) ChildNodes() []Node { return tee.Children } func (tee TemplElementExpression) IsNode() bool { return true } -func (tee TemplElementExpression) Write(w io.Writer, indent int) error { +func (tee TemplElementExpression) Write(cw ContextWriter, indent int) error { source, err := format.Source([]byte(tee.Expression.Value)) if err != nil { source = []byte(tee.Expression.Value) } - if err := writeLinesIndented(w, indent, "@"+string(source)); err != nil { + if err := writeLinesIndented(cw, WriteContextGo, indent, "@"+string(source)); err != nil { return err } if len(tee.Children) == 0 { return nil } - if _, err = io.WriteString(w, " {\n"); err != nil { + if err := cw.Write(WriteContextGo, " {\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, tee.Children); err != nil { + if err := writeNodesIndented(cw, indent+1, tee.Children); err != nil { return err } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -977,8 +1004,8 @@ func (tee TemplElementExpression) Write(w io.Writer, indent int) error { type ChildrenExpression struct{} func (ChildrenExpression) IsNode() bool { return true } -func (ChildrenExpression) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, "{ children... }"); err != nil { +func (ChildrenExpression) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextGo, indent, "{ children... }"); err != nil { return err } return nil @@ -1008,34 +1035,34 @@ func (n IfExpression) ChildNodes() []Node { return nodes } func (n IfExpression) IsNode() bool { return true } -func (n IfExpression) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, "if ", n.Expression.Value, " {\n"); err != nil { +func (n IfExpression) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextGo, indent, "if ", n.Expression.Value, " {\n"); err != nil { return err } indent++ - if err := writeNodesIndented(w, indent, n.Then); err != nil { + if err := writeNodesIndented(cw, indent, n.Then); err != nil { return err } indent-- for _, elseIf := range n.ElseIfs { - if err := writeIndent(w, indent, "} else if ", elseIf.Expression.Value, " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else if ", elseIf.Expression.Value, " {\n"); err != nil { return err } indent++ - if err := writeNodesIndented(w, indent, elseIf.Then); err != nil { + if err := writeNodesIndented(cw, indent, elseIf.Then); err != nil { return err } indent-- } if len(n.Else) > 0 { - if err := writeIndent(w, indent, "} else {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else {\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, n.Else); err != nil { + if err := writeNodesIndented(cw, indent+1, n.Else); err != nil { return err } } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -1057,22 +1084,22 @@ func (se SwitchExpression) ChildNodes() []Node { return nodes } func (se SwitchExpression) IsNode() bool { return true } -func (se SwitchExpression) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, "switch ", se.Expression.Value, " {\n"); err != nil { +func (se SwitchExpression) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextGo, indent, "switch ", se.Expression.Value, " {\n"); err != nil { return err } indent++ for i := 0; i < len(se.Cases); i++ { c := se.Cases[i] - if err := writeIndent(w, indent, c.Expression.Value, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, c.Expression.Value, "\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, c.Children); err != nil { + if err := writeNodesIndented(cw, indent+1, c.Children); err != nil { return err } } indent-- - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -1096,14 +1123,14 @@ func (fe ForExpression) ChildNodes() []Node { return fe.Children } func (fe ForExpression) IsNode() bool { return true } -func (fe ForExpression) Write(w io.Writer, indent int) error { - if err := writeIndent(w, indent, "for ", fe.Expression.Value, " {\n"); err != nil { +func (fe ForExpression) Write(cw ContextWriter, indent int) error { + if err := writeIndent(cw, WriteContextGo, indent, "for ", fe.Expression.Value, " {\n"); err != nil { return err } - if err := writeNodesIndented(w, indent+1, fe.Children); err != nil { + if err := writeNodesIndented(cw, indent+1, fe.Children); err != nil { return err } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil @@ -1123,11 +1150,11 @@ func (se StringExpression) Trailing() TrailingSpace { func (se StringExpression) IsNode() bool { return true } func (se StringExpression) IsStyleDeclarationValue() bool { return true } -func (se StringExpression) Write(w io.Writer, indent int) error { +func (se StringExpression) Write(w ContextWriter, indent int) error { if isWhitespace(se.Expression.Value) { se.Expression.Value = "" } - return writeIndent(w, indent, `{ `, se.Expression.Value, ` }`) + return writeIndent(w, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) } // ScriptTemplate is a script block. @@ -1138,15 +1165,15 @@ type ScriptTemplate struct { } func (s ScriptTemplate) IsTemplateFileNode() bool { return true } -func (s ScriptTemplate) Write(w io.Writer, indent int) error { +func (s ScriptTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(s.Name.Value + "(" + s.Parameters.Value + ")") - if err := writeIndent(w, indent, "script ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "script ", string(source), " {\n"); err != nil { return err } - if _, err := io.WriteString(w, s.Value); err != nil { + if err := cw.Write(WriteContextJS, s.Value); err != nil { return err } - if err := writeIndent(w, indent, "}"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "}"); err != nil { return err } return nil diff --git a/parser/v2/types_test.go b/parser/v2/types_test.go index 312aa007a..583a86817 100644 --- a/parser/v2/types_test.go +++ b/parser/v2/types_test.go @@ -833,7 +833,8 @@ templ test() { t.Fatalf("failed to parse template: %v", err) } w := new(strings.Builder) - err = template.Write(w) + cw := NewContextWriter(w) + err = template.Write(cw) if err != nil { t.Fatalf("failed to write template: %v", err) } From f0051c952cdd4b6e87a6930c86937a6bdc9ff7a5 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Wed, 13 Mar 2024 19:56:12 -0500 Subject: [PATCH 11/21] chore: add WriteContext as param to NewContextWriter --- cmd/templ/fmtcmd/main.go | 2 +- cmd/templ/lspcmd/proxy/server.go | 2 +- cmd/templ/migratecmd/main.go | 2 +- parser/v2/format_test.go | 2 +- parser/v2/templatefile_test.go | 2 +- parser/v2/types.go | 4 ++-- parser/v2/types_test.go | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cmd/templ/fmtcmd/main.go b/cmd/templ/fmtcmd/main.go index fdb3d8c84..98dcb1b55 100644 --- a/cmd/templ/fmtcmd/main.go +++ b/cmd/templ/fmtcmd/main.go @@ -144,7 +144,7 @@ func format(write writer, read reader) (err error) { return err } w := new(bytes.Buffer) - cw := parser.NewContextWriter(w) + cw := parser.NewContextWriter(w, parser.WriteContextAll) if err = t.Write(cw); err != nil { return fmt.Errorf("formatting error: %w", err) } diff --git a/cmd/templ/lspcmd/proxy/server.go b/cmd/templ/lspcmd/proxy/server.go index 26ea6e4ba..72daf66ed 100644 --- a/cmd/templ/lspcmd/proxy/server.go +++ b/cmd/templ/lspcmd/proxy/server.go @@ -734,7 +734,7 @@ func (p *Server) Formatting(ctx context.Context, params *lsp.DocumentFormattingP return } w := new(strings.Builder) - cw := parser.NewContextWriter(w) + cw := parser.NewContextWriter(w, parser.WriteContextAll) err = template.Write(cw) if err != nil { p.Log.Error("handleFormatting: faled to write template", zap.Error(err)) diff --git a/cmd/templ/migratecmd/main.go b/cmd/templ/migratecmd/main.go index e110e2047..21a5d2de5 100644 --- a/cmd/templ/migratecmd/main.go +++ b/cmd/templ/migratecmd/main.go @@ -94,7 +94,7 @@ func migrate(fileName string) (err error) { // Write the updated file. w := new(bytes.Buffer) - cw := v2.NewContextWriter(w) + cw := v2.NewContextWriter(w, v2.WriteContextAll) err = v2Template.Write(cw) if err != nil { return fmt.Errorf("%s formatting error: %w", fileName, err) diff --git a/parser/v2/format_test.go b/parser/v2/format_test.go index deca1423c..5036a6d3a 100644 --- a/parser/v2/format_test.go +++ b/parser/v2/format_test.go @@ -28,7 +28,7 @@ func TestFormat(t *testing.T) { t.Fatal(err) } var actual bytes.Buffer - cw := NewContextWriter(&actual) + cw := NewContextWriter(&actual, WriteContextAll) if err := tem.Write(cw); err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/parser/v2/templatefile_test.go b/parser/v2/templatefile_test.go index 21266d834..457cdedab 100644 --- a/parser/v2/templatefile_test.go +++ b/parser/v2/templatefile_test.go @@ -291,7 +291,7 @@ templ Hello() { } sb := new(strings.Builder) - cw := NewContextWriter(sb) + cw := NewContextWriter(sb, WriteContextAll) err = tf.Write(cw) if err != nil { t.Fatalf("failed to write template file: %v", err) diff --git a/parser/v2/types.go b/parser/v2/types.go index b8f6d5f3c..0771133b1 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -64,10 +64,10 @@ type ContextWriter struct { w io.Writer } -func NewContextWriter(w io.Writer) ContextWriter { +func NewContextWriter(w io.Writer, wc WriteContext) ContextWriter { return ContextWriter{ IndexToContext: make(map[int]WriteContext), - wc: WriteContextAll, + wc: wc, w: w, } } diff --git a/parser/v2/types_test.go b/parser/v2/types_test.go index 583a86817..fe47baa85 100644 --- a/parser/v2/types_test.go +++ b/parser/v2/types_test.go @@ -833,7 +833,7 @@ templ test() { t.Fatalf("failed to parse template: %v", err) } w := new(strings.Builder) - cw := NewContextWriter(w) + cw := NewContextWriter(w, WriteContextAll) err = template.Write(cw) if err != nil { t.Fatalf("failed to write template: %v", err) From d972e09101cdfea4693c53d085feb7232c501168 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Wed, 13 Mar 2024 22:56:56 -0500 Subject: [PATCH 12/21] wip: resolve broken writers and update unit tests --- parser/v2/contextwriter_test.go | 48 ++++++++++++ parser/v2/elementparser_test.go | 100 ++++++++++++++++++------- parser/v2/templateparser_test.go | 28 ++++++- parser/v2/types.go | 122 ++++++++++++++++++++++--------- 4 files changed, 235 insertions(+), 63 deletions(-) create mode 100644 parser/v2/contextwriter_test.go diff --git a/parser/v2/contextwriter_test.go b/parser/v2/contextwriter_test.go new file mode 100644 index 000000000..7a0c9f753 --- /dev/null +++ b/parser/v2/contextwriter_test.go @@ -0,0 +1,48 @@ +package parser + +import ( + "bytes" + "testing" + + "github.com/a-h/parse" + "github.com/google/go-cmp/cmp" +) + +func TestContextWriter(t *testing.T) { + tests := []struct { + name string + input string + writeContext WriteContext + expected string + }{ + { + name: "Adrian's example", + input: `Click`, + writeContext: WriteContextHTML, + expected: `Click`, + }, + } + + for _, tt := range tests { + tt := tt + w := new(bytes.Buffer) + cw := NewContextWriter(w, tt.writeContext) + t.Run(tt.name, func(t *testing.T) { + input := parse.NewInput(tt.input) + actual, ok, err := element.Parse(input) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if !ok { + t.Fatalf("unexpected failure for input %q", tt.input) + } + + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + if diff := cmp.Diff(tt.expected, w.String()); diff != "" { + t.Error(diff) + } + }) + } +} diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 6bb695aa3..3c52262d1 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "strings" "testing" @@ -552,9 +553,10 @@ if test { func TestElementParser(t *testing.T) { tests := []struct { - name string - input string - expected Element + name string + input string + expected Element + expectedHTML string }{ { name: "element: self-closing with single constant attribute", @@ -887,8 +889,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with no attributes", - input: `
`, + name: "element: self-closing with no attributes", + input: `
`, + expectedHTML: `
`, expected: Element{ Name: "hr", NameRange: Range{ @@ -898,8 +901,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with attribute", - input: `
`, + name: "element: self-closing with attribute", + input: `
`, + expectedHTML: `
`, expected: Element{ Name: "hr", NameRange: Range{ @@ -924,6 +928,11 @@ func TestElementParser(t *testing.T) { if true { class="itIsTrue" } +/>`, + expectedHTML: `
`, expected: Element{ Name: "hr", @@ -979,6 +988,13 @@ func TestElementParser(t *testing.T) { } else { class="itIsNotTrue" } +/>`, + expectedHTML: `
`, expected: Element{ Name: "hr", @@ -1042,6 +1058,11 @@ func TestElementParser(t *testing.T) { if true { class="itIsTrue" } +>Test

`, + expectedHTML: `

Test

`, expected: Element{ Name: "p", @@ -1093,8 +1114,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: open and close", - input: ``, + name: "element: open and close", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1104,8 +1126,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: open and close with text", - input: `The text`, + name: "element: open and close with text", + input: `The text`, + expectedHTML: `The text`, expected: Element{ Name: "a", NameRange: Range{ @@ -1120,8 +1143,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: with self-closing child element", - input: ``, + name: "element: with self-closing child element", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1140,8 +1164,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: with non-self-closing child element", - input: ``, + name: "element: with non-self-closing child element", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1160,8 +1185,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: containing space", - input: ` `, + name: "element: containing space", + input: ` `, + expectedHTML: ` `, expected: Element{ Name: "a", NameRange: Range{ @@ -1186,8 +1212,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: with multiple child elements", - input: ``, + name: "element: with multiple child elements", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1222,8 +1249,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: empty", - input: `
`, + name: "element: empty", + input: `
`, + expectedHTML: `
`, expected: Element{ Name: "div", NameRange: Range{ @@ -1233,8 +1261,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: containing string expression", - input: `
{ "test" }
`, + name: "element: containing string expression", + input: `
{ "test" }
`, + expectedHTML: `
`, expected: Element{ Name: "div", NameRange: Range{ @@ -1263,8 +1292,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: inputs can contain class attributes", - input: ``, + name: "element: inputs can contain class attributes", + input: ``, + expectedHTML: ``, expected: Element{ Name: "input", NameRange: Range{ @@ -1343,6 +1373,11 @@ func TestElementParser(t *testing.T) { type="email" id="email" name="email" +>`, + expectedHTML: ``, expected: Element{ Name: "input", @@ -1394,6 +1429,21 @@ func TestElementParser(t *testing.T) { if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } + if tt.expectedHTML != "" { + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } + } }) } } diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index 56caec5a7..d08fa3b89 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -9,10 +10,11 @@ import ( func TestTemplateParser(t *testing.T) { var tests = []struct { - name string - input string - expected HTMLTemplate - expectError bool + name string + input string + expected HTMLTemplate + expectedHTML string + expectError bool }{ { name: "template: no parameters", @@ -131,6 +133,9 @@ func TestTemplateParser(t *testing.T) { input: `templ Name(p Parameter) { { "span content" } }`, + expectedHTML: ` + + `, expected: HTMLTemplate{ Expression: Expression{ Value: "Name(p Parameter)", @@ -749,6 +754,21 @@ func TestTemplateParser(t *testing.T) { case !tt.expectError && diff != "": t.Errorf(diff) } + if tt.expectedHTML != "" { + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } + } }) } } diff --git a/parser/v2/types.go b/parser/v2/types.go index 0771133b1..1f2dceb42 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -172,14 +172,14 @@ func (tf TemplateFile) Write(cw ContextWriter) error { if err := tf.Package.Write(cw, indent); err != nil { return err } - if _, err := io.WriteString(cw.w, "\n\n"); err != nil { + if err := cw.Write(cw.wc, "\n\n"); err != nil { return err } for i := 0; i < len(tf.Nodes); i++ { if err := tf.Nodes[i].Write(cw, indent); err != nil { return err } - if _, err := io.WriteString(cw.w, getNodeWhitespace(tf.Nodes, i)); err != nil { + if err := cw.Write(cw.wc, getNodeWhitespace(tf.Nodes, i)); err != nil { return err } } @@ -228,20 +228,25 @@ func (exp TemplateFileGoExpression) Write(cw ContextWriter, indent int) error { func writeLinesIndented(cw ContextWriter, wc WriteContext, level int, s string) (err error) { indent := strings.Repeat("\t", level) - lines := strings.Split(s, "\n") - indented := strings.Join(lines, "\n"+indent) - if err := cw.Write(WriteContextAll, indent); err != nil { + + if err := cw.Write(cw.wc, indent); err != nil { return err } - if err := cw.Write(wc, indented); err != nil { - return err + + for _, line := range strings.Split(s, "\n") { + if err := cw.Write(wc, line); err != nil { + return err + } + if err := cw.Write(cw.wc, indent+"\n"); err != nil { + return err + } } return nil } func writeIndent(cw ContextWriter, wc WriteContext, level int, s ...string) (err error) { indent := strings.Repeat("\t", level) - if err = cw.Write(WriteContextAll, indent); err != nil { + if err = cw.Write(cw.wc, indent); err != nil { return err } for _, ss := range s { @@ -283,7 +288,7 @@ func (ws Whitespace) Write(cw ContextWriter, indent int) error { // Since any space following another space is ignored, we can collapse to a single rule. // So, the rule is... if there's a newline, it becomes a single space, or it's stripped. // We have to remove the start and end space elsewhere. - return cw.Write(WriteContextAll, " ") + return cw.Write(cw.wc, " ") } // CSS definition. @@ -302,7 +307,10 @@ type CSSTemplate struct { func (css CSSTemplate) IsTemplateFileNode() bool { return true } func (css CSSTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(css.Expression.Value) - if err := writeIndent(cw, WriteContextGo, indent, "css ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "css ", string(source), " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } for _, p := range css.Properties { @@ -398,7 +406,10 @@ func (t HTMLTemplate) IsTemplateFileNode() bool { return true } func (t HTMLTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(t.Expression.Value) - if err := writeIndent(cw, WriteContextGo, indent, "templ ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "templ ", string(source), " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, t.Children); err != nil { @@ -480,7 +491,7 @@ func (t Text) Trailing() TrailingSpace { func (t Text) IsNode() bool { return true } func (t Text) Write(cw ContextWriter, indent int) error { - return writeIndent(cw, WriteContextAll, indent, t.Value) + return writeIndent(cw, WriteContextHTML, indent, t.Value) } // or
...
@@ -575,12 +586,12 @@ func (e Element) Write(cw ContextWriter, indent int) error { // Only the conditional attributes get indented. var attrIndent int if e.IndentAttrs { - if err := cw.Write(WriteContextHTML, "\n"); err != nil { + if err := cw.Write(cw.wc, "\n"); err != nil { return err } attrIndent = indent + 1 } else { - if err := cw.Write(WriteContextAll, " "); err != nil { + if err := cw.Write(cw.wc, " "); err != nil { return err } } @@ -590,14 +601,17 @@ func (e Element) Write(cw ContextWriter, indent int) error { } var closeAngleBracketIndent int if e.IndentAttrs { - if err := cw.Write(WriteContextHTML, "\n"); err != nil { + if err := cw.Write(cw.wc, "\n"); err != nil { return err } closeAngleBracketIndent = indent } if e.hasNonWhitespaceChildren() { if e.IndentChildren { - if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">\n"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, e.Children); err != nil { @@ -620,7 +634,7 @@ func (e Element) Write(cw ContextWriter, indent int) error { return nil } if e.IsVoidElement() { - if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, "/>"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, " />"); err != nil { return err } return nil @@ -669,7 +683,7 @@ func writeNodes(cw ContextWriter, level int, nodes []Node, indent bool) error { case SpaceVertical: level = startLevel } - if err := cw.Write(WriteContextAll, string(trailing)); err != nil { + if err := cw.Write(cw.wc, string(trailing)); err != nil { return err } } @@ -730,7 +744,7 @@ func (e RawElement) Write(cw ContextWriter, indent int) error { return err } // Contents. - if err := cw.Write(WriteContextAll, e.Contents); err != nil { + if err := cw.Write(cw.wc, e.Contents); err != nil { return err } // Close. @@ -791,7 +805,7 @@ func (bea BoolExpressionAttribute) String() string { } func (bea BoolExpressionAttribute) Write(cw ContextWriter, indent int) error { - return writeIndent(cw, WriteContextHTML, indent, bea.String()) + return writeIndent(cw, WriteContextGo, indent, bea.String()) } // href={ ... } @@ -832,11 +846,21 @@ func (ea ExpressionAttribute) formatExpression() (exp []string) { func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { lines := ea.formatExpression() + + if err = writeIndent(cw, WriteContextHTML, indent, ea.Name, "="); err != nil { + return err + } + if len(lines) == 1 { - return writeIndent(cw, WriteContextGo, indent, ea.Name, `={ `, lines[0], ` }`) + if cw.wc.IsSet(WriteContextGo) { + return writeIndent(cw, WriteContextGo, 0, `{ `, lines[0], ` }`) + } else { + return writeIndent(cw, WriteContextHTML, 0, `" `, strings.Repeat(" ", len(lines[0])), ` "`) + } } - if err = writeIndent(cw, WriteContextGo, indent, ea.Name, "={\n"); err != nil { + // TODO: make this conditionally use WriteContexts + if err = writeIndent(cw, WriteContextGo, 0, "{\n"); err != nil { return err } for _, line := range lines { @@ -877,7 +901,10 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { if err := cw.Write(WriteContextGo, ca.Expression.Value); err != nil { return err } - if err := cw.Write(WriteContextGo, " {\n"); err != nil { + if err := cw.Write(WriteContextGo, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } { @@ -886,7 +913,7 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { if err := attr.Write(cw, indent); err != nil { return err } - if err := cw.Write(WriteContextAll, "\n"); err != nil { + if err := cw.Write(cw.wc, "\n"); err != nil { return err } } @@ -899,7 +926,10 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { return nil } // Write the else blocks. - if err := cw.Write(WriteContextGo, " else {\n"); err != nil { + if err := cw.Write(WriteContextGo, " else {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } { @@ -908,7 +938,7 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { if err := attr.Write(cw, indent); err != nil { return err } - if err := cw.Write(WriteContextAll, "\n"); err != nil { + if err := cw.Write(cw.wc, "\n"); err != nil { return err } } @@ -987,7 +1017,10 @@ func (tee TemplElementExpression) Write(cw ContextWriter, indent int) error { if len(tee.Children) == 0 { return nil } - if err := cw.Write(WriteContextGo, " {\n"); err != nil { + if err := cw.Write(WriteContextGo, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, tee.Children); err != nil { @@ -1036,7 +1069,10 @@ func (n IfExpression) ChildNodes() []Node { } func (n IfExpression) IsNode() bool { return true } func (n IfExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "if ", n.Expression.Value, " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "if ", n.Expression.Value, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } indent++ @@ -1045,7 +1081,10 @@ func (n IfExpression) Write(cw ContextWriter, indent int) error { } indent-- for _, elseIf := range n.ElseIfs { - if err := writeIndent(cw, WriteContextGo, indent, "} else if ", elseIf.Expression.Value, " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else if ", elseIf.Expression.Value, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } indent++ @@ -1055,7 +1094,10 @@ func (n IfExpression) Write(cw ContextWriter, indent int) error { indent-- } if len(n.Else) > 0 { - if err := writeIndent(cw, WriteContextGo, indent, "} else {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, n.Else); err != nil { @@ -1085,13 +1127,19 @@ func (se SwitchExpression) ChildNodes() []Node { } func (se SwitchExpression) IsNode() bool { return true } func (se SwitchExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "switch ", se.Expression.Value, " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "switch ", se.Expression.Value, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } indent++ for i := 0; i < len(se.Cases); i++ { c := se.Cases[i] - if err := writeIndent(cw, WriteContextGo, indent, c.Expression.Value, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, c.Expression.Value); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, c.Children); err != nil { @@ -1124,7 +1172,10 @@ func (fe ForExpression) ChildNodes() []Node { } func (fe ForExpression) IsNode() bool { return true } func (fe ForExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "for ", fe.Expression.Value, " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "for ", fe.Expression.Value, " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, fe.Children); err != nil { @@ -1167,7 +1218,10 @@ type ScriptTemplate struct { func (s ScriptTemplate) IsTemplateFileNode() bool { return true } func (s ScriptTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(s.Name.Value + "(" + s.Parameters.Value + ")") - if err := writeIndent(cw, WriteContextGo, indent, "script ", string(source), " {\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "script ", string(source), " {"); err != nil { + return err + } + if err := cw.Write(cw.wc, "\n"); err != nil { return err } if err := cw.Write(WriteContextJS, s.Value); err != nil { From 808514f8436519959ad63a8d10e25c653c407812 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:36:11 -0500 Subject: [PATCH 13/21] fix: ExpressionAttribute conditional writes and unit tests --- parser/v2/elementparser_test.go | 49 +++++++++++++++++---------------- parser/v2/types.go | 37 +++++++++++++++++++------ 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 3c52262d1..f4f741287 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -903,7 +903,7 @@ func TestElementParser(t *testing.T) { { name: "element: self-closing with attribute", input: `
`, - expectedHTML: `
`, + expectedHTML: `
`, expected: Element{ Name: "hr", NameRange: Range{ @@ -929,10 +929,11 @@ func TestElementParser(t *testing.T) { class="itIsTrue" } />`, - expectedHTML: `
`, expected: Element{ Name: "hr", @@ -989,12 +990,13 @@ func TestElementParser(t *testing.T) { class="itIsNotTrue" } />`, - expectedHTML: `
`, expected: Element{ Name: "hr", @@ -1059,10 +1061,11 @@ func TestElementParser(t *testing.T) { class="itIsTrue" } >Test

`, - expectedHTML: `

Test

`, expected: Element{ Name: "p", @@ -1145,7 +1148,7 @@ func TestElementParser(t *testing.T) { { name: "element: with self-closing child element", input: `
`, - expectedHTML: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1187,7 +1190,7 @@ func TestElementParser(t *testing.T) { { name: "element: containing space", input: ` `, - expectedHTML: ` `, + expectedHTML: ` `, expected: Element{ Name: "a", NameRange: Range{ @@ -1214,7 +1217,7 @@ func TestElementParser(t *testing.T) { { name: "element: with multiple child elements", input: ``, - expectedHTML: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -1294,7 +1297,7 @@ func TestElementParser(t *testing.T) { { name: "element: inputs can contain class attributes", input: ``, - expectedHTML: ``, + expectedHTML: ``, expected: Element{ Name: "input", NameRange: Range{ @@ -1375,10 +1378,10 @@ func TestElementParser(t *testing.T) { name="email" >`, expectedHTML: ``, + type="email" + id="email" + name="email" +/>`, expected: Element{ Name: "input", IndentAttrs: true, diff --git a/parser/v2/types.go b/parser/v2/types.go index 1f2dceb42..f39e84bdc 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -233,12 +233,15 @@ func writeLinesIndented(cw ContextWriter, wc WriteContext, level int, s string) return err } - for _, line := range strings.Split(s, "\n") { + lines := strings.Split(s, "\n") + for idx, line := range lines { if err := cw.Write(wc, line); err != nil { return err } - if err := cw.Write(cw.wc, indent+"\n"); err != nil { - return err + if idx < len(lines)-1 { + if err := cw.Write(cw.wc, "\n"+indent); err != nil { + return err + } } } return nil @@ -634,7 +637,7 @@ func (e Element) Write(cw ContextWriter, indent int) error { return nil } if e.IsVoidElement() { - if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, " />"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, "/>"); err != nil { return err } return nil @@ -859,16 +862,34 @@ func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { } } - // TODO: make this conditionally use WriteContexts - if err = writeIndent(cw, WriteContextGo, 0, "{\n"); err != nil { + if cw.wc.IsSet(WriteContextGo) { + if err := cw.Write(WriteContextGo, "{"); err != nil { + return err + } + } else { + if err := cw.Write(cw.wc, `"`); err != nil { + return err + } + } + + if err := cw.Write(cw.wc, "\n"); err != nil { return err } + for _, line := range lines { - if err = writeIndent(cw, WriteContextGo, indent, line, "\n"); err != nil { + if err = writeIndent(cw, WriteContextGo, indent, line); err != nil { return err } + if err := cw.Write(cw.wc, "\n"); err != nil { + return err + } + } + + if cw.wc.IsSet(WriteContextGo) { + return writeIndent(cw, WriteContextGo, indent, "}") + } else { + return writeIndent(cw, cw.wc, indent, `"`) } - return writeIndent(cw, WriteContextGo, indent, "}") } // From 48100268cf8f9dd612e365969ff367941fe037aa Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:54:33 -0500 Subject: [PATCH 14/21] fix: smarter white space preservation --- parser/v2/types.go | 116 ++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 80 deletions(-) diff --git a/parser/v2/types.go b/parser/v2/types.go index f39e84bdc..8c1ebdea0 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -78,13 +78,23 @@ func (cw ContextWriter) Write(wc WriteContext, s string) (err error) { _, err := io.WriteString(cw.w, s) return err } - // Render an empty string of the same length as s. - // This is to keep the indices in sync with the original string. - s = strings.Repeat(" ", len(s)) - _, err = io.WriteString(cw.w, s) + + _, err = io.WriteString(cw.w, whiteSpaceString(s)) return } +// Creates in equivalent length string to the one provided while preserving all white space characters. +func whiteSpaceString(of string) string { + output := []rune(of) + for i, r := range output { + if unicode.IsSpace(r) { + continue + } + output[i] = ' ' + } + return string(output) +} + // Source mapping to map from the source code of the template to the // in-memory representation. type Position struct { @@ -228,21 +238,13 @@ func (exp TemplateFileGoExpression) Write(cw ContextWriter, indent int) error { func writeLinesIndented(cw ContextWriter, wc WriteContext, level int, s string) (err error) { indent := strings.Repeat("\t", level) - - if err := cw.Write(cw.wc, indent); err != nil { + lines := strings.Split(s, "\n") + indented := strings.Join(lines, "\n"+indent) + if err := cw.Write(wc, indent); err != nil { return err } - - lines := strings.Split(s, "\n") - for idx, line := range lines { - if err := cw.Write(wc, line); err != nil { - return err - } - if idx < len(lines)-1 { - if err := cw.Write(cw.wc, "\n"+indent); err != nil { - return err - } - } + if err := cw.Write(wc, indented); err != nil { + return err } return nil } @@ -310,10 +312,7 @@ type CSSTemplate struct { func (css CSSTemplate) IsTemplateFileNode() bool { return true } func (css CSSTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(css.Expression.Value) - if err := writeIndent(cw, WriteContextGo, indent, "css ", string(source), " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "css ", string(source), " {\n"); err != nil { return err } for _, p := range css.Properties { @@ -409,10 +408,7 @@ func (t HTMLTemplate) IsTemplateFileNode() bool { return true } func (t HTMLTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(t.Expression.Value) - if err := writeIndent(cw, WriteContextGo, indent, "templ ", string(source), " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "templ ", string(source), " {\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, t.Children); err != nil { @@ -611,10 +607,7 @@ func (e Element) Write(cw ContextWriter, indent int) error { } if e.hasNonWhitespaceChildren() { if e.IndentChildren { - if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextHTML, closeAngleBracketIndent, ">\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, e.Children); err != nil { @@ -863,24 +856,17 @@ func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { } if cw.wc.IsSet(WriteContextGo) { - if err := cw.Write(WriteContextGo, "{"); err != nil { + if err := cw.Write(WriteContextGo, "{\n"); err != nil { return err } } else { - if err := cw.Write(cw.wc, `"`); err != nil { + if err := cw.Write(cw.wc, `"\n`); err != nil { return err } } - if err := cw.Write(cw.wc, "\n"); err != nil { - return err - } - for _, line := range lines { - if err = writeIndent(cw, WriteContextGo, indent, line); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err = writeIndent(cw, WriteContextGo, indent, line, "\n"); err != nil { return err } } @@ -888,7 +874,7 @@ func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { if cw.wc.IsSet(WriteContextGo) { return writeIndent(cw, WriteContextGo, indent, "}") } else { - return writeIndent(cw, cw.wc, indent, `"`) + return writeIndent(cw, WriteContextHTML, indent, `"`) } } @@ -922,10 +908,7 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { if err := cw.Write(WriteContextGo, ca.Expression.Value); err != nil { return err } - if err := cw.Write(WriteContextGo, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := cw.Write(WriteContextGo, " {\n"); err != nil { return err } { @@ -947,10 +930,7 @@ func (ca ConditionalAttribute) Write(cw ContextWriter, indent int) error { return nil } // Write the else blocks. - if err := cw.Write(WriteContextGo, " else {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := cw.Write(WriteContextGo, " else {\n"); err != nil { return err } { @@ -1038,10 +1018,7 @@ func (tee TemplElementExpression) Write(cw ContextWriter, indent int) error { if len(tee.Children) == 0 { return nil } - if err := cw.Write(WriteContextGo, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := cw.Write(WriteContextGo, " {\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, tee.Children); err != nil { @@ -1090,10 +1067,7 @@ func (n IfExpression) ChildNodes() []Node { } func (n IfExpression) IsNode() bool { return true } func (n IfExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "if ", n.Expression.Value, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "if ", n.Expression.Value, " {\n"); err != nil { return err } indent++ @@ -1102,10 +1076,7 @@ func (n IfExpression) Write(cw ContextWriter, indent int) error { } indent-- for _, elseIf := range n.ElseIfs { - if err := writeIndent(cw, WriteContextGo, indent, "} else if ", elseIf.Expression.Value, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else if ", elseIf.Expression.Value, " {\n"); err != nil { return err } indent++ @@ -1115,10 +1086,7 @@ func (n IfExpression) Write(cw ContextWriter, indent int) error { indent-- } if len(n.Else) > 0 { - if err := writeIndent(cw, WriteContextGo, indent, "} else {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "} else {\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, n.Else); err != nil { @@ -1148,19 +1116,13 @@ func (se SwitchExpression) ChildNodes() []Node { } func (se SwitchExpression) IsNode() bool { return true } func (se SwitchExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "switch ", se.Expression.Value, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "switch ", se.Expression.Value, " {\n"); err != nil { return err } indent++ for i := 0; i < len(se.Cases); i++ { c := se.Cases[i] - if err := writeIndent(cw, WriteContextGo, indent, c.Expression.Value); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, c.Expression.Value, "\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, c.Children); err != nil { @@ -1193,10 +1155,7 @@ func (fe ForExpression) ChildNodes() []Node { } func (fe ForExpression) IsNode() bool { return true } func (fe ForExpression) Write(cw ContextWriter, indent int) error { - if err := writeIndent(cw, WriteContextGo, indent, "for ", fe.Expression.Value, " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "for ", fe.Expression.Value, " {\n"); err != nil { return err } if err := writeNodesIndented(cw, indent+1, fe.Children); err != nil { @@ -1239,10 +1198,7 @@ type ScriptTemplate struct { func (s ScriptTemplate) IsTemplateFileNode() bool { return true } func (s ScriptTemplate) Write(cw ContextWriter, indent int) error { source := formatFunctionArguments(s.Name.Value + "(" + s.Parameters.Value + ")") - if err := writeIndent(cw, WriteContextGo, indent, "script ", string(source), " {"); err != nil { - return err - } - if err := cw.Write(cw.wc, "\n"); err != nil { + if err := writeIndent(cw, WriteContextGo, indent, "script ", string(source), " {\n"); err != nil { return err } if err := cw.Write(WriteContextJS, s.Value); err != nil { From 556439a8787b6abc2688ef8e63153fd852a33f5e Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:48:42 -0500 Subject: [PATCH 15/21] chore: add more expextedHTML to unit tests --- parser/v2/contextwriter_test.go | 48 --------------------------- parser/v2/elementparser_test.go | 43 +++++++++++++++--------- parser/v2/forexpressionparser_test.go | 30 +++++++++++++++-- parser/v2/htmlcommentparser_test.go | 14 ++++++++ parser/v2/ifexpressionparser_test.go | 29 ++++++++++++++-- parser/v2/types.go | 12 +++++-- 6 files changed, 104 insertions(+), 72 deletions(-) delete mode 100644 parser/v2/contextwriter_test.go diff --git a/parser/v2/contextwriter_test.go b/parser/v2/contextwriter_test.go deleted file mode 100644 index 7a0c9f753..000000000 --- a/parser/v2/contextwriter_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package parser - -import ( - "bytes" - "testing" - - "github.com/a-h/parse" - "github.com/google/go-cmp/cmp" -) - -func TestContextWriter(t *testing.T) { - tests := []struct { - name string - input string - writeContext WriteContext - expected string - }{ - { - name: "Adrian's example", - input: `Click`, - writeContext: WriteContextHTML, - expected: `Click`, - }, - } - - for _, tt := range tests { - tt := tt - w := new(bytes.Buffer) - cw := NewContextWriter(w, tt.writeContext) - t.Run(tt.name, func(t *testing.T) { - input := parse.NewInput(tt.input) - actual, ok, err := element.Parse(input) - if err != nil { - t.Fatalf("unexpected error: %v", err) - } - if !ok { - t.Fatalf("unexpected failure for input %q", tt.input) - } - - if err := actual.Write(cw, 0); err != nil { - t.Fatalf("unexpected error: %v", err) - } - if diff := cmp.Diff(tt.expected, w.String()); diff != "" { - t.Error(diff) - } - }) - } -} diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index f4f741287..ebeb8ce7a 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -559,8 +559,9 @@ func TestElementParser(t *testing.T) { expectedHTML string }{ { - name: "element: self-closing with single constant attribute", - input: ``, + name: "element: self-closing with single constant attribute", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -580,8 +581,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with single bool expression attribute", - input: `
`, + name: "element: self-closing with single bool expression attribute", + input: `
`, + expectedHTML: `
`, expected: Element{ Name: "hr", NameRange: Range{ @@ -615,8 +617,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with single expression attribute", - input: ``, + name: "element: self-closing with single expression attribute", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -650,8 +653,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with multiple constant attributes", - input: ``, + name: "element: self-closing with multiple constant attributes", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -679,8 +683,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with multiple spreads attributes", - input: ``, + name: "element: self-closing with multiple spreads attributes", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -726,8 +731,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with multiple boolean attributes", - input: `
`, + name: "element: self-closing with multiple boolean attributes", + input: `
`, + expectedHTML: `
`, expected: Element{ Name: "hr", NameRange: Range{ @@ -776,8 +782,9 @@ func TestElementParser(t *testing.T) { }, }, { - name: "element: self-closing with multiple constant and expr attributes", - input: ``, + name: "element: self-closing with multiple constant and expr attributes", + input: ``, + expectedHTML: ``, expected: Element{ Name: "a", NameRange: Range{ @@ -833,9 +840,13 @@ func TestElementParser(t *testing.T) { class="important" } >Test -} - `, + expectedHTML: `
Test
`, expected: Element{ Name: "div", NameRange: Range{ diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index 793bb6f3f..bee1a718a 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -9,15 +10,19 @@ import ( func TestForExpressionParser(t *testing.T) { tests := []struct { - name string - input string - expected interface{} + name string + input string + expected interface{} + expectedHTML string }{ { name: "for: simple", input: `for _, item := range p.Items {
{ item }
}`, + expectedHTML: ` +
+ `, expected: ForExpression{ Expression: Expression{ Value: `_, item := range p.Items`, @@ -71,6 +76,9 @@ func TestForExpressionParser(t *testing.T) { input: `for _, item := range p.Items{
{ item }
}`, + expectedHTML: ` +
+ `, expected: ForExpression{ Expression: Expression{ Value: `_, item := range p.Items`, @@ -134,6 +142,22 @@ func TestForExpressionParser(t *testing.T) { if diff := cmp.Diff(tt.expected, actual); diff != "" { t.Error(diff) } + + if tt.expectedHTML != "" { + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } + } }) } } diff --git a/parser/v2/htmlcommentparser_test.go b/parser/v2/htmlcommentparser_test.go index 735a4820c..3924798d7 100644 --- a/parser/v2/htmlcommentparser_test.go +++ b/parser/v2/htmlcommentparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -67,6 +68,19 @@ func TestHTMLCommentParser(t *testing.T) { if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.input, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } }) } } diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index de3f3fcd8..bec9929e7 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -9,9 +10,10 @@ import ( func TestIfExpression(t *testing.T) { tests := []struct { - name string - input string - expected IfExpression + name string + input string + expected IfExpression + expectedHTML string }{ { name: "if: simple expression", @@ -21,6 +23,11 @@ func TestIfExpression(t *testing.T) { } `, + expectedHTML: ` + + + + `, expected: IfExpression{ Expression: Expression{ Value: `p.Test`, @@ -607,6 +614,22 @@ func TestIfExpression(t *testing.T) { if diff := cmp.Diff(tt.expected, actual); diff != "" { t.Error(diff) } + + if tt.expectedHTML != "" { + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } + } }) } } diff --git a/parser/v2/types.go b/parser/v2/types.go index 8c1ebdea0..5056e9ee1 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -74,7 +74,7 @@ func NewContextWriter(w io.Writer, wc WriteContext) ContextWriter { func (cw ContextWriter) Write(wc WriteContext, s string) (err error) { if cw.wc.IsSet(wc) { - //TODO: Keep a map of indices to the writecontext, so we can look up in the LSP what type of context (HTML, CSS, JS etc. should be used) + //TODO: Keep a map of indices to the writecontext, so we can look up in the LSP what type of context (Go, HTML, CSS, JS etc. should be used) _, err := io.WriteString(cw.w, s) return err } @@ -801,7 +801,15 @@ func (bea BoolExpressionAttribute) String() string { } func (bea BoolExpressionAttribute) Write(cw ContextWriter, indent int) error { - return writeIndent(cw, WriteContextGo, indent, bea.String()) + if err := writeIndent(cw, WriteContextHTML, indent, bea.Name); err != nil { + return err + } + + if cw.wc.IsSet(WriteContextGo) { + return cw.Write(WriteContextGo, "?={ "+bea.Expression.Value+" }") + } else { + return cw.Write(WriteContextHTML, ` =" `+strings.Repeat(" ", len(bea.Expression.Value))+` "`) + } } // href={ ... } From 601e8f178ab0061235d84f6d201a5288892da480 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Sun, 17 Mar 2024 10:56:16 -0500 Subject: [PATCH 16/21] chore: more html contextwriter unit tests --- parser/v2/elementparser_test.go | 25 +++++++------- parser/v2/forexpressionparser_test.go | 24 +++++++------- parser/v2/scripttemplateparser_test.go | 38 +++++++++++++++++++-- parser/v2/switchexpressionparser_test.go | 42 ++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 32 deletions(-) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index ebeb8ce7a..1da8ee24f 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -1443,20 +1443,19 @@ func TestElementParser(t *testing.T) { if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } - if tt.expectedHTML != "" { - w := new(bytes.Buffer) - cw := NewContextWriter(w, WriteContextHTML) - if err := result.Write(cw, 0); err != nil { - t.Fatalf("unexpected error: %v", err) - } - actualHTML := w.String() - if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { - t.Error(diff) - t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) - t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) - t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) - } + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } }) } diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index bee1a718a..5a7fe0821 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -143,20 +143,18 @@ func TestForExpressionParser(t *testing.T) { t.Error(diff) } - if tt.expectedHTML != "" { - w := new(bytes.Buffer) - cw := NewContextWriter(w, WriteContextHTML) - if err := actual.Write(cw, 0); err != nil { - t.Fatalf("unexpected error: %v", err) - } - actualHTML := w.String() - if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { - t.Error(diff) + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) - t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) - t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) - t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) - } + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } }) } diff --git a/parser/v2/scripttemplateparser_test.go b/parser/v2/scripttemplateparser_test.go index fae590f5d..8180b85c0 100644 --- a/parser/v2/scripttemplateparser_test.go +++ b/parser/v2/scripttemplateparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "fmt" "testing" @@ -10,14 +11,17 @@ import ( func TestScriptTemplateParser(t *testing.T) { var tests = []struct { - name string - input string - expected ScriptTemplate + name string + input string + expected ScriptTemplate + expectedJS string }{ { name: "script: no parameters, no content", input: `script Name() { }`, + expectedJS: ` + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -55,6 +59,8 @@ func TestScriptTemplateParser(t *testing.T) { name: "script: no spaces", input: `script Name(){ }`, + expectedJS: ` + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -93,6 +99,9 @@ func TestScriptTemplateParser(t *testing.T) { input: `script Name() { var x = "x"; }`, + expectedJS: ` +var x = "x"; + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -132,6 +141,9 @@ var x = "x"; input: `script Name(value string) { console.log(value); }`, + expectedJS: ` +console.log(value); + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -171,6 +183,9 @@ console.log(value); input: `script Name() { //' }`, + expectedJS: ` + //' + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -210,6 +225,9 @@ console.log(value); input: `script Name() { let x = ''; }`, + expectedJS: ` + let x = ''; + `, expected: ScriptTemplate{ Name: Expression{ Value: "Name", @@ -266,6 +284,20 @@ console.log(value); t.Error("unexpected suffix") t.Error(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextJS) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualJS := w.String() + if diff := cmp.Diff(tt.expectedJS, actualJS); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedJS)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualJS)) + } }) } } diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index e17cae717..744ac818b 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -9,14 +10,17 @@ import ( func TestSwitchExpressionParser(t *testing.T) { tests := []struct { - name string - input string - expected SwitchExpression + name string + input string + expected SwitchExpression + expectedHTML string }{ { name: "switch: simple", input: `switch "stringy" { }`, + expectedHTML: ` + `, expected: SwitchExpression{ Expression: Expression{ Value: `"stringy"`, @@ -43,6 +47,12 @@ default: { "span content" } }`, + expectedHTML: ` + + + + + `, expected: SwitchExpression{ Expression: Expression{ Value: `"stringy"`, @@ -121,6 +131,12 @@ default: { "span content" } }`, + expectedHTML: ` + + + + + `, expected: SwitchExpression{ Expression: Expression{ Value: `"stringy"`, @@ -198,6 +214,12 @@ default: case "b": { "B" } }`, + expectedHTML: ` + + + + + `, expected: SwitchExpression{ Expression: Expression{ Value: `"stringy"`, @@ -314,6 +336,20 @@ default: if diff := cmp.Diff(tt.expected, actual); diff != "" { t.Error(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextHTML) + if err := actual.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedHTML, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } }) } } From 59c9985042aa9e24a2c5704cccb538fa629d4f93 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:49:06 -0500 Subject: [PATCH 17/21] chore: css parser unit tests --- parser/v2/cssparser_test.go | 97 ++++++++++++++++++++++++++++++------- parser/v2/types.go | 17 ++++++- 2 files changed, 95 insertions(+), 19 deletions(-) diff --git a/parser/v2/cssparser_test.go b/parser/v2/cssparser_test.go index 851608ff3..36ccf5dac 100644 --- a/parser/v2/cssparser_test.go +++ b/parser/v2/cssparser_test.go @@ -1,6 +1,7 @@ package parser import ( + "bytes" "testing" "github.com/a-h/parse" @@ -9,13 +10,15 @@ import ( func TestExpressionCSSPropertyParser(t *testing.T) { tests := []struct { - name string - input string - expected ExpressionCSSProperty + name string + input string + expected ExpressionCSSProperty + expectedCSS string }{ { - name: "css: single constant property", - input: `background-color: { constants.BackgroundColor };`, + name: "css: single constant property", + input: `background-color: { constants.BackgroundColor };`, + expectedCSS: "background-color: ' ';\n", expected: ExpressionCSSProperty{ Name: "background-color", Value: StringExpression{ @@ -38,8 +41,9 @@ func TestExpressionCSSPropertyParser(t *testing.T) { }, }, { - name: "css: single constant property with windows newlines", - input: "background-color:\r\n{ constants.BackgroundColor };\r\n", + name: "css: single constant property with windows newlines", + input: "background-color:\r\n{ constants.BackgroundColor };\r\n", + expectedCSS: "background-color: ' ';\n", expected: ExpressionCSSProperty{ Name: "background-color", Value: StringExpression{ @@ -76,27 +80,44 @@ func TestExpressionCSSPropertyParser(t *testing.T) { if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextCSS) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } }) } } func TestConstantCSSPropertyParser(t *testing.T) { tests := []struct { - name string - input string - expected ConstantCSSProperty + name string + input string + expected ConstantCSSProperty + expectedCSS string }{ { - name: "css: single constant property", - input: `background-color: #ffffff;`, + name: "css: single constant property", + input: `background-color: #ffffff;`, + expectedCSS: "background-color: #ffffff;\n", expected: ConstantCSSProperty{ Name: "background-color", Value: "#ffffff", }, }, { - name: "css: single constant webkit property", - input: `-webkit-text-stroke-color: #ffffff;`, + name: "css: single constant webkit property", + input: `-webkit-text-stroke-color: #ffffff;`, + expectedCSS: "-webkit-text-stroke-color: #ffffff;\n", expected: ConstantCSSProperty{ Name: "-webkit-text-stroke-color", Value: "#ffffff", @@ -117,20 +138,37 @@ func TestConstantCSSPropertyParser(t *testing.T) { if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextCSS) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } }) } } func TestCSSParser(t *testing.T) { tests := []struct { - name string - input string - expected CSSTemplate + name string + input string + expected CSSTemplate + expectedCSS string }{ { name: "css: no parameters, no content", input: `css Name() { }`, + expectedCSS: ` + `, expected: CSSTemplate{ Name: "Name", Expression: Expression{ @@ -155,6 +193,8 @@ func TestCSSParser(t *testing.T) { name: "css: without spaces", input: `css Name() { }`, + expectedCSS: ` + `, expected: CSSTemplate{ Name: "Name", Expression: Expression{ @@ -180,6 +220,9 @@ func TestCSSParser(t *testing.T) { input: `css Name() { background-color: #ffffff; }`, + expectedCSS: ` + background-color: #ffffff; + `, expected: CSSTemplate{ Name: "Name", Expression: Expression{ @@ -210,6 +253,9 @@ background-color: #ffffff; input: `css Name() { background-color: { constants.BackgroundColor }; }`, + expectedCSS: ` + background-color: ' '; + `, expected: CSSTemplate{ Name: "Name", Expression: Expression{ @@ -256,6 +302,9 @@ background-color: { constants.BackgroundColor }; input: `css Name(prop string) { background-color: { prop }; }`, + expectedCSS: ` + background-color: ' '; + `, expected: CSSTemplate{ Name: "Name", Expression: Expression{ @@ -312,6 +361,20 @@ background-color: { prop }; if diff := cmp.Diff(tt.expected, result); diff != "" { t.Errorf(diff) } + + w := new(bytes.Buffer) + cw := NewContextWriter(w, WriteContextCSS) + if err := result.Write(cw, 0); err != nil { + t.Fatalf("unexpected error: %v", err) + } + actualHTML := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + t.Error(diff) + + t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) + t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + } }) } } diff --git a/parser/v2/types.go b/parser/v2/types.go index 5056e9ee1..df8c6118d 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -1189,11 +1189,24 @@ func (se StringExpression) Trailing() TrailingSpace { func (se StringExpression) IsNode() bool { return true } func (se StringExpression) IsStyleDeclarationValue() bool { return true } -func (se StringExpression) Write(w ContextWriter, indent int) error { +func (se StringExpression) Write(cw ContextWriter, indent int) error { if isWhitespace(se.Expression.Value) { se.Expression.Value = "" } - return writeIndent(w, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) + + if cw.wc.IsSet(WriteContextGo) { + return writeIndent(cw, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) + } + + if cw.wc.IsSet(WriteContextCSS) { + return writeIndent(cw, WriteContextCSS, indent, `' `, whiteSpaceString(se.Expression.Value), ` '`) + } + + if cw.wc.IsSet(WriteContextHTML) { + return writeIndent(cw, WriteContextCSS, indent, `" `, whiteSpaceString(se.Expression.Value), ` "`) + } + + return writeIndent(cw, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) } // ScriptTemplate is a script block. From bae606ce9e564be4a49a46ac049421fa8211eb28 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Thu, 21 Mar 2024 14:49:37 -0500 Subject: [PATCH 18/21] chore: remove unused IndexToContext --- parser/v2/types.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/parser/v2/types.go b/parser/v2/types.go index df8c6118d..0d8f72f50 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -59,16 +59,14 @@ const WriteContextJS WriteContext = 0b1000 const WriteContextAll WriteContext = 0b1111 type ContextWriter struct { - IndexToContext map[int]WriteContext - wc WriteContext - w io.Writer + wc WriteContext + w io.Writer } func NewContextWriter(w io.Writer, wc WriteContext) ContextWriter { return ContextWriter{ - IndexToContext: make(map[int]WriteContext), - wc: wc, - w: w, + wc: wc, + w: w, } } From 4c7959bea9f4c5c15ee16d975b477043187f711a Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Fri, 29 Mar 2024 21:05:04 -0500 Subject: [PATCH 19/21] fix: add line length checking to unit tests --- parser/v2/cssparser_test.go | 9 +++++++++ parser/v2/elementparser_test.go | 12 ++++++++++++ parser/v2/forexpressionparser_test.go | 3 +++ parser/v2/ifexpressionparser_test.go | 3 +++ parser/v2/scripttemplateparser_test.go | 3 +++ parser/v2/switchexpressionparser_test.go | 3 +++ parser/v2/templateparser_test.go | 3 +++ 7 files changed, 36 insertions(+) diff --git a/parser/v2/cssparser_test.go b/parser/v2/cssparser_test.go index 36ccf5dac..d3b8af671 100644 --- a/parser/v2/cssparser_test.go +++ b/parser/v2/cssparser_test.go @@ -94,6 +94,9 @@ func TestExpressionCSSPropertyParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + t.Errorf(diff) + } }) } } @@ -152,6 +155,9 @@ func TestConstantCSSPropertyParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + t.Errorf(diff) + } }) } } @@ -375,6 +381,9 @@ background-color: { prop }; t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + t.Errorf(diff) + } }) } } diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index 1da8ee24f..a7a094c49 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -1457,6 +1457,9 @@ func TestElementParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + t.Errorf(diff) + } }) } } @@ -1575,3 +1578,12 @@ func TestBigElement(t *testing.T) { t.Errorf("unexpected failure to parse") } } + +func getLineLengths(s string) (lengths []int) { + lines := strings.Split(s, "\n") + lengths = make([]int, len(lines)) + for i := 0; i < len(lines); i++ { + lengths[i] = len(lines[i]) + } + return lengths +} diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index 5a7fe0821..88d381b7f 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -156,6 +156,9 @@ func TestForExpressionParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + t.Errorf(diff) + } }) } } diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index bec9929e7..8c6bb7bab 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -629,6 +629,9 @@ func TestIfExpression(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + t.Errorf(diff) + } } }) } diff --git a/parser/v2/scripttemplateparser_test.go b/parser/v2/scripttemplateparser_test.go index 8180b85c0..a19189bce 100644 --- a/parser/v2/scripttemplateparser_test.go +++ b/parser/v2/scripttemplateparser_test.go @@ -298,6 +298,9 @@ console.log(value); t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedJS)) t.Errorf("got:\n%s", displayWhitespaceChars(actualJS)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedJS)); diff != "" { + t.Errorf(diff) + } }) } } diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index 744ac818b..770cbda24 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -350,6 +350,9 @@ default: t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + t.Errorf(diff) + } }) } } diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index d08fa3b89..594c363e0 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -768,6 +768,9 @@ func TestTemplateParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + t.Errorf(diff) + } } }) } From cee405d88c867d7bacc3677cdce05834bc382c0c Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Sat, 30 Mar 2024 17:52:45 -0500 Subject: [PATCH 20/21] fix: test line lengths against actual outputs --- parser/v2/cssparser_test.go | 24 ++++++++++++------------ parser/v2/elementparser_test.go | 2 +- parser/v2/forexpressionparser_test.go | 2 +- parser/v2/ifexpressionparser_test.go | 2 +- parser/v2/scripttemplateparser_test.go | 2 +- parser/v2/switchexpressionparser_test.go | 2 +- parser/v2/templateparser_test.go | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/parser/v2/cssparser_test.go b/parser/v2/cssparser_test.go index d3b8af671..c241bbeda 100644 --- a/parser/v2/cssparser_test.go +++ b/parser/v2/cssparser_test.go @@ -86,15 +86,15 @@ func TestExpressionCSSPropertyParser(t *testing.T) { if err := result.Write(cw, 0); err != nil { t.Fatalf("unexpected error: %v", err) } - actualHTML := w.String() - if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + actualCSS := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualCSS); diff != "" { t.Error(diff) t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) - t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualCSS)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualCSS)); diff != "" { t.Errorf(diff) } }) @@ -147,15 +147,15 @@ func TestConstantCSSPropertyParser(t *testing.T) { if err := result.Write(cw, 0); err != nil { t.Fatalf("unexpected error: %v", err) } - actualHTML := w.String() - if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + actualCSS := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualCSS); diff != "" { t.Error(diff) t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) - t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualCSS)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualCSS)); diff != "" { t.Errorf(diff) } }) @@ -373,15 +373,15 @@ background-color: { prop }; if err := result.Write(cw, 0); err != nil { t.Fatalf("unexpected error: %v", err) } - actualHTML := w.String() - if diff := cmp.Diff(tt.expectedCSS, actualHTML); diff != "" { + actualCSS := w.String() + if diff := cmp.Diff(tt.expectedCSS, actualCSS); diff != "" { t.Error(diff) t.Errorf("input:\n%s", displayWhitespaceChars(tt.input)) t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedCSS)) - t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) + t.Errorf("got:\n%s", displayWhitespaceChars(actualCSS)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedCSS)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualCSS)); diff != "" { t.Errorf(diff) } }) diff --git a/parser/v2/elementparser_test.go b/parser/v2/elementparser_test.go index a7a094c49..a54d9fb50 100644 --- a/parser/v2/elementparser_test.go +++ b/parser/v2/elementparser_test.go @@ -1457,7 +1457,7 @@ func TestElementParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualHTML)); diff != "" { t.Errorf(diff) } }) diff --git a/parser/v2/forexpressionparser_test.go b/parser/v2/forexpressionparser_test.go index 88d381b7f..db2c9d3a9 100644 --- a/parser/v2/forexpressionparser_test.go +++ b/parser/v2/forexpressionparser_test.go @@ -156,7 +156,7 @@ func TestForExpressionParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualHTML)); diff != "" { t.Errorf(diff) } }) diff --git a/parser/v2/ifexpressionparser_test.go b/parser/v2/ifexpressionparser_test.go index 8c6bb7bab..3b5f52f18 100644 --- a/parser/v2/ifexpressionparser_test.go +++ b/parser/v2/ifexpressionparser_test.go @@ -629,7 +629,7 @@ func TestIfExpression(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualHTML)); diff != "" { t.Errorf(diff) } } diff --git a/parser/v2/scripttemplateparser_test.go b/parser/v2/scripttemplateparser_test.go index a19189bce..e0fc00700 100644 --- a/parser/v2/scripttemplateparser_test.go +++ b/parser/v2/scripttemplateparser_test.go @@ -298,7 +298,7 @@ console.log(value); t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedJS)) t.Errorf("got:\n%s", displayWhitespaceChars(actualJS)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedJS)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualJS)); diff != "" { t.Errorf(diff) } }) diff --git a/parser/v2/switchexpressionparser_test.go b/parser/v2/switchexpressionparser_test.go index 770cbda24..ca524bd7a 100644 --- a/parser/v2/switchexpressionparser_test.go +++ b/parser/v2/switchexpressionparser_test.go @@ -350,7 +350,7 @@ default: t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualHTML)); diff != "" { t.Errorf(diff) } }) diff --git a/parser/v2/templateparser_test.go b/parser/v2/templateparser_test.go index 594c363e0..db9492af6 100644 --- a/parser/v2/templateparser_test.go +++ b/parser/v2/templateparser_test.go @@ -768,7 +768,7 @@ func TestTemplateParser(t *testing.T) { t.Errorf("expected:\n%s", displayWhitespaceChars(tt.expectedHTML)) t.Errorf("got:\n%s", displayWhitespaceChars(actualHTML)) } - if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(tt.expectedHTML)); diff != "" { + if diff := cmp.Diff(getLineLengths(tt.input), getLineLengths(actualHTML)); diff != "" { t.Errorf(diff) } } From 6de021cbf3602dd5993d297be3942cddd3e64c24 Mon Sep 17 00:00:00 2001 From: Adam Lehechka <42357034+alehechka@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:02:29 -0500 Subject: [PATCH 21/21] chore: refactor some CW uses --- parser/v2/types.go | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/parser/v2/types.go b/parser/v2/types.go index 0d8f72f50..6ab501874 100644 --- a/parser/v2/types.go +++ b/parser/v2/types.go @@ -857,7 +857,7 @@ func (ea ExpressionAttribute) Write(cw ContextWriter, indent int) (err error) { if cw.wc.IsSet(WriteContextGo) { return writeIndent(cw, WriteContextGo, 0, `{ `, lines[0], ` }`) } else { - return writeIndent(cw, WriteContextHTML, 0, `" `, strings.Repeat(" ", len(lines[0])), ` "`) + return writeIndent(cw, WriteContextHTML, 0, `" `, whiteSpaceString(lines[0]), ` "`) } } @@ -1194,17 +1194,11 @@ func (se StringExpression) Write(cw ContextWriter, indent int) error { if cw.wc.IsSet(WriteContextGo) { return writeIndent(cw, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) - } - - if cw.wc.IsSet(WriteContextCSS) { + } else if cw.wc.IsSet(WriteContextCSS) { return writeIndent(cw, WriteContextCSS, indent, `' `, whiteSpaceString(se.Expression.Value), ` '`) + } else { + return writeIndent(cw, WriteContextHTML, indent, `" `, whiteSpaceString(se.Expression.Value), ` "`) } - - if cw.wc.IsSet(WriteContextHTML) { - return writeIndent(cw, WriteContextCSS, indent, `" `, whiteSpaceString(se.Expression.Value), ` "`) - } - - return writeIndent(cw, WriteContextGo, indent, `{ `, se.Expression.Value, ` }`) } // ScriptTemplate is a script block.