From 41cff854d8157be197e6b4698a8d9570ced9476b Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Wed, 18 Jul 2018 15:41:35 -0700 Subject: [PATCH] Fix "attribute" vs "argument" terminology in diagnostics During implementation of HCL in other applications, it became clear that the overloading of the word "attribute" to mean both a key/value pair in a body and an element within an object value creates confusion. It's too late to change that in the HCL Go API now, but here we at least update the diagnostic messages. The new convention is that a key/value pair within a block is now called an "argument", while an element of an object is still called an "attribute". It is unfortunate that the Go-facing API still uses the word "attribute" for both, but the user experience is the most important thing and in practice many applications will treat block arguments as one way to set the attributes of some object anyway, and in that case arguments can be thought of as the subset of attributes of an object whose values come from that object's associated block. This also includes a few other minor terminology tweaks in the diagnostic messages the reflect how our lexicon has evolved during development and authoring of user-facing documentation. --- hcl/hclsyntax/parser.go | 40 ++++++++++++++++++++-------------------- hcl/hclsyntax/token.go | 2 +- hcl/json/parser.go | 18 +++++++++--------- hcl/json/structure.go | 18 +++++++++--------- hcl/merged.go | 12 ++++++------ hcltest/mock.go | 8 ++++---- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/hcl/hclsyntax/parser.go b/hcl/hclsyntax/parser.go index 002858f..009b930 100644 --- a/hcl/hclsyntax/parser.go +++ b/hcl/hclsyntax/parser.go @@ -55,7 +55,7 @@ Token: Severity: hcl.DiagError, Summary: "Attribute redefined", Detail: fmt.Sprintf( - "The attribute %q was already defined at %s. Each attribute may be defined only once.", + "The argument %q was already set at %s. Each argument may be set only once.", titem.Name, existing.NameRange.String(), ), Subject: &titem.NameRange, @@ -80,15 +80,15 @@ Token: if bad.Type == TokenOQuote { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Invalid attribute name", - Detail: "Attribute names must not be quoted.", + Summary: "Invalid argument name", + Detail: "Argument names must not be quoted.", Subject: &bad.Range, }) } else { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Attribute or block definition required", - Detail: "An attribute or block definition is required here.", + Summary: "Argument or block definition required", + Detail: "An argument or block definition is required here.", Subject: &bad.Range, }) } @@ -120,8 +120,8 @@ func (p *parser) ParseBodyItem() (Node, hcl.Diagnostics) { return nil, hcl.Diagnostics{ { Severity: hcl.DiagError, - Summary: "Attribute or block definition required", - Detail: "An attribute or block definition is required here.", + Summary: "Argument or block definition required", + Detail: "An argument or block definition is required here.", Subject: &ident.Range, }, } @@ -139,8 +139,8 @@ func (p *parser) ParseBodyItem() (Node, hcl.Diagnostics) { return nil, hcl.Diagnostics{ { Severity: hcl.DiagError, - Summary: "Attribute or block definition required", - Detail: "An attribute or block definition is required here. To define an attribute, use the equals sign \"=\" to introduce the attribute value.", + Summary: "Argument or block definition required", + Detail: "An argument or block definition is required here. To set an argument, use the equals sign \"=\" to introduce the argument value.", Subject: &ident.Range, }, } @@ -171,8 +171,8 @@ func (p *parser) finishParsingBodyAttribute(ident Token) (Node, hcl.Diagnostics) if !p.recovery { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing newline after attribute definition", - Detail: "An attribute definition must end with a newline.", + Summary: "Missing newline after argument", + Detail: "An argument definition must end with a newline.", Subject: &end.Range, Context: hcl.RangeBetween(ident.Range, end.Range).Ptr(), }) @@ -244,7 +244,7 @@ Token: diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid block definition", - Detail: "The equals sign \"=\" indicates an attribute definition, and must not be used when defining a block.", + Detail: "The equals sign \"=\" indicates an argument definition, and must not be used when defining a block.", Subject: &tok.Range, Context: hcl.RangeBetween(ident.Range, tok.Range).Ptr(), }) @@ -1135,8 +1135,8 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) { if next.Type == TokenNewline || next.Type == TokenComma { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing item value", - Detail: "Expected an item value, introduced by an equals sign (\"=\").", + Summary: "Missing attribute value", + Detail: "Expected an attribute value, introduced by an equals sign (\"=\").", Subject: &next.Range, Context: hcl.RangeBetween(open.Range, next.Range).Ptr(), }) @@ -1144,7 +1144,7 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Missing key/value separator", - Detail: "Expected an equals sign (\"=\") to mark the beginning of the item value.", + Detail: "Expected an equals sign (\"=\") to mark the beginning of the attribute value.", Subject: &next.Range, Context: hcl.RangeBetween(open.Range, next.Range).Ptr(), }) @@ -1182,8 +1182,8 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) { if !p.recovery { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing item separator", - Detail: "Expected a newline or comma to mark the beginning of the next item.", + Summary: "Missing attribute separator", + Detail: "Expected a newline or comma to mark the beginning of the next attribute.", Subject: &next.Range, Context: hcl.RangeBetween(open.Range, next.Range).Ptr(), }) @@ -1277,7 +1277,7 @@ func (p *parser) finishParsingForExpr(open Token) (Expression, hcl.Diagnostics) diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid 'for' expression", - Detail: "For expression requires 'in' keyword after names.", + Detail: "For expression requires the 'in' keyword after its name declarations.", Subject: p.Peek().Range.Ptr(), Context: hcl.RangeBetween(open.Range, p.Peek().Range).Ptr(), }) @@ -1305,7 +1305,7 @@ func (p *parser) finishParsingForExpr(open Token) (Expression, hcl.Diagnostics) diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid 'for' expression", - Detail: "For expression requires colon after collection expression.", + Detail: "For expression requires a colon after the collection expression.", Subject: p.Peek().Range.Ptr(), Context: hcl.RangeBetween(open.Range, p.Peek().Range).Ptr(), }) @@ -1459,7 +1459,7 @@ Token: case TokenTemplateControl, TokenTemplateInterp: which := "$" if tok.Type == TokenTemplateControl { - which = "!" + which = "%" } diags = append(diags, &hcl.Diagnostic{ diff --git a/hcl/hclsyntax/token.go b/hcl/hclsyntax/token.go index bcaa15f..c00129f 100644 --- a/hcl/hclsyntax/token.go +++ b/hcl/hclsyntax/token.go @@ -229,7 +229,7 @@ func checkInvalidTokens(tokens Tokens) hcl.Diagnostics { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Invalid character", - Detail: "The \";\" character is not valid. Use newlines to separate attributes and blocks, and commas to separate items in collection values.", + Detail: "The \";\" character is not valid. Use newlines to separate arguments and blocks, and commas to separate items in collection values.", Subject: &tok.Range, }) diff --git a/hcl/json/parser.go b/hcl/json/parser.go index 246fd1c..a73d6f9 100644 --- a/hcl/json/parser.go +++ b/hcl/json/parser.go @@ -55,7 +55,7 @@ func parseValue(p *peeker) (node, hcl.Diagnostics) { return wrapInvalid(nil, hcl.Diagnostics{ { Severity: hcl.DiagError, - Summary: "Missing attribute value", + Summary: "Missing JSON value", Detail: "A JSON value must start with a brace, a bracket, a number, a string, or a keyword.", Subject: &tok.Range, }, @@ -144,8 +144,8 @@ Token: if !ok { return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Invalid object attribute name", - Detail: "A JSON object attribute name must be a string", + Summary: "Invalid object property name", + Detail: "A JSON object property name must be a string", Subject: keyNode.StartRange().Ptr(), }) } @@ -171,7 +171,7 @@ Token: // Possible confusion with native HCL syntax. return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing attribute value colon", + Summary: "Missing property value colon", Detail: "JSON uses a colon as its name/value delimiter, not an equals sign.", Subject: &colon.Range, }) @@ -179,8 +179,8 @@ Token: return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing attribute value colon", - Detail: "A colon must appear between an object attribute's name and its value.", + Summary: "Missing property value colon", + Detail: "A colon must appear between an object property's name and its value.", Subject: &colon.Range, }) } @@ -205,7 +205,7 @@ Token: return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Trailing comma in object", - Detail: "JSON does not permit a trailing comma after the final attribute in an object.", + Detail: "JSON does not permit a trailing comma after the final property in an object.", Subject: &comma.Range, }) } @@ -234,7 +234,7 @@ Token: return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Missing attribute seperator comma", - Detail: "A comma must appear between each attribute declaration in an object.", + Detail: "A comma must appear between each property definition in an object.", Subject: p.Peek().Range.Ptr(), }) } @@ -301,7 +301,7 @@ Token: return nil, diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Trailing comma in array", - Detail: "JSON does not permit a trailing comma after the final attribute in an array.", + Detail: "JSON does not permit a trailing comma after the final value in an array.", Subject: &comma.Range, }) } diff --git a/hcl/json/structure.go b/hcl/json/structure.go index 28dcf52..9e0c92a 100644 --- a/hcl/json/structure.go +++ b/hcl/json/structure.go @@ -64,7 +64,7 @@ func (b *body) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnostic diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Extraneous JSON object property", - Detail: fmt.Sprintf("No attribute or block type is named %q.%s", k, suggestion), + Detail: fmt.Sprintf("No argument or block type is named %q.%s", k, suggestion), Subject: &attr.NameRange, Context: attr.Range().Ptr(), }) @@ -114,8 +114,8 @@ func (b *body) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Bod if existing, exists := content.Attributes[attrName]; exists { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Duplicate attribute definition", - Detail: fmt.Sprintf("The attribute %q was already defined at %s.", attrName, existing.Range), + Summary: "Duplicate argument", + Detail: fmt.Sprintf("The argument %q was already set at %s.", attrName, existing.Range), Subject: &jsonAttr.NameRange, Context: jsonAttr.Range().Ptr(), }) @@ -149,8 +149,8 @@ func (b *body) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Bod if _, defined := content.Attributes[attrS.Name]; !defined { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing required attribute", - Detail: fmt.Sprintf("The attribute %q is required, but no definition was found.", attrS.Name), + Summary: "Missing required argument", + Detail: fmt.Sprintf("The argument %q is required, but no definition was found.", attrS.Name), Subject: b.MissingItemRange().Ptr(), }) } @@ -175,7 +175,7 @@ func (b *body) JustAttributes() (hcl.Attributes, hcl.Diagnostics) { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Incorrect JSON value type", - Detail: "A JSON object is required here, defining the attributes for this block.", + Detail: "A JSON object is required here, setting the arguments for this block.", Subject: b.val.StartRange().Ptr(), }) return attrs, diags @@ -197,7 +197,7 @@ func (b *body) JustAttributes() (hcl.Attributes, hcl.Diagnostics) { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Duplicate attribute definition", - Detail: fmt.Sprintf("The attribute %q was already defined at %s.", name, existing.Range), + Detail: fmt.Sprintf("The argument %q was already set at %s.", name, existing.Range), Subject: &jsonAttr.NameRange, }) continue @@ -345,7 +345,7 @@ func (b *body) collectDeepAttrs(v node, labelName *string) ([]*objectAttr, hcl.D diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Incorrect JSON value type", - Detail: "A JSON object is required here, to define attributes and child blocks.", + Detail: "A JSON object is required here, to define arguments and child blocks.", Subject: ev.StartRange().Ptr(), }) } @@ -364,7 +364,7 @@ func (b *body) collectDeepAttrs(v node, labelName *string) ([]*objectAttr, hcl.D diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Incorrect JSON value type", - Detail: "Either a JSON object or JSON array of objects is required here, to define attributes and child blocks.", + Detail: "Either a JSON object or JSON array of objects is required here, to define arguments and child blocks.", Subject: v.StartRange().Ptr(), }) } diff --git a/hcl/merged.go b/hcl/merged.go index ca2b728..0e147a0 100644 --- a/hcl/merged.go +++ b/hcl/merged.go @@ -109,9 +109,9 @@ func (mb mergedBodies) JustAttributes() (Attributes, Diagnostics) { if existing := attrs[name]; existing != nil { diags = diags.Append(&Diagnostic{ Severity: DiagError, - Summary: "Duplicate attribute", + Summary: "Duplicate argument", Detail: fmt.Sprintf( - "Attribute %q was already assigned at %s", + "Argument %q was already set at %s", name, existing.NameRange.String(), ), Subject: &attr.NameRange, @@ -182,9 +182,9 @@ func (mb mergedBodies) mergedContent(schema *BodySchema, partial bool) (*BodyCon if existing := content.Attributes[name]; existing != nil { diags = diags.Append(&Diagnostic{ Severity: DiagError, - Summary: "Duplicate attribute", + Summary: "Duplicate argument", Detail: fmt.Sprintf( - "Attribute %q was already assigned at %s", + "Argument %q was already set at %s", name, existing.NameRange.String(), ), Subject: &attr.NameRange, @@ -212,9 +212,9 @@ func (mb mergedBodies) mergedContent(schema *BodySchema, partial bool) (*BodyCon // use of required attributes on merged bodies. diags = diags.Append(&Diagnostic{ Severity: DiagError, - Summary: "Missing required attribute", + Summary: "Missing required argument", Detail: fmt.Sprintf( - "The attribute %q is required, but was not assigned.", + "The argument %q is required, but was not set.", attrS.Name, ), }) diff --git a/hcltest/mock.go b/hcltest/mock.go index 510fc24..7124f45 100644 --- a/hcltest/mock.go +++ b/hcltest/mock.go @@ -26,8 +26,8 @@ func (b mockBody) Content(schema *hcl.BodySchema) (*hcl.BodyContent, hcl.Diagnos for _, attr := range remain.C.Attributes { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Extraneous attribute in mock body", - Detail: fmt.Sprintf("Mock body has extraneous attribute %q.", attr.Name), + Summary: "Extraneous argument in mock body", + Detail: fmt.Sprintf("Mock body has extraneous argument %q.", attr.Name), Subject: &attr.NameRange, }) } @@ -63,8 +63,8 @@ func (b mockBody) PartialContent(schema *hcl.BodySchema) (*hcl.BodyContent, hcl. if attrS.Required { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, - Summary: "Missing required attribute", - Detail: fmt.Sprintf("Mock body doesn't have attribute %q", name), + Summary: "Missing required argument", + Detail: fmt.Sprintf("Mock body doesn't have argument %q", name), Subject: b.C.MissingItemRange.Ptr(), }) }