diff --git a/d2oracle/edit.go b/d2oracle/edit.go index c58c7f62e5..d5afa5d6f6 100644 --- a/d2oracle/edit.go +++ b/d2oracle/edit.go @@ -349,6 +349,7 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) toSkip := 1 reserved := false + imported := false // If you're setting `(x -> y)[0].style.opacity` // There's 3 cases you need to handle: @@ -382,18 +383,16 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) break } obj = o + imported = IsImported(baseAST, obj) var maybeNewScope *d2ast.Map - if baseAST != g.AST { + if baseAST != g.AST || imported { writeableRefs := getWriteableRefs(obj, baseAST) for _, ref := range writeableRefs { if ref.MapKey != nil && ref.MapKey.Value.Map != nil { maybeNewScope = ref.MapKey.Value.Map } } - } else if IsImported(g, obj) { - appendMapKey(scope, mk) - return nil } else { maybeNewScope = obj.Map } @@ -412,8 +411,9 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) } } + writeableLabelMK := true var objK *d2ast.Key - if baseAST != g.AST { + if baseAST != g.AST || imported { writeableRefs := getWriteableRefs(obj, baseAST) if len(writeableRefs) > 0 { objK = writeableRefs[0].MapKey @@ -422,6 +422,13 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) appendMapKey(scope, mk) return nil } + writeableLabelMK = false + for _, ref := range writeableRefs { + if ref.MapKey == obj.Label.MapKey { + writeableLabelMK = true + break + } + } } var m *d2ast.Map if objK != nil { @@ -430,7 +437,7 @@ func _set(g *d2graph.Graph, baseAST *d2ast.Map, key string, tag, value *string) m = obj.Map } - if obj.Label.MapKey != nil && m == nil && (!found || reserved || len(mk.Edges) > 0) { + if (obj.Label.MapKey != nil && writeableLabelMK) && m == nil && (!found || reserved || len(mk.Edges) > 0) { m2 := &d2ast.Map{ Range: d2ast.MakeRange(",1:0:0-1:0:0"), } @@ -3107,7 +3114,7 @@ func filterReservedPath(path []*d2ast.StringBox) (filtered []*d2ast.StringBox) { func getWriteableRefs(obj *d2graph.Object, writeableAST *d2ast.Map) (out []d2graph.Reference) { for i, ref := range obj.References { - if ref.ScopeAST == writeableAST { + if ref.ScopeAST == writeableAST && ref.Key.Range.Path == writeableAST.Range.Path { out = append(out, obj.References[i]) } } diff --git a/d2oracle/edit_test.go b/d2oracle/edit_test.go index b89f4e823c..f12d108b70 100644 --- a/d2oracle/edit_test.go +++ b/d2oracle/edit_test.go @@ -1781,6 +1781,33 @@ scenarios: { a: inner {style.opacity: 0.2} } } +`, + }, + { + name: "scenarios-multiple", + + text: `a + +scenarios: { + x: { + b + a.style.fill: red + } +} +`, + key: `a.style.opacity`, + value: go2.Pointer(`0.2`), + boardPath: []string{"x"}, + + exp: `a + +scenarios: { + x: { + b + a.style.fill: red + a.style.opacity: 0.2 + } +} `, }, { @@ -2105,6 +2132,21 @@ x: @yo`, exp: `a x: @yo x.b.style.fill: red +`, + }, + { + name: "import/7", + + text: `...@yo +b.style.fill: red`, + fsTexts: map[string]string{ + "yo.d2": `b`, + }, + key: `b.style.opacity`, + value: go2.Pointer("0.5"), + exp: `...@yo +b.style.fill: red +b.style.opacity: 0.5 `, }, } diff --git a/d2oracle/get.go b/d2oracle/get.go index b75ad12d1a..6e5721ee89 100644 --- a/d2oracle/get.go +++ b/d2oracle/get.go @@ -140,14 +140,14 @@ func GetParentID(g *d2graph.Graph, boardPath []string, absID string) (string, er return obj.Parent.AbsID(), nil } -func IsImported(g *d2graph.Graph, obj *d2graph.Object) bool { +func IsImported(ast *d2ast.Map, obj *d2graph.Object) bool { for _, ref := range obj.References { - if ref.MapKey.Range.Path == g.AST.Range.Path { - return false + if ref.Key.Range.Path != ast.Range.Path { + return true } } - return true + return false } func GetObj(g *d2graph.Graph, boardPath []string, absID string) *d2graph.Object { diff --git a/testdata/d2oracle/TestSet/import/7.exp.json b/testdata/d2oracle/TestSet/import/7.exp.json new file mode 100644 index 0000000000..ce85d720a8 --- /dev/null +++ b/testdata/d2oracle/TestSet/import/7.exp.json @@ -0,0 +1,300 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "index.d2,0:0:0-3:0:46", + "nodes": [ + { + "import": { + "range": "index.d2,0:0:0-0:6:6", + "spread": true, + "pre": "", + "path": [ + { + "unquoted_string": { + "range": "index.d2,0:4:4-0:6:6", + "value": [ + { + "string": "yo", + "raw_string": "yo" + } + ] + } + } + ] + } + }, + { + "map_key": { + "range": "index.d2,1:0:7-1:17:24", + "key": { + "range": "index.d2,1:0:7-1:12:19", + "path": [ + { + "unquoted_string": { + "range": "index.d2,1:0:7-1:1:8", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,1:2:9-1:7:14", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,1:8:15-1:12:19", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "index.d2,1:14:21-1:17:24", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + }, + { + "map_key": { + "range": "index.d2,2:0:25-2:20:45", + "key": { + "range": "index.d2,2:0:25-2:15:40", + "path": [ + { + "unquoted_string": { + "range": "index.d2,2:0:25-2:1:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,2:2:27-2:7:32", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,2:8:33-2:15:40", + "value": [ + { + "string": "opacity", + "raw_string": "opacity" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "index.d2,2:17:42-2:20:45", + "raw": "0.5", + "value": "1/2" + } + } + } + } + ] + }, + "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": null, + "objects": [ + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "yo.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "yo.d2,0:0:0-0:1:1", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "index.d2,1:0:7-1:12:19", + "path": [ + { + "unquoted_string": { + "range": "index.d2,1:0:7-1:1:8", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,1:2:9-1:7:14", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,1:8:15-1:12:19", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "index.d2,2:0:25-2:15:40", + "path": [ + { + "unquoted_string": { + "range": "index.d2,2:0:25-2:1:26", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,2:2:27-2:7:32", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "index.d2,2:8:33-2:15:40", + "value": [ + { + "string": "opacity", + "raw_string": "opacity" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "opacity": { + "value": "0.5" + }, + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + }, + "err": "" +} diff --git a/testdata/d2oracle/TestSet/scenarios-multiple.exp.json b/testdata/d2oracle/TestSet/scenarios-multiple.exp.json new file mode 100644 index 0000000000..66e45390d3 --- /dev/null +++ b/testdata/d2oracle/TestSet/scenarios-multiple.exp.json @@ -0,0 +1,649 @@ +{ + "graph": { + "name": "", + "isFolderOnly": false, + "ast": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-9:0:82", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,2:0:3-8:1:81", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,2:0:3-2:9:12", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,2:0:3-2:9:12", + "value": [ + { + "string": "scenarios", + "raw_string": "scenarios" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,2:11:14-8:1:81", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,3:2:18-7:3:79", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,3:2:18-3:3:19", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,3:2:18-3:3:19", + "value": [ + { + "string": "x", + "raw_string": "x" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,3:5:21-7:3:79", + "nodes": [ + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,4:4:27-4:5:28", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,4:4:27-4:5:28", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:4:33-5:21:50", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:4:33-5:16:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:4:33-5:5:34", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:6:35-5:11:40", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:12:41-5:16:45", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:18:47-5:21:50", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + } + } + }, + { + "map_key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:4:55-6:24:75", + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:4:55-6:19:70", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:4:55-6:5:56", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:6:57-6:11:62", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:12:63-6:19:70", + "value": [ + { + "string": "opacity", + "raw_string": "opacity" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:21:72-6:24:75", + "raw": "0.2", + "value": "1/5" + } + } + } + } + ] + } + } + } + } + ] + } + } + } + } + ] + }, + "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": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "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 + } + ], + "scenarios": [ + { + "name": "x", + "isFolderOnly": false, + "ast": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "a" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "style" + } + ] + } + } + ] + }, + "primary": {}, + "value": { + "map": { + "range": ",1:0:0-2:0:0", + "nodes": [ + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "fill" + } + ] + } + } + ] + }, + "primary": { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:18:47-5:21:50", + "value": [ + { + "string": "red", + "raw_string": "red" + } + ] + } + }, + "value": {} + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "opacity" + } + ] + } + } + ] + }, + "primary": { + "number": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:21:72-6:24:75", + "raw": "0.2", + "value": "1/5" + } + }, + "value": {} + } + } + ] + } + } + } + } + ] + } + } + } + }, + { + "map_key": { + "range": ",0:0:0-0:0:0", + "key": { + "range": ",0:0:0-0:0:0", + "path": [ + { + "unquoted_string": { + "range": ",0:0:0-0:0:0", + "value": [ + { + "string": "b" + } + ] + } + } + ] + }, + "primary": {}, + "value": {} + } + } + ] + }, + "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": null, + "objects": [ + { + "id": "a", + "id_val": "a", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,0:0:0-0:1:1", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:4:33-5:16:45", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:4:33-5:5:34", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:6:35-5:11:40", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,5:12:41-5:16:45", + "value": [ + { + "string": "fill", + "raw_string": "fill" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + }, + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:4:55-6:19:70", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:4:55-6:5:56", + "value": [ + { + "string": "a", + "raw_string": "a" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:6:57-6:11:62", + "value": [ + { + "string": "style", + "raw_string": "style" + } + ] + } + }, + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,6:12:63-6:19:70", + "value": [ + { + "string": "opacity", + "raw_string": "opacity" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "a" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": { + "opacity": { + "value": "0.2" + }, + "fill": { + "value": "red" + } + }, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + }, + { + "id": "b", + "id_val": "b", + "references": [ + { + "key": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,4:4:27-4:5:28", + "path": [ + { + "unquoted_string": { + "range": "d2/testdata/d2oracle/TestSet/scenarios-multiple.d2,4:4:27-4:5:28", + "value": [ + { + "string": "b", + "raw_string": "b" + } + ] + } + } + ] + }, + "key_path_index": 0, + "map_key_edge_index": -1 + } + ], + "attributes": { + "label": { + "value": "b" + }, + "labelDimensions": { + "width": 0, + "height": 0 + }, + "style": {}, + "near_key": null, + "shape": { + "value": "rectangle" + }, + "direction": { + "value": "" + }, + "constraint": null + }, + "zIndex": 0 + } + ] + } + ] + }, + "err": "" +}