Merge pull request #1810 from ethereum/compactJson

Compact format for AST-Json.
This commit is contained in:
chriseth 2017-05-22 14:33:46 +02:00 committed by GitHub
commit 8eead553af
15 changed files with 579 additions and 495 deletions

View File

@ -1,4 +1,5 @@
### 0.4.12 (unreleased) ### 0.4.12 (unreleased)
* AST: export all attributes to Json format
### 0.4.11 (2017-05-03) ### 0.4.11 (2017-05-03)

View File

@ -1238,13 +1238,17 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
if (auto const* typeType = dynamic_cast<TypeType const*>(expressionType.get())) if (auto const* typeType = dynamic_cast<TypeType const*>(expressionType.get()))
{ {
_functionCall.annotation().isStructConstructorCall = (typeType->actualType()->category() == Type::Category::Struct); if (typeType->actualType()->category() == Type::Category::Struct)
_functionCall.annotation().isTypeConversion = !_functionCall.annotation().isStructConstructorCall; _functionCall.annotation().kind = FunctionCallKind::StructConstructorCall;
else
_functionCall.annotation().kind = FunctionCallKind::TypeConversion;
} }
else else
_functionCall.annotation().isStructConstructorCall = _functionCall.annotation().isTypeConversion = false; _functionCall.annotation().kind = FunctionCallKind::FunctionCall;
solAssert(_functionCall.annotation().kind != FunctionCallKind::Unset, "");
if (_functionCall.annotation().isTypeConversion) if (_functionCall.annotation().kind == FunctionCallKind::TypeConversion)
{ {
TypeType const& t = dynamic_cast<TypeType const&>(*expressionType); TypeType const& t = dynamic_cast<TypeType const&>(*expressionType);
TypePointer resultType = t.actualType(); TypePointer resultType = t.actualType();
@ -1274,7 +1278,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
/// For error message: Struct members that were removed during conversion to memory. /// For error message: Struct members that were removed during conversion to memory.
set<string> membersRemovedForStructConstructor; set<string> membersRemovedForStructConstructor;
if (_functionCall.annotation().isStructConstructorCall) if (_functionCall.annotation().kind == FunctionCallKind::StructConstructorCall)
{ {
TypeType const& t = dynamic_cast<TypeType const&>(*expressionType); TypeType const& t = dynamic_cast<TypeType const&>(*expressionType);
auto const& structType = dynamic_cast<StructType const&>(*t.actualType()); auto const& structType = dynamic_cast<StructType const&>(*t.actualType());
@ -1312,7 +1316,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
toString(parameterTypes.size()) + toString(parameterTypes.size()) +
"."; ".";
// Extend error message in case we try to construct a struct with mapping member. // Extend error message in case we try to construct a struct with mapping member.
if (_functionCall.annotation().isStructConstructorCall && !membersRemovedForStructConstructor.empty()) if (_functionCall.annotation().kind == FunctionCallKind::StructConstructorCall && !membersRemovedForStructConstructor.empty())
{ {
msg += " Members that have to be skipped in memory:"; msg += " Members that have to be skipped in memory:";
for (auto const& member: membersRemovedForStructConstructor) for (auto const& member: membersRemovedForStructConstructor)

View File

@ -583,8 +583,7 @@ public:
bool isPayable() const { return m_isPayable; } bool isPayable() const { return m_isPayable; }
std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; } std::vector<ASTPointer<ModifierInvocation>> const& modifiers() const { return m_functionModifiers; }
std::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); } std::vector<ASTPointer<VariableDeclaration>> const& returnParameters() const { return m_returnParameters->parameters(); }
Block const& body() const { return *m_body; } Block const& body() const { solAssert(m_body, ""); return *m_body; }
virtual bool isVisibleInContract() const override virtual bool isVisibleInContract() const override
{ {
return Declaration::isVisibleInContract() && !isConstructor() && !name().empty(); return Declaration::isVisibleInContract() && !isConstructor() && !name().empty();
@ -1314,7 +1313,7 @@ private:
/** /**
* Tuple, parenthesized expression, or bracketed expression. * Tuple, parenthesized expression, or bracketed expression.
* Examples: (1, 2), (x,), (x), (), [1, 2], * Examples: (1, 2), (x,), (x), (), [1, 2],
* Individual components might be empty shared pointers (as in the second example). * Individual components might be empty shared pointers (as in the second example).
* The respective types in lvalue context are: 2-tuple, 2-tuple (with wildcard), type of x, 0-tuple * The respective types in lvalue context are: 2-tuple, 2-tuple (with wildcard), type of x, 0-tuple
* Not in lvalue context: 2-tuple, _1_-tuple, type of x, 0-tuple. * Not in lvalue context: 2-tuple, _1_-tuple, type of x, 0-tuple.
@ -1327,8 +1326,8 @@ public:
std::vector<ASTPointer<Expression>> const& _components, std::vector<ASTPointer<Expression>> const& _components,
bool _isArray bool _isArray
): ):
Expression(_location), Expression(_location),
m_components(_components), m_components(_components),
m_isArray(_isArray) {} m_isArray(_isArray) {}
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;

View File

@ -200,12 +200,17 @@ struct BinaryOperationAnnotation: ExpressionAnnotation
TypePointer commonType; TypePointer commonType;
}; };
enum class FunctionCallKind
{
Unset,
FunctionCall,
TypeConversion,
StructConstructorCall
};
struct FunctionCallAnnotation: ExpressionAnnotation struct FunctionCallAnnotation: ExpressionAnnotation
{ {
/// Whether this is an explicit type conversion. FunctionCallKind kind = FunctionCallKind::Unset;
bool isTypeConversion = false;
/// Whether this is a struct constructor call.
bool isStructConstructorCall = false;
}; };
} }

File diff suppressed because it is too large Load Diff

View File

@ -42,15 +42,23 @@ class ASTJsonConverter: public ASTConstVisitor
{ {
public: public:
/// Create a converter to JSON for the given abstract syntax tree. /// Create a converter to JSON for the given abstract syntax tree.
/// @a _legacy if true, use legacy format
/// @a _sourceIndices is used to abbreviate source names in source locations. /// @a _sourceIndices is used to abbreviate source names in source locations.
explicit ASTJsonConverter( explicit ASTJsonConverter(
ASTNode const& _ast, bool _legacy,
std::map<std::string, unsigned> _sourceIndices = std::map<std::string, unsigned>() std::map<std::string, unsigned> _sourceIndices = std::map<std::string, unsigned>()
); );
/// Output the json representation of the AST to _stream. /// Output the json representation of the AST to _stream.
void print(std::ostream& _stream); void print(std::ostream& _stream, ASTNode const& _node);
Json::Value const& json(); Json::Value toJson(ASTNode const& _node);
template <class T>
Json::Value toJson(std::vector<ASTPointer<T>> const& _nodes)
{
Json::Value ret(Json::arrayValue);
for (auto const& n: _nodes)
ret.append(n ? toJson(*n) : Json::nullValue);
return ret;
}
bool visit(SourceUnit const& _node) override; bool visit(SourceUnit const& _node) override;
bool visit(PragmaDirective const& _node) override; bool visit(PragmaDirective const& _node) override;
bool visit(ImportDirective const& _node) override; bool visit(ImportDirective const& _node) override;
@ -97,82 +105,60 @@ public:
bool visit(ElementaryTypeNameExpression const& _node) override; bool visit(ElementaryTypeNameExpression const& _node) override;
bool visit(Literal const& _node) override; bool visit(Literal const& _node) override;
void endVisit(SourceUnit const&) override;
void endVisit(PragmaDirective const&) override;
void endVisit(ImportDirective const&) override;
void endVisit(ContractDefinition const&) override;
void endVisit(InheritanceSpecifier const&) override;
void endVisit(UsingForDirective const&) override;
void endVisit(StructDefinition const&) override;
void endVisit(EnumDefinition const&) override;
void endVisit(EnumValue const&) override;
void endVisit(ParameterList const&) override;
void endVisit(FunctionDefinition const&) override;
void endVisit(VariableDeclaration const&) override;
void endVisit(ModifierDefinition const&) override;
void endVisit(ModifierInvocation const&) override;
void endVisit(EventDefinition const&) override; void endVisit(EventDefinition const&) override;
void endVisit(TypeName const&) override;
void endVisit(ElementaryTypeName const&) override;
void endVisit(UserDefinedTypeName const&) override;
void endVisit(FunctionTypeName const&) override;
void endVisit(Mapping const&) override;
void endVisit(ArrayTypeName const&) override;
void endVisit(InlineAssembly const&) override;
void endVisit(Block const&) override;
void endVisit(PlaceholderStatement const&) override;
void endVisit(IfStatement const&) override;
void endVisit(WhileStatement const&) override;
void endVisit(ForStatement const&) override;
void endVisit(Continue const&) override;
void endVisit(Break const&) override;
void endVisit(Return const&) override;
void endVisit(Throw const&) override;
void endVisit(VariableDeclarationStatement const&) override;
void endVisit(ExpressionStatement const&) override;
void endVisit(Conditional const&) override;
void endVisit(Assignment const&) override;
void endVisit(TupleExpression const&) override;
void endVisit(UnaryOperation const&) override;
void endVisit(BinaryOperation const&) override;
void endVisit(FunctionCall const&) override;
void endVisit(NewExpression const&) override;
void endVisit(MemberAccess const&) override;
void endVisit(IndexAccess const&) override;
void endVisit(Identifier const&) override;
void endVisit(ElementaryTypeNameExpression const&) override;
void endVisit(Literal const&) override;
private: private:
void process(); void setJsonNode(
void addJsonNode(
ASTNode const& _node, ASTNode const& _node,
std::string const& _nodeName, std::string const& _nodeName,
std::initializer_list<std::pair<std::string const, Json::Value const>> _attributes, std::initializer_list<std::pair<std::string, Json::Value>>&& _attributes
bool _hasChildren
); );
void addJsonNode( void setJsonNode(
ASTNode const& _node, ASTNode const& _node,
std::string const& _nodeName, std::string const& _nodeName,
std::vector<std::pair<std::string const, Json::Value const>> const& _attributes, std::vector<std::pair<std::string, Json::Value>>&& _attributes
bool _hasChildren
); );
std::string sourceLocationToString(SourceLocation const& _location) const; std::string sourceLocationToString(SourceLocation const& _location) const;
std::string namePathToString(std::vector<ASTString> const& _namePath) const;
Json::Value idOrNull(ASTNode const* _pt)
{
return _pt ? Json::Value(nodeId(*_pt)) : Json::nullValue;
}
Json::Value toJsonOrNull(ASTNode const* _node)
{
return _node ? toJson(*_node) : Json::nullValue;
}
Json::Value inlineAssemblyIdentifierToJson(std::pair<assembly::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info);
std::string visibility(Declaration::Visibility const& _visibility); std::string visibility(Declaration::Visibility const& _visibility);
std::string location(VariableDeclaration::Location _location); std::string location(VariableDeclaration::Location _location);
std::string contractKind(ContractDefinition::ContractKind _kind);
std::string functionCallKind(FunctionCallKind _kind);
std::string type(Expression const& _expression); std::string type(Expression const& _expression);
std::string type(VariableDeclaration const& _varDecl); std::string type(VariableDeclaration const& _varDecl);
inline void goUp() int nodeId(ASTNode const& _node)
{ {
solAssert(!m_jsonNodePtrs.empty(), "Uneven json nodes stack. Internal error."); return _node.id();
m_jsonNodePtrs.pop();
} }
template<class Container>
Json::Value getContainerIds(Container const& container)
{
Json::Value tmp(Json::arrayValue);
for (auto const& element: container)
{
solAssert(element, "");
tmp.append(nodeId(*element));
}
return tmp;
}
Json::Value typePointerToJson(TypePointer _tp);
Json::Value typePointerToJson(std::shared_ptr<std::vector<TypePointer>> _tps);
void appendExpressionAttributes(
std::vector<std::pair<std::string, Json::Value>> &_attributes,
ExpressionAnnotation const& _annotation
);
bool m_legacy = false; ///< if true, use legacy format
bool m_inEvent = false; ///< whether we are currently inside an event or not bool m_inEvent = false; ///< whether we are currently inside an event or not
bool processed = false; Json::Value m_currentValue;
Json::Value m_astJson;
std::stack<Json::Value*> m_jsonNodePtrs;
ASTNode const* m_ast;
std::map<std::string, unsigned> m_sourceIndices; std::map<std::string, unsigned> m_sourceIndices;
}; };

View File

@ -2183,6 +2183,8 @@ string FunctionType::identifier() const
case Kind::ArrayPush: id += "arraypush"; break; case Kind::ArrayPush: id += "arraypush"; break;
case Kind::ByteArrayPush: id += "bytearraypush"; break; case Kind::ByteArrayPush: id += "bytearraypush"; break;
case Kind::ObjectCreation: id += "objectcreation"; break; case Kind::ObjectCreation: id += "objectcreation"; break;
case Kind::Assert: id += "assert"; break;
case Kind::Require: id += "require";break;
default: solAssert(false, "Unknown function location."); break; default: solAssert(false, "Unknown function location."); break;
} }
if (isConstant()) if (isConstant())

View File

@ -434,7 +434,7 @@ bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
bool ExpressionCompiler::visit(FunctionCall const& _functionCall) bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{ {
CompilerContext::LocationSetter locationSetter(m_context, _functionCall); CompilerContext::LocationSetter locationSetter(m_context, _functionCall);
if (_functionCall.annotation().isTypeConversion) if (_functionCall.annotation().kind == FunctionCallKind::TypeConversion)
{ {
solAssert(_functionCall.arguments().size() == 1, ""); solAssert(_functionCall.arguments().size() == 1, "");
solAssert(_functionCall.names().empty(), ""); solAssert(_functionCall.names().empty(), "");
@ -445,7 +445,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
} }
FunctionTypePointer functionType; FunctionTypePointer functionType;
if (_functionCall.annotation().isStructConstructorCall) if (_functionCall.annotation().kind == FunctionCallKind::StructConstructorCall)
{ {
auto const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type); auto const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);
auto const& structType = dynamic_cast<StructType const&>(*type.actualType()); auto const& structType = dynamic_cast<StructType const&>(*type.actualType());
@ -476,7 +476,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
solAssert(found, ""); solAssert(found, "");
} }
if (_functionCall.annotation().isStructConstructorCall) if (_functionCall.annotation().kind == FunctionCallKind::StructConstructorCall)
{ {
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type); TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.expression().annotation().type);
auto const& structType = dynamic_cast<StructType const&>(*type.actualType()); auto const& structType = dynamic_cast<StructType const&>(*type.actualType());

View File

@ -582,7 +582,7 @@ bool Why3Translator::visit(BinaryOperation const& _binaryOperation)
bool Why3Translator::visit(FunctionCall const& _node) bool Why3Translator::visit(FunctionCall const& _node)
{ {
if (_node.annotation().isTypeConversion || _node.annotation().isStructConstructorCall) if (_node.annotation().kind == FunctionCallKind::TypeConversion || _node.annotation().kind == FunctionCallKind::StructConstructorCall)
{ {
error(_node, "Only ordinary function calls supported."); error(_node, "Only ordinary function calls supported.");
return true; return true;

View File

@ -377,7 +377,8 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
{ {
Json::Value sourceResult = Json::objectValue; Json::Value sourceResult = Json::objectValue;
sourceResult["id"] = sourceIndex++; sourceResult["id"] = sourceIndex++;
sourceResult["legacyAST"] = ASTJsonConverter(m_compilerStack.ast(source), m_compilerStack.sourceIndices()).json(); sourceResult["ast"] = ASTJsonConverter(false, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(source));
sourceResult["legacyAST"] = ASTJsonConverter(true, m_compilerStack.sourceIndices()).toJson(m_compilerStack.ast(source));
output["sources"][source] = sourceResult; output["sources"][source] = sourceResult;
} }

View File

@ -838,9 +838,9 @@ void CommandLineInterface::handleCombinedJSON()
output[g_strSources] = Json::Value(Json::objectValue); output[g_strSources] = Json::Value(Json::objectValue);
for (auto const& sourceCode: m_sourceCodes) for (auto const& sourceCode: m_sourceCodes)
{ {
ASTJsonConverter converter(m_compiler->ast(sourceCode.first), m_compiler->sourceIndices()); ASTJsonConverter converter(true, m_compiler->sourceIndices());
output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue); output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue);
output[g_strSources][sourceCode.first]["AST"] = converter.json(); output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first));
} }
} }
cout << dev::jsonCompactPrint(output) << endl; cout << dev::jsonCompactPrint(output) << endl;
@ -883,8 +883,7 @@ void CommandLineInterface::handleAst(string const& _argStr)
} }
else else
{ {
ASTJsonConverter converter(m_compiler->ast(sourceCode.first)); ASTJsonConverter(true).print(data, m_compiler->ast(sourceCode.first));
converter.print(data);
postfix += "_json"; postfix += "_json";
} }
boost::filesystem::path path(sourceCode.first); boost::filesystem::path path(sourceCode.first);
@ -908,8 +907,7 @@ void CommandLineInterface::handleAst(string const& _argStr)
} }
else else
{ {
ASTJsonConverter converter(m_compiler->ast(sourceCode.first)); ASTJsonConverter(true).print(cout, m_compiler->ast(sourceCode.first));
converter.print(cout);
} }
} }
} }

View File

@ -245,7 +245,7 @@ string compile(StringMap const& _sources, bool _optimize, CStyleReadFileCallback
output["sourceList"].append(source); output["sourceList"].append(source);
output["sources"] = Json::Value(Json::objectValue); output["sources"] = Json::Value(Json::objectValue);
for (auto const& source: compiler.sourceNames()) for (auto const& source: compiler.sourceNames())
output["sources"][source]["AST"] = ASTJsonConverter(compiler.ast(source), compiler.sourceIndices()).json(); output["sources"][source]["AST"] = ASTJsonConverter(true, compiler.sourceIndices()).toJson(compiler.ast(source));
} }
catch (...) catch (...)
{ {

View File

@ -44,7 +44,7 @@ BOOST_AUTO_TEST_CASE(smoke_test)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit"); BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
} }
@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(source_location)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit"); BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
BOOST_CHECK_EQUAL(astJson["children"][0]["name"], "ContractDefinition"); BOOST_CHECK_EQUAL(astJson["children"][0]["name"], "ContractDefinition");
BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["name"], "FunctionDefinition"); BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["name"], "FunctionDefinition");
@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE(inheritance_specifier)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
BOOST_CHECK_EQUAL(astJson["children"][1]["attributes"]["name"], "C2"); BOOST_CHECK_EQUAL(astJson["children"][1]["attributes"]["name"], "C2");
BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["name"], "InheritanceSpecifier"); BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["name"], "InheritanceSpecifier");
BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["src"], "30:2:1"); BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["src"], "30:2:1");
@ -84,7 +84,7 @@ BOOST_AUTO_TEST_CASE(using_for_directive)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value usingFor = astJson["children"][1]["children"][0]; Json::Value usingFor = astJson["children"][1]["children"][0];
BOOST_CHECK_EQUAL(usingFor["name"], "UsingForDirective"); BOOST_CHECK_EQUAL(usingFor["name"], "UsingForDirective");
BOOST_CHECK_EQUAL(usingFor["src"], "26:17:1"); BOOST_CHECK_EQUAL(usingFor["src"], "26:17:1");
@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(enum_value)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value enumDefinition = astJson["children"][0]["children"][0]; Json::Value enumDefinition = astJson["children"][0]["children"][0];
BOOST_CHECK_EQUAL(enumDefinition["children"][0]["name"], "EnumValue"); BOOST_CHECK_EQUAL(enumDefinition["children"][0]["name"], "EnumValue");
BOOST_CHECK_EQUAL(enumDefinition["children"][0]["attributes"]["name"], "A"); BOOST_CHECK_EQUAL(enumDefinition["children"][0]["attributes"]["name"], "A");
@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(modifier_definition)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value modifier = astJson["children"][0]["children"][0]; Json::Value modifier = astJson["children"][0]["children"][0];
BOOST_CHECK_EQUAL(modifier["name"], "ModifierDefinition"); BOOST_CHECK_EQUAL(modifier["name"], "ModifierDefinition");
BOOST_CHECK_EQUAL(modifier["attributes"]["name"], "M"); BOOST_CHECK_EQUAL(modifier["attributes"]["name"], "M");
@ -132,7 +132,7 @@ BOOST_AUTO_TEST_CASE(modifier_invocation)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value modifier = astJson["children"][0]["children"][1]["children"][2]; Json::Value modifier = astJson["children"][0]["children"][1]["children"][2];
BOOST_CHECK_EQUAL(modifier["name"], "ModifierInvocation"); BOOST_CHECK_EQUAL(modifier["name"], "ModifierInvocation");
BOOST_CHECK_EQUAL(modifier["src"], "52:4:1"); BOOST_CHECK_EQUAL(modifier["src"], "52:4:1");
@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(event_definition)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value event = astJson["children"][0]["children"][0]; Json::Value event = astJson["children"][0]["children"][0];
BOOST_CHECK_EQUAL(event["name"], "EventDefinition"); BOOST_CHECK_EQUAL(event["name"], "EventDefinition");
BOOST_CHECK_EQUAL(event["attributes"]["name"], "E"); BOOST_CHECK_EQUAL(event["attributes"]["name"], "E");
@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(array_type_name)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value array = astJson["children"][0]["children"][0]["children"][0]; Json::Value array = astJson["children"][0]["children"][0]["children"][0];
BOOST_CHECK_EQUAL(array["name"], "ArrayTypeName"); BOOST_CHECK_EQUAL(array["name"], "ArrayTypeName");
BOOST_CHECK_EQUAL(array["src"], "13:6:1"); BOOST_CHECK_EQUAL(array["src"], "13:6:1");
@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(placeholder_statement)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value placeholder = astJson["children"][0]["children"][0]["children"][1]["children"][0]; Json::Value placeholder = astJson["children"][0]["children"][0]["children"][1]["children"][0];
BOOST_CHECK_EQUAL(placeholder["name"], "PlaceholderStatement"); BOOST_CHECK_EQUAL(placeholder["name"], "PlaceholderStatement");
BOOST_CHECK_EQUAL(placeholder["src"], "26:1:1"); BOOST_CHECK_EQUAL(placeholder["src"], "26:1:1");
@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(non_utf8)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value literal = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][1]; Json::Value literal = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][1];
BOOST_CHECK_EQUAL(literal["name"], "Literal"); BOOST_CHECK_EQUAL(literal["name"], "Literal");
BOOST_CHECK_EQUAL(literal["attributes"]["hexvalue"], "ff"); BOOST_CHECK_EQUAL(literal["attributes"]["hexvalue"], "ff");
@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(function_type)
c.parseAndAnalyze(); c.parseAndAnalyze();
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1; sourceIndices["a"] = 1;
Json::Value astJson = ASTJsonConverter(c.ast("a"), sourceIndices).json(); Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
Json::Value fun = astJson["children"][0]["children"][0]; Json::Value fun = astJson["children"][0]["children"][0];
BOOST_CHECK_EQUAL(fun["name"], "FunctionDefinition"); BOOST_CHECK_EQUAL(fun["name"], "FunctionDefinition");
Json::Value argument = fun["children"][0]["children"][0]; Json::Value argument = fun["children"][0]["children"][0];

View File

@ -90,10 +90,12 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
BOOST_CHECK(result["sources"]["fileA"].isObject()); BOOST_CHECK(result["sources"]["fileA"].isObject());
BOOST_CHECK(result["sources"]["fileA"]["AST"].isObject()); BOOST_CHECK(result["sources"]["fileA"]["AST"].isObject());
BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]) == BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["AST"]) ==
"{\"children\":[{\"attributes\":{\"fullyImplemented\":true,\"isLibrary\":false,\"linearizedBaseContracts\":[1]," "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},"
"\"name\":\"A\"},\"children\":[],\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"name\":\"SourceUnit\"}"); "\"children\":[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],"
"\"contractKind\":\"contract\",\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],"
"\"name\":\"A\",\"nodes\":[null],\"scope\":2},\"id\":1,\"name\":\"ContractDefinition\","
"\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}");
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

View File

@ -215,8 +215,10 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
BOOST_CHECK(result["sources"]["fileA"].isObject()); BOOST_CHECK(result["sources"]["fileA"].isObject());
BOOST_CHECK(result["sources"]["fileA"]["legacyAST"].isObject()); BOOST_CHECK(result["sources"]["fileA"]["legacyAST"].isObject());
BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]) == BOOST_CHECK(dev::jsonCompactPrint(result["sources"]["fileA"]["legacyAST"]) ==
"{\"children\":[{\"attributes\":{\"fullyImplemented\":true,\"isLibrary\":false,\"linearizedBaseContracts\":[1]," "{\"attributes\":{\"absolutePath\":\"fileA\",\"exportedSymbols\":{\"A\":[1]}},\"children\":"
"\"name\":\"A\"},\"children\":[],\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"name\":\"SourceUnit\"}"); "[{\"attributes\":{\"baseContracts\":[null],\"contractDependencies\":[null],\"contractKind\":\"contract\","
"\"fullyImplemented\":true,\"linearizedBaseContracts\":[1],\"name\":\"A\",\"nodes\":[null],\"scope\":2},"
"\"id\":1,\"name\":\"ContractDefinition\",\"src\":\"0:14:0\"}],\"id\":2,\"name\":\"SourceUnit\",\"src\":\"0:14:0\"}");
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()