From 6ed219ebe810ed64c81963e137e83f7d6a4a8f7c Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 16 Aug 2019 14:50:31 +0200 Subject: [PATCH 1/2] Support multiple sources for syntax tests. --- test/TestCase.cpp | 43 ++++++- test/TestCase.h | 2 + test/libsolidity/SMTCheckerJSONTest.cpp | 21 +++- test/libsolidity/SyntaxTest.cpp | 115 ++++++++++++------ test/libsolidity/SyntaxTest.h | 4 +- .../libsolidity/smtCheckerTestsJSON/multi.sol | 1 + .../smtCheckerTestsJSON/simple.sol | 1 + .../multiSource/error_in_first.sol | 10 ++ .../syntaxTests/multiSource/import.sol | 12 ++ .../multiSource/import_not_found.sol | 5 + .../syntaxTests/multiSource/no_import.sol | 10 ++ .../syntaxTests/multiSource/one_source.sol | 7 ++ .../multiSource/warning_in_both.sol | 11 ++ 13 files changed, 191 insertions(+), 51 deletions(-) create mode 100644 test/libsolidity/syntaxTests/multiSource/error_in_first.sol create mode 100644 test/libsolidity/syntaxTests/multiSource/import.sol create mode 100644 test/libsolidity/syntaxTests/multiSource/import_not_found.sol create mode 100644 test/libsolidity/syntaxTests/multiSource/no_import.sol create mode 100644 test/libsolidity/syntaxTests/multiSource/one_source.sol create mode 100644 test/libsolidity/syntaxTests/multiSource/warning_in_both.sol diff --git a/test/TestCase.cpp b/test/TestCase.cpp index e3671e4db..88d7f7862 100644 --- a/test/TestCase.cpp +++ b/test/TestCase.cpp @@ -62,11 +62,15 @@ bool TestCase::validateSettings(langutil::EVMVersion) return true; } -pair TestCase::parseSourceAndSettingsWithLineNumbers(istream& _stream) +pair, size_t> TestCase::parseSourcesAndSettingsWithLineNumbers(istream& _stream) { - string source; + map sources; + string currentSourceName; + string currentSource; string line; size_t lineNumber = 1; + static string const sourceDelimiterStart("==== Source:"); + static string const sourceDelimiterEnd("===="); static string const comment("// "); static string const settingsDelimiter("// ===="); static string const delimiter("// ----"); @@ -80,7 +84,22 @@ pair TestCase::parseSourceAndSettingsWithLineNumbers(istream& _s else if (boost::algorithm::starts_with(line, settingsDelimiter)) sourcePart = false; else if (sourcePart) - source += line + "\n"; + { + if (boost::algorithm::starts_with(line, sourceDelimiterStart) && boost::algorithm::ends_with(line, sourceDelimiterEnd)) + { + if (!(currentSourceName.empty() && currentSource.empty())) + sources[currentSourceName] = std::move(currentSource); + currentSource = {}; + currentSourceName = boost::trim_copy(line.substr( + sourceDelimiterStart.size(), + line.size() - sourceDelimiterEnd.size() - sourceDelimiterStart.size() + )); + if (sources.count(currentSourceName)) + throw runtime_error("Multiple definitions of test source \"" + currentSourceName + "\"."); + } + else + currentSource += line + "\n"; + } else if (boost::algorithm::starts_with(line, comment)) { size_t colon = line.find(':'); @@ -95,12 +114,26 @@ pair TestCase::parseSourceAndSettingsWithLineNumbers(istream& _s else throw runtime_error(string("Expected \"//\" or \"// ---\" to terminate settings and source.")); } - return make_pair(source, lineNumber); + sources[currentSourceName] = currentSource; + return {sources, lineNumber}; +} + +map TestCase::parseSourcesAndSettings(istream& _stream) +{ + return get<0>(parseSourcesAndSettingsWithLineNumbers(_stream)); +} + +pair TestCase::parseSourceAndSettingsWithLineNumbers(istream& _stream) +{ + auto [sourceMap, lineOffset] = parseSourcesAndSettingsWithLineNumbers(_stream); + if (sourceMap.size() != 1) + BOOST_THROW_EXCEPTION(runtime_error("Expected single source definition, but got multiple sources.")); + return {std::move(sourceMap.begin()->second), lineOffset}; } string TestCase::parseSourceAndSettings(istream& _stream) { - return get<0>(parseSourceAndSettingsWithLineNumbers(_stream)); + return parseSourceAndSettingsWithLineNumbers(_stream).first; } string TestCase::parseSimpleExpectations(std::istream& _file) diff --git a/test/TestCase.h b/test/TestCase.h index a121f50f2..0c149c22c 100644 --- a/test/TestCase.h +++ b/test/TestCase.h @@ -80,6 +80,8 @@ public: virtual bool validateSettings(langutil::EVMVersion /*_evmVersion*/); protected: + std::pair, std::size_t> parseSourcesAndSettingsWithLineNumbers(std::istream& _file); + std::map parseSourcesAndSettings(std::istream& _file); std::pair parseSourceAndSettingsWithLineNumbers(std::istream& _file); std::string parseSourceAndSettings(std::istream& _file); static void expect(std::string::iterator& _it, std::string::iterator _end, std::string::value_type _c); diff --git a/test/libsolidity/SMTCheckerJSONTest.cpp b/test/libsolidity/SMTCheckerJSONTest.cpp index ae49ea279..a2ce4e26b 100644 --- a/test/libsolidity/SMTCheckerJSONTest.cpp +++ b/test/libsolidity/SMTCheckerJSONTest.cpp @@ -108,6 +108,9 @@ TestCase::TestResult SMTCheckerTest::run(ostream& _stream, string const& _linePr BOOST_THROW_EXCEPTION(runtime_error("Error must have a SourceLocation with start and end.")); int start = location["start"].asInt(); int end = location["end"].asInt(); + std::string sourceName; + if (location.isMember("source") && location["source"].isString()) + sourceName = location["source"].asString(); if (start >= static_cast(versionPragma.size())) start -= versionPragma.size(); if (end >= static_cast(versionPragma.size())) @@ -115,6 +118,7 @@ TestCase::TestResult SMTCheckerTest::run(ostream& _stream, string const& _linePr m_errorList.emplace_back(SyntaxTestError{ error["type"].asString(), error["message"].asString(), + sourceName, start, end }); @@ -141,13 +145,20 @@ vector SMTCheckerTest::hashesFromJson(Json::Value const& _jsonObj, strin Json::Value SMTCheckerTest::buildJson(string const& _extra) { string language = "\"language\": \"Solidity\""; - string sourceName = "\"A\""; - string sourceContent = "\"" + _extra + m_source + "\""; - string sourceObj = "{ \"content\": " + sourceContent + "}"; - string sources = " \"sources\": { " + sourceName + ": " + sourceObj + "}"; + string sources = " \"sources\": { "; + bool first = true; + for (auto [sourceName, sourceContent]: m_sources) + { + string sourceObj = "{ \"content\": \"" + _extra + sourceContent + "\"}"; + if (!first) + sources += ", "; + sources += "\"" + sourceName + "\": " + sourceObj; + first = false; + } + sources += "}"; string input = "{" + language + ", " + sources + "}"; Json::Value source; if (!jsonParse(input, source)) - BOOST_THROW_EXCEPTION(runtime_error("Could not build JSON from string.")); + BOOST_THROW_EXCEPTION(runtime_error("Could not build JSON from string: " + input)); return source; } diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index d177d29e8..41a4dd18b 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -59,7 +59,8 @@ SyntaxTest::SyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\".")); file.exceptions(ios::badbit); - m_source = parseSourceAndSettings(file); + m_sources = parseSourcesAndSettings(file); + if (m_settings.count("optimize-yul")) { m_optimiseYul = true; @@ -74,7 +75,10 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix { string const versionPragma = "pragma solidity >=0.0;\n"; compiler().reset(); - compiler().setSources({{"", versionPragma + m_source}}); + auto sourcesWithPragma = m_sources; + for (auto& source: sourcesWithPragma) + source.second = versionPragma + source.second; + compiler().setSources(sourcesWithPragma); compiler().setEVMVersion(m_evmVersion); compiler().setParserErrorRecovery(m_parserErrorRecovery); compiler().setOptimiserSettings( @@ -94,6 +98,7 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix m_errorList.emplace_back(SyntaxTestError{ "UnimplementedFeatureError", errorMessage(_e), + "", -1, -1 }); @@ -102,6 +107,7 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix for (auto const& currentError: filterErrors(compiler().errors(), true)) { int locationStart = -1, locationEnd = -1; + string sourceName; if (auto location = boost::get_error_info(*currentError)) { // ignore the version pragma inserted by the testing tool when calculating locations. @@ -109,10 +115,13 @@ TestCase::TestResult SyntaxTest::run(ostream& _stream, string const& _linePrefix locationStart = location->start - versionPragma.size(); if (location->end >= static_cast(versionPragma.size())) locationEnd = location->end - versionPragma.size(); + if (location->source) + sourceName = location->source->name(); } m_errorList.emplace_back(SyntaxTestError{ currentError->typeName(), errorMessage(*currentError), + sourceName, locationStart, locationEnd }); @@ -137,51 +146,65 @@ bool SyntaxTest::printExpectationAndError(ostream& _stream, string const& _lineP void SyntaxTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const { + + if (m_sources.empty()) + return; + + bool outputSourceNames = true; + if (m_sources.size() == 1 && m_sources.begin()->first.empty()) + outputSourceNames = false; + if (_formatted) { - if (m_source.empty()) - return; - - vector sourceFormatting(m_source.length(), formatting::RESET); - for (auto const& error: m_errorList) - if (error.locationStart >= 0 && error.locationEnd >= 0) - { - assert(static_cast(error.locationStart) <= m_source.length()); - assert(static_cast(error.locationEnd) <= m_source.length()); - bool isWarning = error.type == "Warning"; - for (int i = error.locationStart; i < error.locationEnd; i++) - if (isWarning) - { - if (sourceFormatting[i] == formatting::RESET) - sourceFormatting[i] = formatting::ORANGE_BACKGROUND_256; - } - else - sourceFormatting[i] = formatting::RED_BACKGROUND; - } - - _stream << _linePrefix << sourceFormatting.front() << m_source.front(); - for (size_t i = 1; i < m_source.length(); i++) + for (auto const& [name, source]: m_sources) { - if (sourceFormatting[i] != sourceFormatting[i - 1]) - _stream << sourceFormatting[i]; - if (m_source[i] != '\n') - _stream << m_source[i]; - else + if (outputSourceNames) + _stream << _linePrefix << formatting::CYAN << "==== Source: " << name << " ====" << formatting::RESET << endl; + vector sourceFormatting(source.length(), formatting::RESET); + for (auto const& error: m_errorList) + if (error.sourceName == name && error.locationStart >= 0 && error.locationEnd >= 0) + { + assert(static_cast(error.locationStart) <= source.length()); + assert(static_cast(error.locationEnd) <= source.length()); + bool isWarning = error.type == "Warning"; + for (int i = error.locationStart; i < error.locationEnd; i++) + if (isWarning) + { + if (sourceFormatting[i] == formatting::RESET) + sourceFormatting[i] = formatting::ORANGE_BACKGROUND_256; + } + else + sourceFormatting[i] = formatting::RED_BACKGROUND; + } + + _stream << _linePrefix << sourceFormatting.front() << source.front(); + for (size_t i = 1; i < source.length(); i++) { - _stream << formatting::RESET << endl; - if (i + 1 < m_source.length()) - _stream << _linePrefix << sourceFormatting[i]; + if (sourceFormatting[i] != sourceFormatting[i - 1]) + _stream << sourceFormatting[i]; + if (source[i] != '\n') + _stream << source[i]; + else + { + _stream << formatting::RESET << endl; + if (i + 1 < source.length()) + _stream << _linePrefix << sourceFormatting[i]; + } } + _stream << formatting::RESET; } - _stream << formatting::RESET; + } else - { - stringstream stream(m_source); - string line; - while (getline(stream, line)) - _stream << _linePrefix << line << endl; - } + for (auto const& [name, source]: m_sources) + { + if (outputSourceNames) + _stream << _linePrefix << "==== Source: " + name << " ====" << endl; + stringstream stream(source); + string line; + while (getline(stream, line)) + _stream << _linePrefix << line << endl; + } } void SyntaxTest::printErrorList( @@ -201,9 +224,11 @@ void SyntaxTest::printErrorList( _stream << _linePrefix; _stream << error.type << ": "; } - if (error.locationStart >= 0 || error.locationEnd >= 0) + if (!error.sourceName.empty() || error.locationStart >= 0 || error.locationEnd >= 0) { _stream << "("; + if (!error.sourceName.empty()) + _stream << error.sourceName << ":"; if (error.locationStart >= 0) _stream << error.locationStart; _stream << "-"; @@ -248,10 +273,19 @@ vector SyntaxTest::parseExpectations(istream& _stream) int locationStart = -1; int locationEnd = -1; + std::string sourceName; if (it != line.end() && *it == '(') { ++it; + if (it != line.end() && !isdigit(*it)) + { + auto sourceNameStart = it; + while (it != line.end() && *it != ':') + ++it; + sourceName = std::string(sourceNameStart, it); + expect(it, line.end(), ':'); + } locationStart = parseUnsignedInteger(it, line.end()); expect(it, line.end(), '-'); locationEnd = parseUnsignedInteger(it, line.end()); @@ -265,6 +299,7 @@ vector SyntaxTest::parseExpectations(istream& _stream) expectations.emplace_back(SyntaxTestError{ move(errorType), move(errorMessage), + move(sourceName), locationStart, locationEnd }); diff --git a/test/libsolidity/SyntaxTest.h b/test/libsolidity/SyntaxTest.h index 62a85d864..53c06d3fe 100644 --- a/test/libsolidity/SyntaxTest.h +++ b/test/libsolidity/SyntaxTest.h @@ -38,12 +38,14 @@ struct SyntaxTestError { std::string type; std::string message; + std::string sourceName; int locationStart; int locationEnd; bool operator==(SyntaxTestError const& _rhs) const { return type == _rhs.type && message == _rhs.message && + sourceName == _rhs.sourceName && locationStart == _rhs.locationStart && locationEnd == _rhs.locationEnd; } @@ -85,7 +87,7 @@ protected: static std::vector parseExpectations(std::istream& _stream); - std::string m_source; + std::map m_sources; std::vector m_expectations; std::vector m_errorList; bool m_optimiseYul = false; diff --git a/test/libsolidity/smtCheckerTestsJSON/multi.sol b/test/libsolidity/smtCheckerTestsJSON/multi.sol index e0d69b1d0..d81d76cb0 100644 --- a/test/libsolidity/smtCheckerTestsJSON/multi.sol +++ b/test/libsolidity/smtCheckerTestsJSON/multi.sol @@ -1,3 +1,4 @@ +==== Source: A ==== pragma experimental SMTChecker; contract C diff --git a/test/libsolidity/smtCheckerTestsJSON/simple.sol b/test/libsolidity/smtCheckerTestsJSON/simple.sol index 6bc7193db..f93c8fd79 100644 --- a/test/libsolidity/smtCheckerTestsJSON/simple.sol +++ b/test/libsolidity/smtCheckerTestsJSON/simple.sol @@ -1,3 +1,4 @@ +==== Source: A ==== pragma experimental SMTChecker; contract C diff --git a/test/libsolidity/syntaxTests/multiSource/error_in_first.sol b/test/libsolidity/syntaxTests/multiSource/error_in_first.sol new file mode 100644 index 000000000..abf0bce9b --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/error_in_first.sol @@ -0,0 +1,10 @@ +==== Source: A ==== +contract A { + function g() public { x; } +} +==== Source: B ==== +contract B { + function f() public { } +} +// ---- +// DeclarationError: (A:36-37): Undeclared identifier. diff --git a/test/libsolidity/syntaxTests/multiSource/import.sol b/test/libsolidity/syntaxTests/multiSource/import.sol new file mode 100644 index 000000000..4d9f6c686 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/import.sol @@ -0,0 +1,12 @@ +==== Source: A ==== +contract A { + function g(uint256 x) public view returns(uint256) { return x; } +} +==== Source: B ==== +import "A"; +contract B is A { + function f(uint256 x) public view returns(uint256) { return x; } +} +// ---- +// Warning: (A:14-78): Function state mutability can be restricted to pure +// Warning: (B:31-95): Function state mutability can be restricted to pure diff --git a/test/libsolidity/syntaxTests/multiSource/import_not_found.sol b/test/libsolidity/syntaxTests/multiSource/import_not_found.sol new file mode 100644 index 000000000..dd0d2db28 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/import_not_found.sol @@ -0,0 +1,5 @@ +==== Source: a ==== +import "b"; +contract C {} +// ---- +// ParserError: (a:0-11): Source "b" not found: File not supplied initially. diff --git a/test/libsolidity/syntaxTests/multiSource/no_import.sol b/test/libsolidity/syntaxTests/multiSource/no_import.sol new file mode 100644 index 000000000..37b14b871 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/no_import.sol @@ -0,0 +1,10 @@ +==== Source: A ==== +contract A { + function g(uint256 x) public view returns(uint256) { return x; } +} +==== Source: B ==== +contract B is A { + function f(uint256 x) public view returns(uint256) { return x; } +} +// ---- +// DeclarationError: (B:14-15): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/multiSource/one_source.sol b/test/libsolidity/syntaxTests/multiSource/one_source.sol new file mode 100644 index 000000000..0f0d129b5 --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/one_source.sol @@ -0,0 +1,7 @@ +==== Source: SourceName ==== +contract A { + uint256 x; + function f() public pure { x = 42; } +} +// ---- +// TypeError: (SourceName:53-54): Function declared as pure, but this expression (potentially) modifies the state and thus requires non-payable (the default) or payable. diff --git a/test/libsolidity/syntaxTests/multiSource/warning_in_both.sol b/test/libsolidity/syntaxTests/multiSource/warning_in_both.sol new file mode 100644 index 000000000..1522e42aa --- /dev/null +++ b/test/libsolidity/syntaxTests/multiSource/warning_in_both.sol @@ -0,0 +1,11 @@ +==== Source: A ==== +contract A { + function g(uint256 x) public view returns(uint256) { return x; } +} +==== Source: B ==== +contract B { + function f(uint256 x) public view returns(uint256) { return x; } +} +// ---- +// Warning: (A:14-78): Function state mutability can be restricted to pure +// Warning: (B:14-78): Function state mutability can be restricted to pure From aa2167b20817edd8689d7d5f0da16a2f5fa1c15d Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Fri, 16 Aug 2019 15:12:26 +0200 Subject: [PATCH 2/2] Extract some import tests. --- test/libsolidity/Imports.cpp | 427 ------------------ .../syntaxTests/imports/circular_import.sol | 4 + .../syntaxTests/imports/complex_import.sol | 5 + .../imports/filename_with_period.sol | 6 + .../import_does_not_clutter_importee.sol | 6 + .../imports/import_is_transitive.sol | 7 + .../imports/inheritance_abi_encoder_match.sol | 23 + .../inheritance_abi_encoder_mismatch_1.sol | 21 + .../inheritance_abi_encoder_mismatch_2.sol | 18 + .../imports/library_name_clash.sol | 8 + .../library_name_clash_with_contract.sol | 4 + .../imports/name_clash_in_import_1.sol | 6 + .../imports/name_clash_in_import_2.sol | 6 + .../imports/name_clash_in_import_3.sol | 6 + .../imports/name_clash_in_import_4.sol | 6 + .../imports/name_clash_in_import_5.sol | 4 + .../syntaxTests/imports/regular_import.sol | 4 + .../syntaxTests/imports/relative_import.sol | 6 + .../imports/relative_import_multiplex.sol | 4 + .../imports/shadowing_builtins_with_alias.sol | 6 + .../shadowing_builtins_with_imports.sol | 8 + ...adowing_builtins_with_multiple_imports.sol | 11 + .../imports/shadowing_via_import.sol | 8 + .../syntaxTests/imports/simple_alias.sol | 4 + .../syntaxTests/imports/smoke_test.sol | 2 + 25 files changed, 183 insertions(+), 427 deletions(-) create mode 100644 test/libsolidity/syntaxTests/imports/circular_import.sol create mode 100644 test/libsolidity/syntaxTests/imports/complex_import.sol create mode 100644 test/libsolidity/syntaxTests/imports/filename_with_period.sol create mode 100644 test/libsolidity/syntaxTests/imports/import_does_not_clutter_importee.sol create mode 100644 test/libsolidity/syntaxTests/imports/import_is_transitive.sol create mode 100644 test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_match.sol create mode 100644 test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_1.sol create mode 100644 test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_2.sol create mode 100644 test/libsolidity/syntaxTests/imports/library_name_clash.sol create mode 100644 test/libsolidity/syntaxTests/imports/library_name_clash_with_contract.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_1.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_2.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_3.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_4.sol create mode 100644 test/libsolidity/syntaxTests/imports/name_clash_in_import_5.sol create mode 100644 test/libsolidity/syntaxTests/imports/regular_import.sol create mode 100644 test/libsolidity/syntaxTests/imports/relative_import.sol create mode 100644 test/libsolidity/syntaxTests/imports/relative_import_multiplex.sol create mode 100644 test/libsolidity/syntaxTests/imports/shadowing_builtins_with_alias.sol create mode 100644 test/libsolidity/syntaxTests/imports/shadowing_builtins_with_imports.sol create mode 100644 test/libsolidity/syntaxTests/imports/shadowing_builtins_with_multiple_imports.sol create mode 100644 test/libsolidity/syntaxTests/imports/shadowing_via_import.sol create mode 100644 test/libsolidity/syntaxTests/imports/simple_alias.sol create mode 100644 test/libsolidity/syntaxTests/imports/smoke_test.sol diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp index 95a538aae..a326b4e5d 100644 --- a/test/libsolidity/Imports.cpp +++ b/test/libsolidity/Imports.cpp @@ -41,183 +41,6 @@ namespace test BOOST_AUTO_TEST_SUITE(SolidityImports) -BOOST_AUTO_TEST_CASE(smoke_test) -{ - CompilerStack c; - c.setSources({{"a", "contract C {} pragma solidity >=0.0;"}}); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(regular_import) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(import_does_not_clutter_importee) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(import_is_transitive) -{ - CompilerStack c; - c.setSources({ - {"a", "contract 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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(circular_import) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(relative_import) -{ - CompilerStack c; - c.setSources({ - {"a", "import \"./dir/b\"; contract A is B {} 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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(relative_import_multiplex) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(simple_alias) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(library_name_clash) -{ - CompilerStack c; - c.setSources({ - {"a", "library A {} pragma solidity >=0.0;"}, - {"b", "library A {} pragma solidity >=0.0;"}, - {"c", "import {A} from \"./a\"; import {A} from \"./b\";"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(library_name_clash_with_contract) -{ - CompilerStack c; - c.setSources({ - {"a", "contract A {} pragma solidity >=0.0;"}, - {"b", "library A {} pragma solidity >=0.0;"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(complex_import) -{ - CompilerStack c; - c.setSources({ - {"a", "contract A {} contract B {} contract C { struct S { uint a; } } 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()); - BOOST_CHECK(c.compile()); -} - -BOOST_AUTO_TEST_CASE(name_clash_in_import_1) -{ - CompilerStack c; - c.setSources({ - {"a", "contract A {} pragma solidity >=0.0;"}, - {"b", "import \"a\"; contract A {} pragma solidity >=0.0;"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(name_clash_in_import_2) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(name_clash_in_import_3) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(name_clash_in_import_4) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(name_clash_in_import_5) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(c.compile()); -} - BOOST_AUTO_TEST_CASE(remappings) { CompilerStack c; @@ -246,17 +69,6 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings) BOOST_CHECK(c.compile()); } -BOOST_AUTO_TEST_CASE(filename_with_period) -{ - CompilerStack c; - c.setSources({ - {"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()); - BOOST_CHECK(!c.compile()); -} - BOOST_AUTO_TEST_CASE(context_dependent_remappings_ensure_default_and_module_preserved) { CompilerStack c; @@ -303,245 +115,6 @@ BOOST_AUTO_TEST_CASE(context_dependent_remappings_order_independent_2) BOOST_CHECK(c.compile()); } -BOOST_AUTO_TEST_CASE(shadowing_via_import) -{ - CompilerStack c; - c.setSources({ - {"a", "library A {} pragma solidity >=0.0;"}, - {"b", "library A {} pragma solidity >=0.0;"}, - {"c", "import {A} from \"./a\"; import {A} from \"./b\";"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(!c.compile()); -} - -BOOST_AUTO_TEST_CASE(shadowing_builtins_with_imports) -{ - CompilerStack c; - c.setSources({ - {"B.sol", "contract X {} pragma solidity >=0.0;"}, - {"b", R"( - pragma solidity >=0.0; - import * as msg from "B.sol"; - contract C { - })"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); - size_t errorCount = 0; - for (auto const& e: c.errors()) - { - string const* msg = e->comment(); - BOOST_REQUIRE(msg); - if (msg->find("pre-release") != string::npos) - continue; - BOOST_CHECK( - msg->find("shadows a builtin symbol") != string::npos - ); - errorCount++; - } - BOOST_CHECK_EQUAL(errorCount, 1); -} - -BOOST_AUTO_TEST_CASE(shadowing_builtins_with_multiple_imports) -{ - CompilerStack c; - c.setSources({ - {"B.sol", "contract msg {} contract block{} pragma solidity >=0.0;"}, - {"b", R"( - pragma solidity >=0.0; - import {msg, block} from "B.sol"; - contract C { - })"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); - auto numErrors = c.errors().size(); - // Sometimes we get the prerelease warning, sometimes not. - BOOST_CHECK(4 <= numErrors && numErrors <= 5); - for (auto const& e: c.errors()) - { - string const* msg = e->comment(); - BOOST_REQUIRE(msg); - BOOST_CHECK( - msg->find("pre-release") != string::npos || - msg->find("shadows a builtin symbol") != string::npos - ); - } -} - -BOOST_AUTO_TEST_CASE(shadowing_builtins_with_alias) -{ - CompilerStack c; - c.setSources({ - {"B.sol", "contract C {} pragma solidity >=0.0;"}, - {"b", R"( - pragma solidity >=0.0; - import {C as msg} from "B.sol";)"} - }); - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); - auto numErrors = c.errors().size(); - // Sometimes we get the prerelease warning, sometimes not. - BOOST_CHECK(1 <= numErrors && numErrors <= 2); - for (auto const& e: c.errors()) - { - string const* msg = e->comment(); - BOOST_REQUIRE(msg); - BOOST_CHECK( - msg->find("pre-release") != string::npos || - msg->find("shadows a builtin symbol") != string::npos - ); - } -} - -BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_1) -{ - CompilerStack c; - c.setSources({ - {"A.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - contract A - { - struct S { uint a; } - S public s; - function f(S memory _s) returns (S memory,S memory) { } - } - )"}, - {"B.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - import "./A.sol"; - contract B is A { } - )"}, - {"C.sol", R"( - pragma solidity >=0.0; - - import "./B.sol"; - contract C is B { } - )"} - }); - - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(!c.compile()); - - int typeErrors = 0; - - // Sometimes we get the prerelease warning, sometimes not. - for (auto const& e: c.errors()) - { - if (e->type() != langutil::Error::Type::TypeError) - continue; - - typeErrors++; - - string const* msg = e->comment(); - BOOST_REQUIRE(msg); - BOOST_CHECK_EQUAL(*msg, std::string("Contract \"C\" does not use the new experimental ABI encoder but wants to inherit from a contract which uses types that require it. Use \"pragma experimental ABIEncoderV2;\" for the inheriting contract as well to enable the feature.")); - } - BOOST_CHECK_EQUAL(typeErrors, 1); -} - -BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_mismatch_2) -{ - CompilerStack c; - c.setSources({ - {"A.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - contract A - { - struct S { uint a; } - S public s; - function f(S memory _s) returns (S memory,S memory) { } - } - )"}, - {"B.sol", R"( - pragma solidity >=0.0; - - import "./A.sol"; - contract B is A { } - )"}, - {"C.sol", R"( - pragma solidity >=0.0; - - import "./B.sol"; - contract C is B { } - )"} - }); - - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(!c.compile()); - - int typeErrors = 0; - - // Sometimes we get the prerelease warning, sometimes not. - for (auto const& e: c.errors()) - { - if (e->type() != langutil::Error::Type::TypeError) - continue; - - typeErrors++; - - string const* msg = e->comment(); - BOOST_REQUIRE(msg); - BOOST_CHECK_EQUAL(*msg, std::string("Contract \"B\" does not use the new experimental ABI encoder but wants to inherit from a contract which uses types that require it. Use \"pragma experimental ABIEncoderV2;\" for the inheriting contract as well to enable the feature.")); - } - BOOST_CHECK_EQUAL(typeErrors, 1); -} - -BOOST_AUTO_TEST_CASE(inheritance_abi_encoder_match) -{ - CompilerStack c; - c.setSources({ - {"A.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - contract A - { - struct S { uint a; } - S public s; - function f(S memory _s) public returns (S memory,S memory) { } - } - )"}, - {"B.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - import "./A.sol"; - contract B is A { } - )"}, - {"C.sol", R"( - pragma solidity >=0.0; - pragma experimental ABIEncoderV2; - - import "./B.sol"; - contract C is B { } - )"} - }); - - c.setEVMVersion(dev::test::Options::get().evmVersion()); - BOOST_CHECK(c.compile()); - - int typeErrors = 0; - - // Sometimes we get the prerelease warning, sometimes not. - for (auto const& e: c.errors()) - { - if (e->type() != langutil::Error::Type::TypeError) - continue; - - typeErrors++; - } - - BOOST_CHECK_EQUAL(typeErrors, 0); -} - BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/syntaxTests/imports/circular_import.sol b/test/libsolidity/syntaxTests/imports/circular_import.sol new file mode 100644 index 000000000..45492d8cb --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/circular_import.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +import "b"; contract C { D d; } +==== Source: b ==== +import "a"; contract D { C c; } diff --git a/test/libsolidity/syntaxTests/imports/complex_import.sol b/test/libsolidity/syntaxTests/imports/complex_import.sol new file mode 100644 index 000000000..96fc4d308 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/complex_import.sol @@ -0,0 +1,5 @@ +==== Source: a ==== +contract A {} contract B {} contract C { struct S { uint a; } } +==== Source: 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 {} } \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/imports/filename_with_period.sol b/test/libsolidity/syntaxTests/imports/filename_with_period.sol new file mode 100644 index 000000000..73c47087f --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/filename_with_period.sol @@ -0,0 +1,6 @@ +==== Source: a/.b.sol ==== +contract B {} +==== Source: a/a.sol ==== +import ".b.sol"; contract A is B {} +// ---- +// ParserError: (a/a.sol:0-16): Source ".b.sol" not found: File not supplied initially. diff --git a/test/libsolidity/syntaxTests/imports/import_does_not_clutter_importee.sol b/test/libsolidity/syntaxTests/imports/import_does_not_clutter_importee.sol new file mode 100644 index 000000000..99f3f53e3 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/import_does_not_clutter_importee.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +contract C { D d; } +==== Source: b ==== +import "a"; contract D is C {} +// ---- +// DeclarationError: (a:13-14): Identifier not found or not unique. diff --git a/test/libsolidity/syntaxTests/imports/import_is_transitive.sol b/test/libsolidity/syntaxTests/imports/import_is_transitive.sol new file mode 100644 index 000000000..2b1f76002 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/import_is_transitive.sol @@ -0,0 +1,7 @@ +==== Source: a ==== +contract C { } +==== Source: b ==== +import "a"; +==== Source: c ==== +import "b"; +contract D is C {} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_match.sol b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_match.sol new file mode 100644 index 000000000..cead709b4 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_match.sol @@ -0,0 +1,23 @@ +==== Source: A.sol ==== +pragma experimental ABIEncoderV2; + +contract A +{ + struct S { uint a; } + S public s; + function f(S memory _s) public returns (S memory,S memory) { } +} +==== Source: B.sol ==== +pragma experimental ABIEncoderV2; + +import "./A.sol"; +contract B is A { } +==== Source: C.sol ==== +pragma experimental ABIEncoderV2; + +import "./B.sol"; +contract C is B { } +// ---- +// Warning: (A.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// Warning: (B.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// Warning: (C.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. diff --git a/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_1.sol b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_1.sol new file mode 100644 index 000000000..9000ca0fc --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_1.sol @@ -0,0 +1,21 @@ +==== Source: A.sol ==== +pragma experimental ABIEncoderV2; + +contract A +{ + struct S { uint a; } + S public s; + function f(S memory _s) public returns (S memory,S memory) { } +} +==== Source: B.sol ==== +pragma experimental ABIEncoderV2; + +import "./A.sol"; +contract B is A { } +==== Source: C.sol ==== +import "./B.sol"; +contract C is B { } +// ---- +// Warning: (A.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// Warning: (B.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (C.sol:18-37): Contract "C" does not use the new experimental ABI encoder but wants to inherit from a contract which uses types that require it. Use "pragma experimental ABIEncoderV2;" for the inheriting contract as well to enable the feature. diff --git a/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_2.sol b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_2.sol new file mode 100644 index 000000000..b900d1ba4 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/inheritance_abi_encoder_mismatch_2.sol @@ -0,0 +1,18 @@ +==== Source: A.sol ==== +pragma experimental ABIEncoderV2; + +contract A +{ + struct S { uint a; } + S public s; + function f(S memory _s) public returns (S memory,S memory) { } +} +==== Source: B.sol ==== +import "./A.sol"; +contract B is A { } +==== Source: C.sol ==== +import "./B.sol"; +contract C is B { } +// ---- +// Warning: (A.sol:0-33): Experimental features are turned on. Do not use experimental features on live deployments. +// TypeError: (B.sol:18-37): Contract "B" does not use the new experimental ABI encoder but wants to inherit from a contract which uses types that require it. Use "pragma experimental ABIEncoderV2;" for the inheriting contract as well to enable the feature. diff --git a/test/libsolidity/syntaxTests/imports/library_name_clash.sol b/test/libsolidity/syntaxTests/imports/library_name_clash.sol new file mode 100644 index 000000000..cd0dbd240 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/library_name_clash.sol @@ -0,0 +1,8 @@ +==== Source: a ==== +library A {} +==== Source: b ==== +library A {} +==== Source: c ==== +import {A} from "./a"; import {A} from "./b"; +// ---- +// DeclarationError: (c:23-45): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/library_name_clash_with_contract.sol b/test/libsolidity/syntaxTests/imports/library_name_clash_with_contract.sol new file mode 100644 index 000000000..8358b6485 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/library_name_clash_with_contract.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +library A {} diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_1.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_1.sol new file mode 100644 index 000000000..a5b1acc60 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_1.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import "a"; contract A {} +// ---- +// DeclarationError: (b:12-25): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_2.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_2.sol new file mode 100644 index 000000000..96925f368 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_2.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import "a" as A; contract A {} +// ---- +// DeclarationError: (b:17-30): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_3.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_3.sol new file mode 100644 index 000000000..2ff01b5f8 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_3.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A as b} from "a"; contract b {} +// ---- +// DeclarationError: (b:26-39): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_4.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_4.sol new file mode 100644 index 000000000..abe59271e --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_4.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A} from "a"; contract A {} +// ---- +// DeclarationError: (b:21-34): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/name_clash_in_import_5.sol b/test/libsolidity/syntaxTests/imports/name_clash_in_import_5.sol new file mode 100644 index 000000000..596d47b76 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/name_clash_in_import_5.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +contract A {} +==== Source: b ==== +import {A} from "a"; contract B {} diff --git a/test/libsolidity/syntaxTests/imports/regular_import.sol b/test/libsolidity/syntaxTests/imports/regular_import.sol new file mode 100644 index 000000000..5811798e9 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/regular_import.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +contract C {} +==== Source: b ==== +import "a"; contract D is C {} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/imports/relative_import.sol b/test/libsolidity/syntaxTests/imports/relative_import.sol new file mode 100644 index 000000000..db75c0569 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/relative_import.sol @@ -0,0 +1,6 @@ +==== Source: a ==== +import "./dir/b"; contract A is B {} +==== Source: dir/b ==== +contract B {} +==== Source: dir/c ==== +import "../a"; contract C is A {} \ No newline at end of file diff --git a/test/libsolidity/syntaxTests/imports/relative_import_multiplex.sol b/test/libsolidity/syntaxTests/imports/relative_import_multiplex.sol new file mode 100644 index 000000000..c166def7a --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/relative_import_multiplex.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +contract A {} +==== Source: dir/a/b/c ==== +import "../../.././a"; contract B is A {} diff --git a/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_alias.sol b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_alias.sol new file mode 100644 index 000000000..8ed652a71 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_alias.sol @@ -0,0 +1,6 @@ +==== Source: B.sol ==== +contract C {} +==== Source: b ==== +import {C as msg} from "B.sol"; +// ---- +// Warning: (B.sol:0-13): This declaration shadows a builtin symbol. diff --git a/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_imports.sol b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_imports.sol new file mode 100644 index 000000000..2121b1359 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_imports.sol @@ -0,0 +1,8 @@ +==== Source: B.sol ==== +contract X {} +==== Source: b ==== +import * as msg from "B.sol"; +contract C { +} +// ---- +// Warning: (b:0-29): This declaration shadows a builtin symbol. diff --git a/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_multiple_imports.sol b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_multiple_imports.sol new file mode 100644 index 000000000..848e15546 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/shadowing_builtins_with_multiple_imports.sol @@ -0,0 +1,11 @@ +==== Source: B.sol ==== +contract msg {} contract block{} +==== Source: b ==== +import {msg, block} from "B.sol"; +contract C { +} +// ---- +// Warning: (B.sol:0-15): This declaration shadows a builtin symbol. +// Warning: (B.sol:16-32): This declaration shadows a builtin symbol. +// Warning: (B.sol:0-15): This declaration shadows a builtin symbol. +// Warning: (B.sol:16-32): This declaration shadows a builtin symbol. diff --git a/test/libsolidity/syntaxTests/imports/shadowing_via_import.sol b/test/libsolidity/syntaxTests/imports/shadowing_via_import.sol new file mode 100644 index 000000000..cd0dbd240 --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/shadowing_via_import.sol @@ -0,0 +1,8 @@ +==== Source: a ==== +library A {} +==== Source: b ==== +library A {} +==== Source: c ==== +import {A} from "./a"; import {A} from "./b"; +// ---- +// DeclarationError: (c:23-45): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/imports/simple_alias.sol b/test/libsolidity/syntaxTests/imports/simple_alias.sol new file mode 100644 index 000000000..776c5c42f --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/simple_alias.sol @@ -0,0 +1,4 @@ +==== Source: a ==== +contract A {} +==== Source: dir/a/b/c ==== +import "../../.././a" as x; contract B is x.A { function() external { x.A r = x.A(20); r; } } diff --git a/test/libsolidity/syntaxTests/imports/smoke_test.sol b/test/libsolidity/syntaxTests/imports/smoke_test.sol new file mode 100644 index 000000000..78268d5ab --- /dev/null +++ b/test/libsolidity/syntaxTests/imports/smoke_test.sol @@ -0,0 +1,2 @@ +==== Source: a ==== +contract C {}