mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
DeclarationTypeChecker for UserDefinedValueTypes
- Checks for repetitions. - Assigns types. - Checks if the 'actual type' is an elementary type name. - Checks if the 'actual type' is a value type. Also added tests.
This commit is contained in:
parent
15452371d4
commit
0647039864
@ -140,6 +140,30 @@ bool DeclarationTypeChecker::visit(StructDefinition const& _struct)
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeclarationTypeChecker::endVisit(UserDefinedValueTypeDefinition const& _userDefined)
|
||||
{
|
||||
TypeName const* typeName = _userDefined.underlyingType();
|
||||
solAssert(typeName, "");
|
||||
if (!dynamic_cast<ElementaryTypeName const*>(typeName))
|
||||
m_errorReporter.fatalTypeError(
|
||||
8657_error,
|
||||
typeName->location(),
|
||||
"The underlying type for a user defined value type has to be an elementary value type."
|
||||
);
|
||||
|
||||
Type const* type = typeName->annotation().type;
|
||||
solAssert(type, "");
|
||||
solAssert(!dynamic_cast<UserDefinedValueType const*>(type), "");
|
||||
if (!type->isValueType())
|
||||
m_errorReporter.typeError(
|
||||
8129_error,
|
||||
_userDefined.location(),
|
||||
"The underlying type of the user defined value type \"" +
|
||||
_userDefined.name() +
|
||||
"\" is not a value type."
|
||||
);
|
||||
}
|
||||
|
||||
void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)
|
||||
{
|
||||
if (_typeName.annotation().type)
|
||||
@ -158,6 +182,8 @@ void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)
|
||||
_typeName.annotation().type = TypeProvider::enumType(*enumDef);
|
||||
else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
|
||||
_typeName.annotation().type = TypeProvider::contract(*contract);
|
||||
else if (auto userDefinedValueType = dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))
|
||||
_typeName.annotation().type = TypeProvider::userDefinedValueType(*userDefinedValueType);
|
||||
else
|
||||
{
|
||||
_typeName.annotation().type = TypeProvider::emptyTuple();
|
||||
|
@ -60,6 +60,7 @@ private:
|
||||
void endVisit(VariableDeclaration const& _variable) override;
|
||||
bool visit(EnumDefinition const& _enum) override;
|
||||
bool visit(StructDefinition const& _struct) override;
|
||||
void endVisit(UserDefinedValueTypeDefinition const& _userDefined) override;
|
||||
bool visit(UsingForDirective const& _usingForDirective) override;
|
||||
bool visit(InheritanceSpecifier const& _inheritanceSpecifier) override;
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
type MyAddress is address;
|
||||
type MyAddressPayable is address payable;
|
||||
type MyInt is int;
|
||||
type MyUInt is uint;
|
||||
type MyInt128 is int128;
|
||||
type MyUInt128 is uint128;
|
||||
// TODO add fixed point type, when it's implemented
|
||||
type MyFixedBytes32 is bytes32;
|
||||
type MyFixedBytes1 is bytes1;
|
||||
type MyBool is bool;
|
||||
/// test to see if having NatSpec causes issues
|
||||
type redundantNatSpec is bytes2;
|
@ -0,0 +1,6 @@
|
||||
type MyAddress is address;
|
||||
function f() {
|
||||
MyAddress a = MyAddress(5, 2);
|
||||
}
|
||||
// ----
|
||||
// TypeError 2558: (60-75): Exactly one argument expected for explicit type conversion.
|
@ -0,0 +1,6 @@
|
||||
type MyAddress is address;
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
}
|
||||
// ----
|
||||
// Warning 2519: (44-70): This declaration shadows an existing declaration.
|
@ -0,0 +1,9 @@
|
||||
type MyInt is int;
|
||||
type MyInt is address;
|
||||
contract C {
|
||||
type MyAddress is address;
|
||||
type MyAddress is address;
|
||||
}
|
||||
// ----
|
||||
// DeclarationError 2333: (19-41): Identifier already declared.
|
||||
// DeclarationError 2333: (90-116): Identifier already declared.
|
@ -0,0 +1,3 @@
|
||||
type MyBytes is bytes;
|
||||
// ----
|
||||
// TypeError 8129: (0-22): The underlying type of the user defined value type "MyBytes" is not a value type.
|
@ -0,0 +1,4 @@
|
||||
contract C {}
|
||||
type MyContract is C;
|
||||
// ----
|
||||
// TypeError 8657: (33-34): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,3 @@
|
||||
type MyFunction is function(uint) returns (uint);
|
||||
// ----
|
||||
// TypeError 8657: (19-49): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,3 @@
|
||||
type MyInt is mapping(uint => uint);
|
||||
// ----
|
||||
// TypeError 8657: (14-35): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,3 @@
|
||||
type MyString is string;
|
||||
// ----
|
||||
// TypeError 8129: (0-24): The underlying type of the user defined value type "MyString" is not a value type.
|
@ -0,0 +1,7 @@
|
||||
struct S {uint x;}
|
||||
|
||||
contract C {
|
||||
type MyType is S;
|
||||
}
|
||||
// ----
|
||||
// TypeError 8657: (52-53): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,4 @@
|
||||
type MyInt1 is MyInt2;
|
||||
type MyInt2 is MyInt1;
|
||||
// ----
|
||||
// TypeError 8657: (15-21): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,3 @@
|
||||
type MyFunction is function(MyFunction) external returns(MyFunction);
|
||||
// ----
|
||||
// TypeError 8657: (19-69): The underlying type for a user defined value type has to be an elementary value type.
|
@ -0,0 +1,13 @@
|
||||
library L {
|
||||
type MyInt is int;
|
||||
}
|
||||
|
||||
contract C {
|
||||
L.MyInt a;
|
||||
type MyInt is int8;
|
||||
}
|
||||
|
||||
contract D is C {
|
||||
C.MyInt b;
|
||||
L.MyInt c;
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
type MyInt is int;
|
||||
type MyInt is int;
|
||||
type MyAddress is address;
|
||||
type MyAddress is uint;
|
||||
// ----
|
||||
// DeclarationError 2333: (19-37): Identifier already declared.
|
||||
// DeclarationError 2333: (65-88): Identifier already declared.
|
@ -0,0 +1,3 @@
|
||||
type MyInt is MyInt;
|
||||
// ----
|
||||
// TypeError 8657: (14-19): The underlying type for a user defined value type has to be an elementary value type.
|
Loading…
Reference in New Issue
Block a user