mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9204 from ethereum/prepareAllowUsingForEverywhere
Prepare for allowing bound functions and using for everywhere.
This commit is contained in:
commit
547fbf0b6e
@ -311,10 +311,15 @@ TypePointer Type::commonType(Type const* _a, Type const* _b)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList const& Type::members(ContractDefinition const* _currentScope) const
|
MemberList const& Type::members(ASTNode const* _currentScope) const
|
||||||
{
|
{
|
||||||
if (!m_members[_currentScope])
|
if (!m_members[_currentScope])
|
||||||
{
|
{
|
||||||
|
solAssert(
|
||||||
|
_currentScope == nullptr ||
|
||||||
|
dynamic_cast<SourceUnit const*>(_currentScope) ||
|
||||||
|
dynamic_cast<ContractDefinition const*>(_currentScope),
|
||||||
|
"");
|
||||||
MemberList::MemberMap members = nativeMembers(_currentScope);
|
MemberList::MemberMap members = nativeMembers(_currentScope);
|
||||||
if (_currentScope)
|
if (_currentScope)
|
||||||
members += boundFunctions(*this, *_currentScope);
|
members += boundFunctions(*this, *_currentScope);
|
||||||
@ -344,8 +349,20 @@ TypePointer Type::fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool) c
|
|||||||
return encodingType;
|
return encodingType;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition const& _scope)
|
MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _scope)
|
||||||
{
|
{
|
||||||
|
vector<UsingForDirective const*> usingForDirectives;
|
||||||
|
if (auto const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope))
|
||||||
|
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes());
|
||||||
|
else if (auto const* contract = dynamic_cast<ContractDefinition const*>(&_scope))
|
||||||
|
{
|
||||||
|
for (ContractDefinition const* contract: contract->annotation().linearizedBaseContracts)
|
||||||
|
usingForDirectives += contract->usingForDirectives();
|
||||||
|
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(contract->sourceUnit().nodes());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
solAssert(false, "");
|
||||||
|
|
||||||
// Normalise data location of type.
|
// Normalise data location of type.
|
||||||
DataLocation typeLocation = DataLocation::Storage;
|
DataLocation typeLocation = DataLocation::Storage;
|
||||||
if (auto refType = dynamic_cast<ReferenceType const*>(&_type))
|
if (auto refType = dynamic_cast<ReferenceType const*>(&_type))
|
||||||
@ -353,8 +370,8 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
|
|||||||
|
|
||||||
set<Declaration const*> seenFunctions;
|
set<Declaration const*> seenFunctions;
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
for (ContractDefinition const* contract: _scope.annotation().linearizedBaseContracts)
|
|
||||||
for (UsingForDirective const* ufd: contract->usingForDirectives())
|
for (UsingForDirective const* ufd: usingForDirectives)
|
||||||
{
|
{
|
||||||
// Convert both types to pointers for comparison to see if the `using for`
|
// Convert both types to pointers for comparison to see if the `using for`
|
||||||
// directive applies.
|
// directive applies.
|
||||||
@ -385,6 +402,7 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
|
|||||||
members.emplace_back(function->name(), fun, function);
|
members.emplace_back(function->name(), fun, function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,7 +482,7 @@ bool AddressType::operator==(Type const& _other) const
|
|||||||
return other.m_stateMutability == m_stateMutability;
|
return other.m_stateMutability == m_stateMutability;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap AddressType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap AddressType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members = {
|
MemberList::MemberMap members = {
|
||||||
{"balance", TypeProvider::uint256()},
|
{"balance", TypeProvider::uint256()},
|
||||||
@ -1400,7 +1418,7 @@ TypeResult FixedBytesType::binaryOperatorResult(Token _operator, Type const* _ot
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap FixedBytesType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap FixedBytesType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
return MemberList::MemberMap{MemberList::Member{"length", TypeProvider::uint(8)}};
|
return MemberList::MemberMap{MemberList::Member{"length", TypeProvider::uint(8)}};
|
||||||
}
|
}
|
||||||
@ -1856,7 +1874,7 @@ string ArrayType::signatureInExternalFunction(bool _structsByName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap ArrayType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap ArrayType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
if (!isString())
|
if (!isString())
|
||||||
@ -2029,10 +2047,9 @@ string ContractType::canonicalName() const
|
|||||||
return m_contract.annotation().canonicalName;
|
return m_contract.annotation().canonicalName;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _contract) const
|
MemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
solAssert(_contract, "");
|
|
||||||
if (m_super)
|
if (m_super)
|
||||||
{
|
{
|
||||||
// add the most derived of all functions which are visible in derived contracts
|
// add the most derived of all functions which are visible in derived contracts
|
||||||
@ -2063,14 +2080,13 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!m_contract.isLibrary())
|
else if (!m_contract.isLibrary())
|
||||||
{
|
|
||||||
for (auto const& it: m_contract.interfaceFunctions())
|
for (auto const& it: m_contract.interfaceFunctions())
|
||||||
members.emplace_back(
|
members.emplace_back(
|
||||||
it.second->declaration().name(),
|
it.second->declaration().name(),
|
||||||
it.second->asExternallyCallableFunction(m_contract.isLibrary()),
|
it.second->asExternallyCallableFunction(m_contract.isLibrary()),
|
||||||
&it.second->declaration()
|
&it.second->declaration()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2241,7 +2257,7 @@ string StructType::toString(bool _short) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap StructType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap StructType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
for (ASTPointer<VariableDeclaration> const& variable: m_struct.members())
|
for (ASTPointer<VariableDeclaration> const& variable: m_struct.members())
|
||||||
@ -3146,7 +3162,7 @@ FunctionTypePointer FunctionType::interfaceFunctionType() const
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const* _scope) const
|
MemberList::MemberMap FunctionType::nativeMembers(ASTNode const* _scope) const
|
||||||
{
|
{
|
||||||
switch (m_kind)
|
switch (m_kind)
|
||||||
{
|
{
|
||||||
@ -3165,7 +3181,8 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const* _sco
|
|||||||
functionDefinition->isPartOfExternalInterface()
|
functionDefinition->isPartOfExternalInterface()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
solAssert(_scope->derivesFrom(*functionDefinition->annotation().contract), "");
|
auto const* contractScope = dynamic_cast<ContractDefinition const*>(_scope);
|
||||||
|
solAssert(contractScope && contractScope->derivesFrom(*functionDefinition->annotation().contract), "");
|
||||||
return {{"selector", TypeProvider::fixedBytes(4)}};
|
return {{"selector", TypeProvider::fixedBytes(4)}};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3640,13 +3657,14 @@ vector<tuple<string, TypePointer>> TypeType::makeStackItems() const
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _currentScope) const
|
MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap members;
|
MemberList::MemberMap members;
|
||||||
if (m_actualType->category() == Category::Contract)
|
if (m_actualType->category() == Category::Contract)
|
||||||
{
|
{
|
||||||
|
auto const* contractScope = dynamic_cast<ContractDefinition const*>(_currentScope);
|
||||||
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).contractDefinition();
|
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).contractDefinition();
|
||||||
bool inDerivingScope = _currentScope && _currentScope->derivesFrom(contract);
|
bool inDerivingScope = contractScope && contractScope->derivesFrom(contract);
|
||||||
|
|
||||||
for (auto const* declaration: contract.declarations())
|
for (auto const* declaration: contract.declarations())
|
||||||
{
|
{
|
||||||
@ -3748,7 +3766,7 @@ bool ModuleType::operator==(Type const& _other) const
|
|||||||
return &m_sourceUnit == &dynamic_cast<ModuleType const&>(_other).m_sourceUnit;
|
return &m_sourceUnit == &dynamic_cast<ModuleType const&>(_other).m_sourceUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap ModuleType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap ModuleType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
MemberList::MemberMap symbols;
|
MemberList::MemberMap symbols;
|
||||||
for (auto const& symbolName: m_sourceUnit.annotation().exportedSymbols)
|
for (auto const& symbolName: m_sourceUnit.annotation().exportedSymbols)
|
||||||
@ -3789,7 +3807,7 @@ bool MagicType::operator==(Type const& _other) const
|
|||||||
return other.m_kind == m_kind;
|
return other.m_kind == m_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap MagicType::nativeMembers(ContractDefinition const*) const
|
MemberList::MemberMap MagicType::nativeMembers(ASTNode const*) const
|
||||||
{
|
{
|
||||||
switch (m_kind)
|
switch (m_kind)
|
||||||
{
|
{
|
||||||
|
@ -315,9 +315,9 @@ public:
|
|||||||
|
|
||||||
/// Returns the list of all members of this type. Default implementation: no members apart from bound.
|
/// Returns the list of all members of this type. Default implementation: no members apart from bound.
|
||||||
/// @param _currentScope scope in which the members are accessed.
|
/// @param _currentScope scope in which the members are accessed.
|
||||||
MemberList const& members(ContractDefinition const* _currentScope) const;
|
MemberList const& members(ASTNode const* _currentScope) const;
|
||||||
/// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.
|
/// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.
|
||||||
TypePointer memberType(std::string const& _name, ContractDefinition const* _currentScope = nullptr) const
|
TypePointer memberType(std::string const& _name, ASTNode const* _currentScope = nullptr) const
|
||||||
{
|
{
|
||||||
return members(_currentScope).memberType(_name);
|
return members(_currentScope).memberType(_name);
|
||||||
}
|
}
|
||||||
@ -361,12 +361,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/// @returns a member list containing all members added to this type by `using for` directives.
|
/// @returns a member list containing all members added to this type by `using for` directives.
|
||||||
static MemberList::MemberMap boundFunctions(Type const& _type, ContractDefinition const& _scope);
|
static MemberList::MemberMap boundFunctions(Type const& _type, ASTNode const& _scope);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// @returns the members native to this type depending on the given context. This function
|
/// @returns the members native to this type depending on the given context. This function
|
||||||
/// is used (in conjunction with boundFunctions to fill m_members below.
|
/// is used (in conjunction with boundFunctions to fill m_members below.
|
||||||
virtual MemberList::MemberMap nativeMembers(ContractDefinition const* /*_currentScope*/) const
|
virtual MemberList::MemberMap nativeMembers(ASTNode const* /*_currentScope*/) const
|
||||||
{
|
{
|
||||||
return MemberList::MemberMap();
|
return MemberList::MemberMap();
|
||||||
}
|
}
|
||||||
@ -379,7 +379,7 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
/// List of member types (parameterised by scape), will be lazy-initialized.
|
/// List of member types (parameterised by scape), will be lazy-initialized.
|
||||||
mutable std::map<ContractDefinition const*, std::unique_ptr<MemberList>> m_members;
|
mutable std::map<ASTNode const*, std::unique_ptr<MemberList>> m_members;
|
||||||
mutable std::optional<std::vector<std::tuple<std::string, TypePointer>>> m_stackItems;
|
mutable std::optional<std::vector<std::tuple<std::string, TypePointer>>> m_stackItems;
|
||||||
mutable std::optional<size_t> m_stackSize;
|
mutable std::optional<size_t> m_stackSize;
|
||||||
};
|
};
|
||||||
@ -408,7 +408,7 @@ public:
|
|||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
@ -649,7 +649,7 @@ public:
|
|||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
|
|
||||||
std::string toString(bool) const override { return "bytes" + util::toString(m_bytes); }
|
std::string toString(bool) const override { return "bytes" + util::toString(m_bytes); }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
TypePointer encodingType() const override { return this; }
|
TypePointer encodingType() const override { return this; }
|
||||||
TypeResult interfaceType(bool) const override { return this; }
|
TypeResult interfaceType(bool) const override { return this; }
|
||||||
|
|
||||||
@ -786,7 +786,7 @@ public:
|
|||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
std::string signatureInExternalFunction(bool _structsByName) const override;
|
std::string signatureInExternalFunction(bool _structsByName) const override;
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
TypePointer encodingType() const override;
|
TypePointer encodingType() const override;
|
||||||
TypePointer decodingType() const override;
|
TypePointer decodingType() const override;
|
||||||
TypeResult interfaceType(bool _inLibrary) const override;
|
TypeResult interfaceType(bool _inLibrary) const override;
|
||||||
@ -889,7 +889,7 @@ public:
|
|||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
|
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
|
|
||||||
Type const* encodingType() const override;
|
Type const* encodingType() const override;
|
||||||
|
|
||||||
@ -949,7 +949,7 @@ public:
|
|||||||
bool nameable() const override { return true; }
|
bool nameable() const override { return true; }
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
|
|
||||||
Type const* encodingType() const override;
|
Type const* encodingType() const override;
|
||||||
TypeResult interfaceType(bool _inLibrary) const override;
|
TypeResult interfaceType(bool _inLibrary) const override;
|
||||||
@ -1220,7 +1220,7 @@ public:
|
|||||||
bool nameable() const override;
|
bool nameable() const override;
|
||||||
bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { return false; }
|
bool hasSimpleZeroValueInMemory() const override { return false; }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
TypePointer encodingType() const override;
|
TypePointer encodingType() const override;
|
||||||
TypeResult interfaceType(bool _inLibrary) const override;
|
TypeResult interfaceType(bool _inLibrary) const override;
|
||||||
|
|
||||||
@ -1389,7 +1389,7 @@ public:
|
|||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
|
std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
|
||||||
|
|
||||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
protected:
|
protected:
|
||||||
@ -1441,7 +1441,7 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return true; }
|
bool canLiveOutsideStorage() const override { return true; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
@ -1481,7 +1481,7 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return true; }
|
bool canLiveOutsideStorage() const override { return true; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ASTNode const*) const override;
|
||||||
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user