From b83b6b27be1879955390648c8e5dac929e509cb6 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Sun, 18 Jun 2017 08:28:20 -0700 Subject: [PATCH] zclsyntax: catch and test more erroneous use of "for" --- zcl/zclsyntax/expression_test.go | 66 ++++++++++++++++++++++++++++++++ zcl/zclsyntax/parser.go | 10 +++++ 2 files changed, 76 insertions(+) diff --git a/zcl/zclsyntax/expression_test.go b/zcl/zclsyntax/expression_test.go index 06d9bfd..b3b59cb 100644 --- a/zcl/zclsyntax/expression_test.go +++ b/zcl/zclsyntax/expression_test.go @@ -493,6 +493,72 @@ upper( }), 0, }, + { + `[for k, v in {hello: "world"}: k => v]`, + nil, + cty.ObjectVal(map[string]cty.Value{ + "hello": cty.StringVal("world"), + }), + 1, // can't have a key expr when producing a tuple + }, + { + `{for v in {hello: "world"}: v}`, + nil, + cty.TupleVal([]cty.Value{ + cty.StringVal("world"), + }), + 1, // must have a key expr when producing a map + }, + { + `[for v in {hello: "world"}: v...]`, + nil, + cty.TupleVal([]cty.Value{ + cty.StringVal("world"), + }), + 1, // can't use grouping when producing a tuple + }, + { + `[for v in "hello": v]`, + nil, + cty.DynamicVal, + 1, // can't iterate over a string + }, + { + `[for v in null: v]`, + nil, + cty.DynamicVal, + 1, // can't iterate over a null value + }, + { + `[for v in unk: v]`, + &zcl.EvalContext{ + Variables: map[string]cty.Value{ + "unk": cty.UnknownVal(cty.List(cty.String)), + }, + }, + cty.DynamicVal, + 0, + }, + { + `[for v in unk: v]`, + &zcl.EvalContext{ + Variables: map[string]cty.Value{ + "unk": cty.DynamicVal, + }, + }, + cty.DynamicVal, + 0, + }, + { + `[for v in unk: v]`, + &zcl.EvalContext{ + Variables: map[string]cty.Value{ + "unk": cty.UnknownVal(cty.String), + }, + }, + cty.DynamicVal, + 1, // can't iterate over a string (even if it's unknown) + }, { `[{name: "Steve"}, {name: "Ermintrude"}].*.name`, diff --git a/zcl/zclsyntax/parser.go b/zcl/zclsyntax/parser.go index d5d880a..c604d15 100644 --- a/zcl/zclsyntax/parser.go +++ b/zcl/zclsyntax/parser.go @@ -1331,6 +1331,16 @@ func (p *parser) finishParsingForExpr(open Token) (Expression, zcl.Diagnostics) Context: zcl.RangeBetween(open.Range, close.Range).Ptr(), }) } + } else { + if keyExpr == nil { + diags = append(diags, &zcl.Diagnostic{ + Severity: zcl.DiagError, + Summary: "Invalid 'for' expression", + Detail: "Key expression is required when building an object.", + Subject: valExpr.Range().Ptr(), + Context: zcl.RangeBetween(open.Range, close.Range).Ptr(), + }) + } } return &ForExpr{