-
Notifications
You must be signed in to change notification settings - Fork 6k
/
Copy pathObject.h
170 lines (134 loc) · 5.65 KB
/
Object.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
/**
* Yul code and data object container.
*/
#pragma once
#include <libyul/ASTForward.h>
#include <libyul/AsmPrinter.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <libsolutil/Common.h>
#include <libsolutil/JSON.h>
#include <memory>
#include <set>
#include <limits>
namespace solidity::yul
{
class Dialect;
struct AsmAnalysisInfo;
using SourceNameMap = std::map<unsigned, std::shared_ptr<std::string const>>;
class Object;
/**
* Generic base class for both Yul objects and Yul data.
*/
struct ObjectNode
{
virtual ~ObjectNode() = default;
/// Name of the object.
/// Can be empty since .yul files can also just contain code, without explicitly placing it in an object.
std::string name;
virtual std::string toString(
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
) const = 0;
virtual Json toJson() const = 0;
};
/**
* Named data in Yul objects.
*/
struct Data: public ObjectNode
{
Data(std::string _name, bytes _data): data(std::move(_data)) { name = _name; }
bytes data;
std::string toString(
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
) const override;
Json toJson() const override;
};
struct ObjectDebugData
{
std::optional<SourceNameMap> sourceNames = {};
std::string formatUseSrcComment() const;
};
/**
* Yul code and data object container.
*/
class Object: public ObjectNode
{
public:
/// @returns a (parseable) string representation.
std::string toString(
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
) const override;
/// @returns a compact JSON representation of the AST.
Json toJson() const override;
/// Summarizes the structure of the subtree rooted at a given object,
/// in particular the paths that can be used from within to refer to nested nodes (objects and data).
struct Structure
{
/// The name of the object
std::string objectName;
/// Available dot-separated paths to nested objects (relative to current object).
std::set<std::string> objectPaths;
/// Available dot-separated paths to nested data entries (relative to current object).
std::set<std::string> dataPaths;
/// Checks if a path is available.
bool contains(std::string const& _path) const { return containsObject(_path) || containsData(_path); }
/// Checks if a path is available and leads to an object.
bool containsObject(std::string const& _path) const { return objectPaths.count(_path) > 0; }
/// Checks if a path is available and leads to a data entry.
bool containsData(std::string const& _path) const { return dataPaths.count(_path) > 0; }
std::set<std::string> topLevelSubObjectNames() const;
};
/// @returns the set of names of data objects accessible from within the code of
/// this object, including the name of object itself
/// Handles all names containing dots as reserved identifiers, not accessible as data.
Structure summarizeStructure() const;
/// @returns vector of subIDs if possible to reach subobject with @a _qualifiedName, throws otherwise
/// For "B.C" should return vector of two values if success (subId of B and subId of C in B).
/// In object "A" if called for "A.B" will return only one value (subId for B)
/// will return empty vector for @a _qualifiedName that equals to object name.
/// Example:
/// A1{ B2{ C3, D3 }, E2{ F3{ G4, K4, H4{ I5 } } } }
/// pathToSubObject("A1.E2.F3.H4") == {1, 0, 2}
/// pathToSubObject("E2.F3.H4") == {1, 0, 2}
/// pathToSubObject("A1.E2") == {1}
/// The path must not lead to a @a Data object (will throw in that case).
std::vector<size_t> pathToSubObject(std::string_view _qualifiedName) const;
std::shared_ptr<AST const> code() const;
void setCode(std::shared_ptr<AST const> const& _ast, std::shared_ptr<yul::AsmAnalysisInfo> = nullptr);
bool hasCode() const;
/// sub id for object if it is subobject of another object, max value if it is not subobject
size_t subId = std::numeric_limits<size_t>::max();
std::vector<std::shared_ptr<ObjectNode>> subObjects;
std::map<std::string, size_t, std::less<>> subIndexByName;
std::shared_ptr<yul::AsmAnalysisInfo> analysisInfo;
std::shared_ptr<ObjectDebugData const> debugData;
/// Collects names of all Solidity source units present in the debug data
/// of the Yul object (including sub-objects) and their assigned indices.
/// @param _indices map that will be filled with source indices of the current Yul object & its sub-objects.
void collectSourceIndices(std::map<std::string, unsigned>& _indices) const;
/// @returns true, if the range of source indices starts at zero and is contiguous, false otherwise.
bool hasContiguousSourceIndices() const;
/// @returns the name of the special metadata data object.
static std::string metadataName() { return ".metadata"; }
Dialect const* dialect() const;
private:
std::shared_ptr<AST const> m_code;
};
}