aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--solidityCompiler.cpp26
-rw-r--r--solidityExpressionCompiler.cpp47
-rw-r--r--solidityNameAndTypeResolution.cpp11
-rw-r--r--solidityParser.cpp55
4 files changed, 102 insertions, 37 deletions
diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp
index 3e86919a..883cecf2 100644
--- a/solidityCompiler.cpp
+++ b/solidityCompiler.cpp
@@ -46,16 +46,22 @@ namespace
bytes compileContract(const string& _sourceCode)
{
Parser parser;
- ASTPointer<ContractDefinition> contract;
- BOOST_REQUIRE_NO_THROW(contract = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
- NameAndTypeResolver resolver({});
- BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
-
- Compiler compiler;
- compiler.compileContract(*contract, {});
- // debug
- //compiler.streamAssembly(cout);
- return compiler.getAssembledBytecode();
+ ASTPointer<SourceUnit> sourceUnit;
+ BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ NameAndTypeResolver resolver({});
+ BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
+
+ Compiler compiler;
+ compiler.compileContract(*contract, {});
+ // debug
+ //compiler.streamAssembly(cout);
+ return compiler.getAssembledBytecode();
+ }
+ BOOST_FAIL("No contract found in source.");
+ return bytes();
}
/// Checks that @a _compiledCode is present starting from offset @a _offset in @a _expectation.
diff --git a/solidityExpressionCompiler.cpp b/solidityExpressionCompiler.cpp
index 6ea66bad..b077e262 100644
--- a/solidityExpressionCompiler.cpp
+++ b/solidityExpressionCompiler.cpp
@@ -86,27 +86,32 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
vector<vector<string>> _localVariables = {})
{
Parser parser;
- ASTPointer<ContractDefinition> contract;
- BOOST_REQUIRE_NO_THROW(contract = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
- NameAndTypeResolver resolver({});
- BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
- FirstExpressionExtractor extractor(*contract);
- BOOST_REQUIRE(extractor.getExpression() != nullptr);
-
- CompilerContext context;
- for (vector<string> const& function: _functions)
- context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver)));
- for (vector<string> const& variable: _localVariables)
- context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver)));
-
- ExpressionCompiler::compileExpression(context, *extractor.getExpression());
-
- for (vector<string> const& function: _functions)
- context << context.getFunctionEntryLabel(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver)));
- bytes instructions = context.getAssembledBytecode();
- // debug
- // cout << eth::disassemble(instructions) << endl;
- return instructions;
+ ASTPointer<SourceUnit> sourceUnit;
+ BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode))));
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ NameAndTypeResolver resolver({});
+ BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract));
+ FirstExpressionExtractor extractor(*contract);
+ BOOST_REQUIRE(extractor.getExpression() != nullptr);
+
+ CompilerContext context;
+ for (vector<string> const& function: _functions)
+ context.addFunction(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver)));
+ for (vector<string> const& variable: _localVariables)
+ context.addVariable(dynamic_cast<VariableDeclaration const&>(resolveDeclaration(variable, resolver)));
+
+ ExpressionCompiler::compileExpression(context, *extractor.getExpression());
+
+ for (vector<string> const& function: _functions)
+ context << context.getFunctionEntryLabel(dynamic_cast<FunctionDefinition const&>(resolveDeclaration(function, resolver)));
+ bytes instructions = context.getAssembledBytecode();
+ // debug
+ // cout << eth::disassemble(instructions) << endl;
+ return instructions;
+ }
+ BOOST_FAIL("No contract found in source.");
}
} // end anonymous namespace
diff --git a/solidityNameAndTypeResolution.cpp b/solidityNameAndTypeResolution.cpp
index 8804c519..219fa259 100644
--- a/solidityNameAndTypeResolution.cpp
+++ b/solidityNameAndTypeResolution.cpp
@@ -41,10 +41,13 @@ namespace
void parseTextAndResolveNames(std::string const& _source)
{
Parser parser;
- ASTPointer<ContractDefinition> contract = parser.parse(
- std::make_shared<Scanner>(CharStream(_source)));
- NameAndTypeResolver resolver({});
- resolver.resolveNamesAndTypes(*contract);
+ ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get()))
+ {
+ NameAndTypeResolver resolver({});
+ resolver.resolveNamesAndTypes(*contract);
+ }
}
}
diff --git a/solidityParser.cpp b/solidityParser.cpp
index 6a97a5d9..a9e2d531 100644
--- a/solidityParser.cpp
+++ b/solidityParser.cpp
@@ -21,13 +21,15 @@
*/
#include <string>
-
+#include <memory>
#include <libdevcore/Log.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
#include <libsolidity/Exceptions.h>
#include <boost/test/unit_test.hpp>
+using namespace std;
+
namespace dev
{
namespace solidity
@@ -40,7 +42,12 @@ namespace
ASTPointer<ContractDefinition> parseText(std::string const& _source)
{
Parser parser;
- return parser.parse(std::make_shared<Scanner>(CharStream(_source)));
+ ASTPointer<SourceUnit> sourceUnit = parser.parse(std::make_shared<Scanner>(CharStream(_source)));
+ for (ASTPointer<ASTNode> const& node: sourceUnit->getNodes())
+ if (ASTPointer<ContractDefinition> contract = dynamic_pointer_cast<ContractDefinition>(node))
+ return contract;
+ BOOST_FAIL("No contract found in source.");
+ return ASTPointer<ContractDefinition>();
}
}
@@ -380,6 +387,50 @@ BOOST_AUTO_TEST_CASE(statement_starting_with_type_conversion)
BOOST_CHECK_NO_THROW(parseText(text));
}
+BOOST_AUTO_TEST_CASE(import_directive)
+{
+ char const* text = "import \"abc\";\n"
+ "contract test {\n"
+ " function fun() {\n"
+ " uint64(2);\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_NO_THROW(parseText(text));
+}
+
+BOOST_AUTO_TEST_CASE(multiple_contracts)
+{
+ char const* text = "contract test {\n"
+ " function fun() {\n"
+ " uint64(2);\n"
+ " }\n"
+ "}\n"
+ "contract test2 {\n"
+ " function fun() {\n"
+ " uint64(2);\n"
+ " }\n"
+ "}\n";
+ BOOST_CHECK_NO_THROW(parseText(text));
+}
+
+BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports)
+{
+ char const* text = "import \"abc\";\n"
+ "contract test {\n"
+ " function fun() {\n"
+ " uint64(2);\n"
+ " }\n"
+ "}\n"
+ "import \"def\";\n"
+ "contract test2 {\n"
+ " function fun() {\n"
+ " uint64(2);\n"
+ " }\n"
+ "}\n"
+ "import \"ghi\";\n";
+ BOOST_CHECK_NO_THROW(parseText(text));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}