新增: @use 同文件片段复用

支持 @use("name") 引用同一文件内 @tpl 定义的块,
消除 _list/_count 模板中 WHERE 条件重复问题。
This commit is contained in:
2026-04-01 01:59:51 +08:00
parent a6847c7d18
commit 1b5b6aff8f
7 changed files with 190 additions and 8 deletions

View File

@@ -96,6 +96,13 @@ func (p *Parser) Parse() ([]Node, error) {
}
nodes = append(nodes, node)
case TokUseStart:
node, err := p.parseUse(tok)
if err != nil {
return nil, err
}
nodes = append(nodes, node)
case TokElse:
return nil, fmt.Errorf("line %d, col %d: unexpected else", tok.Pos.Line, tok.Pos.Col)
@@ -521,6 +528,26 @@ func (p *Parser) expandInclude(tok Token) ([]Node, error) {
return subParser.Parse()
}
func (p *Parser) parseUse(tok Token) (*UseNode, error) {
runePos := p.runePosFromToken(tok)
name, quotePos, err := p.readUntilQuote(runePos)
if err != nil {
return nil, fmt.Errorf("line %d, col %d: unterminated @use name", tok.Pos.Line, tok.Pos.Col)
}
name = strings.TrimSpace(name)
endPos := quotePos + 1
if endPos < len(p.input) && p.input[endPos] == ')' {
endPos++
}
p.consumeTokensForRuneRange(runePos, endPos)
return &UseNode{
Pos: tok.Pos,
Name: name,
}, nil
}
func (p *Parser) parseNamespace(tok Token, nodeCount int) (*NamespaceNode, error) {
if nodeCount > 0 {
return nil, fmt.Errorf("line %d, col %d: @namespace must be at the top of the file", tok.Pos.Line, tok.Pos.Col)
@@ -695,6 +722,12 @@ func (p *Parser) parseBlockBodyWithElse(blockType string) ([]Node, []Node, []*El
return nil, nil, nil, err
}
body = append(body, subNodes...)
case TokUseStart:
node, err := p.parseUse(tok)
if err != nil {
return nil, nil, nil, err
}
body = append(body, node)
case TokNamespaceStart:
return nil, nil, nil, fmt.Errorf("line %d, col %d: @namespace must be at file top level", tok.Pos.Line, tok.Pos.Col)
}