Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions source/dub/internal/configy/Read.d
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,7 @@ public T parseConfigFile (T) (in CLIArgs cmdln, StrictMode strict = StrictMode.E
public T parseConfigString (T) (string data, string path, StrictMode strict = StrictMode.Error)
{
CLIArgs cmdln = { config_path: path };
auto loader = Loader.fromString(data);
loader.name = path;
auto loader = Loader.fromString(data, path);
Node root = loader.load();
return parseConfig!T(cmdln, root, strict);
}
Expand Down
2 changes: 1 addition & 1 deletion source/dub/internal/configy/Test.d
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ unittest
}
catch (ConfigException exc)
{
assert(exc.toString() == "(0:0): chris.jay: Required key was not found in configuration or command line arguments");
assert(exc.toString() == "<unknown>(0:0): chris.jay: Required key was not found in configuration or command line arguments");
}
}

Expand Down
141 changes: 105 additions & 36 deletions source/dub/internal/dyaml/composer.d
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@ import dub.internal.dyaml.resolver;


package:
/**
* Exception thrown at composer errors.
*
* See_Also: MarkedYAMLException
*/
class ComposerException : MarkedYAMLException
{
mixin MarkedExceptionCtors;
}

///Composes YAML documents from events provided by a Parser.
struct Composer
Expand Down Expand Up @@ -70,7 +61,7 @@ struct Composer
* Params: parser = Parser to provide YAML events.
* resolver = Resolver to resolve tags (data types).
*/
this(Parser parser, Resolver resolver) @safe
this(Parser parser, Resolver resolver) @safe nothrow
{
parser_ = parser;
resolver_ = resolver;
Expand Down Expand Up @@ -101,6 +92,22 @@ struct Composer
return composeDocument();
}

/// Set file name.
ref inout(string) name() inout @safe return pure nothrow @nogc
{
return parser_.name;
}
/// Get a mark from the current reader position
Mark mark() const @safe pure nothrow @nogc
{
return parser_.mark;
}

/// Get resolver
ref Resolver resolver() @safe return pure nothrow @nogc {
return resolver_;
}

private:

void skipExpected(const EventID id) @safe
Expand Down Expand Up @@ -158,8 +165,8 @@ struct Composer
//it's not finished, i.e. we're currently composing it
//and trying to use it recursively here.
enforce(anchors_[anchor] != Node(),
new ComposerException("Found recursive alias: " ~ anchor,
event.startMark));
new ComposerException(text("Found recursive alias: ", anchor),
event.startMark, "defined here", anchors_[anchor].startMark));

return anchors_[anchor];
}
Expand All @@ -168,16 +175,18 @@ struct Composer
const anchor = event.anchor;
if((anchor !is null) && (anchor in anchors_) !is null)
{
throw new ComposerException("Found duplicate anchor: " ~ anchor,
event.startMark);
throw new ComposerException(text("Found duplicate anchor: ", anchor),
event.startMark, "defined here", anchors_[anchor].startMark);
}

Node result;
//Associate the anchor, if any, with an uninitialized node.
//used to detect duplicate and recursive anchors.
if(anchor !is null)
{
anchors_[anchor] = Node();
Node tempNode;
tempNode.startMark_ = event.startMark;
anchors_[anchor] = tempNode;
}

switch (parser_.front.id)
Expand Down Expand Up @@ -265,12 +274,10 @@ struct Composer
{
//this is Composer, but the code is related to Constructor.
throw new ConstructorException("While constructing a mapping, " ~
"expected a mapping or a list of " ~
"mappings for merging, but found: " ~
text(node.type) ~
" NOTE: line/column shows topmost parent " ~
"to which the content is being merged",
startMark, endMark);
"expected a mapping or a list of " ~
"mappings for merging, but found: " ~
text(node.type),
endMark, "mapping started here", startMark);
}

ensureAppendersExist(pairAppenderLevel, nodeAppenderLevel);
Expand Down Expand Up @@ -360,14 +367,14 @@ struct Composer
}

auto sorted = pairAppender.data.dup.sort!((x,y) => x.key > y.key);
if (sorted.length) {
if (sorted.length)
{
foreach (index, const ref value; sorted[0 .. $ - 1].enumerate)
if (value.key == sorted[index + 1].key) {
const message = () @trusted {
return format("Key '%s' appears multiple times in mapping (first: %s)",
value.key.get!string, value.key.startMark);
}();
throw new ComposerException(message, sorted[index + 1].key.startMark);
if (value.key == sorted[index + 1].key)
{
throw new ComposerException(
text("Key '", value.key.get!string, "' appears multiple times in mapping"),
sorted[index + 1].key.startMark, "defined here", value.key.startMark);
}
}

Expand All @@ -382,8 +389,7 @@ struct Composer
}

// Provide good error message on multiple keys (which JSON supports)
// DUB: This unittest is `@safe` from v2.100 as `message` was made `@safe`, not before
unittest
@safe unittest
{
import dub.internal.dyaml.loader : Loader;

Expand All @@ -393,10 +399,73 @@ unittest
"comment": "To write down comments pre-JSON5"
}`;

try
auto node = Loader.fromString(str).load();
catch (ComposerException exc)
assert(exc.message() ==
"Key 'comment' appears multiple times in mapping " ~
"(first: file <unknown>,line 2,column 5)\nfile <unknown>,line 4,column 5");
const exc = collectException!LoaderException(Loader.fromString(str).load());
assert(exc);
assert(exc.message() ==
"Unable to load <unknown>: Key 'comment' appears multiple times in mapping\n" ~
"<unknown>:4,5\ndefined here: <unknown>:2,5");
}

// Provide good error message on duplicate anchors
@safe unittest
{
import dub.internal.dyaml.loader : Loader;

const str = `{
a: &anchor b,
b: &anchor c,
}`;

const exc = collectException!LoaderException(Loader.fromString(str).load());
assert(exc);
assert(exc.message() ==
"Unable to load <unknown>: Found duplicate anchor: anchor\n" ~
"<unknown>:3,8\ndefined here: <unknown>:2,8");
}

// Provide good error message on missing alias
@safe unittest
{
import dub.internal.dyaml.loader : Loader;

const str = `{
a: *anchor,
}`;

const exc = collectException!LoaderException(Loader.fromString(str).load());
assert(exc);
assert(exc.message() ==
"Unable to load <unknown>: Found undefined alias: anchor\n" ~
"<unknown>:2,8");
}

// Provide good error message on recursive alias
@safe unittest
{
import dub.internal.dyaml.loader : Loader;

const str = `a: &anchor {
b: *anchor
}`;

const exc = collectException!LoaderException(Loader.fromString(str).load());
assert(exc);
assert(exc.message() ==
"Unable to load <unknown>: Found recursive alias: anchor\n" ~
"<unknown>:2,8\ndefined here: <unknown>:1,4");
}

// Provide good error message on failed merges
@safe unittest
{
import dub.internal.dyaml.loader : Loader;

const str = `a: &anchor 3
b: { <<: *anchor }`;

const exc = collectException!LoaderException(Loader.fromString(str).load());
assert(exc);
assert(exc.message() ==
"Unable to load <unknown>: While constructing a mapping, expected a mapping or a list of mappings for merging, but found: integer\n" ~
"<unknown>:2,19\nmapping started here: <unknown>:2,4");
}
Loading
Loading