/* This file is part of solidity. solidity is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. solidity is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with solidity. If not, see . */ // SPDX-License-Identifier: GPL-3.0 #include #include #include #include #include #include #include namespace solidity::lsp { using namespace frontend; using namespace langutil; using namespace std; optional parseLineColumn(Json::Value const& _lineColumn) { if (_lineColumn.isObject() && _lineColumn["line"].isInt() && _lineColumn["character"].isInt()) return LineColumn{_lineColumn["line"].asInt(), _lineColumn["character"].asInt()}; else return nullopt; } Json::Value toJson(LineColumn const& _pos) { Json::Value json = Json::objectValue; json["line"] = max(_pos.line, 0); json["character"] = max(_pos.column, 0); return json; } Json::Value toJsonRange(LineColumn const& _start, LineColumn const& _end) { Json::Value json; json["start"] = toJson(_start); json["end"] = toJson(_end); return json; } Declaration const* referencedDeclaration(Expression const* _expression) { if (auto const* identifier = dynamic_cast(_expression)) if (Declaration const* referencedDeclaration = identifier->annotation().referencedDeclaration) return referencedDeclaration; if (auto const* memberAccess = dynamic_cast(_expression)) if (memberAccess->annotation().referencedDeclaration) return memberAccess->annotation().referencedDeclaration; return nullptr; } optional declarationLocation(Declaration const* _declaration) { if (!_declaration) return nullopt; if (_declaration->nameLocation().isValid()) return _declaration->nameLocation(); if (_declaration->location().isValid()) return _declaration->location(); return nullopt; } optional parsePosition( FileRepository const& _fileRepository, string const& _sourceUnitName, Json::Value const& _position ) { if (!_fileRepository.sourceUnits().count(_sourceUnitName)) return nullopt; if (optional lineColumn = parseLineColumn(_position)) if (optional const offset = CharStream::translateLineColumnToPosition( _fileRepository.sourceUnits().at(_sourceUnitName), *lineColumn )) return SourceLocation{*offset, *offset, make_shared(_sourceUnitName)}; return nullopt; } optional parseRange(FileRepository const& _fileRepository, string const& _sourceUnitName, Json::Value const& _range) { if (!_range.isObject()) return nullopt; optional start = parsePosition(_fileRepository, _sourceUnitName, _range["start"]); optional end = parsePosition(_fileRepository, _sourceUnitName, _range["end"]); if (!start || !end) return nullopt; solAssert(*start->sourceName == *end->sourceName); start->end = end->end; return start; } string stripFileUriSchemePrefix(string const& _path) { regex const windowsDriveLetterPath("^file:///[a-zA-Z]:/"); if (regex_search(_path, windowsDriveLetterPath)) return _path.substr(8); if (_path.find("file://") == 0) return _path.substr(7); else return _path; } }