From 566ea11db7bccb057e88e0bedf117e27452e72b0 Mon Sep 17 00:00:00 2001 From: Anmol Sethi Date: Sun, 22 Jan 2023 01:43:25 -0800 Subject: [PATCH] d2compiler: Integrate d2ir (wip) --- d2compiler/compile.go | 35 ++++++++++++++++++++++++++++++----- d2graph/d2graph.go | 14 +++++++++++--- d2ir/compile.go | 12 +++++++++--- d2ir/d2ir.go | 27 +++++++++++---------------- 4 files changed, 61 insertions(+), 27 deletions(-) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 9f4512dd5..c9d9b1604 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -123,7 +123,7 @@ func (c *compiler) compileMap(obj *d2graph.Object, m *d2ir.Map) { func (c *compiler) compileField(obj *d2graph.Object, f *d2ir.Field) { keyword := strings.ToLower(f.Name) - _, isReserved := d2graph.ReservedKeywords[keyword] + _, isReserved := d2graph.SimpleReservedKeywords[keyword] if isReserved { c.compileReserved(obj.Attributes, f) return @@ -142,6 +142,18 @@ func (c *compiler) compileField(obj *d2graph.Object, f *d2ir.Field) { if f.Map() != nil { c.compileMap(obj, f.Map()) } + + for _, er := range f.References { + obj.References = append(obj.References, d2graph.Reference{ + Key: er.KeyPath, + KeyPathIndex: er.KeyPathIndex(), + + MapKey: er.Context.Key, + MapKeyEdgeIndex: er.Context.EdgeIndex(), + Scope: er.Context.Scope, + ScopeObj: obj.Parent, + }) + } } func (c *compiler) compileLabel(attrs *d2graph.Attributes, f d2ir.Node) { @@ -246,13 +258,16 @@ func (c *compiler) compileStyleField(attrs *d2graph.Attributes, f *d2ir.Field) { if f.Primary() == nil { return } + compileStyleFieldInit(attrs, f) scalar := f.Primary().Value err := attrs.Style.Apply(f.Name, scalar.ScalarString()) if err != nil { c.errorf(scalar, err.Error()) return } +} +func compileStyleFieldInit(attrs *d2graph.Attributes, f *d2ir.Field) { switch f.Name { case "opacity": attrs.Style.Opacity = &d2graph.Scalar{MapKey: f.LastPrimaryKey()} @@ -315,11 +330,21 @@ func (c *compiler) compileEdge(obj *d2graph.Object, e *d2ir.Edge) { c.compileEdgeField(edge, f) } } + + for _, er := range e.References { + edge.References = append(edge.References, d2graph.EdgeReference{ + Edge: er.Context.Edge, + MapKey: er.Context.Key, + MapKeyEdgeIndex: er.Context.EdgeIndex(), + Scope: er.Context.Scope, + ScopeObj: obj, + }) + } } func (c *compiler) compileEdgeField(edge *d2graph.Edge, f *d2ir.Field) { keyword := strings.ToLower(f.Name) - _, isReserved := d2graph.ReservedKeywords[keyword] + _, isReserved := d2graph.SimpleReservedKeywords[keyword] if isReserved { c.compileReserved(edge.Attributes, f) return @@ -354,7 +379,7 @@ func (c *compiler) compileArrowheads(edge *d2graph.Edge, f *d2ir.Field) { for _, f2 := range f.Map().Fields { keyword := strings.ToLower(f2.Name) - _, isReserved := d2graph.ReservedKeywords[keyword] + _, isReserved := d2graph.SimpleReservedKeywords[keyword] if isReserved { c.compileReserved(attrs, f2) continue @@ -474,8 +499,8 @@ func (c *compiler) validateKeys(obj *d2graph.Object, m *d2ir.Map) { } func (c *compiler) validateKey(obj *d2graph.Object, f *d2ir.Field) { - keyword := strings.ToLower(f.Name) - _, isReserved := d2graph.ReservedKeywords[keyword] + keyword := strings.ToLower(f.Name) + _, isReserved := d2graph.SimpleReservedKeywords[keyword] if isReserved { switch obj.Attributes.Shape.Value { case d2target.ShapeSQLTable, d2target.ShapeClass: diff --git a/d2graph/d2graph.go b/d2graph/d2graph.go index 4984c1864..27a723923 100644 --- a/d2graph/d2graph.go +++ b/d2graph/d2graph.go @@ -987,7 +987,7 @@ func addSQLTableColumnIndexes(e *Edge, srcID, dstID []string, obj, src, dst *Obj } objAbsID := obj.AbsIDArray() srcAbsID := src.AbsIDArray() - if len(objAbsID) + len(srcID) > len(srcAbsID) { + if len(objAbsID)+len(srcID) > len(srcAbsID) { for i, d2col := range src.SQLTable.Columns { if d2col.Name.Label == srcID[len(srcID)-1] { d2col.Reference = dst.AbsID() @@ -1001,7 +1001,7 @@ func addSQLTableColumnIndexes(e *Edge, srcID, dstID []string, obj, src, dst *Obj if dst.Attributes.Shape.Value == d2target.ShapeSQLTable { objAbsID := obj.AbsIDArray() dstAbsID := dst.AbsIDArray() - if len(objAbsID) + len(dstID) > len(dstAbsID) { + if len(objAbsID)+len(dstID) > len(dstAbsID) { for i, d2col := range dst.SQLTable.Columns { if d2col.Name.Label == dstID[len(dstID)-1] { d2col.Reference = dst.AbsID() @@ -1284,7 +1284,11 @@ func Key(k *d2ast.KeyPath) []string { return d2format.KeyPath(k) } -var ReservedKeywords = map[string]struct{}{ +// All reserved keywords. See init below. +var ReservedKeywords map[string]struct{} + +// Non Style/Holder keywords. +var SimpleReservedKeywords = map[string]struct{}{ "label": {}, "desc": {}, "shape": {}, @@ -1351,6 +1355,10 @@ var NearConstantsArray = []string{ var NearConstants map[string]struct{} func init() { + ReservedKeywords = make(map[string]struct{}) + for k, v := range SimpleReservedKeywords { + ReservedKeywords[k] = v + } for k, v := range StyleKeywords { ReservedKeywords[k] = v } diff --git a/d2ir/compile.go b/d2ir/compile.go index 30f22bc49..80021a606 100644 --- a/d2ir/compile.go +++ b/d2ir/compile.go @@ -206,6 +206,10 @@ func (c *compiler) compileEdges(dst *Map, refctx *RefContext) { parent: e, Value: refctx.Key.Primary.Unbox(), } + } + if refctx.Key.Value.Array != nil { + c.errorf(refctx.Key.Value.Unbox(), "edges cannot be assigned arrays") + continue } else if refctx.Key.Value.Map != nil { if e.Map_ == nil { e.Map_ = &Map{ @@ -213,9 +217,11 @@ func (c *compiler) compileEdges(dst *Map, refctx *RefContext) { } } c.compileMap(e.Map_, refctx.Key.Value.Map) - } else if refctx.Key.Value.Unbox() != nil { - c.errorf(refctx.Key.Value.Unbox(), "edges cannot be assigned arrays") - continue + } else if refctx.Key.Value.ScalarBox().Unbox() != nil { + e.Primary_ = &Scalar{ + parent: e, + Value: refctx.Key.Value.ScalarBox().Unbox(), + } } } } diff --git a/d2ir/d2ir.go b/d2ir/d2ir.go index 15788ee3d..f73d0e7fd 100644 --- a/d2ir/d2ir.go +++ b/d2ir/d2ir.go @@ -105,12 +105,12 @@ func (n *Array) String() string { return d2format.Format(n.ast()) } func (n *Map) String() string { return d2format.Format(n.ast()) } func (n *Scalar) LastRef() Reference { return parentRef(n) } -func (n *Map) LastRef() Reference { return parentRef(n) } -func (n *Array) LastRef() Reference { return parentRef(n) } +func (n *Map) LastRef() Reference { return parentRef(n) } +func (n *Array) LastRef() Reference { return parentRef(n) } func (n *Scalar) LastPrimaryKey() *d2ast.Key { return parentPrimaryKey(n) } -func (n *Map) LastPrimaryKey() *d2ast.Key { return parentPrimaryKey(n) } -func (n *Array) LastPrimaryKey() *d2ast.Key { return parentPrimaryKey(n) } +func (n *Map) LastPrimaryKey() *d2ast.Key { return parentPrimaryKey(n) } +func (n *Array) LastPrimaryKey() *d2ast.Key { return parentPrimaryKey(n) } type Reference interface { reference() @@ -213,7 +213,7 @@ func NodeLayerKind(n Node) LayerKind { var f *Field switch n := n.(type) { case *Field: - f = ParentField(n) + f = n case *Map: f = ParentField(n) } @@ -540,7 +540,7 @@ func (rc *RefContext) EdgeIndex() int { return i } } - panic("d2ir.RefContext.EdgeIndex: Edge not in Key.Edges?") + return -1 } func (m *Map) FieldCountRecursive() int { @@ -909,7 +909,6 @@ func ParentMap(n Node) *Map { return m } } - return nil } func ParentField(n Node) *Field { @@ -922,20 +921,17 @@ func ParentField(n Node) *Field { return f } } - return nil } -func ParentLayer(n Node) *Map { +func ParentLayer(n Node) Node { for { - // ParentMap and not ParentField so we get the root layer too. - m := ParentMap(n) - if m == nil { + n = n.Parent() + if n == nil { return nil } - if NodeLayerKind(m) != "" { - return m + if NodeLayerKind(n) != "" { + return n } - n = m } } @@ -949,7 +945,6 @@ func ParentEdge(n Node) *Edge { return e } } - return nil } func countUnderscores(p []string) int {