diff options
author | chriseth <c@ethdev.com> | 2015-11-20 01:02:04 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-11-26 22:37:55 +0800 |
commit | 86495dfc57dde9b825ffd8c219ea809446e978f9 (patch) | |
tree | 99003d3865a0fbb9c08bd20c6b290f0702f31821 /libsolidity/analysis | |
parent | c498dcce22b2921ee57f280da9117e491c021e1b (diff) | |
download | dexon-solidity-86495dfc57dde9b825ffd8c219ea809446e978f9.tar.gz dexon-solidity-86495dfc57dde9b825ffd8c219ea809446e978f9.tar.zst dexon-solidity-86495dfc57dde9b825ffd8c219ea809446e978f9.zip |
Make members context-sensitive.
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 8 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 4 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.h | 3 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 16 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.h | 2 |
5 files changed, 14 insertions, 19 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index fa894456..a2397d9e 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -64,7 +64,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) { m_currentScope = &m_scopes[nullptr]; - ReferencesResolver resolver(m_errors, *this, &_contract, nullptr); + ReferencesResolver resolver(m_errors, *this, nullptr); bool success = true; for (ASTPointer<InheritanceSpecifier> const& baseContract: _contract.baseContracts()) if (!resolver.resolve(*baseContract)) @@ -100,7 +100,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers()) { m_currentScope = &m_scopes[modifier.get()]; - ReferencesResolver resolver(m_errors, *this, &_contract, nullptr); + ReferencesResolver resolver(m_errors, *this, nullptr); if (!resolver.resolve(*modifier)) success = false; } @@ -111,7 +111,6 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) if (!ReferencesResolver( m_errors, *this, - &_contract, function->returnParameterList().get() ).resolve(*function)) success = false; @@ -126,7 +125,7 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers()) { m_currentScope = &m_scopes[modifier.get()]; - ReferencesResolver resolver(m_errors, *this, &_contract, nullptr, true); + ReferencesResolver resolver(m_errors, *this, nullptr, true); if (!resolver.resolve(*modifier)) success = false; } @@ -137,7 +136,6 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) if (!ReferencesResolver( m_errors, *this, - &_contract, function->returnParameterList().get(), true ).resolve(*function)) diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index f0afc4f9..2207fd80 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -50,7 +50,6 @@ bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName) _typeName.annotation().referencedDeclaration = declaration; - _typeName.annotation().contractScope = m_currentContract; return true; } @@ -73,10 +72,7 @@ bool ReferencesResolver::visit(Identifier const& _identifier) if (declarations.empty()) fatalDeclarationError(_identifier.location(), "Undeclared identifier."); else if (declarations.size() == 1) - { _identifier.annotation().referencedDeclaration = declarations.front(); - _identifier.annotation().contractScope = m_currentContract; - } else _identifier.annotation().overloadedDeclarations = m_resolver.cleanedDeclarations(_identifier, declarations); diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 62104611..870312f1 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -45,13 +45,11 @@ public: ReferencesResolver( ErrorList& _errors, NameAndTypeResolver& _resolver, - ContractDefinition const* _currentContract, ParameterList const* _returnParameters, bool _resolveInsideCode = false ): m_errors(_errors), m_resolver(_resolver), - m_currentContract(_currentContract), m_returnParameters(_returnParameters), m_resolveInsideCode(_resolveInsideCode) {} @@ -83,7 +81,6 @@ private: ErrorList& m_errors; NameAndTypeResolver& m_resolver; - ContractDefinition const* m_currentContract; ParameterList const* m_returnParameters; bool const m_resolveInsideCode; bool m_errorOccurred = false; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 42fdad91..2dc357bb 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -60,6 +60,8 @@ TypePointer const& TypeChecker::type(VariableDeclaration const& _variable) const bool TypeChecker::visit(ContractDefinition const& _contract) { + m_scope = &_contract; + // We force our own visiting order here. ASTNode::listAccept(_contract.definedStructs(), *this); ASTNode::listAccept(_contract.baseContracts(), *this); @@ -1057,13 +1059,13 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) if (!contract->annotation().isFullyImplemented) typeError(_newExpression.location(), "Trying to create an instance of an abstract contract."); - auto scopeContract = contractName->annotation().contractScope; - scopeContract->annotation().contractDependencies.insert(contract); + solAssert(!!m_scope, ""); + m_scope->annotation().contractDependencies.insert(contract); solAssert( !contract->annotation().linearizedBaseContracts.empty(), "Linearized base contracts not yet available." ); - if (contractDependenciesAreCyclic(*scopeContract)) + if (contractDependenciesAreCyclic(*m_scope)) typeError( _newExpression.location(), "Circular reference for contract creation (cannot create instance of derived or same contract)." @@ -1112,7 +1114,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) // Retrieve the types of the arguments if this is used to call a function. auto const& argumentTypes = _memberAccess.annotation().argumentTypes; - MemberList::MemberMap possibleMembers = exprType->members().membersByName(memberName); + MemberList::MemberMap possibleMembers = exprType->members(m_scope).membersByName(memberName); if (possibleMembers.size() > 1 && argumentTypes) { // do overload resolution @@ -1131,7 +1133,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) DataLocation::Storage, exprType ); - if (!storageType->members().membersByName(memberName).empty()) + if (!storageType->members(m_scope).membersByName(memberName).empty()) fatalTypeError( _memberAccess.location(), "Member \"" + memberName + "\" is not available in " + @@ -1258,7 +1260,7 @@ bool TypeChecker::visit(Identifier const& _identifier) for (Declaration const* declaration: annotation.overloadedDeclarations) { - TypePointer function = declaration->type(_identifier.annotation().contractScope); + TypePointer function = declaration->type(); solAssert(!!function, "Requested type not present."); auto const* functionType = dynamic_cast<FunctionType const*>(function.get()); if (functionType && functionType->canTakeArguments(*annotation.argumentTypes)) @@ -1277,7 +1279,7 @@ bool TypeChecker::visit(Identifier const& _identifier) "Referenced declaration is null after overload resolution." ); annotation.isLValue = annotation.referencedDeclaration->isLValue(); - annotation.type = annotation.referencedDeclaration->type(_identifier.annotation().contractScope); + annotation.type = annotation.referencedDeclaration->type(); if (!annotation.type) fatalTypeError(_identifier.location(), "Declaration referenced before type could be determined."); return false; diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 2295bc22..9563d4a9 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -117,6 +117,8 @@ private: /// Runs type checks on @a _expression to infer its type and then checks that it is an LValue. void requireLValue(Expression const& _expression); + ContractDefinition const* m_scope = nullptr; + ErrorList& m_errors; }; |