d2ir: IR Root wip
This commit is contained in:
parent
748557d8f2
commit
7d89174a1b
2 changed files with 38 additions and 18 deletions
|
|
@ -292,6 +292,13 @@ func testCompileLayers(t *testing.T) {
|
||||||
assert.ErrorString(t, err, `TestCompile/layer/errs/bad_edge/2.d2:1:1: cannot create edges between layers, scenarios or steps`)
|
assert.ErrorString(t, err, `TestCompile/layer/errs/bad_edge/2.d2:1:1: cannot create edges between layers, scenarios or steps`)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "bad_edge/3",
|
||||||
|
run: func(t testing.TB) {
|
||||||
|
_, err := compile(t, `layers.x.y -> steps.z.p`)
|
||||||
|
assert.ErrorString(t, err, `TestCompile/layer/errs/bad_edge/3.d2:1:1: cannot create edges between layers, scenarios or steps`)
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
runa(t, tca)
|
runa(t, tca)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
47
d2ir/d2ir.go
47
d2ir/d2ir.go
|
|
@ -110,6 +110,9 @@ func (m *Map) Copy(newp Node) Node {
|
||||||
m.parent = newp
|
m.parent = newp
|
||||||
m.Fields = append([]*Field(nil), m.Fields...)
|
m.Fields = append([]*Field(nil), m.Fields...)
|
||||||
for i := range m.Fields {
|
for i := range m.Fields {
|
||||||
|
if hasLayerKeywords(m.Fields[i].Name) != -1 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
m.Fields[i] = m.Fields[i].Copy(m).(*Field)
|
m.Fields[i] = m.Fields[i].Copy(m).(*Field)
|
||||||
}
|
}
|
||||||
m.Edges = append([]*Edge(nil), m.Edges...)
|
m.Edges = append([]*Edge(nil), m.Edges...)
|
||||||
|
|
@ -124,25 +127,38 @@ func (m *Map) Root() bool {
|
||||||
return m.parent == nil
|
return m.parent == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layer reports whether n represents the root of a layer.
|
type LayerKind string
|
||||||
func IsLayer(n Node) bool {
|
|
||||||
|
const (
|
||||||
|
LayerLayer LayerKind = "layer"
|
||||||
|
LayerScenario LayerKind = "scenario"
|
||||||
|
LayerStep LayerKind = "step"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NodeLayerKind reports whether n represents the root of a layer.
|
||||||
|
// n should be *Field or *Map
|
||||||
|
func NodeLayerKind(n Node) LayerKind {
|
||||||
switch n := n.(type) {
|
switch n := n.(type) {
|
||||||
case *Field:
|
case *Field:
|
||||||
n = ParentField(n)
|
n = ParentField(n)
|
||||||
if n != nil {
|
if n != nil {
|
||||||
switch n.Name {
|
switch n.Name {
|
||||||
case "layers", "scenarios", "steps":
|
case "layers":
|
||||||
return true
|
return LayerLayer
|
||||||
|
case "scenarios":
|
||||||
|
return LayerScenario
|
||||||
|
case "steps":
|
||||||
|
return LayerStep
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case *Map:
|
case *Map:
|
||||||
f := ParentField(n)
|
f := ParentField(n)
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return true
|
return LayerLayer
|
||||||
}
|
}
|
||||||
return IsLayer(f)
|
return NodeLayerKind(f)
|
||||||
}
|
}
|
||||||
return false
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
type Field struct {
|
type Field struct {
|
||||||
|
|
@ -485,12 +501,9 @@ func (m *Map) ensureField(i int, kp *d2ast.KeyPath, refctx *RefContext) (*Field,
|
||||||
return nil, d2parser.Errorf(kp.Path[i].Unbox(), `parent "_" can only be used in the beginning of paths, e.g. "_.x"`)
|
return nil, d2parser.Errorf(kp.Path[i].Unbox(), `parent "_" can only be used in the beginning of paths, e.g. "_.x"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch head {
|
if hasLayerKeywords(head) != -1 && NodeLayerKind(m) == "" {
|
||||||
case "layers", "scenarios", "steps":
|
|
||||||
if !IsLayer(m) {
|
|
||||||
return nil, d2parser.Errorf(kp.Path[i].Unbox(), "%s is only allowed at a layer root", head)
|
return nil, d2parser.Errorf(kp.Path[i].Unbox(), "%s is only allowed at a layer root", head)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for _, f := range m.Fields {
|
for _, f := range m.Fields {
|
||||||
if !strings.EqualFold(f.Name, head) {
|
if !strings.EqualFold(f.Name, head) {
|
||||||
|
|
@ -617,20 +630,20 @@ func (m *Map) CreateEdge(eid *EdgeID, refctx *RefContext) (*Edge, error) {
|
||||||
return f_m.CreateEdge(eid, refctx)
|
return f_m.CreateEdge(eid, refctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
ij := hasLayerKeyword(eid.SrcPath)
|
ij := hasLayerKeywords(eid.SrcPath...)
|
||||||
if ij != -1 {
|
if ij != -1 {
|
||||||
return nil, d2parser.Errorf(refctx.Edge.Src.Path[ij].Unbox(), "cannot create edges between layers, scenarios or steps")
|
return nil, d2parser.Errorf(refctx.Edge.Src.Path[ij].Unbox(), "cannot create edges between layers, scenarios or steps")
|
||||||
}
|
}
|
||||||
src := m.GetField(eid.SrcPath...)
|
src := m.GetField(eid.SrcPath...)
|
||||||
if IsLayer(src) {
|
if NodeLayerKind(src) != "" {
|
||||||
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot create edges between layers, scenarios or steps")
|
return nil, d2parser.Errorf(refctx.Edge.Src, "cannot create edges between layers, scenarios or steps")
|
||||||
}
|
}
|
||||||
ij = hasLayerKeyword(eid.DstPath)
|
ij = hasLayerKeywords(eid.DstPath...)
|
||||||
if ij != -1 {
|
if ij != -1 {
|
||||||
return nil, d2parser.Errorf(refctx.Edge.Dst.Path[ij].Unbox(), "cannot create edges between layers, scenarios or steps")
|
return nil, d2parser.Errorf(refctx.Edge.Dst.Path[ij].Unbox(), "cannot create edges between layers, scenarios or steps")
|
||||||
}
|
}
|
||||||
dst := m.GetField(eid.DstPath...)
|
dst := m.GetField(eid.DstPath...)
|
||||||
if IsLayer(dst) {
|
if NodeLayerKind(dst) != "" {
|
||||||
return nil, d2parser.Errorf(refctx.Edge.Dst, "cannot create edges between layers, scenarios or steps")
|
return nil, d2parser.Errorf(refctx.Edge.Dst, "cannot create edges between layers, scenarios or steps")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -804,7 +817,7 @@ func ParentLayer(n Node) Node {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if IsLayer(m) {
|
if NodeLayerKind(m) != "" {
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
n = m
|
n = m
|
||||||
|
|
@ -822,7 +835,7 @@ func countUnderscores(p []string) int {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasLayerKeyword(ida []string) int {
|
func hasLayerKeywords(ida ...string) int {
|
||||||
for i := range ida {
|
for i := range ida {
|
||||||
switch ida[i] {
|
switch ida[i] {
|
||||||
case "layers", "scenarios", "steps":
|
case "layers", "scenarios", "steps":
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue