mirror of
https://github.com/lightbend/config.git
synced 2025-01-28 21:20:07 +08:00
reimplement Path.newPath using the full parser
This commit is contained in:
parent
859dc082bd
commit
d46b068eaf
@ -214,7 +214,7 @@ final class Parser {
|
||||
// now save substitution
|
||||
List<Token> expression = Tokens
|
||||
.getSubstitutionPathExpression(valueToken);
|
||||
Path path = parsePathExpression(expression,
|
||||
Path path = parsePathExpression(expression.iterator(),
|
||||
Tokens.getSubstitutionOrigin(valueToken));
|
||||
minimized.add(path);
|
||||
} else {
|
||||
@ -447,13 +447,14 @@ final class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
private static Path parsePathExpression(List<Token> expression,
|
||||
private static Path parsePathExpression(Iterator<Token> expression,
|
||||
ConfigOrigin origin) {
|
||||
// each builder in "buf" is an element in the path.
|
||||
List<Element> buf = new ArrayList<Element>();
|
||||
buf.add(new Element("", false));
|
||||
|
||||
for (Token t : expression) {
|
||||
while (expression.hasNext()) {
|
||||
Token t = expression.next();
|
||||
if (Tokens.isValueWithType(t, ConfigValueType.STRING)) {
|
||||
AbstractConfigValue v = Tokens.getValue(t);
|
||||
// this is a quoted string; so any periods
|
||||
@ -461,6 +462,11 @@ final class Parser {
|
||||
String s = v.transformToString();
|
||||
|
||||
addPathText(buf, true, s);
|
||||
} else if (t == Tokens.END) {
|
||||
// ignore this; when parsing a file, it should not happen
|
||||
// since we're parsing a token list rather than the main
|
||||
// token iterator, and when parsing a path expression from the
|
||||
// API, it's expected to have an END.
|
||||
} else {
|
||||
// any periods outside of a quoted string count as
|
||||
// separators
|
||||
@ -501,4 +507,14 @@ final class Parser {
|
||||
|
||||
return pb.result();
|
||||
}
|
||||
|
||||
static ConfigOrigin apiOrigin = new SimpleConfigOrigin("path parameter");
|
||||
|
||||
static Path parsePath(String path) {
|
||||
StringReader reader = new StringReader(path);
|
||||
Iterator<Token> tokens = Tokenizer.tokenize(apiOrigin, reader);
|
||||
tokens.next(); // drop START
|
||||
|
||||
return parsePathExpression(tokens, apiOrigin);
|
||||
}
|
||||
}
|
||||
|
@ -101,8 +101,6 @@ final class Path {
|
||||
}
|
||||
|
||||
static Path newPath(String path) {
|
||||
PathBuilder pb = new PathBuilder();
|
||||
pb.appendPath(path);
|
||||
return pb.result();
|
||||
return Parser.parsePath(path);
|
||||
}
|
||||
}
|
||||
|
@ -51,8 +51,10 @@ class ConfParserTest extends TestUtils {
|
||||
}
|
||||
|
||||
private def parsePath(s: String): Path = {
|
||||
// parse first by wrapping into a whole document and using
|
||||
// the regular parser.
|
||||
val tree = parseWithoutResolving("[${" + s + "}]")
|
||||
tree match {
|
||||
val result = tree match {
|
||||
case list: ConfigList =>
|
||||
list.asJavaList().get(0) match {
|
||||
case subst: ConfigSubstitution =>
|
||||
@ -61,6 +63,12 @@ class ConfParserTest extends TestUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
// also parse with the standalone path parser and be sure the
|
||||
// outcome is the same
|
||||
val shouldBeSame = Parser.parsePath(s)
|
||||
assertEquals(result, shouldBeSame)
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -9,10 +9,14 @@ class PathTest extends TestUtils {
|
||||
def pathEquality() {
|
||||
// note: foo.bar is a single key here
|
||||
val a = Path.newKey("foo.bar")
|
||||
// check that newKey worked
|
||||
assertEquals(path("foo.bar"), a);
|
||||
val sameAsA = Path.newKey("foo.bar")
|
||||
val differentKey = Path.newKey("hello")
|
||||
// here foo.bar is two elements
|
||||
val twoElements = Path.newPath("foo.bar")
|
||||
// check that newPath worked
|
||||
assertEquals(path("foo", "bar"), twoElements);
|
||||
val sameAsTwoElements = Path.newPath("foo.bar")
|
||||
|
||||
checkEqualObjects(a, a)
|
||||
@ -24,18 +28,18 @@ class PathTest extends TestUtils {
|
||||
|
||||
@Test
|
||||
def pathToString() {
|
||||
assertEquals("Path(foo)", Path.newPath("foo").toString())
|
||||
assertEquals("Path(foo.bar)", Path.newPath("foo.bar").toString())
|
||||
assertEquals("Path(foo.\"bar*\")", Path.newPath("foo.bar*").toString())
|
||||
assertEquals("Path(\"foo.bar\")", Path.newKey("foo.bar").toString())
|
||||
assertEquals("Path(foo)", path("foo").toString())
|
||||
assertEquals("Path(foo.bar)", path("foo", "bar").toString())
|
||||
assertEquals("Path(foo.\"bar*\")", path("foo", "bar*").toString())
|
||||
assertEquals("Path(\"foo.bar\")", path("foo.bar").toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
def pathRender() {
|
||||
assertEquals("foo", Path.newPath("foo").render())
|
||||
assertEquals("foo.bar", Path.newPath("foo.bar").render())
|
||||
assertEquals("foo.\"bar*\"", Path.newPath("foo.bar*").render())
|
||||
assertEquals("\"foo.bar\"", Path.newKey("foo.bar").render())
|
||||
assertEquals("foo bar", Path.newKey("foo bar").render())
|
||||
assertEquals("foo", path("foo").render())
|
||||
assertEquals("foo.bar", path("foo", "bar").render())
|
||||
assertEquals("foo.\"bar*\"", path("foo", "bar*").render())
|
||||
assertEquals("\"foo.bar\"", path("foo.bar").render())
|
||||
assertEquals("foo bar", path("foo bar").render())
|
||||
}
|
||||
}
|
||||
|
@ -288,5 +288,8 @@ abstract trait TestUtils {
|
||||
tokenize(s).asScala.toList
|
||||
}
|
||||
|
||||
// this is importantly NOT using Path.newPath, which relies on
|
||||
// the parser; in the test suite we are often testing the parser,
|
||||
// so we don't want to use the parser to build the expected result.
|
||||
def path(elements: String*) = new Path(elements: _*)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user