Merge pull request #2494 from alixander/fix-slkjdf
d2ir: fix imported glob leaf filter
This commit is contained in:
commit
0b584b2122
6 changed files with 400 additions and 4 deletions
|
|
@ -38,6 +38,7 @@
|
||||||
- fixes panic when classes were mixed with layers incorrectly [#2448](https://github.com/terrastruct/d2/pull/2448)
|
- fixes panic when classes were mixed with layers incorrectly [#2448](https://github.com/terrastruct/d2/pull/2448)
|
||||||
- fixes panic when gradient colors are used in sketch mode [#2481](https://github.com/terrastruct/d2/pull/2487)
|
- fixes panic when gradient colors are used in sketch mode [#2481](https://github.com/terrastruct/d2/pull/2487)
|
||||||
- fixes panic using glob ampersand filters with composite values [#2489](https://github.com/terrastruct/d2/pull/2489)
|
- fixes panic using glob ampersand filters with composite values [#2489](https://github.com/terrastruct/d2/pull/2489)
|
||||||
|
- fixes leaf ampersand filter when used with imports [#2494](https://github.com/terrastruct/d2/pull/2494)
|
||||||
- Formatter:
|
- Formatter:
|
||||||
- fixes substitutions in quotes surrounded by text [#2462](https://github.com/terrastruct/d2/pull/2462)
|
- fixes substitutions in quotes surrounded by text [#2462](https://github.com/terrastruct/d2/pull/2462)
|
||||||
- CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370)
|
- CLI: fetch and render remote images of mimetype octet-stream correctly [#2370](https://github.com/terrastruct/d2/pull/2370)
|
||||||
|
|
|
||||||
|
|
@ -1726,6 +1726,33 @@ k
|
||||||
expErr: `d2/testdata/d2compiler/TestCompile/composite-glob-filter.d2:3:3: glob filters cannot be composites
|
expErr: `d2/testdata/d2compiler/TestCompile/composite-glob-filter.d2:3:3: glob filters cannot be composites
|
||||||
d2/testdata/d2compiler/TestCompile/composite-glob-filter.d2:3:3: glob filters cannot be composites`,
|
d2/testdata/d2compiler/TestCompile/composite-glob-filter.d2:3:3: glob filters cannot be composites`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "imported-glob-leaf-filter",
|
||||||
|
|
||||||
|
text: `
|
||||||
|
***: {
|
||||||
|
&leaf: true
|
||||||
|
style: {
|
||||||
|
font-size: 30
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a: {
|
||||||
|
...@x
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
files: map[string]string{
|
||||||
|
"x.d2": `
|
||||||
|
b
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
assertions: func(t *testing.T, g *d2graph.Graph) {
|
||||||
|
assert.Equal(t, 2, len(g.Objects))
|
||||||
|
assert.Equal(t, "b", g.Objects[0].Label.Value)
|
||||||
|
assert.Equal(t, "a", g.Objects[1].Label.Value)
|
||||||
|
assert.Equal(t, "30", g.Objects[0].Style.FontSize.Value)
|
||||||
|
assert.Equal(t, (*d2graph.Scalar)(nil), g.Objects[1].Style.FontSize)
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "import-nested-var",
|
name: "import-nested-var",
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -981,7 +981,7 @@ func (c *compiler) _ampersandPropertyFilter(propName string, value string, node
|
||||||
c.errorf(key, `&leaf must be "true" or "false", got %q`, value)
|
c.errorf(key, `&leaf must be "true" or "false", got %q`, value)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
isLeaf := node.Map() == nil || !node.Map().IsContainer()
|
isLeaf := node.Map() == nil || !c.IsContainer(node.Map())
|
||||||
return isLeaf == boolVal
|
return isLeaf == boolVal
|
||||||
case "connected":
|
case "connected":
|
||||||
boolVal, err := strconv.ParseBool(value)
|
boolVal, err := strconv.ParseBool(value)
|
||||||
|
|
|
||||||
20
d2ir/d2ir.go
20
d2ir/d2ir.go
|
|
@ -705,7 +705,7 @@ func (m *Map) FieldCountRecursive() int {
|
||||||
return acc
|
return acc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Map) IsContainer() bool {
|
func (c *compiler) IsContainer(m *Map) bool {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
@ -714,6 +714,20 @@ func (m *Map) IsContainer() bool {
|
||||||
for _, ref := range f.References {
|
for _, ref := range f.References {
|
||||||
if ref.Primary() && ref.Context_.Key != nil && ref.Context_.Key.Value.Map != nil {
|
if ref.Primary() && ref.Context_.Key != nil && ref.Context_.Key.Value.Map != nil {
|
||||||
for _, n := range ref.Context_.Key.Value.Map.Nodes {
|
for _, n := range ref.Context_.Key.Value.Map.Nodes {
|
||||||
|
if n.MapKey == nil {
|
||||||
|
if n.Import != nil {
|
||||||
|
impn, ok := c.peekImport(n.Import)
|
||||||
|
if ok {
|
||||||
|
for _, f := range impn.Fields {
|
||||||
|
_, isReserved := d2ast.ReservedKeywords[f.Name.ScalarString()]
|
||||||
|
if !(isReserved && f.Name.IsUnquoted()) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if len(n.MapKey.Edges) > 0 {
|
if len(n.MapKey.Edges) > 0 {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -1333,7 +1347,7 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, gctx *globContext, c *
|
||||||
|
|
||||||
if refctx.Edge.Src.HasMultiGlob() {
|
if refctx.Edge.Src.HasMultiGlob() {
|
||||||
// If src has a double glob we only select leafs, those without children.
|
// If src has a double glob we only select leafs, those without children.
|
||||||
if src.Map().IsContainer() {
|
if c.IsContainer(src.Map()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if NodeBoardKind(src) != "" || ParentBoard(src) != ParentBoard(dst) {
|
if NodeBoardKind(src) != "" || ParentBoard(src) != ParentBoard(dst) {
|
||||||
|
|
@ -1342,7 +1356,7 @@ func (m *Map) createEdge(eid *EdgeID, refctx *RefContext, gctx *globContext, c *
|
||||||
}
|
}
|
||||||
if refctx.Edge.Dst.HasMultiGlob() {
|
if refctx.Edge.Dst.HasMultiGlob() {
|
||||||
// If dst has a double glob we only select leafs, those without children.
|
// If dst has a double glob we only select leafs, those without children.
|
||||||
if dst.Map().IsContainer() {
|
if c.IsContainer(dst.Map()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if NodeBoardKind(dst) != "" || ParentBoard(src) != ParentBoard(dst) {
|
if NodeBoardKind(dst) != "" || ParentBoard(src) != ParentBoard(dst) {
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,53 @@ func (c *compiler) __import(imp *d2ast.Import) (*Map, bool) {
|
||||||
return ir, true
|
return ir, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *compiler) peekImport(imp *d2ast.Import) (*Map, bool) {
|
||||||
|
impPath := imp.PathWithPre()
|
||||||
|
if impPath == "" && imp.Range != (d2ast.Range{}) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(c.importStack) > 0 {
|
||||||
|
if path.Ext(impPath) != ".d2" {
|
||||||
|
impPath += ".d2"
|
||||||
|
}
|
||||||
|
|
||||||
|
if !filepath.IsAbs(impPath) {
|
||||||
|
impPath = path.Join(path.Dir(c.importStack[len(c.importStack)-1]), impPath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var f fs.File
|
||||||
|
var err error
|
||||||
|
if c.fs == nil {
|
||||||
|
f, err = os.Open(impPath)
|
||||||
|
} else {
|
||||||
|
f, err = c.fs.Open(impPath)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
// Use a separate parse error to avoid polluting the main one
|
||||||
|
localErr := &d2parser.ParseError{}
|
||||||
|
ast, err := d2parser.Parse(impPath, f, &d2parser.ParseOptions{
|
||||||
|
UTF16Pos: c.utf16Pos,
|
||||||
|
ParseError: localErr,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
ir := &Map{}
|
||||||
|
ir.initRoot()
|
||||||
|
ir.parent.(*Field).References[0].Context_.Scope = ast
|
||||||
|
|
||||||
|
c.compileMap(ir, ast, ast)
|
||||||
|
|
||||||
|
return ir, true
|
||||||
|
}
|
||||||
|
|
||||||
func nilScopeMap(n Node) {
|
func nilScopeMap(n Node) {
|
||||||
switch n := n.(type) {
|
switch n := n.(type) {
|
||||||
case *Map:
|
case *Map:
|
||||||
|
|
|
||||||
307
testdata/d2compiler/TestCompile/imported-glob-leaf-filter.exp.json
generated
vendored
Normal file
307
testdata/d2compiler/TestCompile/imported-glob-leaf-filter.exp.json
generated
vendored
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
{
|
||||||
|
"graph": {
|
||||||
|
"name": "",
|
||||||
|
"isFolderOnly": false,
|
||||||
|
"ast": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,0:0:0-10:0:71",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,1:0:1-6:1:56",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,1:0:1-1:3:4",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,1:0:1-1:3:4",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "***",
|
||||||
|
"raw_string": "***"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pattern": [
|
||||||
|
"*",
|
||||||
|
"",
|
||||||
|
"*",
|
||||||
|
"",
|
||||||
|
"*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"map": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,1:5:6-6:1:56",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,2:2:10-2:13:21",
|
||||||
|
"ampersand": true,
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,2:3:11-2:7:15",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,2:3:11-2:7:15",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "leaf",
|
||||||
|
"raw_string": "leaf"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"boolean": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,2:9:17-2:13:21",
|
||||||
|
"value": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,3:2:24-5:3:54",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,3:2:24-3:7:29",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,3:2:24-3:7:29",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "style",
|
||||||
|
"raw_string": "style"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"map": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,3:9:31-5:3:54",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,4:4:37-4:17:50",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,4:4:37-4:13:46",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,4:4:37-4:13:46",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "font-size",
|
||||||
|
"raw_string": "font-size"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"number": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,4:15:48-4:17:50",
|
||||||
|
"raw": "30",
|
||||||
|
"value": "30"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"map_key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:0:57-9:1:70",
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:0:57-7:1:58",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:0:57-7:1:58",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "a",
|
||||||
|
"raw_string": "a"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"primary": {},
|
||||||
|
"value": {
|
||||||
|
"map": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:3:60-9:1:70",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"import": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,8:1:63-8:6:68",
|
||||||
|
"spread": true,
|
||||||
|
"pre": "",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,8:5:67-8:6:68",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"string": "x",
|
||||||
|
"raw_string": "x"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"id": "",
|
||||||
|
"id_val": "",
|
||||||
|
"attributes": {
|
||||||
|
"label": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"labelDimensions": {
|
||||||
|
"width": 0,
|
||||||
|
"height": 0
|
||||||
|
},
|
||||||
|
"style": {},
|
||||||
|
"iconStyle": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"constraint": null
|
||||||
|
},
|
||||||
|
"zIndex": 0
|
||||||
|
},
|
||||||
|
"edges": null,
|
||||||
|
"objects": [
|
||||||
|
{
|
||||||
|
"id": "b",
|
||||||
|
"id_val": "b",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/x.d2,1:0:1-1:1:2",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/x.d2,1:0:1-1:1:2",
|
||||||
|
"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": {
|
||||||
|
"fontSize": {
|
||||||
|
"value": "30"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"iconStyle": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": "rectangle"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"constraint": null
|
||||||
|
},
|
||||||
|
"zIndex": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "a",
|
||||||
|
"id_val": "a",
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"key": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:0:57-7:1:58",
|
||||||
|
"path": [
|
||||||
|
{
|
||||||
|
"unquoted_string": {
|
||||||
|
"range": "d2/testdata/d2compiler/TestCompile/imported-glob-leaf-filter.d2,7:0:57-7:1:58",
|
||||||
|
"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": {},
|
||||||
|
"iconStyle": {},
|
||||||
|
"near_key": null,
|
||||||
|
"shape": {
|
||||||
|
"value": "rectangle"
|
||||||
|
},
|
||||||
|
"direction": {
|
||||||
|
"value": ""
|
||||||
|
},
|
||||||
|
"constraint": null
|
||||||
|
},
|
||||||
|
"zIndex": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"err": null
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue