mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #7267 from ethereum/globalStruct
Allow global struct definitions.
This commit is contained in:
commit
ac5498bb88
@ -5,6 +5,7 @@ Breaking changes:
|
||||
|
||||
|
||||
Language Features:
|
||||
* Allow global enums and structs.
|
||||
|
||||
|
||||
Compiler Features:
|
||||
|
@ -285,17 +285,17 @@ bool CompilerStack::analyze()
|
||||
// the special variables "this" and "super" must be set appropriately.
|
||||
for (Source const* source: m_sourceOrder)
|
||||
for (ASTPointer<ASTNode> const& node: source->ast->nodes())
|
||||
{
|
||||
if (!resolver.resolveNamesAndTypes(*node))
|
||||
return false;
|
||||
if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
|
||||
{
|
||||
|
||||
if (!resolver.resolveNamesAndTypes(*contract)) return false;
|
||||
// Note that we now reference contracts by their fully qualified names, and
|
||||
// thus contracts can only conflict if declared in the same source file. This
|
||||
// already causes a double-declaration error elsewhere, so we do not report
|
||||
// an error here and instead silently drop any additional contracts we find.
|
||||
if (m_contracts.find(contract->fullyQualifiedName()) == m_contracts.end())
|
||||
m_contracts[contract->fullyQualifiedName()].contract = contract;
|
||||
}
|
||||
}
|
||||
|
||||
// Next, we check inheritance, overrides, function collisions and other things at
|
||||
// contract or function level.
|
||||
|
@ -96,8 +96,14 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
||||
case Token::Library:
|
||||
nodes.push_back(parseContractDefinition());
|
||||
break;
|
||||
case Token::Struct:
|
||||
nodes.push_back(parseStructDefinition());
|
||||
break;
|
||||
case Token::Enum:
|
||||
nodes.push_back(parseEnumDefinition());
|
||||
break;
|
||||
default:
|
||||
fatalParserError(string("Expected pragma, import directive or contract/interface/library definition."));
|
||||
fatalParserError(string("Expected pragma, import directive or contract/interface/library/struct/enum definition."));
|
||||
}
|
||||
}
|
||||
solAssert(m_recursionDepth == 0, "");
|
||||
|
58
test/libsolidity/ABIJson/global_struct.sol
Normal file
58
test/libsolidity/ABIJson/global_struct.sol
Normal file
@ -0,0 +1,58 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
struct S { uint a; }
|
||||
contract C {
|
||||
function f(S calldata s) external view {}
|
||||
function g(S memory s) public view {}
|
||||
}
|
||||
// ----
|
||||
// :C
|
||||
// [
|
||||
// {
|
||||
// "constant": true,
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "components":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "uint256",
|
||||
// "name": "a",
|
||||
// "type": "uint256"
|
||||
// }
|
||||
// ],
|
||||
// "internalType": "struct S",
|
||||
// "name": "s",
|
||||
// "type": "tuple"
|
||||
// }
|
||||
// ],
|
||||
// "name": "g",
|
||||
// "outputs": [],
|
||||
// "payable": false,
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// },
|
||||
// {
|
||||
// "constant": true,
|
||||
// "inputs":
|
||||
// [
|
||||
// {
|
||||
// "components":
|
||||
// [
|
||||
// {
|
||||
// "internalType": "uint256",
|
||||
// "name": "a",
|
||||
// "type": "uint256"
|
||||
// }
|
||||
// ],
|
||||
// "internalType": "struct S",
|
||||
// "name": "s",
|
||||
// "type": "tuple"
|
||||
// }
|
||||
// ],
|
||||
// "name": "f",
|
||||
// "outputs": [],
|
||||
// "payable": false,
|
||||
// "stateMutability": "view",
|
||||
// "type": "function"
|
||||
// }
|
||||
// ]
|
32
test/libsolidity/ASTJSON/global_enum.json
Normal file
32
test/libsolidity/ASTJSON/global_enum.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"absolutePath" : "a",
|
||||
"exportedSymbols" :
|
||||
{
|
||||
"E" :
|
||||
[
|
||||
2
|
||||
]
|
||||
},
|
||||
"id" : 3,
|
||||
"nodeType" : "SourceUnit",
|
||||
"nodes" :
|
||||
[
|
||||
{
|
||||
"canonicalName" : "E",
|
||||
"id" : 2,
|
||||
"members" :
|
||||
[
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "A",
|
||||
"nodeType" : "EnumValue",
|
||||
"src" : "9:1:1"
|
||||
}
|
||||
],
|
||||
"name" : "E",
|
||||
"nodeType" : "EnumDefinition",
|
||||
"src" : "0:12:1"
|
||||
}
|
||||
],
|
||||
"src" : "0:13:1"
|
||||
}
|
3
test/libsolidity/ASTJSON/global_enum.sol
Normal file
3
test/libsolidity/ASTJSON/global_enum.sol
Normal file
@ -0,0 +1,3 @@
|
||||
enum E { A }
|
||||
|
||||
// ----
|
41
test/libsolidity/ASTJSON/global_enum_legacy.json
Normal file
41
test/libsolidity/ASTJSON/global_enum_legacy.json
Normal file
@ -0,0 +1,41 @@
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"absolutePath" : "a",
|
||||
"exportedSymbols" :
|
||||
{
|
||||
"E" :
|
||||
[
|
||||
2
|
||||
]
|
||||
}
|
||||
},
|
||||
"children" :
|
||||
[
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"canonicalName" : "E",
|
||||
"name" : "E"
|
||||
},
|
||||
"children" :
|
||||
[
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"name" : "A"
|
||||
},
|
||||
"id" : 1,
|
||||
"name" : "EnumValue",
|
||||
"src" : "9:1:1"
|
||||
}
|
||||
],
|
||||
"id" : 2,
|
||||
"name" : "EnumDefinition",
|
||||
"src" : "0:12:1"
|
||||
}
|
||||
],
|
||||
"id" : 3,
|
||||
"name" : "SourceUnit",
|
||||
"src" : "0:13:1"
|
||||
}
|
58
test/libsolidity/ASTJSON/global_struct.json
Normal file
58
test/libsolidity/ASTJSON/global_struct.json
Normal file
@ -0,0 +1,58 @@
|
||||
{
|
||||
"absolutePath" : "a",
|
||||
"exportedSymbols" :
|
||||
{
|
||||
"S" :
|
||||
[
|
||||
3
|
||||
]
|
||||
},
|
||||
"id" : 4,
|
||||
"nodeType" : "SourceUnit",
|
||||
"nodes" :
|
||||
[
|
||||
{
|
||||
"canonicalName" : "S",
|
||||
"id" : 3,
|
||||
"members" :
|
||||
[
|
||||
{
|
||||
"constant" : false,
|
||||
"id" : 2,
|
||||
"name" : "a",
|
||||
"nodeType" : "VariableDeclaration",
|
||||
"overrides" : null,
|
||||
"scope" : 3,
|
||||
"src" : "11:9:1",
|
||||
"stateVariable" : false,
|
||||
"storageLocation" : "default",
|
||||
"typeDescriptions" :
|
||||
{
|
||||
"typeIdentifier" : "t_uint256",
|
||||
"typeString" : "uint256"
|
||||
},
|
||||
"typeName" :
|
||||
{
|
||||
"id" : 1,
|
||||
"name" : "uint256",
|
||||
"nodeType" : "ElementaryTypeName",
|
||||
"src" : "11:7:1",
|
||||
"typeDescriptions" :
|
||||
{
|
||||
"typeIdentifier" : "t_uint256",
|
||||
"typeString" : "uint256"
|
||||
}
|
||||
},
|
||||
"value" : null,
|
||||
"visibility" : "internal"
|
||||
}
|
||||
],
|
||||
"name" : "S",
|
||||
"nodeType" : "StructDefinition",
|
||||
"scope" : 4,
|
||||
"src" : "0:23:1",
|
||||
"visibility" : "public"
|
||||
}
|
||||
],
|
||||
"src" : "0:24:1"
|
||||
}
|
3
test/libsolidity/ASTJSON/global_struct.sol
Normal file
3
test/libsolidity/ASTJSON/global_struct.sol
Normal file
@ -0,0 +1,3 @@
|
||||
struct S { uint256 a; }
|
||||
|
||||
// ----
|
64
test/libsolidity/ASTJSON/global_struct_legacy.json
Normal file
64
test/libsolidity/ASTJSON/global_struct_legacy.json
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"absolutePath" : "a",
|
||||
"exportedSymbols" :
|
||||
{
|
||||
"S" :
|
||||
[
|
||||
3
|
||||
]
|
||||
}
|
||||
},
|
||||
"children" :
|
||||
[
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"canonicalName" : "S",
|
||||
"name" : "S",
|
||||
"scope" : 4,
|
||||
"visibility" : "public"
|
||||
},
|
||||
"children" :
|
||||
[
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"constant" : false,
|
||||
"name" : "a",
|
||||
"overrides" : null,
|
||||
"scope" : 3,
|
||||
"stateVariable" : false,
|
||||
"storageLocation" : "default",
|
||||
"type" : "uint256",
|
||||
"value" : null,
|
||||
"visibility" : "internal"
|
||||
},
|
||||
"children" :
|
||||
[
|
||||
{
|
||||
"attributes" :
|
||||
{
|
||||
"name" : "uint256",
|
||||
"type" : "uint256"
|
||||
},
|
||||
"id" : 1,
|
||||
"name" : "ElementaryTypeName",
|
||||
"src" : "11:7:1"
|
||||
}
|
||||
],
|
||||
"id" : 2,
|
||||
"name" : "VariableDeclaration",
|
||||
"src" : "11:9:1"
|
||||
}
|
||||
],
|
||||
"id" : 3,
|
||||
"name" : "StructDefinition",
|
||||
"src" : "0:23:1"
|
||||
}
|
||||
],
|
||||
"id" : 4,
|
||||
"name" : "SourceUnit",
|
||||
"src" : "0:24:1"
|
||||
}
|
10
test/libsolidity/semanticTests/structs/global.sol
Normal file
10
test/libsolidity/semanticTests/structs/global.sol
Normal file
@ -0,0 +1,10 @@
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
struct S { uint256 a; uint256 b; }
|
||||
contract C {
|
||||
function f(S calldata s) external pure returns (uint256, uint256) {
|
||||
return (s.a, s.b);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// f((uint256,uint256)): 42, 23 -> 42, 23
|
7
test/libsolidity/syntaxTests/enums/global_enum.sol
Normal file
7
test/libsolidity/syntaxTests/enums/global_enum.sol
Normal file
@ -0,0 +1,7 @@
|
||||
enum E { A }
|
||||
contract C {
|
||||
function f() public pure {
|
||||
E e = E.A;
|
||||
e;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
enum E { A }
|
||||
contract E {}
|
||||
// ----
|
||||
// DeclarationError: (13-26): Identifier already declared.
|
@ -0,0 +1,4 @@
|
||||
enum E { A }
|
||||
enum E { A }
|
||||
// ----
|
||||
// DeclarationError: (13-25): Identifier already declared.
|
10
test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol
Normal file
10
test/libsolidity/syntaxTests/enums/global_enum_shadowing.sol
Normal file
@ -0,0 +1,10 @@
|
||||
enum E { A }
|
||||
contract C {
|
||||
enum E { A }
|
||||
function f() public pure {
|
||||
E e = E.A;
|
||||
e;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (30-42): This declaration shadows an existing declaration.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
contract A {}
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:12-35): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
contract A {}
|
||||
==== Source: b ====
|
||||
import "a" as A;
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:17-40): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
contract A {}
|
||||
==== Source: b ====
|
||||
import {A as b} from "a";
|
||||
struct b { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:26-49): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
contract A {}
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:21-44): Identifier already declared.
|
@ -0,0 +1,5 @@
|
||||
==== Source: a ====
|
||||
contract A {}
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
struct B { uint256 a; }
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
enum E { A }
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
enum E { A }
|
||||
// ----
|
||||
// DeclarationError: (b:12-24): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
enum E { A }
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
contract E { }
|
||||
// ----
|
||||
// DeclarationError: (b:12-26): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
enum E { A }
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
struct E { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:12-35): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:12-35): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import "a" as A;
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:17-40): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A as b} from "a";
|
||||
struct b { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:26-49): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
struct A { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (b:21-44): Identifier already declared.
|
@ -0,0 +1,5 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
struct B { uint256 a; }
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import "a";
|
||||
contract A {}
|
||||
// ----
|
||||
// DeclarationError: (b:12-25): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import "a" as A;
|
||||
contract A {}
|
||||
// ----
|
||||
// DeclarationError: (b:17-30): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A as b} from "a";
|
||||
contract b {}
|
||||
// ----
|
||||
// DeclarationError: (b:26-39): Identifier already declared.
|
@ -0,0 +1,7 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
contract A {}
|
||||
// ----
|
||||
// DeclarationError: (b:21-34): Identifier already declared.
|
@ -0,0 +1,5 @@
|
||||
==== Source: a ====
|
||||
struct A { uint256 a; }
|
||||
==== Source: b ====
|
||||
import {A} from "a";
|
||||
contract B {}
|
@ -0,0 +1,4 @@
|
||||
contract S {}
|
||||
struct S { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (14-37): Identifier already declared.
|
7
test/libsolidity/syntaxTests/structs/global_struct.sol
Normal file
7
test/libsolidity/syntaxTests/structs/global_struct.sol
Normal file
@ -0,0 +1,7 @@
|
||||
struct S { uint a; }
|
||||
contract C {
|
||||
function f() public pure {
|
||||
S memory s = S(42);
|
||||
s;
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
struct S { uint256 a; }
|
||||
contract S {}
|
||||
// ----
|
||||
// DeclarationError: (24-37): Identifier already declared.
|
@ -0,0 +1,10 @@
|
||||
struct S { uint a; }
|
||||
contract C {
|
||||
struct S { address x; }
|
||||
function f() public view {
|
||||
S memory s = S(address(this));
|
||||
s;
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (38-61): This declaration shadows an existing declaration.
|
@ -0,0 +1,4 @@
|
||||
struct S { uint256 a; }
|
||||
struct S { uint256 a; }
|
||||
// ----
|
||||
// DeclarationError: (24-47): Identifier already declared.
|
Loading…
Reference in New Issue
Block a user