Skip to content

Commit

Permalink
printer: handle labels properly while printing tags
Browse files Browse the repository at this point in the history
  • Loading branch information
mateusz834 committed Nov 8, 2024
1 parent 3fe510e commit 1d08a46
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 20 deletions.
28 changes: 15 additions & 13 deletions printer/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) {
tagOneLine = make([]bool, 1, 32)
)

openTagIndent, endTagUnindent, oneline := p.tagIndent(list)
openPair, endPair, oneline := p.tagIndent(list)

for _, s := range list {
// ignore empty statements (was issue 3466)
Expand All @@ -1216,26 +1216,28 @@ func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) {
p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || p.linesFrom(line) > 0)
}

if v, ok := s.(*ast.EndTagStmt); ok {
if _, ok := endTagUnindent[v]; ok {
if v, ok := unlabel(s).(*ast.EndTagStmt); ok {
if _, ok := endPair[v]; ok {
p.print(unindent)
forceNextNewline = !tagOneLine[len(tagOneLine)-1]
tagOneLine = tagOneLine[:len(tagOneLine)-1]
if forceNextNewline && p.commentBefore(p.posFor(s.Pos())) {
p.linebreak(p.lineFor(s.Pos()), 0, ignore, false)
}
}
forceNextNewline = !tagOneLine[len(tagOneLine)-1]
tagOneLine = tagOneLine[:len(tagOneLine)-1]
if forceNextNewline && p.commentBefore(p.posFor(s.Pos())) {
p.linebreak(p.lineFor(s.Pos()), 0, ignore, false)
} else if v, ok := unlabel(s).(*ast.OpenTagStmt); ok {
if _, ok := openPair[v]; ok {
forceNextNewline = false
_, ok := oneline[v]
tagOneLine = append(tagOneLine, ok)
}
} else if v, ok := s.(*ast.OpenTagStmt); ok {
forceNextNewline = false
_, ok := oneline[v]
tagOneLine = append(tagOneLine, ok)
}

p.recordLine(&line)
p.stmt(s, nextIsRBrace && i == len(list)-1)

if v, ok := s.(*ast.OpenTagStmt); ok {
if _, ok := openTagIndent[v]; ok {
if v, ok := unlabel(s).(*ast.OpenTagStmt); ok {
if _, ok := openPair[v]; ok {
p.print(indent)
}
}
Expand Down
34 changes: 34 additions & 0 deletions printer/testdata/tgo/void_elements.formatted
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ func test() {
</div>
}

func test() {
<div>
<br>
_ = 3
</div>
_ = 3
}

func test() {
<div>
_ = 3
</div>
_ = 3
}

func test() {
<div>
<br>
Expand Down Expand Up @@ -61,3 +76,22 @@ func test() {
</div>
</div>
}

func test() {
a:
<div>
goto a
}

func test() {
a:
</div>
goto a
}

func test() {
a:
<div>
</div>
goto a
}
34 changes: 34 additions & 0 deletions printer/testdata/tgo/void_elements.tgo
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ func test() {
</div>
}

func test() {
<div>
<br>
_ = 3
</div>
_ = 3
}

func test() {
<div>
_ = 3
</div>
_ = 3
}

func test() {
<div>
<br>
Expand Down Expand Up @@ -61,3 +76,22 @@ func test() {
</div>
</div>
}

func test() {
a:
<div>
goto a
}

func test() {
a:
</div>
goto a
}

func test() {
a:
<div>
</div>
goto a
}
24 changes: 17 additions & 7 deletions printer/tgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,24 +139,34 @@ func (p *printer) templateLiteralExpr(x *ast.TemplateLiteralExpr) {
}
}

func (p *printer) tagIndent(list []ast.Stmt) (indent map[*ast.OpenTagStmt]struct{}, unindent map[*ast.EndTagStmt]struct{}, oneline map[*ast.OpenTagStmt]struct{}) {
indent = make(map[*ast.OpenTagStmt]struct{})
unindent = make(map[*ast.EndTagStmt]struct{})
func unlabel(s ast.Stmt) ast.Stmt {
for {
if l, ok := s.(*ast.LabeledStmt); ok {
s = l.Stmt
continue
}
return s
}
}

func (p *printer) tagIndent(list []ast.Stmt) (openPair map[*ast.OpenTagStmt]struct{}, endPair map[*ast.EndTagStmt]struct{}, oneline map[*ast.OpenTagStmt]struct{}) {
openPair = make(map[*ast.OpenTagStmt]struct{})
endPair = make(map[*ast.EndTagStmt]struct{})
oneline = make(map[*ast.OpenTagStmt]struct{})

deep := make([]int, 0, 32)
for i, v := range list {
switch v := v.(type) {
switch v := unlabel(v).(type) {
case *ast.OpenTagStmt:
deep = append(deep, i)
case *ast.EndTagStmt:
for len(deep) != 0 {
openTagIndex := deep[len(deep)-1]
openTag := list[openTagIndex].(*ast.OpenTagStmt)
openTag := unlabel(list[openTagIndex]).(*ast.OpenTagStmt)
deep = deep[:len(deep)-1]
if openTag.Name.Name == v.Name.Name {
indent[openTag] = struct{}{}
unindent[v] = struct{}{}
openPair[openTag] = struct{}{}
endPair[v] = struct{}{}
if p.lineFor(openTag.Pos()) == p.lineFor(v.End()) && !p.willHaveNewLine(openTag, list[openTagIndex+1:i]) {
oneline[openTag] = struct{}{}
}
Expand Down

0 comments on commit 1d08a46

Please sign in to comment.