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;
|
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)
|
void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)
|
||||||
{
|
{
|
||||||
if (_typeName.annotation().type)
|
if (_typeName.annotation().type)
|
||||||
@ -158,6 +182,8 @@ void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName)
|
|||||||
_typeName.annotation().type = TypeProvider::enumType(*enumDef);
|
_typeName.annotation().type = TypeProvider::enumType(*enumDef);
|
||||||
else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
|
else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
|
||||||
_typeName.annotation().type = TypeProvider::contract(*contract);
|
_typeName.annotation().type = TypeProvider::contract(*contract);
|
||||||
|
else if (auto userDefinedValueType = dynamic_cast<UserDefinedValueTypeDefinition const*>(declaration))
|
||||||
|
_typeName.annotation().type = TypeProvider::userDefinedValueType(*userDefinedValueType);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_typeName.annotation().type = TypeProvider::emptyTuple();
|
_typeName.annotation().type = TypeProvider::emptyTuple();
|
||||||
|
@ -60,6 +60,7 @@ private:
|
|||||||
void endVisit(VariableDeclaration const& _variable) override;
|
void endVisit(VariableDeclaration const& _variable) override;
|
||||||
bool visit(EnumDefinition const& _enum) override;
|
bool visit(EnumDefinition const& _enum) override;
|
||||||
bool visit(StructDefinition const& _struct) override;
|
bool visit(StructDefinition const& _struct) override;
|
||||||
|
void endVisit(UserDefinedValueTypeDefinition const& _userDefined) override;
|
||||||
bool visit(UsingForDirective const& _usingForDirective) override;
|
bool visit(UsingForDirective const& _usingForDirective) override;
|
||||||
bool visit(InheritanceSpecifier const& _inheritanceSpecifier) 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