Merge pull request #10880 from ethereum/EnumValue-members

nativeMembers() missing out EnumValue declaration
This commit is contained in:
chriseth 2021-02-11 11:28:59 +01:00 committed by GitHub
commit 0c7ce4213a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 322 additions and 26 deletions

View File

@ -11,6 +11,7 @@ Compiler Features:
Bugfixes: Bugfixes:
* Type Checker: Fix internal error when override specifier is not a contract. * Type Checker: Fix internal error when override specifier is not a contract.
* SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase. * SMTChecker: Fix missing type constraints on block and transaction variables in the deployment phase.
* AST: Added ``referencedDeclaration`` for enum members.
AST Changes: AST Changes:

View File

@ -111,6 +111,13 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
} }
MemberList::Member::Member(Declaration const* _declaration, Type const* _type):
name(_declaration->name()),
type(_type),
declaration(_declaration)
{
}
void Type::clearCache() const void Type::clearCache() const
{ {
m_members.clear(); m_members.clear();
@ -365,7 +372,7 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
FunctionTypePointer fun = FunctionTypePointer fun =
dynamic_cast<FunctionType const&>(*function->typeViaContractName()).asBoundFunction(); dynamic_cast<FunctionType const&>(*function->typeViaContractName()).asBoundFunction();
if (_type.isImplicitlyConvertibleTo(*fun->selfType())) if (_type.isImplicitlyConvertibleTo(*fun->selfType()))
members.emplace_back(function->name(), fun, function); members.emplace_back(function, fun);
} }
} }
@ -1985,9 +1992,8 @@ MemberList::MemberMap ContractType::nativeMembers(ASTNode const*) const
if (!m_contract.isLibrary()) 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(),
it.second->asExternallyCallableFunction(m_contract.isLibrary()), it.second->asExternallyCallableFunction(m_contract.isLibrary())
&it.second->declaration()
); );
return members; return members;
@ -2213,9 +2219,8 @@ MemberList::MemberMap StructType::nativeMembers(ASTNode const*) const
solAssert(type, ""); solAssert(type, "");
solAssert(!(location() != DataLocation::Storage && type->containsNestedMapping()), ""); solAssert(!(location() != DataLocation::Storage && type->containsNestedMapping()), "");
members.emplace_back( members.emplace_back(
variable->name(), variable.get(),
copyForLocationIfReference(type), copyForLocationIfReference(type)
variable.get()
); );
} }
return members; return members;
@ -3687,7 +3692,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
break; break;
} }
if (!functionWithEqualArgumentsFound) if (!functionWithEqualArgumentsFound)
members.emplace_back(function->name(), functionType, function); members.emplace_back(function, functionType);
} }
} }
else else
@ -3708,15 +3713,15 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(declaration); auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(declaration);
functionDefinition && !functionDefinition->isImplemented() functionDefinition && !functionDefinition->isImplemented()
) )
members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration); members.emplace_back(declaration, declaration->typeViaContractName());
else else
members.emplace_back(declaration->name(), declaration->type(), declaration); members.emplace_back(declaration, declaration->type());
} }
else if ( else if (
(contract.isLibrary() && declaration->isVisibleAsLibraryMember()) || (contract.isLibrary() && declaration->isVisibleAsLibraryMember()) ||
declaration->isVisibleViaContractTypeAccess() declaration->isVisibleViaContractTypeAccess()
) )
members.emplace_back(declaration->name(), declaration->typeViaContractName(), declaration); members.emplace_back(declaration, declaration->typeViaContractName());
} }
} }
} }
@ -3725,7 +3730,7 @@ MemberList::MemberMap TypeType::nativeMembers(ASTNode const* _currentScope) cons
EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition(); EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition();
auto enumType = TypeProvider::enumType(enumDef); auto enumType = TypeProvider::enumType(enumDef);
for (ASTPointer<EnumValue> const& enumValue: enumDef.members()) for (ASTPointer<EnumValue> const& enumValue: enumDef.members())
members.emplace_back(enumValue->name(), enumType); members.emplace_back(enumValue.get(), enumType);
} }
return members; return members;
} }
@ -3801,9 +3806,12 @@ bool ModuleType::operator==(Type const& _other) const
MemberList::MemberMap ModuleType::nativeMembers(ASTNode 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& [name, declarations]: *m_sourceUnit.annotation().exportedSymbols)
for (Declaration const* symbol: symbolName.second) for (Declaration const* symbol: declarations)
symbols.emplace_back(symbolName.first, symbol->type(), symbol); {
solAssert(name == symbol->name(), "");
symbols.emplace_back(symbol, symbol->type());
}
return symbols; return symbols;
} }

View File

@ -100,15 +100,19 @@ class MemberList
public: public:
struct Member struct Member
{ {
Member(std::string _name, Type const* _type, Declaration const* _declaration = nullptr): /// Manual constructor for members that are not taken from a declaration.
name(std::move(_name)), Member(char const* _name, Type const* _type):
name(_name),
type(_type), type(_type),
declaration(_declaration) declaration(nullptr)
{ {
} }
/// Constructs a Member with the name extracted from @p _declaration's name.
Member(Declaration const* _declaration, Type const* _type);
std::string name; std::string name;
Type const* type; Type const* type = nullptr;
Declaration const* declaration = nullptr; Declaration const* declaration = nullptr;
}; };

View File

@ -0,0 +1,159 @@
{
"absolutePath": "a",
"exportedSymbols":
{
"A":
[
3
],
"f":
[
13
]
},
"id": 14,
"nodeType": "SourceUnit",
"nodes":
[
{
"canonicalName": "A",
"id": 3,
"members":
[
{
"id": 1,
"name": "X",
"nameLocation": "9:1:1",
"nodeType": "EnumValue",
"src": "9:1:1"
},
{
"id": 2,
"name": "Y",
"nameLocation": "12:1:1",
"nodeType": "EnumValue",
"src": "12:1:1"
}
],
"name": "A",
"nameLocation": "5:1:1",
"nodeType": "EnumDefinition",
"src": "0:15:1"
},
{
"body":
{
"id": 12,
"nodeType": "Block",
"src": "46:15:1",
"statements":
[
{
"expression":
{
"expression":
{
"id": 9,
"name": "A",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"referencedDeclaration": 3,
"src": "55:1:1",
"typeDescriptions":
{
"typeIdentifier": "t_type$_t_enum$_A_$3_$",
"typeString": "type(enum A)"
}
},
"id": 10,
"isConstant": false,
"isLValue": false,
"isPure": true,
"lValueRequested": false,
"memberName": "X",
"nodeType": "MemberAccess",
"referencedDeclaration": 1,
"src": "55:3:1",
"typeDescriptions":
{
"typeIdentifier": "t_enum$_A_$3",
"typeString": "enum A"
}
},
"functionReturnParameters": 8,
"id": 11,
"nodeType": "Return",
"src": "48:10:1"
}
]
},
"id": 13,
"implemented": true,
"kind": "freeFunction",
"modifiers": [],
"name": "f",
"nameLocation": "25:1:1",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters": [],
"src": "26:2:1"
},
"returnParameters":
{
"id": 8,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 7,
"mutability": "mutable",
"name": "",
"nameLocation": "-1:-1:-1",
"nodeType": "VariableDeclaration",
"scope": 13,
"src": "43:1:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions":
{
"typeIdentifier": "t_enum$_A_$3",
"typeString": "enum A"
},
"typeName":
{
"id": 6,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 5,
"name": "A",
"nodeType": "IdentifierPath",
"referencedDeclaration": 3,
"src": "43:1:1"
},
"referencedDeclaration": 3,
"src": "43:1:1",
"typeDescriptions":
{
"typeIdentifier": "t_enum$_A_$3",
"typeString": "enum A"
}
},
"visibility": "internal"
}
],
"src": "42:3:1"
},
"scope": 14,
"src": "16:45:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "internal"
}
],
"src": "0:62:1"
}

View File

@ -0,0 +1,4 @@
enum A { X, Y }
function f() pure returns (A) { return A.X; }
// ----

View File

@ -0,0 +1,120 @@
{
"absolutePath": "a",
"id": 14,
"nodeType": "SourceUnit",
"nodes":
[
{
"id": 3,
"members":
[
{
"id": 1,
"name": "X",
"nameLocation": "9:1:1",
"nodeType": "EnumValue",
"src": "9:1:1"
},
{
"id": 2,
"name": "Y",
"nameLocation": "12:1:1",
"nodeType": "EnumValue",
"src": "12:1:1"
}
],
"name": "A",
"nameLocation": "5:1:1",
"nodeType": "EnumDefinition",
"src": "0:15:1"
},
{
"body":
{
"id": 12,
"nodeType": "Block",
"src": "46:15:1",
"statements":
[
{
"expression":
{
"expression":
{
"id": 9,
"name": "A",
"nodeType": "Identifier",
"overloadedDeclarations": [],
"src": "55:1:1",
"typeDescriptions": {}
},
"id": 10,
"memberName": "X",
"nodeType": "MemberAccess",
"src": "55:3:1",
"typeDescriptions": {}
},
"id": 11,
"nodeType": "Return",
"src": "48:10:1"
}
]
},
"id": 13,
"implemented": true,
"kind": "freeFunction",
"modifiers": [],
"name": "f",
"nameLocation": "25:1:1",
"nodeType": "FunctionDefinition",
"parameters":
{
"id": 4,
"nodeType": "ParameterList",
"parameters": [],
"src": "26:2:1"
},
"returnParameters":
{
"id": 8,
"nodeType": "ParameterList",
"parameters":
[
{
"constant": false,
"id": 7,
"mutability": "mutable",
"name": "",
"nameLocation": "-1:-1:-1",
"nodeType": "VariableDeclaration",
"src": "43:1:1",
"stateVariable": false,
"storageLocation": "default",
"typeDescriptions": {},
"typeName":
{
"id": 6,
"nodeType": "UserDefinedTypeName",
"pathNode":
{
"id": 5,
"name": "A",
"nodeType": "IdentifierPath",
"src": "43:1:1"
},
"src": "43:1:1",
"typeDescriptions": {}
},
"visibility": "internal"
}
],
"src": "42:3:1"
},
"src": "16:45:1",
"stateMutability": "pure",
"virtual": false,
"visibility": "internal"
}
],
"src": "0:62:1"
}

View File

@ -78,9 +78,9 @@ BOOST_AUTO_TEST_CASE(ufixed_types)
BOOST_AUTO_TEST_CASE(storage_layout_simple) BOOST_AUTO_TEST_CASE(storage_layout_simple)
{ {
MemberList members(MemberList::MemberMap({ MemberList members(MemberList::MemberMap({
{string("first"), TypeProvider::fromElementaryTypeName("uint128")}, {"first", TypeProvider::fromElementaryTypeName("uint128")},
{string("second"), TypeProvider::fromElementaryTypeName("uint120")}, {"second", TypeProvider::fromElementaryTypeName("uint120")},
{string("wraps"), TypeProvider::fromElementaryTypeName("uint16")} {"wraps", TypeProvider::fromElementaryTypeName("uint16")}
})); }));
BOOST_REQUIRE_EQUAL(u256(2), members.storageSize()); BOOST_REQUIRE_EQUAL(u256(2), members.storageSize());
BOOST_REQUIRE(members.memberStorageOffset("first") != nullptr); BOOST_REQUIRE(members.memberStorageOffset("first") != nullptr);
@ -94,13 +94,13 @@ BOOST_AUTO_TEST_CASE(storage_layout_simple)
BOOST_AUTO_TEST_CASE(storage_layout_mapping) BOOST_AUTO_TEST_CASE(storage_layout_mapping)
{ {
MemberList members(MemberList::MemberMap({ MemberList members(MemberList::MemberMap({
{string("first"), TypeProvider::fromElementaryTypeName("uint128")}, {"first", TypeProvider::fromElementaryTypeName("uint128")},
{string("second"), TypeProvider::mapping( {"second", TypeProvider::mapping(
TypeProvider::fromElementaryTypeName("uint8"), TypeProvider::fromElementaryTypeName("uint8"),
TypeProvider::fromElementaryTypeName("uint8") TypeProvider::fromElementaryTypeName("uint8")
)}, )},
{string("third"), TypeProvider::fromElementaryTypeName("uint16")}, {"third", TypeProvider::fromElementaryTypeName("uint16")},
{string("final"), TypeProvider::mapping( {"final", TypeProvider::mapping(
TypeProvider::fromElementaryTypeName("uint8"), TypeProvider::fromElementaryTypeName("uint8"),
TypeProvider::fromElementaryTypeName("uint8") TypeProvider::fromElementaryTypeName("uint8")
)}, )},