From 46d1fceb9c77c6494007c69a164ce3566b28e990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw=20Barzowski?= Date: Sun, 6 Jun 2021 21:06:59 +0200 Subject: [PATCH] [Linter] Fix super index type and handle "object or string" indexing correctly. --- linter/internal/types/build_graph.go | 2 +- linter/internal/types/check.go | 4 ++-- linter/testdata/object_or_array_indexing.jsonnet | 5 +++++ linter/testdata/object_or_array_indexing.linter.golden | 0 linter/testdata/object_or_string_indexing.jsonnet | 5 +++++ linter/testdata/object_or_string_indexing.linter.golden | 0 linter/testdata/super_index_array.jsonnet | 4 ++++ linter/testdata/super_index_array.linter.golden | 0 8 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 linter/testdata/object_or_array_indexing.jsonnet create mode 100644 linter/testdata/object_or_array_indexing.linter.golden create mode 100644 linter/testdata/object_or_string_indexing.jsonnet create mode 100644 linter/testdata/object_or_string_indexing.linter.golden create mode 100644 linter/testdata/super_index_array.jsonnet create mode 100644 linter/testdata/super_index_array.linter.golden diff --git a/linter/internal/types/build_graph.go b/linter/internal/types/build_graph.go index f58ecab..1e0e35b 100644 --- a/linter/internal/types/build_graph.go +++ b/linter/internal/types/build_graph.go @@ -234,7 +234,7 @@ func calcTP(node ast.Node, varAt map[ast.Node]*common.Variable, g *typeGraph) ty // no recursion yet return tpRef(anyObjectType) case *ast.SuperIndex: - return tpRef(anyObjectType) + return tpRef(anyType) case *ast.InSuper: return tpRef(boolType) case *ast.Function: diff --git a/linter/internal/types/check.go b/linter/internal/types/check.go index 0c1276a..738bad7 100644 --- a/linter/internal/types/check.go +++ b/linter/internal/types/check.go @@ -55,8 +55,8 @@ func check(node ast.Node, typeOf exprTypes, ec *common.ErrCollector) { if !indexType.Number { ec.StaticErr("Indexed value is assumed to be "+assumedType+", but index is not a number", node.Loc()) } - } else if !targetType.Array() { - // It's not an array so it must be an object + } else if !targetType.Array() && !targetType.String { + // It's not an array or a string so it must be an object if !indexType.String { ec.StaticErr("Indexed value is assumed to be an object, but index is not a string", node.Loc()) } diff --git a/linter/testdata/object_or_array_indexing.jsonnet b/linter/testdata/object_or_array_indexing.jsonnet new file mode 100644 index 0000000..34d6134 --- /dev/null +++ b/linter/testdata/object_or_array_indexing.jsonnet @@ -0,0 +1,5 @@ +local foo = if true then {"foo": "bar"} else ["f", "o", "o"]; +[ + foo[0], + foo["foo"] +] diff --git a/linter/testdata/object_or_array_indexing.linter.golden b/linter/testdata/object_or_array_indexing.linter.golden new file mode 100644 index 0000000..e69de29 diff --git a/linter/testdata/object_or_string_indexing.jsonnet b/linter/testdata/object_or_string_indexing.jsonnet new file mode 100644 index 0000000..8a9507a --- /dev/null +++ b/linter/testdata/object_or_string_indexing.jsonnet @@ -0,0 +1,5 @@ +local foo = if true then {"foo": "bar"} else "foo"; +[ + foo[0], + foo["foo"] +] diff --git a/linter/testdata/object_or_string_indexing.linter.golden b/linter/testdata/object_or_string_indexing.linter.golden new file mode 100644 index 0000000..e69de29 diff --git a/linter/testdata/super_index_array.jsonnet b/linter/testdata/super_index_array.jsonnet new file mode 100644 index 0000000..24e557d --- /dev/null +++ b/linter/testdata/super_index_array.jsonnet @@ -0,0 +1,4 @@ +local foo = { config: [{ x: 'y' }] }; +foo { + config: [super.config[0] { a: 'b' }], +} diff --git a/linter/testdata/super_index_array.linter.golden b/linter/testdata/super_index_array.linter.golden new file mode 100644 index 0000000..e69de29