mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-09-19 11:09:05 +01:00
TypeGraphParser: Throw custom error types
We can catch these exceptions and print clearer failure messages. Before: unknown file: Failure C++ exception with description "Invalid type for child" thrown in the test body. After: ../test/type_graph_utils.cpp:44: Failure Failed Error parsing input graph: Invalid type for child
This commit is contained in:
parent
31f46831c2
commit
4d96848bdb
@ -49,7 +49,8 @@ Primitive::Kind getKind(std::string_view kindStr) {
|
||||
return Primitive::Kind::UIntPtr;
|
||||
if (kindStr == "void")
|
||||
return Primitive::Kind::Void;
|
||||
throw std::runtime_error("Invalid Primitive::Kind: " + std::string{kindStr});
|
||||
throw TypeGraphParserError{"Invalid Primitive::Kind: " +
|
||||
std::string{kindStr}};
|
||||
}
|
||||
|
||||
ContainerInfo getContainerInfo(std::string_view name) {
|
||||
@ -71,14 +72,14 @@ ContainerInfo getContainerInfo(std::string_view name) {
|
||||
ContainerInfo info{"std::allocator", DUMMY_TYPE, "memory"};
|
||||
return info;
|
||||
}
|
||||
throw std::runtime_error("Unsupported container: " + std::string{name});
|
||||
throw TypeGraphParserError{"Unsupported container: " + std::string{name}};
|
||||
}
|
||||
|
||||
Qualifier getQualifier(std::string_view line) {
|
||||
if (line == "const") {
|
||||
return Qualifier::Const;
|
||||
}
|
||||
throw std::runtime_error("Unsupported qualifier: " + std::string{line});
|
||||
throw TypeGraphParserError{"Unsupported qualifier: " + std::string{line}};
|
||||
}
|
||||
|
||||
size_t stripIndent(std::string_view& line) {
|
||||
@ -96,9 +97,9 @@ bool tryRemovePrefix(std::string_view& line, std::string_view prefix) {
|
||||
|
||||
void removePrefix(std::string_view& line, std::string_view prefix) {
|
||||
if (!tryRemovePrefix(line, prefix))
|
||||
throw std::runtime_error("Unexpected line prefix. Expected '" +
|
||||
std::string{prefix} + "'. Got '" +
|
||||
std::string{line} + "'.");
|
||||
throw TypeGraphParserError{"Unexpected line prefix. Expected '" +
|
||||
std::string{prefix} + "'. Got '" +
|
||||
std::string{line} + "'."};
|
||||
}
|
||||
|
||||
std::optional<uint64_t> tryParseIntAttribute(std::string_view line,
|
||||
@ -120,9 +121,9 @@ uint64_t parseIntAttribute(std::string_view line,
|
||||
std::string_view marker) {
|
||||
auto val = tryParseIntAttribute(line, marker);
|
||||
if (!val)
|
||||
throw std::runtime_error(std::string{type} + " must have an attribute: '" +
|
||||
std::string{marker} + "'. Got: '" +
|
||||
std::string{line} + "'");
|
||||
throw TypeGraphParserError{
|
||||
std::string{type} + " must have an attribute: '" + std::string{marker} +
|
||||
"'. Got: '" + std::string{line} + "'"};
|
||||
return *val;
|
||||
}
|
||||
|
||||
@ -186,8 +187,8 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
||||
|
||||
size_t indent = stripIndent(line) + idLen;
|
||||
if (indent != rootIndent)
|
||||
throw std::runtime_error("Unexpected indent for line: " +
|
||||
std::string{line});
|
||||
throw TypeGraphParserError{"Unexpected indent for line: " +
|
||||
std::string{line}};
|
||||
|
||||
auto nodeEndPos = line.find_first_of(": \n");
|
||||
auto nodeTypeName = line.substr(0, nodeEndPos);
|
||||
@ -196,8 +197,8 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
||||
if (NodeId refId = getId(nodeTypeName); refId != -1) {
|
||||
auto it = nodesById_.find(refId);
|
||||
if (it == nodesById_.end())
|
||||
throw std::runtime_error("Node ID referenced before definition: " +
|
||||
std::to_string(refId));
|
||||
throw TypeGraphParserError{"Node ID referenced before definition: " +
|
||||
std::to_string(refId)};
|
||||
|
||||
type = &it->second.get();
|
||||
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
|
||||
@ -281,8 +282,8 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
||||
type = &typeGraph_.makeType<Pointer>(id, pointeeType);
|
||||
nodesById_.insert({id, *type});
|
||||
} else {
|
||||
throw std::runtime_error("Unsupported node type: " +
|
||||
std::string{nodeTypeName});
|
||||
throw TypeGraphParserError{"Unsupported node type: " +
|
||||
std::string{nodeTypeName}};
|
||||
}
|
||||
|
||||
return *type;
|
||||
@ -413,7 +414,7 @@ void TypeGraphParser::parseChildren(Class& c,
|
||||
Type& type = parseType(input, rootIndent + 2);
|
||||
auto* childClass = dynamic_cast<Class*>(&type);
|
||||
if (!childClass)
|
||||
throw std::runtime_error("Invalid type for child");
|
||||
throw TypeGraphParserError{"Invalid type for child"};
|
||||
|
||||
c.children.push_back(*childClass);
|
||||
}
|
||||
|
@ -35,3 +35,9 @@ class TypeGraphParser {
|
||||
void parseFunctions(Class& c, std::string_view& input, size_t rootIndent);
|
||||
void parseChildren(Class& c, std::string_view& input, size_t rootIndent);
|
||||
};
|
||||
|
||||
class TypeGraphParserError : public std::runtime_error {
|
||||
public:
|
||||
TypeGraphParserError(const std::string& msg) : std::runtime_error{msg} {
|
||||
}
|
||||
};
|
||||
|
@ -38,10 +38,14 @@ void test(type_graph::Pass pass,
|
||||
input.remove_prefix(1); // Remove initial '\n'
|
||||
TypeGraph typeGraph;
|
||||
TypeGraphParser parser{typeGraph};
|
||||
parser.parse(input);
|
||||
try {
|
||||
parser.parse(input);
|
||||
} catch (const TypeGraphParserError& err) {
|
||||
FAIL() << "Error parsing input graph: " << err.what();
|
||||
}
|
||||
|
||||
// Validate input formatting
|
||||
check(typeGraph.rootTypes(), input, " parsing input graph");
|
||||
check(typeGraph.rootTypes(), input, "parsing input graph");
|
||||
|
||||
// Run pass and check results
|
||||
test(pass, typeGraph.rootTypes(), expectedAfter);
|
||||
@ -51,10 +55,14 @@ void testNoChange(type_graph::Pass pass, std::string_view input) {
|
||||
input.remove_prefix(1); // Remove initial '\n'
|
||||
TypeGraph typeGraph;
|
||||
TypeGraphParser parser{typeGraph};
|
||||
parser.parse(input);
|
||||
try {
|
||||
parser.parse(input);
|
||||
} catch (const TypeGraphParserError& err) {
|
||||
FAIL() << "Error parsing input graph: " << err.what();
|
||||
}
|
||||
|
||||
// Validate input formatting
|
||||
check(typeGraph.rootTypes(), input, " parsing input graph");
|
||||
check(typeGraph.rootTypes(), input, "parsing input graph");
|
||||
|
||||
// Run pass and check results
|
||||
test(pass, typeGraph.rootTypes(), input);
|
||||
|
Loading…
Reference in New Issue
Block a user