Skip to content

Commit 03f41e1

Browse files
committed
Parse type annotations correctly
1 parent 01af25c commit 03f41e1

File tree

4 files changed

+34
-31
lines changed

4 files changed

+34
-31
lines changed

variant.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ func MakeVariant(v interface{}) Variant {
2323
// https://developer.gnome.org/glib/unstable/gvariant-text.html. If sig is not
2424
// empty, it is taken to be the expected signature for the variant.
2525
func ParseVariant(s string, sig Signature) (Variant, error) {
26-
ch := varLex(s)
27-
p := &varParser{ch: ch}
26+
tokens := varLex(s)
27+
p := &varParser{tokens: tokens}
2828
n, err := varMakeNode(p)
2929
if err != nil {
3030
return Variant{}, err

variant_lexer.go

+17-16
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ type varLexer struct {
3939
start int
4040
pos int
4141
width int
42-
tokens chan varToken
42+
tokens []varToken
4343
}
4444

4545
type lexState func(*varLexer) lexState
4646

47-
func varLex(s string) chan varToken {
48-
l := &varLexer{input: s, tokens: make(chan varToken)}
49-
go l.run()
47+
func varLex(s string) []varToken {
48+
l := &varLexer{input: s}
49+
l.run()
5050
return l.tokens
5151
}
5252

@@ -63,15 +63,15 @@ func (l *varLexer) backup() {
6363
}
6464

6565
func (l *varLexer) emit(t varTokenType) {
66-
l.tokens <- varToken{t, l.input[l.start:l.pos]}
66+
l.tokens = append(l.tokens, varToken{t, l.input[l.start:l.pos]})
6767
l.start = l.pos
6868
}
6969

7070
func (l *varLexer) errorf(format string, v ...interface{}) lexState {
71-
l.tokens <- varToken{
71+
l.tokens = append(l.tokens, varToken{
7272
tokError,
7373
fmt.Sprintf(format, v...),
74-
}
74+
})
7575
return nil
7676
}
7777

@@ -95,7 +95,6 @@ func (l *varLexer) run() {
9595
for state := varLexNormal; state != nil; {
9696
state = state(l)
9797
}
98-
close(l.tokens)
9998
}
10099

101100
func (l *varLexer) peek() rune {
@@ -133,6 +132,11 @@ func varLexNormal(l *varLexer) lexState {
133132
case r == '@':
134133
l.backup()
135134
return varLexType
135+
case unicode.IsSpace(r):
136+
l.ignore()
137+
case unicode.IsNumber(r) || r == '+' || r == '-':
138+
l.backup()
139+
return varLexNumber
136140
case r == 'b':
137141
pos := l.start
138142
if n := l.peek(); n == '"' || n == '\'' {
@@ -141,28 +145,25 @@ func varLexNormal(l *varLexer) lexState {
141145
// not a byte string; try to parse it as a type or bool below
142146
l.pos = pos + 1
143147
l.width = 1
144-
case unicode.IsSpace(r):
145-
l.ignore()
146-
case unicode.IsNumber(r) || r == '+' || r == '-':
147-
l.backup()
148-
return varLexNumber
148+
fallthrough
149149
default:
150150
// either a bool or a type. Try bools first.
151151
l.backup()
152152
if l.pos+4 <= len(l.input) {
153153
if l.input[l.pos:l.pos+4] == "true" {
154154
l.pos += 4
155155
l.emit(tokBool)
156+
continue
156157
}
157158
} else if l.pos+5 <= len(l.input) {
158159
if l.input[l.pos:l.pos+5] == "false" {
159160
l.pos += 5
160161
l.emit(tokBool)
162+
continue
161163
}
162-
} else {
163-
// must be a type.
164-
return varLexType
165164
}
165+
// must be a type.
166+
return varLexType
166167
}
167168
}
168169
}

variant_parser.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ import (
1212
)
1313

1414
type varParser struct {
15-
ch chan varToken
16-
saved varToken
15+
tokens []varToken
16+
i int
1717
}
1818

19-
func (p *varParser) backup(t varToken) {
20-
p.saved = t
19+
func (p *varParser) backup() {
20+
p.i--
2121
}
2222

2323
func (p *varParser) next() varToken {
24-
if p.saved.typ != tokEOF {
25-
t := p.saved
26-
p.saved = varToken{}
24+
if p.i < len(p.tokens) {
25+
t := p.tokens[p.i]
26+
p.i++
2727
return t
2828
}
29-
return <-p.ch
29+
return varToken{typ: tokEOF}
3030
}
3131

3232
type varNode interface {
@@ -471,7 +471,7 @@ func varMakeArrayNode(p *varParser, sig Signature) (varNode, error) {
471471
if t := p.next(); t.typ == tokArrayEnd {
472472
return n, nil
473473
} else {
474-
p.backup(t)
474+
p.backup()
475475
}
476476
Loop:
477477
for {
@@ -482,7 +482,7 @@ Loop:
482482
case tokError:
483483
return nil, errors.New(t.val)
484484
}
485-
p.backup(t)
485+
p.backup()
486486
cn, err := varMakeNode(p)
487487
if err != nil {
488488
return nil, err
@@ -653,7 +653,7 @@ func varMakeDictNode(p *varParser, sig Signature) (varNode, error) {
653653
if t := p.next(); t.typ == tokDictEnd {
654654
return n, nil
655655
} else {
656-
p.backup(t)
656+
p.backup()
657657
}
658658
Loop:
659659
for {
@@ -664,7 +664,7 @@ Loop:
664664
case tokError:
665665
return nil, errors.New(t.val)
666666
}
667-
p.backup(t)
667+
p.backup()
668668
kn, err := varMakeNode(p)
669669
if err != nil {
670670
return nil, err
@@ -696,7 +696,7 @@ Loop:
696696
case tokError:
697697
return nil, errors.New(t.val)
698698
}
699-
p.backup(t)
699+
p.backup()
700700
vn, err := varMakeNode(p)
701701
if err != nil {
702702
return nil, err

variant_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var variantParseTests = []struct {
5454
{`b"abc"`, []byte{'a', 'b', 'c', 0}},
5555
{`b"\x01\0002\n"`, []byte{1, 2, '\n', 0}},
5656
{`[[0], b""]`, [][]byte{{0}, {0}}},
57+
{"int16 0", int16(0)},
58+
{"byte 0", byte(0)},
5759
}
5860

5961
func TestParseVariant(t *testing.T) {

0 commit comments

Comments
 (0)