mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
make it work for var x = f;
This commit is contained in:
parent
ddcfd441f3
commit
4033615464
29
AST.cpp
29
AST.cpp
@ -674,15 +674,23 @@ void FunctionCall::checkTypeRequirements()
|
|||||||
else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast<OverloadedFunctionType const*>(expressionType))
|
else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast<OverloadedFunctionType const*>(expressionType))
|
||||||
{
|
{
|
||||||
// this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions.
|
// this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions.
|
||||||
overloadedTypes->m_identifier->overloadResolution(*this);
|
auto identifier = dynamic_cast<Identifier*>(m_expression.get());
|
||||||
FunctionType const* functionType = dynamic_cast<FunctionType const*>(overloadedTypes->m_identifier->getType().get());
|
solAssert(identifier, "only applies to 'var x = f;'");
|
||||||
|
|
||||||
|
Declaration const* function = overloadedTypes->getIdentifier()->overloadResolution(*this);
|
||||||
|
if (!function)
|
||||||
|
BOOST_THROW_EXCEPTION(createTypeError("Can't resolve declarations"));
|
||||||
|
|
||||||
|
identifier->setReferencedDeclaration(*function);
|
||||||
|
identifier->checkTypeRequirements();
|
||||||
|
|
||||||
|
TypePointer type = identifier->getType();
|
||||||
|
FunctionType const* functionType = dynamic_cast<FunctionType const*>(type.get());
|
||||||
|
|
||||||
// @todo actually the return type should be an anonymous struct,
|
|
||||||
// but we change it to the type of the first return value until we have structs
|
|
||||||
if (functionType->getReturnParameterTypes().empty())
|
if (functionType->getReturnParameterTypes().empty())
|
||||||
m_type = make_shared<VoidType>();
|
m_type = make_shared<VoidType>();
|
||||||
else
|
else
|
||||||
m_type = functionType->getReturnParameterTypes().front();
|
m_type = functionType->getReturnParameterTypes().front();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Type is not callable."));
|
BOOST_THROW_EXCEPTION(createTypeError("Type is not callable."));
|
||||||
@ -781,7 +789,7 @@ void Identifier::checkTypeRequirementsWithFunctionCall(FunctionCall const& _func
|
|||||||
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
|
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
|
||||||
|
|
||||||
if (!m_referencedDeclaration)
|
if (!m_referencedDeclaration)
|
||||||
overloadResolution(_functionCall);
|
setReferencedDeclaration(*overloadResolution(_functionCall));
|
||||||
|
|
||||||
checkTypeRequirements();
|
checkTypeRequirements();
|
||||||
}
|
}
|
||||||
@ -791,7 +799,7 @@ void Identifier::checkTypeRequirementsFromVariableDeclaration()
|
|||||||
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
|
solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved.");
|
||||||
|
|
||||||
if (!m_referencedDeclaration)
|
if (!m_referencedDeclaration)
|
||||||
m_type = make_shared<OverloadedFunctionType>(m_overloadedDeclarations, this);
|
m_type = make_shared<OverloadedFunctionType>(this);
|
||||||
else
|
else
|
||||||
checkTypeRequirements();
|
checkTypeRequirements();
|
||||||
|
|
||||||
@ -808,13 +816,11 @@ void Identifier::checkTypeRequirements()
|
|||||||
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
|
BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Identifier::overloadResolution(FunctionCall const& _functionCall)
|
Declaration const* Identifier::overloadResolution(FunctionCall const& _functionCall)
|
||||||
{
|
{
|
||||||
solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved.");
|
solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved.");
|
||||||
solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution.");
|
solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution.");
|
||||||
|
|
||||||
bool resolved = false;
|
|
||||||
|
|
||||||
std::vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
|
std::vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
|
||||||
std::vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.getNames();
|
std::vector<ASTPointer<ASTString>> const& argumentNames = _functionCall.getNames();
|
||||||
|
|
||||||
@ -844,7 +850,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall)
|
|||||||
{
|
{
|
||||||
return declaration->getScope() == possibles.front()->getScope();
|
return declaration->getScope() == possibles.front()->getScope();
|
||||||
}))
|
}))
|
||||||
setReferencedDeclaration(*possibles.front());
|
return possibles.front();
|
||||||
else
|
else
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier"));
|
BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier"));
|
||||||
}
|
}
|
||||||
@ -852,6 +858,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall)
|
|||||||
// named arguments
|
// named arguments
|
||||||
// TODO: don't support right now
|
// TODO: don't support right now
|
||||||
BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet."));
|
BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet."));
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElementaryTypeNameExpression::checkTypeRequirements()
|
void ElementaryTypeNameExpression::checkTypeRequirements()
|
||||||
|
2
AST.h
2
AST.h
@ -1157,7 +1157,7 @@ public:
|
|||||||
void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall);
|
void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall);
|
||||||
void checkTypeRequirementsFromVariableDeclaration();
|
void checkTypeRequirementsFromVariableDeclaration();
|
||||||
|
|
||||||
void overloadResolution(FunctionCall const& _functionCall);
|
Declaration const* overloadResolution(FunctionCall const& _functionCall);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ASTPointer<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
|
@ -822,11 +822,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
|||||||
void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
Declaration const* declaration = _identifier.getReferencedDeclaration();
|
Declaration const* declaration = _identifier.getReferencedDeclaration();
|
||||||
if (declaration == nullptr)
|
if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
||||||
{
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
else if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
|
||||||
{
|
{
|
||||||
if (magicVar->getType()->getCategory() == Type::Category::Contract)
|
if (magicVar->getType()->getCategory() == Type::Category::Contract)
|
||||||
// "this" or "super"
|
// "this" or "super"
|
||||||
@ -849,6 +845,13 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
|||||||
{
|
{
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
else if (declaration == nullptr && _identifier.getOverloadedDeclarations().size() > 1)
|
||||||
|
{
|
||||||
|
// var x = f;
|
||||||
|
declaration = *_identifier.getOverloadedDeclarations().begin();
|
||||||
|
FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration);
|
||||||
|
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context."));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context."));
|
||||||
|
9
Types.h
9
Types.h
@ -527,13 +527,14 @@ private:
|
|||||||
class OverloadedFunctionType: public Type
|
class OverloadedFunctionType: public Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit OverloadedFunctionType(std::set<Declaration const*> const& _overloadedDeclarations, Identifier* _identifier):
|
explicit OverloadedFunctionType(Identifier* _identifier): m_identifier(_identifier) {}
|
||||||
m_overloadedDeclarations(_overloadedDeclarations), m_identifier(_identifier) {}
|
|
||||||
virtual Category getCategory() const override { return Category::OverloadedFunctions; }
|
virtual Category getCategory() const override { return Category::OverloadedFunctions; }
|
||||||
virtual std::string toString() const override { return "OverloadedFunctions"; }
|
virtual std::string toString() const override { return "OverloadedFunctions"; }
|
||||||
|
|
||||||
// private:
|
Identifier* getIdentifier() const { return m_identifier; }
|
||||||
std::set<Declaration const*> m_overloadedDeclarations;
|
|
||||||
|
private:
|
||||||
Identifier * m_identifier;
|
Identifier * m_identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user