mirror of
https://github.com/semihalev/twig.git
synced 2026-03-14 13:55:46 +01:00
Indent format fixes
This commit is contained in:
parent
529420e7f2
commit
0548a9d547
16 changed files with 465 additions and 465 deletions
|
|
@ -277,7 +277,7 @@ func (b *Buffer) WriteFloat(f float64, fmt byte, prec int) (n int, err error) {
|
|||
}
|
||||
|
||||
// Format fractional part, ensuring proper padding with zeros
|
||||
fracPart := int64((f - float64(intPart)) * float64(fracFactor) + 0.5) // Round
|
||||
fracPart := int64((f-float64(intPart))*float64(fracFactor) + 0.5) // Round
|
||||
if fracPart >= fracFactor {
|
||||
// Rounding caused carry
|
||||
fracPart = 0
|
||||
|
|
@ -344,7 +344,7 @@ func (b *Buffer) WriteFormat(format string, args ...interface{}) (n int, err err
|
|||
// It's an escaped %
|
||||
// Write everything up to and including the first %
|
||||
if i > startIdx {
|
||||
written, err := b.WriteString(format[startIdx:i+1])
|
||||
written, err := b.WriteString(format[startIdx : i+1])
|
||||
totalWritten += written
|
||||
if err != nil {
|
||||
return totalWritten, err
|
||||
|
|
@ -352,7 +352,7 @@ func (b *Buffer) WriteFormat(format string, args ...interface{}) (n int, err err
|
|||
}
|
||||
// Skip the second %
|
||||
i++
|
||||
startIdx = i+1
|
||||
startIdx = i + 1
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -423,7 +423,7 @@ func (b *Buffer) WriteFormat(format string, args ...interface{}) (n int, err err
|
|||
|
||||
// Move past the format specifier
|
||||
i++
|
||||
startIdx = i+1
|
||||
startIdx = i + 1
|
||||
}
|
||||
|
||||
// Write any remaining part of the format string
|
||||
|
|
|
|||
|
|
@ -91,11 +91,11 @@ func BenchmarkFloatFormatting(b *testing.B) {
|
|||
defer buf.Release()
|
||||
|
||||
vals := []float64{
|
||||
0.0, 1.0, -1.0, // Whole numbers
|
||||
3.14, -2.718, // Common constants
|
||||
123.456, -789.012, // Medium floats
|
||||
0.123, 0.001, 9.999, // Small decimals
|
||||
1234567.89, -9876543.21, // Large numbers
|
||||
0.0, 1.0, -1.0, // Whole numbers
|
||||
3.14, -2.718, // Common constants
|
||||
123.456, -789.012, // Medium floats
|
||||
0.123, 0.001, 9.999, // Small decimals
|
||||
1234567.89, -9876543.21, // Large numbers
|
||||
}
|
||||
|
||||
b.Run("OptimizedFloat", func(b *testing.B) {
|
||||
|
|
|
|||
2
expr.go
2
expr.go
|
|
@ -495,7 +495,7 @@ func ParseLiteralOptimized(expr string) (interface{}, bool) {
|
|||
|
||||
// Check for string literals
|
||||
if len(expr) >= 2 && ((expr[0] == '"' && expr[len(expr)-1] == '"') ||
|
||||
(expr[0] == '\'' && expr[len(expr)-1] == '\'')) {
|
||||
(expr[0] == '\'' && expr[len(expr)-1] == '\'')) {
|
||||
// String literal
|
||||
return expr[1 : len(expr)-1], true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ func BenchmarkExpressionRender(b *testing.B) {
|
|||
func BenchmarkFilterChain(b *testing.B) {
|
||||
engine := New()
|
||||
ctx := NewRenderContext(engine.environment, map[string]interface{}{
|
||||
"a": 10,
|
||||
"a": 10,
|
||||
"text": "Hello, World!",
|
||||
"html": "<p>This is a paragraph</p>",
|
||||
}, engine)
|
||||
|
|
@ -217,8 +217,8 @@ func BenchmarkFunctionCall(b *testing.B) {
|
|||
engine := New()
|
||||
ctx := NewRenderContext(engine.environment, map[string]interface{}{
|
||||
"numbers": []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
"start": 1,
|
||||
"end": 10,
|
||||
}, engine)
|
||||
defer ctx.Release()
|
||||
|
||||
|
|
|
|||
12
expr_pool.go
12
expr_pool.go
|
|
@ -465,11 +465,11 @@ func ReleaseHashMap(hashMap map[string]interface{}) {
|
|||
// Not using pool return for maps directly returned as results
|
||||
|
||||
/*
|
||||
switch {
|
||||
case len(hashMap) <= 5:
|
||||
smallHashMapPool.Put(hashMap)
|
||||
case len(hashMap) <= 15:
|
||||
mediumHashMapPool.Put(hashMap)
|
||||
}
|
||||
switch {
|
||||
case len(hashMap) <= 5:
|
||||
smallHashMapPool.Put(hashMap)
|
||||
case len(hashMap) <= 15:
|
||||
mediumHashMapPool.Put(hashMap)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -85,8 +85,8 @@ func (p *Parser) parseFrom(parser *Parser) (Node, error) {
|
|||
// Check for alias
|
||||
parser.tokenIndex++
|
||||
if parser.tokenIndex < len(parser.tokens) &&
|
||||
parser.tokens[parser.tokenIndex].Type == TOKEN_NAME &&
|
||||
parser.tokens[parser.tokenIndex].Value == "as" {
|
||||
parser.tokens[parser.tokenIndex].Type == TOKEN_NAME &&
|
||||
parser.tokens[parser.tokenIndex].Value == "as" {
|
||||
|
||||
// Skip 'as' keyword
|
||||
parser.tokenIndex++
|
||||
|
|
|
|||
22
render.go
22
render.go
|
|
@ -17,17 +17,17 @@ import (
|
|||
|
||||
// RenderContext holds the state during template rendering
|
||||
type RenderContext struct {
|
||||
env *Environment
|
||||
context map[string]interface{}
|
||||
blocks map[string][]Node
|
||||
parentBlocks map[string][]Node // Original block content from parent templates
|
||||
macros map[string]Node
|
||||
parent *RenderContext
|
||||
engine *Engine // Reference to engine for loading templates
|
||||
extending bool // Whether this template extends another
|
||||
currentBlock *BlockNode // Current block being rendered (for parent() function)
|
||||
inParentCall bool // Flag to indicate if we're currently rendering a parent() call
|
||||
sandboxed bool // Flag indicating if this context is sandboxed
|
||||
env *Environment
|
||||
context map[string]interface{}
|
||||
blocks map[string][]Node
|
||||
parentBlocks map[string][]Node // Original block content from parent templates
|
||||
macros map[string]Node
|
||||
parent *RenderContext
|
||||
engine *Engine // Reference to engine for loading templates
|
||||
extending bool // Whether this template extends another
|
||||
currentBlock *BlockNode // Current block being rendered (for parent() function)
|
||||
inParentCall bool // Flag to indicate if we're currently rendering a parent() call
|
||||
sandboxed bool // Flag indicating if this context is sandboxed
|
||||
lastLoadedTemplate *Template // The template that created this context (for resolving relative paths)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,10 +115,10 @@ func BenchmarkContextVariableLookup(b *testing.B) {
|
|||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// Test variable lookup at different levels
|
||||
level2.GetVariable("level2Var") // Local var
|
||||
level2.GetVariable("level1Var") // Parent var
|
||||
level2.GetVariable("rootVar") // Root var
|
||||
level2.GetVariable("shared") // Shadowed var
|
||||
level2.GetVariable("level2Var") // Local var
|
||||
level2.GetVariable("level1Var") // Parent var
|
||||
level2.GetVariable("rootVar") // Root var
|
||||
level2.GetVariable("shared") // Shadowed var
|
||||
level2.GetVariable("nonExistentVar") // Missing var
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,37 +12,37 @@ const (
|
|||
maxCacheableLength = 64 // Only cache strings shorter than this to avoid memory bloat
|
||||
|
||||
// Common HTML tags
|
||||
stringDiv = "div"
|
||||
stringSpan = "span"
|
||||
stringP = "p"
|
||||
stringA = "a"
|
||||
stringImg = "img"
|
||||
stringHref = "href"
|
||||
stringClass = "class"
|
||||
stringId = "id"
|
||||
stringStyle = "style"
|
||||
stringDiv = "div"
|
||||
stringSpan = "span"
|
||||
stringP = "p"
|
||||
stringA = "a"
|
||||
stringImg = "img"
|
||||
stringHref = "href"
|
||||
stringClass = "class"
|
||||
stringId = "id"
|
||||
stringStyle = "style"
|
||||
|
||||
// Common Twig syntax
|
||||
stringIf = "if"
|
||||
stringFor = "for"
|
||||
stringEnd = "end"
|
||||
stringEndif = "endif"
|
||||
stringEndfor = "endfor"
|
||||
stringElse = "else"
|
||||
stringBlock = "block"
|
||||
stringSet = "set"
|
||||
stringIf = "if"
|
||||
stringFor = "for"
|
||||
stringEnd = "end"
|
||||
stringEndif = "endif"
|
||||
stringEndfor = "endfor"
|
||||
stringElse = "else"
|
||||
stringBlock = "block"
|
||||
stringSet = "set"
|
||||
stringInclude = "include"
|
||||
stringExtends = "extends"
|
||||
stringMacro = "macro"
|
||||
stringMacro = "macro"
|
||||
|
||||
// Common operators
|
||||
stringEquals = "=="
|
||||
stringEquals = "=="
|
||||
stringNotEquals = "!="
|
||||
stringAnd = "and"
|
||||
stringOr = "or"
|
||||
stringNot = "not"
|
||||
stringIn = "in"
|
||||
stringIs = "is"
|
||||
stringAnd = "and"
|
||||
stringOr = "or"
|
||||
stringNot = "not"
|
||||
stringIn = "in"
|
||||
stringIs = "is"
|
||||
)
|
||||
|
||||
// GlobalStringCache provides a centralized cache for string interning
|
||||
|
|
@ -78,12 +78,12 @@ type TagLocation struct {
|
|||
// ZeroAllocTokenizer is an allocation-free tokenizer
|
||||
// It uses a pre-allocated token buffer for all token operations
|
||||
type ZeroAllocTokenizer struct {
|
||||
tokenBuffer []Token // Pre-allocated buffer of tokens
|
||||
source string // Source string being tokenized
|
||||
position int // Current position in source
|
||||
line int // Current line
|
||||
result []Token // Slice of actually used tokens
|
||||
tempStrings []string // String constants that we can reuse
|
||||
tokenBuffer []Token // Pre-allocated buffer of tokens
|
||||
source string // Source string being tokenized
|
||||
position int // Current position in source
|
||||
line int // Current line
|
||||
result []Token // Slice of actually used tokens
|
||||
tempStrings []string // String constants that we can reuse
|
||||
}
|
||||
|
||||
// This array contains commonly used strings in tokenization to avoid allocations
|
||||
|
|
@ -119,7 +119,7 @@ var tokenizerPool = sync.Pool{
|
|||
// Create a pre-allocated tokenizer with reasonable defaults
|
||||
return &TokenizerPooled{
|
||||
tokenizer: ZeroAllocTokenizer{
|
||||
tokenBuffer: make([]Token, 0, 256), // Buffer for tokens
|
||||
tokenBuffer: make([]Token, 0, 256), // Buffer for tokens
|
||||
tempStrings: append([]string{}, commonStrings...),
|
||||
result: nil,
|
||||
},
|
||||
|
|
@ -310,9 +310,9 @@ func (t *ZeroAllocTokenizer) TokenizeExpression(expr string) []Token {
|
|||
t.position++
|
||||
for t.position < len(t.source) &&
|
||||
((t.source[t.position] >= 'a' && t.source[t.position] <= 'z') ||
|
||||
(t.source[t.position] >= 'A' && t.source[t.position] <= 'Z') ||
|
||||
(t.source[t.position] >= '0' && t.source[t.position] <= '9') ||
|
||||
t.source[t.position] == '_') {
|
||||
(t.source[t.position] >= 'A' && t.source[t.position] <= 'Z') ||
|
||||
(t.source[t.position] >= '0' && t.source[t.position] <= '9') ||
|
||||
t.source[t.position] == '_') {
|
||||
t.position++
|
||||
}
|
||||
|
||||
|
|
@ -401,7 +401,7 @@ func (t *ZeroAllocTokenizer) TokenizeHtmlPreserving() ([]Token, error) {
|
|||
for i := 0; i < 5; i++ {
|
||||
pattern := tagPatterns[i]
|
||||
if len(remainingSource) >= len(pattern) &&
|
||||
remainingSource[:len(pattern)] == pattern {
|
||||
remainingSource[:len(pattern)] == pattern {
|
||||
// Tag found at current position
|
||||
nextTagPos = t.position
|
||||
tagType = tagTypes[i]
|
||||
|
|
@ -425,7 +425,7 @@ func (t *ZeroAllocTokenizer) TokenizeHtmlPreserving() ([]Token, error) {
|
|||
if nextTagPos != -1 && nextTagPos > 0 && t.source[nextTagPos-1] == '\\' {
|
||||
// Add text up to the backslash
|
||||
if nextTagPos-1 > t.position {
|
||||
preText := t.source[t.position:nextTagPos-1]
|
||||
preText := t.source[t.position : nextTagPos-1]
|
||||
t.AddToken(TOKEN_TEXT, preText, t.line)
|
||||
t.line += countNewlines(preText)
|
||||
}
|
||||
|
|
@ -522,7 +522,7 @@ func (t *ZeroAllocTokenizer) TokenizeHtmlPreserving() ([]Token, error) {
|
|||
}
|
||||
|
||||
// Get content between tags
|
||||
tagContent := t.source[t.position:t.position+endPos]
|
||||
tagContent := t.source[t.position : t.position+endPos]
|
||||
t.line += countNewlines(tagContent)
|
||||
|
||||
// Process tag content based on type
|
||||
|
|
@ -710,7 +710,7 @@ func (t *ZeroAllocTokenizer) processBlockTag(content string) {
|
|||
if strings.HasPrefix(contextExpr, "{") && strings.HasSuffix(contextExpr, "}") {
|
||||
// Context is an object literal
|
||||
t.AddToken(TOKEN_PUNCTUATION, "{", t.line)
|
||||
objectContent := contextExpr[1:len(contextExpr)-1]
|
||||
objectContent := contextExpr[1 : len(contextExpr)-1]
|
||||
t.tokenizeObjectContents(objectContent)
|
||||
t.AddToken(TOKEN_PUNCTUATION, "}", t.line)
|
||||
} else {
|
||||
|
|
@ -816,9 +816,9 @@ func (t *ZeroAllocTokenizer) tokenizeTemplatePath(path string) {
|
|||
|
||||
// If it's a quoted string
|
||||
if (strings.HasPrefix(path, "\"") && strings.HasSuffix(path, "\"")) ||
|
||||
(strings.HasPrefix(path, "'") && strings.HasSuffix(path, "'")) {
|
||||
(strings.HasPrefix(path, "'") && strings.HasSuffix(path, "'")) {
|
||||
// Extract content without quotes
|
||||
content := path[1:len(path)-1]
|
||||
content := path[1 : len(path)-1]
|
||||
t.AddToken(TOKEN_STRING, content, t.line)
|
||||
} else {
|
||||
// Otherwise tokenize as expression
|
||||
|
|
@ -852,7 +852,7 @@ func (t *ZeroAllocTokenizer) tokenizeObjectContents(content string) {
|
|||
if colonPos != -1 {
|
||||
// We have a key-value pair
|
||||
keyStr := strings.TrimSpace(content[start:colonPos])
|
||||
valueStr := strings.TrimSpace(content[colonPos+1:i])
|
||||
valueStr := strings.TrimSpace(content[colonPos+1 : i])
|
||||
|
||||
// Process key
|
||||
if (len(keyStr) >= 2 && keyStr[0] == '"' && keyStr[len(keyStr)-1] == '"') ||
|
||||
|
|
@ -984,8 +984,8 @@ func Intern(s string) string {
|
|||
// Fast path for very common strings to avoid lock contention
|
||||
switch s {
|
||||
case stringDiv, stringSpan, stringP, stringA, stringImg,
|
||||
stringIf, stringFor, stringEnd, stringEndif, stringEndfor,
|
||||
stringElse, "":
|
||||
stringIf, stringFor, stringEnd, stringEndif, stringEndfor,
|
||||
stringElse, "":
|
||||
return s
|
||||
}
|
||||
|
||||
|
|
@ -1139,7 +1139,7 @@ func (t *ZeroAllocTokenizer) TokenizeOptimized() ([]Token, error) {
|
|||
if tagLoc.Position > 0 && t.source[tagLoc.Position-1] == '\\' {
|
||||
// Add text up to the backslash
|
||||
if tagLoc.Position-1 > pos {
|
||||
preText := t.source[pos:tagLoc.Position-1]
|
||||
preText := t.source[pos : tagLoc.Position-1]
|
||||
t.AddToken(TOKEN_TEXT, preText, t.line)
|
||||
t.line += countNewlines(preText)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue