Skip to content

Commit d8e1af6

Browse files
committed
Test: Add abstraction for internal compiler
1 parent 7e78843 commit d8e1af6

File tree

4 files changed

+222
-0
lines changed

4 files changed

+222
-0
lines changed

test/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ detect_stray_source_files("${libsolidity_sources}" "libsolidity/")
119119
set(libsolidity_util_sources
120120
libsolidity/util/compiler/Compiler.h
121121
libsolidity/util/compiler/Compiler.cpp
122+
libsolidity/util/compiler/InternalCompiler.h
123+
libsolidity/util/compiler/InternalCompiler.cpp
122124
libsolidity/util/BytesUtils.cpp
123125
libsolidity/util/BytesUtilsTests.cpp
124126
libsolidity/util/BytesUtils.h
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
#include <test/libsolidity/util/compiler/InternalCompiler.h>
2+
3+
using namespace solidity;
4+
using namespace solidity::evmasm;
5+
using namespace solidity::frontend::test;
6+
7+
CompilerOutput InternalCompiler::compile(CompilerInput const& _input)
8+
{
9+
configure(_input);
10+
11+
auto [contracts, errors] = internalCompile(_input);
12+
bool success = m_stack.compilationSuccessful();
13+
14+
return CompilerOutput{
15+
contracts,
16+
success,
17+
errors,
18+
formatErrorInformation()
19+
};
20+
}
21+
22+
void InternalCompiler::configure(CompilerInput const& _input)
23+
{
24+
m_stack.reset();
25+
26+
m_stack.setSources(_input.sourceCode);
27+
m_stack.setLibraries(_input.libraryAddresses);
28+
29+
if (_input.evmVersion.has_value())
30+
m_stack.setEVMVersion(_input.evmVersion.value());
31+
if (_input.optimise.has_value())
32+
m_stack.setOptimiserSettings(_input.optimise.value());
33+
if (_input.optimiserSettings.has_value())
34+
m_stack.setOptimiserSettings(_input.optimiserSettings.value());
35+
if (_input.revertStrings.has_value())
36+
m_stack.setRevertStringBehaviour(_input.revertStrings.value());
37+
if (_input.metadataFormat.has_value())
38+
m_stack.setMetadataFormat(_input.metadataFormat.value());
39+
if (_input.metadataHash.has_value())
40+
m_stack.setMetadataHash(_input.metadataHash.value());
41+
if (_input.viaIR.has_value())
42+
m_stack.setViaIR(_input.viaIR.value());
43+
m_stack.setEOFVersion(_input.eofVersion);
44+
}
45+
46+
std::pair<MappedContracts, Errors> InternalCompiler::internalCompile(
47+
CompilerInput const& _input
48+
)
49+
{
50+
m_stack.compile();
51+
52+
MappedContracts mappedContracts{};
53+
for (auto sourceName: m_stack.sourceNames())
54+
{
55+
std::vector<CompiledContract> compiled;
56+
for (auto const& contract: m_stack.contractDefinitions(sourceName))
57+
{
58+
std::string contractName = contract->fullyQualifiedName();
59+
LinkerObject object = m_stack.object(contractName);
60+
LinkerObject runtimeObject = m_stack.runtimeObject(contractName);
61+
bool hasUnlinkedReferences = !object.linkReferences.empty();
62+
bytes cborMetadata = m_stack.cborMetadata(contractName);
63+
64+
std::optional<AssemblyItems> assemblyItems;
65+
std::optional<AssemblyItems> runtimeAssemblyItems;
66+
67+
if (!_input.eofVersion.has_value())
68+
{
69+
if (auto items = m_stack.assemblyItems(contractName); items != nullptr)
70+
assemblyItems = std::make_optional(*items);
71+
72+
if (auto items = m_stack.runtimeAssemblyItems(contractName); items != nullptr)
73+
runtimeAssemblyItems = std::make_optional(*items);
74+
}
75+
76+
if (!m_stack.isExperimentalSolidity())
77+
compiled.emplace_back(CompiledContract{
78+
contractName,
79+
object.bytecode,
80+
runtimeObject.bytecode,
81+
hasUnlinkedReferences,
82+
cborMetadata,
83+
assemblyItems,
84+
runtimeAssemblyItems,
85+
m_stack.metadata(contractName),
86+
m_stack.contractABI(contractName),
87+
m_stack.interfaceSymbols(contractName),
88+
generateEventSignatures(contractName)
89+
});
90+
else
91+
compiled.emplace_back(CompiledContract{
92+
contractName,
93+
object.bytecode,
94+
runtimeObject.bytecode,
95+
hasUnlinkedReferences,
96+
cborMetadata,
97+
assemblyItems,
98+
runtimeAssemblyItems,
99+
std::nullopt,
100+
std::nullopt,
101+
std::nullopt,
102+
std::vector<EventSignature>{}
103+
});
104+
}
105+
mappedContracts.insert(std::make_pair(sourceName, compiled));
106+
}
107+
108+
return std::make_pair(mappedContracts, m_stack.errors());
109+
}
110+
111+
std::vector<EventSignature> InternalCompiler::generateEventSignatures(
112+
std::string const& _contractName
113+
) const
114+
{
115+
auto const& contract = m_stack.contractDefinition(_contractName);
116+
auto const& events = contract.events();
117+
auto const& interfaceEvents = contract.usedInterfaceEvents();
118+
119+
auto toSignature = [](EventDefinition const* _event)
120+
{
121+
soltestAssert(_event);
122+
return EventSignature::fromEvent(*_event);
123+
};
124+
125+
auto signatures =
126+
ranges::views::concat(events, interfaceEvents) |
127+
ranges::views::transform(toSignature) |
128+
ranges::to<std::vector>();
129+
130+
return signatures;
131+
}
132+
133+
std::string InternalCompiler::formatErrorInformation() const
134+
{
135+
std::string errorInformation;
136+
for (auto const& error: m_stack.errors())
137+
{
138+
auto formatted = SourceReferenceFormatter::formatErrorInformation(
139+
*error,
140+
m_stack,
141+
true,
142+
false
143+
);
144+
errorInformation.append(formatted);
145+
}
146+
147+
return errorInformation;
148+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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+
#pragma once
20+
21+
#include <liblangutil/SourceReferenceFormatter.h>
22+
23+
#include <test/libsolidity/util/compiler/Compiler.h>
24+
25+
#include <test/libsolidity/util/SoltestErrors.h>
26+
27+
using namespace solidity::langutil;
28+
29+
namespace solidity::frontend::test
30+
{
31+
32+
using MappedContracts = std::map<std::string, std::vector<CompiledContract>>;
33+
using Errors = ErrorList;
34+
35+
/**
36+
* Abstraction of the internal compiler aka. `CompilerStack`.
37+
*/
38+
class InternalCompiler
39+
{
40+
public:
41+
/// Configures and compiles using the internal compiler stack.
42+
/// @param _input the compiler input with sources, options etc. optionally
43+
/// set.
44+
/// @returns the aggregated compiler output.
45+
CompilerOutput compile(CompilerInput const& _input);
46+
47+
private:
48+
/// Configures the compiler stack. Needs to be called before compilation.
49+
/// @param _input is mapped to the compiler stacks' setters.
50+
void configure(CompilerInput const& _input);
51+
52+
/// Compile with current input.
53+
/// @returns compiled contracts per source unit and all errors.
54+
std::pair<MappedContracts, Errors> internalCompile(CompilerInput const& _input);
55+
56+
/// @returns annotated event signatures per contract.
57+
/// @param _contractName defines the contract to be used.
58+
std::vector<EventSignature> generateEventSignatures(
59+
std::string const& _contractName
60+
) const;
61+
62+
/// @returns a formatted output of all errors that occurred during
63+
/// compilation.
64+
std::string formatErrorInformation() const;
65+
66+
/// The compiler stack
67+
CompilerStack m_stack;
68+
};
69+
70+
}

test/tools/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ add_executable(isoltest
2525
../libsolidity/util/TestFunctionCall.cpp
2626
../libsolidity/util/compiler/Compiler.h
2727
../libsolidity/util/compiler/Compiler.cpp
28+
../libsolidity/util/compiler/InternalCompiler.h
29+
../libsolidity/util/compiler/InternalCompiler.cpp
2830
../libsolidity/GasTest.cpp
2931
../libsolidity/MemoryGuardTest.cpp
3032
../libsolidity/NatspecJSONTest.cpp

0 commit comments

Comments
 (0)