From d90da0c4bab2c7d9c6332c86aae2bf972c827095 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Fri, 16 Jun 2017 08:39:28 -0700 Subject: [PATCH] zclsyntax: specific error message for nested attr-only splat Attribute-only splat expressions cannot have other splats nested inside, since we're only interested in supporting how these behaved for HIL when running inside Hashicorp Terraform. More complex cases should be dealt with using either full splats (bracketed *) or "for" expressions. --- zcl/zclsyntax/expression_test.go | 9 +++++++++ zcl/zclsyntax/parser.go | 21 +++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/zcl/zclsyntax/expression_test.go b/zcl/zclsyntax/expression_test.go index 335cde0..56891e0 100644 --- a/zcl/zclsyntax/expression_test.go +++ b/zcl/zclsyntax/expression_test.go @@ -529,6 +529,15 @@ upper( cty.StringVal("Steve"), 0, }, + { + `[["hello"], ["goodbye"]].*.*`, + nil, + cty.TupleVal([]cty.Value{ + cty.TupleVal([]cty.Value{cty.StringVal("hello")}), + cty.TupleVal([]cty.Value{cty.StringVal("goodbye")}), + }), + 1, + }, { `["hello"][0]`, diff --git a/zcl/zclsyntax/parser.go b/zcl/zclsyntax/parser.go index a082a8c..0272617 100644 --- a/zcl/zclsyntax/parser.go +++ b/zcl/zclsyntax/parser.go @@ -512,12 +512,21 @@ Traversal: dot := p.Read() if p.Peek().Type != TokenIdent { if !p.recovery { - diags = append(diags, &zcl.Diagnostic{ - Severity: zcl.DiagError, - Summary: "Invalid attribute name", - Detail: "An attribute name is required after a dot.", - Subject: &attrTok.Range, - }) + if p.Peek().Type == TokenStar { + diags = append(diags, &zcl.Diagnostic{ + Severity: zcl.DiagError, + Summary: "Nested splat expression not allowed", + Detail: "A splat expression (*) cannot be used inside another attribute-only splat expression.", + Subject: p.Peek().Range.Ptr(), + }) + } else { + diags = append(diags, &zcl.Diagnostic{ + Severity: zcl.DiagError, + Summary: "Invalid attribute name", + Detail: "An attribute name is required after a dot.", + Subject: &attrTok.Range, + }) + } } p.setRecovery() continue Traversal