unsuspend ancestors

This commit is contained in:
Alexander Wang 2025-03-12 16:05:08 -06:00
parent b175c0370c
commit c25d313511
No known key found for this signature in database
GPG key ID: BE3937D0D52D8927
3 changed files with 575 additions and 2 deletions

View file

@ -5648,6 +5648,24 @@ a -> b
assert.Equal(t, 0, len(g.Edges))
},
},
{
name: "unsuspend-edge-child",
run: func(t *testing.T) {
g, _ := assertCompile(t, `
a: {
b -> c
}
**: suspend
(** -> **)[*]: suspend
(** -> **)[*]: unsuspend {
&dst: a.c
}
`, ``)
assert.Equal(t, 3, len(g.Objects))
assert.Equal(t, 1, len(g.Edges))
},
},
{
name: "unsuspend-shape-label",
run: func(t *testing.T) {

View file

@ -869,6 +869,22 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
for _, part := range edge.ID.SrcPath {
srcParts = append(srcParts, part.ScalarString())
}
container := ParentField(edge)
if container != nil && container.Name.ScalarString() != "root" {
containerPath := []string{}
curr := container
for curr != nil && curr.Name.ScalarString() != "root" {
containerPath = append([]string{curr.Name.ScalarString()}, containerPath...)
curr = ParentField(curr)
}
srcStart := srcParts[0]
if !strings.EqualFold(srcStart, containerPath[0]) {
srcParts = append(containerPath, srcParts...)
}
}
srcPath := strings.Join(srcParts, ".")
return srcPath == filterValue
@ -889,6 +905,23 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
for _, part := range edge.ID.DstPath {
dstParts = append(dstParts, part.ScalarString())
}
// Find the container that holds this edge
// Build the absolute path by prepending the container's path
container := ParentField(edge)
if container != nil && container.Name.ScalarString() != "root" {
containerPath := []string{}
curr := container
for curr != nil && curr.Name.ScalarString() != "root" {
containerPath = append([]string{curr.Name.ScalarString()}, containerPath...)
curr = ParentField(curr)
}
dstStart := dstParts[0]
if !strings.EqualFold(dstStart, containerPath[0]) {
dstParts = append(containerPath, dstParts...)
}
}
dstPath := strings.Join(dstParts, ".")
return dstPath == filterValue
@ -1298,16 +1331,48 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
e.suspended = suspensionValue
// If we're unsuspending an edge, we should also unsuspend its src and dst objects
// And their ancestors
if !suspensionValue {
srcPath, dstPath := e.ID.SrcPath, e.ID.DstPath
srcObj := refctx.ScopeMap.GetField(srcPath...)
dstObj := refctx.ScopeMap.GetField(dstPath...)
container := ParentField(e)
if container != nil && container.Name.ScalarString() != "root" {
containerPath := []d2ast.String{}
curr := container
for curr != nil && curr.Name.ScalarString() != "root" {
containerPath = append([]d2ast.String{curr.Name}, containerPath...)
curr = ParentField(curr)
}
if len(srcPath) > 0 && !strings.EqualFold(srcPath[0].ScalarString(), containerPath[0].ScalarString()) {
absSrcPath := append([]d2ast.String{}, containerPath...)
srcPath = append(absSrcPath, srcPath...)
}
if len(dstPath) > 0 && !strings.EqualFold(dstPath[0].ScalarString(), containerPath[0].ScalarString()) {
absDstPath := append([]d2ast.String{}, containerPath...)
dstPath = append(absDstPath, dstPath...)
}
}
rootMap := RootMap(refctx.ScopeMap)
srcObj := rootMap.GetField(srcPath...)
dstObj := rootMap.GetField(dstPath...)
if srcObj != nil {
srcObj.suspended = false
parent := ParentField(srcObj)
for parent != nil && parent.Name.ScalarString() != "root" {
parent.suspended = false
parent = ParentField(parent)
}
}
if dstObj != nil {
dstObj.suspended = false
parent := ParentField(srcObj)
for parent != nil && parent.Name.ScalarString() != "root" {
parent.suspended = false
parent = ParentField(parent)
}
}
}
}

View file

@ -0,0 +1,490 @@
{
"graph": {
"name": "",
"isFolderOnly": false,
"ast": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,0:0:0-10:0:94",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-3:1:16",
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
}
]
},
"primary": {},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:3:4-3:1:16",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14",
"edges": [
{
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:8:14",
"src": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9",
"value": [
{
"string": "b",
"raw_string": "b"
}
]
}
}
]
},
"src_arrow": "",
"dst": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14",
"value": [
{
"string": "c",
"raw_string": "c"
}
]
}
}
]
},
"dst_arrow": ">"
}
],
"primary": {},
"value": {}
}
}
]
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:11:29",
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:0:18-5:2:20",
"value": [
{
"string": "**",
"raw_string": "**"
}
],
"pattern": [
"*",
"",
"*"
]
}
}
]
},
"primary": {},
"value": {
"suspension": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,5:4:22-5:11:29",
"value": true
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:0:30-6:22:52",
"edges": [
{
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:9:39",
"src": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:1:31-6:3:33",
"value": [
{
"string": "**",
"raw_string": "**"
}
],
"pattern": [
"*",
"",
"*"
]
}
}
]
},
"src_arrow": "",
"dst": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:7:37-6:9:39",
"value": [
{
"string": "**",
"raw_string": "**"
}
],
"pattern": [
"*",
"",
"*"
]
}
}
]
},
"dst_arrow": ">"
}
],
"edge_index": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:10:40-6:13:43",
"int": null,
"glob": true
},
"primary": {},
"value": {
"suspension": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,6:15:45-6:22:52",
"value": true
}
}
}
},
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:0:53-9:1:93",
"edges": [
{
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:9:62",
"src": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:1:54-7:3:56",
"value": [
{
"string": "**",
"raw_string": "**"
}
],
"pattern": [
"*",
"",
"*"
]
}
}
]
},
"src_arrow": "",
"dst": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:7:60-7:9:62",
"value": [
{
"string": "**",
"raw_string": "**"
}
],
"pattern": [
"*",
"",
"*"
]
}
}
]
},
"dst_arrow": ">"
}
],
"edge_index": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:10:63-7:13:66",
"int": null,
"glob": true
},
"primary": {
"suspension": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:15:68-7:24:77",
"value": false
}
},
"value": {
"map": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,7:25:78-9:1:93",
"nodes": [
{
"map_key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:2:82-8:11:91",
"ampersand": true,
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:3:83-8:6:86",
"value": [
{
"string": "dst",
"raw_string": "dst"
}
]
}
}
]
},
"primary": {},
"value": {
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,8:8:88-8:11:91",
"value": [
{
"string": "a.c",
"raw_string": "a.c"
}
]
}
}
}
}
]
}
}
}
}
]
},
"root": {
"id": "",
"id_val": "",
"attributes": {
"label": {
"value": ""
},
"labelDimensions": {
"width": 0,
"height": 0
},
"style": {},
"near_key": null,
"shape": {
"value": ""
},
"direction": {
"value": ""
},
"constraint": null
},
"zIndex": 0
},
"edges": [
{
"index": 0,
"isCurve": false,
"src_arrow": false,
"dst_arrow": true,
"references": [
{
"map_key_edge_index": 0
},
{
"map_key_edge_index": 0
},
{
"map_key_edge_index": 0
}
],
"attributes": {
"label": {
"value": ""
},
"labelDimensions": {
"width": 0,
"height": 0
},
"style": {},
"near_key": null,
"shape": {
"value": ""
},
"direction": {
"value": ""
},
"constraint": null
},
"zIndex": 0
}
],
"objects": [
{
"id": "a",
"id_val": "a",
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,1:0:1-1:1:2",
"value": [
{
"string": "a",
"raw_string": "a"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": -1
}
],
"attributes": {
"label": {
"value": "a"
},
"labelDimensions": {
"width": 0,
"height": 0
},
"style": {},
"near_key": null,
"shape": {
"value": "rectangle"
},
"direction": {
"value": ""
},
"constraint": null
},
"zIndex": 0
},
{
"id": "b",
"id_val": "b",
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:2:8-2:3:9",
"value": [
{
"string": "b",
"raw_string": "b"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
}
],
"attributes": {
"label": {
"value": "b"
},
"labelDimensions": {
"width": 0,
"height": 0
},
"style": {},
"near_key": null,
"shape": {
"value": "rectangle"
},
"direction": {
"value": ""
},
"constraint": null
},
"zIndex": 0
},
{
"id": "c",
"id_val": "c",
"references": [
{
"key": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14",
"path": [
{
"unquoted_string": {
"range": "d2/testdata/d2compiler/TestCompile2/globs/unsuspend-edge-child.d2,2:7:13-2:8:14",
"value": [
{
"string": "c",
"raw_string": "c"
}
]
}
}
]
},
"key_path_index": 0,
"map_key_edge_index": 0
}
],
"attributes": {
"label": {
"value": "c"
},
"labelDimensions": {
"width": 0,
"height": 0
},
"style": {},
"near_key": null,
"shape": {
"value": "rectangle"
},
"direction": {
"value": ""
},
"constraint": null
},
"zIndex": 0
}
]
},
"err": null
}