Commit Graph

256 Commits

Author SHA1 Message Date
Martin Atkins
2cfc08c632 json: Allow strings to be treated as HIL templates
Eventually zcl will have its own native template format that we'll use
by default, but for applications migrating from HCL/HIL we can instead
parse strings as HIL templates, for compatibility with how JSON configs
would've been processed in a HCL/HIL app.

When this mode is not enabled, we still just treat strings as literals,
pending the implementation of the zcl template parser.
2017-05-21 22:34:23 -07:00
Martin Atkins
e4fdbb6b15 hclhil: interface to treat HIL templates as expressions 2017-05-21 22:09:17 -07:00
Martin Atkins
fde586e193 hclhil: Expression.Value implementation
Currently only deals with the literal HCL structure. Later we will also
support HIL parsing and evaluation within strings, to achieve parity with
existing uses of HCL/HIL together. For now, this has parity with uses of
HCL alone, with the exception that float and int values are not
distinguished, because cty does not make this distinction.
2017-05-21 18:42:39 -07:00
Martin Atkins
0b8f6498ff hclhil: Body.Content and Body.PartialContent implementations 2017-05-21 17:45:31 -07:00
Martin Atkins
764e4c465b hclhil: Parsing and JustAttributes for HCL 2017-05-21 16:13:04 -07:00
Martin Atkins
c5df265cd0 Define Body.JustAttributes as returning Attributes
This was missed when updating the previous direct references to
map[string]*Attribute.
2017-05-21 15:43:41 -07:00
Martin Atkins
e765ff422a zclparse: Stub API for HCL/HIL file parsing
This is intended as a backward-compatibility interface, allowing
applications that previously used HCL/HIL to adopt zcl while still being
able to parse their old HCL/HIL-based configuration file formats.
2017-05-21 13:04:33 -07:00
Martin Atkins
49641f2a9a gozcl: decoding of bodies into structs and maps 2017-05-21 12:44:07 -07:00
Martin Atkins
cd019809a4 json: detect and report insufficient object levels for block labels
When decoding a block with labels, the right number of object levels must
be present to populate the labels.
2017-05-21 12:42:42 -07:00
Martin Atkins
8654cf0361 Body.MissingItemRange method
When producing diagnostics about missing attributes or bodies it's
necessary to have a range representing the place where the missing thing
might be inserted.

There's not always a single reasonable value for this, so some liberty
can be taken about what exactly is returned as long as it's somewhere
the user can relate back to the construct producing the error.
2017-05-21 11:46:58 -07:00
Martin Atkins
5fa767a43a json: mark properties as used after blocks are decoded from them 2017-05-21 11:03:47 -07:00
Martin Atkins
64c1036f80 Remove "ExprRange" from zcl.Attribute
Now that expressions themselves have Range and StartRange methods, this
is redundant.
2017-05-21 09:50:29 -07:00
Martin Atkins
4fcad1f493 json: Respect hiddenAttrs in JustAttributes
Previously it was leaking out hidden attributes.
2017-05-21 09:46:50 -07:00
Martin Atkins
a291478c78 "Attributes" type for map[string]*Attribute
This is primarily for symmetry with "Blocks", but perhaps it will also
get some useful methods later.
2017-05-21 09:05:06 -07:00
Martin Atkins
5b8d54380b gozcl: DecodeExpression implementation
This is really just a wrapper around converting the value to a Go native
value with gocty, but is convenient to provide since it can attempt
type conversion and produce diagnostics automatically.
2017-05-21 08:47:05 -07:00
Martin Atkins
bb5044d015 Range and StartRange methods on Expression
This gives us some contextual information to use for error handling when
working generically with expressions.
2017-05-20 17:40:03 -07:00
Martin Atkins
802ea19d72 gozcl: stub of the Decode functions 2017-05-20 17:30:02 -07:00
Martin Atkins
17cf497b6e gozcl: ImpliedBodySchema derives a body schema from a Go struct 2017-05-20 16:47:14 -07:00
Martin Atkins
0612bb9843 gozcl: new package for decoding zcl data into native Go values 2017-05-20 16:46:54 -07:00
Martin Atkins
dfafa6fc00 Flesh out interface for evaluating expressions
Expressions can now be evaluated within an "EvalContext", which provides
the variable and function scopes. The JSON implementation of this
currently ignores the context entirely and just returns literal values,
since we've not yet implemented the template language parser that would
be needed for the JSON parser to properly support expressions.
2017-05-20 15:17:56 -07:00
Martin Atkins
92e407e672 Body.JustAttributes method
The Content and PartialContent methods deal with the case where the caller
knows what structure is expected within the body, but sometimes the
structure of a body is just a free-form set of attributes that the caller
needs to enumerate.

The idea here is that the block in question must contain only attributes,
and no child blocks. For JSON this just entails interpreting every
property as an attribute. For native syntax later this will mean
producing an error diagnostic if any blocks appear within the body.
2017-05-20 14:35:19 -07:00
Martin Atkins
4bbfa6d6ab json: recovery behavior for the parser
When using the parser to do static analysis and editor integrations, it's
still useful to be able to get the incomplete AST resulting from a parse
error.

Callers that intend to use the returned value to take real actions (as
opposed to just analysis) must check diags.HasError() to determine if
the returned file can be considered valid.
2017-05-20 13:32:12 -07:00
Martin Atkins
341223612b MergeBodies return value now works as a Body
Its implementation calls into each of the child bodies in turn and merges
the result to produce a single BodyContent. This is intended to support
the case of a directory being the unit of configuration rather than a
file, with the calling application discovering and parsing each of the
files in its workspace and then merging them together for processing as
a single configuration.
2017-05-20 12:45:43 -07:00
Martin Atkins
873a4d07b5 json: improve error message for duplicate property
We need to be careful to keep straight the distinction between JSON
properties and zcl body attributes here, since properties can represent
both attributes _and_ blocks.
2017-05-20 11:12:03 -07:00
Martin Atkins
45f97bf427 json: Implement Body.Content
This is a wrapper around Body.PartialContent that generates additional
error diagnostics if any object properties are left over after decoding,
helping the config author to catch typos that would otherwise have caused
a property to be silently ignored.
2017-05-20 09:50:48 -07:00
Martin Atkins
17d372677d json: Generalize "keywordSuggestion" for general name suggestions
keywordSuggestion is now a wrapper around nameSuggestion with a predefined
list of names.
2017-05-20 09:45:15 -07:00
Martin Atkins
aa13eab21f json: Don't suppress parser return value on errors
Even if errors were encountered during parsing, it is helpful to still
return a partial AST if possible since that allows for the source code
analysis features to still (partially) work in the face of errors.
2017-05-20 09:30:04 -07:00
Martin Atkins
69164859c8 json: Tests for Body.PartialContent 2017-05-20 08:56:55 -07:00
Martin Atkins
8883fb76ce json: include NameRange and ExprRange in returned attributes 2017-05-20 08:56:41 -07:00
Martin Atkins
d2c9089812 json: ContextString implementation
This JSON-flavored ContextString implementation returns a chain of
property names using JavaScript-style attribute access syntax.
2017-05-19 19:33:58 -07:00
Martin Atkins
a940c30903 Mechanism for introspection of source code for editors
The new "Nav" member on a zcl.File is an opaque object that can be
populated by parsers with an object that supports certain interfaces
that are not part of the main API but are useful for integration with
editors and other tooling.

As a first example of this, we replace the hack for getting context in
the diagnostic package with a new ContextString interface, which can
then be optionally implemented by a given parser to return a contextual
string native to the source language.
2017-05-19 19:33:58 -07:00
Martin Atkins
1168f36be5 json: start of low-level decoding 2017-05-19 19:33:58 -07:00
Martin Atkins
ca6c6b127c Initial support for printing out diagnostics
The indication of specific characters in the source code that are in
error is not yet implemented, but this gets at the main functionality
of printing diagnostics.
2017-05-18 19:01:41 -07:00
Martin Atkins
cdefa254c9 zclparse: new package for the primary parser API
Although the actual parsing code will be split across multiple packages,
it's convenient for the public interface to be in a single package. The
parsers are accessed through a "Parser" type, which both wraps the
real parsers and maintains a registry of parsed files to ensure that
the same file isn't parsed more than once (which might be confusing if
there are different results) and to provide raw source code for
diagnostic-printing functions.

The parser API is in a separate package both due to the fundamental
problem that it would create an import cycle if included in the main
package and also because it's expected that calling applications will
deal with parsing once in a central place (a single file depending on
zclparse) but the resulting objects will be used broadly across the
application, causing many files to depend on the main zcl package.
2017-05-18 08:41:48 -07:00
Martin Atkins
1ecde9204c Interface for treating several files as one file
Some applications treat an entire directory as a configuration, merging
the configurations from all of the files in a directory and treating them
as one.

MergeFiles supports this idea by wrapping the bodies of the several files.
It's not yet implemented here, but once implemented it will act as an
aggregator of the content of the wrapped bodies, delegating to them for
actual body content and then merging the returned body content in a
well-defined way.
2017-05-18 08:10:21 -07:00
Martin Atkins
41527d1a3c Retain the bytes used to construct a file
Later on this will be useful when printing diagnostics with source code
snippets as context.
2017-05-18 08:07:52 -07:00
Martin Atkins
160f56abb1 json: beginnings of parsing JSON into File objects
The returned file objects are not actually functional yet, but this
establishes the interface.
2017-05-18 07:57:04 -07:00
Martin Atkins
87677ae03a Rename "Element" to "Block"
The term "element" is already used for an item from a collection in cty,
so we'll use "block" to talk about the nested blocks in a zcl config to
reduce confusion.
2017-05-18 07:21:21 -07:00
Martin Atkins
eca76d650c json: Detect and report extraneous data at EOF 2017-05-17 07:59:41 -07:00
Martin Atkins
0ef4932962 json: parsing of arrays
(and assorted bugfixes in parsing of objects that were found in the
process of adapting that code for arrays.)
2017-05-17 07:55:21 -07:00
Martin Atkins
b073937523 json: Basic parsing of number values 2017-05-17 07:34:33 -07:00
Martin Atkins
4100bdfd2f json: Parsing of strings and objects 2017-05-16 08:00:07 -07:00
Martin Atkins
b5a78fd826 Helper for determining if a Diagnostics contains errors
Checking if it's non-nil, as we would for Go errors, doesn't work here
because there may be warnings.
2017-05-16 07:58:34 -07:00
Martin Atkins
8dfc3c4bbe json: fix overly-greedy keyword scanning
Logic error in the scanner caused it to always consume the remainder of
the string.
2017-05-16 07:23:33 -07:00
Martin Atkins
bd0cbc1c81 more detailed default stringification of diagnostics 2017-05-16 07:22:56 -07:00
Martin Atkins
66c38447d3 json: fix buggy peeker.Read 2017-05-16 06:51:19 -07:00
Martin Atkins
f6bd122f4b json: parsing of keywords 2017-05-16 06:51:19 -07:00
Martin Atkins
f754328a91 json: beginnings of parser
Only supports parsing objects right now, and even then doesn't really
because objects have to contain strings and that isn't implemented yet.
2017-05-15 08:35:32 -07:00
Martin Atkins
377e20b7b8 json: AST node types 2017-05-15 08:34:35 -07:00
Martin Atkins
838a0332e6 json: token peeker
This will help our hand-written recursive-descent parser walk the tokens
with one token of lookahead.
2017-05-15 08:34:00 -07:00