Merge pull request #6338 from ethereum/compilerstack-setsource

Introduce setSources in CompilerStack
This commit is contained in:
chriseth 2019-03-26 15:31:57 +01:00 committed by GitHub
commit 72c0e44907
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 190 additions and 126 deletions

View File

@ -169,6 +169,17 @@ bool CompilerStack::addSource(string const& _name, string const& _content)
return existed; return existed;
} }
void CompilerStack::setSources(StringMap const& _sources)
{
if (m_stackState == SourcesSet)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Cannot change sources once set."));
if (m_stackState != Empty)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must set sources before parsing."));
for (auto const& source: _sources)
m_sources[source.first].scanner = make_shared<Scanner>(CharStream(/*content*/source.second, /*name*/source.first));
m_stackState = SourcesSet;
}
bool CompilerStack::parse() bool CompilerStack::parse()
{ {
if (m_stackState != SourcesSet) if (m_stackState != SourcesSet)

View File

@ -152,6 +152,9 @@ public:
/// @returns true if a source object by the name already existed and was replaced. /// @returns true if a source object by the name already existed and was replaced.
bool addSource(std::string const& _name, std::string const& _content); bool addSource(std::string const& _name, std::string const& _content);
/// Sets the sources. Must be set before parsing.
void setSources(StringMap const& _sources);
/// Adds a response to an SMTLib2 query (identified by the hash of the query input). /// Adds a response to an SMTLib2 query (identified by the hash of the query input).
/// Must be set before parsing. /// Must be set before parsing.
void addSMTLib2Response(h256 const& _hash, std::string const& _response); void addSMTLib2Response(h256 const& _hash, std::string const& _response);

View File

@ -647,8 +647,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
CompilerStack compilerStack(m_readFile); CompilerStack compilerStack(m_readFile);
StringMap sourceList = std::move(_inputsAndSettings.sources); StringMap sourceList = std::move(_inputsAndSettings.sources);
for (auto const& source: sourceList) compilerStack.setSources(sourceList);
compilerStack.addSource(source.first, source.second);
for (auto const& smtLib2Response: _inputsAndSettings.smtLib2Responses) for (auto const& smtLib2Response: _inputsAndSettings.smtLib2Responses)
compilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second); compilerStack.addSMTLib2Response(smtLib2Response.first, smtLib2Response.second);
compilerStack.setEVMVersion(_inputsAndSettings.evmVersion); compilerStack.setEVMVersion(_inputsAndSettings.evmVersion);

View File

@ -901,8 +901,7 @@ bool CommandLineInterface::processInput()
m_compiler->useMetadataLiteralSources(true); m_compiler->useMetadataLiteralSources(true);
if (m_args.count(g_argInputFile)) if (m_args.count(g_argInputFile))
m_compiler->setRemappings(m_remappings); m_compiler->setRemappings(m_remappings);
for (auto const& sourceCode: m_sourceCodes) m_compiler->setSources(m_sourceCodes);
m_compiler->addSource(sourceCode.first, sourceCode.second);
if (m_args.count(g_argLibraries)) if (m_args.count(g_argLibraries))
m_compiler->setLibraries(m_libraries); m_compiler->setLibraries(m_libraries);
m_compiler->setEVMVersion(m_evmVersion); m_compiler->setEVMVersion(m_evmVersion);

View File

@ -92,13 +92,14 @@ bool ASTJSONTest::run(ostream& _stream, string const& _linePrefix, bool const _f
{ {
CompilerStack c; CompilerStack c;
StringMap sources;
map<string, unsigned> sourceIndices; map<string, unsigned> sourceIndices;
for (size_t i = 0; i < m_sources.size(); i++) for (size_t i = 0; i < m_sources.size(); i++)
{ {
c.addSource(m_sources[i].first, m_sources[i].second); sources[m_sources[i].first] = m_sources[i].second;
sourceIndices[m_sources[i].first] = i + 1; sourceIndices[m_sources[i].first] = i + 1;
} }
c.setSources(sources);
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
c.parseAndAnalyze(); c.parseAndAnalyze();

View File

@ -48,7 +48,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
) )
{ {
m_compiler.reset(); m_compiler.reset();
m_compiler.addSource("", _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source); m_compiler.setSources({{"", _insertVersionPragma ? "pragma solidity >=0.0;\n" + _source : _source}});
m_compiler.setEVMVersion(dev::test::Options::get().evmVersion()); m_compiler.setEVMVersion(dev::test::Options::get().evmVersion());
if (!m_compiler.parse()) if (!m_compiler.parse())
{ {

View File

@ -46,8 +46,8 @@ class GasMeterTestFramework: public SolidityExecutionFramework
public: public:
void compile(string const& _sourceCode) void compile(string const& _sourceCode)
{ {
m_compiler.reset(false); m_compiler.reset();
m_compiler.addSource("", "pragma solidity >=0.0;\n" + _sourceCode); m_compiler.setSources({{"", "pragma solidity >=0.0;\n" + _sourceCode}});
m_compiler.setOptimiserSettings(dev::test::Options::get().optimize); m_compiler.setOptimiserSettings(dev::test::Options::get().optimize);
m_compiler.setEVMVersion(m_evmVersion); m_compiler.setEVMVersion(m_evmVersion);
BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed"); BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");

View File

@ -44,7 +44,7 @@ BOOST_AUTO_TEST_SUITE(SolidityImports)
BOOST_AUTO_TEST_CASE(smoke_test) BOOST_AUTO_TEST_CASE(smoke_test)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract C {} pragma solidity >=0.0;"); c.setSources({{"a", "contract C {} pragma solidity >=0.0;"}});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -52,8 +52,10 @@ BOOST_AUTO_TEST_CASE(smoke_test)
BOOST_AUTO_TEST_CASE(regular_import) BOOST_AUTO_TEST_CASE(regular_import)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract C {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;"); {"a", "contract C {} pragma solidity >=0.0;"},
{"b", "import \"a\"; contract D is C {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -61,8 +63,10 @@ BOOST_AUTO_TEST_CASE(regular_import)
BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee) BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract C { D d; } pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\"; contract D is C {} pragma solidity >=0.0;"); {"a", "contract C { D d; } pragma solidity >=0.0;"},
{"b", "import \"a\"; contract D is C {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -70,9 +74,11 @@ BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee)
BOOST_AUTO_TEST_CASE(import_is_transitive) BOOST_AUTO_TEST_CASE(import_is_transitive)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract C { } pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\"; pragma solidity >=0.0;"); {"a", "contract C { } pragma solidity >=0.0;"},
c.addSource("c", "import \"b\"; contract D is C {} pragma solidity >=0.0;"); {"b", "import \"a\"; pragma solidity >=0.0;"},
{"c", "import \"b\"; contract D is C {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -80,8 +86,10 @@ BOOST_AUTO_TEST_CASE(import_is_transitive)
BOOST_AUTO_TEST_CASE(circular_import) BOOST_AUTO_TEST_CASE(circular_import)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "import \"b\"; contract C { D d; } pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\"; contract D { C c; } pragma solidity >=0.0;"); {"a", "import \"b\"; contract C { D d; } pragma solidity >=0.0;"},
{"b", "import \"a\"; contract D { C c; } pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -89,9 +97,11 @@ BOOST_AUTO_TEST_CASE(circular_import)
BOOST_AUTO_TEST_CASE(relative_import) BOOST_AUTO_TEST_CASE(relative_import)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "import \"./dir/b\"; contract A is B {} pragma solidity >=0.0;"); c.setSources({
c.addSource("dir/b", "contract B {} pragma solidity >=0.0;"); {"a", "import \"./dir/b\"; contract A is B {} pragma solidity >=0.0;"},
c.addSource("dir/c", "import \"../a\"; contract C is A {} pragma solidity >=0.0;"); {"dir/b", "contract B {} pragma solidity >=0.0;"},
{"dir/c", "import \"../a\"; contract C is A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -99,8 +109,10 @@ BOOST_AUTO_TEST_CASE(relative_import)
BOOST_AUTO_TEST_CASE(relative_import_multiplex) BOOST_AUTO_TEST_CASE(relative_import_multiplex)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("dir/a/b/c", "import \"../../.././a\"; contract B is A {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"dir/a/b/c", "import \"../../.././a\"; contract B is A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -108,8 +120,10 @@ BOOST_AUTO_TEST_CASE(relative_import_multiplex)
BOOST_AUTO_TEST_CASE(simple_alias) BOOST_AUTO_TEST_CASE(simple_alias)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() external { x.A r = x.A(20); } } pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"dir/a/b/c", "import \"../../.././a\" as x; contract B is x.A { function() external { x.A r = x.A(20); } } pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -117,9 +131,11 @@ BOOST_AUTO_TEST_CASE(simple_alias)
BOOST_AUTO_TEST_CASE(library_name_clash) BOOST_AUTO_TEST_CASE(library_name_clash)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "library A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "library A {} pragma solidity >=0.0;"); {"a", "library A {} pragma solidity >=0.0;"},
c.addSource("c", "import {A} from \"./a\"; import {A} from \"./b\";"); {"b", "library A {} pragma solidity >=0.0;"},
{"c", "import {A} from \"./a\"; import {A} from \"./b\";"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -127,8 +143,10 @@ BOOST_AUTO_TEST_CASE(library_name_clash)
BOOST_AUTO_TEST_CASE(library_name_clash_with_contract) BOOST_AUTO_TEST_CASE(library_name_clash_with_contract)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "library A {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "library A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -136,9 +154,11 @@ BOOST_AUTO_TEST_CASE(library_name_clash_with_contract)
BOOST_AUTO_TEST_CASE(complex_import) BOOST_AUTO_TEST_CASE(complex_import)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; " {"a", "contract A {} contract B {} contract C { struct S { uint a; } } pragma solidity >=0.0;"},
"contract D is b { function f(c.S memory var1, x.C.S memory var2, C.S memory var3) internal {} } pragma solidity >=0.0;"); {"b", "import \"a\" as x; import {B as b, C as c, C} from \"a\"; "
"contract D is b { function f(c.S memory var1, x.C.S memory var2, C.S memory var3) internal {} } pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -146,8 +166,10 @@ BOOST_AUTO_TEST_CASE(complex_import)
BOOST_AUTO_TEST_CASE(name_clash_in_import_1) BOOST_AUTO_TEST_CASE(name_clash_in_import_1)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\"; contract A {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "import \"a\"; contract A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -155,8 +177,10 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import_1)
BOOST_AUTO_TEST_CASE(name_clash_in_import_2) BOOST_AUTO_TEST_CASE(name_clash_in_import_2)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"a\" as A; contract A {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "import \"a\" as A; contract A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -164,8 +188,10 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import_2)
BOOST_AUTO_TEST_CASE(name_clash_in_import_3) BOOST_AUTO_TEST_CASE(name_clash_in_import_3)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import {A as b} from \"a\"; contract b {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "import {A as b} from \"a\"; contract b {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -173,8 +199,10 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import_3)
BOOST_AUTO_TEST_CASE(name_clash_in_import_4) BOOST_AUTO_TEST_CASE(name_clash_in_import_4)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import {A} from \"a\"; contract A {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "import {A} from \"a\"; contract A {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -182,8 +210,10 @@ BOOST_AUTO_TEST_CASE(name_clash_in_import_4)
BOOST_AUTO_TEST_CASE(name_clash_in_import_5) BOOST_AUTO_TEST_CASE(name_clash_in_import_5)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "contract A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import {A} from \"a\"; contract B {} pragma solidity >=0.0;"); {"a", "contract A {} pragma solidity >=0.0;"},
{"b", "import {A} from \"a\"; contract B {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -192,10 +222,12 @@ BOOST_AUTO_TEST_CASE(remappings)
{ {
CompilerStack c; CompilerStack c;
c.setRemappings(vector<CompilerStack::Remapping>{{"", "s", "s_1.4.6"},{"", "t", "Tee"}}); c.setRemappings(vector<CompilerStack::Remapping>{{"", "s", "s_1.4.6"},{"", "t", "Tee"}});
c.addSource("a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;"); {"a", "import \"s/s.sol\"; contract A is S {} pragma solidity >=0.0;"},
c.addSource("s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;"); {"b", "import \"t/tee.sol\"; contract A is Tee {} pragma solidity >=0.0;"},
c.addSource("Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;"); {"s_1.4.6/s.sol", "contract S {} pragma solidity >=0.0;"},
{"Tee/tee.sol", "contract Tee {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -204,10 +236,12 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings)
{ {
CompilerStack c; CompilerStack c;
c.setRemappings(vector<CompilerStack::Remapping>{{"a", "s", "s_1.4.6"}, {"b", "s", "s_1.4.7"}}); c.setRemappings(vector<CompilerStack::Remapping>{{"a", "s", "s_1.4.6"}, {"b", "s", "s_1.4.7"}});
c.addSource("a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;"); {"a/a.sol", "import \"s/s.sol\"; contract A is SSix {} pragma solidity >=0.0;"},
c.addSource("s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;"); {"b/b.sol", "import \"s/s.sol\"; contract B is SSeven {} pragma solidity >=0.0;"},
c.addSource("s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;"); {"s_1.4.6/s.sol", "contract SSix {} pragma solidity >=0.0;"},
{"s_1.4.7/s.sol", "contract SSeven {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -215,8 +249,10 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings)
BOOST_AUTO_TEST_CASE(filename_with_period) BOOST_AUTO_TEST_CASE(filename_with_period)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a/a.sol", "import \".b.sol\"; contract A is B {} pragma solidity >=0.0;"); c.setSources({
c.addSource("a/.b.sol", "contract B {} pragma solidity >=0.0;"); {"a/a.sol", "import \".b.sol\"; contract A is B {} pragma solidity >=0.0;"},
{"a/.b.sol", "contract B {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -229,10 +265,12 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_pres
{"vendor/bar", "foo", "vendor/foo_1.0.0"}, {"vendor/bar", "foo", "vendor/foo_1.0.0"},
{"", "bar", "vendor/bar"} {"", "bar", "vendor/bar"}
}); });
c.addSource("main.sol", "import \"foo/foo.sol\"; import {Bar} from \"bar/bar.sol\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;"); c.setSources({
c.addSource("vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;"); {"main.sol", "import \"foo/foo.sol\"; import {Bar} from \"bar/bar.sol\"; contract Main is Foo2, Bar {} pragma solidity >=0.0;"},
c.addSource("vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;"); {"vendor/bar/bar.sol", "import \"foo/foo.sol\"; contract Bar {Foo1 foo;} pragma solidity >=0.0;"},
c.addSource("vendor/foo_2.0.0/foo.sol", "contract Foo2 {} pragma solidity >=0.0;"); {"vendor/foo_1.0.0/foo.sol", "contract Foo1 {} pragma solidity >=0.0;"},
{"vendor/foo_2.0.0/foo.sol", "contract Foo2 {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -241,10 +279,12 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_1)
{ {
CompilerStack c; CompilerStack c;
c.setRemappings(vector<CompilerStack::Remapping>{{"a", "x/y/z", "d"}, {"a/b", "x", "e"}}); c.setRemappings(vector<CompilerStack::Remapping>{{"a", "x/y/z", "d"}, {"a/b", "x", "e"}});
c.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"); c.setSources({
c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"); {"a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"},
c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;"); {"a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"},
c.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"); {"d/z.sol", "contract D {} pragma solidity >=0.0;"},
{"e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -253,10 +293,12 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_2)
{ {
CompilerStack c; CompilerStack c;
c.setRemappings(vector<CompilerStack::Remapping>{{"a/b", "x", "e"}, {"a", "x/y/z", "d"}}); c.setRemappings(vector<CompilerStack::Remapping>{{"a/b", "x", "e"}, {"a", "x/y/z", "d"}});
c.addSource("a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"); c.setSources({
c.addSource("a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"); {"a/main.sol", "import \"x/y/z/z.sol\"; contract Main is D {} pragma solidity >=0.0;"},
c.addSource("d/z.sol", "contract D {} pragma solidity >=0.0;"); {"a/b/main.sol", "import \"x/y/z/z.sol\"; contract Main is E {} pragma solidity >=0.0;"},
c.addSource("e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"); {"d/z.sol", "contract D {} pragma solidity >=0.0;"},
{"e/y/z/z.sol", "contract E {} pragma solidity >=0.0;"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
} }
@ -264,9 +306,11 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_2)
BOOST_AUTO_TEST_CASE(shadowing_via_import) BOOST_AUTO_TEST_CASE(shadowing_via_import)
{ {
CompilerStack c; CompilerStack c;
c.addSource("a", "library A {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", "library A {} pragma solidity >=0.0;"); {"a", "library A {} pragma solidity >=0.0;"},
c.addSource("c", "import {A} from \"./a\"; import {A} from \"./b\";"); {"b", "library A {} pragma solidity >=0.0;"},
{"c", "import {A} from \"./a\"; import {A} from \"./b\";"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
} }
@ -274,13 +318,14 @@ BOOST_AUTO_TEST_CASE(shadowing_via_import)
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports) BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports)
{ {
CompilerStack c; CompilerStack c;
c.addSource("B.sol", "contract X {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", R"( {"B.sol", "contract X {} pragma solidity >=0.0;"},
{"b", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import * as msg from "B.sol"; import * as msg from "B.sol";
contract C { contract C {
} })"}
)"); });
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
size_t errorCount = 0; size_t errorCount = 0;
@ -301,13 +346,14 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports)
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports) BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports)
{ {
CompilerStack c; CompilerStack c;
c.addSource("B.sol", "contract msg {} contract block{} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", R"( {"B.sol", "contract msg {} contract block{} pragma solidity >=0.0;"},
{"b", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import {msg, block} from "B.sol"; import {msg, block} from "B.sol";
contract C { contract C {
} })"}
)"); });
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
auto numErrors = c.errors().size(); auto numErrors = c.errors().size();
@ -327,11 +373,12 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports)
BOOST_AUTO_TEST_CASE(shadowing_builtins_with_alias) BOOST_AUTO_TEST_CASE(shadowing_builtins_with_alias)
{ {
CompilerStack c; CompilerStack c;
c.addSource("B.sol", "contract C {} pragma solidity >=0.0;"); c.setSources({
c.addSource("b", R"( {"B.sol", "contract C {} pragma solidity >=0.0;"},
{"b", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import {C as msg} from "B.sol"; import {C as msg} from "B.sol";)"}
)"); });
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());
auto numErrors = c.errors().size(); auto numErrors = c.errors().size();
@ -351,7 +398,8 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_alias)
BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_1) BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_1)
{ {
CompilerStack c; CompilerStack c;
c.addSource("A.sol", R"( c.setSources({
{"A.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
@ -361,22 +409,21 @@ BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_1)
S public s; S public s;
function f(S memory _s) returns (S memory,S memory) { } function f(S memory _s) returns (S memory,S memory) { }
} }
)"); )"},
{"B.sol", R"(
c.addSource("B.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "./A.sol"; import "./A.sol";
contract B is A { } contract B is A { }
)"); )"},
{"C.sol", R"(
c.addSource("C.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import "./B.sol"; import "./B.sol";
contract C is B { } contract C is B { }
)"); )"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
@ -401,7 +448,8 @@ BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_1)
BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_2) BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_2)
{ {
CompilerStack c; CompilerStack c;
c.addSource("A.sol", R"( c.setSources({
{"A.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
@ -411,21 +459,20 @@ BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_2)
S public s; S public s;
function f(S memory _s) returns (S memory,S memory) { } function f(S memory _s) returns (S memory,S memory) { }
} }
)"); )"},
{"B.sol", R"(
c.addSource("B.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import "./A.sol"; import "./A.sol";
contract B is A { } contract B is A { }
)"); )"},
{"C.sol", R"(
c.addSource("C.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import "./B.sol"; import "./B.sol";
contract C is B { } contract C is B { }
)"); )"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!c.compile()); BOOST_CHECK(!c.compile());
@ -450,7 +497,8 @@ BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_2)
BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_match) BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_match)
{ {
CompilerStack c; CompilerStack c;
c.addSource("A.sol", R"( c.setSources({
{"A.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
@ -460,23 +508,22 @@ BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_match)
S public s; S public s;
function f(S memory _s) public returns (S memory,S memory) { } function f(S memory _s) public returns (S memory,S memory) { }
} }
)"); )"},
{"B.sol", R"(
c.addSource("B.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "./A.sol"; import "./A.sol";
contract B is A { } contract B is A { }
)"); )"},
{"C.sol", R"(
c.addSource("C.sol", R"(
pragma solidity >=0.0; pragma solidity >=0.0;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "./B.sol"; import "./B.sol";
contract C is B { } contract C is B { }
)"); )"}
});
c.setEVMVersion(dev::test::Options::get().evmVersion()); c.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(c.compile()); BOOST_CHECK(c.compile());

View File

@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp)
} }
)"; )";
CompilerStack compilerStack; CompilerStack compilerStack;
compilerStack.addSource("", std::string(sourceCode)); compilerStack.setSources({{"", std::string(sourceCode)}});
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
} }
)"; )";
CompilerStack compilerStack; CompilerStack compilerStack;
compilerStack.addSource("", std::string(sourceCode)); compilerStack.setSources({{"", std::string(sourceCode)}});
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
@ -105,20 +105,22 @@ BOOST_AUTO_TEST_CASE(metadata_stamp_experimental)
BOOST_AUTO_TEST_CASE(metadata_relevant_sources) BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
{ {
CompilerStack compilerStack; CompilerStack compilerStack;
char const* sourceCode = R"( char const* sourceCodeA = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
contract A { contract A {
function g(function(uint) external returns (uint) x) public {} function g(function(uint) external returns (uint) x) public {}
} }
)"; )";
compilerStack.addSource("A", std::string(sourceCode)); char const* sourceCodeB = R"(
sourceCode = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
contract B { contract B {
function g(function(uint) external returns (uint) x) public {} function g(function(uint) external returns (uint) x) public {}
} }
)"; )";
compilerStack.addSource("B", std::string(sourceCode)); compilerStack.setSources({
{"A", std::string(sourceCodeA)},
{"B", std::string(sourceCodeB)},
});
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
@ -135,29 +137,31 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports) BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
{ {
CompilerStack compilerStack; CompilerStack compilerStack;
char const* sourceCode = R"( char const* sourceCodeA = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
contract A { contract A {
function g(function(uint) external returns (uint) x) public {} function g(function(uint) external returns (uint) x) public {}
} }
)"; )";
compilerStack.addSource("A", std::string(sourceCode)); char const* sourceCodeB = R"(
sourceCode = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import "./A"; import "./A";
contract B is A { contract B is A {
function g(function(uint) external returns (uint) x) public {} function g(function(uint) external returns (uint) x) public {}
} }
)"; )";
compilerStack.addSource("B", std::string(sourceCode)); char const* sourceCodeC = R"(
sourceCode = R"(
pragma solidity >=0.0; pragma solidity >=0.0;
import "./B"; import "./B";
contract C is B { contract C is B {
function g(function(uint) external returns (uint) x) public {} function g(function(uint) external returns (uint) x) public {}
} }
)"; )";
compilerStack.addSource("C", std::string(sourceCode)); compilerStack.setSources({
{"A", std::string(sourceCodeA)},
{"B", std::string(sourceCodeB)},
{"C", std::string(sourceCodeC)}
});
compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed"); BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");

View File

@ -40,8 +40,8 @@ class JSONInterfaceChecker
public: public:
void checkInterface(std::string const& _code, std::string const& _contractName, std::string const& _expectedInterfaceString) void checkInterface(std::string const& _code, std::string const& _contractName, std::string const& _expectedInterfaceString)
{ {
m_compilerStack.reset(false); m_compilerStack.reset();
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code); m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}});
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
m_compilerStack.setOptimiserSettings(dev::test::Options::get().optimize); m_compilerStack.setOptimiserSettings(dev::test::Options::get().optimize);
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed"); BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");

View File

@ -69,8 +69,8 @@ public:
if (dev::test::Options::get().useABIEncoderV2 && _sourceCode.find("pragma experimental ABIEncoderV2;") == std::string::npos) if (dev::test::Options::get().useABIEncoderV2 && _sourceCode.find("pragma experimental ABIEncoderV2;") == std::string::npos)
sourceCode += "pragma experimental ABIEncoderV2;\n"; sourceCode += "pragma experimental ABIEncoderV2;\n";
sourceCode += _sourceCode; sourceCode += _sourceCode;
m_compiler.reset(false); m_compiler.reset();
m_compiler.addSource("", sourceCode); m_compiler.setSources({{"", sourceCode}});
m_compiler.setLibraries(_libraryAddresses); m_compiler.setLibraries(_libraryAddresses);
m_compiler.setEVMVersion(m_evmVersion); m_compiler.setEVMVersion(m_evmVersion);
m_compiler.setOptimiserSettings(m_optimiserSettings); m_compiler.setOptimiserSettings(m_optimiserSettings);

View File

@ -46,8 +46,8 @@ public:
bool _userDocumentation bool _userDocumentation
) )
{ {
m_compilerStack.reset(false); m_compilerStack.reset();
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code); m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}});
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed"); BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
@ -67,8 +67,8 @@ public:
void expectNatspecError(std::string const& _code) void expectNatspecError(std::string const& _code)
{ {
m_compilerStack.reset(false); m_compilerStack.reset();
m_compilerStack.addSource("", "pragma solidity >=0.0;\n" + _code); m_compilerStack.setSources({{"", "pragma solidity >=0.0;\n" + _code}});
m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion()); m_compilerStack.setEVMVersion(dev::test::Options::get().evmVersion());
BOOST_CHECK(!m_compilerStack.parseAndAnalyze()); BOOST_CHECK(!m_compilerStack.parseAndAnalyze());
BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError)); BOOST_REQUIRE(Error::containsErrorOfType(m_compilerStack.errors(), Error::Type::DocstringParsingError));

View File

@ -67,7 +67,7 @@ bool SyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatte
{ {
string const versionPragma = "pragma solidity >=0.0;\n"; string const versionPragma = "pragma solidity >=0.0;\n";
m_compiler.reset(); m_compiler.reset();
m_compiler.addSource("", versionPragma + m_source); m_compiler.setSources({{"", versionPragma + m_source}});
m_compiler.setEVMVersion(m_evmVersion); m_compiler.setEVMVersion(m_evmVersion);
if (m_compiler.parse()) if (m_compiler.parse())