mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Applying final review
This commit is contained in:
parent
6884d2f516
commit
02e84ea547
@ -548,7 +548,7 @@ void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tuple<ASTNode const*, int> LanguageServer::astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, langutil::LineColumn const& _filePos)
|
tuple<ASTNode const*, int> LanguageServer::astNodeAndOffsetAtSourceLocation(std::string const& _sourceUnitName, LineColumn const& _filePos)
|
||||||
{
|
{
|
||||||
if (m_compilerStack.state() < CompilerStack::AnalysisPerformed)
|
if (m_compilerStack.state() < CompilerStack::AnalysisPerformed)
|
||||||
return {nullptr, -1};
|
return {nullptr, -1};
|
||||||
|
@ -35,23 +35,23 @@ namespace solidity::lsp
|
|||||||
|
|
||||||
ReferenceCollector::ReferenceCollector(
|
ReferenceCollector::ReferenceCollector(
|
||||||
Declaration const& _declaration,
|
Declaration const& _declaration,
|
||||||
string const& _sourceIdentifierName
|
string const& _identifierAtCursorLocation
|
||||||
):
|
):
|
||||||
m_declaration{_declaration},
|
m_declaration{_declaration},
|
||||||
m_sourceIdentifierName{_sourceIdentifierName.empty() ? _declaration.name() : _sourceIdentifierName}
|
m_identifierAtCursorLocation{_identifierAtCursorLocation.empty() ? _declaration.name() : _identifierAtCursorLocation}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Reference> ReferenceCollector::collect(
|
vector<Reference> ReferenceCollector::collect(
|
||||||
Declaration const* _declaration,
|
Declaration const* _declaration,
|
||||||
ASTNode const& _astSearchRoot,
|
ASTNode const& _astSearchRoot,
|
||||||
string const& _sourceIdentifierName
|
string const& _identifierAtCursorLocation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!_declaration)
|
if (!_declaration)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
ReferenceCollector collector(*_declaration, _sourceIdentifierName);
|
ReferenceCollector collector(*_declaration, _identifierAtCursorLocation);
|
||||||
_astSearchRoot.accept(collector);
|
_astSearchRoot.accept(collector);
|
||||||
return std::move(collector.m_collectedReferences);
|
return std::move(collector.m_collectedReferences);
|
||||||
}
|
}
|
||||||
@ -65,10 +65,10 @@ vector<Reference> ReferenceCollector::collect(
|
|||||||
if (!_sourceNode)
|
if (!_sourceNode)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto references = vector<Reference>{};
|
solAssert(_sourceNode->location().containsOffset(_sourceOffset), "");
|
||||||
|
|
||||||
if (auto const* identifier = dynamic_cast<Identifier const*>(_sourceNode))
|
if (auto const* identifier = dynamic_cast<Identifier const*>(_sourceNode))
|
||||||
references += collect(identifier->annotation().referencedDeclaration, _sourceUnit, identifier->name());
|
return collect(identifier->annotation().referencedDeclaration, _sourceUnit, identifier->name());
|
||||||
else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(_sourceNode))
|
else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(_sourceNode))
|
||||||
{
|
{
|
||||||
solAssert(identifierPath->path().size() >= 1, "");
|
solAssert(identifierPath->path().size() >= 1, "");
|
||||||
@ -79,19 +79,17 @@ vector<Reference> ReferenceCollector::collect(
|
|||||||
{
|
{
|
||||||
Declaration const* declaration = identifierPath->annotation().pathDeclarations.at(i);
|
Declaration const* declaration = identifierPath->annotation().pathDeclarations.at(i);
|
||||||
ASTString const& name = identifierPath->path().at(i);
|
ASTString const& name = identifierPath->path().at(i);
|
||||||
references += collect(declaration, _sourceUnit, name);
|
return collect(declaration, _sourceUnit, name);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
else if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(_sourceNode))
|
else if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(_sourceNode))
|
||||||
references += collect(memberAccess->annotation().referencedDeclaration, _sourceUnit, memberAccess->memberName());
|
return collect(memberAccess->annotation().referencedDeclaration, _sourceUnit, memberAccess->memberName());
|
||||||
else if (auto const* declaration = dynamic_cast<Declaration const*>(_sourceNode))
|
else if (auto const* declaration = dynamic_cast<Declaration const*>(_sourceNode))
|
||||||
references += collect(declaration, _sourceUnit, declaration->name());
|
return collect(declaration, _sourceUnit, declaration->name());
|
||||||
else
|
else
|
||||||
lspRequire(false, ErrorCode::InternalError, "Unhandled AST node "s + typeid(*_sourceNode).name());
|
lspRequire(false, ErrorCode::InternalError, "Unhandled AST node "s + typeid(*_sourceNode).name());
|
||||||
|
|
||||||
return references;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReferenceCollector::visit(ImportDirective const& _import)
|
bool ReferenceCollector::visit(ImportDirective const& _import)
|
||||||
@ -99,7 +97,7 @@ bool ReferenceCollector::visit(ImportDirective const& _import)
|
|||||||
for (ImportDirective::SymbolAlias const& symbolAlias: _import.symbolAliases())
|
for (ImportDirective::SymbolAlias const& symbolAlias: _import.symbolAliases())
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
symbolAlias.alias && *symbolAlias.alias == m_sourceIdentifierName &&
|
symbolAlias.alias && *symbolAlias.alias == m_identifierAtCursorLocation &&
|
||||||
symbolAlias.symbol && symbolAlias.symbol->annotation().referencedDeclaration == &m_declaration
|
symbolAlias.symbol && symbolAlias.symbol->annotation().referencedDeclaration == &m_declaration
|
||||||
)
|
)
|
||||||
m_collectedReferences.emplace_back(symbolAlias.location, DocumentHighlightKind::Read);
|
m_collectedReferences.emplace_back(symbolAlias.location, DocumentHighlightKind::Read);
|
||||||
@ -122,7 +120,7 @@ void ReferenceCollector::endVisit(IdentifierPath const& _identifierPath)
|
|||||||
_identifierPath.annotation().pathDeclarations.at(i) :
|
_identifierPath.annotation().pathDeclarations.at(i) :
|
||||||
nullptr;
|
nullptr;
|
||||||
|
|
||||||
if (declaration == &m_declaration && name == m_sourceIdentifierName)
|
if (declaration == &m_declaration && name == m_identifierAtCursorLocation)
|
||||||
m_collectedReferences.emplace_back(_identifierPath.pathLocations().at(i), m_kind);
|
m_collectedReferences.emplace_back(_identifierPath.pathLocations().at(i), m_kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +146,7 @@ bool ReferenceCollector::visit(Assignment const& _assignment)
|
|||||||
|
|
||||||
bool ReferenceCollector::visit(VariableDeclaration const& _variableDeclaration)
|
bool ReferenceCollector::visit(VariableDeclaration const& _variableDeclaration)
|
||||||
{
|
{
|
||||||
if (&_variableDeclaration == &m_declaration && _variableDeclaration.name() == m_sourceIdentifierName)
|
if (&_variableDeclaration == &m_declaration && _variableDeclaration.name() == m_identifierAtCursorLocation)
|
||||||
m_collectedReferences.emplace_back(_variableDeclaration.nameLocation(), DocumentHighlightKind::Write);
|
m_collectedReferences.emplace_back(_variableDeclaration.nameLocation(), DocumentHighlightKind::Write);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -158,7 +156,7 @@ bool ReferenceCollector::visitNode(ASTNode const& _genericNode)
|
|||||||
if (&_genericNode == &m_declaration)
|
if (&_genericNode == &m_declaration)
|
||||||
{
|
{
|
||||||
Declaration const* declaration = dynamic_cast<Declaration const*>(&_genericNode);
|
Declaration const* declaration = dynamic_cast<Declaration const*>(&_genericNode);
|
||||||
if (declaration->name() == m_sourceIdentifierName)
|
if (declaration->name() == m_identifierAtCursorLocation)
|
||||||
m_collectedReferences.emplace_back(declaration->nameLocation(), m_kind);
|
m_collectedReferences.emplace_back(declaration->nameLocation(), m_kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ namespace solidity::lsp
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Describes the way a reference to be highlighted is used in the code.
|
||||||
|
*
|
||||||
* See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentHighlightKind
|
* See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentHighlightKind
|
||||||
*/
|
*/
|
||||||
enum class DocumentHighlightKind
|
enum class DocumentHighlightKind
|
||||||
@ -41,31 +43,19 @@ using Reference = std::tuple<langutil::SourceLocation, DocumentHighlightKind>;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ReferenceCollector can be used to collect all source locations and their usage
|
* ReferenceCollector can be used to collect all source locations and their usage
|
||||||
* of a given symbol in the AST tree.
|
* of a given symbol in the AST.
|
||||||
*/
|
*/
|
||||||
class ReferenceCollector: public frontend::ASTConstVisitor
|
class ReferenceCollector: public frontend::ASTConstVisitor
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
ReferenceCollector(frontend::Declaration const& _declaration, std::string const& _sourceIdentifierName = "");
|
/// Collects all references (symbols with the same matching declaration as @p _sourceNode) in the given source unit.
|
||||||
|
|
||||||
/// Collects all occurrences of a given identifier matching the same declaration.
|
|
||||||
/// Just passing the AST node and infer the name from there is not enough as they might have been aliased.
|
|
||||||
///
|
///
|
||||||
/// @param _declaration the declaration to match against for the symbols to collect
|
/// @param _sourceNode AST node to start collecting recursively down from.
|
||||||
/// @param _sourceOffset byte offset into the respective file reflecting the exact location of the cursor
|
/// @param _sourceOffset byte offset into the respective file reflecting the exact location of the cursor
|
||||||
/// @param _astSearchRoot the AST base root node to start the recursive traversal to collect the references
|
/// @param _sourceUnit the related source unit the given AST node belongs to.
|
||||||
/// @param _sourceIdentifierName the symbolic name that must match, which is explicitly given as it might have been altered due to aliases.
|
|
||||||
///
|
///
|
||||||
/// @returns a vector of Reference objects that contain the source location of each match as well as their
|
/// @returns a vector of Reference objects that contain the source location of each match as well as their
|
||||||
/// semantic use (e.g. read access or write access).
|
/// semantic use (e.g. read access or write access).
|
||||||
static std::vector<Reference> collect(
|
|
||||||
frontend::Declaration const* _declaration,
|
|
||||||
frontend::ASTNode const& _astSearchRoot,
|
|
||||||
std::string const& _sourceIdentifierName
|
|
||||||
);
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// Collects all references (symbols with the same matching declaration as @p _sourceNode) in the given source unit.
|
|
||||||
static std::vector<Reference> collect(frontend::ASTNode const* _sourceNode, int _sourceOffset, frontend::SourceUnit const& _sourceUnit);
|
static std::vector<Reference> collect(frontend::ASTNode const* _sourceNode, int _sourceOffset, frontend::SourceUnit const& _sourceUnit);
|
||||||
|
|
||||||
bool visit(frontend::ImportDirective const& _import) override;
|
bool visit(frontend::ImportDirective const& _import) override;
|
||||||
@ -76,9 +66,27 @@ public:
|
|||||||
bool visit(frontend::VariableDeclaration const& _node) override;
|
bool visit(frontend::VariableDeclaration const& _node) override;
|
||||||
bool visitNode(frontend::ASTNode const& _node) override;
|
bool visitNode(frontend::ASTNode const& _node) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
ReferenceCollector(frontend::Declaration const& _declaration, std::string const& _identifierAtCursorLocation = "");
|
||||||
|
|
||||||
|
/// Collects all occurrences of a given identifier matching the same declaration.
|
||||||
|
/// Just passing the AST node and inferring the name from there is not enough as they might have been aliased.
|
||||||
|
///
|
||||||
|
/// @param _declaration the declaration to match against for the symbols to collect
|
||||||
|
/// @param _astSearchRoot the AST base root node to start the recursive traversal to collect the references
|
||||||
|
/// @param _identifierAtCursorLocation the symbolic name that must match, which is explicitly given as it might have been altered due to aliases.
|
||||||
|
///
|
||||||
|
/// @returns a vector of Reference objects that contain the source location of each match as well as their
|
||||||
|
/// semantic use (e.g. read access or write access).
|
||||||
|
static std::vector<Reference> collect(
|
||||||
|
frontend::Declaration const* _declaration,
|
||||||
|
frontend::ASTNode const& _astSearchRoot,
|
||||||
|
std::string const& _identifierAtCursorLocation
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
frontend::Declaration const& m_declaration;
|
frontend::Declaration const& m_declaration;
|
||||||
std::string const& m_sourceIdentifierName;
|
std::string const& m_identifierAtCursorLocation;
|
||||||
std::vector<Reference> m_collectedReferences;
|
std::vector<Reference> m_collectedReferences;
|
||||||
DocumentHighlightKind m_kind = DocumentHighlightKind::Read;
|
DocumentHighlightKind m_kind = DocumentHighlightKind::Read;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user