Skip to content

Commit f75b550

Browse files
committed
Remove CharStream from SourceLocation.
1 parent 57d32ca commit f75b550

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+613
-560
lines changed

libevmasm/Assembly.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ namespace
7676
string locationFromSources(StringMap const& _sourceCodes, SourceLocation const& _location)
7777
{
7878
if (!_location.hasText() || _sourceCodes.empty())
79-
return "";
79+
return {};
8080

81-
auto it = _sourceCodes.find(_location.source->name());
81+
auto it = _sourceCodes.find(*_location.sourceName);
8282
if (it == _sourceCodes.end())
83-
return "";
83+
return {};
8484

8585
string const& source = it->second;
8686
if (static_cast<size_t>(_location.start) >= source.size())
87-
return "";
87+
return {};
8888

8989
string cut = source.substr(static_cast<size_t>(_location.start), static_cast<size_t>(_location.end - _location.start));
9090
auto newLinePos = cut.find_first_of("\n");
@@ -152,8 +152,8 @@ class Functionalizer
152152
if (!m_location.isValid())
153153
return;
154154
m_out << m_prefix << " /*";
155-
if (m_location.source)
156-
m_out << " \"" + m_location.source->name() + "\"";
155+
if (m_location.sourceName)
156+
m_out << " " + escapeAndQuoteYulString(*m_location.sourceName);
157157
if (m_location.hasText())
158158
m_out << ":" << to_string(m_location.start) + ":" + to_string(m_location.end);
159159
m_out << " " << locationFromSources(m_sourceCodes, m_location);
@@ -235,9 +235,9 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices)
235235
for (AssemblyItem const& i: m_items)
236236
{
237237
int sourceIndex = -1;
238-
if (i.location().source)
238+
if (i.location().sourceName)
239239
{
240-
auto iter = _sourceIndices.find(i.location().source->name());
240+
auto iter = _sourceIndices.find(*i.location().sourceName);
241241
if (iter != _sourceIndices.end())
242242
sourceIndex = static_cast<int>(iter->second);
243243
}

libevmasm/AssemblyItem.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,8 @@ std::string AssemblyItem::computeSourceMapping(
350350
SourceLocation const& location = item.location();
351351
int length = location.start != -1 && location.end != -1 ? location.end - location.start : -1;
352352
int sourceIndex =
353-
location.source && _sourceIndicesMap.count(location.source->name()) ?
354-
static_cast<int>(_sourceIndicesMap.at(location.source->name())) :
353+
(location.sourceName && _sourceIndicesMap.count(*location.sourceName)) ?
354+
static_cast<int>(_sourceIndicesMap.at(*location.sourceName)) :
355355
-1;
356356
char jump = '-';
357357
if (item.getJumpType() == evmasm::AssemblyItem::JumpType::IntoFunction)

liblangutil/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ set(sources
1313
ParserBase.h
1414
Scanner.cpp
1515
Scanner.h
16+
CharStreamProvider.h
1617
SemVerHandler.cpp
1718
SemVerHandler.h
1819
SourceLocation.h

liblangutil/CharStream.cpp

+13-3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@
4545
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4646
*/
4747
/**
48-
* @author Christian <[email protected]>
49-
* @date 2014
50-
* Solidity scanner.
48+
* Character stream / input file.
5149
*/
5250

5351
#include <liblangutil/CharStream.h>
@@ -118,3 +116,15 @@ tuple<int, int> CharStream::translatePositionToLineColumn(int _position) const
118116
}
119117
return tuple<int, int>(lineNumber, searchPosition - lineStart);
120118
}
119+
120+
string_view CharStream::text(SourceLocation const& _location) const
121+
{
122+
if (!_location.hasText())
123+
return {};
124+
solAssert(_location.sourceName && *_location.sourceName == m_name, "");
125+
solAssert(static_cast<size_t>(_location.end) <= m_source.size(), "");
126+
return string_view{m_source}.substr(
127+
static_cast<size_t>(_location.start),
128+
static_cast<size_t>(_location.end - _location.start)
129+
);
130+
}

liblangutil/CharStream.h

+11-5
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@
4545
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4646
*/
4747
/**
48-
* @author Christian <[email protected]>
49-
* @date 2014
50-
* Solidity scanner.
48+
* Character stream / input file.
5149
*/
5250

5351
#pragma once
@@ -60,6 +58,8 @@
6058
namespace solidity::langutil
6159
{
6260

61+
struct SourceLocation;
62+
6363
/**
6464
* Bidirectional stream of characters.
6565
*
@@ -69,8 +69,8 @@ class CharStream
6969
{
7070
public:
7171
CharStream() = default;
72-
explicit CharStream(std::string _source, std::string name):
73-
m_source(std::move(_source)), m_name(std::move(name)) {}
72+
CharStream(std::string _source, std::string _name):
73+
m_source(std::move(_source)), m_name(std::move(_name)) {}
7474

7575
size_t position() const { return m_position; }
7676
bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_position + _charsForward) >= m_source.size(); }
@@ -90,6 +90,8 @@ class CharStream
9090
std::string const& source() const noexcept { return m_source; }
9191
std::string const& name() const noexcept { return m_name; }
9292

93+
size_t size() const { return m_source.size(); }
94+
9395
///@{
9496
///@name Error printing helper functions
9597
/// Functions that help pretty-printing parse errors
@@ -112,6 +114,10 @@ class CharStream
112114
return true;
113115
}
114116

117+
/// @returns the substring of the source that the source location references.
118+
/// Returns an empty string view if the source location does not `hasText()`.
119+
std::string_view text(SourceLocation const& _location) const;
120+
115121
private:
116122
std::string m_source;
117123
std::string m_name;

liblangutil/CharStreamProvider.h

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
* Interface to retrieve the character stream by a source name.
20+
*/
21+
22+
#pragma once
23+
24+
#include <liblangutil/CharStream.h>
25+
#include <liblangutil/Exceptions.h>
26+
27+
#include <string>
28+
29+
namespace solidity::langutil
30+
{
31+
32+
/**
33+
* Interface to retrieve a CharStream (source) from a source name.
34+
* Used especially for printing error information.
35+
*/
36+
class CharStreamProvider
37+
{
38+
public:
39+
virtual ~CharStreamProvider() = default;
40+
virtual CharStream const& charStream(std::string const& _sourceName) const = 0;
41+
};
42+
43+
class SingletonCharStreamProvider: public CharStreamProvider
44+
{
45+
public:
46+
explicit SingletonCharStreamProvider(CharStream const& _charStream):
47+
m_charStream(_charStream) {}
48+
CharStream const& charStream(std::string const& _sourceName) const override
49+
{
50+
solAssert(m_charStream.name() == _sourceName, "");
51+
return m_charStream;
52+
}
53+
private:
54+
CharStream const& m_charStream;
55+
};
56+
57+
}

liblangutil/Scanner.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,15 @@ class LiteralScope
138138
void Scanner::reset(CharStream _source)
139139
{
140140
m_source = make_shared<CharStream>(std::move(_source));
141+
m_sourceName = make_shared<string>(m_source->name());
141142
reset();
142143
}
143144

144145
void Scanner::reset(shared_ptr<CharStream> _source)
145146
{
146147
solAssert(_source.get() != nullptr, "You MUST provide a CharStream when resetting.");
147148
m_source = std::move(_source);
149+
m_sourceName = make_shared<string>(m_source->name());
148150
reset();
149151
}
150152

@@ -497,7 +499,7 @@ Token Scanner::scanSlash()
497499
return skipSingleLineComment();
498500
// doxygen style /// comment
499501
m_skippedComments[NextNext].location.start = firstSlashPosition;
500-
m_skippedComments[NextNext].location.source = m_source;
502+
m_skippedComments[NextNext].location.sourceName = m_sourceName;
501503
m_skippedComments[NextNext].token = Token::CommentLiteral;
502504
m_skippedComments[NextNext].location.end = static_cast<int>(scanSingleLineDocComment());
503505
return Token::Whitespace;
@@ -526,7 +528,7 @@ Token Scanner::scanSlash()
526528
return skipMultiLineComment();
527529
// we actually have a multiline documentation comment
528530
m_skippedComments[NextNext].location.start = firstSlashPosition;
529-
m_skippedComments[NextNext].location.source = m_source;
531+
m_skippedComments[NextNext].location.sourceName = m_sourceName;
530532
Token comment = scanMultiLineDocComment();
531533
m_skippedComments[NextNext].location.end = static_cast<int>(sourcePos());
532534
m_skippedComments[NextNext].token = comment;
@@ -766,7 +768,7 @@ void Scanner::scanToken()
766768
}
767769
while (token == Token::Whitespace);
768770
m_tokens[NextNext].location.end = static_cast<int>(sourcePos());
769-
m_tokens[NextNext].location.source = m_source;
771+
m_tokens[NextNext].location.sourceName = m_sourceName;
770772
m_tokens[NextNext].token = token;
771773
m_tokens[NextNext].extendedTokenInfo = make_tuple(m, n);
772774
}

liblangutil/Scanner.h

+1-8
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,6 @@ class Scanner
177177
Token peekNextNextToken() const { return m_tokens[NextNext].token; }
178178
///@}
179179

180-
///@{
181-
///@name Error printing helper functions
182-
/// Functions that help pretty-printing parse errors
183-
/// Do only use in error cases, they are quite expensive.
184-
std::string lineAtPosition(int _position) const { return m_source->lineAtPosition(_position); }
185-
std::tuple<int, int> translatePositionToLineColumn(int _position) const { return m_source->translatePositionToLineColumn(_position); }
186-
///@}
187-
188180
private:
189181

190182
inline Token setError(ScannerError _error) noexcept
@@ -270,6 +262,7 @@ class Scanner
270262
TokenDesc m_tokens[3] = {}; // desc for the current, next and nextnext token
271263

272264
std::shared_ptr<CharStream> m_source;
265+
std::shared_ptr<std::string const> m_sourceName;
273266

274267
ScannerKind m_kind = ScannerKind::Solidity;
275268

liblangutil/SourceLocation.cpp

+2-6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ SourceLocation const parseSourceLocation(std::string const& _input, std::string
3434

3535
boost::algorithm::split(pos, _input, boost::is_any_of(":"));
3636

37+
// TODO What to do with sourceIndex?
3738
solAssert(pos.size() == 3, "SourceLocation string must have 3 colon separated numeric fields.");
3839
auto const sourceIndex = stoi(pos[Index]);
3940

@@ -45,12 +46,7 @@ SourceLocation const parseSourceLocation(std::string const& _input, std::string
4546
int start = stoi(pos[Start]);
4647
int end = start + stoi(pos[Length]);
4748

48-
// ASSUMPTION: only the name of source is used from here on, the m_source of the CharStream-Object can be empty
49-
std::shared_ptr<langutil::CharStream> source;
50-
if (sourceIndex != -1)
51-
source = std::make_shared<langutil::CharStream>("", _sourceName);
52-
53-
return SourceLocation{start, end, source};
49+
return SourceLocation{start, end, std::make_shared<std::string>(_sourceName)};
5450
}
5551

5652
}

liblangutil/SourceLocation.h

+23-32
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
#include <libsolutil/Assertions.h>
2727
#include <libsolutil/Exceptions.h>
2828

29-
#include <liblangutil/CharStream.h>
30-
3129
#include <limits>
3230
#include <memory>
3331
#include <string>
@@ -44,51 +42,44 @@ struct SourceLocation
4442
{
4543
bool operator==(SourceLocation const& _other) const
4644
{
47-
return source.get() == _other.source.get() && start == _other.start && end == _other.end;
45+
return start == _other.start && end == _other.end && equalSources(_other);
4846
}
4947
bool operator!=(SourceLocation const& _other) const { return !operator==(_other); }
5048

51-
inline bool operator<(SourceLocation const& _other) const
49+
bool operator<(SourceLocation const& _other) const
5250
{
53-
if (!source|| !_other.source)
54-
return std::make_tuple(int(!!source), start, end) < std::make_tuple(int(!!_other.source), _other.start, _other.end);
51+
if (!sourceName || !_other.sourceName)
52+
return std::make_tuple(int(!!sourceName), start, end) < std::make_tuple(int(!!_other.sourceName), _other.start, _other.end);
5553
else
56-
return std::make_tuple(source->name(), start, end) < std::make_tuple(_other.source->name(), _other.start, _other.end);
54+
return std::make_tuple(*sourceName, start, end) < std::make_tuple(*_other.sourceName, _other.start, _other.end);
5755
}
5856

59-
inline bool contains(SourceLocation const& _other) const
57+
bool contains(SourceLocation const& _other) const
6058
{
61-
if (!hasText() || !_other.hasText() || source.get() != _other.source.get())
59+
if (!hasText() || !_other.hasText() || !equalSources(_other))
6260
return false;
6361
return start <= _other.start && _other.end <= end;
6462
}
6563

66-
inline bool intersects(SourceLocation const& _other) const
64+
bool intersects(SourceLocation const& _other) const
6765
{
68-
if (!hasText() || !_other.hasText() || source.get() != _other.source.get())
66+
if (!hasText() || !_other.hasText() || !equalSources(_other))
6967
return false;
7068
return _other.start < end && start < _other.end;
7169
}
7270

73-
bool isValid() const { return source || start != -1 || end != -1; }
74-
75-
bool hasText() const
71+
bool equalSources(SourceLocation const& _other) const
7672
{
77-
return
78-
source &&
79-
0 <= start &&
80-
start <= end &&
81-
end <= int(source->source().length());
73+
if (!!sourceName != !!_other.sourceName)
74+
return false;
75+
if (sourceName && *sourceName != *_other.sourceName)
76+
return false;
77+
return true;
8278
}
8379

84-
std::string text() const
85-
{
86-
assertThrow(source, SourceLocationError, "Requested text from null source.");
87-
assertThrow(0 <= start, SourceLocationError, "Invalid source location.");
88-
assertThrow(start <= end, SourceLocationError, "Invalid source location.");
89-
assertThrow(end <= int(source->source().length()), SourceLocationError, "Invalid source location.");
90-
return source->source().substr(size_t(start), size_t(end - start));
91-
}
80+
bool isValid() const { return sourceName || start != -1 || end != -1; }
81+
82+
bool hasText() const { return sourceName && 0 <= start && start <= end; }
9283

9384
/// @returns the smallest SourceLocation that contains both @param _a and @param _b.
9485
/// Assumes that @param _a and @param _b refer to the same source (exception: if the source of either one
@@ -97,8 +88,8 @@ struct SourceLocation
9788
/// @param _b, then start resp. end of the result will be -1 as well).
9889
static SourceLocation smallestCovering(SourceLocation _a, SourceLocation const& _b)
9990
{
100-
if (!_a.source)
101-
_a.source = _b.source;
91+
if (!_a.sourceName)
92+
_a.sourceName = _b.sourceName;
10293

10394
if (_a.start < 0)
10495
_a.start = _b.start;
@@ -112,7 +103,7 @@ struct SourceLocation
112103

113104
int start = -1;
114105
int end = -1;
115-
std::shared_ptr<CharStream> source;
106+
std::shared_ptr<std::string const> sourceName;
116107
};
117108

118109
SourceLocation const parseSourceLocation(
@@ -127,8 +118,8 @@ inline std::ostream& operator<<(std::ostream& _out, SourceLocation const& _locat
127118
if (!_location.isValid())
128119
return _out << "NO_LOCATION_SPECIFIED";
129120

130-
if (_location.source)
131-
_out << _location.source->name();
121+
if (_location.sourceName)
122+
_out << *_location.sourceName;
132123

133124
_out << "[" << _location.start << "," << _location.end << "]";
134125

0 commit comments

Comments
 (0)