diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index de58d5b7a..007940101 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -13,6 +13,7 @@ - Constraints in `sql_table` sheds their excessive letter-spacing and is padded from the end consistently [#1372](https://github.com/terrastruct/d2/pull/1372) - Duplicate image URLs in icons are only fetched once [#1373](https://github.com/terrastruct/d2/pull/1373) - In watch mode, images are cached by default across compiles. Can be disabled with flag `--img-cache=0`. [#1373](https://github.com/terrastruct/d2/pull/1373) +- Common invalid array separator `,` usage in class arrays returns a helpful error message [#1376](https://github.com/terrastruct/d2/pull/1376) #### Bugfixes ⛑️ diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 661f697f0..b01beb15a 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -147,6 +147,21 @@ func (c *compiler) compileMap(obj *d2graph.Object, m *d2ir.Map) { classMap := m.GetClassMap(className) if classMap != nil { c.compileMap(obj, classMap) + } else { + if strings.Contains(className, ",") { + split := strings.Split(className, ",") + allFound := true + for _, maybeClassName := range split { + maybeClassName = strings.TrimSpace(maybeClassName) + if m.GetClassMap(maybeClassName) == nil { + allFound = false + break + } + } + if allFound { + c.errorf(class.LastRef().AST(), `class "%s" not found. Did you mean to use ";" to separate array items?`, className) + } + } } } } diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 985050a83..1ecd7ff30 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -2482,6 +2482,23 @@ nostar -> 1star: { class: [path; path2] } tassert.Equal(t, "2", g.Edges[0].Style.StrokeWidth.Value) }, }, + { + name: "comma-array-class", + + text: `classes: { + dragon_ball: { + label: "" + shape: circle + style.fill: orange + } + path: { + label: "then" + style.stroke-width: 4 + } +} +nostar: { class: [dragon_ball, path] }`, + expErr: `d2/testdata/d2compiler/TestCompile/comma-array-class.d2:12:11: class "dragon_ball, path" not found. Did you mean to use ";" to separate array items?`, + }, { name: "reordered-classes", text: `classes: { diff --git a/testdata/d2compiler/TestCompile/comma-array-class.exp.json b/testdata/d2compiler/TestCompile/comma-array-class.exp.json new file mode 100644 index 000000000..cedc232f6 --- /dev/null +++ b/testdata/d2compiler/TestCompile/comma-array-class.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/comma-array-class.d2,11:10:157-11:15:162", + "errmsg": "d2/testdata/d2compiler/TestCompile/comma-array-class.d2:12:11: class \"dragon_ball, path\" not found. Did you mean to use \";\" to separate array items?" + } + ] + } +}