diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-01-05 20:05:11 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-01-11 16:30:08 +0100 |
| commit | 2cfe62f82077ba012aef55db5288985bc0c426d9 (patch) | |
| tree | 501d83deb358a230d157c9d7efc6fc393e239472 /pkg/compiler/check.go | |
| parent | 16e21d13ea26a631e9b3a30c94635b1d565fd78f (diff) | |
pkg/compiler: add out_overlay field attribute
Diffstat (limited to 'pkg/compiler/check.go')
| -rw-r--r-- | pkg/compiler/check.go | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/pkg/compiler/check.go b/pkg/compiler/check.go index c5fc226d6..676b96c5c 100644 --- a/pkg/compiler/check.go +++ b/pkg/compiler/check.go @@ -182,13 +182,33 @@ func (comp *compiler) checkStructFields(n *ast.Struct, typ, name string) { if len(n.Fields) < 1 { comp.error(n.Pos, "%v %v has no fields, need at least 1 field", typ, name) } - for _, f := range n.Fields { + hasDirections, hasOutOverlay := false, false + for fieldIdx, f := range n.Fields { attrs := comp.parseAttrs(fieldAttrs, f, f.Attrs) - - if attrs[attrIn]+attrs[attrOut]+attrs[attrInOut] > 1 { + dirCount := attrs[attrIn] + attrs[attrOut] + attrs[attrInOut] + if dirCount != 0 { + hasDirections = true + } + if dirCount > 1 { _, typ, _ := f.Info() comp.error(f.Pos, "%v has multiple direction attributes", typ) } + if attrs[attrOutOverlay] > 0 { + if n.IsUnion { + _, typ, name := f.Info() + comp.error(f.Pos, "unknown %v %v attribute %v", typ, name, attrOutOverlay.Name) + } + if fieldIdx == 0 { + comp.error(f.Pos, "%v attribute must not be specified on the first field", attrOutOverlay.Name) + } + if hasOutOverlay || attrs[attrOutOverlay] > 1 { + comp.error(f.Pos, "multiple %v attributes", attrOutOverlay.Name) + } + hasOutOverlay = true + } + if hasDirections && hasOutOverlay { + comp.error(f.Pos, "mix of direction and %v attributes is not supported", attrOutOverlay.Name) + } } } @@ -301,12 +321,22 @@ func (comp *compiler) checkAttributeValues() { } // Check each field's attributes. st := decl.(*ast.Struct) + hasOutOverlay := false for _, f := range st.Fields { + isOut := hasOutOverlay for _, attr := range f.Attrs { desc := fieldAttrs[attr.Ident] if desc.CheckConsts != nil { desc.CheckConsts(comp, f, attr) } + switch attr.Ident { + case attrOutOverlay.Name: + hasOutOverlay = true + isOut = true + } + } + if isOut && comp.getTypeDesc(f.Type).CantBeOut { + comp.error(f.Pos, "%v type must not be used as output", f.Type.Ident) } } } |
