aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ast
diff options
context:
space:
mode:
authorNecip Fazil Yildiran <necip@google.com>2020-08-10 14:43:38 +0000
committerDmitry Vyukov <dvyukov@google.com>2020-08-13 13:50:25 +0200
commitf5442bde55872d703f184f8617329f706bad8149 (patch)
tree14e121020d6aacd857b80351f01546818f19a74b /pkg/ast
parentee7cb8b69583db417b187b53f4765c3a403cd4cf (diff)
pkg, prog: add per-field direction attribute
Diffstat (limited to 'pkg/ast')
-rw-r--r--pkg/ast/ast.go1
-rw-r--r--pkg/ast/clone.go1
-rw-r--r--pkg/ast/format.go22
-rw-r--r--pkg/ast/parser.go19
-rw-r--r--pkg/ast/testdata/errors.txt13
-rw-r--r--pkg/ast/walk.go3
6 files changed, 44 insertions, 15 deletions
diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go
index c0707aca9..66dfc11bd 100644
--- a/pkg/ast/ast.go
+++ b/pkg/ast/ast.go
@@ -223,6 +223,7 @@ type Field struct {
Pos Pos
Name *Ident
Type *Type
+ Attrs []*Type
NewBlock bool // separated from previous fields by a new line
Comments []*Comment
}
diff --git a/pkg/ast/clone.go b/pkg/ast/clone.go
index ece4ba594..23e4f421c 100644
--- a/pkg/ast/clone.go
+++ b/pkg/ast/clone.go
@@ -168,6 +168,7 @@ func (n *Field) Clone() Node {
Pos: n.Pos,
Name: n.Name.Clone().(*Ident),
Type: n.Type.Clone().(*Type),
+ Attrs: cloneTypes(n.Attrs),
NewBlock: n.NewBlock,
Comments: cloneComments(n.Comments),
}
diff --git a/pkg/ast/format.go b/pkg/ast/format.go
index 3803d1e66..6b16f4015 100644
--- a/pkg/ast/format.go
+++ b/pkg/ast/format.go
@@ -113,11 +113,7 @@ func (n *Call) serialize(w io.Writer) {
fmt.Fprintf(w, " %v", fmtType(n.Ret))
}
if len(n.Attrs) != 0 {
- fmt.Fprintf(w, " (")
- for i, t := range n.Attrs {
- fmt.Fprintf(w, "%v%v", comma(i, ""), fmtType(t))
- }
- fmt.Fprintf(w, ")")
+ fmt.Fprintf(w, " %v", fmtTypeList(n.Attrs, "(", ")"))
}
fmt.Fprintf(w, "\n")
}
@@ -148,13 +144,17 @@ func (n *Struct) serialize(w io.Writer) {
for tabs := len(f.Name.Name)/tabWidth + 1; tabs < maxTabs; tabs++ {
fmt.Fprintf(w, "\t")
}
- fmt.Fprintf(w, "%v\n", fmtType(f.Type))
+ fmt.Fprintf(w, "%v", fmtType(f.Type))
+ if len(f.Attrs) != 0 {
+ fmt.Fprintf(w, "\t%v", fmtTypeList(f.Attrs, "(", ")"))
+ }
+ fmt.Fprintf(w, "\n")
}
for _, com := range n.Comments {
fmt.Fprintf(w, "#%v\n", com.Text)
}
fmt.Fprintf(w, "%c", closing)
- if attrs := fmtTypeList(n.Attrs); attrs != "" {
+ if attrs := fmtTypeList(n.Attrs, "[", "]"); attrs != "" {
fmt.Fprintf(w, " %v", attrs)
}
fmt.Fprintf(w, "\n")
@@ -197,20 +197,20 @@ func fmtType(t *Type) string {
for _, c := range t.Colon {
v += ":" + fmtType(c)
}
- v += fmtTypeList(t.Args)
+ v += fmtTypeList(t.Args, "[", "]")
return v
}
-func fmtTypeList(args []*Type) string {
+func fmtTypeList(args []*Type, opening, closing string) string {
if len(args) == 0 {
return ""
}
w := new(bytes.Buffer)
- fmt.Fprintf(w, "[")
+ fmt.Fprint(w, opening)
for i, t := range args {
fmt.Fprintf(w, "%v%v", comma(i, ""), fmtType(t))
}
- fmt.Fprintf(w, "]")
+ fmt.Fprint(w, closing)
return w.String()
}
diff --git a/pkg/ast/parser.go b/pkg/ast/parser.go
index 025c5dcc2..20898169e 100644
--- a/pkg/ast/parser.go
+++ b/pkg/ast/parser.go
@@ -290,7 +290,7 @@ func (p *parser) parseCall(name *Ident) *Call {
}
p.consume(tokLParen)
for p.tok != tokRParen {
- c.Args = append(c.Args, p.parseField())
+ c.Args = append(c.Args, p.parseField(false))
p.expect(tokComma, tokRParen)
p.tryConsume(tokComma)
}
@@ -376,7 +376,7 @@ func (p *parser) parseStruct(name *Ident) *Struct {
str.Comments = comments
break
}
- fld := p.parseField()
+ fld := p.parseField(true)
fld.NewBlock = newBlock
fld.Comments = comments
str.Fields = append(str.Fields, fld)
@@ -403,13 +403,24 @@ func (p *parser) parseCommentBlock() []*Comment {
return comments
}
-func (p *parser) parseField() *Field {
+func (p *parser) parseField(parseAttrs bool) *Field {
name := p.parseIdent()
- return &Field{
+
+ field := &Field{
Pos: name.Pos,
Name: name,
Type: p.parseType(),
}
+
+ if parseAttrs && p.tryConsume(tokLParen) {
+ field.Attrs = append(field.Attrs, p.parseType())
+ for p.tryConsume(tokComma) {
+ field.Attrs = append(field.Attrs, p.parseType())
+ }
+ p.consume(tokRParen)
+ }
+
+ return field
}
func (p *parser) parseType() *Type {
diff --git a/pkg/ast/testdata/errors.txt b/pkg/ast/testdata/errors.txt
index 30af16d9a..463158756 100644
--- a/pkg/ast/testdata/errors.txt
+++ b/pkg/ast/testdata/errors.txt
@@ -30,6 +30,7 @@ call() ("attr1")
call() (42)
call() ( ### unexpected '\n', expecting int, identifier, string
call() () ### unexpected ')', expecting int, identifier, string
+call(foo int32 (attr)) ### unexpected '(', expecting ',', ')'
define FOO bar
@@ -81,3 +82,15 @@ type templ_struct0[A, B] {
typ const[A, int16]
data B
} [align_4]
+
+s4 {
+ f0 int8 (attr)
+ f1 int8 (attr1, attr2[arg1, "arg2"])
+ f2 int8 ("attr1")
+}
+
+s5 {
+ f0 int8 ( ### unexpected '\n', expecting int, identifier, string
+
+s6 {
+ f0 int8 () ### unexpected ')', expecting int, identifier, string \ No newline at end of file
diff --git a/pkg/ast/walk.go b/pkg/ast/walk.go
index fe64b0676..84a3c67c3 100644
--- a/pkg/ast/walk.go
+++ b/pkg/ast/walk.go
@@ -118,6 +118,9 @@ func (n *Type) walk(cb func(Node)) {
func (n *Field) walk(cb func(Node)) {
cb(n.Name)
cb(n.Type)
+ for _, a := range n.Attrs {
+ cb(a)
+ }
for _, c := range n.Comments {
cb(c)
}