mirror of
https://github.com/JakeHillion/object-introspection.git
synced 2024-11-09 21:24:14 +00: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;
|
return Primitive::Kind::UIntPtr;
|
||||||
if (kindStr == "void")
|
if (kindStr == "void")
|
||||||
return Primitive::Kind::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) {
|
ContainerInfo getContainerInfo(std::string_view name) {
|
||||||
@ -71,14 +72,14 @@ ContainerInfo getContainerInfo(std::string_view name) {
|
|||||||
ContainerInfo info{"std::allocator", DUMMY_TYPE, "memory"};
|
ContainerInfo info{"std::allocator", DUMMY_TYPE, "memory"};
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Unsupported container: " + std::string{name});
|
throw TypeGraphParserError{"Unsupported container: " + std::string{name}};
|
||||||
}
|
}
|
||||||
|
|
||||||
Qualifier getQualifier(std::string_view line) {
|
Qualifier getQualifier(std::string_view line) {
|
||||||
if (line == "const") {
|
if (line == "const") {
|
||||||
return Qualifier::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) {
|
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) {
|
void removePrefix(std::string_view& line, std::string_view prefix) {
|
||||||
if (!tryRemovePrefix(line, prefix))
|
if (!tryRemovePrefix(line, prefix))
|
||||||
throw std::runtime_error("Unexpected line prefix. Expected '" +
|
throw TypeGraphParserError{"Unexpected line prefix. Expected '" +
|
||||||
std::string{prefix} + "'. Got '" +
|
std::string{prefix} + "'. Got '" +
|
||||||
std::string{line} + "'.");
|
std::string{line} + "'."};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<uint64_t> tryParseIntAttribute(std::string_view 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) {
|
std::string_view marker) {
|
||||||
auto val = tryParseIntAttribute(line, marker);
|
auto val = tryParseIntAttribute(line, marker);
|
||||||
if (!val)
|
if (!val)
|
||||||
throw std::runtime_error(std::string{type} + " must have an attribute: '" +
|
throw TypeGraphParserError{
|
||||||
std::string{marker} + "'. Got: '" +
|
std::string{type} + " must have an attribute: '" + std::string{marker} +
|
||||||
std::string{line} + "'");
|
"'. Got: '" + std::string{line} + "'"};
|
||||||
return *val;
|
return *val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,8 +187,8 @@ Type& TypeGraphParser::parseType(std::string_view& input, size_t rootIndent) {
|
|||||||
|
|
||||||
size_t indent = stripIndent(line) + idLen;
|
size_t indent = stripIndent(line) + idLen;
|
||||||
if (indent != rootIndent)
|
if (indent != rootIndent)
|
||||||
throw std::runtime_error("Unexpected indent for line: " +
|
throw TypeGraphParserError{"Unexpected indent for line: " +
|
||||||
std::string{line});
|
std::string{line}};
|
||||||
|
|
||||||
auto nodeEndPos = line.find_first_of(": \n");
|
auto nodeEndPos = line.find_first_of(": \n");
|
||||||
auto nodeTypeName = line.substr(0, nodeEndPos);
|
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) {
|
if (NodeId refId = getId(nodeTypeName); refId != -1) {
|
||||||
auto it = nodesById_.find(refId);
|
auto it = nodesById_.find(refId);
|
||||||
if (it == nodesById_.end())
|
if (it == nodesById_.end())
|
||||||
throw std::runtime_error("Node ID referenced before definition: " +
|
throw TypeGraphParserError{"Node ID referenced before definition: " +
|
||||||
std::to_string(refId));
|
std::to_string(refId)};
|
||||||
|
|
||||||
type = &it->second.get();
|
type = &it->second.get();
|
||||||
} else if (nodeTypeName == "Class" || nodeTypeName == "Struct" ||
|
} 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);
|
type = &typeGraph_.makeType<Pointer>(id, pointeeType);
|
||||||
nodesById_.insert({id, *type});
|
nodesById_.insert({id, *type});
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Unsupported node type: " +
|
throw TypeGraphParserError{"Unsupported node type: " +
|
||||||
std::string{nodeTypeName});
|
std::string{nodeTypeName}};
|
||||||
}
|
}
|
||||||
|
|
||||||
return *type;
|
return *type;
|
||||||
@ -413,7 +414,7 @@ void TypeGraphParser::parseChildren(Class& c,
|
|||||||
Type& type = parseType(input, rootIndent + 2);
|
Type& type = parseType(input, rootIndent + 2);
|
||||||
auto* childClass = dynamic_cast<Class*>(&type);
|
auto* childClass = dynamic_cast<Class*>(&type);
|
||||||
if (!childClass)
|
if (!childClass)
|
||||||
throw std::runtime_error("Invalid type for child");
|
throw TypeGraphParserError{"Invalid type for child"};
|
||||||
|
|
||||||
c.children.push_back(*childClass);
|
c.children.push_back(*childClass);
|
||||||
}
|
}
|
||||||
|
@ -35,3 +35,9 @@ class TypeGraphParser {
|
|||||||
void parseFunctions(Class& c, std::string_view& input, size_t rootIndent);
|
void parseFunctions(Class& c, std::string_view& input, size_t rootIndent);
|
||||||
void parseChildren(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'
|
input.remove_prefix(1); // Remove initial '\n'
|
||||||
TypeGraph typeGraph;
|
TypeGraph typeGraph;
|
||||||
TypeGraphParser parser{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
|
// Validate input formatting
|
||||||
check(typeGraph.rootTypes(), input, " parsing input graph");
|
check(typeGraph.rootTypes(), input, "parsing input graph");
|
||||||
|
|
||||||
// Run pass and check results
|
// Run pass and check results
|
||||||
test(pass, typeGraph.rootTypes(), expectedAfter);
|
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'
|
input.remove_prefix(1); // Remove initial '\n'
|
||||||
TypeGraph typeGraph;
|
TypeGraph typeGraph;
|
||||||
TypeGraphParser parser{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
|
// Validate input formatting
|
||||||
check(typeGraph.rootTypes(), input, " parsing input graph");
|
check(typeGraph.rootTypes(), input, "parsing input graph");
|
||||||
|
|
||||||
// Run pass and check results
|
// Run pass and check results
|
||||||
test(pass, typeGraph.rootTypes(), input);
|
test(pass, typeGraph.rootTypes(), input);
|
||||||
|
Loading…
Reference in New Issue
Block a user