@@ -39,22 +39,66 @@ using FunctionTypePointer = FunctionType const*;
39
39
namespace solidity ::frontend::test
40
40
{
41
41
42
+ enum class PipelineStage {
43
+ Parsing,
44
+ Analysis,
45
+ Compilation,
46
+ };
47
+
42
48
class AnalysisFramework
43
49
{
44
50
45
51
protected:
46
- virtual std::pair<SourceUnit const *, langutil::ErrorList>
47
- parseAnalyseAndReturnError (
52
+ virtual ~AnalysisFramework () = default ;
53
+
54
+ // / Runs analysis via runFramework() and returns either an AST or a filtered list of errors.
55
+ // / Uses Boost test macros to fail if errors do not occur specifically at the analysis stage.
56
+ // /
57
+ // / @deprecated This is a legacy helper. Use runFramework() directly in new tests.
58
+ // /
59
+ // / @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.
60
+ // / @param _addPreamble Apply withPreamble() to @p _source.
61
+ // / @param _allowMultiple When false, use Boost test macros to fail when there's more
62
+ // / than one item on the error list.
63
+ std::pair<SourceUnit const *, langutil::ErrorList> runAnalysisAndExpectNoParsingErrors (
48
64
std::string const & _source,
49
- bool _reportWarnings = false ,
50
- bool _insertLicenseAndVersionPragma = true ,
51
- bool _allowMultipleErrors = false
65
+ bool _includeWarningsAndInfos = false ,
66
+ bool _addPreamble = true ,
67
+ bool _allowMultiple = false
52
68
);
53
- virtual ~AnalysisFramework () = default ;
54
69
55
- SourceUnit const * parseAndAnalyse (std::string const & _source);
56
- bool success (std::string const & _source);
57
- langutil::ErrorList expectError (std::string const & _source, bool _warning = false , bool _allowMultiple = false );
70
+ // / Runs analysis via runAnalysisAndExpectNoParsingErrors() and returns the list of errors.
71
+ // / Uses Boost test macros to fail if there are no errors.
72
+ // /
73
+ // / @deprecated This is a legacy helper. Use runFramework() directly in new tests.
74
+ // /
75
+ // / @param _includeWarningsAndInfos Do not remove warning and info messages from the error list.
76
+ // / @param _allowMultiple When false, use Boost test macros to fail when there's more
77
+ // / than one item on the error list.
78
+ langutil::ErrorList runAnalysisAndExpectError (
79
+ std::string const & _source,
80
+ bool _includeWarningsAndInfos = false ,
81
+ bool _allowMultiple = false
82
+ );
83
+
84
+ public:
85
+ // / Runs the full compiler pipeline on specified sources. This is the main function of the
86
+ // / framework. Resets the stack, configures it and runs either until the first failed stage or
87
+ // / until the @p _targetStage is reached.
88
+ // / Afterwards the caller can inspect the stack via @p compiler(). The framework provides a few
89
+ // / convenience helpers to check the state and error list, in general the caller can freely
90
+ // / access the stack, including generating outputs if the compilation succeeded.
91
+ bool runFramework (StringMap _sources, PipelineStage _targetStage = PipelineStage::Compilation);
92
+ bool runFramework (std::string _source, PipelineStage _targetStage = PipelineStage::Compilation)
93
+ {
94
+ return runFramework ({{" " , std::move (_source)}}, _targetStage);
95
+ }
96
+
97
+ void resetFramework ();
98
+
99
+ PipelineStage targetStage () const { return m_targetStage; }
100
+ bool pipelineSuccessful () const { return stageSuccessful (m_targetStage); }
101
+ bool stageSuccessful (PipelineStage _stage) const ;
58
102
59
103
std::string formatErrors (
60
104
langutil::ErrorList const & _errors,
@@ -80,9 +124,6 @@ class AnalysisFramework
80
124
return filterErrors (compiler ().errors (), _includeWarningsAndInfos);
81
125
}
82
126
83
- std::vector<std::string> m_warningsToFilter = {" This is a pre-release compiler version" };
84
- std::vector<std::string> m_messagesToCut = {" Source file requires different compiler version (current compiler is" };
85
-
86
127
// / @returns reference to lazy-instantiated CompilerStack.
87
128
solidity::frontend::CompilerStack& compiler ()
88
129
{
@@ -99,28 +140,41 @@ class AnalysisFramework
99
140
return *m_compiler;
100
141
}
101
142
143
+ protected:
102
144
// / Creates a new instance of @p CompilerStack. Override if your test case needs to pass in
103
145
// / custom constructor arguments.
104
146
virtual std::unique_ptr<CompilerStack> createStack () const ;
105
147
148
+ // / Configures @p CompilerStack. The default implementation sets basic parameters based on
149
+ // / CLI options. Override if your test case needs extra configuration.
150
+ virtual void setupCompiler (CompilerStack& _compiler);
151
+
152
+ // / Executes the requested pipeline stages until @p m_targetStage is reached.
153
+ // / Stops at the first failed stage.
154
+ void executeCompilationPipeline ();
155
+
156
+ std::vector<std::string> m_warningsToFilter = {" This is a pre-release compiler version" };
157
+ std::vector<std::string> m_messagesToCut = {" Source file requires different compiler version (current compiler is" };
158
+
106
159
private:
107
160
mutable std::unique_ptr<solidity::frontend::CompilerStack> m_compiler;
161
+ PipelineStage m_targetStage = PipelineStage::Compilation;
108
162
};
109
163
110
164
// Asserts that the compilation down to typechecking
111
165
// emits multiple errors of different types and messages, provided in the second argument.
112
166
#define CHECK_ALLOW_MULTI (text, expectations ) \
113
167
do \
114
168
{ \
115
- ErrorList errors = expectError ((text), true , true ); \
169
+ ErrorList errors = runAnalysisAndExpectError ((text), true , true ); \
116
170
auto message = searchErrors (errors, (expectations)); \
117
171
BOOST_CHECK_MESSAGE (message.empty (), message); \
118
172
} while (0 )
119
173
120
- #define CHECK_ERROR_OR_WARNING (text, typ, substrings, warning , allowMulti ) \
174
+ #define CHECK_ERROR_OR_WARNING (text, typ, substrings, includeWarningsAndInfos , allowMulti ) \
121
175
do \
122
176
{ \
123
- ErrorList errors = expectError ((text), (warning ), (allowMulti)); \
177
+ ErrorList errors = runAnalysisAndExpectError ((text), (includeWarningsAndInfos ), (allowMulti)); \
124
178
std::vector<std::pair<Error::Type, std::string>> expectations; \
125
179
for (auto const & str: substrings) \
126
180
expectations.emplace_back ((Error::Type::typ), str); \
@@ -154,16 +208,19 @@ CHECK_ERROR_OR_WARNING(text, Warning, std::vector<std::string>{(substring)}, tru
154
208
CHECK_ERROR_OR_WARNING (text, Warning, substrings, true , true )
155
209
156
210
// [checkSuccess(text)] asserts that the compilation down to typechecking succeeds.
157
- #define CHECK_SUCCESS (text ) do { BOOST_CHECK (success ((text))); } while (0 )
211
+ #define CHECK_SUCCESS (text ) do { \
212
+ auto [ast, errors] = runAnalysisAndExpectNoParsingErrors ((text)); \
213
+ BOOST_CHECK (errors.empty ()); \
214
+ } while (0 )
158
215
159
216
#define CHECK_SUCCESS_NO_WARNINGS (text ) \
160
217
do \
161
218
{ \
162
- auto sourceAndError = parseAnalyseAndReturnError ((text), true ); \
219
+ auto [ast, errors] = runAnalysisAndExpectNoParsingErrors ((text), true ); \
163
220
std::string message; \
164
- if (!sourceAndError. second .empty ()) \
165
- message = formatErrors (compiler (). errors () );\
166
- BOOST_CHECK_MESSAGE (sourceAndError. second .empty (), message); \
221
+ if (!errors .empty ()) \
222
+ message = formatErrors (errors);\
223
+ BOOST_CHECK_MESSAGE (errors .empty (), message); \
167
224
} \
168
225
while (0 )
169
226
0 commit comments