refactoring functionCallAnnotation

This commit is contained in:
djudjuu 2017-05-19 15:45:01 +02:00
parent 6316a76ab9
commit 1d22233a43
6 changed files with 51 additions and 21 deletions

View File

@ -1238,13 +1238,16 @@ 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;
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 +1277,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 +1315,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

@ -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;
}; };
} }

View File

@ -156,7 +156,7 @@ Json::Value ASTJsonConverter::typePointerToJson(std::shared_ptr<std::vector<Type
} }
void ASTJsonConverter::appendExpressionAttributes( void ASTJsonConverter::appendExpressionAttributes(
std::vector<pair<string, Json::Value>> &_attributes, std::vector<pair<string, Json::Value>>& _attributes,
ExpressionAnnotation const& _annotation ExpressionAnnotation const& _annotation
) )
{ {
@ -168,7 +168,7 @@ void ASTJsonConverter::appendExpressionAttributes(
make_pair("lValueRequested", _annotation.lValueRequested), make_pair("lValueRequested", _annotation.lValueRequested),
make_pair("argumentTypes", typePointerToJson(_annotation.argumentTypes)) make_pair("argumentTypes", typePointerToJson(_annotation.argumentTypes))
}; };
_attributes.insert(_attributes.end(), exprAttributes.begin(), exprAttributes.end()); _attributes += exprAttributes;
} }
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<assembly::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<assembly::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info)
@ -344,6 +344,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node)
make_pair("name", _node.name()), make_pair("name", _node.name()),
make_pair("typeName", toJsonOrNull(_node.typeName())), make_pair("typeName", toJsonOrNull(_node.typeName())),
make_pair("constant", _node.isConstant()), make_pair("constant", _node.isConstant()),
make_pair("stateVariable", _node.isStateVariable()),
make_pair("storageLocation", location(_node.referenceLocation())), make_pair("storageLocation", location(_node.referenceLocation())),
make_pair("visibility", visibility(_node.visibility())), make_pair("visibility", visibility(_node.visibility())),
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue), make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
@ -627,12 +628,17 @@ bool ASTJsonConverter::visit(FunctionCall const& _node)
for (auto const& name: _node.names()) for (auto const& name: _node.names())
names.append(Json::Value(*name)); names.append(Json::Value(*name));
std::vector<pair<string, Json::Value>> attributes = { std::vector<pair<string, Json::Value>> attributes = {
make_pair(m_legacy ? "type_conversion" : "isTypeConversion", _node.annotation().isTypeConversion),
make_pair("isStructConstructorCall", _node.annotation().isStructConstructorCall),
make_pair("expression", toJson(_node.expression())), make_pair("expression", toJson(_node.expression())),
make_pair("names", std::move(names)), make_pair("names", std::move(names)),
make_pair("arguments", toJson(_node.arguments())) make_pair("arguments", toJson(_node.arguments()))
}; };
if (m_legacy)
{
attributes.push_back(make_pair("isStructConstructorCall", functionCallKind(_node.annotation().kind)));
attributes.push_back(make_pair("type_conversion", _node.annotation().kind == FunctionCallKind::TypeConversion));
}
else
attributes.push_back(make_pair("kind", functionCallKind(_node.annotation().kind)));
appendExpressionAttributes(attributes, _node.annotation()); appendExpressionAttributes(attributes, _node.annotation());
setJsonNode(_node, "FunctionCall", std::move(attributes)); setJsonNode(_node, "FunctionCall", std::move(attributes));
return false; return false;
@ -768,7 +774,22 @@ string ASTJsonConverter::contractKind(ContractDefinition::ContractKind _kind)
case ContractDefinition::ContractKind::Library: case ContractDefinition::ContractKind::Library:
return "library"; return "library";
default: default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown contract kind.")); BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of contract."));
}
}
string ASTJsonConverter::functionCallKind(FunctionCallKind _kind)
{
switch (_kind)
{
case FunctionCallKind::FunctionCall:
return "functionCall";
case FunctionCallKind::TypeConversion:
return "typeConversion";
case FunctionCallKind::StructConstructorCall:
return "structConstructorCall";
default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of function call ."));
} }
} }

View File

@ -132,6 +132,7 @@ private:
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 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);
int nodeId(ASTNode const& _node) int nodeId(ASTNode const& _node)

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;