@@ -869,6 +869,22 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
869
869
for _ , part := range edge .ID .SrcPath {
870
870
srcParts = append (srcParts , part .ScalarString ())
871
871
}
872
+
873
+ container := ParentField (edge )
874
+ if container != nil && container .Name .ScalarString () != "root" {
875
+ containerPath := []string {}
876
+ curr := container
877
+ for curr != nil && curr .Name .ScalarString () != "root" {
878
+ containerPath = append ([]string {curr .Name .ScalarString ()}, containerPath ... )
879
+ curr = ParentField (curr )
880
+ }
881
+
882
+ srcStart := srcParts [0 ]
883
+ if ! strings .EqualFold (srcStart , containerPath [0 ]) {
884
+ srcParts = append (containerPath , srcParts ... )
885
+ }
886
+ }
887
+
872
888
srcPath := strings .Join (srcParts , "." )
873
889
874
890
return srcPath == filterValue
@@ -889,6 +905,23 @@ func (c *compiler) ampersandFilter(refctx *RefContext) bool {
889
905
for _ , part := range edge .ID .DstPath {
890
906
dstParts = append (dstParts , part .ScalarString ())
891
907
}
908
+
909
+ // Find the container that holds this edge
910
+ // Build the absolute path by prepending the container's path
911
+ container := ParentField (edge )
912
+ if container != nil && container .Name .ScalarString () != "root" {
913
+ containerPath := []string {}
914
+ curr := container
915
+ for curr != nil && curr .Name .ScalarString () != "root" {
916
+ containerPath = append ([]string {curr .Name .ScalarString ()}, containerPath ... )
917
+ curr = ParentField (curr )
918
+ }
919
+
920
+ dstStart := dstParts [0 ]
921
+ if ! strings .EqualFold (dstStart , containerPath [0 ]) {
922
+ dstParts = append (containerPath , dstParts ... )
923
+ }
924
+ }
892
925
dstPath := strings .Join (dstParts , "." )
893
926
894
927
return dstPath == filterValue
@@ -1273,8 +1306,37 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
1273
1306
continue
1274
1307
}
1275
1308
1309
+ if refctx .Key .Value .Map != nil && refctx .Key .Value .Map .HasFilter () {
1310
+ if e .Map_ == nil {
1311
+ e .Map_ = & Map {
1312
+ parent : e ,
1313
+ }
1314
+ }
1315
+ c .mapRefContextStack = append (c .mapRefContextStack , refctx )
1316
+ ok := c .ampersandFilterMap (e .Map_ , refctx .Key .Value .Map , refctx .ScopeAST )
1317
+ c .mapRefContextStack = c .mapRefContextStack [:len (c .mapRefContextStack )- 1 ]
1318
+ if ! ok {
1319
+ continue
1320
+ }
1321
+ }
1322
+
1276
1323
if refctx .Key .Primary .Suspension != nil || refctx .Key .Value .Suspension != nil {
1277
1324
if ! c .lazyGlobBeingApplied {
1325
+ // Check if edge passes filter before applying suspension
1326
+ if refctx .Key .Value .Map != nil && refctx .Key .Value .Map .HasFilter () {
1327
+ if e .Map_ == nil {
1328
+ e .Map_ = & Map {
1329
+ parent : e ,
1330
+ }
1331
+ }
1332
+ c .mapRefContextStack = append (c .mapRefContextStack , refctx )
1333
+ ok := c .ampersandFilterMap (e .Map_ , refctx .Key .Value .Map , refctx .ScopeAST )
1334
+ c .mapRefContextStack = c .mapRefContextStack [:len (c .mapRefContextStack )- 1 ]
1335
+ if ! ok {
1336
+ continue
1337
+ }
1338
+ }
1339
+
1278
1340
var suspensionValue bool
1279
1341
if refctx .Key .Primary .Suspension != nil {
1280
1342
suspensionValue = refctx .Key .Primary .Suspension .Value
@@ -1284,16 +1346,53 @@ func (c *compiler) _compileEdges(refctx *RefContext) {
1284
1346
e .suspended = suspensionValue
1285
1347
1286
1348
// If we're unsuspending an edge, we should also unsuspend its src and dst objects
1349
+ // And their ancestors
1287
1350
if ! suspensionValue {
1288
1351
srcPath , dstPath := e .ID .SrcPath , e .ID .DstPath
1289
- srcObj := refctx .ScopeMap .GetField (srcPath ... )
1290
- dstObj := refctx .ScopeMap .GetField (dstPath ... )
1291
1352
1353
+ // Make paths absolute if they're relative
1354
+ container := ParentField (e )
1355
+ if container != nil && container .Name .ScalarString () != "root" {
1356
+ containerPath := []d2ast.String {}
1357
+ curr := container
1358
+ for curr != nil && curr .Name .ScalarString () != "root" {
1359
+ containerPath = append ([]d2ast.String {curr .Name }, containerPath ... )
1360
+ curr = ParentField (curr )
1361
+ }
1362
+
1363
+ if len (srcPath ) > 0 && ! strings .EqualFold (srcPath [0 ].ScalarString (), containerPath [0 ].ScalarString ()) {
1364
+ absSrcPath := append ([]d2ast.String {}, containerPath ... )
1365
+ srcPath = append (absSrcPath , srcPath ... )
1366
+ }
1367
+
1368
+ if len (dstPath ) > 0 && ! strings .EqualFold (dstPath [0 ].ScalarString (), containerPath [0 ].ScalarString ()) {
1369
+ absDstPath := append ([]d2ast.String {}, containerPath ... )
1370
+ dstPath = append (absDstPath , dstPath ... )
1371
+ }
1372
+ }
1373
+
1374
+ rootMap := RootMap (refctx .ScopeMap )
1375
+ srcObj := rootMap .GetField (srcPath ... )
1376
+ dstObj := rootMap .GetField (dstPath ... )
1377
+
1378
+ // Unsuspend source node and all its ancestors
1292
1379
if srcObj != nil {
1293
1380
srcObj .suspended = false
1381
+ parent := ParentField (srcObj )
1382
+ for parent != nil && parent .Name .ScalarString () != "root" {
1383
+ parent .suspended = false
1384
+ parent = ParentField (parent )
1385
+ }
1294
1386
}
1387
+
1388
+ // Unsuspend destination node and all its ancestors
1295
1389
if dstObj != nil {
1296
1390
dstObj .suspended = false
1391
+ parent := ParentField (dstObj )
1392
+ for parent != nil && parent .Name .ScalarString () != "root" {
1393
+ parent .suspended = false
1394
+ parent = ParentField (parent )
1395
+ }
1297
1396
}
1298
1397
}
1299
1398
}
0 commit comments