this is part of a plan to remove SubstitutionResolver (moving the
memoized hash to ResolveContext) and to move the "replacements"
functionality to ResolveSource. Should be clearer.
I think this was a relic of some earlier idea about how to do
things. It was used in one place that could just use the
public NotResolved exception, since it was converted to that
later anyhow.
To avoid error-message regression, we still catch NotResolved
and change it into a NotResolved with a different message in
certain cases.
Also clean up the wording of NotResolved in various places.
Probably NotResolved could just have a zero-parameters constructor.
With this patch, you can write:
path="a🅱️c"
path=${path}":d"
The semantics are somewhat complicated to specify and
implement, but hopefully not complicated to use for
any reasonable usage that makes any sense.
This patch is technically backward incompatible,
illustrated by a change to existing unit tests,
but the changed behavior is in a bizarre corner case:
cyclical self-references where the cycle could be broken
by only partially resolving an object.
This corner case just threw an exception in the version
of this lib included with Akka/Play 2.0, but in commit
a59e31f744 we tried to handle the case. So the behavior
changes since that commit.
The partial resolution case now has the same consistent
defined semantics we use for all self-reference
resolution, that is it "looks back." In the previous
code it would "look forward."
This makes it easier to mess with the parameters needed without
changing every resolveSubstitutions() all over the place.
Really the SubstitutionResolver and ResolveContext should maybe
be merged, but keeping this patch more incremental.
This is probably not different from the depth counter
in practical situations, but it does guarantee 100%
that we are only detecting true cycles. Since we want
true cycles to have different semantics (in a following
patch), I feel better about this implementation.
So we get any reference.conf from the context class loader.
This does NOT fix loading non-default configs, we need new API
to allow passing in a class loader for that. It also makes
things a bit less efficient since it no longer caches;
in the future we could do a per-class-loader cache.
The main idea of this patch is to introduce "partial resolution"
which means resolving only the minimum branch of the object tree
to get to a desired value. By using partial resolution whenever
possible, more interdependencies between substitutions are permitted.
ConfigDelayedMergeObject was a big problem because a lot of the
code in AbstractConfigObject really didn't work on it, because
it assumed a resolved object; much of that code now moves down
to SimpleConfigObject.
The broken behavior was:
foo=10
foo=${?bar}
where 'foo' should be 10 if bar is undefined, but instead
ended up undefined. Now, foo will be 10 (which was the
documented behavior).