Coverage Report

Created: 2025-09-04 07:34

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