vendor: go get github.com/hashicorp/hcl2@master
This includes a missing feature for the splat syntax (null.* returns an empty tuple) and also fixes a bug in the source code formatter where it was inserting spaces between two consecutive interpolation sequences, like "${foo}${bar}".
This commit is contained in:
parent
b88ef2b47c
commit
787c176063
2
go.mod
2
go.mod
|
@ -72,7 +72,7 @@ require (
|
|||
github.com/hashicorp/go-version v1.0.0
|
||||
github.com/hashicorp/golang-lru v0.5.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0
|
||||
github.com/hashicorp/hcl2 v0.0.0-20181220012050-6631d7cd0a68
|
||||
github.com/hashicorp/hcl2 v0.0.0-20190116200548-7b147fbae47a
|
||||
github.com/hashicorp/hil v0.0.0-20170627220502-fa9f258a9250
|
||||
github.com/hashicorp/logutils v0.0.0-20150609070431-0dc08b1671f3
|
||||
github.com/hashicorp/memberlist v0.1.0 // indirect
|
||||
|
|
14
go.sum
14
go.sum
|
@ -59,7 +59,7 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWs
|
|||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/coreos/bbolt v1.3.0 h1:HIgH5xUWXT914HCI671AxuTTqjj64UOFr7pHn48LUTI=
|
||||
github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible h1:jFneRYjIvLMLhDLCzuTuU4rSJUjRplcJQ7pD7MnhC04=
|
||||
github.com/coreos/etcd v3.3.10+incompatible h1:KjVWqrZ5U0wa3CxY2AxlH6/UcB+PK2td1DcsYhA+HRs=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-semver v0.2.0 h1:3Jm3tLmsgAYcjC+4Up7hJrFBPr+n7rAqYeSw/SZazuY=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
|
@ -110,7 +110,7 @@ github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f h1:JJ2EP5vV3LAD2
|
|||
github.com/gopherjs/gopherjs v0.0.0-20181004151105-1babbf986f6f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:Iju5GlWwrvL6UBg4zJJt3btmonfrMlCDdsejg4CZE7c=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 h1:BWIsLfhgKhV5g/oF34aRjniBHLTZe5DNekSjbAjIS6c=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
|
@ -127,7 +127,7 @@ github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de h1:XDCSyth
|
|||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86 h1:hLYM35twiyKH44g36g+GFYODcrZQetEAY4+zrJtGea0=
|
||||
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86 h1:mv3oKLM8sTaxmU/PrT39T35HRnUfchK+vtzXw6Ci9lY=
|
||||
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86/go.mod h1:6rdJFnhkXnzGOJbvkrdv4t9nLwKcVA+tmbQeUlkIzrU=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f h1:Yv9YzBlAETjy6AOX9eLBZ3nshNVRREgerT/3nvxlGho=
|
||||
|
@ -143,11 +143,11 @@ github.com/hashicorp/go-plugin v0.0.0-20181212150838-f444068e8f5a h1:z9eTtDWoxYr
|
|||
github.com/hashicorp/go-plugin v0.0.0-20181212150838-f444068e8f5a/go.mod h1:Ft7ju2vWzhO0ETMKUVo12XmXmII6eSUS4rsPTkY/siA=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.1 h1:Vsx5XKPqPs3M6sM4U4GWyUqFS8aBiL9U5gkgvpkg4SE=
|
||||
github.com/hashicorp/go-retryablehttp v0.5.1/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
||||
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:VBj0QYQ0u2MCJzBfeYXGexnAl17GsH1yidnoxCqqD9E=
|
||||
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 h1:9HVkPxOpo+yO93Ah4yrO67d/qh0fbLLWbKqhYjyHq9A=
|
||||
github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90/go.mod h1:o4zcYY1e0GEZI6eSEr+43QDYmuGglw1qSO6qdHUHCgg=
|
||||
github.com/hashicorp/go-safetemp v0.0.0-20180326211150-b1a1dbde6fdc h1:wAa9fGALVHfjYxZuXRnmuJG2CnwRpJYOTvY6YdErAh0=
|
||||
github.com/hashicorp/go-safetemp v0.0.0-20180326211150-b1a1dbde6fdc/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
||||
github.com/hashicorp/go-slug v0.2.0 h1:MVdZAkTmDsUi1AT+3NQDsn8n3ssnVSIHwiM6RcUHvE8=
|
||||
github.com/hashicorp/go-slug v0.2.0 h1:gekvezBc+9LwN3qC+lesrz0Qg36hhgge9z/an1FCHx4=
|
||||
github.com/hashicorp/go-slug v0.2.0/go.mod h1:+zDycQOzGqOqMW7Kn2fp9vz/NtqpMLQlgb9JUF+0km4=
|
||||
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86 h1:7YOlAIO2YWnJZkQp7B5eFykaIY7C9JndqAFQyVV5BhM=
|
||||
github.com/hashicorp/go-sockaddr v0.0.0-20180320115054-6d291a969b86/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
|
@ -162,8 +162,8 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/hcl2 v0.0.0-20181208003705-670926858200/go.mod h1:ShfpTh661oAaxo7VcNxg0zcZW6jvMa7Moy2oFx7e5dE=
|
||||
github.com/hashicorp/hcl2 v0.0.0-20181220012050-6631d7cd0a68 h1:d2VhAXrdo8KXWFsn8lNHp5IL0OUXmXMIIlcZBmZa1iU=
|
||||
github.com/hashicorp/hcl2 v0.0.0-20181220012050-6631d7cd0a68/go.mod h1:ShfpTh661oAaxo7VcNxg0zcZW6jvMa7Moy2oFx7e5dE=
|
||||
github.com/hashicorp/hcl2 v0.0.0-20190116200548-7b147fbae47a h1:+RoIWXVNQ9PUkXCKvzE+PlMLU/O0PNI9ItPQ7A0KW88=
|
||||
github.com/hashicorp/hcl2 v0.0.0-20190116200548-7b147fbae47a/go.mod h1:ShfpTh661oAaxo7VcNxg0zcZW6jvMa7Moy2oFx7e5dE=
|
||||
github.com/hashicorp/hil v0.0.0-20170627220502-fa9f258a9250 h1:fooK5IvDL/KIsi4LxF/JH68nVdrBSiGNPhS2JAQjtjo=
|
||||
github.com/hashicorp/hil v0.0.0-20170627220502-fa9f258a9250/go.mod h1:KHvg/R2/dPtaePb16oW4qIyzkMxXOL38xjRN64adsts=
|
||||
github.com/hashicorp/logutils v0.0.0-20150609070431-0dc08b1671f3 h1:oD64EFjELI9RY9yoWlfua58r+etdnoIC871z+rr6lkA=
|
||||
|
|
|
@ -1235,19 +1235,6 @@ func (e *SplatExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
|||
return cty.DynamicVal, diags
|
||||
}
|
||||
|
||||
if sourceVal.IsNull() {
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Splat of null value",
|
||||
Detail: "Splat expressions (with the * symbol) cannot be applied to null values.",
|
||||
Subject: e.Source.Range().Ptr(),
|
||||
Context: hcl.RangeBetween(e.Source.Range(), e.MarkerRange).Ptr(),
|
||||
Expression: e.Source,
|
||||
EvalContext: ctx,
|
||||
})
|
||||
return cty.DynamicVal, diags
|
||||
}
|
||||
|
||||
sourceTy := sourceVal.Type()
|
||||
if sourceTy == cty.DynamicPseudoType {
|
||||
// If we don't even know the _type_ of our source value yet then
|
||||
|
@ -1258,9 +1245,27 @@ func (e *SplatExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
|
|||
|
||||
// A "special power" of splat expressions is that they can be applied
|
||||
// both to tuples/lists and to other values, and in the latter case
|
||||
// the value will be treated as an implicit single-value tuple. We'll
|
||||
// deal with that here first.
|
||||
if !(sourceTy.IsTupleType() || sourceTy.IsListType() || sourceTy.IsSetType()) {
|
||||
// the value will be treated as an implicit single-item tuple, or as
|
||||
// an empty tuple if the value is null.
|
||||
autoUpgrade := !(sourceTy.IsTupleType() || sourceTy.IsListType() || sourceTy.IsSetType())
|
||||
|
||||
if sourceVal.IsNull() {
|
||||
if autoUpgrade {
|
||||
return cty.EmptyTupleVal, diags
|
||||
}
|
||||
diags = append(diags, &hcl.Diagnostic{
|
||||
Severity: hcl.DiagError,
|
||||
Summary: "Splat of null value",
|
||||
Detail: "Splat expressions (with the * symbol) cannot be applied to null sequences.",
|
||||
Subject: e.Source.Range().Ptr(),
|
||||
Context: hcl.RangeBetween(e.Source.Range(), e.MarkerRange).Ptr(),
|
||||
Expression: e.Source,
|
||||
EvalContext: ctx,
|
||||
})
|
||||
return cty.DynamicVal, diags
|
||||
}
|
||||
|
||||
if autoUpgrade {
|
||||
sourceVal = cty.TupleVal([]cty.Value{sourceVal})
|
||||
sourceTy = sourceVal.Type()
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ generation of configuration.
|
|||
|
||||
The language consists of three integrated sub-languages:
|
||||
|
||||
* The _structural_ language defines the overall hierarchical configuration
|
||||
- The _structural_ language defines the overall hierarchical configuration
|
||||
structure, and is a serialization of HCL bodies, blocks and attributes.
|
||||
|
||||
* The _expression_ language is used to express attribute values, either as
|
||||
- The _expression_ language is used to express attribute values, either as
|
||||
literals or as derivations of other values.
|
||||
|
||||
* The _template_ language is used to compose values together into strings,
|
||||
- The _template_ language is used to compose values together into strings,
|
||||
as one of several types of expression in the expression language.
|
||||
|
||||
In normal use these three sub-languages are used together within configuration
|
||||
|
@ -30,19 +30,19 @@ Within this specification a semi-formal notation is used to illustrate the
|
|||
details of syntax. This notation is intended for human consumption rather
|
||||
than machine consumption, with the following conventions:
|
||||
|
||||
* A naked name starting with an uppercase letter is a global production,
|
||||
- A naked name starting with an uppercase letter is a global production,
|
||||
common to all of the syntax specifications in this document.
|
||||
* A naked name starting with a lowercase letter is a local production,
|
||||
- A naked name starting with a lowercase letter is a local production,
|
||||
meaningful only within the specification where it is defined.
|
||||
* Double and single quotes (`"` and `'`) are used to mark literal character
|
||||
- Double and single quotes (`"` and `'`) are used to mark literal character
|
||||
sequences, which may be either punctuation markers or keywords.
|
||||
* The default operator for combining items, which has no punctuation,
|
||||
- The default operator for combining items, which has no punctuation,
|
||||
is concatenation.
|
||||
* The symbol `|` indicates that any one of its left and right operands may
|
||||
- The symbol `|` indicates that any one of its left and right operands may
|
||||
be present.
|
||||
* The `*` symbol indicates zero or more repetitions of the item to its left.
|
||||
* The `?` symbol indicates zero or one of the item to its left.
|
||||
* Parentheses (`(` and `)`) are used to group items together to apply
|
||||
- The `*` symbol indicates zero or more repetitions of the item to its left.
|
||||
- The `?` symbol indicates zero or one of the item to its left.
|
||||
- Parentheses (`(` and `)`) are used to group items together to apply
|
||||
the `|`, `*` and `?` operators to them collectively.
|
||||
|
||||
The grammar notation does not fully describe the language. The prose may
|
||||
|
@ -77,11 +77,11 @@ are not valid within HCL native syntax.
|
|||
|
||||
Comments serve as program documentation and come in two forms:
|
||||
|
||||
* _Line comments_ start with either the `//` or `#` sequences and end with
|
||||
- _Line comments_ start with either the `//` or `#` sequences and end with
|
||||
the next newline sequence. A line comments is considered equivalent to a
|
||||
newline sequence.
|
||||
|
||||
* _Inline comments_ start with the `/*` sequence and end with the `*/`
|
||||
- _Inline comments_ start with the `/*` sequence and end with the `*/`
|
||||
sequence, and may have any characters within except the ending sequence.
|
||||
An inline comments is considered equivalent to a whitespace sequence.
|
||||
|
||||
|
@ -91,7 +91,7 @@ template literals except inside an interpolation sequence or template directive.
|
|||
### Identifiers
|
||||
|
||||
Identifiers name entities such as blocks, attributes and expression variables.
|
||||
Identifiers are interpreted as per [UAX #31][UAX31] Section 2. Specifically,
|
||||
Identifiers are interpreted as per [UAX #31][uax31] Section 2. Specifically,
|
||||
their syntax is defined in terms of the `ID_Start` and `ID_Continue`
|
||||
character properties as follows:
|
||||
|
||||
|
@ -109,7 +109,7 @@ that is not part of the unicode `ID_Continue` definition. This is to allow
|
|||
attribute names and block type names to contain dashes, although underscores
|
||||
as word separators are considered the idiomatic usage.
|
||||
|
||||
[UAX31]: http://unicode.org/reports/tr31/ "Unicode Identifier and Pattern Syntax"
|
||||
[uax31]: http://unicode.org/reports/tr31/ "Unicode Identifier and Pattern Syntax"
|
||||
|
||||
### Keywords
|
||||
|
||||
|
@ -150,9 +150,9 @@ expmark = ('e' | 'E') ("+" | "-")?;
|
|||
The structural language consists of syntax representing the following
|
||||
constructs:
|
||||
|
||||
* _Attributes_, which assign a value to a specified name.
|
||||
* _Blocks_, which create a child body annotated by a type and optional labels.
|
||||
* _Body Content_, which consists of a collection of attributes and blocks.
|
||||
- _Attributes_, which assign a value to a specified name.
|
||||
- _Blocks_, which create a child body annotated by a type and optional labels.
|
||||
- _Body Content_, which consists of a collection of attributes and blocks.
|
||||
|
||||
These constructs correspond to the similarly-named concepts in the
|
||||
language-agnostic HCL information model.
|
||||
|
@ -253,9 +253,9 @@ LiteralValue = (
|
|||
);
|
||||
```
|
||||
|
||||
* Numeric literals represent values of type _number_.
|
||||
* The `true` and `false` keywords represent values of type _bool_.
|
||||
* The `null` keyword represents a null value of the dynamic pseudo-type.
|
||||
- Numeric literals represent values of type _number_.
|
||||
- The `true` and `false` keywords represent values of type _bool_.
|
||||
- The `null` keyword represents a null value of the dynamic pseudo-type.
|
||||
|
||||
String literals are not directly available in the expression sub-language, but
|
||||
are available via the template sub-language, which can in turn be incorporated
|
||||
|
@ -286,8 +286,8 @@ When specifying an object element, an identifier is interpreted as a literal
|
|||
attribute name as opposed to a variable reference. To populate an item key
|
||||
from a variable, use parentheses to disambiguate:
|
||||
|
||||
* `{foo = "baz"}` is interpreted as an attribute literally named `foo`.
|
||||
* `{(foo) = "baz"}` is interpreted as an attribute whose name is taken
|
||||
- `{foo = "baz"}` is interpreted as an attribute literally named `foo`.
|
||||
- `{(foo) = "baz"}` is interpreted as an attribute whose name is taken
|
||||
from the variable named `foo`.
|
||||
|
||||
Between the open and closing delimiters of these sequences, newline sequences
|
||||
|
@ -299,12 +299,12 @@ _for expression_ interpretation has priority, so to produce a tuple whose
|
|||
first element is the value of a variable named `for`, or an object with a
|
||||
key named `for`, use parentheses to disambiguate:
|
||||
|
||||
* `[for, foo, baz]` is a syntax error.
|
||||
* `[(for), foo, baz]` is a tuple whose first element is the value of variable
|
||||
- `[for, foo, baz]` is a syntax error.
|
||||
- `[(for), foo, baz]` is a tuple whose first element is the value of variable
|
||||
`for`.
|
||||
* `{for: 1, baz: 2}` is a syntax error.
|
||||
* `{(for): 1, baz: 2}` is an object with an attribute literally named `for`.
|
||||
* `{baz: 2, for: 1}` is equivalent to the previous example, and resolves the
|
||||
- `{for: 1, baz: 2}` is a syntax error.
|
||||
- `{(for): 1, baz: 2}` is an object with an attribute literally named `for`.
|
||||
- `{baz: 2, for: 1}` is equivalent to the previous example, and resolves the
|
||||
ambiguity by reordering.
|
||||
|
||||
### Template Expressions
|
||||
|
@ -312,9 +312,9 @@ key named `for`, use parentheses to disambiguate:
|
|||
A _template expression_ embeds a program written in the template sub-language
|
||||
as an expression. Template expressions come in two forms:
|
||||
|
||||
* A _quoted_ template expression is delimited by quote characters (`"`) and
|
||||
- A _quoted_ template expression is delimited by quote characters (`"`) and
|
||||
defines a template as a single-line expression with escape characters.
|
||||
* A _heredoc_ template expression is introduced by a `<<` sequence and
|
||||
- A _heredoc_ template expression is introduced by a `<<` sequence and
|
||||
defines a template via a multi-line sequence terminated by a user-chosen
|
||||
delimiter.
|
||||
|
||||
|
@ -322,7 +322,7 @@ In both cases the template interpolation and directive syntax is available for
|
|||
use within the delimiters, and any text outside of these special sequences is
|
||||
interpreted as a literal string.
|
||||
|
||||
In _quoted_ template expressions any literal string sequences within the
|
||||
In _quoted_ template expressions any literal string sequences within the
|
||||
template behave in a special way: literal newline sequences are not permitted
|
||||
and instead _escape sequences_ can be included, starting with the
|
||||
backslash `\`:
|
||||
|
@ -458,14 +458,14 @@ are provided, the first is the key and the second is the value.
|
|||
Tuple, object, list, map, and set types are iterable. The type of collection
|
||||
used defines how the key and value variables are populated:
|
||||
|
||||
* For tuple and list types, the _key_ is the zero-based index into the
|
||||
- For tuple and list types, the _key_ is the zero-based index into the
|
||||
sequence for each element, and the _value_ is the element value. The
|
||||
elements are visited in index order.
|
||||
* For object and map types, the _key_ is the string attribute name or element
|
||||
- For object and map types, the _key_ is the string attribute name or element
|
||||
key, and the _value_ is the attribute or element value. The elements are
|
||||
visited in the order defined by a lexicographic sort of the attribute names
|
||||
or keys.
|
||||
* For set types, the _key_ and _value_ are both the element value. The elements
|
||||
- For set types, the _key_ and _value_ are both the element value. The elements
|
||||
are visited in an undefined but consistent order.
|
||||
|
||||
The expression after the colon and (in the case of object `for`) the expression
|
||||
|
@ -487,12 +487,12 @@ immediately after the value expression, this activates the grouping mode in
|
|||
which each value in the resulting object is a _tuple_ of all of the values
|
||||
that were produced against each distinct key.
|
||||
|
||||
* `[for v in ["a", "b"]: v]` returns `["a", "b"]`.
|
||||
* `[for i, v in ["a", "b"]: i]` returns `[0, 1]`.
|
||||
* `{for i, v in ["a", "b"]: v => i}` returns `{a = 0, b = 1}`.
|
||||
* `{for i, v in ["a", "a", "b"]: k => v}` produces an error, because attribute
|
||||
- `[for v in ["a", "b"]: v]` returns `["a", "b"]`.
|
||||
- `[for i, v in ["a", "b"]: i]` returns `[0, 1]`.
|
||||
- `{for i, v in ["a", "b"]: v => i}` returns `{a = 0, b = 1}`.
|
||||
- `{for i, v in ["a", "a", "b"]: k => v}` produces an error, because attribute
|
||||
`a` is defined twice.
|
||||
* `{for i, v in ["a", "a", "b"]: v => i...}` returns `{a = [0, 1], b = [2]}`.
|
||||
- `{for i, v in ["a", "a", "b"]: v => i...}` returns `{a = [0, 1], b = [2]}`.
|
||||
|
||||
If the `if` keyword is used after the element expression(s), it applies an
|
||||
additional predicate that can be used to conditionally filter elements from
|
||||
|
@ -502,7 +502,7 @@ element expression(s). It must evaluate to a boolean value; if `true`, the
|
|||
element will be evaluated as normal, while if `false` the element will be
|
||||
skipped.
|
||||
|
||||
* `[for i, v in ["a", "b", "c"]: v if i < 2]` returns `["a", "b"]`.
|
||||
- `[for i, v in ["a", "b", "c"]: v if i < 2]` returns `["a", "b"]`.
|
||||
|
||||
If the collection value, element expression(s) or condition expression return
|
||||
unknown values that are otherwise type-valid, the result is a value of the
|
||||
|
@ -567,10 +567,10 @@ elements in a tuple, list, or set value.
|
|||
|
||||
There are two kinds of "splat" operator:
|
||||
|
||||
* The _attribute-only_ splat operator supports only attribute lookups into
|
||||
- The _attribute-only_ splat operator supports only attribute lookups into
|
||||
the elements from a list, but supports an arbitrary number of them.
|
||||
|
||||
* The _full_ splat operator additionally supports indexing into the elements
|
||||
- The _full_ splat operator additionally supports indexing into the elements
|
||||
from a list, and allows any combination of attribute access and index
|
||||
operations.
|
||||
|
||||
|
@ -583,9 +583,9 @@ fullSplat = "[" "*" "]" (GetAttr | Index)*;
|
|||
The splat operators can be thought of as shorthands for common operations that
|
||||
could otherwise be performed using _for expressions_:
|
||||
|
||||
* `tuple.*.foo.bar[0]` is approximately equivalent to
|
||||
- `tuple.*.foo.bar[0]` is approximately equivalent to
|
||||
`[for v in tuple: v.foo.bar][0]`.
|
||||
* `tuple[*].foo.bar[0]` is approximately equivalent to
|
||||
- `tuple[*].foo.bar[0]` is approximately equivalent to
|
||||
`[for v in tuple: v.foo.bar[0]]`
|
||||
|
||||
Note the difference in how the trailing index operator is interpreted in
|
||||
|
@ -597,13 +597,15 @@ _for expressions_ shown above: if a splat operator is applied to a value that
|
|||
is _not_ of tuple, list, or set type, the value is coerced automatically into
|
||||
a single-value list of the value type:
|
||||
|
||||
* `any_object.*.id` is equivalent to `[any_object.id]`, assuming that `any_object`
|
||||
- `any_object.*.id` is equivalent to `[any_object.id]`, assuming that `any_object`
|
||||
is a single object.
|
||||
* `any_number.*` is equivalent to `[any_number]`, assuming that `any_number`
|
||||
- `any_number.*` is equivalent to `[any_number]`, assuming that `any_number`
|
||||
is a single number.
|
||||
|
||||
If the left operand of a splat operator is an unknown value of any type, the
|
||||
result is a value of the dynamic pseudo-type.
|
||||
If applied to a null value that is not tuple, list, or set, the result is always
|
||||
an empty tuple, which allows conveniently converting a possibly-null scalar
|
||||
value into a tuple of zero or one elements. It is illegal to apply a splat
|
||||
operator to a null value of tuple, list, or set type.
|
||||
|
||||
### Operations
|
||||
|
||||
|
@ -684,7 +686,7 @@ Arithmetic operations are considered to be performed in an arbitrary-precision
|
|||
number space.
|
||||
|
||||
If either operand of an arithmetic operator is an unknown number or a value
|
||||
of the dynamic pseudo-type, the result is an unknown number.
|
||||
of the dynamic pseudo-type, the result is an unknown number.
|
||||
|
||||
### Logic Operators
|
||||
|
||||
|
@ -709,7 +711,7 @@ the outcome of a boolean expression.
|
|||
Conditional = Expression "?" Expression ":" Expression;
|
||||
```
|
||||
|
||||
The first expression is the _predicate_, which is evaluated and must produce
|
||||
The first expression is the _predicate_, which is evaluated and must produce
|
||||
a boolean result. If the predicate value is `true`, the result of the second
|
||||
expression is the result of the conditional. If the predicate value is
|
||||
`false`, the result of the third expression is the result of the conditional.
|
||||
|
@ -777,8 +779,8 @@ interpolations or directives that are adjacent to it. A strip marker is
|
|||
a tilde (`~`) placed immediately after the opening `{` or before the closing
|
||||
`}` of a template sequence:
|
||||
|
||||
* `hello ${~ "world" }` produces `"helloworld"`.
|
||||
* `%{ if true ~} hello %{~ endif }` produces `"hello"`.
|
||||
- `hello ${~ "world" }` produces `"helloworld"`.
|
||||
- `%{ if true ~} hello %{~ endif }` produces `"hello"`.
|
||||
|
||||
When a strip marker is present, any spaces adjacent to it in the corresponding
|
||||
string literal (if any) are removed before producing the final value. Space
|
||||
|
@ -787,7 +789,7 @@ characters are interpreted as per Unicode's definition.
|
|||
Stripping is done at syntax level rather than value level. Values returned
|
||||
by interpolations or directives are not subject to stripping:
|
||||
|
||||
* `${"hello" ~}${" world"}` produces `"hello world"`, and not `"helloworld"`,
|
||||
- `${"hello" ~}${" world"}` produces `"hello world"`, and not `"helloworld"`,
|
||||
because the space is not in a template literal directly adjacent to the
|
||||
strip marker.
|
||||
|
||||
|
@ -825,9 +827,9 @@ TemplateIf = (
|
|||
The evaluation of the `if` directive is equivalent to the conditional
|
||||
expression, with the following exceptions:
|
||||
|
||||
* The two sub-templates always produce strings, and thus the result value is
|
||||
- The two sub-templates always produce strings, and thus the result value is
|
||||
also always a string.
|
||||
* The `else` clause may be omitted, in which case the conditional's third
|
||||
- The `else` clause may be omitted, in which case the conditional's third
|
||||
expression result is implied to be the empty string.
|
||||
|
||||
### Template For Directive
|
||||
|
@ -847,9 +849,9 @@ TemplateFor = (
|
|||
The evaluation of the `for` directive is equivalent to the _for expression_
|
||||
when producing a tuple, with the following exceptions:
|
||||
|
||||
* The sub-template always produces a string.
|
||||
* There is no equivalent of the "if" clause on the for expression.
|
||||
* The elements of the resulting tuple are all converted to strings and
|
||||
- The sub-template always produces a string.
|
||||
- There is no equivalent of the "if" clause on the for expression.
|
||||
- The elements of the resulting tuple are all converted to strings and
|
||||
concatenated to produce a flat string result.
|
||||
|
||||
### Template Interpolation Unwrapping
|
||||
|
@ -865,13 +867,13 @@ template or expression syntax. Unwrapping allows arbitrary expressions to be
|
|||
used to populate attributes when strings in such languages are interpreted
|
||||
as templates.
|
||||
|
||||
* `${true}` produces the boolean value `true`
|
||||
* `${"${true}"}` produces the boolean value `true`, because both the inner
|
||||
- `${true}` produces the boolean value `true`
|
||||
- `${"${true}"}` produces the boolean value `true`, because both the inner
|
||||
and outer interpolations are subject to unwrapping.
|
||||
* `hello ${true}` produces the string `"hello true"`
|
||||
* `${""}${true}` produces the string `"true"` because there are two
|
||||
- `hello ${true}` produces the string `"hello true"`
|
||||
- `${""}${true}` produces the string `"true"` because there are two
|
||||
interpolation sequences, even though one produces an empty result.
|
||||
* `%{ for v in [true] }${v}%{ endif }` produces the string `true` because
|
||||
- `%{ for v in [true] }${v}%{ endif }` produces the string `true` because
|
||||
the presence of the `for` directive circumvents the unwrapping even though
|
||||
the final result is a single value.
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@ _Parsing_ such JSON has some additional constraints not beyond what is normally
|
|||
supported by JSON parsers, so a specialized parser may be required that
|
||||
is able to:
|
||||
|
||||
* Preserve the relative ordering of properties defined in an object.
|
||||
* Preserve multiple definitions of the same property name.
|
||||
* Preserve numeric values to the precision required by the number type
|
||||
- Preserve the relative ordering of properties defined in an object.
|
||||
- Preserve multiple definitions of the same property name.
|
||||
- Preserve numeric values to the precision required by the number type
|
||||
in [the HCL syntax-agnostic information model](../spec.md).
|
||||
* Retain source location information for parsed tokens/constructs in order
|
||||
- Retain source location information for parsed tokens/constructs in order
|
||||
to produce good error messages.
|
||||
|
||||
## Structural Elements
|
||||
|
@ -118,6 +118,7 @@ type:
|
|||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"foo": []
|
||||
|
@ -147,7 +148,7 @@ the following examples:
|
|||
"boz": {
|
||||
"baz": {
|
||||
"child_attr": "baz"
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ the following examples:
|
|||
"boz": {
|
||||
"child_attr": "baz"
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
"bar": {
|
||||
|
@ -402,4 +403,3 @@ to that expression.
|
|||
|
||||
If the original expression is not a string or its contents cannot be parsed
|
||||
as a native syntax expression then static call analysis is not supported.
|
||||
|
||||
|
|
|
@ -57,10 +57,10 @@ access to the specific attributes and blocks requested.
|
|||
A _body schema_ consists of a list of _attribute schemata_ and
|
||||
_block header schemata_:
|
||||
|
||||
* An _attribute schema_ provides the name of an attribute and whether its
|
||||
- An _attribute schema_ provides the name of an attribute and whether its
|
||||
presence is required.
|
||||
|
||||
* A _block header schema_ provides a block type name and the semantic names
|
||||
- A _block header schema_ provides a block type name and the semantic names
|
||||
assigned to each of the labels of that block type, if any.
|
||||
|
||||
Within a schema, it is an error to request the same attribute name twice or
|
||||
|
@ -72,11 +72,11 @@ a block whose type name is identical to the attribute name.
|
|||
The result of applying a body schema to a body is _body content_, which
|
||||
consists of an _attribute map_ and a _block sequence_:
|
||||
|
||||
* The _attribute map_ is a map data structure whose keys are attribute names
|
||||
- The _attribute map_ is a map data structure whose keys are attribute names
|
||||
and whose values are _expressions_ that represent the corresponding attribute
|
||||
values.
|
||||
|
||||
* The _block sequence_ is an ordered sequence of blocks, with each specifying
|
||||
- The _block sequence_ is an ordered sequence of blocks, with each specifying
|
||||
a block _type name_, the sequence of _labels_ specified for the block,
|
||||
and the body object (not body _content_) representing the block's own body.
|
||||
|
||||
|
@ -132,13 +132,13 @@ the schema has been processed.
|
|||
|
||||
Specifically:
|
||||
|
||||
* Any attribute whose name is specified in the schema is returned in body
|
||||
- Any attribute whose name is specified in the schema is returned in body
|
||||
content and elided from the new body.
|
||||
|
||||
* Any block whose type is specified in the schema is returned in body content
|
||||
- Any block whose type is specified in the schema is returned in body content
|
||||
and elided from the new body.
|
||||
|
||||
* Any attribute or block _not_ meeting the above conditions is placed into
|
||||
- Any attribute or block _not_ meeting the above conditions is placed into
|
||||
the new body, unmodified.
|
||||
|
||||
The new body can then be recursively processed using any of the body
|
||||
|
@ -168,20 +168,20 @@ In order to obtain a concrete value, each expression must be _evaluated_.
|
|||
Evaluation is performed in terms of an evaluation context, which
|
||||
consists of the following:
|
||||
|
||||
* An _evaluation mode_, which is defined below.
|
||||
* A _variable scope_, which provides a set of named variables for use in
|
||||
- An _evaluation mode_, which is defined below.
|
||||
- A _variable scope_, which provides a set of named variables for use in
|
||||
expressions.
|
||||
* A _function table_, which provides a set of named functions for use in
|
||||
- A _function table_, which provides a set of named functions for use in
|
||||
expressions.
|
||||
|
||||
The _evaluation mode_ allows for two different interpretations of an
|
||||
expression:
|
||||
|
||||
* In _literal-only mode_, variables and functions are not available and it
|
||||
- In _literal-only mode_, variables and functions are not available and it
|
||||
is assumed that the calling application's intent is to treat the attribute
|
||||
value as a literal.
|
||||
|
||||
* In _full expression mode_, variables and functions are defined and it is
|
||||
- In _full expression mode_, variables and functions are defined and it is
|
||||
assumed that the calling application wishes to provide a full expression
|
||||
language for definition of the attribute value.
|
||||
|
||||
|
@ -235,15 +235,15 @@ for interpretation into any suitable number representation. An implementation
|
|||
may in practice implement numbers with limited precision so long as the
|
||||
following constraints are met:
|
||||
|
||||
* Integers are represented with at least 256 bits.
|
||||
* Non-integer numbers are represented as floating point values with a
|
||||
- Integers are represented with at least 256 bits.
|
||||
- Non-integer numbers are represented as floating point values with a
|
||||
mantissa of at least 256 bits and a signed binary exponent of at least
|
||||
16 bits.
|
||||
* An error is produced if an integer value given in source cannot be
|
||||
- An error is produced if an integer value given in source cannot be
|
||||
represented precisely.
|
||||
* An error is produced if a non-integer value cannot be represented due to
|
||||
- An error is produced if a non-integer value cannot be represented due to
|
||||
overflow.
|
||||
* A non-integer number is rounded to the nearest possible value when a
|
||||
- A non-integer number is rounded to the nearest possible value when a
|
||||
value is of too high a precision to be represented.
|
||||
|
||||
The _number_ type also requires representation of both positive and negative
|
||||
|
@ -265,11 +265,11 @@ _Structural types_ are types that are constructed by combining other types.
|
|||
Each distinct combination of other types is itself a distinct type. There
|
||||
are two structural type _kinds_:
|
||||
|
||||
* _Object types_ are constructed of a set of named attributes, each of which
|
||||
- _Object types_ are constructed of a set of named attributes, each of which
|
||||
has a type. Attribute names are always strings. (_Object_ attributes are a
|
||||
distinct idea from _body_ attributes, though calling applications
|
||||
may choose to blur the distinction by use of common naming schemes.)
|
||||
* _Tuple types_ are constructed of a sequence of elements, each of which
|
||||
- _Tuple types_ are constructed of a sequence of elements, each of which
|
||||
has a type.
|
||||
|
||||
Values of structural types are compared for equality in terms of their
|
||||
|
@ -284,9 +284,9 @@ have attributes or elements with identical types.
|
|||
_Collection types_ are types that combine together an arbitrary number of
|
||||
values of some other single type. There are three collection type _kinds_:
|
||||
|
||||
* _List types_ represent ordered sequences of values of their element type.
|
||||
* _Map types_ represent values of their element type accessed via string keys.
|
||||
* _Set types_ represent unordered sets of distinct values of their element type.
|
||||
- _List types_ represent ordered sequences of values of their element type.
|
||||
- _Map types_ represent values of their element type accessed via string keys.
|
||||
- _Set types_ represent unordered sets of distinct values of their element type.
|
||||
|
||||
For each of these kinds and each distinct element type there is a distinct
|
||||
collection type. For example, "list of string" is a distinct type from
|
||||
|
@ -376,9 +376,9 @@ a type has a non-commutative _matches_ relationship with a _type specification_.
|
|||
A type specification is, in practice, just a different interpretation of a
|
||||
type such that:
|
||||
|
||||
* Any type _matches_ any type that it is identical to.
|
||||
- Any type _matches_ any type that it is identical to.
|
||||
|
||||
* Any type _matches_ the dynamic pseudo-type.
|
||||
- Any type _matches_ the dynamic pseudo-type.
|
||||
|
||||
For example, given a type specification "list of dynamic pseudo-type", the
|
||||
concrete types "list of string" and "list of map" match, but the
|
||||
|
@ -397,51 +397,51 @@ applications to provide functions that are interoperable with all syntaxes.
|
|||
|
||||
A _function_ is defined from the following elements:
|
||||
|
||||
* Zero or more _positional parameters_, each with a name used for documentation,
|
||||
- Zero or more _positional parameters_, each with a name used for documentation,
|
||||
a type specification for expected argument values, and a flag for whether
|
||||
each of null values, unknown values, and values of the dynamic pseudo-type
|
||||
are accepted.
|
||||
|
||||
* Zero or one _variadic parameters_, with the same structure as the _positional_
|
||||
- Zero or one _variadic parameters_, with the same structure as the _positional_
|
||||
parameters, which if present collects any additional arguments provided at
|
||||
the function call site.
|
||||
|
||||
* A _result type definition_, which specifies the value type returned for each
|
||||
- A _result type definition_, which specifies the value type returned for each
|
||||
valid sequence of argument values.
|
||||
|
||||
* A _result value definition_, which specifies the value returned for each
|
||||
- A _result value definition_, which specifies the value returned for each
|
||||
valid sequence of argument values.
|
||||
|
||||
A _function call_, regardless of source syntax, consists of a sequence of
|
||||
argument values. The argument values are each mapped to a corresponding
|
||||
parameter as follows:
|
||||
|
||||
* For each of the function's positional parameters in sequence, take the next
|
||||
- For each of the function's positional parameters in sequence, take the next
|
||||
argument. If there are no more arguments, the call is erroneous.
|
||||
|
||||
* If the function has a variadic parameter, take all remaining arguments that
|
||||
- If the function has a variadic parameter, take all remaining arguments that
|
||||
where not yet assigned to a positional parameter and collect them into
|
||||
a sequence of variadic arguments that each correspond to the variadic
|
||||
parameter.
|
||||
|
||||
* If the function has _no_ variadic parameter, it is an error if any arguments
|
||||
- If the function has _no_ variadic parameter, it is an error if any arguments
|
||||
remain after taking one argument for each positional parameter.
|
||||
|
||||
After mapping each argument to a parameter, semantic checking proceeds
|
||||
for each argument:
|
||||
|
||||
* If the argument value corresponding to a parameter does not match the
|
||||
- If the argument value corresponding to a parameter does not match the
|
||||
parameter's type specification, the call is erroneous.
|
||||
|
||||
* If the argument value corresponding to a parameter is null and the parameter
|
||||
- If the argument value corresponding to a parameter is null and the parameter
|
||||
is not specified as accepting nulls, the call is erroneous.
|
||||
|
||||
* If the argument value corresponding to a parameter is the dynamic value
|
||||
- If the argument value corresponding to a parameter is the dynamic value
|
||||
and the parameter is not specified as accepting values of the dynamic
|
||||
pseudo-type, the call is valid but its _result type_ is forced to be the
|
||||
dynamic pseudo type.
|
||||
|
||||
* If neither of the above conditions holds for any argument, the call is
|
||||
- If neither of the above conditions holds for any argument, the call is
|
||||
valid and the function's value type definition is used to determine the
|
||||
call's _result type_. A function _may_ vary its result type depending on
|
||||
the argument _values_ as well as the argument _types_; for example, a
|
||||
|
@ -450,11 +450,11 @@ for each argument:
|
|||
|
||||
If semantic checking succeeds without error, the call is _executed_:
|
||||
|
||||
* For each argument, if its value is unknown and its corresponding parameter
|
||||
- For each argument, if its value is unknown and its corresponding parameter
|
||||
is not specified as accepting unknowns, the _result value_ is forced to be an
|
||||
unknown value of the result type.
|
||||
|
||||
* If the previous condition does not apply, the function's result value
|
||||
- If the previous condition does not apply, the function's result value
|
||||
definition is used to determine the call's _result value_.
|
||||
|
||||
The result of a function call expression is either an error, if one of the
|
||||
|
@ -631,20 +631,20 @@ diagnostics if they are applied to inappropriate expressions.
|
|||
|
||||
The following are the required static analysis functions:
|
||||
|
||||
* **Static List**: Require list/tuple construction syntax to be used and
|
||||
- **Static List**: Require list/tuple construction syntax to be used and
|
||||
return a list of expressions for each of the elements given.
|
||||
|
||||
* **Static Map**: Require map/object construction syntax to be used and
|
||||
- **Static Map**: Require map/object construction syntax to be used and
|
||||
return a list of key/value pairs -- both expressions -- for each of
|
||||
the elements given. The usual constraint that a map key must be a string
|
||||
must not apply to this analysis, thus allowing applications to interpret
|
||||
arbitrary keys as they see fit.
|
||||
|
||||
* **Static Call**: Require function call syntax to be used and return an
|
||||
- **Static Call**: Require function call syntax to be used and return an
|
||||
object describing the called function name and a list of expressions
|
||||
representing each of the call arguments.
|
||||
|
||||
* **Static Traversal**: Require a reference to a symbol in the variable
|
||||
- **Static Traversal**: Require a reference to a symbol in the variable
|
||||
scope and return a description of the path from the root scope to the
|
||||
accessed attribute or index.
|
||||
|
||||
|
@ -670,18 +670,18 @@ with the goals of this specification.
|
|||
The language-agnosticism of this specification assumes that certain behaviors
|
||||
are implemented separately for each syntax:
|
||||
|
||||
* Matching of a body schema with the physical elements of a body in the
|
||||
- Matching of a body schema with the physical elements of a body in the
|
||||
source language, to determine correspondence between physical constructs
|
||||
and schema elements.
|
||||
|
||||
* Implementing the _dynamic attributes_ body processing mode by either
|
||||
- Implementing the _dynamic attributes_ body processing mode by either
|
||||
interpreting all physical constructs as attributes or producing an error
|
||||
if non-attribute constructs are present.
|
||||
|
||||
* Providing an evaluation function for all possible expressions that produces
|
||||
- Providing an evaluation function for all possible expressions that produces
|
||||
a value given an evaluation context.
|
||||
|
||||
* Providing the static analysis functionality described above in a manner that
|
||||
- Providing the static analysis functionality described above in a manner that
|
||||
makes sense within the convention of the syntax.
|
||||
|
||||
The suggested implementation strategy is to use an implementation language's
|
||||
|
|
|
@ -325,6 +325,10 @@ func spaceAfterToken(subject, before, after *Token) bool {
|
|||
case subject.Type == hclsyntax.TokenCBrace && after.Type == hclsyntax.TokenTemplateSeqEnd:
|
||||
return true
|
||||
|
||||
// Don't add spaces between interpolated items
|
||||
case subject.Type == hclsyntax.TokenTemplateSeqEnd && after.Type == hclsyntax.TokenTemplateInterp:
|
||||
return false
|
||||
|
||||
case tokenBracketChange(subject) > 0:
|
||||
// No spaces after open brackets
|
||||
return false
|
||||
|
|
|
@ -351,7 +351,7 @@ github.com/hashicorp/hcl/hcl/scanner
|
|||
github.com/hashicorp/hcl/hcl/strconv
|
||||
github.com/hashicorp/hcl/json/scanner
|
||||
github.com/hashicorp/hcl/json/token
|
||||
# github.com/hashicorp/hcl2 v0.0.0-20181220012050-6631d7cd0a68
|
||||
# github.com/hashicorp/hcl2 v0.0.0-20190116200548-7b147fbae47a
|
||||
github.com/hashicorp/hcl2/hcl
|
||||
github.com/hashicorp/hcl2/hcl/hclsyntax
|
||||
github.com/hashicorp/hcl2/hcldec
|
||||
|
|
Loading…
Reference in New Issue