diff options
Diffstat (limited to 'libsolidity/interface/CompilerStack.cpp')
-rw-r--r-- | libsolidity/interface/CompilerStack.cpp | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index de4a7ec2..610caea1 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -28,6 +28,7 @@ #include <libsolidity/analysis/SemVerHandler.h> #include <libsolidity/ast/AST.h> #include <libsolidity/parsing/Parser.h> +#include <libsolidity/analysis/ContractLevelChecker.h> #include <libsolidity/analysis/ControlFlowAnalyzer.h> #include <libsolidity/analysis/ControlFlowGraph.h> #include <libsolidity/analysis/GlobalContext.h> @@ -125,7 +126,7 @@ bool CompilerStack::addSource(string const& _name, string const& _content, bool { bool existed = m_sources.count(_name) != 0; reset(true); - m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content), _name); + m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content, _name)); m_sources[_name].isLibrary = _isLibrary; m_stackState = SourcesSet; return existed; @@ -160,7 +161,7 @@ bool CompilerStack::parse() { string const& newPath = newSource.first; string const& newContents = newSource.second; - m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents), newPath); + m_sources[newPath].scanner = make_shared<Scanner>(CharStream(newContents, newPath)); sourcesToParse.push_back(newPath); } } @@ -225,8 +226,21 @@ bool CompilerStack::analyze() m_contracts[contract->fullyQualifiedName()].contract = contract; } - // This cannot be done in the above loop, because cross-contract types couldn't be resolved. - // A good example is `LibraryName.TypeName x;`. + // Next, we check inheritance, overrides, function collisions and other things at + // contract or function level. + // This also calculates whether a contract is abstract, which is needed by the + // type checker. + ContractLevelChecker contractLevelChecker(m_errorReporter); + for (Source const* source: m_sourceOrder) + for (ASTPointer<ASTNode> const& node: source->ast->nodes()) + if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(node.get())) + if (!contractLevelChecker.check(*contract)) + noErrors = false; + + // New we run full type checks that go down to the expression level. This + // cannot be done earlier, because we need cross-contract types and information + // about whether a contract is abstract for the `new` expression. + // This populates the `type` annotation for all expressions. // // Note: this does not resolve overloaded functions. In order to do that, types of arguments are needed, // which is only done one step later. @@ -598,8 +612,8 @@ tuple<int, int, int, int> CompilerStack::positionFromSourceLocation(SourceLocati int startColumn; int endLine; int endColumn; - tie(startLine, startColumn) = scanner(*_sourceLocation.sourceName).translatePositionToLineColumn(_sourceLocation.start); - tie(endLine, endColumn) = scanner(*_sourceLocation.sourceName).translatePositionToLineColumn(_sourceLocation.end); + tie(startLine, startColumn) = scanner(_sourceLocation.source->name()).translatePositionToLineColumn(_sourceLocation.start); + tie(endLine, endColumn) = scanner(_sourceLocation.source->name()).translatePositionToLineColumn(_sourceLocation.end); return make_tuple(++startLine, ++startColumn, ++endLine, ++endColumn); } @@ -922,8 +936,8 @@ string CompilerStack::computeSourceMapping(eth::AssemblyItems const& _items) con SourceLocation const& location = item.location(); int length = location.start != -1 && location.end != -1 ? location.end - location.start : -1; int sourceIndex = - location.sourceName && sourceIndicesMap.count(*location.sourceName) ? - sourceIndicesMap.at(*location.sourceName) : + location.source && sourceIndicesMap.count(location.source->name()) ? + sourceIndicesMap.at(location.source->name()) : -1; char jump = '-'; if (item.getJumpType() == eth::AssemblyItem::JumpType::IntoFunction) |