From e09e776964ab18e51a425fd870e30dd30c81be4d Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 15 May 2025 11:47:43 +0200 Subject: [PATCH 1/4] parser: remove String() method from tokenType tbh, I see no reason why this should be there except debugging purpose. If this is the case, we could use stringer --- parser.go | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/parser.go b/parser.go index e4ff88b..69715e6 100644 --- a/parser.go +++ b/parser.go @@ -57,7 +57,7 @@ func (t *tokenizer) next() (tokenEntry, error) { } value := t.s.TokenText() pos := t.s.Pos() - if newTokenType(value).String() == "STYLE_SEPARATOR" { + if newTokenType(value) == tokenStyleSeparator { t.s.IsIdentRune = func(ch rune, i int) bool { // property value can contain spaces if ch == -1 || ch == '\n' || ch == '\r' || ch == '\t' || ch == ':' || ch == ';' { return false @@ -78,22 +78,6 @@ func (t *tokenizer) next() (tokenEntry, error) { }, nil } -func (t tokenType) String() string { - switch t { - case tokenBlockStart: - return "BLOCK_START" - case tokenBlockEnd: - return "BLOCK_END" - case tokenStyleSeparator: - return "STYLE_SEPARATOR" - case tokenStatementEnd: - return "STATEMENT_END" - case tokenSelector: - return "SELECTOR" - } - return "VALUE" -} - func newTokenType(typ string) tokenType { switch typ { case "{": From 165736652ca607f9d49c56107eaaa8de2a7d6709 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 15 May 2025 11:48:48 +0200 Subject: [PATCH 2/4] add stringer command on tokenType type --- parser.go | 2 ++ tokentype_string.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tokentype_string.go diff --git a/parser.go b/parser.go index 69715e6..8a7b20a 100644 --- a/parser.go +++ b/parser.go @@ -10,6 +10,8 @@ import ( "text/scanner" ) +//go:generate stringer -type=tokenType + type tokenType int const ( diff --git a/tokentype_string.go b/tokentype_string.go new file mode 100644 index 0000000..c6840e4 --- /dev/null +++ b/tokentype_string.go @@ -0,0 +1,31 @@ +// Code generated by "stringer -type=tokenType"; DO NOT EDIT. + +package css + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[tokenFirstToken - -1] + _ = x[tokenBlockStart-0] + _ = x[tokenBlockEnd-1] + _ = x[tokenRuleName-2] + _ = x[tokenValue-3] + _ = x[tokenSelector-4] + _ = x[tokenStyleSeparator-5] + _ = x[tokenStatementEnd-6] +} + +const _tokenType_name = "tokenFirstTokentokenBlockStarttokenBlockEndtokenRuleNametokenValuetokenSelectortokenStyleSeparatortokenStatementEnd" + +var _tokenType_index = [...]uint8{0, 15, 30, 43, 56, 66, 79, 98, 115} + +func (i tokenType) String() string { + i -= -1 + if i < 0 || i >= tokenType(len(_tokenType_index)-1) { + return "tokenType(" + strconv.FormatInt(int64(i+-1), 10) + ")" + } + return _tokenType_name[_tokenType_index[i]:_tokenType_index[i+1]] +} From 19d06c1c4bbefe01a9a24bfaa15fccbf9dcdf05f Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 15 May 2025 11:59:30 +0200 Subject: [PATCH 3/4] parser: reorder code also replace one switch-case with a mapa --- parser.go | 71 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/parser.go b/parser.go index 8a7b20a..6ae246e 100644 --- a/parser.go +++ b/parser.go @@ -25,33 +25,46 @@ const ( tokenStatementEnd ) -// Rule is a string type that represents a CSS rule. -type Rule string - type tokenEntry struct { value string pos scanner.Position } -type tokenizer struct { - s *scanner.Scanner -} - -// Type returns the rule type, which can be a class, id or a tag. -func (rule Rule) Type() string { - if strings.HasPrefix(string(rule), ".") { - return "class" +func newTokenType(typ string) tokenType { + types := map[string]tokenType{ + "{": tokenBlockStart, + "}": tokenBlockEnd, + ":": tokenStyleSeparator, + ";": tokenStatementEnd, + ".": tokenSelector, + "#": tokenSelector, } - if strings.HasPrefix(string(rule), "#") { - return "id" + + result, ok := types[typ] + if ok { + return result } - return "tag" + + return tokenValue } func (e tokenEntry) typ() tokenType { return newTokenType(e.value) } +type tokenizer struct { + s *scanner.Scanner +} + +func newTokenizer(r io.Reader) *tokenizer { + s := &scanner.Scanner{} + s.Init(r) + + return &tokenizer{ + s: s, + } +} + func (t *tokenizer) next() (tokenEntry, error) { token := t.s.Scan() if token == scanner.EOF { @@ -80,28 +93,18 @@ func (t *tokenizer) next() (tokenEntry, error) { }, nil } -func newTokenType(typ string) tokenType { - switch typ { - case "{": - return tokenBlockStart - case "}": - return tokenBlockEnd - case ":": - return tokenStyleSeparator - case ";": - return tokenStatementEnd - case ".", "#": - return tokenSelector - } - return tokenValue -} +// Rule is a string type that represents a CSS rule. +type Rule string -func newTokenizer(r io.Reader) *tokenizer { - s := &scanner.Scanner{} - s.Init(r) - return &tokenizer{ - s: s, +// Type returns the rule type, which can be a class, id or a tag. +func (rule Rule) Type() string { + if strings.HasPrefix(string(rule), ".") { + return "class" + } + if strings.HasPrefix(string(rule), "#") { + return "id" } + return "tag" } func buildList(r io.Reader) *list.List { From af1053545beaae02b3bff6a8c9627b1f1e102108 Mon Sep 17 00:00:00 2001 From: gucio321 Date: Thu, 15 May 2025 14:10:51 +0200 Subject: [PATCH 4/4] fix test case name --- parser_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser_test.go b/parser_test.go index 938aa11..16ad22a 100644 --- a/parser_test.go +++ b/parser_test.go @@ -78,7 +78,7 @@ rule1 { } for _, tt := range cases { - t.Run("GoodCSS", func(t *testing.T) { + t.Run(tt.name, func(t *testing.T) { css, err := Unmarshal([]byte(tt.CSS)) if err != nil { t.Fatal(err)