Skip to content

Commit db34d02

Browse files
committed
Adjusts support for multi-line sol_t in isoltest.
1 parent e00f358 commit db34d02

File tree

4 files changed

+128
-118
lines changed

4 files changed

+128
-118
lines changed

test/libsolidity/SemanticTest.cpp

+26-13
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@ using namespace boost::unit_test;
3737

3838
namespace
3939
{
40-
string formatBytes(bytes const& _bytes, vector<ABIType> _types, bool const _formatInvalid = false)
40+
string formatBytes(bytes const& _bytes, vector<FormatInfo> _formats, bool const _formatInvalid = false)
4141
{
4242
stringstream resultStream;
4343
auto it = _bytes.begin();
44-
for (auto const& abiType: _types)
44+
for (auto const& format: _formats)
4545
{
46-
bytes byteRange{it, it + abiType.size};
47-
switch (abiType.type)
46+
bytes byteRange{it, it + format.abiType.size};
47+
switch (format.abiType.type)
4848
{
4949
case ABIType::SignedDec:
5050
if (*byteRange.begin() & 0x80)
@@ -70,8 +70,8 @@ namespace
7070
resultStream << fromBigEndian<u256>(byteRange);
7171
break;
7272
}
73-
it += abiType.size;
74-
if (it != _bytes.end())
73+
it += format.abiType.size;
74+
if (it != _bytes.end() && !(format.abiType.type == ABIType::Invalid))
7575
resultStream << ", ";
7676
}
7777
return resultStream.str();
@@ -167,13 +167,23 @@ bool SemanticTest::deploy(string const& _contractName, u256 const& _value, bytes
167167

168168
void SemanticTest::printFunctionCallHighlighted(ostream& _stream, FunctionCall const& _call, string const& _linePrefix) const
169169
{
170-
_stream << _linePrefix << _call.signature;
170+
const bool isMultiLine = _call.displayMode == FunctionCall::DisplayMode::MultiLine;
171+
_stream << _linePrefix << _call.signature
172+
<< (isMultiLine ? "\n" + _linePrefix : "");
173+
171174
if (_call.value > u256(0))
172-
_stream << ", " << _call.value << " " <<TestFileParser::formatToken(SoltToken::Ether);
175+
_stream << TestFileParser::formatToken(SoltToken::Comma)
176+
<< _call.value << " "
177+
<< TestFileParser::formatToken(SoltToken::Ether);
173178
if (!_call.arguments.rawBytes.empty())
174-
_stream << ": " << formatBytes(_call.arguments.rawBytes, _call.arguments.formats);
179+
_stream << ": "
180+
<< formatBytes(_call.arguments.rawBytes, _call.arguments.formats)
181+
<< (isMultiLine ? "\n" + _linePrefix : "");
175182
if (!_call.arguments.comment.empty())
176-
_stream << " # " << _call.arguments.comment;
183+
_stream << " "
184+
<< TestFileParser::formatToken(SoltToken::Comment)
185+
<< _call.arguments.comment
186+
<< TestFileParser::formatToken(SoltToken::Comment);
177187
_stream << endl;
178188
}
179189

@@ -185,12 +195,12 @@ void SemanticTest::printFunctionCallTestHighlighted(
185195
bool const _formatted
186196
) const
187197
{
188-
auto formatOutput = [](bytes _bytes, vector<ABIType> _types, const bool _isExpectation) -> string
198+
auto formatOutput = [](bytes _bytes, vector<FormatInfo> _formats, const bool _isExpectation) -> string
189199
{
190200
if (_bytes.empty())
191201
return TestFileParser::formatToken(SoltToken::Failure);
192202
else
193-
return formatBytes(_bytes, _types, !_isExpectation);
203+
return formatBytes(_bytes, _formats, !_isExpectation);
194204
};
195205
bytes outputBytes = _printExcepted
196206
? _test.call.expectations.rawBytes
@@ -204,6 +214,9 @@ void SemanticTest::printFunctionCallTestHighlighted(
204214
if (_formatted && !_test.matchesExpectation())
205215
_stream << formatting::RESET;
206216
if (!_test.call.expectations.comment.empty())
207-
_stream << " # " << _test.call.expectations.comment;
217+
_stream << " "
218+
<< TestFileParser::formatToken(SoltToken::Comment)
219+
<< _test.call.expectations.comment
220+
<< TestFileParser::formatToken(SoltToken::Comment);
208221
_stream << endl;
209222
}

test/libsolidity/semanticTests/smoke_test.sol

+3-7
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,7 @@ contract C {
1010
}
1111
}
1212
// ----
13-
// iam_not_there()
13+
// h()
14+
// -> 1 # This should work. #
15+
// f(uint256): 1, 2
1416
// -> FAILURE
15-
// f()
16-
// -> 1
17-
// g(uint256,uint256): 4, 8
18-
// -> 4
19-
// h(), 314 ether
20-
// -> 1

test/libsolidity/util/TestFileParser.cpp

+88-92
Original file line numberDiff line numberDiff line change
@@ -52,42 +52,6 @@ namespace
5252
}
5353
}
5454

55-
string TestFileParser::formatToken(SoltToken _token)
56-
{
57-
switch (_token)
58-
{
59-
#define T(name, string, precedence) case SoltToken::name: return string;
60-
SOLT_TOKEN_LIST(T, T)
61-
#undef T
62-
default: // Token::NUM_TOKENS:
63-
return "";
64-
}
65-
}
66-
67-
bool TestFileParser::accept(SoltToken _token, bool const _expect)
68-
{
69-
if (m_scanner.currentToken() == _token)
70-
{
71-
if (_expect)
72-
expect(_token);
73-
return true;
74-
}
75-
return false;
76-
}
77-
78-
bool TestFileParser::expect(SoltToken _token, bool const _advance)
79-
{
80-
if (m_scanner.currentToken() != _token)
81-
throw Error(Error::Type::ParserError,
82-
"Unexpected " + formatToken(m_scanner.currentToken()) + ": \"" +
83-
m_scanner.currentLiteral() + "\". " +
84-
"Expected \"" + formatToken(_token) + "\"."
85-
);
86-
if (_advance)
87-
m_scanner.scanNextToken();
88-
return true;
89-
}
90-
9155
vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
9256
{
9357
vector<FunctionCall> calls;
@@ -116,12 +80,19 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
11680
if (accept(SoltToken::Colon, true))
11781
call.arguments = parseFunctionCallArguments();
11882

83+
if (accept(SoltToken::Newline, true))
84+
call.displayMode = FunctionCall::DisplayMode::MultiLine;
85+
11986
string comment = m_scanner.currentLiteral();
12087
if (accept(SoltToken::Comment, true))
12188
call.arguments.comment = comment;
12289

123-
// -> 1
124-
expect(SoltToken::Newline);
90+
// f() -> 1
91+
// f(uint256): 3
92+
// -> 2
93+
if (accept(SoltToken::Newline, true))
94+
call.displayMode = FunctionCall::DisplayMode::MultiLine;
95+
12596
expect(SoltToken::Arrow);
12697

12798
if (accept(SoltToken::Newline, true))
@@ -143,9 +114,43 @@ vector<dev::solidity::test::FunctionCall> TestFileParser::parseFunctionCalls()
143114
m_scanner.scanNextToken();
144115
}
145116
}
146-
signature += formatToken(SoltToken::RParen);
147-
expect(SoltToken::RParen);
148-
return signature;
117+
return calls;
118+
}
119+
120+
string TestFileParser::formatToken(SoltToken _token)
121+
{
122+
switch (_token)
123+
{
124+
#define T(name, string, precedence) case SoltToken::name: return string;
125+
SOLT_TOKEN_LIST(T, T)
126+
#undef T
127+
default: // Token::NUM_TOKENS:
128+
return "";
129+
}
130+
}
131+
132+
bool TestFileParser::accept(SoltToken _token, bool const _expect)
133+
{
134+
if (m_scanner.currentToken() == _token)
135+
{
136+
if (_expect)
137+
expect(_token);
138+
return true;
139+
}
140+
return false;
141+
}
142+
143+
bool TestFileParser::expect(SoltToken _token, bool const _advance)
144+
{
145+
if (m_scanner.currentToken() != _token)
146+
throw Error(Error::Type::ParserError,
147+
"Unexpected " + formatToken(m_scanner.currentToken()) + ": \"" +
148+
m_scanner.currentLiteral() + "\". " +
149+
"Expected \"" + formatToken(_token) + "\"."
150+
);
151+
if (_advance)
152+
m_scanner.scanNextToken();
153+
return true;
149154
}
150155

151156
string TestFileParser::parseFunctionSignature()
@@ -175,94 +180,67 @@ string TestFileParser::parseFunctionSignature()
175180

176181
u256 TestFileParser::parseFunctionCallValue()
177182
{
178-
u256 value;
179-
string literal = m_scanner.currentLiteral();
180-
expect(SoltToken::Number);
181-
value = convertNumber(literal);
183+
u256 value = convertNumber(parseNumber());
182184
expect(SoltToken::Ether);
183185
return value;
184186
}
185187

186188
FunctionCallArgs TestFileParser::parseFunctionCallArguments()
187189
{
188190
FunctionCallArgs arguments;
191+
std::pair<bytes, ABIType> newline{};
189192

190-
auto formattedBytes = parseNumberLiteral();
191-
arguments.rawBytes += formattedBytes.first;
192-
arguments.formats.emplace_back(std::move(formattedBytes.second));
193+
if (accept(SoltToken::Newline, true))
194+
arguments.appendParameter(newline, true);
195+
arguments.appendParameter(parseABITypeLiteral());
193196
while (accept(SoltToken::Comma, true))
194197
{
195-
auto formattedBytes = parseNumberLiteral();
196-
arguments.rawBytes += formattedBytes.first;
197-
arguments.formats.emplace_back(std::move(formattedBytes.second));
198+
if (accept(SoltToken::Newline, true))
199+
arguments.appendParameter(newline, true);
200+
arguments.appendParameter(parseABITypeLiteral());
198201
}
199-
return expectations;
202+
return arguments;
200203
}
201204

202-
pair<bytes, ABIType> TestFileParser::parseABITypeLiteral()
205+
FunctionCallExpectations TestFileParser::parseFunctionCallExpectations()
203206
{
204207
FunctionCallExpectations expectations;
205-
string token = m_scanner.currentLiteral();
208+
std::pair<bytes, ABIType> newline{};
206209

207210
if (accept(SoltToken::Failure, true))
208211
expectations.status = false;
209212
else
210213
{
211-
auto formattedBytes = parseNumberLiteral();
212-
expectations.rawBytes += formattedBytes.first;
213-
expectations.formats.emplace_back(std::move(formattedBytes.second));
214-
214+
if (accept(SoltToken::Newline, true))
215+
expectations.appendExpected(newline, true);
216+
expectations.appendExpected(parseABITypeLiteral());
215217
while (accept(SoltToken::Comma, true))
216218
{
217-
auto formattedBytes = parseNumberLiteral();
218-
expectations.rawBytes += formattedBytes.first;
219-
expectations.formats.emplace_back(std::move(formattedBytes.second));
219+
if (accept(SoltToken::Newline, true))
220+
expectations.appendExpected(newline, true);
221+
expectations.appendExpected(parseABITypeLiteral());
220222
}
221-
else
222-
if (accept(SoltToken::Number))
223-
{
224-
abiType = ABIType{ABIType::UnsignedDec, 32};
225-
number = convertNumber(parseNumber());
226-
}
227-
return make_pair(toBigEndian(number), abiType);
228223
}
229224
return expectations;
230225
}
231226

232-
u256 TestFileParser::convertNumber(string const& _literal)
233-
{
234-
try {
235-
return u256{_literal};
236-
}
237-
catch (std::exception const&)
238-
{
239-
throw Error(Error::Type::ParserError, "Number encoding invalid.");
240-
}
241-
}
242-
243-
pair<bytes, ABIType> TestFileParser::parseNumberLiteral()
227+
pair<bytes, ABIType> TestFileParser::parseABITypeLiteral()
244228
{
245-
u256 number;
246-
ABIType abiType;
247229
try
248230
{
231+
u256 number;
232+
ABIType abiType;
249233
if (accept(SoltToken::Sub))
250234
{
251-
abiType.type = ABIType::Type::SignedDec;
235+
abiType = ABIType{ABIType::SignedDec, 32};
252236
expect(SoltToken::Sub);
253-
254-
string literal = m_scanner.currentLiteral();
255-
expect(SoltToken::Number);
256-
number = convertNumber(literal) * -1;
237+
number = convertNumber(parseNumber()) * -1;
257238
}
258239
else
259240
if (accept(SoltToken::Number))
260241
{
261-
abiType.type = ABIType::Type::UnsignedDec;
262-
263-
string literal = m_scanner.currentLiteral();
264-
expect(SoltToken::Number);
265-
number = convertNumber(literal);
242+
abiType = ABIType{ABIType::UnsignedDec, 32};
243+
number = convertNumber(parseNumber());
266244
}
267245
return make_pair(toBigEndian(number), abiType);
268246
}
@@ -272,6 +250,24 @@ pair<bytes, ABIType> TestFileParser::parseNumberLiteral()
272250
}
273251
}
274252

253+
string TestFileParser::parseNumber()
254+
{
255+
string literal = m_scanner.currentLiteral();
256+
expect(SoltToken::Number);
257+
return literal;
258+
}
259+
260+
u256 TestFileParser::convertNumber(string const& _literal)
261+
{
262+
try {
263+
return u256{_literal};
264+
}
265+
catch (std::exception const&)
266+
{
267+
throw Error(Error::Type::ParserError, "Number encoding invalid.");
268+
}
269+
}
270+
275271
void TestFileParser::Scanner::readStream(istream& _stream)
276272
{
277273
std::string line;

test/libsolidity/util/TestFileParser.h

+11-6
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@ namespace test
3232
{
3333

3434
/**
35-
* All SOLT (or sol_t) tokens.
35+
* All SOLT (or SOLTest) tokens.
3636
*/
3737
#define SOLT_TOKEN_LIST(T, K) \
3838
T(Unknown, "unknown", 0) \
39+
T(Invalid, "invalid", 0) \
3940
T(EOS, "EOS", 0) \
41+
T(Whitespace, "_", 0) \
42+
/* punctuations */ \
4043
T(LParen, "(", 0) \
4144
T(RParen, ")", 0) \
4245
T(LBrack, "[", 0) \
@@ -52,8 +55,8 @@ namespace test
5255
/* Literals & identifier */ \
5356
T(Comment, "#", 0) \
5457
T(Number, "number", 0) \
55-
K(Failure, "FAILURE", 0) \
56-
/* type keywords*/ \
58+
T(Identifier, "identifier", 0) \
59+
/* type keywords */ \
5760
K(Ether, "ether", 0) \
5861
K(UInt, "uint256", 0) \
5962
/* special keywords */ \
@@ -67,9 +70,11 @@ enum class SoltToken : unsigned int {
6770
};
6871

6972
/**
70-
* Format information used for the conversion of human-readable
71-
* function arguments and return values to `bytes`. Defaults to
72-
* a 32-byte representation.
73+
* The purpose of the ABI type is the storage of type information
74+
* retrieved while parsing a test. This information is used
75+
* for the conversion of human-readable function arguments and
76+
* return values to `bytes` and vice-versa.
77+
* Defaults to an invalid 0-byte representation.
7378
*/
7479
struct ABIType
7580
{

0 commit comments

Comments
 (0)