I don't think they made sense:
- "fallback lists" in substitutions can already be done another way
- the "delete" operator isn't clearly useful and feels imperative
rather than declarative
The earlier change to make ${user.home} in a file included underneath
"foo" search both ${foo.user.home} and then ${user.home}, means
that even in included files system props are picked up just fine
as long as they were merged into the root config. So there is no
longer any need to have a special-case fallback to system properties.
This leaves ConfigResolveOptions as a really complex way to pass
in a single bool, but of course the point is to allow for future
extension.
This should lay the groundwork for removing the special case fallback
to system properties, and allows included files to look at the reference
configuration.
Avoids confusion because ConfigValue.toValue was pointless and
Config.toValue was not as clear as Config.root (plus having two ways
to do it on Config was strange).
This change does require a cast in the withFallback implementation but
we already have the analogous pattern all over the place (i.e. assuming that
instances of the public interfaces are always instances of our private
implementations).
One side effect of this is that if an object merge does nothing, the ConfigOrigin
for the fallback is discarded instead of merged in, but I think that's OK.
currently needed for files that are included in other files.
not really happy with how this works now, but documenting it
as a starting point.
maybe to force a substitution to resolve from the root we could
start it with a period? ${.this.is.a.root.prop} ?
This allows verifying that a config has all the keys it's supposed
to have, and also that they have plausible value types. It uses
a reference config as a kind of very loose schema.
Another benefit is that it can give users a big batch of error
messages at once, rather than one at a time via exceptions
when config settings are used.
Because the reference config is not really a schema, users of
checkValid() may have to tune its behavior by removing some
things from the reference config used for validation, or
ignoring certain errors, or doing additional validation
on their own. But checkValid() is a good basic validator
for all your simple settings and if you have complex
settings you can write additional code to support them
while still using checkValid() for the simple ones.
The main case that motivated this was:
a.b.c = 1
a.b.x = 2
where the two a.b objects are merged. With this patch, ConfigOrigin
still reports the filename only once, and correctly, for the a.b
object.
When we see a newline token, its number is the line it was on
(i.e. the line just ended) not the line we are now on.
This was correct in one place in Parser.java but not
in the other place.