mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Basic nlohmann-json integration.
Co-authored-by: Alex Beregszaszi <alex@rtfs.hu>
This commit is contained in:
parent
2cc6610e40
commit
5c66718295
@ -43,9 +43,8 @@ include(EthCcache)
|
||||
# Let's find our dependencies
|
||||
include(EthDependencies)
|
||||
include(fmtlib)
|
||||
include(jsoncpp)
|
||||
include(nlohmann-json)
|
||||
include(range-v3)
|
||||
include_directories(SYSTEM ${JSONCPP_INCLUDE_DIR})
|
||||
|
||||
find_package(Threads)
|
||||
|
||||
|
@ -1,70 +0,0 @@
|
||||
include(ExternalProject)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
|
||||
set(JSONCPP_CMAKE_COMMAND emcmake cmake)
|
||||
else()
|
||||
set(JSONCPP_CMAKE_COMMAND ${CMAKE_COMMAND})
|
||||
endif()
|
||||
|
||||
set(prefix "${CMAKE_BINARY_DIR}/deps")
|
||||
set(JSONCPP_LIBRARY "${prefix}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}jsoncpp${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
set(JSONCPP_INCLUDE_DIR "${prefix}/include")
|
||||
|
||||
# TODO: Investigate why this breaks some emscripten builds and
|
||||
# check whether this can be removed after updating the emscripten
|
||||
# versions used in the CI runs.
|
||||
if(EMSCRIPTEN)
|
||||
# Do not include all flags in CMAKE_CXX_FLAGS for emscripten,
|
||||
# but only use -std=c++17. Using all flags causes build failures
|
||||
# at the moment.
|
||||
set(JSONCPP_CXX_FLAGS -std=c++17)
|
||||
else()
|
||||
# jsoncpp uses implicit casts for comparing integer and
|
||||
# floating point numbers. This causes clang-10 (used by ossfuzz builder)
|
||||
# to error on the implicit conversions. Here, we request jsoncpp
|
||||
# to unconditionally use static casts for these conversions by defining the
|
||||
# JSON_USE_INT64_DOUBLE_CONVERSION preprocessor macro. Doing so,
|
||||
# not only gets rid of the implicit conversion error that clang-10 produces
|
||||
# but also forces safer behavior in general.
|
||||
set(JSONCPP_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DJSON_USE_INT64_DOUBLE_CONVERSION")
|
||||
endif()
|
||||
|
||||
set(byproducts "")
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.1)
|
||||
set(byproducts BUILD_BYPRODUCTS "${JSONCPP_LIBRARY}")
|
||||
endif()
|
||||
|
||||
# Propagate CMAKE_MSVC_RUNTIME_LIBRARY on Windows builds, if set.
|
||||
if (WIN32 AND POLICY CMP0091 AND CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW")
|
||||
list(APPEND JSONCPP_CMAKE_ARGS "-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}")
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(jsoncpp-project
|
||||
PREFIX "${prefix}"
|
||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/downloads"
|
||||
DOWNLOAD_NAME jsoncpp-1.9.3.tar.gz
|
||||
URL https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz
|
||||
URL_HASH SHA256=8593c1d69e703563d94d8c12244e2e18893eeb9a8a9f8aa3d09a327aa45c8f7d
|
||||
CMAKE_COMMAND ${JSONCPP_CMAKE_COMMAND}
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_INSTALL_LIBDIR=lib
|
||||
# Build static lib but suitable to be included in a shared lib.
|
||||
-DCMAKE_POSITION_INDEPENDENT_CODE=${BUILD_SHARED_LIBS}
|
||||
-DJSONCPP_WITH_EXAMPLE=OFF
|
||||
-DJSONCPP_WITH_TESTS=OFF
|
||||
-DJSONCPP_WITH_PKGCONFIG_SUPPORT=OFF
|
||||
-DCMAKE_CXX_FLAGS=${JSONCPP_CXX_FLAGS}
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
|
||||
${JSONCPP_CMAKE_ARGS}
|
||||
${byproducts}
|
||||
)
|
||||
|
||||
# Create jsoncpp imported library
|
||||
add_library(jsoncpp STATIC IMPORTED)
|
||||
file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist.
|
||||
set_property(TARGET jsoncpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY})
|
||||
set_property(TARGET jsoncpp PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR})
|
||||
set_property(TARGET jsoncpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR})
|
||||
add_dependencies(jsoncpp jsoncpp-project)
|
14
cmake/nlohmann-json.cmake
Normal file
14
cmake/nlohmann-json.cmake
Normal file
@ -0,0 +1,14 @@
|
||||
include(ExternalProject)
|
||||
|
||||
ExternalProject_Add(nlohmann-json
|
||||
DOWNLOAD_DIR "${CMAKE_SOURCE_DIR}/deps/nlohmann/json"
|
||||
DOWNLOAD_NAME json.hpp
|
||||
DOWNLOAD_NO_EXTRACT 1
|
||||
URL https://github.com/nlohmann/json/releases/download/v3.10.2/json.hpp
|
||||
URL_HASH SHA256=059743e48b37e41579ee3a92e82e984bfa0d2a9a2b20b175d04db8089f46f047
|
||||
CMAKE_COMMAND true
|
||||
BUILD_COMMAND true
|
||||
INSTALL_COMMAND true
|
||||
)
|
||||
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/deps/nlohmann)
|
@ -34,62 +34,33 @@ picosha2:
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
jsoncpp:
|
||||
The JsonCpp library's source code, including accompanying documentation,
|
||||
tests and demonstration applications, are licensed under the following
|
||||
conditions...
|
||||
nlohmann-json:
|
||||
__ _____ _____ _____
|
||||
__| | __| | | | JSON for Modern C++
|
||||
| | |__ | | | | | | version 3.10.2
|
||||
|_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
|
||||
The JsonCpp Authors explicitly disclaim copyright in all
|
||||
jurisdictions which recognize such a disclaimer. In such jurisdictions,
|
||||
this software is released into the Public Domain.
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
|
||||
|
||||
In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
|
||||
2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is
|
||||
released under the terms of the MIT License (see below).
|
||||
|
||||
In jurisdictions which recognize Public Domain property, the user of this
|
||||
software may choose to accept it either as 1) Public Domain, 2) under the
|
||||
conditions of the MIT License (see below), or 3) under the terms of dual
|
||||
Public Domain/MIT License conditions described here, as they choose.
|
||||
|
||||
The MIT License is about as close to Public Domain as a license can get, and is
|
||||
described in clear, concise terms at:
|
||||
|
||||
http://en.wikipedia.org/wiki/MIT_License
|
||||
|
||||
The full text of the MIT License follows:
|
||||
|
||||
========================================================================
|
||||
Copyright (c) 2007-2010 The JsonCpp Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
========================================================================
|
||||
(END LICENSE TEXT)
|
||||
|
||||
The MIT license is compatible with both the GPL and commercial
|
||||
software, affording one all of the rights of Public Domain with the
|
||||
minor nuisance of being required to keep the above copyright notice
|
||||
and license text in the source code. Note also that by accepting the
|
||||
Public Domain "license" you can re-license your copy using whatever
|
||||
license you like.
|
||||
|
||||
scanner/token:
|
||||
The liblangutil/{CharStream,Scanner,Token}.{h,cpp} files are derived from
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include <liblangutil/CharStream.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <range/v3/algorithm/any_of.hpp>
|
||||
#include <range/v3/view/enumerate.hpp>
|
||||
|
||||
@ -222,11 +220,12 @@ string Assembly::assemblyString(
|
||||
return tmp.str();
|
||||
}
|
||||
|
||||
Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices, bool _includeSourceList) const
|
||||
Json Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices, bool _includeSourceList) const
|
||||
{
|
||||
Json::Value root;
|
||||
root[".code"] = Json::arrayValue;
|
||||
Json::Value& code = root[".code"];
|
||||
Json root{Json::object()};
|
||||
root[".code"] = Json::array();
|
||||
|
||||
Json& code = root[".code"];
|
||||
for (AssemblyItem const& item: m_items)
|
||||
{
|
||||
int sourceIndex = -1;
|
||||
@ -238,7 +237,7 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices,
|
||||
}
|
||||
|
||||
auto [name, data] = item.nameAndData();
|
||||
Json::Value jsonItem;
|
||||
Json jsonItem;
|
||||
jsonItem["name"] = name;
|
||||
jsonItem["begin"] = item.location().start;
|
||||
jsonItem["end"] = item.location().end;
|
||||
@ -254,32 +253,32 @@ Json::Value Assembly::assemblyJSON(map<string, unsigned> const& _sourceIndices,
|
||||
if (!data.empty())
|
||||
jsonItem["value"] = data;
|
||||
jsonItem["source"] = sourceIndex;
|
||||
code.append(std::move(jsonItem));
|
||||
code.emplace_back(std::move(jsonItem));
|
||||
|
||||
if (item.type() == AssemblyItemType::Tag)
|
||||
{
|
||||
Json::Value jumpdest;
|
||||
Json jumpdest;
|
||||
jumpdest["name"] = "JUMPDEST";
|
||||
jumpdest["begin"] = item.location().start;
|
||||
jumpdest["end"] = item.location().end;
|
||||
jumpdest["source"] = sourceIndex;
|
||||
if (item.m_modifierDepth != 0)
|
||||
jumpdest["modifierDepth"] = static_cast<int>(item.m_modifierDepth);
|
||||
code.append(std::move(jumpdest));
|
||||
code.emplace_back(std::move(jumpdest));
|
||||
}
|
||||
}
|
||||
if (_includeSourceList)
|
||||
{
|
||||
root["sourceList"] = Json::arrayValue;
|
||||
Json::Value& jsonSourceList = root["sourceList"];
|
||||
root["sourceList"] = Json::array();
|
||||
Json& jsonSourceList = root["sourceList"];
|
||||
for (auto const& [name, index]: _sourceIndices)
|
||||
jsonSourceList[index] = name;
|
||||
}
|
||||
|
||||
if (!m_data.empty() || !m_subs.empty())
|
||||
{
|
||||
root[".data"] = Json::objectValue;
|
||||
Json::Value& data = root[".data"];
|
||||
root[".data"] = Json::object();
|
||||
Json& data = root[".data"];
|
||||
for (auto const& i: m_data)
|
||||
if (u256(i.first) >= m_subs.size())
|
||||
data[util::toHex(toBigEndian((u256)i.first), util::HexPrefix::DontAdd, util::HexCase::Upper)] = util::toHex(i.second);
|
||||
|
@ -29,12 +29,11 @@
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
#include <libsolutil/Assertions.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolutil/Keccak256.h>
|
||||
|
||||
#include <libsolidity/interface/OptimiserSettings.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
@ -149,7 +148,7 @@ public:
|
||||
) const;
|
||||
|
||||
/// Create a JSON representation of the assembly.
|
||||
Json::Value assemblyJSON(
|
||||
Json assemblyJSON(
|
||||
std::map<std::string, unsigned> const& _sourceIndices = std::map<std::string, unsigned>(),
|
||||
bool _includeSourceList = true
|
||||
) const;
|
||||
|
@ -32,11 +32,10 @@
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
#include <libevmasm/Instruction.h>
|
||||
#include <libsolutil/FixedHash.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolutil/LazyInit.h>
|
||||
#include <libsolutil/Visitor.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <range/v3/view/subrange.hpp>
|
||||
#include <range/v3/view/map.hpp>
|
||||
|
||||
|
@ -51,7 +51,7 @@ namespace
|
||||
{
|
||||
|
||||
template<typename V, template<typename> typename C>
|
||||
void addIfSet(std::vector<pair<string, Json::Value>>& _attributes, string const& _name, C<V> const& _value)
|
||||
void addIfSet(std::vector<pair<string, Json>>& _attributes, string const& _name, C<V> const& _value)
|
||||
{
|
||||
if constexpr (std::is_same_v<C<V>, solidity::util::SetOnce<V>>)
|
||||
{
|
||||
@ -82,23 +82,23 @@ ASTJsonExporter::ASTJsonExporter(CompilerStack::State _stackState, map<string, u
|
||||
void ASTJsonExporter::setJsonNode(
|
||||
ASTNode const& _node,
|
||||
string const& _nodeName,
|
||||
initializer_list<pair<string, Json::Value>>&& _attributes
|
||||
initializer_list<pair<string, Json>>&& _attributes
|
||||
)
|
||||
{
|
||||
ASTJsonExporter::setJsonNode(
|
||||
_node,
|
||||
_nodeName,
|
||||
std::vector<pair<string, Json::Value>>(std::move(_attributes))
|
||||
std::vector<pair<string, Json>>(std::move(_attributes))
|
||||
);
|
||||
}
|
||||
|
||||
void ASTJsonExporter::setJsonNode(
|
||||
ASTNode const& _node,
|
||||
string const& _nodeType,
|
||||
std::vector<pair<string, Json::Value>>&& _attributes
|
||||
std::vector<pair<string, Json>>&& _attributes
|
||||
)
|
||||
{
|
||||
m_currentValue = Json::objectValue;
|
||||
m_currentValue = Json::object();
|
||||
m_currentValue["id"] = nodeId(_node);
|
||||
m_currentValue["src"] = sourceLocationToString(_node.location());
|
||||
if (auto const* documented = dynamic_cast<Documented const*>(&_node))
|
||||
@ -126,12 +126,12 @@ string ASTJsonExporter::sourceLocationToString(SourceLocation const& _location)
|
||||
return to_string(_location.start) + ":" + to_string(length) + ":" + (sourceIndexOpt.has_value() ? to_string(sourceIndexOpt.value()) : "-1");
|
||||
}
|
||||
|
||||
Json::Value ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const& _sourceLocations) const
|
||||
Json ASTJsonExporter::sourceLocationsToJson(vector<SourceLocation> const& _sourceLocations) const
|
||||
{
|
||||
Json::Value locations = Json::arrayValue;
|
||||
Json locations = Json::array();
|
||||
|
||||
for (SourceLocation const& location: _sourceLocations)
|
||||
locations.append(sourceLocationToString(location));
|
||||
locations.emplace_back(sourceLocationToString(location));
|
||||
|
||||
return locations;
|
||||
}
|
||||
@ -141,33 +141,33 @@ string ASTJsonExporter::namePathToString(std::vector<ASTString> const& _namePath
|
||||
return boost::algorithm::join(_namePath, ".");
|
||||
}
|
||||
|
||||
Json::Value ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation)
|
||||
Json ASTJsonExporter::typePointerToJson(Type const* _tp, bool _withoutDataLocation)
|
||||
{
|
||||
Json::Value typeDescriptions(Json::objectValue);
|
||||
typeDescriptions["typeString"] = _tp ? Json::Value(_tp->toString(_withoutDataLocation)) : Json::nullValue;
|
||||
typeDescriptions["typeIdentifier"] = _tp ? Json::Value(_tp->identifier()) : Json::nullValue;
|
||||
Json typeDescriptions(Json::object());
|
||||
typeDescriptions["typeString"] = _tp ? Json(_tp->toString(_withoutDataLocation)) : Json{};
|
||||
typeDescriptions["typeIdentifier"] = _tp ? Json(_tp->identifier()) : Json{};
|
||||
return typeDescriptions;
|
||||
|
||||
}
|
||||
Json::Value ASTJsonExporter::typePointerToJson(std::optional<FuncCallArguments> const& _tps)
|
||||
Json ASTJsonExporter::typePointerToJson(std::optional<FuncCallArguments> const& _tps)
|
||||
{
|
||||
if (_tps)
|
||||
{
|
||||
Json::Value arguments(Json::arrayValue);
|
||||
Json arguments(Json::array());
|
||||
for (auto const& tp: _tps->types)
|
||||
appendMove(arguments, typePointerToJson(tp));
|
||||
return arguments;
|
||||
}
|
||||
else
|
||||
return Json::nullValue;
|
||||
return Json{};
|
||||
}
|
||||
|
||||
void ASTJsonExporter::appendExpressionAttributes(
|
||||
std::vector<pair<string, Json::Value>>& _attributes,
|
||||
std::vector<pair<string, Json>>& _attributes,
|
||||
ExpressionAnnotation const& _annotation
|
||||
)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> exprAttributes = {
|
||||
std::vector<pair<string, Json>> exprAttributes = {
|
||||
make_pair("typeDescriptions", typePointerToJson(_annotation.type)),
|
||||
make_pair("argumentTypes", typePointerToJson(_annotation.arguments))
|
||||
};
|
||||
@ -182,18 +182,19 @@ void ASTJsonExporter::appendExpressionAttributes(
|
||||
_attributes += exprAttributes;
|
||||
}
|
||||
|
||||
Json::Value ASTJsonExporter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
|
||||
Json ASTJsonExporter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
|
||||
{
|
||||
Json::Value tuple(Json::objectValue);
|
||||
Json tuple(Json::object());
|
||||
tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first));
|
||||
tuple["declaration"] = idOrNull(_info.second.declaration);
|
||||
tuple["isSlot"] = Json::Value(_info.second.suffix == "slot");
|
||||
tuple["isOffset"] = Json::Value(_info.second.suffix == "offset");
|
||||
tuple["isSlot"] = Json(_info.second.suffix == "slot");
|
||||
tuple["isOffset"] = Json(_info.second.suffix == "offset");
|
||||
|
||||
if (!_info.second.suffix.empty())
|
||||
tuple["suffix"] = Json::Value(_info.second.suffix);
|
||||
tuple["suffix"] = Json(_info.second.suffix);
|
||||
|
||||
tuple["valueSize"] = Json::Value(Json::LargestUInt(_info.second.valueSize));
|
||||
// TODO: assert?
|
||||
tuple["valueSize"] = Json(static_cast<Json::number_integer_t>(_info.second.valueSize));
|
||||
|
||||
return tuple;
|
||||
}
|
||||
@ -203,7 +204,7 @@ void ASTJsonExporter::print(ostream& _stream, ASTNode const& _node, util::JsonFo
|
||||
_stream << util::jsonPrint(toJson(_node), _format);
|
||||
}
|
||||
|
||||
Json::Value ASTJsonExporter::toJson(ASTNode const& _node)
|
||||
Json ASTJsonExporter::toJson(ASTNode const& _node)
|
||||
{
|
||||
_node.accept(*this);
|
||||
return util::removeNullMembers(std::move(m_currentValue));
|
||||
@ -211,19 +212,19 @@ Json::Value ASTJsonExporter::toJson(ASTNode const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(SourceUnit const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("license", _node.licenseString() ? Json::Value(*_node.licenseString()) : Json::nullValue),
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("license", _node.licenseString() ? Json(*_node.licenseString()) : Json{}),
|
||||
make_pair("nodes", toJson(_node.nodes()))
|
||||
};
|
||||
|
||||
if (_node.annotation().exportedSymbols.set())
|
||||
{
|
||||
Json::Value exportedSymbols = Json::objectValue;
|
||||
Json exportedSymbols{Json::object()};
|
||||
for (auto const& sym: *_node.annotation().exportedSymbols)
|
||||
{
|
||||
exportedSymbols[sym.first] = Json::arrayValue;
|
||||
exportedSymbols[sym.first] = Json::array();
|
||||
for (Declaration const* overload: sym.second)
|
||||
exportedSymbols[sym.first].append(nodeId(*overload));
|
||||
exportedSymbols[sym.first].emplace_back(nodeId(*overload));
|
||||
}
|
||||
|
||||
attributes.emplace_back("exportedSymbols", exportedSymbols);
|
||||
@ -238,9 +239,9 @@ bool ASTJsonExporter::visit(SourceUnit const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(PragmaDirective const& _node)
|
||||
{
|
||||
Json::Value literals(Json::arrayValue);
|
||||
Json literals(Json::array());
|
||||
for (auto const& literal: _node.literals())
|
||||
literals.append(literal);
|
||||
literals.emplace_back(literal);
|
||||
setJsonNode(_node, "PragmaDirective", {
|
||||
make_pair("literals", std::move(literals))
|
||||
});
|
||||
@ -249,7 +250,7 @@ bool ASTJsonExporter::visit(PragmaDirective const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ImportDirective const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("file", _node.path()),
|
||||
make_pair("sourceUnit", idOrNull(_node.annotation().sourceUnit)),
|
||||
make_pair("scope", idOrNull(_node.scope()))
|
||||
@ -258,17 +259,17 @@ bool ASTJsonExporter::visit(ImportDirective const& _node)
|
||||
addIfSet(attributes, "absolutePath", _node.annotation().absolutePath);
|
||||
|
||||
attributes.emplace_back("unitAlias", _node.name());
|
||||
attributes.emplace_back("nameLocation", Json::Value(sourceLocationToString(_node.nameLocation())));
|
||||
attributes.emplace_back("nameLocation", Json(sourceLocationToString(_node.nameLocation())));
|
||||
|
||||
Json::Value symbolAliases(Json::arrayValue);
|
||||
Json symbolAliases(Json::array());
|
||||
for (auto const& symbolAlias: _node.symbolAliases())
|
||||
{
|
||||
Json::Value tuple(Json::objectValue);
|
||||
Json tuple(Json::object());
|
||||
solAssert(symbolAlias.symbol, "");
|
||||
tuple["foreign"] = toJson(*symbolAlias.symbol);
|
||||
tuple["local"] = symbolAlias.alias ? Json::Value(*symbolAlias.alias) : Json::nullValue;
|
||||
tuple["local"] = symbolAlias.alias ? Json(*symbolAlias.alias) : Json{};
|
||||
tuple["nameLocation"] = sourceLocationToString(_node.nameLocation());
|
||||
symbolAliases.append(tuple);
|
||||
symbolAliases.emplace_back(tuple);
|
||||
}
|
||||
attributes.emplace_back("symbolAliases", std::move(symbolAliases));
|
||||
setJsonNode(_node, "ImportDirective", std::move(attributes));
|
||||
@ -277,10 +278,10 @@ bool ASTJsonExporter::visit(ImportDirective const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ContractDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json{}),
|
||||
make_pair("contractKind", contractKind(_node.contractKind())),
|
||||
make_pair("abstract", _node.abstract()),
|
||||
make_pair("baseContracts", toJson(_node.baseContracts())),
|
||||
@ -302,10 +303,10 @@ bool ASTJsonExporter::visit(ContractDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(IdentifierPath const& _node)
|
||||
{
|
||||
Json::Value nameLocations = Json::arrayValue;
|
||||
Json nameLocations = Json::array();
|
||||
|
||||
for (SourceLocation location: _node.pathLocations())
|
||||
nameLocations.append(sourceLocationToString(location));
|
||||
nameLocations.emplace_back(sourceLocationToString(location));
|
||||
|
||||
setJsonNode(_node, "IdentifierPath", {
|
||||
make_pair("name", namePathToString(_node.path())),
|
||||
@ -319,24 +320,24 @@ bool ASTJsonExporter::visit(InheritanceSpecifier const& _node)
|
||||
{
|
||||
setJsonNode(_node, "InheritanceSpecifier", {
|
||||
make_pair("baseName", toJson(_node.name())),
|
||||
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
|
||||
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json{})
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ASTJsonExporter::visit(UsingForDirective const& _node)
|
||||
{
|
||||
vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json::nullValue)
|
||||
vector<pair<string, Json>> attributes = {
|
||||
make_pair("typeName", _node.typeName() ? toJson(*_node.typeName()) : Json{})
|
||||
};
|
||||
if (_node.usesBraces())
|
||||
{
|
||||
Json::Value functionList;
|
||||
Json functionList;
|
||||
for (auto const& function: _node.functionsOrLibrary())
|
||||
{
|
||||
Json::Value functionNode;
|
||||
Json functionNode;
|
||||
functionNode["function"] = toJson(*function);
|
||||
functionList.append(std::move(functionNode));
|
||||
functionList.emplace_back(std::move(functionNode));
|
||||
}
|
||||
attributes.emplace_back("functionList", std::move(functionList));
|
||||
}
|
||||
@ -351,7 +352,7 @@ bool ASTJsonExporter::visit(UsingForDirective const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(StructDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||
@ -368,7 +369,7 @@ bool ASTJsonExporter::visit(StructDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(EnumDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("members", toJson(_node.members()))
|
||||
@ -393,7 +394,7 @@ bool ASTJsonExporter::visit(EnumValue const& _node)
|
||||
bool ASTJsonExporter::visit(UserDefinedValueTypeDefinition const& _node)
|
||||
{
|
||||
solAssert(_node.underlyingType(), "");
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("underlyingType", toJson(*_node.underlyingType()))
|
||||
@ -423,18 +424,18 @@ bool ASTJsonExporter::visit(OverrideSpecifier const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(FunctionDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json{}),
|
||||
make_pair("kind", _node.isFree() ? "freeFunction" : TokenTraits::toString(_node.kind())),
|
||||
make_pair("stateMutability", stateMutabilityToString(_node.stateMutability())),
|
||||
make_pair("virtual", _node.markedVirtual()),
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json{}),
|
||||
make_pair("parameters", toJson(_node.parameterList())),
|
||||
make_pair("returnParameters", toJson(*_node.returnParameterList())),
|
||||
make_pair("modifiers", toJson(_node.modifiers())),
|
||||
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue),
|
||||
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json{}),
|
||||
make_pair("implemented", _node.isImplemented()),
|
||||
make_pair("scope", idOrNull(_node.scope()))
|
||||
};
|
||||
@ -461,7 +462,7 @@ bool ASTJsonExporter::visit(FunctionDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(VariableDeclaration const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("typeName", toJson(_node.typeName())),
|
||||
@ -469,9 +470,9 @@ bool ASTJsonExporter::visit(VariableDeclaration const& _node)
|
||||
make_pair("mutability", VariableDeclaration::mutabilityToString(_node.mutability())),
|
||||
make_pair("stateVariable", _node.isStateVariable()),
|
||||
make_pair("storageLocation", location(_node.referenceLocation())),
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json{}),
|
||||
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||
make_pair("value", _node.value() ? toJson(*_node.value()) : Json::nullValue),
|
||||
make_pair("value", _node.value() ? toJson(*_node.value()) : Json{}),
|
||||
make_pair("scope", idOrNull(_node.scope())),
|
||||
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
|
||||
};
|
||||
@ -489,15 +490,15 @@ bool ASTJsonExporter::visit(VariableDeclaration const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ModifierDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json{}),
|
||||
make_pair("visibility", Declaration::visibilityToString(_node.visibility())),
|
||||
make_pair("parameters", toJson(_node.parameterList())),
|
||||
make_pair("virtual", _node.markedVirtual()),
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json::nullValue),
|
||||
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json::nullValue)
|
||||
make_pair("overrides", _node.overrides() ? toJson(*_node.overrides()) : Json{}),
|
||||
make_pair("body", _node.isImplemented() ? toJson(_node.body()) : Json{})
|
||||
};
|
||||
if (!_node.annotation().baseFunctions.empty())
|
||||
attributes.emplace_back(make_pair("baseModifiers", getContainerIds(_node.annotation().baseFunctions, true)));
|
||||
@ -507,9 +508,9 @@ bool ASTJsonExporter::visit(ModifierDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ModifierInvocation const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes{
|
||||
std::vector<pair<string, Json>> attributes{
|
||||
make_pair("modifierName", toJson(_node.name())),
|
||||
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json::nullValue)
|
||||
make_pair("arguments", _node.arguments() ? toJson(*_node.arguments()) : Json{})
|
||||
};
|
||||
if (Declaration const* declaration = _node.name().annotation().referencedDeclaration)
|
||||
{
|
||||
@ -525,10 +526,10 @@ bool ASTJsonExporter::visit(ModifierInvocation const& _node)
|
||||
bool ASTJsonExporter::visit(EventDefinition const& _node)
|
||||
{
|
||||
m_inEvent = true;
|
||||
std::vector<pair<string, Json::Value>> _attributes = {
|
||||
std::vector<pair<string, Json>> _attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json{}),
|
||||
make_pair("parameters", toJson(_node.parameterList())),
|
||||
make_pair("anonymous", _node.isAnonymous())
|
||||
};
|
||||
@ -545,10 +546,10 @@ bool ASTJsonExporter::visit(EventDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ErrorDefinition const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> _attributes = {
|
||||
std::vector<pair<string, Json>> _attributes = {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("nameLocation", sourceLocationToString(_node.nameLocation())),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json::nullValue),
|
||||
make_pair("documentation", _node.documentation() ? toJson(*_node.documentation()) : Json{}),
|
||||
make_pair("parameters", toJson(_node.parameterList()))
|
||||
};
|
||||
if (m_stackState >= CompilerStack::State::AnalysisPerformed)
|
||||
@ -560,7 +561,7 @@ bool ASTJsonExporter::visit(ErrorDefinition const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ElementaryTypeName const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("name", _node.typeName().toString()),
|
||||
make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true))
|
||||
};
|
||||
@ -616,7 +617,7 @@ bool ASTJsonExporter::visit(ArrayTypeName const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(InlineAssembly const& _node)
|
||||
{
|
||||
vector<pair<string, Json::Value>> externalReferences;
|
||||
vector<pair<string, Json>> externalReferences;
|
||||
|
||||
for (auto const& it: _node.annotation().externalReferences)
|
||||
if (it.first)
|
||||
@ -625,26 +626,26 @@ bool ASTJsonExporter::visit(InlineAssembly const& _node)
|
||||
inlineAssemblyIdentifierToJson(it)
|
||||
));
|
||||
|
||||
Json::Value externalReferencesJson = Json::arrayValue;
|
||||
Json externalReferencesJson{Json::array()};
|
||||
|
||||
std::sort(externalReferences.begin(), externalReferences.end());
|
||||
for (Json::Value& it: externalReferences | ranges::views::values)
|
||||
externalReferencesJson.append(std::move(it));
|
||||
for (Json& it: externalReferences | ranges::views::values)
|
||||
externalReferencesJson.emplace_back(std::move(it));
|
||||
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("AST", Json::Value(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))),
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("AST", Json(yul::AsmJsonConverter(sourceIndexFromLocation(_node.location()))(_node.operations()))),
|
||||
make_pair("externalReferences", std::move(externalReferencesJson)),
|
||||
make_pair("evmVersion", dynamic_cast<solidity::yul::EVMDialect const&>(_node.dialect()).evmVersion().name())
|
||||
};
|
||||
|
||||
if (_node.flags())
|
||||
{
|
||||
Json::Value flags(Json::arrayValue);
|
||||
Json flags(Json::array());
|
||||
for (auto const& flag: *_node.flags())
|
||||
if (flag)
|
||||
flags.append(*flag);
|
||||
flags.emplace_back(*flag);
|
||||
else
|
||||
flags.append(Json::nullValue);
|
||||
flags.emplace_back(Json{});
|
||||
attributes.emplace_back(make_pair("flags", std::move(flags)));
|
||||
}
|
||||
setJsonNode(_node, "InlineAssembly", std::move(attributes));
|
||||
@ -764,7 +765,7 @@ bool ASTJsonExporter::visit(RevertStatement const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(VariableDeclarationStatement const& _node)
|
||||
{
|
||||
Json::Value varDecs(Json::arrayValue);
|
||||
Json varDecs(Json::array());
|
||||
for (auto const& v: _node.declarations())
|
||||
appendMove(varDecs, idOrNull(v.get()));
|
||||
setJsonNode(_node, "VariableDeclarationStatement", {
|
||||
@ -785,7 +786,7 @@ bool ASTJsonExporter::visit(ExpressionStatement const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(Conditional const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("condition", toJson(_node.condition())),
|
||||
make_pair("trueExpression", toJson(_node.trueExpression())),
|
||||
make_pair("falseExpression", toJson(_node.falseExpression()))
|
||||
@ -797,7 +798,7 @@ bool ASTJsonExporter::visit(Conditional const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(Assignment const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("operator", TokenTraits::toString(_node.assignmentOperator())),
|
||||
make_pair("leftHandSide", toJson(_node.leftHandSide())),
|
||||
make_pair("rightHandSide", toJson(_node.rightHandSide()))
|
||||
@ -809,8 +810,8 @@ bool ASTJsonExporter::visit(Assignment const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(TupleExpression const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
make_pair("isInlineArray", Json::Value(_node.isInlineArray())),
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("isInlineArray", Json(_node.isInlineArray())),
|
||||
make_pair("components", toJson(_node.components())),
|
||||
};
|
||||
appendExpressionAttributes(attributes, _node.annotation());
|
||||
@ -820,7 +821,7 @@ bool ASTJsonExporter::visit(TupleExpression const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(UnaryOperation const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("prefix", _node.isPrefixOperation()),
|
||||
make_pair("operator", TokenTraits::toString(_node.getOperator())),
|
||||
make_pair("subExpression", toJson(_node.subExpression()))
|
||||
@ -832,7 +833,7 @@ bool ASTJsonExporter::visit(UnaryOperation const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(BinaryOperation const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("operator", TokenTraits::toString(_node.getOperator())),
|
||||
make_pair("leftExpression", toJson(_node.leftExpression())),
|
||||
make_pair("rightExpression", toJson(_node.rightExpression())),
|
||||
@ -845,10 +846,10 @@ bool ASTJsonExporter::visit(BinaryOperation const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(FunctionCall const& _node)
|
||||
{
|
||||
Json::Value names(Json::arrayValue);
|
||||
Json names(Json::array());
|
||||
for (auto const& name: _node.names())
|
||||
names.append(Json::Value(*name));
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
names.emplace_back(*name);
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("expression", toJson(_node.expression())),
|
||||
make_pair("names", std::move(names)),
|
||||
make_pair("nameLocations", sourceLocationsToJson(_node.nameLocations())),
|
||||
@ -869,11 +870,11 @@ bool ASTJsonExporter::visit(FunctionCall const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(FunctionCallOptions const& _node)
|
||||
{
|
||||
Json::Value names(Json::arrayValue);
|
||||
Json names(Json::array());
|
||||
for (auto const& name: _node.names())
|
||||
names.append(Json::Value(*name));
|
||||
names.emplace_back(Json(*name));
|
||||
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("expression", toJson(_node.expression())),
|
||||
make_pair("names", std::move(names)),
|
||||
make_pair("options", toJson(_node.options())),
|
||||
@ -886,7 +887,7 @@ bool ASTJsonExporter::visit(FunctionCallOptions const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(NewExpression const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("typeName", toJson(_node.typeName()))
|
||||
};
|
||||
appendExpressionAttributes(attributes, _node.annotation());
|
||||
@ -896,9 +897,9 @@ bool ASTJsonExporter::visit(NewExpression const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(MemberAccess const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("memberName", _node.memberName()),
|
||||
make_pair("memberLocation", Json::Value(sourceLocationToString(_node.memberLocation()))),
|
||||
make_pair("memberLocation", Json(sourceLocationToString(_node.memberLocation()))),
|
||||
make_pair("expression", toJson(_node.expression())),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
|
||||
};
|
||||
@ -909,7 +910,7 @@ bool ASTJsonExporter::visit(MemberAccess const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(IndexAccess const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("baseExpression", toJson(_node.baseExpression())),
|
||||
make_pair("indexExpression", toJsonOrNull(_node.indexExpression())),
|
||||
};
|
||||
@ -920,7 +921,7 @@ bool ASTJsonExporter::visit(IndexAccess const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(IndexRangeAccess const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("baseExpression", toJson(_node.baseExpression())),
|
||||
make_pair("startExpression", toJsonOrNull(_node.startExpression())),
|
||||
make_pair("endExpression", toJsonOrNull(_node.endExpression())),
|
||||
@ -932,9 +933,9 @@ bool ASTJsonExporter::visit(IndexRangeAccess const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(Identifier const& _node)
|
||||
{
|
||||
Json::Value overloads(Json::arrayValue);
|
||||
Json overloads(Json::array());
|
||||
for (auto const& dec: _node.annotation().overloadedDeclarations)
|
||||
overloads.append(nodeId(*dec));
|
||||
overloads.emplace_back(nodeId(*dec));
|
||||
setJsonNode(_node, "Identifier", {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("referencedDeclaration", idOrNull(_node.annotation().referencedDeclaration)),
|
||||
@ -947,7 +948,7 @@ bool ASTJsonExporter::visit(Identifier const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node)
|
||||
{
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("typeName", toJson(_node.type()))
|
||||
};
|
||||
appendExpressionAttributes(attributes, _node.annotation());
|
||||
@ -957,19 +958,19 @@ bool ASTJsonExporter::visit(ElementaryTypeNameExpression const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(Literal const& _node)
|
||||
{
|
||||
Json::Value value{_node.value()};
|
||||
Json value{_node.value()};
|
||||
if (!util::validateUTF8(_node.value()))
|
||||
value = Json::nullValue;
|
||||
value = Json{};
|
||||
Token subdenomination = Token(_node.subDenomination());
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("kind", literalTokenKind(_node.token())),
|
||||
make_pair("value", value),
|
||||
make_pair("hexValue", util::toHex(util::asBytes(_node.value()))),
|
||||
make_pair(
|
||||
"subdenomination",
|
||||
subdenomination == Token::Illegal ?
|
||||
Json::nullValue :
|
||||
Json::Value{TokenTraits::toString(subdenomination)}
|
||||
Json{} :
|
||||
Json{TokenTraits::toString(subdenomination)}
|
||||
)
|
||||
};
|
||||
appendExpressionAttributes(attributes, _node.annotation());
|
||||
@ -979,8 +980,8 @@ bool ASTJsonExporter::visit(Literal const& _node)
|
||||
|
||||
bool ASTJsonExporter::visit(StructuredDocumentation const& _node)
|
||||
{
|
||||
Json::Value text{*_node.text()};
|
||||
std::vector<pair<string, Json::Value>> attributes = {
|
||||
Json text{*_node.text()};
|
||||
std::vector<pair<string, Json>> attributes = {
|
||||
make_pair("text", text)
|
||||
};
|
||||
setJsonNode(_node, "StructuredDocumentation", std::move(attributes));
|
||||
|
@ -26,10 +26,8 @@
|
||||
#include <libsolidity/ast/ASTAnnotations.h>
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <json/json.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
@ -60,16 +58,16 @@ public:
|
||||
);
|
||||
/// Output the json representation of the AST to _stream.
|
||||
void print(std::ostream& _stream, ASTNode const& _node, util::JsonFormat const& _format);
|
||||
Json::Value toJson(ASTNode const& _node);
|
||||
Json toJson(ASTNode const& _node);
|
||||
template <class T>
|
||||
Json::Value toJson(std::vector<ASTPointer<T>> const& _nodes)
|
||||
Json toJson(std::vector<ASTPointer<T>> const& _nodes)
|
||||
{
|
||||
Json::Value ret(Json::arrayValue);
|
||||
Json ret{Json::array()};
|
||||
for (auto const& n: _nodes)
|
||||
if (n)
|
||||
appendMove(ret, toJson(*n));
|
||||
else
|
||||
ret.append(Json::nullValue);
|
||||
ret.emplace_back(Json{});
|
||||
return ret;
|
||||
}
|
||||
bool visit(SourceUnit const& _node) override;
|
||||
@ -134,27 +132,27 @@ private:
|
||||
void setJsonNode(
|
||||
ASTNode const& _node,
|
||||
std::string const& _nodeName,
|
||||
std::initializer_list<std::pair<std::string, Json::Value>>&& _attributes
|
||||
std::initializer_list<std::pair<std::string, Json>>&& _attributes
|
||||
);
|
||||
void setJsonNode(
|
||||
ASTNode const& _node,
|
||||
std::string const& _nodeName,
|
||||
std::vector<std::pair<std::string, Json::Value>>&& _attributes
|
||||
std::vector<std::pair<std::string, Json>>&& _attributes
|
||||
);
|
||||
/// Maps source location to an index, if source is valid and a mapping does exist, otherwise returns std::nullopt.
|
||||
std::optional<size_t> sourceIndexFromLocation(langutil::SourceLocation const& _location) const;
|
||||
std::string sourceLocationToString(langutil::SourceLocation const& _location) const;
|
||||
Json::Value sourceLocationsToJson(std::vector<langutil::SourceLocation> const& _sourceLocations) const;
|
||||
Json sourceLocationsToJson(std::vector<langutil::SourceLocation> const& _sourceLocations) const;
|
||||
static std::string namePathToString(std::vector<ASTString> const& _namePath);
|
||||
static Json::Value idOrNull(ASTNode const* _pt)
|
||||
static Json idOrNull(ASTNode const* _pt)
|
||||
{
|
||||
return _pt ? Json::Value(nodeId(*_pt)) : Json::nullValue;
|
||||
return _pt ? Json(nodeId(*_pt)) : Json{};
|
||||
}
|
||||
Json::Value toJsonOrNull(ASTNode const* _node)
|
||||
Json toJsonOrNull(ASTNode const* _node)
|
||||
{
|
||||
return _node ? toJson(*_node) : Json::nullValue;
|
||||
return _node ? toJson(*_node) : Json{};
|
||||
}
|
||||
Json::Value inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
|
||||
Json inlineAssemblyIdentifierToJson(std::pair<yul::Identifier const* , InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const;
|
||||
static std::string location(VariableDeclaration::Location _location);
|
||||
static std::string contractKind(ContractKind _kind);
|
||||
static std::string functionCallKind(FunctionCallKind _kind);
|
||||
@ -166,7 +164,7 @@ private:
|
||||
return _node.id();
|
||||
}
|
||||
template<class Container>
|
||||
static Json::Value getContainerIds(Container const& _container, bool _order = false)
|
||||
static Json getContainerIds(Container const& _container, bool _order = false)
|
||||
{
|
||||
std::vector<int64_t> tmp;
|
||||
|
||||
@ -177,28 +175,27 @@ private:
|
||||
}
|
||||
if (_order)
|
||||
std::sort(tmp.begin(), tmp.end());
|
||||
Json::Value json(Json::arrayValue);
|
||||
|
||||
Json json{Json::array()};
|
||||
for (int64_t val: tmp)
|
||||
json.append(val);
|
||||
|
||||
json.emplace_back(val);
|
||||
return json;
|
||||
}
|
||||
static Json::Value typePointerToJson(Type const* _tp, bool _withoutDataLocation = false);
|
||||
static Json::Value typePointerToJson(std::optional<FuncCallArguments> const& _tps);
|
||||
static Json typePointerToJson(Type const* _tp, bool _withoutDataLocation = false);
|
||||
static Json typePointerToJson(std::optional<FuncCallArguments> const& _tps);
|
||||
void appendExpressionAttributes(
|
||||
std::vector<std::pair<std::string, Json::Value>> &_attributes,
|
||||
std::vector<std::pair<std::string, Json>> &_attributes,
|
||||
ExpressionAnnotation const& _annotation
|
||||
);
|
||||
static void appendMove(Json::Value& _array, Json::Value&& _value)
|
||||
static void appendMove(Json& _array, Json&& _value)
|
||||
{
|
||||
solAssert(_array.isArray(), "");
|
||||
_array.append(std::move(_value));
|
||||
solAssert(_array.is_array(), "");
|
||||
_array.emplace_back(std::move(_value));
|
||||
}
|
||||
|
||||
CompilerStack::State m_stackState = CompilerStack::State::Empty; ///< Used to only access information that already exists
|
||||
bool m_inEvent = false; ///< whether we are currently inside an event or not
|
||||
Json::Value m_currentValue;
|
||||
Json m_currentValue;
|
||||
std::map<std::string, unsigned> m_sourceIndices;
|
||||
};
|
||||
|
||||
|
@ -44,9 +44,9 @@ namespace solidity::frontend
|
||||
using SourceLocation = langutil::SourceLocation;
|
||||
|
||||
template<class T>
|
||||
ASTPointer<T> ASTJsonImporter::nullOrCast(Json::Value const& _json)
|
||||
ASTPointer<T> ASTJsonImporter::nullOrCast(Json const& _json)
|
||||
{
|
||||
if (_json.isNull())
|
||||
if (_json.is_null())
|
||||
return nullptr;
|
||||
else
|
||||
return dynamic_pointer_cast<T>(convertJsonToASTNode(_json));
|
||||
@ -55,13 +55,13 @@ ASTPointer<T> ASTJsonImporter::nullOrCast(Json::Value const& _json)
|
||||
|
||||
// ============ public ===========================
|
||||
|
||||
map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string, Json::Value> const& _sourceList)
|
||||
map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string, Json> const& _sourceList)
|
||||
{
|
||||
for (auto const& src: _sourceList)
|
||||
m_sourceNames.emplace_back(make_shared<string const>(src.first));
|
||||
for (auto const& srcPair: _sourceList)
|
||||
{
|
||||
astAssert(!srcPair.second.isNull());
|
||||
astAssert(!srcPair.second.is_null(), "");
|
||||
astAssert(member(srcPair.second,"nodeType") == "SourceUnit", "The 'nodeType' of the highest node must be 'SourceUnit'.");
|
||||
m_sourceUnits[srcPair.first] = createSourceUnit(srcPair.second, srcPair.first);
|
||||
}
|
||||
@ -72,11 +72,11 @@ map<string, ASTPointer<SourceUnit>> ASTJsonImporter::jsonToSourceUnit(map<string
|
||||
|
||||
// =========== general creation functions ==============
|
||||
template <typename T, typename... Args>
|
||||
ASTPointer<T> ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&... _args)
|
||||
ASTPointer<T> ASTJsonImporter::createASTNode(Json const& _node, Args&&... _args)
|
||||
{
|
||||
astAssert(member(_node, "id").isInt64(), "'id'-field must be 64bit integer.");
|
||||
astAssert(member(_node, "id").is_number_integer(), "'id'-field must be 64bit integer.");
|
||||
|
||||
int64_t id = _node["id"].asInt64();
|
||||
int64_t id = static_cast<Json::number_integer_t>(_node["id"]);
|
||||
|
||||
astAssert(m_usedIDs.insert(id).second, "Found duplicate node ID!");
|
||||
|
||||
@ -88,36 +88,36 @@ ASTPointer<T> ASTJsonImporter::createASTNode(Json::Value const& _node, Args&&...
|
||||
return n;
|
||||
}
|
||||
|
||||
SourceLocation const ASTJsonImporter::createSourceLocation(Json::Value const& _node)
|
||||
SourceLocation const ASTJsonImporter::createSourceLocation(Json const& _node)
|
||||
{
|
||||
astAssert(member(_node, "src").isString(), "'src' must be a string");
|
||||
astAssert(member(_node, "src").is_string(), "'src' must be a string");
|
||||
|
||||
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
|
||||
return solidity::langutil::parseSourceLocation(_node["src"].get<string>(), m_sourceNames);
|
||||
}
|
||||
|
||||
optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json::Value const& _node) const
|
||||
optional<vector<SourceLocation>> ASTJsonImporter::createSourceLocations(Json const& _node) const
|
||||
{
|
||||
vector<SourceLocation> locations;
|
||||
|
||||
if (_node.isMember("nameLocations") && _node["nameLocations"].isArray())
|
||||
if (_node.contains("nameLocations") && _node["nameLocations"].is_array())
|
||||
{
|
||||
for (auto const& val: _node["nameLocations"])
|
||||
locations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames));
|
||||
locations.emplace_back(langutil::parseSourceLocation(val.get<string>(), m_sourceNames));
|
||||
return locations;
|
||||
}
|
||||
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
SourceLocation ASTJsonImporter::createNameSourceLocation(Json::Value const& _node)
|
||||
SourceLocation ASTJsonImporter::createNameSourceLocation(Json const& _node)
|
||||
{
|
||||
astAssert(member(_node, "nameLocation").isString(), "'nameLocation' must be a string");
|
||||
astAssert(member(_node, "nameLocation").is_string(), "'nameLocation' must be a string");
|
||||
|
||||
return solidity::langutil::parseSourceLocation(_node["nameLocation"].asString(), m_sourceNames);
|
||||
return solidity::langutil::parseSourceLocation(_node["nameLocation"].get<string>(), m_sourceNames);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
ASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node)
|
||||
ASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json const& _node)
|
||||
{
|
||||
ASTPointer<T> ret = dynamic_pointer_cast<T>(convertJsonToASTNode(_node));
|
||||
astAssert(ret, "cast of converted json-node must not be nullptr");
|
||||
@ -125,10 +125,10 @@ ASTPointer<T> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node)
|
||||
}
|
||||
|
||||
|
||||
ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _json)
|
||||
ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json const& _json)
|
||||
{
|
||||
astAssert(_json["nodeType"].isString() && _json.isMember("id"), "JSON-Node needs to have 'nodeType' and 'id' fields.");
|
||||
string nodeType = _json["nodeType"].asString();
|
||||
astAssert(_json["nodeType"].is_string() && _json.contains("id"), "JSON-Node needs to have 'nodeType' and 'id' fields.");
|
||||
string nodeType = _json["nodeType"].get<string>();
|
||||
if (nodeType == "PragmaDirective")
|
||||
return createPragmaDirective(_json);
|
||||
if (nodeType == "ImportDirective")
|
||||
@ -250,11 +250,11 @@ ASTPointer<ASTNode> ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js
|
||||
|
||||
// ============ functions to instantiate the AST-Nodes from Json-Nodes ==============
|
||||
|
||||
ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _node, string const& _srcName)
|
||||
ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json const& _node, string const& _srcName)
|
||||
{
|
||||
optional<string> license;
|
||||
if (_node.isMember("license") && !_node["license"].isNull())
|
||||
license = _node["license"].asString();
|
||||
if (_node.contains("license") && !_node["license"].is_null())
|
||||
license = _node["license"].get<string>();
|
||||
|
||||
vector<ASTPointer<ASTNode>> nodes;
|
||||
for (auto& child: member(_node, "nodes"))
|
||||
@ -265,20 +265,20 @@ ASTPointer<SourceUnit> ASTJsonImporter::createSourceUnit(Json::Value const& _nod
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ASTPointer<PragmaDirective> ASTJsonImporter::createPragmaDirective(Json::Value const& _node)
|
||||
ASTPointer<PragmaDirective> ASTJsonImporter::createPragmaDirective(Json const& _node)
|
||||
{
|
||||
vector<Token> tokens;
|
||||
vector<ASTString> literals;
|
||||
for (auto const& lit: member(_node, "literals"))
|
||||
{
|
||||
string l = lit.asString();
|
||||
string l = lit.get<string>();
|
||||
literals.push_back(l);
|
||||
tokens.push_back(scanSingleToken(l));
|
||||
}
|
||||
return createASTNode<PragmaDirective>(_node, tokens, literals);
|
||||
}
|
||||
|
||||
ASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json::Value const& _node)
|
||||
ASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json const& _node)
|
||||
{
|
||||
ASTPointer<ASTString> unitAlias = memberAsASTString(_node, "unitAlias");
|
||||
ASTPointer<ASTString> path = memberAsASTString(_node, "file");
|
||||
@ -286,11 +286,11 @@ ASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json::Value c
|
||||
|
||||
for (auto& tuple: member(_node, "symbolAliases"))
|
||||
{
|
||||
astAssert(tuple["local"].isNull() || tuple["local"].isString(), "expected 'local' to be a string or null!");
|
||||
astAssert(tuple["local"].is_null() || tuple["local"].is_string(), "expected 'local' to be a string or null!");
|
||||
|
||||
symbolAliases.push_back({
|
||||
createIdentifier(tuple["foreign"]),
|
||||
tuple["local"].isNull() ? nullptr : make_shared<ASTString>(tuple["local"].asString()),
|
||||
tuple["local"].is_null() ? nullptr : make_shared<ASTString>(tuple["local"].get<string>()),
|
||||
createSourceLocation(tuple["foreign"])}
|
||||
);
|
||||
}
|
||||
@ -302,15 +302,15 @@ ASTPointer<ImportDirective> ASTJsonImporter::createImportDirective(Json::Value c
|
||||
std::move(symbolAliases)
|
||||
);
|
||||
|
||||
astAssert(_node["absolutePath"].isString(), "Expected 'absolutePath' to be a string!");
|
||||
astAssert(_node["absolutePath"].is_string(), "Expected 'absolutePath' to be a string!");
|
||||
|
||||
tmp->annotation().absolutePath = _node["absolutePath"].asString();
|
||||
tmp->annotation().absolutePath = _node["absolutePath"].get<string>();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json::Value const& _node)
|
||||
ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json const& _node)
|
||||
{
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
astAssert(_node["name"].is_string(), "Expected 'name' to be a string!");
|
||||
|
||||
std::vector<ASTPointer<InheritanceSpecifier>> baseContracts;
|
||||
|
||||
@ -324,9 +324,9 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json::V
|
||||
|
||||
return createASTNode<ContractDefinition>(
|
||||
_node,
|
||||
make_shared<ASTString>(_node["name"].asString()),
|
||||
make_shared<ASTString>(_node["name"].get<string>()),
|
||||
createNameSourceLocation(_node),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
baseContracts,
|
||||
subNodes,
|
||||
contractKind(_node),
|
||||
@ -334,14 +334,14 @@ ASTPointer<ContractDefinition> ASTJsonImporter::createContractDefinition(Json::V
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value const& _node)
|
||||
ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json const& _node)
|
||||
{
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
astAssert(_node["name"].is_string(), "Expected 'name' to be a string!");
|
||||
|
||||
vector<ASTString> namePath;
|
||||
vector<SourceLocation> namePathLocations;
|
||||
vector<string> strs;
|
||||
string nameString = member(_node, "name").asString();
|
||||
string nameString = member(_node, "name").get<string>();
|
||||
boost::algorithm::split(strs, nameString, boost::is_any_of("."));
|
||||
astAssert(!strs.empty(), "Expected at least one element in IdentifierPath.");
|
||||
for (string s: strs)
|
||||
@ -350,9 +350,9 @@ ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value con
|
||||
namePath.emplace_back(s);
|
||||
}
|
||||
|
||||
if (_node.isMember("nameLocations") && _node["nameLocations"].isArray())
|
||||
if (_node.contains("nameLocations") && _node["nameLocations"].is_array())
|
||||
for (auto const& val: _node["nameLocations"])
|
||||
namePathLocations.emplace_back(langutil::parseSourceLocation(val.asString(), m_sourceNames));
|
||||
namePathLocations.emplace_back(langutil::parseSourceLocation(val.get<string>(), m_sourceNames));
|
||||
else
|
||||
namePathLocations.resize(namePath.size());
|
||||
|
||||
@ -368,7 +368,7 @@ ASTPointer<IdentifierPath> ASTJsonImporter::createIdentifierPath(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json::Value const& _node)
|
||||
ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
for (auto& arg: member(_node, "arguments"))
|
||||
@ -376,29 +376,29 @@ ASTPointer<InheritanceSpecifier> ASTJsonImporter::createInheritanceSpecifier(Jso
|
||||
return createASTNode<InheritanceSpecifier>(
|
||||
_node,
|
||||
createIdentifierPath(member(_node, "baseName")),
|
||||
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
member(_node, "arguments").is_null() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json::Value const& _node)
|
||||
ASTPointer<UsingForDirective> ASTJsonImporter::createUsingForDirective(Json const& _node)
|
||||
{
|
||||
vector<ASTPointer<IdentifierPath>> functions;
|
||||
if (_node.isMember("libraryName"))
|
||||
if (_node.contains("libraryName"))
|
||||
functions.emplace_back(createIdentifierPath(_node["libraryName"]));
|
||||
else if (_node.isMember("functionList"))
|
||||
for (Json::Value const& function: _node["functionList"])
|
||||
else if (_node.contains("functionList"))
|
||||
for (Json const& function: _node["functionList"])
|
||||
functions.emplace_back(createIdentifierPath(function["function"]));
|
||||
|
||||
return createASTNode<UsingForDirective>(
|
||||
_node,
|
||||
std::move(functions),
|
||||
!_node.isMember("libraryName"),
|
||||
_node["typeName"].isNull() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"]),
|
||||
!_node.contains("libraryName"),
|
||||
_node["typeName"].is_null() ? nullptr : convertJsonToASTNode<TypeName>(_node["typeName"]),
|
||||
memberAsBool(_node, "global")
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ASTNode> ASTJsonImporter::createStructDefinition(Json::Value const& _node)
|
||||
ASTPointer<ASTNode> ASTJsonImporter::createStructDefinition(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<VariableDeclaration>> members;
|
||||
for (auto& member: _node["members"])
|
||||
@ -411,7 +411,7 @@ ASTPointer<ASTNode> ASTJsonImporter::createStructDefinition(Json::Value const& _
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<EnumDefinition> ASTJsonImporter::createEnumDefinition(Json::Value const& _node)
|
||||
ASTPointer<EnumDefinition> ASTJsonImporter::createEnumDefinition(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<EnumValue>> members;
|
||||
for (auto& member: _node["members"])
|
||||
@ -424,7 +424,7 @@ ASTPointer<EnumDefinition> ASTJsonImporter::createEnumDefinition(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<EnumValue> ASTJsonImporter::createEnumValue(Json::Value const& _node)
|
||||
ASTPointer<EnumValue> ASTJsonImporter::createEnumValue(Json const& _node)
|
||||
{
|
||||
return createASTNode<EnumValue>(
|
||||
_node,
|
||||
@ -432,7 +432,7 @@ ASTPointer<EnumValue> ASTJsonImporter::createEnumValue(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<UserDefinedValueTypeDefinition> ASTJsonImporter::createUserDefinedValueTypeDefinition(Json::Value const& _node)
|
||||
ASTPointer<UserDefinedValueTypeDefinition> ASTJsonImporter::createUserDefinedValueTypeDefinition(Json const& _node)
|
||||
{
|
||||
return createASTNode<UserDefinedValueTypeDefinition>(
|
||||
_node,
|
||||
@ -442,7 +442,7 @@ ASTPointer<UserDefinedValueTypeDefinition> ASTJsonImporter::createUserDefinedVal
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json::Value const& _node)
|
||||
ASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<VariableDeclaration>> parameters;
|
||||
for (auto& param: _node["parameters"])
|
||||
@ -453,7 +453,7 @@ ASTPointer<ParameterList> ASTJsonImporter::createParameterList(Json::Value const
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json::Value const& _node)
|
||||
ASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<IdentifierPath>> overrides;
|
||||
|
||||
@ -466,13 +466,13 @@ ASTPointer<OverrideSpecifier> ASTJsonImporter::createOverrideSpecifier(Json::Val
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json::Value const& _node)
|
||||
ASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json const& _node)
|
||||
{
|
||||
astAssert(_node["kind"].isString(), "Expected 'kind' to be a string!");
|
||||
astAssert(_node["kind"].is_string(), "Expected 'kind' to be a string!");
|
||||
|
||||
Token kind;
|
||||
bool freeFunction = false;
|
||||
string kindStr = member(_node, "kind").asString();
|
||||
string kindStr = member(_node, "kind").get<string>();
|
||||
|
||||
if (kindStr == "constructor")
|
||||
kind = Token::Constructor;
|
||||
@ -509,8 +509,8 @@ ASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json::V
|
||||
freeFunction,
|
||||
kind,
|
||||
memberAsBool(_node, "virtual"),
|
||||
_node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node["overrides"].is_null() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
createParameterList(member(_node, "parameters")),
|
||||
modifiers,
|
||||
createParameterList(member(_node, "returnParameters")),
|
||||
@ -518,13 +518,13 @@ ASTPointer<FunctionDefinition> ASTJsonImporter::createFunctionDefinition(Json::V
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json::Value const& _node)
|
||||
ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json const& _node)
|
||||
{
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
astAssert(_node["name"].is_string(), "Expected 'name' to be a string!");
|
||||
|
||||
VariableDeclaration::Mutability mutability{};
|
||||
astAssert(member(_node, "mutability").isString(), "'mutability' expected to be string.");
|
||||
string const mutabilityStr = member(_node, "mutability").asString();
|
||||
astAssert(member(_node, "mutability").is_string(), "'mutability' expected to be string.");
|
||||
string const mutabilityStr = member(_node, "mutability").get<string>();
|
||||
if (mutabilityStr == "constant")
|
||||
{
|
||||
mutability = VariableDeclaration::Mutability::Constant;
|
||||
@ -544,33 +544,33 @@ ASTPointer<VariableDeclaration> ASTJsonImporter::createVariableDeclaration(Json:
|
||||
return createASTNode<VariableDeclaration>(
|
||||
_node,
|
||||
nullOrCast<TypeName>(member(_node, "typeName")),
|
||||
make_shared<ASTString>(member(_node, "name").asString()),
|
||||
make_shared<ASTString>(member(_node, "name").get<string>()),
|
||||
createNameSourceLocation(_node),
|
||||
nullOrCast<Expression>(member(_node, "value")),
|
||||
visibility(_node),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node.isMember("indexed") ? memberAsBool(_node, "indexed") : false,
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node.contains("indexed") ? memberAsBool(_node, "indexed") : false,
|
||||
mutability,
|
||||
_node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
_node["overrides"].is_null() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
location(_node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ModifierDefinition> ASTJsonImporter::createModifierDefinition(Json::Value const& _node)
|
||||
ASTPointer<ModifierDefinition> ASTJsonImporter::createModifierDefinition(Json const& _node)
|
||||
{
|
||||
return createASTNode<ModifierDefinition>(
|
||||
_node,
|
||||
memberAsASTString(_node, "name"),
|
||||
createNameSourceLocation(_node),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
createParameterList(member(_node, "parameters")),
|
||||
memberAsBool(_node, "virtual"),
|
||||
_node["overrides"].isNull() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
_node["body"].isNull() ? nullptr: createBlock(member(_node, "body"), false)
|
||||
_node["overrides"].is_null() ? nullptr : createOverrideSpecifier(member(_node, "overrides")),
|
||||
_node["body"].is_null() ? nullptr: createBlock(member(_node, "body"), false)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json::Value const& _node)
|
||||
ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
for (auto& arg: member(_node, "arguments"))
|
||||
@ -578,53 +578,53 @@ ASTPointer<ModifierInvocation> ASTJsonImporter::createModifierInvocation(Json::V
|
||||
return createASTNode<ModifierInvocation>(
|
||||
_node,
|
||||
createIdentifierPath(member(_node, "modifierName")),
|
||||
member(_node, "arguments").isNull() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
member(_node, "arguments").is_null() ? nullptr : make_unique<std::vector<ASTPointer<Expression>>>(arguments)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<EventDefinition> ASTJsonImporter::createEventDefinition(Json::Value const& _node)
|
||||
ASTPointer<EventDefinition> ASTJsonImporter::createEventDefinition(Json const& _node)
|
||||
{
|
||||
return createASTNode<EventDefinition>(
|
||||
_node,
|
||||
memberAsASTString(_node, "name"),
|
||||
createNameSourceLocation(_node),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
createParameterList(member(_node, "parameters")),
|
||||
memberAsBool(_node, "anonymous")
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ErrorDefinition> ASTJsonImporter::createErrorDefinition(Json::Value const& _node)
|
||||
ASTPointer<ErrorDefinition> ASTJsonImporter::createErrorDefinition(Json const& _node)
|
||||
{
|
||||
return createASTNode<ErrorDefinition>(
|
||||
_node,
|
||||
memberAsASTString(_node, "name"),
|
||||
createNameSourceLocation(_node),
|
||||
_node["documentation"].isNull() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
_node["documentation"].is_null() ? nullptr : createDocumentation(member(_node, "documentation")),
|
||||
createParameterList(member(_node, "parameters"))
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ElementaryTypeName> ASTJsonImporter::createElementaryTypeName(Json::Value const& _node)
|
||||
ASTPointer<ElementaryTypeName> ASTJsonImporter::createElementaryTypeName(Json const& _node)
|
||||
{
|
||||
unsigned short firstNum;
|
||||
unsigned short secondNum;
|
||||
|
||||
astAssert(_node["name"].isString(), "Expected 'name' to be a string!");
|
||||
astAssert(_node["name"].is_string(), "Expected 'name' to be a string!");
|
||||
|
||||
string name = member(_node, "name").asString();
|
||||
string name = member(_node, "name").get<string>();
|
||||
Token token;
|
||||
tie(token, firstNum, secondNum) = TokenTraits::fromIdentifierOrKeyword(name);
|
||||
ElementaryTypeNameToken elem(token, firstNum, secondNum);
|
||||
|
||||
std::optional<StateMutability> mutability = {};
|
||||
if (_node.isMember("stateMutability"))
|
||||
if (_node.contains("stateMutability"))
|
||||
mutability = stateMutability(_node);
|
||||
|
||||
return createASTNode<ElementaryTypeName>(_node, elem, mutability);
|
||||
}
|
||||
|
||||
ASTPointer<UserDefinedTypeName> ASTJsonImporter::createUserDefinedTypeName(Json::Value const& _node)
|
||||
ASTPointer<UserDefinedTypeName> ASTJsonImporter::createUserDefinedTypeName(Json const& _node)
|
||||
{
|
||||
return createASTNode<UserDefinedTypeName>(
|
||||
_node,
|
||||
@ -632,7 +632,7 @@ ASTPointer<UserDefinedTypeName> ASTJsonImporter::createUserDefinedTypeName(Json:
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<FunctionTypeName> ASTJsonImporter::createFunctionTypeName(Json::Value const& _node)
|
||||
ASTPointer<FunctionTypeName> ASTJsonImporter::createFunctionTypeName(Json const& _node)
|
||||
{
|
||||
return createASTNode<FunctionTypeName>(
|
||||
_node,
|
||||
@ -643,7 +643,7 @@ ASTPointer<FunctionTypeName> ASTJsonImporter::createFunctionTypeName(Json::Value
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Mapping> ASTJsonImporter::createMapping(Json::Value const& _node)
|
||||
ASTPointer<Mapping> ASTJsonImporter::createMapping(Json const& _node)
|
||||
{
|
||||
return createASTNode<Mapping>(
|
||||
_node,
|
||||
@ -652,7 +652,7 @@ ASTPointer<Mapping> ASTJsonImporter::createMapping(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ArrayTypeName> ASTJsonImporter::createArrayTypeName(Json::Value const& _node)
|
||||
ASTPointer<ArrayTypeName> ASTJsonImporter::createArrayTypeName(Json const& _node)
|
||||
{
|
||||
return createASTNode<ArrayTypeName>(
|
||||
_node,
|
||||
@ -661,24 +661,24 @@ ASTPointer<ArrayTypeName> ASTJsonImporter::createArrayTypeName(Json::Value const
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json::Value const& _node)
|
||||
ASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json const& _node)
|
||||
{
|
||||
astAssert(_node["evmVersion"].isString(), "Expected evmVersion to be a string!");
|
||||
auto evmVersion = langutil::EVMVersion::fromString(_node["evmVersion"].asString());
|
||||
astAssert(_node["evmVersion"].is_string(), "Expected evmVersion to be a string!");
|
||||
auto evmVersion = langutil::EVMVersion::fromString(_node["evmVersion"].get<string>());
|
||||
astAssert(evmVersion.has_value(), "Invalid EVM version!");
|
||||
astAssert(m_evmVersion == evmVersion, "Imported tree evm version differs from configured evm version!");
|
||||
|
||||
yul::Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(evmVersion.value());
|
||||
ASTPointer<vector<ASTPointer<ASTString>>> flags;
|
||||
if (_node.isMember("flags"))
|
||||
if (_node.contains("flags"))
|
||||
{
|
||||
flags = make_shared<vector<ASTPointer<ASTString>>>();
|
||||
Json::Value const& flagsNode = _node["flags"];
|
||||
astAssert(flagsNode.isArray(), "Assembly flags must be an array.");
|
||||
for (Json::ArrayIndex i = 0; i < flagsNode.size(); ++i)
|
||||
Json const& flagsNode = _node["flags"];
|
||||
astAssert(flagsNode.is_array(), "Assembly flags must be an array.");
|
||||
for (Json const& flag: flagsNode)
|
||||
{
|
||||
astAssert(flagsNode[i].isString(), "Assembly flag must be a string.");
|
||||
flags->emplace_back(make_shared<ASTString>(flagsNode[i].asString()));
|
||||
astAssert(flag.is_string(), "Assembly flag must be a string.");
|
||||
flags->emplace_back(make_shared<ASTString>(flag.get<string>()));
|
||||
}
|
||||
}
|
||||
shared_ptr<yul::Block> operations = make_shared<yul::Block>(yul::AsmJsonImporter(m_sourceNames).createBlock(member(_node, "AST")));
|
||||
@ -691,7 +691,7 @@ ASTPointer<InlineAssembly> ASTJsonImporter::createInlineAssembly(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Block> ASTJsonImporter::createBlock(Json::Value const& _node, bool _unchecked)
|
||||
ASTPointer<Block> ASTJsonImporter::createBlock(Json const& _node, bool _unchecked)
|
||||
{
|
||||
std::vector<ASTPointer<Statement>> statements;
|
||||
for (auto& stat: member(_node, "statements"))
|
||||
@ -704,7 +704,7 @@ ASTPointer<Block> ASTJsonImporter::createBlock(Json::Value const& _node, bool _u
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<PlaceholderStatement> ASTJsonImporter::createPlaceholderStatement(Json::Value const& _node)
|
||||
ASTPointer<PlaceholderStatement> ASTJsonImporter::createPlaceholderStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<PlaceholderStatement>(
|
||||
_node,
|
||||
@ -712,7 +712,7 @@ ASTPointer<PlaceholderStatement> ASTJsonImporter::createPlaceholderStatement(Jso
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<IfStatement> ASTJsonImporter::createIfStatement(Json::Value const& _node)
|
||||
ASTPointer<IfStatement> ASTJsonImporter::createIfStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<IfStatement>(
|
||||
_node,
|
||||
@ -723,7 +723,7 @@ ASTPointer<IfStatement> ASTJsonImporter::createIfStatement(Json::Value const& _
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<TryCatchClause> ASTJsonImporter::createTryCatchClause(Json::Value const& _node)
|
||||
ASTPointer<TryCatchClause> ASTJsonImporter::createTryCatchClause(Json const& _node)
|
||||
{
|
||||
return createASTNode<TryCatchClause>(
|
||||
_node,
|
||||
@ -733,7 +733,7 @@ ASTPointer<TryCatchClause> ASTJsonImporter::createTryCatchClause(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<TryStatement> ASTJsonImporter::createTryStatement(Json::Value const& _node)
|
||||
ASTPointer<TryStatement> ASTJsonImporter::createTryStatement(Json const& _node)
|
||||
{
|
||||
vector<ASTPointer<TryCatchClause>> clauses;
|
||||
|
||||
@ -748,7 +748,7 @@ ASTPointer<TryStatement> ASTJsonImporter::createTryStatement(Json::Value const&
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<WhileStatement> ASTJsonImporter::createWhileStatement(Json::Value const& _node, bool _isDoWhile=false)
|
||||
ASTPointer<WhileStatement> ASTJsonImporter::createWhileStatement(Json const& _node, bool _isDoWhile=false)
|
||||
{
|
||||
return createASTNode<WhileStatement>(
|
||||
_node,
|
||||
@ -759,7 +759,7 @@ ASTPointer<WhileStatement> ASTJsonImporter::createWhileStatement(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ForStatement> ASTJsonImporter::createForStatement(Json::Value const& _node)
|
||||
ASTPointer<ForStatement> ASTJsonImporter::createForStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<ForStatement>(
|
||||
_node,
|
||||
@ -771,7 +771,7 @@ ASTPointer<ForStatement> ASTJsonImporter::createForStatement(Json::Value const&
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Continue> ASTJsonImporter::createContinue(Json::Value const& _node)
|
||||
ASTPointer<Continue> ASTJsonImporter::createContinue(Json const& _node)
|
||||
{
|
||||
return createASTNode<Continue>(
|
||||
_node,
|
||||
@ -779,7 +779,7 @@ ASTPointer<Continue> ASTJsonImporter::createContinue(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Break> ASTJsonImporter::createBreak(Json::Value const& _node)
|
||||
ASTPointer<Break> ASTJsonImporter::createBreak(Json const& _node)
|
||||
{
|
||||
return createASTNode<Break>(
|
||||
_node,
|
||||
@ -787,7 +787,7 @@ ASTPointer<Break> ASTJsonImporter::createBreak(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Return> ASTJsonImporter::createReturn(Json::Value const& _node)
|
||||
ASTPointer<Return> ASTJsonImporter::createReturn(Json const& _node)
|
||||
{
|
||||
return createASTNode<Return>(
|
||||
_node,
|
||||
@ -796,7 +796,7 @@ ASTPointer<Return> ASTJsonImporter::createReturn(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Throw> ASTJsonImporter::createThrow(Json::Value const& _node)
|
||||
ASTPointer<Throw> ASTJsonImporter::createThrow(Json const& _node)
|
||||
{
|
||||
return createASTNode<Throw>(
|
||||
_node,
|
||||
@ -804,7 +804,7 @@ ASTPointer<Throw> ASTJsonImporter::createThrow(Json::Value const& _node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<EmitStatement> ASTJsonImporter::createEmitStatement(Json::Value const& _node)
|
||||
ASTPointer<EmitStatement> ASTJsonImporter::createEmitStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<EmitStatement>(
|
||||
_node,
|
||||
@ -813,7 +813,7 @@ ASTPointer<EmitStatement> ASTJsonImporter::createEmitStatement(Json::Value const
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<RevertStatement> ASTJsonImporter::createRevertStatement(Json::Value const& _node)
|
||||
ASTPointer<RevertStatement> ASTJsonImporter::createRevertStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<RevertStatement>(
|
||||
_node,
|
||||
@ -822,11 +822,11 @@ ASTPointer<RevertStatement> ASTJsonImporter::createRevertStatement(Json::Value c
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<VariableDeclarationStatement> ASTJsonImporter::createVariableDeclarationStatement(Json::Value const& _node)
|
||||
ASTPointer<VariableDeclarationStatement> ASTJsonImporter::createVariableDeclarationStatement(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<VariableDeclaration>> variables;
|
||||
for (auto& var: member(_node, "declarations"))
|
||||
variables.push_back(var.isNull() ? nullptr : createVariableDeclaration(var)); //unnamed components are empty pointers
|
||||
variables.push_back(var.is_null() ? nullptr : createVariableDeclaration(var)); //unnamed components are empty pointers
|
||||
return createASTNode<VariableDeclarationStatement>(
|
||||
_node,
|
||||
nullOrASTString(_node, "documentation"),
|
||||
@ -835,7 +835,7 @@ ASTPointer<VariableDeclarationStatement> ASTJsonImporter::createVariableDeclarat
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ExpressionStatement> ASTJsonImporter::createExpressionStatement(Json::Value const& _node)
|
||||
ASTPointer<ExpressionStatement> ASTJsonImporter::createExpressionStatement(Json const& _node)
|
||||
{
|
||||
return createASTNode<ExpressionStatement>(
|
||||
_node,
|
||||
@ -844,7 +844,7 @@ ASTPointer<ExpressionStatement> ASTJsonImporter::createExpressionStatement(Json:
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Conditional> ASTJsonImporter::createConditional(Json::Value const& _node)
|
||||
ASTPointer<Conditional> ASTJsonImporter::createConditional(Json const& _node)
|
||||
{
|
||||
return createASTNode<Conditional>(
|
||||
_node,
|
||||
@ -854,7 +854,7 @@ ASTPointer<Conditional> ASTJsonImporter::createConditional(Json::Value const& _
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Assignment> ASTJsonImporter::createAssignment(Json::Value const& _node)
|
||||
ASTPointer<Assignment> ASTJsonImporter::createAssignment(Json const& _node)
|
||||
{
|
||||
return createASTNode<Assignment>(
|
||||
_node,
|
||||
@ -864,7 +864,7 @@ ASTPointer<Assignment> ASTJsonImporter::createAssignment(Json::Value const& _no
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<TupleExpression> ASTJsonImporter::createTupleExpression(Json::Value const& _node)
|
||||
ASTPointer<TupleExpression> ASTJsonImporter::createTupleExpression(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> components;
|
||||
for (auto& comp: member(_node, "components"))
|
||||
@ -876,7 +876,7 @@ ASTPointer<TupleExpression> ASTJsonImporter::createTupleExpression(Json::Value c
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<UnaryOperation> ASTJsonImporter::createUnaryOperation(Json::Value const& _node)
|
||||
ASTPointer<UnaryOperation> ASTJsonImporter::createUnaryOperation(Json const& _node)
|
||||
{
|
||||
return createASTNode<UnaryOperation>(
|
||||
_node,
|
||||
@ -886,7 +886,7 @@ ASTPointer<UnaryOperation> ASTJsonImporter::createUnaryOperation(Json::Value con
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<BinaryOperation> ASTJsonImporter::createBinaryOperation(Json::Value const& _node)
|
||||
ASTPointer<BinaryOperation> ASTJsonImporter::createBinaryOperation(Json const& _node)
|
||||
{
|
||||
return createASTNode<BinaryOperation>(
|
||||
_node,
|
||||
@ -896,7 +896,7 @@ ASTPointer<BinaryOperation> ASTJsonImporter::createBinaryOperation(Json::Value c
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const& _node)
|
||||
ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
for (auto& arg: member(_node, "arguments"))
|
||||
@ -904,8 +904,8 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
|
||||
std::vector<ASTPointer<ASTString>> names;
|
||||
for (auto& name: member(_node, "names"))
|
||||
{
|
||||
astAssert(name.isString(), "Expected 'names' members to be strings!");
|
||||
names.push_back(make_shared<ASTString>(name.asString()));
|
||||
astAssert(name.is_string(), "Expected 'names' members to be strings!");
|
||||
names.push_back(make_shared<ASTString>(name.get<string>()));
|
||||
}
|
||||
|
||||
optional<vector<SourceLocation>> sourceLocations = createSourceLocations(_node);
|
||||
@ -921,7 +921,7 @@ ASTPointer<FunctionCall> ASTJsonImporter::createFunctionCall(Json::Value const&
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json::Value const& _node)
|
||||
ASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json const& _node)
|
||||
{
|
||||
std::vector<ASTPointer<Expression>> options;
|
||||
for (auto& option: member(_node, "options"))
|
||||
@ -929,8 +929,8 @@ ASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json:
|
||||
std::vector<ASTPointer<ASTString>> names;
|
||||
for (auto& name: member(_node, "names"))
|
||||
{
|
||||
astAssert(name.isString(), "Expected 'names' members to be strings!");
|
||||
names.push_back(make_shared<ASTString>(name.asString()));
|
||||
astAssert(name.is_string(), "Expected 'names' members to be strings!");
|
||||
names.push_back(make_shared<ASTString>(name.get<string>()));
|
||||
}
|
||||
|
||||
return createASTNode<FunctionCallOptions>(
|
||||
@ -941,7 +941,7 @@ ASTPointer<FunctionCallOptions> ASTJsonImporter::createFunctionCallOptions(Json:
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<NewExpression> ASTJsonImporter::createNewExpression(Json::Value const& _node)
|
||||
ASTPointer<NewExpression> ASTJsonImporter::createNewExpression(Json const& _node)
|
||||
{
|
||||
return createASTNode<NewExpression>(
|
||||
_node,
|
||||
@ -949,11 +949,11 @@ ASTPointer<NewExpression> ASTJsonImporter::createNewExpression(Json::Value const
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<MemberAccess> ASTJsonImporter::createMemberAccess(Json::Value const& _node)
|
||||
ASTPointer<MemberAccess> ASTJsonImporter::createMemberAccess(Json const& _node)
|
||||
{
|
||||
SourceLocation memberLocation;
|
||||
if (member(_node, "memberLocation").isString())
|
||||
memberLocation = solidity::langutil::parseSourceLocation(_node["memberLocation"].asString(), m_sourceNames);
|
||||
if (member(_node, "memberLocation").is_string())
|
||||
memberLocation = solidity::langutil::parseSourceLocation(_node["memberLocation"].get<string>(), m_sourceNames);
|
||||
|
||||
return createASTNode<MemberAccess>(
|
||||
_node,
|
||||
@ -963,7 +963,7 @@ ASTPointer<MemberAccess> ASTJsonImporter::createMemberAccess(Json::Value const&
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<IndexAccess> ASTJsonImporter::createIndexAccess(Json::Value const& _node)
|
||||
ASTPointer<IndexAccess> ASTJsonImporter::createIndexAccess(Json const& _node)
|
||||
{
|
||||
return createASTNode<IndexAccess>(
|
||||
_node,
|
||||
@ -972,7 +972,7 @@ ASTPointer<IndexAccess> ASTJsonImporter::createIndexAccess(Json::Value const& _n
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<IndexRangeAccess> ASTJsonImporter::createIndexRangeAccess(Json::Value const& _node)
|
||||
ASTPointer<IndexRangeAccess> ASTJsonImporter::createIndexRangeAccess(Json const& _node)
|
||||
{
|
||||
return createASTNode<IndexRangeAccess>(
|
||||
_node,
|
||||
@ -982,12 +982,12 @@ ASTPointer<IndexRangeAccess> ASTJsonImporter::createIndexRangeAccess(Json::Value
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<Identifier> ASTJsonImporter::createIdentifier(Json::Value const& _node)
|
||||
ASTPointer<Identifier> ASTJsonImporter::createIdentifier(Json const& _node)
|
||||
{
|
||||
return createASTNode<Identifier>(_node, memberAsASTString(_node, "name"));
|
||||
}
|
||||
|
||||
ASTPointer<ElementaryTypeNameExpression> ASTJsonImporter::createElementaryTypeNameExpression(Json::Value const& _node)
|
||||
ASTPointer<ElementaryTypeNameExpression> ASTJsonImporter::createElementaryTypeNameExpression(Json const& _node)
|
||||
{
|
||||
return createASTNode<ElementaryTypeNameExpression>(
|
||||
_node,
|
||||
@ -995,116 +995,116 @@ ASTPointer<ElementaryTypeNameExpression> ASTJsonImporter::createElementaryTypeNa
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<ASTNode> ASTJsonImporter::createLiteral(Json::Value const& _node)
|
||||
ASTPointer<ASTNode> ASTJsonImporter::createLiteral(Json const& _node)
|
||||
{
|
||||
static string const valStr = "value";
|
||||
static string const hexValStr = "hexValue";
|
||||
|
||||
astAssert(member(_node, valStr).isString() || member(_node, hexValStr).isString(), "Literal-value is unset.");
|
||||
astAssert(member(_node, valStr).is_string() || member(_node, hexValStr).is_string(), "Literal-value is unset.");
|
||||
|
||||
ASTPointer<ASTString> value = _node.isMember(hexValStr) ?
|
||||
make_shared<ASTString>(util::asString(util::fromHex(_node[hexValStr].asString()))) :
|
||||
make_shared<ASTString>(_node[valStr].asString());
|
||||
ASTPointer<ASTString> value = _node.contains(hexValStr) ?
|
||||
make_shared<ASTString>(util::asString(util::fromHex(_node[hexValStr].get<string>()))) :
|
||||
make_shared<ASTString>(_node[valStr].get<string>());
|
||||
|
||||
return createASTNode<Literal>(
|
||||
_node,
|
||||
literalTokenKind(_node),
|
||||
value,
|
||||
member(_node, "subdenomination").isNull() ? Literal::SubDenomination::None : subdenomination(_node)
|
||||
member(_node, "subdenomination").is_null() ? Literal::SubDenomination::None : subdenomination(_node)
|
||||
);
|
||||
}
|
||||
|
||||
ASTPointer<StructuredDocumentation> ASTJsonImporter::createDocumentation(Json::Value const& _node)
|
||||
ASTPointer<StructuredDocumentation> ASTJsonImporter::createDocumentation(Json const& _node)
|
||||
{
|
||||
static string const textString = "text";
|
||||
|
||||
astAssert(member(_node, textString).isString(), "'text' must be a string");
|
||||
astAssert(member(_node, textString).is_string(), "'text' must be a string");
|
||||
|
||||
return createASTNode<StructuredDocumentation>(
|
||||
_node,
|
||||
make_shared<ASTString>(_node[textString].asString())
|
||||
make_shared<ASTString>(_node[textString].get<string>())
|
||||
);
|
||||
}
|
||||
|
||||
// ===== helper functions ==========
|
||||
|
||||
Json::Value ASTJsonImporter::member(Json::Value const& _node, string const& _name)
|
||||
Json ASTJsonImporter::member(Json const& _node, string const& _name)
|
||||
{
|
||||
if (!_node.isMember(_name))
|
||||
return Json::nullValue;
|
||||
if (!_node.contains(_name))
|
||||
return Json{};
|
||||
return _node[_name];
|
||||
}
|
||||
|
||||
Token ASTJsonImporter::scanSingleToken(Json::Value const& _node)
|
||||
Token ASTJsonImporter::scanSingleToken(Json const& _node)
|
||||
{
|
||||
langutil::CharStream charStream(_node.asString(), "");
|
||||
langutil::CharStream charStream(_node.get<string>(), "");
|
||||
langutil::Scanner scanner{charStream};
|
||||
astAssert(scanner.peekNextToken() == Token::EOS, "Token string is too long.");
|
||||
return scanner.currentToken();
|
||||
}
|
||||
|
||||
ASTPointer<ASTString> ASTJsonImporter::nullOrASTString(Json::Value const& _json, string const& _name)
|
||||
ASTPointer<ASTString> ASTJsonImporter::nullOrASTString(Json const& _json, string const& _name)
|
||||
{
|
||||
return _json[_name].isString() ? memberAsASTString(_json, _name) : nullptr;
|
||||
return _json[_name].is_string() ? memberAsASTString(_json, _name) : nullptr;
|
||||
}
|
||||
|
||||
ASTPointer<ASTString> ASTJsonImporter::memberAsASTString(Json::Value const& _node, string const& _name)
|
||||
ASTPointer<ASTString> ASTJsonImporter::memberAsASTString(Json const& _node, string const& _name)
|
||||
{
|
||||
Json::Value value = member(_node, _name);
|
||||
astAssert(value.isString(), "field " + _name + " must be of type string.");
|
||||
return make_shared<ASTString>(_node[_name].asString());
|
||||
Json value = member(_node, _name);
|
||||
astAssert(value.is_string(), "field " + _name + " must be of type string.");
|
||||
return make_shared<ASTString>(_node[_name].get<string>());
|
||||
}
|
||||
|
||||
bool ASTJsonImporter::memberAsBool(Json::Value const& _node, string const& _name)
|
||||
bool ASTJsonImporter::memberAsBool(Json const& _node, string const& _name)
|
||||
{
|
||||
Json::Value value = member(_node, _name);
|
||||
astAssert(value.isBool(), "field " + _name + " must be of type boolean.");
|
||||
return _node[_name].asBool();
|
||||
Json value = member(_node, _name);
|
||||
astAssert(value.is_boolean(), "field " + _name + " must be of type boolean.");
|
||||
return _node[_name].get<bool>();
|
||||
}
|
||||
|
||||
|
||||
// =========== JSON to definition helpers =======================
|
||||
|
||||
ContractKind ASTJsonImporter::contractKind(Json::Value const& _node)
|
||||
ContractKind ASTJsonImporter::contractKind(Json const& _node)
|
||||
{
|
||||
ContractKind kind;
|
||||
astAssert(!member(_node, "contractKind").isNull(), "'Contract-kind' can not be null.");
|
||||
if (_node["contractKind"].asString() == "interface")
|
||||
astAssert(!member(_node, "contractKind").is_null(), "'Contract-kind' can not be null.");
|
||||
if (_node["contractKind"].get<string>() == "interface")
|
||||
kind = ContractKind::Interface;
|
||||
else if (_node["contractKind"].asString() == "contract")
|
||||
else if (_node["contractKind"].get<string>() == "contract")
|
||||
kind = ContractKind::Contract;
|
||||
else if (_node["contractKind"].asString() == "library")
|
||||
else if (_node["contractKind"].get<string>() == "library")
|
||||
kind = ContractKind::Library;
|
||||
else
|
||||
astAssert(false, "Unknown ContractKind");
|
||||
return kind;
|
||||
}
|
||||
|
||||
Token ASTJsonImporter::literalTokenKind(Json::Value const& _node)
|
||||
Token ASTJsonImporter::literalTokenKind(Json const& _node)
|
||||
{
|
||||
astAssert(member(_node, "kind").isString(), "Token-'kind' expected to be a string.");
|
||||
astAssert(member(_node, "kind").is_string(), "Token-'kind' expected to be a string.");
|
||||
Token tok;
|
||||
if (_node["kind"].asString() == "number")
|
||||
if (_node["kind"].get<string>() == "number")
|
||||
tok = Token::Number;
|
||||
else if (_node["kind"].asString() == "string")
|
||||
else if (_node["kind"].get<string>() == "string")
|
||||
tok = Token::StringLiteral;
|
||||
else if (_node["kind"].asString() == "unicodeString")
|
||||
else if (_node["kind"].get<string>() == "unicodeString")
|
||||
tok = Token::UnicodeStringLiteral;
|
||||
else if (_node["kind"].asString() == "hexString")
|
||||
else if (_node["kind"].get<string>() == "hexString")
|
||||
tok = Token::HexStringLiteral;
|
||||
else if (_node["kind"].asString() == "bool")
|
||||
tok = (member(_node, "value").asString() == "true") ? Token::TrueLiteral : Token::FalseLiteral;
|
||||
else if (_node["kind"].get<string>() == "bool")
|
||||
tok = (member(_node, "value").get<string>() == "true") ? Token::TrueLiteral : Token::FalseLiteral;
|
||||
else
|
||||
astAssert(false, "Unknown kind of literalString");
|
||||
return tok;
|
||||
}
|
||||
|
||||
Visibility ASTJsonImporter::visibility(Json::Value const& _node)
|
||||
Visibility ASTJsonImporter::visibility(Json const& _node)
|
||||
{
|
||||
Json::Value visibility = member(_node, "visibility");
|
||||
astAssert(visibility.isString(), "'visibility' expected to be a string.");
|
||||
Json visibility = member(_node, "visibility");
|
||||
astAssert(visibility.is_string(), "'visibility' expected to be a string.");
|
||||
|
||||
string const visibilityStr = visibility.asString();
|
||||
string const visibilityStr = visibility.get<string>();
|
||||
|
||||
if (visibilityStr == "default")
|
||||
return Visibility::Default;
|
||||
@ -1123,12 +1123,12 @@ Visibility ASTJsonImporter::visibility(Json::Value const& _node)
|
||||
util::unreachable();
|
||||
}
|
||||
|
||||
VariableDeclaration::Location ASTJsonImporter::location(Json::Value const& _node)
|
||||
VariableDeclaration::Location ASTJsonImporter::location(Json const& _node)
|
||||
{
|
||||
Json::Value storageLoc = member(_node, "storageLocation");
|
||||
astAssert(storageLoc.isString(), "'storageLocation' expected to be a string.");
|
||||
Json storageLoc = member(_node, "storageLocation");
|
||||
astAssert(storageLoc.is_string(), "'storageLocation' expected to be a string.");
|
||||
|
||||
string const storageLocStr = storageLoc.asString();
|
||||
string const storageLocStr = storageLoc.get<string>();
|
||||
|
||||
if (storageLocStr == "default")
|
||||
return VariableDeclaration::Location::Unspecified;
|
||||
@ -1145,16 +1145,16 @@ VariableDeclaration::Location ASTJsonImporter::location(Json::Value const& _node
|
||||
util::unreachable();
|
||||
}
|
||||
|
||||
Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _node)
|
||||
Literal::SubDenomination ASTJsonImporter::subdenomination(Json const& _node)
|
||||
{
|
||||
Json::Value subDen = member(_node, "subdenomination");
|
||||
Json subDen = member(_node, "subdenomination");
|
||||
|
||||
if (subDen.isNull())
|
||||
if (subDen.is_null())
|
||||
return Literal::SubDenomination::None;
|
||||
|
||||
astAssert(subDen.isString(), "'subDenomination' expected to be string.");
|
||||
astAssert(subDen.is_string(), "'subDenomination' expected to be string.");
|
||||
|
||||
string const subDenStr = subDen.asString();
|
||||
string const subDenStr = subDen.get<string>();
|
||||
|
||||
if (subDenStr == "wei")
|
||||
return Literal::SubDenomination::Wei;
|
||||
@ -1181,10 +1181,10 @@ Literal::SubDenomination ASTJsonImporter::subdenomination(Json::Value const& _no
|
||||
util::unreachable();
|
||||
}
|
||||
|
||||
StateMutability ASTJsonImporter::stateMutability(Json::Value const& _node)
|
||||
StateMutability ASTJsonImporter::stateMutability(Json const& _node)
|
||||
{
|
||||
astAssert(member(_node, "stateMutability").isString(), "StateMutability' expected to be string.");
|
||||
string const mutabilityStr = member(_node, "stateMutability").asString();
|
||||
astAssert(member(_node, "stateMutability").is_string(), "StateMutability' expected to be string.");
|
||||
string const mutabilityStr = member(_node, "stateMutability").get<string>();
|
||||
|
||||
if (mutabilityStr == "pure")
|
||||
return StateMutability::Pure;
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <json/json.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolidity/ast/ASTAnnotations.h>
|
||||
#include <liblangutil/EVMVersion.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
@ -47,7 +47,7 @@ public:
|
||||
/// Converts the AST from JSON-format to ASTPointer
|
||||
/// @a _sourceList used to provide source names for the ASTs
|
||||
/// @returns map of sourcenames to their respective ASTs
|
||||
std::map<std::string, ASTPointer<SourceUnit>> jsonToSourceUnit(std::map<std::string, Json::Value> const& _sourceList);
|
||||
std::map<std::string, ASTPointer<SourceUnit>> jsonToSourceUnit(std::map<std::string, Json> const& _sourceList);
|
||||
|
||||
private:
|
||||
|
||||
@ -56,101 +56,101 @@ private:
|
||||
/// Sets the source location and nodeID
|
||||
/// @returns the ASTNode Object class of the respective JSON node,
|
||||
template <typename T, typename... Args>
|
||||
ASTPointer<T> createASTNode(Json::Value const& _node, Args&&... _args);
|
||||
ASTPointer<T> createASTNode(Json const& _node, Args&&... _args);
|
||||
/// @returns the sourceLocation-object created from the string in the JSON node
|
||||
langutil::SourceLocation const createSourceLocation(Json::Value const& _node);
|
||||
std::optional<std::vector<langutil::SourceLocation>> createSourceLocations(Json::Value const& _node) const;
|
||||
langutil::SourceLocation const createSourceLocation(Json const& _node);
|
||||
std::optional<std::vector<langutil::SourceLocation>> createSourceLocations(Json const& _node) const;
|
||||
/// Creates an ASTNode for a given JSON-ast of unknown type
|
||||
/// @returns Pointer to a new created ASTNode
|
||||
ASTPointer<ASTNode> convertJsonToASTNode(Json::Value const& _ast);
|
||||
ASTPointer<ASTNode> convertJsonToASTNode(Json const& _ast);
|
||||
/// @returns a pointer to the more specific subclass of ASTNode
|
||||
/// as indicated by the nodeType field of the json
|
||||
template<class T>
|
||||
ASTPointer<T> convertJsonToASTNode(Json::Value const& _node);
|
||||
ASTPointer<T> convertJsonToASTNode(Json const& _node);
|
||||
|
||||
langutil::SourceLocation createNameSourceLocation(Json::Value const& _node);
|
||||
langutil::SourceLocation createNameSourceLocation(Json const& _node);
|
||||
|
||||
/// \defgroup nodeCreators JSON to AST-Nodes
|
||||
///@{
|
||||
ASTPointer<SourceUnit> createSourceUnit(Json::Value const& _node, std::string const& _srcName);
|
||||
ASTPointer<PragmaDirective> createPragmaDirective(Json::Value const& _node);
|
||||
ASTPointer<ImportDirective> createImportDirective(Json::Value const& _node);
|
||||
ASTPointer<ContractDefinition> createContractDefinition(Json::Value const& _node);
|
||||
ASTPointer<IdentifierPath> createIdentifierPath(Json::Value const& _node);
|
||||
ASTPointer<InheritanceSpecifier> createInheritanceSpecifier(Json::Value const& _node);
|
||||
ASTPointer<UsingForDirective> createUsingForDirective(Json::Value const& _node);
|
||||
ASTPointer<ASTNode> createStructDefinition(Json::Value const& _node);
|
||||
ASTPointer<EnumDefinition> createEnumDefinition(Json::Value const& _node);
|
||||
ASTPointer<EnumValue> createEnumValue(Json::Value const& _node);
|
||||
ASTPointer<UserDefinedValueTypeDefinition> createUserDefinedValueTypeDefinition(Json::Value const& _node);
|
||||
ASTPointer<ParameterList> createParameterList(Json::Value const& _node);
|
||||
ASTPointer<OverrideSpecifier> createOverrideSpecifier(Json::Value const& _node);
|
||||
ASTPointer<FunctionDefinition> createFunctionDefinition(Json::Value const& _node);
|
||||
ASTPointer<VariableDeclaration> createVariableDeclaration(Json::Value const& _node);
|
||||
ASTPointer<ModifierDefinition> createModifierDefinition(Json::Value const& _node);
|
||||
ASTPointer<ModifierInvocation> createModifierInvocation(Json::Value const& _node);
|
||||
ASTPointer<EventDefinition> createEventDefinition(Json::Value const& _node);
|
||||
ASTPointer<ErrorDefinition> createErrorDefinition(Json::Value const& _node);
|
||||
ASTPointer<ElementaryTypeName> createElementaryTypeName(Json::Value const& _node);
|
||||
ASTPointer<UserDefinedTypeName> createUserDefinedTypeName(Json::Value const& _node);
|
||||
ASTPointer<FunctionTypeName> createFunctionTypeName(Json::Value const& _node);
|
||||
ASTPointer<Mapping> createMapping(Json::Value const& _node);
|
||||
ASTPointer<ArrayTypeName> createArrayTypeName(Json::Value const& _node);
|
||||
ASTPointer<InlineAssembly> createInlineAssembly(Json::Value const& _node);
|
||||
ASTPointer<Block> createBlock(Json::Value const& _node, bool _unchecked);
|
||||
ASTPointer<PlaceholderStatement> createPlaceholderStatement(Json::Value const& _node);
|
||||
ASTPointer<IfStatement> createIfStatement(Json::Value const& _node);
|
||||
ASTPointer<TryCatchClause> createTryCatchClause(Json::Value const& _node);
|
||||
ASTPointer<TryStatement> createTryStatement(Json::Value const& _node);
|
||||
ASTPointer<WhileStatement> createWhileStatement(Json::Value const& _node, bool _isDoWhile);
|
||||
ASTPointer<ForStatement> createForStatement(Json::Value const& _node);
|
||||
ASTPointer<Continue> createContinue(Json::Value const& _node);
|
||||
ASTPointer<Break> createBreak(Json::Value const& _node);
|
||||
ASTPointer<Return> createReturn(Json::Value const& _node);
|
||||
ASTPointer<Throw> createThrow(Json::Value const& _node);
|
||||
ASTPointer<EmitStatement> createEmitStatement(Json::Value const& _node);
|
||||
ASTPointer<RevertStatement> createRevertStatement(Json::Value const& _node);
|
||||
ASTPointer<VariableDeclarationStatement> createVariableDeclarationStatement(Json::Value const& _node);
|
||||
ASTPointer<ExpressionStatement> createExpressionStatement(Json::Value const& _node);
|
||||
ASTPointer<Conditional> createConditional(Json::Value const& _node);
|
||||
ASTPointer<Assignment> createAssignment(Json::Value const& _node);
|
||||
ASTPointer<TupleExpression> createTupleExpression(Json::Value const& _node);
|
||||
ASTPointer<UnaryOperation> createUnaryOperation(Json::Value const& _node);
|
||||
ASTPointer<BinaryOperation> createBinaryOperation(Json::Value const& _node);
|
||||
ASTPointer<FunctionCall> createFunctionCall(Json::Value const& _node);
|
||||
ASTPointer<FunctionCallOptions> createFunctionCallOptions(Json::Value const& _node);
|
||||
ASTPointer<NewExpression> createNewExpression(Json::Value const& _node);
|
||||
ASTPointer<MemberAccess> createMemberAccess(Json::Value const& _node);
|
||||
ASTPointer<IndexAccess> createIndexAccess(Json::Value const& _node);
|
||||
ASTPointer<IndexRangeAccess> createIndexRangeAccess(Json::Value const& _node);
|
||||
ASTPointer<Identifier> createIdentifier(Json::Value const& _node);
|
||||
ASTPointer<ElementaryTypeNameExpression> createElementaryTypeNameExpression(Json::Value const& _node);
|
||||
ASTPointer<ASTNode> createLiteral(Json::Value const& _node);
|
||||
ASTPointer<StructuredDocumentation> createDocumentation(Json::Value const& _node);
|
||||
ASTPointer<SourceUnit> createSourceUnit(Json const& _node, std::string const& _srcName);
|
||||
ASTPointer<PragmaDirective> createPragmaDirective(Json const& _node);
|
||||
ASTPointer<ImportDirective> createImportDirective(Json const& _node);
|
||||
ASTPointer<ContractDefinition> createContractDefinition(Json const& _node);
|
||||
ASTPointer<IdentifierPath> createIdentifierPath(Json const& _node);
|
||||
ASTPointer<InheritanceSpecifier> createInheritanceSpecifier(Json const& _node);
|
||||
ASTPointer<UsingForDirective> createUsingForDirective(Json const& _node);
|
||||
ASTPointer<ASTNode> createStructDefinition(Json const& _node);
|
||||
ASTPointer<EnumDefinition> createEnumDefinition(Json const& _node);
|
||||
ASTPointer<EnumValue> createEnumValue(Json const& _node);
|
||||
ASTPointer<UserDefinedValueTypeDefinition> createUserDefinedValueTypeDefinition(Json const& _node);
|
||||
ASTPointer<ParameterList> createParameterList(Json const& _node);
|
||||
ASTPointer<OverrideSpecifier> createOverrideSpecifier(Json const& _node);
|
||||
ASTPointer<FunctionDefinition> createFunctionDefinition(Json const& _node);
|
||||
ASTPointer<VariableDeclaration> createVariableDeclaration(Json const& _node);
|
||||
ASTPointer<ModifierDefinition> createModifierDefinition(Json const& _node);
|
||||
ASTPointer<ModifierInvocation> createModifierInvocation(Json const& _node);
|
||||
ASTPointer<EventDefinition> createEventDefinition(Json const& _node);
|
||||
ASTPointer<ErrorDefinition> createErrorDefinition(Json const& _node);
|
||||
ASTPointer<ElementaryTypeName> createElementaryTypeName(Json const& _node);
|
||||
ASTPointer<UserDefinedTypeName> createUserDefinedTypeName(Json const& _node);
|
||||
ASTPointer<FunctionTypeName> createFunctionTypeName(Json const& _node);
|
||||
ASTPointer<Mapping> createMapping(Json const& _node);
|
||||
ASTPointer<ArrayTypeName> createArrayTypeName(Json const& _node);
|
||||
ASTPointer<InlineAssembly> createInlineAssembly(Json const& _node);
|
||||
ASTPointer<Block> createBlock(Json const& _node, bool _unchecked);
|
||||
ASTPointer<PlaceholderStatement> createPlaceholderStatement(Json const& _node);
|
||||
ASTPointer<IfStatement> createIfStatement(Json const& _node);
|
||||
ASTPointer<TryCatchClause> createTryCatchClause(Json const& _node);
|
||||
ASTPointer<TryStatement> createTryStatement(Json const& _node);
|
||||
ASTPointer<WhileStatement> createWhileStatement(Json const& _node, bool _isDoWhile);
|
||||
ASTPointer<ForStatement> createForStatement(Json const& _node);
|
||||
ASTPointer<Continue> createContinue(Json const& _node);
|
||||
ASTPointer<Break> createBreak(Json const& _node);
|
||||
ASTPointer<Return> createReturn(Json const& _node);
|
||||
ASTPointer<Throw> createThrow(Json const& _node);
|
||||
ASTPointer<EmitStatement> createEmitStatement(Json const& _node);
|
||||
ASTPointer<RevertStatement> createRevertStatement(Json const& _node);
|
||||
ASTPointer<VariableDeclarationStatement> createVariableDeclarationStatement(Json const& _node);
|
||||
ASTPointer<ExpressionStatement> createExpressionStatement(Json const& _node);
|
||||
ASTPointer<Conditional> createConditional(Json const& _node);
|
||||
ASTPointer<Assignment> createAssignment(Json const& _node);
|
||||
ASTPointer<TupleExpression> createTupleExpression(Json const& _node);
|
||||
ASTPointer<UnaryOperation> createUnaryOperation(Json const& _node);
|
||||
ASTPointer<BinaryOperation> createBinaryOperation(Json const& _node);
|
||||
ASTPointer<FunctionCall> createFunctionCall(Json const& _node);
|
||||
ASTPointer<FunctionCallOptions> createFunctionCallOptions(Json const& _node);
|
||||
ASTPointer<NewExpression> createNewExpression(Json const& _node);
|
||||
ASTPointer<MemberAccess> createMemberAccess(Json const& _node);
|
||||
ASTPointer<IndexAccess> createIndexAccess(Json const& _node);
|
||||
ASTPointer<IndexRangeAccess> createIndexRangeAccess(Json const& _node);
|
||||
ASTPointer<Identifier> createIdentifier(Json const& _node);
|
||||
ASTPointer<ElementaryTypeNameExpression> createElementaryTypeNameExpression(Json const& _node);
|
||||
ASTPointer<ASTNode> createLiteral(Json const& _node);
|
||||
ASTPointer<StructuredDocumentation> createDocumentation(Json const& _node);
|
||||
///@}
|
||||
|
||||
// =============== general helper functions ===================
|
||||
/// @returns the member of a given JSON object, throws if member does not exist
|
||||
Json::Value member(Json::Value const& _node, std::string const& _name);
|
||||
Json member(Json const& _node, std::string const& _name);
|
||||
/// @returns the appropriate TokenObject used in parsed Strings (pragma directive or operator)
|
||||
Token scanSingleToken(Json::Value const& _node);
|
||||
Token scanSingleToken(Json const& _node);
|
||||
template<class T>
|
||||
///@returns nullptr or an ASTPointer cast to a specific Class
|
||||
ASTPointer<T> nullOrCast(Json::Value const& _json);
|
||||
ASTPointer<T> nullOrCast(Json const& _json);
|
||||
/// @returns nullptr or ASTString, given an JSON string or an empty field
|
||||
ASTPointer<ASTString> nullOrASTString(Json::Value const& _json, std::string const& _name);
|
||||
ASTPointer<ASTString> nullOrASTString(Json const& _json, std::string const& _name);
|
||||
|
||||
// ============== JSON to definition helpers ===============
|
||||
/// \defgroup typeHelpers Json to ast-datatype helpers
|
||||
/// {@
|
||||
ASTPointer<ASTString> memberAsASTString(Json::Value const& _node, std::string const& _name);
|
||||
bool memberAsBool(Json::Value const& _node, std::string const& _name);
|
||||
Visibility visibility(Json::Value const& _node);
|
||||
StateMutability stateMutability(Json::Value const& _node);
|
||||
VariableDeclaration::Location location(Json::Value const& _node);
|
||||
ContractKind contractKind(Json::Value const& _node);
|
||||
Token literalTokenKind(Json::Value const& _node);
|
||||
Literal::SubDenomination subdenomination(Json::Value const& _node);
|
||||
ASTPointer<ASTString> memberAsASTString(Json const& _node, std::string const& _name);
|
||||
bool memberAsBool(Json const& _node, std::string const& _name);
|
||||
Visibility visibility(Json const& _node);
|
||||
StateMutability stateMutability(Json const& _node);
|
||||
VariableDeclaration::Location location(Json const& _node);
|
||||
ContractKind contractKind(Json const& _node);
|
||||
Token literalTokenKind(Json const& _node);
|
||||
Literal::SubDenomination subdenomination(Json const& _node);
|
||||
///@}
|
||||
|
||||
// =========== member variables ===============
|
||||
|
@ -39,12 +39,14 @@ bool anyDataStoredInStorage(TypePointers const& _pointers)
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||
Json ABI::generate(ContractDefinition const& _contractDef)
|
||||
{
|
||||
auto compare = [](Json::Value const& _a, Json::Value const& _b) -> bool {
|
||||
return make_tuple(_a["type"], _a["name"]) < make_tuple(_b["type"], _b["name"]);
|
||||
// TODO: consider using nlohmann_json::ordered_json instead
|
||||
auto compare = [](Json const& _a, Json const& _b) -> bool {
|
||||
// NOTE: some cases, like the constructor, don't contain a `name` entry
|
||||
return make_tuple(_a["type"], _a.value("name", Json())) < make_tuple(_b["type"], _b.value("name", Json()));
|
||||
};
|
||||
multiset<Json::Value, decltype(compare)> abi(compare);
|
||||
multiset<Json, decltype(compare)> abi(compare);
|
||||
|
||||
for (auto it: _contractDef.interfaceFunctions())
|
||||
{
|
||||
@ -56,7 +58,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||
|
||||
FunctionType const* externalFunctionType = it.second->interfaceFunctionType();
|
||||
solAssert(!!externalFunctionType, "");
|
||||
Json::Value method{Json::objectValue};
|
||||
Json method{Json::object()};
|
||||
method["type"] = "function";
|
||||
method["name"] = it.second->declaration().name();
|
||||
method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability());
|
||||
@ -80,7 +82,7 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||
FunctionType constrType(*constructor);
|
||||
FunctionType const* externalFunctionType = constrType.interfaceFunctionType();
|
||||
solAssert(!!externalFunctionType, "");
|
||||
Json::Value method{Json::objectValue};
|
||||
Json method{Json::object()};
|
||||
method["type"] = "constructor";
|
||||
method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability());
|
||||
method["inputs"] = formatTypeList(
|
||||
@ -96,25 +98,25 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||
{
|
||||
auto const* externalFunctionType = FunctionType(*fallbackOrReceive).interfaceFunctionType();
|
||||
solAssert(!!externalFunctionType, "");
|
||||
Json::Value method{Json::objectValue};
|
||||
Json method{Json::object()};
|
||||
method["type"] = TokenTraits::toString(fallbackOrReceive->kind());
|
||||
method["stateMutability"] = stateMutabilityToString(externalFunctionType->stateMutability());
|
||||
abi.emplace(std::move(method));
|
||||
}
|
||||
for (auto const& it: _contractDef.definedInterfaceEvents())
|
||||
{
|
||||
Json::Value event{Json::objectValue};
|
||||
Json event{Json::object()};
|
||||
event["type"] = "event";
|
||||
event["name"] = it->name();
|
||||
event["anonymous"] = it->isAnonymous();
|
||||
Json::Value params{Json::arrayValue};
|
||||
Json params{Json::array()};
|
||||
for (auto const& p: it->parameters())
|
||||
{
|
||||
Type const* type = p->annotation().type->interfaceType(false);
|
||||
solAssert(type, "");
|
||||
auto param = formatType(p->name(), *type, *p->annotation().type, false);
|
||||
param["indexed"] = p->isIndexed();
|
||||
params.append(std::move(param));
|
||||
params.emplace_back(param);
|
||||
}
|
||||
event["inputs"] = std::move(params);
|
||||
abi.emplace(std::move(event));
|
||||
@ -122,53 +124,53 @@ Json::Value ABI::generate(ContractDefinition const& _contractDef)
|
||||
|
||||
for (ErrorDefinition const* error: _contractDef.interfaceErrors())
|
||||
{
|
||||
Json::Value errorJson{Json::objectValue};
|
||||
Json errorJson{Json::object()};
|
||||
errorJson["type"] = "error";
|
||||
errorJson["name"] = error->name();
|
||||
errorJson["inputs"] = Json::arrayValue;
|
||||
errorJson["inputs"] = Json::array();
|
||||
for (auto const& p: error->parameters())
|
||||
{
|
||||
Type const* type = p->annotation().type->interfaceType(false);
|
||||
solAssert(type, "");
|
||||
errorJson["inputs"].append(
|
||||
errorJson["inputs"].emplace_back(
|
||||
formatType(p->name(), *type, *p->annotation().type, false)
|
||||
);
|
||||
}
|
||||
abi.emplace(std::move(errorJson));
|
||||
}
|
||||
|
||||
Json::Value abiJson{Json::arrayValue};
|
||||
Json abiJson{Json::array()};
|
||||
for (auto& f: abi)
|
||||
abiJson.append(std::move(f));
|
||||
abiJson.emplace_back(std::move(f));
|
||||
return abiJson;
|
||||
}
|
||||
|
||||
Json::Value ABI::formatTypeList(
|
||||
Json ABI::formatTypeList(
|
||||
vector<string> const& _names,
|
||||
vector<Type const*> const& _encodingTypes,
|
||||
vector<Type const*> const& _solidityTypes,
|
||||
bool _forLibrary
|
||||
)
|
||||
{
|
||||
Json::Value params{Json::arrayValue};
|
||||
Json params{Json::array()};
|
||||
solAssert(_names.size() == _encodingTypes.size(), "Names and types vector size does not match");
|
||||
solAssert(_names.size() == _solidityTypes.size(), "");
|
||||
for (unsigned i = 0; i < _names.size(); ++i)
|
||||
{
|
||||
solAssert(_encodingTypes[i], "");
|
||||
params.append(formatType(_names[i], *_encodingTypes[i], *_solidityTypes[i], _forLibrary));
|
||||
params.emplace_back(formatType(_names[i], *_encodingTypes[i], *_solidityTypes[i], _forLibrary));
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
Json::Value ABI::formatType(
|
||||
Json ABI::formatType(
|
||||
string const& _name,
|
||||
Type const& _encodingType,
|
||||
Type const& _solidityType,
|
||||
bool _forLibrary
|
||||
)
|
||||
{
|
||||
Json::Value ret{Json::objectValue};
|
||||
Json ret{Json::object()};
|
||||
ret["name"] = _name;
|
||||
ret["internalType"] = _solidityType.toString(true);
|
||||
string suffix = (_forLibrary && _encodingType.dataStoredIn(DataLocation::Storage)) ? " storage" : "";
|
||||
@ -186,31 +188,31 @@ Json::Value ABI::formatType(
|
||||
else
|
||||
suffix = string("[") + arrayType->length().str() + "]";
|
||||
solAssert(arrayType->baseType(), "");
|
||||
Json::Value subtype = formatType(
|
||||
Json subtype = formatType(
|
||||
"",
|
||||
*arrayType->baseType(),
|
||||
*dynamic_cast<ArrayType const&>(_solidityType).baseType(),
|
||||
_forLibrary
|
||||
);
|
||||
if (subtype.isMember("components"))
|
||||
if (subtype.contains("components"))
|
||||
{
|
||||
ret["type"] = subtype["type"].asString() + suffix;
|
||||
ret["type"] = subtype["type"].get<string>() + suffix;
|
||||
ret["components"] = subtype["components"];
|
||||
}
|
||||
else
|
||||
ret["type"] = subtype["type"].asString() + suffix;
|
||||
ret["type"] = subtype["type"].get<string>() + suffix;
|
||||
}
|
||||
}
|
||||
else if (StructType const* structType = dynamic_cast<StructType const*>(&_encodingType))
|
||||
{
|
||||
ret["type"] = "tuple";
|
||||
ret["components"] = Json::arrayValue;
|
||||
ret["components"] = Json::array();
|
||||
for (auto const& member: structType->members(nullptr))
|
||||
{
|
||||
solAssert(member.type, "");
|
||||
Type const* t = member.type->interfaceType(_forLibrary);
|
||||
solAssert(t, "");
|
||||
ret["components"].append(formatType(member.name, *t, *member.type, _forLibrary));
|
||||
ret["components"].emplace_back(formatType(member.name, *t, *member.type, _forLibrary));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -21,9 +21,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
@ -38,14 +38,14 @@ public:
|
||||
/// Get the ABI Interface of the contract
|
||||
/// @param _contractDef The contract definition
|
||||
/// @return A JSONrepresentation of the contract's ABI Interface
|
||||
static Json::Value generate(ContractDefinition const& _contractDef);
|
||||
static Json generate(ContractDefinition const& _contractDef);
|
||||
private:
|
||||
/// @returns a json value suitable for a list of types in function input or output
|
||||
/// parameters or other places. If @a _forLibrary is true, complex types are referenced
|
||||
/// by name, otherwise they are anonymously expanded.
|
||||
/// @a _solidityTypes is the list of original Solidity types where @a _encodingTypes is the list of
|
||||
/// ABI types used for the actual encoding.
|
||||
static Json::Value formatTypeList(
|
||||
static Json formatTypeList(
|
||||
std::vector<std::string> const& _names,
|
||||
std::vector<Type const*> const& _encodingTypes,
|
||||
std::vector<Type const*> const& _solidityTypes,
|
||||
@ -56,7 +56,7 @@ private:
|
||||
/// If it is possible to express the type as a single string, it is allowed to return a single string.
|
||||
/// @a _solidityType is the original Solidity type and @a _encodingTypes is the
|
||||
/// ABI type used for the actual encoding.
|
||||
static Json::Value formatType(
|
||||
static Json formatType(
|
||||
std::string const& _name,
|
||||
Type const& _encodingType,
|
||||
Type const& _solidityType,
|
||||
|
@ -77,8 +77,6 @@
|
||||
#include <libsolutil/Algorithms.h>
|
||||
#include <libsolutil/FunctionSelector.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include <range/v3/view/concat.hpp>
|
||||
@ -392,7 +390,7 @@ bool CompilerStack::parse()
|
||||
return !m_hasError;
|
||||
}
|
||||
|
||||
void CompilerStack::importASTs(map<string, Json::Value> const& _sources)
|
||||
void CompilerStack::importASTs(map<string, Json> const& _sources)
|
||||
{
|
||||
if (m_stackState != Empty)
|
||||
solThrow(CompilerError, "Must call importASTs only before the SourcesSet state.");
|
||||
@ -759,18 +757,18 @@ evmasm::AssemblyItems const* CompilerStack::runtimeAssemblyItems(string const& _
|
||||
return currentContract.evmRuntimeAssembly ? ¤tContract.evmRuntimeAssembly->items() : nullptr;
|
||||
}
|
||||
|
||||
Json::Value CompilerStack::generatedSources(string const& _contractName, bool _runtime) const
|
||||
Json CompilerStack::generatedSources(string const& _contractName, bool _runtime) const
|
||||
{
|
||||
if (m_stackState != CompilationSuccessful)
|
||||
solThrow(CompilerError, "Compilation was not successful.");
|
||||
|
||||
Contract const& c = contract(_contractName);
|
||||
util::LazyInit<Json::Value const> const& sources =
|
||||
util::LazyInit<Json const> const& sources =
|
||||
_runtime ?
|
||||
c.runtimeGeneratedSources :
|
||||
c.generatedSources;
|
||||
return sources.init([&]{
|
||||
Json::Value sources{Json::arrayValue};
|
||||
Json sources{Json::array()};
|
||||
// If there is no compiler, then no bytecode was generated and thus no
|
||||
// sources were generated (or we compiled "via IR").
|
||||
if (c.compiler)
|
||||
@ -918,7 +916,7 @@ string CompilerStack::assemblyString(string const& _contractName, StringMap cons
|
||||
}
|
||||
|
||||
/// TODO: cache the JSON
|
||||
Json::Value CompilerStack::assemblyJSON(string const& _contractName) const
|
||||
Json CompilerStack::assemblyJSON(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState != CompilationSuccessful)
|
||||
solThrow(CompilerError, "Compilation was not successful.");
|
||||
@ -927,7 +925,7 @@ Json::Value CompilerStack::assemblyJSON(string const& _contractName) const
|
||||
if (currentContract.evmAssembly)
|
||||
return currentContract.evmAssembly->assemblyJSON(sourceIndices());
|
||||
else
|
||||
return Json::Value();
|
||||
return Json();
|
||||
}
|
||||
|
||||
vector<string> CompilerStack::sourceNames() const
|
||||
@ -949,7 +947,7 @@ map<string, unsigned> CompilerStack::sourceIndices() const
|
||||
return indices;
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::contractABI(string const& _contractName) const
|
||||
Json const& CompilerStack::contractABI(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -957,7 +955,7 @@ Json::Value const& CompilerStack::contractABI(string const& _contractName) const
|
||||
return contractABI(contract(_contractName));
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::contractABI(Contract const& _contract) const
|
||||
Json const& CompilerStack::contractABI(Contract const& _contract) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -967,7 +965,7 @@ Json::Value const& CompilerStack::contractABI(Contract const& _contract) const
|
||||
return _contract.abi.init([&]{ return ABI::generate(*_contract.contract); });
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::storageLayout(string const& _contractName) const
|
||||
Json const& CompilerStack::storageLayout(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -975,7 +973,7 @@ Json::Value const& CompilerStack::storageLayout(string const& _contractName) con
|
||||
return storageLayout(contract(_contractName));
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::storageLayout(Contract const& _contract) const
|
||||
Json const& CompilerStack::storageLayout(Contract const& _contract) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -985,7 +983,7 @@ Json::Value const& CompilerStack::storageLayout(Contract const& _contract) const
|
||||
return _contract.storageLayout.init([&]{ return StorageLayout().generate(*_contract.contract); });
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::natspecUser(string const& _contractName) const
|
||||
Json const& CompilerStack::natspecUser(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -993,7 +991,7 @@ Json::Value const& CompilerStack::natspecUser(string const& _contractName) const
|
||||
return natspecUser(contract(_contractName));
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::natspecUser(Contract const& _contract) const
|
||||
Json const& CompilerStack::natspecUser(Contract const& _contract) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -1003,7 +1001,7 @@ Json::Value const& CompilerStack::natspecUser(Contract const& _contract) const
|
||||
return _contract.userDocumentation.init([&]{ return Natspec::userDocumentation(*_contract.contract); });
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::natspecDev(string const& _contractName) const
|
||||
Json const& CompilerStack::natspecDev(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -1011,7 +1009,7 @@ Json::Value const& CompilerStack::natspecDev(string const& _contractName) const
|
||||
return natspecDev(contract(_contractName));
|
||||
}
|
||||
|
||||
Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const
|
||||
Json const& CompilerStack::natspecDev(Contract const& _contract) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
@ -1021,14 +1019,14 @@ Json::Value const& CompilerStack::natspecDev(Contract const& _contract) const
|
||||
return _contract.devDocumentation.init([&]{ return Natspec::devDocumentation(*_contract.contract); });
|
||||
}
|
||||
|
||||
Json::Value CompilerStack::interfaceSymbols(string const& _contractName) const
|
||||
Json CompilerStack::interfaceSymbols(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState < AnalysisPerformed)
|
||||
solThrow(CompilerError, "Analysis was not successful.");
|
||||
|
||||
Json::Value interfaceSymbols(Json::objectValue);
|
||||
Json interfaceSymbols(Json::object());
|
||||
// Always have a methods object
|
||||
interfaceSymbols["methods"] = Json::objectValue;
|
||||
interfaceSymbols["methods"] = Json::object();
|
||||
|
||||
for (auto const& it: contractDefinition(_contractName).interfaceFunctions())
|
||||
interfaceSymbols["methods"][it.second->externalSignature()] = it.first.hex();
|
||||
@ -1481,7 +1479,7 @@ CompilerStack::Source const& CompilerStack::source(string const& _sourceName) co
|
||||
|
||||
string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) const
|
||||
{
|
||||
Json::Value meta{Json::objectValue};
|
||||
Json meta{Json::object()};
|
||||
meta["version"] = 1;
|
||||
string sourceType;
|
||||
switch (m_compilationSourceType)
|
||||
@ -1502,7 +1500,7 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
for (auto const sourceUnit: _contract.contract->sourceUnit().referencedSourceUnits(true))
|
||||
referencedSources.insert(*sourceUnit->annotation().path);
|
||||
|
||||
meta["sources"] = Json::objectValue;
|
||||
meta["sources"] = Json::object();
|
||||
for (auto const& s: m_sources)
|
||||
{
|
||||
if (!referencedSources.count(s.first))
|
||||
@ -1516,15 +1514,15 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
meta["sources"][s.first]["content"] = s.second.charStream->source();
|
||||
else
|
||||
{
|
||||
meta["sources"][s.first]["urls"] = Json::arrayValue;
|
||||
meta["sources"][s.first]["urls"].append("bzz-raw://" + util::toHex(s.second.swarmHash().asBytes()));
|
||||
meta["sources"][s.first]["urls"].append(s.second.ipfsUrl());
|
||||
meta["sources"][s.first]["urls"] = Json::array();
|
||||
meta["sources"][s.first]["urls"].emplace_back("bzz-raw://" + util::toHex(s.second.swarmHash().asBytes()));
|
||||
meta["sources"][s.first]["urls"].emplace_back(s.second.ipfsUrl());
|
||||
}
|
||||
}
|
||||
|
||||
static_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::LargestUInt), "Invalid word size.");
|
||||
solAssert(static_cast<Json::LargestUInt>(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits<Json::LargestUInt>::max(), "");
|
||||
meta["settings"]["optimizer"]["runs"] = Json::Value(Json::LargestUInt(m_optimiserSettings.expectedExecutionsPerDeployment));
|
||||
static_assert(sizeof(m_optimiserSettings.expectedExecutionsPerDeployment) <= sizeof(Json::number_integer_t), "Invalid word size.");
|
||||
solAssert(static_cast<Json::number_integer_t>(m_optimiserSettings.expectedExecutionsPerDeployment) < std::numeric_limits<Json::number_integer_t>::max(), "");
|
||||
meta["settings"]["optimizer"]["runs"] = Json::number_integer_t(m_optimiserSettings.expectedExecutionsPerDeployment);
|
||||
|
||||
/// Backwards compatibility: If set to one of the default settings, do not provide details.
|
||||
OptimiserSettings settingsWithoutRuns = m_optimiserSettings;
|
||||
@ -1536,7 +1534,7 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
meta["settings"]["optimizer"]["enabled"] = true;
|
||||
else
|
||||
{
|
||||
Json::Value details{Json::objectValue};
|
||||
Json details{Json::object()};
|
||||
|
||||
details["orderLiterals"] = m_optimiserSettings.runOrderLiterals;
|
||||
details["inliner"] = m_optimiserSettings.runInliner;
|
||||
@ -1548,7 +1546,7 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
details["yul"] = m_optimiserSettings.runYulOptimiser;
|
||||
if (m_optimiserSettings.runYulOptimiser)
|
||||
{
|
||||
details["yulDetails"] = Json::objectValue;
|
||||
details["yulDetails"] = Json::object();
|
||||
details["yulDetails"]["stackAllocation"] = m_optimiserSettings.optimizeStackAllocation;
|
||||
details["yulDetails"]["optimizerSteps"] = m_optimiserSettings.yulOptimiserSteps + ":" + m_optimiserSettings.yulOptimiserCleanupSteps;
|
||||
}
|
||||
@ -1574,14 +1572,14 @@ string CompilerStack::createMetadata(Contract const& _contract, bool _forIR) con
|
||||
meta["settings"]["compilationTarget"][_contract.contract->sourceUnitName()] =
|
||||
*_contract.contract->annotation().canonicalName;
|
||||
|
||||
meta["settings"]["remappings"] = Json::arrayValue;
|
||||
meta["settings"]["remappings"] = Json::array();
|
||||
set<string> remappings;
|
||||
for (auto const& r: m_importRemapper.remappings())
|
||||
remappings.insert(r.context + ":" + r.prefix + "=" + r.target);
|
||||
for (auto const& r: remappings)
|
||||
meta["settings"]["remappings"].append(r);
|
||||
meta["settings"]["remappings"].emplace_back(r);
|
||||
|
||||
meta["settings"]["libraries"] = Json::objectValue;
|
||||
meta["settings"]["libraries"] = Json::object();
|
||||
for (auto const& library: m_libraries)
|
||||
meta["settings"]["libraries"][library.first] = "0x" + util::toHex(library.second.asBytes());
|
||||
|
||||
@ -1713,34 +1711,35 @@ bytes CompilerStack::createCBORMetadata(Contract const& _contract, bool _forIR)
|
||||
namespace
|
||||
{
|
||||
|
||||
Json::Value gasToJson(GasEstimator::GasConsumption const& _gas)
|
||||
Json gasToJson(GasEstimator::GasConsumption const& _gas)
|
||||
{
|
||||
if (_gas.isInfinite)
|
||||
return Json::Value("infinite");
|
||||
return Json("infinite");
|
||||
else
|
||||
return Json::Value(util::toString(_gas.value));
|
||||
// TODO use _gas.value.str()?
|
||||
return Json(util::toString(_gas.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Json::Value CompilerStack::gasEstimates(string const& _contractName) const
|
||||
Json CompilerStack::gasEstimates(string const& _contractName) const
|
||||
{
|
||||
if (m_stackState != CompilationSuccessful)
|
||||
solThrow(CompilerError, "Compilation was not successful.");
|
||||
|
||||
if (!assemblyItems(_contractName) && !runtimeAssemblyItems(_contractName))
|
||||
return Json::Value();
|
||||
return Json();
|
||||
|
||||
using Gas = GasEstimator::GasConsumption;
|
||||
GasEstimator gasEstimator(m_evmVersion);
|
||||
Json::Value output(Json::objectValue);
|
||||
Json output(Json::object());
|
||||
|
||||
if (evmasm::AssemblyItems const* items = assemblyItems(_contractName))
|
||||
{
|
||||
Gas executionGas = gasEstimator.functionalEstimation(*items);
|
||||
Gas codeDepositGas{evmasm::GasMeter::dataGas(runtimeObject(_contractName).bytecode, false, m_evmVersion)};
|
||||
|
||||
Json::Value creation(Json::objectValue);
|
||||
Json creation(Json::object());
|
||||
creation["codeDepositCost"] = gasToJson(codeDepositGas);
|
||||
creation["executionCost"] = gasToJson(executionGas);
|
||||
/// TODO: implement + overload to avoid the need of +=
|
||||
@ -1753,7 +1752,7 @@ Json::Value CompilerStack::gasEstimates(string const& _contractName) const
|
||||
{
|
||||
/// External functions
|
||||
ContractDefinition const& contract = contractDefinition(_contractName);
|
||||
Json::Value externalFunctions(Json::objectValue);
|
||||
Json externalFunctions(Json::object());
|
||||
for (auto it: contract.interfaceFunctions())
|
||||
{
|
||||
string sig = it.second->externalSignature();
|
||||
@ -1770,7 +1769,7 @@ Json::Value CompilerStack::gasEstimates(string const& _contractName) const
|
||||
output["external"] = externalFunctions;
|
||||
|
||||
/// Internal functions
|
||||
Json::Value internalFunctions(Json::objectValue);
|
||||
Json internalFunctions(Json::object());
|
||||
for (auto const& it: contract.definedFunctions())
|
||||
{
|
||||
/// Exclude externally visible functions, constructor, fallback and receive ether function
|
||||
|
@ -45,10 +45,9 @@
|
||||
|
||||
#include <libsolutil/Common.h>
|
||||
#include <libsolutil/FixedHash.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libsolutil/LazyInit.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
@ -227,7 +226,7 @@ public:
|
||||
|
||||
/// Imports given SourceUnits so they can be analyzed. Leads to the same internal state as parse().
|
||||
/// Will throw errors if the import fails
|
||||
void importASTs(std::map<std::string, Json::Value> const& _sources);
|
||||
void importASTs(std::map<std::string, Json> const& _sources);
|
||||
|
||||
/// Performs the analysis steps (imports, scopesetting, syntaxCheck, referenceResolving,
|
||||
/// typechecking, staticAnalysis) on previously parsed sources.
|
||||
@ -298,7 +297,7 @@ public:
|
||||
|
||||
/// @returns an array containing all utility sources generated during compilation.
|
||||
/// Format: [ { name: string, id: number, language: "Yul", contents: string }, ... ]
|
||||
Json::Value generatedSources(std::string const& _contractName, bool _runtime = false) const;
|
||||
Json generatedSources(std::string const& _contractName, bool _runtime = false) const;
|
||||
|
||||
/// @returns the string that provides a mapping between bytecode and sourcecode or a nullptr
|
||||
/// if the contract does not (yet) have bytecode.
|
||||
@ -316,26 +315,26 @@ public:
|
||||
/// @returns a JSON representation of the assembly.
|
||||
/// @arg _sourceCodes is the map of input files to source code strings
|
||||
/// Prerequisite: Successful compilation.
|
||||
Json::Value assemblyJSON(std::string const& _contractName) const;
|
||||
Json assemblyJSON(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a JSON representing the contract ABI.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
Json::Value const& contractABI(std::string const& _contractName) const;
|
||||
Json const& contractABI(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a JSON representing the storage layout of the contract.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
Json::Value const& storageLayout(std::string const& _contractName) const;
|
||||
Json const& storageLayout(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a JSON representing the contract's user documentation.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
Json::Value const& natspecUser(std::string const& _contractName) const;
|
||||
Json const& natspecUser(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a JSON representing the contract's developer documentation.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
Json::Value const& natspecDev(std::string const& _contractName) const;
|
||||
Json const& natspecDev(std::string const& _contractName) const;
|
||||
|
||||
/// @returns a JSON object with the three members ``methods``, ``events``, ``errors``. Each is a map, mapping identifiers (hashes) to function names.
|
||||
Json::Value interfaceSymbols(std::string const& _contractName) const;
|
||||
Json interfaceSymbols(std::string const& _contractName) const;
|
||||
|
||||
/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.
|
||||
std::string const& metadata(std::string const& _contractName) const { return metadata(contract(_contractName)); }
|
||||
@ -349,7 +348,7 @@ public:
|
||||
bytes cborMetadata(std::string const& _contractName, bool _forIR) const;
|
||||
|
||||
/// @returns a JSON representing the estimated gas usage for contract creation, internal and external functions
|
||||
Json::Value gasEstimates(std::string const& _contractName) const;
|
||||
Json gasEstimates(std::string const& _contractName) const;
|
||||
|
||||
/// Changes the format of the metadata appended at the end of the bytecode.
|
||||
void setMetadataFormat(MetadataFormat _metadataFormat) { m_metadataFormat = _metadataFormat; }
|
||||
@ -388,12 +387,12 @@ private:
|
||||
std::string ewasm; ///< Experimental Ewasm text representation
|
||||
evmasm::LinkerObject ewasmObject; ///< Experimental Ewasm code
|
||||
util::LazyInit<std::string const> metadata; ///< The metadata json that will be hashed into the chain.
|
||||
util::LazyInit<Json::Value const> abi;
|
||||
util::LazyInit<Json::Value const> storageLayout;
|
||||
util::LazyInit<Json::Value const> userDocumentation;
|
||||
util::LazyInit<Json::Value const> devDocumentation;
|
||||
util::LazyInit<Json::Value const> generatedSources;
|
||||
util::LazyInit<Json::Value const> runtimeGeneratedSources;
|
||||
util::LazyInit<Json const> abi;
|
||||
util::LazyInit<Json const> storageLayout;
|
||||
util::LazyInit<Json const> userDocumentation;
|
||||
util::LazyInit<Json const> devDocumentation;
|
||||
util::LazyInit<Json const> generatedSources;
|
||||
util::LazyInit<Json const> runtimeGeneratedSources;
|
||||
mutable std::optional<std::string const> sourceMapping;
|
||||
mutable std::optional<std::string const> runtimeSourceMapping;
|
||||
};
|
||||
@ -467,19 +466,19 @@ private:
|
||||
|
||||
/// @returns the contract ABI as a JSON object.
|
||||
/// This will generate the JSON object and store it in the Contract object if it is not present yet.
|
||||
Json::Value const& contractABI(Contract const&) const;
|
||||
Json const& contractABI(Contract const&) const;
|
||||
|
||||
/// @returns the storage layout of the contract as a JSON object.
|
||||
/// This will generate the JSON object and store it in the Contract object if it is not present yet.
|
||||
Json::Value const& storageLayout(Contract const&) const;
|
||||
Json const& storageLayout(Contract const&) const;
|
||||
|
||||
/// @returns the Natspec User documentation as a JSON object.
|
||||
/// This will generate the JSON object and store it in the Contract object if it is not present yet.
|
||||
Json::Value const& natspecUser(Contract const&) const;
|
||||
Json const& natspecUser(Contract const&) const;
|
||||
|
||||
/// @returns the Natspec Developer documentation as a JSON object.
|
||||
/// This will generate the JSON object and store it in the Contract object if it is not present yet.
|
||||
Json::Value const& natspecDev(Contract const&) const;
|
||||
Json const& natspecDev(Contract const&) const;
|
||||
|
||||
/// @returns the Contract Metadata matching the pipeline selected using the viaIR setting.
|
||||
/// This will generate the metadata and store it in the Contract object if it is not present yet.
|
||||
@ -507,7 +506,7 @@ private:
|
||||
ImportRemapper m_importRemapper;
|
||||
std::map<std::string const, Source> m_sources;
|
||||
// if imported, store AST-JSONS for each filename
|
||||
std::map<std::string, Json::Value> m_sourceJsons;
|
||||
std::map<std::string, Json> m_sourceJsons;
|
||||
std::vector<std::string> m_unhandledSMTLib2Queries;
|
||||
std::map<util::h256, std::string> m_smtlib2Responses;
|
||||
std::shared_ptr<GlobalContext> m_globalContext;
|
||||
|
@ -35,13 +35,13 @@ using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
|
||||
Json Natspec::userDocumentation(ContractDefinition const& _contractDef)
|
||||
{
|
||||
Json::Value doc{Json::objectValue};
|
||||
Json doc{Json::object()};
|
||||
|
||||
doc["version"] = Json::Value(c_natspecVersion);
|
||||
doc["kind"] = Json::Value("user");
|
||||
doc["methods"] = Json::objectValue;
|
||||
doc["version"] = Json(c_natspecVersion);
|
||||
doc["kind"] = Json("user");
|
||||
doc["methods"] = Json::object();
|
||||
|
||||
auto constructorDefinition(_contractDef.constructor());
|
||||
if (constructorDefinition)
|
||||
@ -50,15 +50,15 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
|
||||
if (!value.empty())
|
||||
{
|
||||
// add the constructor, only if we have any documentation to add
|
||||
Json::Value user{Json::objectValue};
|
||||
user["notice"] = Json::Value(value);
|
||||
Json user{Json::object()};
|
||||
user["notice"] = Json(value);
|
||||
doc["methods"]["constructor"] = user;
|
||||
}
|
||||
}
|
||||
|
||||
string notice = extractDoc(_contractDef.annotation().docTags, "notice");
|
||||
if (!notice.empty())
|
||||
doc["notice"] = Json::Value(notice);
|
||||
doc["notice"] = Json(notice);
|
||||
|
||||
for (auto const& it: _contractDef.interfaceFunctions())
|
||||
if (it.second->hasDeclaration())
|
||||
@ -90,21 +90,21 @@ Json::Value Natspec::userDocumentation(ContractDefinition const& _contractDef)
|
||||
string value = extractDoc(error->annotation().docTags, "notice");
|
||||
if (!value.empty())
|
||||
{
|
||||
Json::Value errorDoc{Json::objectValue};
|
||||
Json errorDoc{Json::object()};
|
||||
errorDoc["notice"] = value;
|
||||
doc["errors"][error->functionType(true)->externalSignature()].append(std::move(errorDoc));
|
||||
doc["errors"][error->functionType(true)->externalSignature()].emplace_back(std::move(errorDoc));
|
||||
}
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
Json Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
{
|
||||
Json::Value doc = extractCustomDoc(_contractDef.annotation().docTags);
|
||||
Json doc = extractCustomDoc(_contractDef.annotation().docTags);
|
||||
|
||||
doc["version"] = Json::Value(c_natspecVersion);
|
||||
doc["kind"] = Json::Value("dev");
|
||||
doc["version"] = Json(c_natspecVersion);
|
||||
doc["kind"] = Json("dev");
|
||||
|
||||
auto author = extractDoc(_contractDef.annotation().docTags, "author");
|
||||
if (!author.empty())
|
||||
@ -114,13 +114,13 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
doc["title"] = title;
|
||||
auto dev = extractDoc(_contractDef.annotation().docTags, "dev");
|
||||
if (!dev.empty())
|
||||
doc["details"] = Json::Value(dev);
|
||||
doc["details"] = Json(dev);
|
||||
|
||||
doc["methods"] = Json::objectValue;
|
||||
doc["methods"] = Json::object();
|
||||
auto constructorDefinition(_contractDef.constructor());
|
||||
if (constructorDefinition)
|
||||
{
|
||||
Json::Value constructor(devDocumentation(constructorDefinition->annotation().docTags));
|
||||
Json constructor(devDocumentation(constructorDefinition->annotation().docTags));
|
||||
if (!constructor.empty())
|
||||
// add the constructor, only if we have any documentation to add
|
||||
doc["methods"]["constructor"] = constructor;
|
||||
@ -132,9 +132,9 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
continue;
|
||||
if (auto fun = dynamic_cast<FunctionDefinition const*>(&it.second->declaration()))
|
||||
{
|
||||
Json::Value method(devDocumentation(fun->annotation().docTags));
|
||||
Json method(devDocumentation(fun->annotation().docTags));
|
||||
// add the function, only if we have any documentation to add
|
||||
Json::Value jsonReturn = extractReturnParameterDocs(
|
||||
Json jsonReturn = extractReturnParameterDocs(
|
||||
fun->annotation().docTags,
|
||||
fun->functionType(false)->returnParameterNames()
|
||||
);
|
||||
@ -152,7 +152,7 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
if (auto devDoc = devDocumentation(varDecl->annotation().docTags); !devDoc.empty())
|
||||
doc["stateVariables"][varDecl->name()] = devDoc;
|
||||
|
||||
auto const assignIfNotEmpty = [&](string const& _name, Json::Value const& _content)
|
||||
auto const assignIfNotEmpty = [&](string const& _name, Json const& _content)
|
||||
{
|
||||
if (!_content.empty())
|
||||
doc["stateVariables"][varDecl->name()][_name] = _content;
|
||||
@ -174,14 +174,14 @@ Json::Value Natspec::devDocumentation(ContractDefinition const& _contractDef)
|
||||
|
||||
for (auto const& error: _contractDef.interfaceErrors())
|
||||
if (auto devDoc = devDocumentation(error->annotation().docTags); !devDoc.empty())
|
||||
doc["errors"][error->functionType(true)->externalSignature()].append(devDoc);
|
||||
doc["errors"][error->functionType(true)->externalSignature()].emplace_back(devDoc);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, vector<string> const& _returnParameterNames)
|
||||
Json Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, vector<string> const& _returnParameterNames)
|
||||
{
|
||||
Json::Value jsonReturn{Json::objectValue};
|
||||
Json jsonReturn{Json::object()};
|
||||
auto returnDocs = _tags.equal_range("return");
|
||||
|
||||
if (!_returnParameterNames.empty())
|
||||
@ -202,7 +202,7 @@ Json::Value Natspec::extractReturnParameterDocs(std::multimap<std::string, DocTa
|
||||
content = content.substr(nameEndPos+1);
|
||||
}
|
||||
|
||||
jsonReturn[paramName] = Json::Value(content);
|
||||
jsonReturn[paramName] = Json(content);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@ -219,7 +219,7 @@ string Natspec::extractDoc(multimap<string, DocTag> const& _tags, string const&
|
||||
return value;
|
||||
}
|
||||
|
||||
Json::Value Natspec::extractCustomDoc(multimap<string, DocTag> const& _tags)
|
||||
Json Natspec::extractCustomDoc(multimap<string, DocTag> const& _tags)
|
||||
{
|
||||
std::map<string, string> concatenated;
|
||||
for (auto const& [tag, value]: _tags)
|
||||
@ -227,28 +227,28 @@ Json::Value Natspec::extractCustomDoc(multimap<string, DocTag> const& _tags)
|
||||
concatenated[tag] += value.content;
|
||||
// We do not want to create an object if there are no custom tags found.
|
||||
if (concatenated.empty())
|
||||
return Json::nullValue;
|
||||
Json::Value result{Json::objectValue};
|
||||
return Json{};
|
||||
Json result{Json::object()};
|
||||
for (auto& [tag, value]: concatenated)
|
||||
result[tag] = std::move(value);
|
||||
return result;
|
||||
}
|
||||
|
||||
Json::Value Natspec::devDocumentation(std::multimap<std::string, DocTag> const& _tags)
|
||||
Json Natspec::devDocumentation(std::multimap<std::string, DocTag> const& _tags)
|
||||
{
|
||||
Json::Value json = extractCustomDoc(_tags);
|
||||
Json json = extractCustomDoc(_tags);
|
||||
auto dev = extractDoc(_tags, "dev");
|
||||
if (!dev.empty())
|
||||
json["details"] = Json::Value(dev);
|
||||
json["details"] = Json(dev);
|
||||
|
||||
auto author = extractDoc(_tags, "author");
|
||||
if (!author.empty())
|
||||
json["author"] = author;
|
||||
|
||||
Json::Value params(Json::objectValue);
|
||||
Json params(Json::object());
|
||||
auto paramRange = _tags.equal_range("param");
|
||||
for (auto i = paramRange.first; i != paramRange.second; ++i)
|
||||
params[i->second.paramName] = Json::Value(i->second.content);
|
||||
params[i->second.paramName] = Json(i->second.content);
|
||||
|
||||
if (!params.empty())
|
||||
json["params"] = params;
|
||||
|
@ -26,10 +26,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
@ -46,32 +46,32 @@ public:
|
||||
/// Get the User documentation of the contract
|
||||
/// @param _contractDef The contract definition
|
||||
/// @return A JSON representation of the contract's user documentation
|
||||
static Json::Value userDocumentation(ContractDefinition const& _contractDef);
|
||||
static Json userDocumentation(ContractDefinition const& _contractDef);
|
||||
/// Generates the Developer's documentation of the contract
|
||||
/// @param _contractDef The contract definition
|
||||
/// @return A JSON representation
|
||||
/// of the contract's developer documentation
|
||||
static Json::Value devDocumentation(ContractDefinition const& _contractDef);
|
||||
static Json devDocumentation(ContractDefinition const& _contractDef);
|
||||
|
||||
private:
|
||||
/// @returns concatenation of all content under the given tag name.
|
||||
static std::string extractDoc(std::multimap<std::string, DocTag> const& _tags, std::string const& _name);
|
||||
|
||||
/// Extract all custom tags from @a _tags.
|
||||
static Json::Value extractCustomDoc(std::multimap<std::string, DocTag> const& _tags);
|
||||
static Json extractCustomDoc(std::multimap<std::string, DocTag> const& _tags);
|
||||
|
||||
/// Helper-function that will create a json object with dev specific annotations, if present.
|
||||
/// @param _tags docTags that are used.
|
||||
/// @return A JSON representation
|
||||
/// of the contract's developer documentation
|
||||
static Json::Value devDocumentation(std::multimap<std::string, DocTag> const& _tags);
|
||||
static Json devDocumentation(std::multimap<std::string, DocTag> const& _tags);
|
||||
|
||||
/// Helper-function that will create a json object for the "returns" field for a given function definition.
|
||||
/// @param _tags docTags that are used.
|
||||
/// @param _returnParameterNames names of the return parameters
|
||||
/// @return A JSON representation
|
||||
/// of a method's return notice documentation
|
||||
static Json::Value extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, std::vector<std::string> const& _returnParameterNames);
|
||||
static Json extractReturnParameterDocs(std::multimap<std::string, DocTag> const& _tags, std::vector<std::string> const& _returnParameterNames);
|
||||
};
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,12 +58,12 @@ public:
|
||||
|
||||
/// Sets all input parameters according to @a _input which conforms to the standardized input
|
||||
/// format, performs compilation and returns a standardized output.
|
||||
Json::Value compile(Json::Value const& _input) noexcept;
|
||||
Json compile(Json const& _input) noexcept;
|
||||
/// Parses input as JSON and peforms the above processing steps, returning a serialized JSON
|
||||
/// output. Parsing errors are returned as regular errors.
|
||||
std::string compile(std::string const& _input) noexcept;
|
||||
|
||||
static Json::Value formatFunctionDebugData(
|
||||
static Json formatFunctionDebugData(
|
||||
std::map<std::string, evmasm::LinkerObject::FunctionDebugData> const& _debugInfo
|
||||
);
|
||||
|
||||
@ -71,7 +71,7 @@ private:
|
||||
struct InputsAndSettings
|
||||
{
|
||||
std::string language;
|
||||
Json::Value errors;
|
||||
Json errors;
|
||||
bool parserErrorRecovery = false;
|
||||
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
|
||||
std::map<std::string, std::string> sources;
|
||||
@ -85,17 +85,17 @@ private:
|
||||
bool metadataLiteralSources = false;
|
||||
CompilerStack::MetadataFormat metadataFormat = CompilerStack::defaultMetadataFormat();
|
||||
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;
|
||||
Json::Value outputSelection;
|
||||
Json outputSelection;
|
||||
ModelCheckerSettings modelCheckerSettings = ModelCheckerSettings{};
|
||||
bool viaIR = false;
|
||||
};
|
||||
|
||||
/// Parses the input json (and potentially invokes the read callback) and either returns
|
||||
/// it in condensed form or an error as a json object.
|
||||
std::variant<InputsAndSettings, Json::Value> parseInput(Json::Value const& _input);
|
||||
std::variant<InputsAndSettings, Json> parseInput(Json const& _input);
|
||||
|
||||
Json::Value compileSolidity(InputsAndSettings _inputsAndSettings);
|
||||
Json::Value compileYul(InputsAndSettings _inputsAndSettings);
|
||||
Json compileSolidity(InputsAndSettings _inputsAndSettings);
|
||||
Json compileYul(InputsAndSettings _inputsAndSettings);
|
||||
|
||||
ReadCallback::Callback m_readFile;
|
||||
|
||||
|
@ -24,7 +24,7 @@ using namespace std;
|
||||
using namespace solidity;
|
||||
using namespace solidity::frontend;
|
||||
|
||||
Json::Value StorageLayout::generate(ContractDefinition const& _contractDef)
|
||||
Json StorageLayout::generate(ContractDefinition const& _contractDef)
|
||||
{
|
||||
solAssert(!m_contract, "");
|
||||
m_contract = &_contractDef;
|
||||
@ -35,19 +35,19 @@ Json::Value StorageLayout::generate(ContractDefinition const& _contractDef)
|
||||
auto contractType = dynamic_cast<ContractType const*>(typeType->actualType());
|
||||
solAssert(contractType, "");
|
||||
|
||||
Json::Value variables(Json::arrayValue);
|
||||
Json variables(Json::array());
|
||||
for (auto [var, slot, offset]: contractType->stateVariables())
|
||||
variables.append(generate(*var, slot, offset));
|
||||
variables.emplace_back(generate(*var, slot, offset));
|
||||
|
||||
Json::Value layout;
|
||||
Json layout;
|
||||
layout["storage"] = std::move(variables);
|
||||
layout["types"] = std::move(m_types);
|
||||
return layout;
|
||||
}
|
||||
|
||||
Json::Value StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset)
|
||||
Json StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset)
|
||||
{
|
||||
Json::Value varEntry;
|
||||
Json varEntry;
|
||||
Type const* varType = _var.type();
|
||||
|
||||
varEntry["label"] = _var.name();
|
||||
@ -64,22 +64,22 @@ Json::Value StorageLayout::generate(VariableDeclaration const& _var, u256 const&
|
||||
|
||||
void StorageLayout::generate(Type const* _type)
|
||||
{
|
||||
if (m_types.isMember(typeKeyName(_type)))
|
||||
if (m_types.contains(typeKeyName(_type)))
|
||||
return;
|
||||
|
||||
// Register it now to cut recursive visits.
|
||||
Json::Value& typeInfo = m_types[typeKeyName(_type)];
|
||||
Json& typeInfo = m_types[typeKeyName(_type)];
|
||||
typeInfo["label"] = _type->toString(true);
|
||||
typeInfo["numberOfBytes"] = u256(_type->storageBytes() * _type->storageSize()).str();
|
||||
|
||||
if (auto structType = dynamic_cast<StructType const*>(_type))
|
||||
{
|
||||
Json::Value members(Json::arrayValue);
|
||||
Json members(Json::array());
|
||||
auto const& structDef = structType->structDefinition();
|
||||
for (auto const& member: structDef.members())
|
||||
{
|
||||
auto const& offsets = structType->storageOffsetsOfMember(member->name());
|
||||
members.append(generate(*member, offsets.first, offsets.second));
|
||||
members.emplace_back(generate(*member, offsets.first, offsets.second));
|
||||
}
|
||||
typeInfo["members"] = std::move(members);
|
||||
typeInfo["encoding"] = "inplace";
|
||||
@ -109,7 +109,7 @@ void StorageLayout::generate(Type const* _type)
|
||||
typeInfo["encoding"] = "inplace";
|
||||
}
|
||||
|
||||
solAssert(typeInfo.isMember("encoding"), "");
|
||||
solAssert(typeInfo.contains("encoding"), "");
|
||||
}
|
||||
|
||||
string StorageLayout::typeKeyName(Type const* _type)
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/ast/Types.h>
|
||||
|
||||
#include <json/json.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
namespace solidity::frontend
|
||||
{
|
||||
@ -35,11 +35,11 @@ public:
|
||||
/// Generates the storage layout of the contract
|
||||
/// @param _contractDef The contract definition
|
||||
/// @return A JSON representation of the contract's storage layout.
|
||||
Json::Value generate(ContractDefinition const& _contractDef);
|
||||
Json generate(ContractDefinition const& _contractDef);
|
||||
|
||||
private:
|
||||
/// Generates the JSON information for a variable and its storage location.
|
||||
Json::Value generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset);
|
||||
Json generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset);
|
||||
|
||||
/// Generates the JSON information for @param _type
|
||||
void generate(Type const* _type);
|
||||
@ -47,7 +47,7 @@ private:
|
||||
/// The key for the JSON object describing a type.
|
||||
std::string typeKeyName(Type const* _type);
|
||||
|
||||
Json::Value m_types;
|
||||
Json m_types;
|
||||
|
||||
/// Current analyzed contract
|
||||
ContractDefinition const* m_contract = nullptr;
|
||||
|
@ -32,7 +32,7 @@ using namespace solidity::langutil;
|
||||
using namespace solidity::lsp;
|
||||
using namespace std;
|
||||
|
||||
void GotoDefinition::operator()(MessageID _id, Json::Value const& _args)
|
||||
void GotoDefinition::operator()(MessageID _id, Json const& _args)
|
||||
{
|
||||
auto const [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args);
|
||||
|
||||
@ -59,8 +59,8 @@ void GotoDefinition::operator()(MessageID _id, Json::Value const& _args)
|
||||
locations.emplace_back(SourceLocation{0, 0, make_shared<string const>(path)});
|
||||
}
|
||||
|
||||
Json::Value reply = Json::arrayValue;
|
||||
Json reply = Json::array();
|
||||
for (SourceLocation const& location: locations)
|
||||
reply.append(toJson(location));
|
||||
reply.emplace_back(toJson(location));
|
||||
client().reply(_id, reply);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class GotoDefinition: public HandlerBase
|
||||
public:
|
||||
explicit GotoDefinition(LanguageServer& _server): HandlerBase(_server) {}
|
||||
|
||||
void operator()(MessageID, Json::Value const&);
|
||||
void operator()(MessageID, Json const&);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ using namespace solidity::lsp;
|
||||
using namespace solidity::util;
|
||||
using namespace std;
|
||||
|
||||
Json::Value HandlerBase::toRange(SourceLocation const& _location) const
|
||||
Json HandlerBase::toRange(SourceLocation const& _location) const
|
||||
{
|
||||
if (!_location.hasText())
|
||||
return toJsonRange({}, {});
|
||||
@ -43,18 +43,18 @@ Json::Value HandlerBase::toRange(SourceLocation const& _location) const
|
||||
return toJsonRange(start, end);
|
||||
}
|
||||
|
||||
Json::Value HandlerBase::toJson(SourceLocation const& _location) const
|
||||
Json HandlerBase::toJson(SourceLocation const& _location) const
|
||||
{
|
||||
solAssert(_location.sourceName);
|
||||
Json::Value item = Json::objectValue;
|
||||
Json item = Json::object();
|
||||
item["uri"] = fileRepository().sourceUnitNameToUri(*_location.sourceName);
|
||||
item["range"] = toRange(_location);
|
||||
return item;
|
||||
}
|
||||
|
||||
pair<string, LineColumn> HandlerBase::extractSourceUnitNameAndLineColumn(Json::Value const& _args) const
|
||||
pair<string, LineColumn> HandlerBase::extractSourceUnitNameAndLineColumn(Json const& _args) const
|
||||
{
|
||||
string const uri = _args["textDocument"]["uri"].asString();
|
||||
string const uri = _args["textDocument"]["uri"].get<string>();
|
||||
string const sourceUnitName = fileRepository().uriToSourceUnitName(uri);
|
||||
if (!fileRepository().sourceUnits().count(sourceUnitName))
|
||||
BOOST_THROW_EXCEPTION(
|
||||
|
@ -38,12 +38,12 @@ class HandlerBase
|
||||
public:
|
||||
explicit HandlerBase(LanguageServer& _server): m_server{_server} {}
|
||||
|
||||
Json::Value toRange(langutil::SourceLocation const& _location) const;
|
||||
Json::Value toJson(langutil::SourceLocation const& _location) const;
|
||||
Json toRange(langutil::SourceLocation const& _location) const;
|
||||
Json toJson(langutil::SourceLocation const& _location) const;
|
||||
|
||||
/// @returns source unit name and the line column position as extracted
|
||||
/// from the JSON-RPC parameters.
|
||||
std::pair<std::string, langutil::LineColumn> extractSourceUnitNameAndLineColumn(Json::Value const& _params) const;
|
||||
std::pair<std::string, langutil::LineColumn> extractSourceUnitNameAndLineColumn(Json const& _params) const;
|
||||
|
||||
langutil::CharStreamProvider const& charStreamProvider() const noexcept { return m_server.compilerStack(); }
|
||||
FileRepository& fileRepository() const noexcept { return m_server.fileRepository(); }
|
||||
|
@ -86,44 +86,44 @@ int toDiagnosticSeverity(Error::Type _errorType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
Json::Value semanticTokensLegend()
|
||||
Json semanticTokensLegend()
|
||||
{
|
||||
Json::Value legend = Json::objectValue;
|
||||
Json legend = Json::object();
|
||||
|
||||
// NOTE! The (alphabetical) order and items must match exactly the items of
|
||||
// their respective enum class members.
|
||||
|
||||
Json::Value tokenTypes = Json::arrayValue;
|
||||
tokenTypes.append("class");
|
||||
tokenTypes.append("comment");
|
||||
tokenTypes.append("enum");
|
||||
tokenTypes.append("enumMember");
|
||||
tokenTypes.append("event");
|
||||
tokenTypes.append("function");
|
||||
tokenTypes.append("interface");
|
||||
tokenTypes.append("keyword");
|
||||
tokenTypes.append("macro");
|
||||
tokenTypes.append("method");
|
||||
tokenTypes.append("modifier");
|
||||
tokenTypes.append("number");
|
||||
tokenTypes.append("operator");
|
||||
tokenTypes.append("parameter");
|
||||
tokenTypes.append("property");
|
||||
tokenTypes.append("string");
|
||||
tokenTypes.append("struct");
|
||||
tokenTypes.append("type");
|
||||
tokenTypes.append("typeParameter");
|
||||
tokenTypes.append("variable");
|
||||
Json tokenTypes = Json::array();
|
||||
tokenTypes.emplace_back("class");
|
||||
tokenTypes.emplace_back("comment");
|
||||
tokenTypes.emplace_back("enum");
|
||||
tokenTypes.emplace_back("enumMember");
|
||||
tokenTypes.emplace_back("event");
|
||||
tokenTypes.emplace_back("function");
|
||||
tokenTypes.emplace_back("interface");
|
||||
tokenTypes.emplace_back("keyword");
|
||||
tokenTypes.emplace_back("macro");
|
||||
tokenTypes.emplace_back("method");
|
||||
tokenTypes.emplace_back("modifier");
|
||||
tokenTypes.emplace_back("number");
|
||||
tokenTypes.emplace_back("operator");
|
||||
tokenTypes.emplace_back("parameter");
|
||||
tokenTypes.emplace_back("property");
|
||||
tokenTypes.emplace_back("string");
|
||||
tokenTypes.emplace_back("struct");
|
||||
tokenTypes.emplace_back("type");
|
||||
tokenTypes.emplace_back("typeParameter");
|
||||
tokenTypes.emplace_back("variable");
|
||||
legend["tokenTypes"] = tokenTypes;
|
||||
|
||||
Json::Value tokenModifiers = Json::arrayValue;
|
||||
tokenModifiers.append("abstract");
|
||||
tokenModifiers.append("declaration");
|
||||
tokenModifiers.append("definition");
|
||||
tokenModifiers.append("deprecated");
|
||||
tokenModifiers.append("documentation");
|
||||
tokenModifiers.append("modification");
|
||||
tokenModifiers.append("readonly");
|
||||
Json tokenModifiers = Json::array();
|
||||
tokenModifiers.emplace_back("abstract");
|
||||
tokenModifiers.emplace_back("declaration");
|
||||
tokenModifiers.emplace_back("definition");
|
||||
tokenModifiers.emplace_back("deprecated");
|
||||
tokenModifiers.emplace_back("documentation");
|
||||
tokenModifiers.emplace_back("modification");
|
||||
tokenModifiers.emplace_back("readonly");
|
||||
legend["tokenModifiers"] = tokenModifiers;
|
||||
|
||||
return legend;
|
||||
@ -139,7 +139,7 @@ LanguageServer::LanguageServer(Transport& _transport):
|
||||
{"exit", [this](auto, auto) { m_state = (m_state == State::ShutdownRequested ? State::ExitRequested : State::ExitWithoutShutdown); }},
|
||||
{"initialize", bind(&LanguageServer::handleInitialize, this, _1, _2)},
|
||||
{"initialized", bind(&LanguageServer::handleInitialized, this, _1, _2)},
|
||||
{"$/setTrace", [this](auto, Json::Value const& args) { setTrace(args["value"]); }},
|
||||
{"$/setTrace", [this](auto, Json const& args) { setTrace(args["value"]); }},
|
||||
{"shutdown", [this](auto, auto) { m_state = State::ShutdownRequested; }},
|
||||
{"textDocument/definition", GotoDefinition(*this) },
|
||||
{"textDocument/didOpen", bind(&LanguageServer::handleTextDocumentDidOpen, this, _2)},
|
||||
@ -156,17 +156,17 @@ LanguageServer::LanguageServer(Transport& _transport):
|
||||
{
|
||||
}
|
||||
|
||||
Json::Value LanguageServer::toRange(SourceLocation const& _location)
|
||||
Json LanguageServer::toRange(SourceLocation const& _location)
|
||||
{
|
||||
return HandlerBase(*this).toRange(_location);
|
||||
}
|
||||
|
||||
Json::Value LanguageServer::toJson(SourceLocation const& _location)
|
||||
Json LanguageServer::toJson(SourceLocation const& _location)
|
||||
{
|
||||
return HandlerBase(*this).toJson(_location);
|
||||
}
|
||||
|
||||
void LanguageServer::changeConfiguration(Json::Value const& _settings)
|
||||
void LanguageServer::changeConfiguration(Json const& _settings)
|
||||
{
|
||||
// The settings item: "file-load-strategy" (enum) defaults to "project-directory" if not (or not correctly) set.
|
||||
// It can be overridden during client's handshake or at runtime, as usual.
|
||||
@ -179,7 +179,7 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings)
|
||||
// those files being imported directly or indirectly will be included in operations.
|
||||
if (_settings["file-load-strategy"])
|
||||
{
|
||||
auto const text = _settings["file-load-strategy"].asString();
|
||||
auto const text = _settings["file-load-strategy"].get<string>();
|
||||
if (text == "project-directory")
|
||||
m_fileLoadStrategy = FileLoadStrategy::ProjectDirectory;
|
||||
else if (text == "directly-opened-and-on-import")
|
||||
@ -189,18 +189,18 @@ void LanguageServer::changeConfiguration(Json::Value const& _settings)
|
||||
}
|
||||
|
||||
m_settingsObject = _settings;
|
||||
Json::Value jsonIncludePaths = _settings["include-paths"];
|
||||
Json jsonIncludePaths = _settings["include-paths"];
|
||||
|
||||
if (jsonIncludePaths)
|
||||
{
|
||||
int typeFailureCount = 0;
|
||||
if (jsonIncludePaths.isArray())
|
||||
if (jsonIncludePaths.is_array())
|
||||
{
|
||||
vector<boost::filesystem::path> includePaths;
|
||||
for (Json::Value const& jsonPath: jsonIncludePaths)
|
||||
for (Json const& jsonPath: jsonIncludePaths)
|
||||
{
|
||||
if (jsonPath.isString())
|
||||
includePaths.emplace_back(boost::filesystem::path(jsonPath.asString()));
|
||||
if (jsonPath.is_string())
|
||||
includePaths.emplace_back(boost::filesystem::path(jsonPath.get<string>()));
|
||||
else
|
||||
typeFailureCount++;
|
||||
}
|
||||
@ -271,11 +271,11 @@ void LanguageServer::compileAndUpdateDiagnostics()
|
||||
|
||||
// These are the source units we will sent diagnostics to the client for sure,
|
||||
// even if it is just to clear previous diagnostics.
|
||||
map<string, Json::Value> diagnosticsBySourceUnit;
|
||||
map<string, Json> diagnosticsBySourceUnit;
|
||||
for (string const& sourceUnitName: m_fileRepository.sourceUnits() | ranges::views::keys)
|
||||
diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue;
|
||||
diagnosticsBySourceUnit[sourceUnitName] = Json::array();
|
||||
for (string const& sourceUnitName: m_nonemptyDiagnostics)
|
||||
diagnosticsBySourceUnit[sourceUnitName] = Json::arrayValue;
|
||||
diagnosticsBySourceUnit[sourceUnitName] = Json::array();
|
||||
|
||||
for (shared_ptr<Error const> const& error: m_compilerStack.errors())
|
||||
{
|
||||
@ -284,10 +284,10 @@ void LanguageServer::compileAndUpdateDiagnostics()
|
||||
// LSP only has diagnostics applied to individual files.
|
||||
continue;
|
||||
|
||||
Json::Value jsonDiag;
|
||||
Json jsonDiag;
|
||||
jsonDiag["source"] = "solc";
|
||||
jsonDiag["severity"] = toDiagnosticSeverity(error->type());
|
||||
jsonDiag["code"] = Json::UInt64{error->errorId().error};
|
||||
jsonDiag["code"] = Json{error->errorId().error};
|
||||
string message = Error::formatErrorType(error->type()) + ":";
|
||||
if (string const* comment = error->comment())
|
||||
message += " " + *comment;
|
||||
@ -297,26 +297,26 @@ void LanguageServer::compileAndUpdateDiagnostics()
|
||||
if (auto const* secondary = error->secondarySourceLocation())
|
||||
for (auto&& [secondaryMessage, secondaryLocation]: secondary->infos)
|
||||
{
|
||||
Json::Value jsonRelated;
|
||||
Json jsonRelated;
|
||||
jsonRelated["message"] = secondaryMessage;
|
||||
jsonRelated["location"] = toJson(secondaryLocation);
|
||||
jsonDiag["relatedInformation"].append(jsonRelated);
|
||||
jsonDiag["relatedInformation"].emplace_back(jsonRelated);
|
||||
}
|
||||
|
||||
diagnosticsBySourceUnit[*location->sourceName].append(jsonDiag);
|
||||
diagnosticsBySourceUnit[*location->sourceName].emplace_back(jsonDiag);
|
||||
}
|
||||
|
||||
if (m_client.traceValue() != TraceValue::Off)
|
||||
{
|
||||
Json::Value extra;
|
||||
extra["openFileCount"] = Json::UInt64(diagnosticsBySourceUnit.size());
|
||||
Json extra;
|
||||
extra["openFileCount"] = Json{diagnosticsBySourceUnit.size()};
|
||||
m_client.trace("Number of currently open files: " + to_string(diagnosticsBySourceUnit.size()), extra);
|
||||
}
|
||||
|
||||
m_nonemptyDiagnostics.clear();
|
||||
for (auto&& [sourceUnitName, diagnostics]: diagnosticsBySourceUnit)
|
||||
{
|
||||
Json::Value params;
|
||||
Json params;
|
||||
params["uri"] = m_fileRepository.sourceUnitNameToUri(sourceUnitName);
|
||||
if (!diagnostics.empty())
|
||||
m_nonemptyDiagnostics.insert(sourceUnitName);
|
||||
@ -332,13 +332,13 @@ bool LanguageServer::run()
|
||||
MessageID id;
|
||||
try
|
||||
{
|
||||
optional<Json::Value> const jsonMessage = m_client.receive();
|
||||
optional<Json> const jsonMessage = m_client.receive();
|
||||
if (!jsonMessage)
|
||||
continue;
|
||||
|
||||
if ((*jsonMessage)["method"].isString())
|
||||
if ((*jsonMessage)["method"].is_string())
|
||||
{
|
||||
string const methodName = (*jsonMessage)["method"].asString();
|
||||
string const methodName = (*jsonMessage)["method"].get<string>();
|
||||
id = (*jsonMessage)["id"];
|
||||
lspDebug(fmt::format("received method call: {}", methodName));
|
||||
|
||||
@ -350,7 +350,7 @@ bool LanguageServer::run()
|
||||
else
|
||||
m_client.error({}, ErrorCode::ParseError, "\"method\" has to be a string.");
|
||||
}
|
||||
catch (Json::Exception const&)
|
||||
catch (Json::exception const&)
|
||||
{
|
||||
m_client.error(id, ErrorCode::InvalidParams, "JSON object access error. Most likely due to a badly formatted JSON request message."s);
|
||||
}
|
||||
@ -375,7 +375,7 @@ void LanguageServer::requireServerInitialized()
|
||||
);
|
||||
}
|
||||
|
||||
void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
|
||||
void LanguageServer::handleInitialize(MessageID _id, Json const& _args)
|
||||
{
|
||||
lspRequire(
|
||||
m_state == State::Started,
|
||||
@ -388,9 +388,9 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
|
||||
// The default of FileReader is to use `.`, but the path from where the LSP was started
|
||||
// should not matter.
|
||||
string rootPath("/");
|
||||
if (Json::Value uri = _args["rootUri"])
|
||||
if (Json uri = _args["rootUri"])
|
||||
{
|
||||
rootPath = uri.asString();
|
||||
rootPath = uri.get<string>();
|
||||
lspRequire(
|
||||
boost::starts_with(rootPath, "file://"),
|
||||
ErrorCode::InvalidParams,
|
||||
@ -398,17 +398,17 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
|
||||
);
|
||||
rootPath = stripFileUriSchemePrefix(rootPath);
|
||||
}
|
||||
else if (Json::Value rootPath = _args["rootPath"])
|
||||
rootPath = rootPath.asString();
|
||||
else if (Json rootPath = _args["rootPath"])
|
||||
rootPath = rootPath.get<string>();
|
||||
|
||||
if (_args["trace"])
|
||||
setTrace(_args["trace"]);
|
||||
|
||||
m_fileRepository = FileRepository(rootPath, {});
|
||||
if (_args["initializationOptions"].isObject())
|
||||
if (_args["initializationOptions"].is_object())
|
||||
changeConfiguration(_args["initializationOptions"]);
|
||||
|
||||
Json::Value replyArgs;
|
||||
Json replyArgs;
|
||||
replyArgs["serverInfo"]["name"] = "solc";
|
||||
replyArgs["serverInfo"]["version"] = string(VersionNumber);
|
||||
replyArgs["capabilities"]["definitionProvider"] = true;
|
||||
@ -424,44 +424,44 @@ void LanguageServer::handleInitialize(MessageID _id, Json::Value const& _args)
|
||||
m_client.reply(_id, std::move(replyArgs));
|
||||
}
|
||||
|
||||
void LanguageServer::handleInitialized(MessageID, Json::Value const&)
|
||||
void LanguageServer::handleInitialized(MessageID, Json const&)
|
||||
{
|
||||
if (m_fileLoadStrategy == FileLoadStrategy::ProjectDirectory)
|
||||
compileAndUpdateDiagnostics();
|
||||
}
|
||||
|
||||
void LanguageServer::semanticTokensFull(MessageID _id, Json::Value const& _args)
|
||||
void LanguageServer::semanticTokensFull(MessageID _id, Json const& _args)
|
||||
{
|
||||
auto uri = _args["textDocument"]["uri"];
|
||||
|
||||
compile();
|
||||
|
||||
auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.as<string>());
|
||||
auto const sourceName = m_fileRepository.uriToSourceUnitName(uri.get<string>());
|
||||
SourceUnit const& ast = m_compilerStack.ast(sourceName);
|
||||
m_compilerStack.charStream(sourceName);
|
||||
Json::Value data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName));
|
||||
Json data = SemanticTokensBuilder().build(ast, m_compilerStack.charStream(sourceName));
|
||||
|
||||
Json::Value reply = Json::objectValue;
|
||||
Json reply = Json::object();
|
||||
reply["data"] = data;
|
||||
|
||||
m_client.reply(_id, std::move(reply));
|
||||
}
|
||||
|
||||
void LanguageServer::handleWorkspaceDidChangeConfiguration(Json::Value const& _args)
|
||||
void LanguageServer::handleWorkspaceDidChangeConfiguration(Json const& _args)
|
||||
{
|
||||
requireServerInitialized();
|
||||
|
||||
if (_args["settings"].isObject())
|
||||
if (_args["settings"].is_object())
|
||||
changeConfiguration(_args["settings"]);
|
||||
}
|
||||
|
||||
void LanguageServer::setTrace(Json::Value const& _args)
|
||||
void LanguageServer::setTrace(Json const& _args)
|
||||
{
|
||||
if (!_args.isString())
|
||||
if (!_args.is_string())
|
||||
// Simply ignore invalid parameter.
|
||||
return;
|
||||
|
||||
string const stringValue = _args.asString();
|
||||
string const stringValue = _args.get<string>();
|
||||
if (stringValue == "off")
|
||||
m_client.setTrace(TraceValue::Off);
|
||||
else if (stringValue == "messages")
|
||||
@ -470,7 +470,7 @@ void LanguageServer::setTrace(Json::Value const& _args)
|
||||
m_client.setTrace(TraceValue::Verbose);
|
||||
}
|
||||
|
||||
void LanguageServer::handleTextDocumentDidOpen(Json::Value const& _args)
|
||||
void LanguageServer::handleTextDocumentDidOpen(Json const& _args)
|
||||
{
|
||||
requireServerInitialized();
|
||||
|
||||
@ -480,23 +480,23 @@ void LanguageServer::handleTextDocumentDidOpen(Json::Value const& _args)
|
||||
"Text document parameter missing."
|
||||
);
|
||||
|
||||
string text = _args["textDocument"]["text"].asString();
|
||||
string uri = _args["textDocument"]["uri"].asString();
|
||||
string text = _args["textDocument"]["text"].get<string>();
|
||||
string uri = _args["textDocument"]["uri"].get<string>();
|
||||
m_openFiles.insert(uri);
|
||||
m_fileRepository.setSourceByUri(uri, std::move(text));
|
||||
compileAndUpdateDiagnostics();
|
||||
}
|
||||
|
||||
void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args)
|
||||
void LanguageServer::handleTextDocumentDidChange(Json const& _args)
|
||||
{
|
||||
requireServerInitialized();
|
||||
|
||||
string const uri = _args["textDocument"]["uri"].asString();
|
||||
string const uri = _args["textDocument"]["uri"].get<string>();
|
||||
|
||||
for (Json::Value jsonContentChange: _args["contentChanges"])
|
||||
for (Json jsonContentChange: _args["contentChanges"])
|
||||
{
|
||||
lspRequire(
|
||||
jsonContentChange.isObject(),
|
||||
jsonContentChange.is_object(),
|
||||
ErrorCode::RequestFailed,
|
||||
"Invalid content reference."
|
||||
);
|
||||
@ -508,8 +508,8 @@ void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args)
|
||||
"Unknown file: " + uri
|
||||
);
|
||||
|
||||
string text = jsonContentChange["text"].asString();
|
||||
if (jsonContentChange["range"].isObject()) // otherwise full content update
|
||||
string text = jsonContentChange["text"].get<string>();
|
||||
if (jsonContentChange["range"].is_object()) // otherwise full content update
|
||||
{
|
||||
optional<SourceLocation> change = parseRange(m_fileRepository, sourceUnitName, jsonContentChange["range"]);
|
||||
lspRequire(
|
||||
@ -528,7 +528,7 @@ void LanguageServer::handleTextDocumentDidChange(Json::Value const& _args)
|
||||
compileAndUpdateDiagnostics();
|
||||
}
|
||||
|
||||
void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args)
|
||||
void LanguageServer::handleTextDocumentDidClose(Json const& _args)
|
||||
{
|
||||
requireServerInitialized();
|
||||
|
||||
@ -538,7 +538,7 @@ void LanguageServer::handleTextDocumentDidClose(Json::Value const& _args)
|
||||
"Text document parameter missing."
|
||||
);
|
||||
|
||||
string uri = _args["textDocument"]["uri"].asString();
|
||||
string uri = _args["textDocument"]["uri"].get<string>();
|
||||
m_openFiles.erase(uri);
|
||||
|
||||
compileAndUpdateDiagnostics();
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <libsolidity/interface/CompilerStack.h>
|
||||
#include <libsolidity/interface/FileReader.h>
|
||||
|
||||
#include <json/value.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
@ -85,29 +85,29 @@ private:
|
||||
/// Checks if the server is initialized (to be used by messages that need it to be initialized).
|
||||
/// Reports an error and returns false if not.
|
||||
void requireServerInitialized();
|
||||
void handleInitialize(MessageID _id, Json::Value const& _args);
|
||||
void handleInitialized(MessageID _id, Json::Value const& _args);
|
||||
void handleWorkspaceDidChangeConfiguration(Json::Value const& _args);
|
||||
void setTrace(Json::Value const& _args);
|
||||
void handleTextDocumentDidOpen(Json::Value const& _args);
|
||||
void handleTextDocumentDidChange(Json::Value const& _args);
|
||||
void handleTextDocumentDidClose(Json::Value const& _args);
|
||||
void handleRename(Json::Value const& _args);
|
||||
void handleGotoDefinition(MessageID _id, Json::Value const& _args);
|
||||
void semanticTokensFull(MessageID _id, Json::Value const& _args);
|
||||
void handleInitialize(MessageID _id, Json const& _args);
|
||||
void handleInitialized(MessageID _id, Json const& _args);
|
||||
void handleWorkspaceDidChangeConfiguration(Json const& _args);
|
||||
void setTrace(Json const& _args);
|
||||
void handleTextDocumentDidOpen(Json const& _args);
|
||||
void handleTextDocumentDidChange(Json const& _args);
|
||||
void handleTextDocumentDidClose(Json const& _args);
|
||||
void handleRename(Json const& _args);
|
||||
void handleGotoDefinition(MessageID _id, Json const& _args);
|
||||
void semanticTokensFull(MessageID _id, Json const& _args);
|
||||
|
||||
/// Invoked when the server user-supplied configuration changes (initiated by the client).
|
||||
void changeConfiguration(Json::Value const&);
|
||||
void changeConfiguration(Json const&);
|
||||
|
||||
/// Compile everything until after analysis phase.
|
||||
void compile();
|
||||
|
||||
std::vector<boost::filesystem::path> allSolidityFilesFromProject() const;
|
||||
|
||||
using MessageHandler = std::function<void(MessageID, Json::Value const&)>;
|
||||
using MessageHandler = std::function<void(MessageID, Json const&)>;
|
||||
|
||||
Json::Value toRange(langutil::SourceLocation const& _location);
|
||||
Json::Value toJson(langutil::SourceLocation const& _location);
|
||||
Json toRange(langutil::SourceLocation const& _location);
|
||||
Json toJson(langutil::SourceLocation const& _location);
|
||||
|
||||
// LSP related member fields
|
||||
|
||||
@ -127,7 +127,7 @@ private:
|
||||
frontend::CompilerStack m_compilerStack;
|
||||
|
||||
/// User-supplied custom configuration settings (such as EVM version).
|
||||
Json::Value m_settingsObject;
|
||||
Json m_settingsObject;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -48,11 +48,11 @@ CallableDeclaration const* extractCallableDeclaration(FunctionCall const& _funct
|
||||
|
||||
}
|
||||
|
||||
void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
|
||||
void RenameSymbol::operator()(MessageID _id, Json const& _args)
|
||||
{
|
||||
auto const&& [sourceUnitName, lineColumn] = extractSourceUnitNameAndLineColumn(_args);
|
||||
string const newName = _args["newName"].asString();
|
||||
string const uri = _args["textDocument"]["uri"].asString();
|
||||
string const newName = _args["newName"].get<string>();
|
||||
string const uri = _args["textDocument"]["uri"].get<string>();
|
||||
|
||||
ASTNode const* sourceNode = m_server.astNodeAtSourceLocation(sourceUnitName, lineColumn);
|
||||
|
||||
@ -91,10 +91,10 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
|
||||
// Apply changes in reverse order (will iterate in reverse)
|
||||
sort(m_locations.begin(), m_locations.end());
|
||||
|
||||
Json::Value reply = Json::objectValue;
|
||||
reply["changes"] = Json::objectValue;
|
||||
Json reply = Json::object();
|
||||
reply["changes"] = Json::object();
|
||||
|
||||
Json::Value edits = Json::arrayValue;
|
||||
Json edits = Json::array();
|
||||
|
||||
for (auto i = m_locations.rbegin(); i != m_locations.rend(); i++)
|
||||
{
|
||||
@ -106,16 +106,16 @@ void RenameSymbol::operator()(MessageID _id, Json::Value const& _args)
|
||||
buffer.replace((size_t)i->start, (size_t)(i->end - i->start), newName);
|
||||
fileRepository().setSourceByUri(uri, std::move(buffer));
|
||||
|
||||
Json::Value edit = Json::objectValue;
|
||||
Json edit = Json::object();
|
||||
edit["range"] = toRange(*i);
|
||||
edit["newText"] = newName;
|
||||
|
||||
// Record changes for the client
|
||||
edits.append(edit);
|
||||
edits.emplace_back(edit);
|
||||
if (i + 1 == m_locations.rend() || (i + 1)->sourceName != i->sourceName)
|
||||
{
|
||||
reply["changes"][uri] = edits;
|
||||
edits = Json::arrayValue;
|
||||
edits = Json::array();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class RenameSymbol: public HandlerBase
|
||||
public:
|
||||
explicit RenameSymbol(LanguageServer& _server): HandlerBase(_server) {}
|
||||
|
||||
void operator()(MessageID, Json::Value const&);
|
||||
void operator()(MessageID, Json const&);
|
||||
protected:
|
||||
// Nested class because otherwise `RenameSymbol` couldn't be easily used
|
||||
// with LanguageServer::m_handlers as `ASTConstVisitor` deletes required
|
||||
|
@ -71,7 +71,7 @@ SemanticTokenType semanticTokenTypeForExpression(frontend::Type const* _type)
|
||||
|
||||
} // end namespace
|
||||
|
||||
Json::Value SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStream const& _charStream)
|
||||
Json SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStream const& _charStream)
|
||||
{
|
||||
reset(&_charStream);
|
||||
_sourceUnit.accept(*this);
|
||||
@ -80,7 +80,7 @@ Json::Value SemanticTokensBuilder::build(SourceUnit const& _sourceUnit, CharStre
|
||||
|
||||
void SemanticTokensBuilder::reset(CharStream const* _charStream)
|
||||
{
|
||||
m_encodedTokens = Json::arrayValue;
|
||||
m_encodedTokens = Json::array();
|
||||
m_charStream = _charStream;
|
||||
m_lastLine = 0;
|
||||
m_lastStartChar = 0;
|
||||
@ -121,14 +121,14 @@ void SemanticTokensBuilder::encode(
|
||||
|
||||
lspDebug(fmt::format("encode [{}:{}..{}] {}", line, startChar, length, _tokenType));
|
||||
|
||||
m_encodedTokens.append(line - m_lastLine);
|
||||
m_encodedTokens.emplace_back(line - m_lastLine);
|
||||
if (line == m_lastLine)
|
||||
m_encodedTokens.append(startChar - m_lastStartChar);
|
||||
m_encodedTokens.emplace_back(startChar - m_lastStartChar);
|
||||
else
|
||||
m_encodedTokens.append(startChar);
|
||||
m_encodedTokens.append(length);
|
||||
m_encodedTokens.append(static_cast<int>(_tokenType));
|
||||
m_encodedTokens.append(static_cast<int>(_modifiers));
|
||||
m_encodedTokens.emplace_back(startChar);
|
||||
m_encodedTokens.emplace_back(length);
|
||||
m_encodedTokens.emplace_back(static_cast<int>(_tokenType));
|
||||
m_encodedTokens.emplace_back(static_cast<int>(_modifiers));
|
||||
|
||||
m_lastLine = line;
|
||||
m_lastStartChar = startChar;
|
||||
|
@ -17,7 +17,8 @@
|
||||
// SPDX-License-Identifier: GPL-3.0
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
#include <json/json.h>
|
||||
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@ -87,7 +88,7 @@ constexpr SemanticTokenModifiers operator|(SemanticTokenModifiers a, SemanticTok
|
||||
class SemanticTokensBuilder: public frontend::ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
Json::Value build(frontend::SourceUnit const& _sourceUnit, langutil::CharStream const& _charStream);
|
||||
Json build(frontend::SourceUnit const& _sourceUnit, langutil::CharStream const& _charStream);
|
||||
|
||||
void reset(langutil::CharStream const* _charStream);
|
||||
void encode(
|
||||
@ -114,7 +115,7 @@ public:
|
||||
bool visit(frontend::VariableDeclaration const&) override;
|
||||
|
||||
private:
|
||||
Json::Value m_encodedTokens;
|
||||
Json m_encodedTokens;
|
||||
langutil::CharStream const* m_charStream;
|
||||
int m_lastLine;
|
||||
int m_lastStartChar;
|
||||
|
@ -41,7 +41,7 @@ using namespace std;
|
||||
using namespace solidity::lsp;
|
||||
|
||||
// {{{ Transport
|
||||
optional<Json::Value> Transport::receive()
|
||||
optional<Json> Transport::receive()
|
||||
{
|
||||
auto const headers = parseHeaders();
|
||||
if (!headers)
|
||||
@ -58,10 +58,10 @@ optional<Json::Value> Transport::receive()
|
||||
|
||||
string const data = readBytes(stoul(headers->at("content-length")));
|
||||
|
||||
Json::Value jsonMessage;
|
||||
Json jsonMessage;
|
||||
string jsonParsingErrors;
|
||||
solidity::util::jsonParseStrict(data, jsonMessage, &jsonParsingErrors);
|
||||
if (!jsonParsingErrors.empty() || !jsonMessage || !jsonMessage.isObject())
|
||||
if (!jsonParsingErrors.empty() || !jsonMessage || !jsonMessage.is_object())
|
||||
{
|
||||
error({}, ErrorCode::ParseError, "Could not parse RPC JSON payload. " + jsonParsingErrors);
|
||||
return nullopt;
|
||||
@ -70,12 +70,12 @@ optional<Json::Value> Transport::receive()
|
||||
return {std::move(jsonMessage)};
|
||||
}
|
||||
|
||||
void Transport::trace(std::string _message, Json::Value _extra)
|
||||
void Transport::trace(std::string _message, Json _extra)
|
||||
{
|
||||
if (m_logTrace != TraceValue::Off)
|
||||
{
|
||||
Json::Value params;
|
||||
if (_extra.isObject())
|
||||
Json params;
|
||||
if (_extra.is_object())
|
||||
params = std::move(_extra);
|
||||
params["message"] = std::move(_message);
|
||||
notify("$/logTrace", std::move(params));
|
||||
@ -104,34 +104,34 @@ optional<map<string, string>> Transport::parseHeaders()
|
||||
return {std::move(headers)};
|
||||
}
|
||||
|
||||
void Transport::notify(string _method, Json::Value _message)
|
||||
void Transport::notify(string _method, Json _message)
|
||||
{
|
||||
Json::Value json;
|
||||
Json json;
|
||||
json["method"] = std::move(_method);
|
||||
json["params"] = std::move(_message);
|
||||
send(std::move(json));
|
||||
}
|
||||
|
||||
void Transport::reply(MessageID _id, Json::Value _message)
|
||||
void Transport::reply(MessageID _id, Json _message)
|
||||
{
|
||||
Json::Value json;
|
||||
Json json;
|
||||
json["result"] = std::move(_message);
|
||||
send(std::move(json), _id);
|
||||
}
|
||||
|
||||
void Transport::error(MessageID _id, ErrorCode _code, string _message)
|
||||
{
|
||||
Json::Value json;
|
||||
Json json;
|
||||
json["error"]["code"] = static_cast<int>(_code);
|
||||
json["error"]["message"] = std::move(_message);
|
||||
send(std::move(json), _id);
|
||||
}
|
||||
|
||||
void Transport::send(Json::Value _json, MessageID _id)
|
||||
void Transport::send(Json _json, MessageID _id)
|
||||
{
|
||||
solAssert(_json.isObject());
|
||||
solAssert(_json.is_object());
|
||||
_json["jsonrpc"] = "2.0";
|
||||
if (_id != Json::nullValue)
|
||||
if (_id != Json{})
|
||||
_json["id"] = _id;
|
||||
|
||||
// Trailing CRLF only for easier readability.
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <libsolutil/Exceptions.h>
|
||||
|
||||
#include <json/value.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <functional>
|
||||
#include <iosfwd>
|
||||
@ -32,7 +32,7 @@
|
||||
namespace solidity::lsp
|
||||
{
|
||||
|
||||
using MessageID = Json::Value;
|
||||
using MessageID = nlohmann::json;
|
||||
|
||||
enum class TraceValue
|
||||
{
|
||||
@ -98,14 +98,14 @@ class Transport
|
||||
public:
|
||||
virtual ~Transport() = default;
|
||||
|
||||
std::optional<Json::Value> receive();
|
||||
void notify(std::string _method, Json::Value _params);
|
||||
void reply(MessageID _id, Json::Value _result);
|
||||
std::optional<Json> receive();
|
||||
void notify(std::string _method, Json _params);
|
||||
void reply(MessageID _id, Json _result);
|
||||
void error(MessageID _id, ErrorCode _code, std::string _message);
|
||||
|
||||
virtual bool closed() const noexcept = 0;
|
||||
|
||||
void trace(std::string _message, Json::Value _extra = Json::nullValue);
|
||||
void trace(std::string _message, Json _extra = Json{});
|
||||
|
||||
TraceValue traceValue() const noexcept { return m_logTrace; }
|
||||
void setTrace(TraceValue _value) noexcept { m_logTrace = _value; }
|
||||
@ -135,7 +135,7 @@ protected:
|
||||
/// Sends an arbitrary raw message to the client.
|
||||
///
|
||||
/// Used by the notify/reply/error function family.
|
||||
virtual void send(Json::Value _message, MessageID _id = Json::nullValue);
|
||||
virtual void send(Json _message, MessageID _id = Json{});
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -32,26 +32,26 @@ using namespace frontend;
|
||||
using namespace langutil;
|
||||
using namespace std;
|
||||
|
||||
optional<LineColumn> parseLineColumn(Json::Value const& _lineColumn)
|
||||
optional<LineColumn> parseLineColumn(Json const& _lineColumn)
|
||||
{
|
||||
if (_lineColumn.isObject() && _lineColumn["line"].isInt() && _lineColumn["character"].isInt())
|
||||
return LineColumn{_lineColumn["line"].asInt(), _lineColumn["character"].asInt()};
|
||||
if (_lineColumn.is_object() && _lineColumn["line"].is_number_integer() && _lineColumn["character"].is_number_integer())
|
||||
return LineColumn{_lineColumn["line"].get<int>(), _lineColumn["character"].get<int>()};
|
||||
else
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
Json::Value toJson(LineColumn const& _pos)
|
||||
Json toJson(LineColumn const& _pos)
|
||||
{
|
||||
Json::Value json = Json::objectValue;
|
||||
Json json = Json::object();
|
||||
json["line"] = max(_pos.line, 0);
|
||||
json["character"] = max(_pos.column, 0);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
Json::Value toJsonRange(LineColumn const& _start, LineColumn const& _end)
|
||||
Json toJsonRange(LineColumn const& _start, LineColumn const& _end)
|
||||
{
|
||||
Json::Value json;
|
||||
Json json;
|
||||
json["start"] = toJson(_start);
|
||||
json["end"] = toJson(_end);
|
||||
return json;
|
||||
@ -87,7 +87,7 @@ optional<SourceLocation> declarationLocation(Declaration const* _declaration)
|
||||
optional<SourceLocation> parsePosition(
|
||||
FileRepository const& _fileRepository,
|
||||
string const& _sourceUnitName,
|
||||
Json::Value const& _position
|
||||
Json const& _position
|
||||
)
|
||||
{
|
||||
if (!_fileRepository.sourceUnits().count(_sourceUnitName))
|
||||
@ -102,9 +102,9 @@ optional<SourceLocation> parsePosition(
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<SourceLocation> parseRange(FileRepository const& _fileRepository, string const& _sourceUnitName, Json::Value const& _range)
|
||||
optional<SourceLocation> parseRange(FileRepository const& _fileRepository, string const& _sourceUnitName, Json const& _range)
|
||||
{
|
||||
if (!_range.isObject())
|
||||
if (!_range.is_object())
|
||||
return nullopt;
|
||||
optional<SourceLocation> start = parsePosition(_fileRepository, _sourceUnitName, _range["start"]);
|
||||
optional<SourceLocation> end = parsePosition(_fileRepository, _sourceUnitName, _range["end"]);
|
||||
|
@ -44,16 +44,16 @@ namespace solidity::lsp
|
||||
|
||||
class FileRepository;
|
||||
|
||||
std::optional<langutil::LineColumn> parseLineColumn(Json::Value const& _lineColumn);
|
||||
Json::Value toJson(langutil::LineColumn const& _pos);
|
||||
Json::Value toJsonRange(langutil::LineColumn const& _start, langutil::LineColumn const& _end);
|
||||
std::optional<langutil::LineColumn> parseLineColumn(Json const& _lineColumn);
|
||||
Json toJson(langutil::LineColumn const& _pos);
|
||||
Json toJsonRange(langutil::LineColumn const& _start, langutil::LineColumn const& _end);
|
||||
|
||||
/// @returns the source location given a source unit name and an LSP Range object,
|
||||
/// or nullopt on failure.
|
||||
std::optional<langutil::SourceLocation> parsePosition(
|
||||
FileRepository const& _fileRepository,
|
||||
std::string const& _sourceUnitName,
|
||||
Json::Value const& _position
|
||||
Json const& _position
|
||||
);
|
||||
|
||||
/// @returns the source location given a source unit name and an LSP Range object,
|
||||
@ -61,7 +61,7 @@ std::optional<langutil::SourceLocation> parsePosition(
|
||||
std::optional<langutil::SourceLocation> parseRange(
|
||||
FileRepository const& _fileRepository,
|
||||
std::string const& _sourceUnitName,
|
||||
Json::Value const& _range
|
||||
Json const& _range
|
||||
);
|
||||
|
||||
/// Strips the file:// URI prefix off the given path, if present,
|
||||
|
@ -43,7 +43,7 @@ set(sources
|
||||
)
|
||||
|
||||
add_library(solutil ${sources})
|
||||
target_link_libraries(solutil PUBLIC jsoncpp Boost::boost Boost::filesystem Boost::system range-v3)
|
||||
target_link_libraries(solutil PUBLIC Boost::boost Boost::filesystem Boost::system range-v3)
|
||||
target_include_directories(solutil PUBLIC "${CMAKE_SOURCE_DIR}")
|
||||
add_dependencies(solutil solidity_BuildInfo.h)
|
||||
|
||||
|
@ -33,8 +33,8 @@
|
||||
using namespace std;
|
||||
|
||||
static_assert(
|
||||
(JSONCPP_VERSION_MAJOR == 1) && (JSONCPP_VERSION_MINOR == 9) && (JSONCPP_VERSION_PATCH == 3),
|
||||
"Unexpected jsoncpp version: " JSONCPP_VERSION_STRING ". Expecting 1.9.3."
|
||||
(NLOHMANN_JSON_VERSION_MAJOR == 3) && (NLOHMANN_JSON_VERSION_MINOR == 10) && (NLOHMANN_JSON_VERSION_PATCH == 2),
|
||||
"Unexpected nlohmann-json version. Expecting 3.10.2."
|
||||
);
|
||||
|
||||
namespace solidity::util
|
||||
@ -43,53 +43,9 @@ namespace solidity::util
|
||||
namespace
|
||||
{
|
||||
|
||||
/// StreamWriterBuilder that can be constructed with specific settings
|
||||
class StreamWriterBuilder: public Json::StreamWriterBuilder
|
||||
{
|
||||
public:
|
||||
explicit StreamWriterBuilder(map<string, Json::Value> const& _settings)
|
||||
{
|
||||
for (auto const& iter: _settings)
|
||||
this->settings_[iter.first] = iter.second;
|
||||
}
|
||||
};
|
||||
|
||||
/// CharReaderBuilder with strict-mode settings
|
||||
class StrictModeCharReaderBuilder: public Json::CharReaderBuilder
|
||||
{
|
||||
public:
|
||||
StrictModeCharReaderBuilder()
|
||||
{
|
||||
Json::CharReaderBuilder::strictMode(&this->settings_);
|
||||
}
|
||||
};
|
||||
|
||||
/// Serialise the JSON object (@a _input) with specific builder (@a _builder)
|
||||
/// \param _input JSON input string
|
||||
/// \param _builder StreamWriterBuilder that is used to create new Json::StreamWriter
|
||||
/// \return serialized json object
|
||||
string print(Json::Value const& _input, Json::StreamWriterBuilder const& _builder)
|
||||
{
|
||||
stringstream stream;
|
||||
unique_ptr<Json::StreamWriter> writer(_builder.newStreamWriter());
|
||||
writer->write(_input, &stream);
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
/// Parse a JSON string (@a _input) with specified builder (@ _builder) and writes resulting JSON object to (@a _json)
|
||||
/// \param _builder CharReaderBuilder that is used to create new Json::CharReaders
|
||||
/// \param _input JSON input string
|
||||
/// \param _json [out] resulting JSON object
|
||||
/// \param _errs [out] Formatted error messages
|
||||
/// \return \c true if the document was successfully parsed, \c false if an error occurred.
|
||||
bool parse(Json::CharReaderBuilder& _builder, string const& _input, Json::Value& _json, string* _errs)
|
||||
{
|
||||
unique_ptr<Json::CharReader> reader(_builder.newCharReader());
|
||||
return reader->parse(_input.c_str(), _input.c_str() + _input.length(), &_json, _errs);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/// Takes a JSON value (@ _json) and removes all its members with value 'null' recursively.
|
||||
void removeNullMembersHelper(Json::Value& _json)
|
||||
void removeNullMembersHelper(Json& _json)
|
||||
{
|
||||
if (_json.type() == Json::ValueType::arrayValue)
|
||||
for (auto& child: _json)
|
||||
@ -104,46 +60,54 @@ void removeNullMembersHelper(Json::Value& _json)
|
||||
removeNullMembersHelper(value);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
Json::Value removeNullMembers(Json::Value _json)
|
||||
Json removeNullMembers(Json _json)
|
||||
{
|
||||
removeNullMembersHelper(_json);
|
||||
// TODO: Support this.
|
||||
// removeNullMembersHelper(_json);
|
||||
return _json;
|
||||
}
|
||||
|
||||
string jsonPrettyPrint(Json::Value const& _input)
|
||||
string jsonPrettyPrint(Json const& _input)
|
||||
{
|
||||
return jsonPrint(_input, JsonFormat{ JsonFormat::Pretty });
|
||||
}
|
||||
|
||||
string jsonCompactPrint(Json::Value const& _input)
|
||||
string jsonCompactPrint(Json const& _input)
|
||||
{
|
||||
return jsonPrint(_input, JsonFormat{ JsonFormat::Compact });
|
||||
}
|
||||
|
||||
string jsonPrint(Json::Value const& _input, JsonFormat const& _format)
|
||||
string jsonPrint(Json const& _input, JsonFormat const& _format)
|
||||
{
|
||||
map<string, Json::Value> settings;
|
||||
if (_format.format == JsonFormat::Pretty)
|
||||
{
|
||||
settings["indentation"] = string(_format.indent, ' ');
|
||||
settings["enableYAMLCompatibility"] = true;
|
||||
}
|
||||
else
|
||||
settings["indentation"] = "";
|
||||
StreamWriterBuilder writerBuilder(settings);
|
||||
string result = print(_input, writerBuilder);
|
||||
if (_format.format == JsonFormat::Pretty)
|
||||
boost::replace_all(result, " \n", "\n");
|
||||
return result;
|
||||
// NOTE: -1 here means no new lines (it is also the default setting)
|
||||
return _input.dump(
|
||||
/* indent */ (_format.format == JsonFormat::Pretty) ? static_cast<int>(_format.indent) : -1,
|
||||
/* indent_char */ ' ',
|
||||
/* ensure_ascii */ true
|
||||
);
|
||||
}
|
||||
|
||||
bool jsonParseStrict(string const& _input, Json::Value& _json, string* _errs /* = nullptr */)
|
||||
bool jsonParseStrict(string const& _input, Json& _json, string* _errs /* = nullptr */)
|
||||
{
|
||||
static StrictModeCharReaderBuilder readerBuilder;
|
||||
return parse(readerBuilder, _input, _json, _errs);
|
||||
try
|
||||
{
|
||||
_json = Json::parse(_input);
|
||||
_errs = {};
|
||||
return true;
|
||||
}
|
||||
catch (Json::parse_error const& e)
|
||||
{
|
||||
// NOTE: e.id() gives the code and e.byte() gives the byte offset
|
||||
if (_errs)
|
||||
{
|
||||
*_errs = e.what();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace solidity::util
|
||||
|
@ -23,15 +23,17 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include <json/json.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
using Json = nlohmann::json;
|
||||
|
||||
namespace solidity::util
|
||||
{
|
||||
|
||||
/// Removes members with null value recursively from (@a _json).
|
||||
Json::Value removeNullMembers(Json::Value _json);
|
||||
Json removeNullMembers(Json _json);
|
||||
|
||||
/// JSON printing format.
|
||||
struct JsonFormat
|
||||
@ -52,20 +54,20 @@ struct JsonFormat
|
||||
};
|
||||
|
||||
/// Serialise the JSON object (@a _input) with indentation
|
||||
std::string jsonPrettyPrint(Json::Value const& _input);
|
||||
std::string jsonPrettyPrint(Json const& _input);
|
||||
|
||||
/// Serialise the JSON object (@a _input) without indentation
|
||||
std::string jsonCompactPrint(Json::Value const& _input);
|
||||
std::string jsonCompactPrint(Json const& _input);
|
||||
|
||||
/// Serialise the JSON object (@a _input) using specified format (@a _format)
|
||||
std::string jsonPrint(Json::Value const& _input, JsonFormat const& _format);
|
||||
std::string jsonPrint(Json const& _input, JsonFormat const& _format);
|
||||
|
||||
/// Parse a JSON string (@a _input) with enabled strict-mode and writes resulting JSON object to (@a _json)
|
||||
/// \param _input JSON input string
|
||||
/// \param _json [out] resulting JSON object
|
||||
/// \param _errs [out] Formatted error messages
|
||||
/// \return \c true if the document was successfully parsed, \c false if an error occurred.
|
||||
bool jsonParseStrict(std::string const& _input, Json::Value& _json, std::string* _errs = nullptr);
|
||||
bool jsonParseStrict(std::string const& _input, Json& _json, std::string* _errs = nullptr);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
@ -31,25 +31,25 @@ using namespace std;
|
||||
namespace solidity::yul
|
||||
{
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Block const& _node) const
|
||||
Json AsmJsonConverter::operator()(Block const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulBlock");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulBlock");
|
||||
ret["statements"] = vectorOfVariantsToJson(_node.statements);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(TypedName const& _node) const
|
||||
Json AsmJsonConverter::operator()(TypedName const& _node) const
|
||||
{
|
||||
yulAssert(!_node.name.empty(), "Invalid variable name.");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulTypedName");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulTypedName");
|
||||
ret["name"] = _node.name.str();
|
||||
ret["type"] = _node.type.str();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Literal const& _node) const
|
||||
Json AsmJsonConverter::operator()(Literal const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulLiteral");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulLiteral");
|
||||
switch (_node.kind)
|
||||
{
|
||||
case LiteralKind::Number:
|
||||
@ -73,94 +73,92 @@ Json::Value AsmJsonConverter::operator()(Literal const& _node) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Identifier const& _node) const
|
||||
Json AsmJsonConverter::operator()(Identifier const& _node) const
|
||||
{
|
||||
yulAssert(!_node.name.empty(), "Invalid identifier");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulIdentifier");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulIdentifier");
|
||||
ret["name"] = _node.name.str();
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Assignment const& _node) const
|
||||
Json AsmJsonConverter::operator()(Assignment const& _node) const
|
||||
{
|
||||
yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulAssignment");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulAssignment");
|
||||
for (auto const& var: _node.variableNames)
|
||||
ret["variableNames"].append((*this)(var));
|
||||
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue;
|
||||
ret["variableNames"].emplace_back((*this)(var));
|
||||
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json{};
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const
|
||||
Json AsmJsonConverter::operator()(FunctionCall const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulFunctionCall");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulFunctionCall");
|
||||
ret["functionName"] = (*this)(_node.functionName);
|
||||
ret["arguments"] = vectorOfVariantsToJson(_node.arguments);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(ExpressionStatement const& _node) const
|
||||
Json AsmJsonConverter::operator()(ExpressionStatement const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulExpressionStatement");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulExpressionStatement");
|
||||
ret["expression"] = std::visit(*this, _node.expression);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const
|
||||
Json AsmJsonConverter::operator()(VariableDeclaration const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulVariableDeclaration");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulVariableDeclaration");
|
||||
for (auto const& var: _node.variables)
|
||||
ret["variables"].append((*this)(var));
|
||||
|
||||
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue;
|
||||
|
||||
ret["variables"].emplace_back((*this)(var));
|
||||
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json{};
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const
|
||||
Json AsmJsonConverter::operator()(FunctionDefinition const& _node) const
|
||||
{
|
||||
yulAssert(!_node.name.empty(), "Invalid function name.");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulFunctionDefinition");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulFunctionDefinition");
|
||||
ret["name"] = _node.name.str();
|
||||
for (auto const& var: _node.parameters)
|
||||
ret["parameters"].append((*this)(var));
|
||||
ret["parameters"].emplace_back((*this)(var));
|
||||
for (auto const& var: _node.returnVariables)
|
||||
ret["returnVariables"].append((*this)(var));
|
||||
ret["returnVariables"].emplace_back((*this)(var));
|
||||
ret["body"] = (*this)(_node.body);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(If const& _node) const
|
||||
Json AsmJsonConverter::operator()(If const& _node) const
|
||||
{
|
||||
yulAssert(_node.condition, "Invalid if condition.");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulIf");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulIf");
|
||||
ret["condition"] = std::visit(*this, *_node.condition);
|
||||
ret["body"] = (*this)(_node.body);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Switch const& _node) const
|
||||
Json AsmJsonConverter::operator()(Switch const& _node) const
|
||||
{
|
||||
yulAssert(_node.expression, "Invalid expression pointer.");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulSwitch");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulSwitch");
|
||||
ret["expression"] = std::visit(*this, *_node.expression);
|
||||
for (auto const& var: _node.cases)
|
||||
ret["cases"].append((*this)(var));
|
||||
ret["cases"].emplace_back((*this)(var));
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Case const& _node) const
|
||||
Json AsmJsonConverter::operator()(Case const& _node) const
|
||||
{
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulCase");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulCase");
|
||||
ret["value"] = _node.value ? (*this)(*_node.value) : "default";
|
||||
ret["body"] = (*this)(_node.body);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
|
||||
Json AsmJsonConverter::operator()(ForLoop const& _node) const
|
||||
{
|
||||
yulAssert(_node.condition, "Invalid for loop condition.");
|
||||
Json::Value ret = createAstNode(nativeLocationOf(_node), "YulForLoop");
|
||||
Json ret = createAstNode(nativeLocationOf(_node), "YulForLoop");
|
||||
ret["pre"] = (*this)(_node.pre);
|
||||
ret["condition"] = std::visit(*this, *_node.condition);
|
||||
ret["post"] = (*this)(_node.post);
|
||||
@ -168,24 +166,24 @@ Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Break const& _node) const
|
||||
Json AsmJsonConverter::operator()(Break const& _node) const
|
||||
{
|
||||
return createAstNode(nativeLocationOf(_node), "YulBreak");
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Continue const& _node) const
|
||||
Json AsmJsonConverter::operator()(Continue const& _node) const
|
||||
{
|
||||
return createAstNode(nativeLocationOf(_node), "YulContinue");
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::operator()(Leave const& _node) const
|
||||
Json AsmJsonConverter::operator()(Leave const& _node) const
|
||||
{
|
||||
return createAstNode(nativeLocationOf(_node), "YulLeave");
|
||||
}
|
||||
|
||||
Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const
|
||||
Json AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const
|
||||
{
|
||||
Json::Value ret{Json::objectValue};
|
||||
Json ret{Json::object()};
|
||||
ret["nodeType"] = std::move(_nodeType);
|
||||
int length = -1;
|
||||
if (_location.start >= 0 && _location.end >= 0)
|
||||
@ -195,11 +193,11 @@ Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _loc
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Json::Value AsmJsonConverter::vectorOfVariantsToJson(vector<T> const& _vec) const
|
||||
Json AsmJsonConverter::vectorOfVariantsToJson(vector<T> const& _vec) const
|
||||
{
|
||||
Json::Value ret{Json::arrayValue};
|
||||
Json ret{Json::array()};
|
||||
for (auto const& var: _vec)
|
||||
ret.append(std::visit(*this, var));
|
||||
ret.emplace_back(std::visit(*this, var));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <libyul/ASTForward.h>
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
#include <json/json.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
@ -36,35 +36,35 @@ namespace solidity::yul
|
||||
/**
|
||||
* Converter of the yul AST into JSON format
|
||||
*/
|
||||
class AsmJsonConverter: public boost::static_visitor<Json::Value>
|
||||
class AsmJsonConverter: public boost::static_visitor<Json>
|
||||
{
|
||||
public:
|
||||
/// Create a converter to JSON for any block of inline assembly
|
||||
/// @a _sourceIndex to be used to abbreviate source name in the source locations
|
||||
explicit AsmJsonConverter(std::optional<size_t> _sourceIndex): m_sourceIndex(_sourceIndex) {}
|
||||
|
||||
Json::Value operator()(Block const& _node) const;
|
||||
Json::Value operator()(TypedName const& _node) const;
|
||||
Json::Value operator()(Literal const& _node) const;
|
||||
Json::Value operator()(Identifier const& _node) const;
|
||||
Json::Value operator()(Assignment const& _node) const;
|
||||
Json::Value operator()(VariableDeclaration const& _node) const;
|
||||
Json::Value operator()(FunctionDefinition const& _node) const;
|
||||
Json::Value operator()(FunctionCall const& _node) const;
|
||||
Json::Value operator()(If const& _node) const;
|
||||
Json::Value operator()(Switch const& _node) const;
|
||||
Json::Value operator()(Case const& _node) const;
|
||||
Json::Value operator()(ForLoop const& _node) const;
|
||||
Json::Value operator()(Break const& _node) const;
|
||||
Json::Value operator()(Continue const& _node) const;
|
||||
Json::Value operator()(Leave const& _node) const;
|
||||
Json::Value operator()(ExpressionStatement const& _node) const;
|
||||
Json::Value operator()(Label const& _node) const;
|
||||
Json operator()(Block const& _node) const;
|
||||
Json operator()(TypedName const& _node) const;
|
||||
Json operator()(Literal const& _node) const;
|
||||
Json operator()(Identifier const& _node) const;
|
||||
Json operator()(Assignment const& _node) const;
|
||||
Json operator()(VariableDeclaration const& _node) const;
|
||||
Json operator()(FunctionDefinition const& _node) const;
|
||||
Json operator()(FunctionCall const& _node) const;
|
||||
Json operator()(If const& _node) const;
|
||||
Json operator()(Switch const& _node) const;
|
||||
Json operator()(Case const& _node) const;
|
||||
Json operator()(ForLoop const& _node) const;
|
||||
Json operator()(Break const& _node) const;
|
||||
Json operator()(Continue const& _node) const;
|
||||
Json operator()(Leave const& _node) const;
|
||||
Json operator()(ExpressionStatement const& _node) const;
|
||||
Json operator()(Label const& _node) const;
|
||||
|
||||
private:
|
||||
Json::Value createAstNode(langutil::SourceLocation const& _location, std::string _nodeType) const;
|
||||
Json createAstNode(langutil::SourceLocation const& _location, std::string _nodeType) const;
|
||||
template <class T>
|
||||
Json::Value vectorOfVariantsToJson(std::vector<T> const& vec) const;
|
||||
Json vectorOfVariantsToJson(std::vector<T> const& vec) const;
|
||||
|
||||
std::optional<size_t> const m_sourceIndex;
|
||||
};
|
||||
|
@ -42,15 +42,15 @@ namespace solidity::yul
|
||||
|
||||
using SourceLocation = langutil::SourceLocation;
|
||||
|
||||
SourceLocation const AsmJsonImporter::createSourceLocation(Json::Value const& _node)
|
||||
SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node)
|
||||
{
|
||||
yulAssert(member(_node, "src").isString(), "'src' must be a string");
|
||||
yulAssert(member(_node, "src").is_string(), "'src' must be a string");
|
||||
|
||||
return solidity::langutil::parseSourceLocation(_node["src"].asString(), m_sourceNames);
|
||||
return solidity::langutil::parseSourceLocation(_node["src"].get<string>(), m_sourceNames);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T AsmJsonImporter::createAsmNode(Json::Value const& _node)
|
||||
T AsmJsonImporter::createAsmNode(Json const& _node)
|
||||
{
|
||||
T r;
|
||||
SourceLocation nativeLocation = createSourceLocation(_node);
|
||||
@ -62,26 +62,26 @@ T AsmJsonImporter::createAsmNode(Json::Value const& _node)
|
||||
return r;
|
||||
}
|
||||
|
||||
Json::Value AsmJsonImporter::member(Json::Value const& _node, string const& _name)
|
||||
Json AsmJsonImporter::member(Json const& _node, string const& _name)
|
||||
{
|
||||
if (!_node.isMember(_name))
|
||||
return Json::nullValue;
|
||||
if (!_node.contains(_name))
|
||||
return Json{};
|
||||
return _node[_name];
|
||||
}
|
||||
|
||||
TypedName AsmJsonImporter::createTypedName(Json::Value const& _node)
|
||||
TypedName AsmJsonImporter::createTypedName(Json const& _node)
|
||||
{
|
||||
auto typedName = createAsmNode<TypedName>(_node);
|
||||
typedName.type = YulString{member(_node, "type").asString()};
|
||||
typedName.name = YulString{member(_node, "name").asString()};
|
||||
typedName.type = YulString{member(_node, "type").get<string>()};
|
||||
typedName.name = YulString{member(_node, "name").get<string>()};
|
||||
return typedName;
|
||||
}
|
||||
|
||||
Statement AsmJsonImporter::createStatement(Json::Value const& _node)
|
||||
Statement AsmJsonImporter::createStatement(Json const& _node)
|
||||
{
|
||||
Json::Value jsonNodeType = member(_node, "nodeType");
|
||||
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
||||
string nodeType = jsonNodeType.asString();
|
||||
Json jsonNodeType = member(_node, "nodeType");
|
||||
yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!");
|
||||
string nodeType = jsonNodeType.get<string>();
|
||||
|
||||
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
||||
nodeType = nodeType.substr(3);
|
||||
@ -115,11 +115,11 @@ Statement AsmJsonImporter::createStatement(Json::Value const& _node)
|
||||
util::unreachable();
|
||||
}
|
||||
|
||||
Expression AsmJsonImporter::createExpression(Json::Value const& _node)
|
||||
Expression AsmJsonImporter::createExpression(Json const& _node)
|
||||
{
|
||||
Json::Value jsonNodeType = member(_node, "nodeType");
|
||||
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
||||
string nodeType = jsonNodeType.asString();
|
||||
Json jsonNodeType = member(_node, "nodeType");
|
||||
yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!");
|
||||
string nodeType = jsonNodeType.get<string>();
|
||||
|
||||
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
||||
nodeType = nodeType.substr(3);
|
||||
@ -137,7 +137,7 @@ Expression AsmJsonImporter::createExpression(Json::Value const& _node)
|
||||
util::unreachable();
|
||||
}
|
||||
|
||||
vector<Expression> AsmJsonImporter::createExpressionVector(Json::Value const& _array)
|
||||
vector<Expression> AsmJsonImporter::createExpressionVector(Json const& _array)
|
||||
{
|
||||
vector<Expression> ret;
|
||||
for (auto& var: _array)
|
||||
@ -145,7 +145,7 @@ vector<Expression> AsmJsonImporter::createExpressionVector(Json::Value const& _a
|
||||
return ret;
|
||||
}
|
||||
|
||||
vector<Statement> AsmJsonImporter::createStatementVector(Json::Value const& _array)
|
||||
vector<Statement> AsmJsonImporter::createStatementVector(Json const& _array)
|
||||
{
|
||||
vector<Statement> ret;
|
||||
for (auto& var: _array)
|
||||
@ -153,25 +153,25 @@ vector<Statement> AsmJsonImporter::createStatementVector(Json::Value const& _arr
|
||||
return ret;
|
||||
}
|
||||
|
||||
Block AsmJsonImporter::createBlock(Json::Value const& _node)
|
||||
Block AsmJsonImporter::createBlock(Json const& _node)
|
||||
{
|
||||
auto block = createAsmNode<Block>(_node);
|
||||
block.statements = createStatementVector(_node["statements"]);
|
||||
return block;
|
||||
}
|
||||
|
||||
Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
||||
Literal AsmJsonImporter::createLiteral(Json const& _node)
|
||||
{
|
||||
auto lit = createAsmNode<Literal>(_node);
|
||||
string kind = member(_node, "kind").asString();
|
||||
string kind = member(_node, "kind").get<string>();
|
||||
|
||||
solAssert(member(_node, "hexValue").isString() || member(_node, "value").isString(), "");
|
||||
if (_node.isMember("hexValue"))
|
||||
lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").asString()))};
|
||||
solAssert(member(_node, "hexValue").is_string() || member(_node, "value").is_string(), "");
|
||||
if (_node.contains("hexValue"))
|
||||
lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").get<string>()))};
|
||||
else
|
||||
lit.value = YulString{member(_node, "value").asString()};
|
||||
lit.value = YulString{member(_node, "value").get<string>()};
|
||||
|
||||
lit.type= YulString{member(_node, "type").asString()};
|
||||
lit.type= YulString{member(_node, "type").get<string>()};
|
||||
|
||||
if (kind == "number")
|
||||
{
|
||||
@ -208,23 +208,23 @@ Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
||||
return lit;
|
||||
}
|
||||
|
||||
Leave AsmJsonImporter::createLeave(Json::Value const& _node)
|
||||
Leave AsmJsonImporter::createLeave(Json const& _node)
|
||||
{
|
||||
return createAsmNode<Leave>(_node);
|
||||
}
|
||||
|
||||
Identifier AsmJsonImporter::createIdentifier(Json::Value const& _node)
|
||||
Identifier AsmJsonImporter::createIdentifier(Json const& _node)
|
||||
{
|
||||
auto identifier = createAsmNode<Identifier>(_node);
|
||||
identifier.name = YulString(member(_node, "name").asString());
|
||||
identifier.name = YulString(member(_node, "name").get<string>());
|
||||
return identifier;
|
||||
}
|
||||
|
||||
Assignment AsmJsonImporter::createAssignment(Json::Value const& _node)
|
||||
Assignment AsmJsonImporter::createAssignment(Json const& _node)
|
||||
{
|
||||
auto assignment = createAsmNode<Assignment>(_node);
|
||||
|
||||
if (_node.isMember("variableNames"))
|
||||
if (_node.contains("variableNames"))
|
||||
for (auto const& var: member(_node, "variableNames"))
|
||||
assignment.variableNames.emplace_back(createIdentifier(var));
|
||||
|
||||
@ -232,7 +232,7 @@ Assignment AsmJsonImporter::createAssignment(Json::Value const& _node)
|
||||
return assignment;
|
||||
}
|
||||
|
||||
FunctionCall AsmJsonImporter::createFunctionCall(Json::Value const& _node)
|
||||
FunctionCall AsmJsonImporter::createFunctionCall(Json const& _node)
|
||||
{
|
||||
auto functionCall = createAsmNode<FunctionCall>(_node);
|
||||
|
||||
@ -244,14 +244,14 @@ FunctionCall AsmJsonImporter::createFunctionCall(Json::Value const& _node)
|
||||
return functionCall;
|
||||
}
|
||||
|
||||
ExpressionStatement AsmJsonImporter::createExpressionStatement(Json::Value const& _node)
|
||||
ExpressionStatement AsmJsonImporter::createExpressionStatement(Json const& _node)
|
||||
{
|
||||
auto statement = createAsmNode<ExpressionStatement>(_node);
|
||||
statement.expression = createExpression(member(_node, "expression"));
|
||||
return statement;
|
||||
}
|
||||
|
||||
VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json::Value const& _node)
|
||||
VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node)
|
||||
{
|
||||
auto varDec = createAsmNode<VariableDeclaration>(_node);
|
||||
for (auto const& var: member(_node, "variables"))
|
||||
@ -260,16 +260,16 @@ VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json::Value const
|
||||
return varDec;
|
||||
}
|
||||
|
||||
FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json::Value const& _node)
|
||||
FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node)
|
||||
{
|
||||
auto funcDef = createAsmNode<FunctionDefinition>(_node);
|
||||
funcDef.name = YulString{member(_node, "name").asString()};
|
||||
funcDef.name = YulString{member(_node, "name").get<string>()};
|
||||
|
||||
if (_node.isMember("parameters"))
|
||||
if (_node.contains("parameters"))
|
||||
for (auto const& var: member(_node, "parameters"))
|
||||
funcDef.parameters.emplace_back(createTypedName(var));
|
||||
|
||||
if (_node.isMember("returnVariables"))
|
||||
if (_node.contains("returnVariables"))
|
||||
for (auto const& var: member(_node, "returnVariables"))
|
||||
funcDef.returnVariables.emplace_back(createTypedName(var));
|
||||
|
||||
@ -277,7 +277,7 @@ FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json::Value const&
|
||||
return funcDef;
|
||||
}
|
||||
|
||||
If AsmJsonImporter::createIf(Json::Value const& _node)
|
||||
If AsmJsonImporter::createIf(Json const& _node)
|
||||
{
|
||||
auto ifStatement = createAsmNode<If>(_node);
|
||||
ifStatement.condition = make_unique<Expression>(createExpression(member(_node, "condition")));
|
||||
@ -285,19 +285,19 @@ If AsmJsonImporter::createIf(Json::Value const& _node)
|
||||
return ifStatement;
|
||||
}
|
||||
|
||||
Case AsmJsonImporter::createCase(Json::Value const& _node)
|
||||
Case AsmJsonImporter::createCase(Json const& _node)
|
||||
{
|
||||
auto caseStatement = createAsmNode<Case>(_node);
|
||||
auto const& value = member(_node, "value");
|
||||
if (value.isString())
|
||||
yulAssert(value.asString() == "default", "Expected default case");
|
||||
if (value.is_string())
|
||||
yulAssert(value.get<string>() == "default", "Expected default case");
|
||||
else
|
||||
caseStatement.value = make_unique<Literal>(createLiteral(value));
|
||||
caseStatement.body = createBlock(member(_node, "body"));
|
||||
return caseStatement;
|
||||
}
|
||||
|
||||
Switch AsmJsonImporter::createSwitch(Json::Value const& _node)
|
||||
Switch AsmJsonImporter::createSwitch(Json const& _node)
|
||||
{
|
||||
auto switchStatement = createAsmNode<Switch>(_node);
|
||||
switchStatement.expression = make_unique<Expression>(createExpression(member(_node, "expression")));
|
||||
@ -306,7 +306,7 @@ Switch AsmJsonImporter::createSwitch(Json::Value const& _node)
|
||||
return switchStatement;
|
||||
}
|
||||
|
||||
ForLoop AsmJsonImporter::createForLoop(Json::Value const& _node)
|
||||
ForLoop AsmJsonImporter::createForLoop(Json const& _node)
|
||||
{
|
||||
auto forLoop = createAsmNode<ForLoop>(_node);
|
||||
forLoop.pre = createBlock(member(_node, "pre"));
|
||||
@ -316,12 +316,12 @@ ForLoop AsmJsonImporter::createForLoop(Json::Value const& _node)
|
||||
return forLoop;
|
||||
}
|
||||
|
||||
Break AsmJsonImporter::createBreak(Json::Value const& _node)
|
||||
Break AsmJsonImporter::createBreak(Json const& _node)
|
||||
{
|
||||
return createAsmNode<Break>(_node);
|
||||
}
|
||||
|
||||
Continue AsmJsonImporter::createContinue(Json::Value const& _node)
|
||||
Continue AsmJsonImporter::createContinue(Json const& _node)
|
||||
{
|
||||
return createAsmNode<Continue>(_node);
|
||||
}
|
||||
|
@ -23,8 +23,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <json/json.h>
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
#include <libyul/ASTForward.h>
|
||||
|
||||
#include <utility>
|
||||
@ -41,36 +41,36 @@ public:
|
||||
explicit AsmJsonImporter(std::vector<std::shared_ptr<std::string const>> const& _sourceNames):
|
||||
m_sourceNames(_sourceNames)
|
||||
{}
|
||||
yul::Block createBlock(Json::Value const& _node);
|
||||
yul::Block createBlock(Json const& _node);
|
||||
|
||||
private:
|
||||
langutil::SourceLocation const createSourceLocation(Json::Value const& _node);
|
||||
langutil::SourceLocation const createSourceLocation(Json const& _node);
|
||||
template <class T>
|
||||
T createAsmNode(Json::Value const& _node);
|
||||
T createAsmNode(Json const& _node);
|
||||
/// helper function to access member functions of the JSON
|
||||
/// and throw an error if it does not exist
|
||||
Json::Value member(Json::Value const& _node, std::string const& _name);
|
||||
Json member(Json const& _node, std::string const& _name);
|
||||
|
||||
yul::Statement createStatement(Json::Value const& _node);
|
||||
yul::Expression createExpression(Json::Value const& _node);
|
||||
std::vector<yul::Statement> createStatementVector(Json::Value const& _array);
|
||||
std::vector<yul::Expression> createExpressionVector(Json::Value const& _array);
|
||||
yul::Statement createStatement(Json const& _node);
|
||||
yul::Expression createExpression(Json const& _node);
|
||||
std::vector<yul::Statement> createStatementVector(Json const& _array);
|
||||
std::vector<yul::Expression> createExpressionVector(Json const& _array);
|
||||
|
||||
yul::TypedName createTypedName(Json::Value const& _node);
|
||||
yul::Literal createLiteral(Json::Value const& _node);
|
||||
yul::Leave createLeave(Json::Value const& _node);
|
||||
yul::Identifier createIdentifier(Json::Value const& _node);
|
||||
yul::Assignment createAssignment(Json::Value const& _node);
|
||||
yul::FunctionCall createFunctionCall(Json::Value const& _node);
|
||||
yul::ExpressionStatement createExpressionStatement(Json::Value const& _node);
|
||||
yul::VariableDeclaration createVariableDeclaration(Json::Value const& _node);
|
||||
yul::FunctionDefinition createFunctionDefinition(Json::Value const& _node);
|
||||
yul::If createIf(Json::Value const& _node);
|
||||
yul::Case createCase(Json::Value const& _node);
|
||||
yul::Switch createSwitch(Json::Value const& _node);
|
||||
yul::ForLoop createForLoop(Json::Value const& _node);
|
||||
yul::Break createBreak(Json::Value const& _node);
|
||||
yul::Continue createContinue(Json::Value const& _node);
|
||||
yul::TypedName createTypedName(Json const& _node);
|
||||
yul::Literal createLiteral(Json const& _node);
|
||||
yul::Leave createLeave(Json const& _node);
|
||||
yul::Identifier createIdentifier(Json const& _node);
|
||||
yul::Assignment createAssignment(Json const& _node);
|
||||
yul::FunctionCall createFunctionCall(Json const& _node);
|
||||
yul::ExpressionStatement createExpressionStatement(Json const& _node);
|
||||
yul::VariableDeclaration createVariableDeclaration(Json const& _node);
|
||||
yul::FunctionDefinition createFunctionDefinition(Json const& _node);
|
||||
yul::If createIf(Json const& _node);
|
||||
yul::Case createCase(Json const& _node);
|
||||
yul::Switch createSwitch(Json const& _node);
|
||||
yul::ForLoop createForLoop(Json const& _node);
|
||||
yul::Break createBreak(Json const& _node);
|
||||
yul::Continue createContinue(Json const& _node);
|
||||
|
||||
std::vector<std::shared_ptr<std::string const>> const& m_sourceNames;
|
||||
};
|
||||
|
@ -125,9 +125,9 @@ mv solidity solc
|
||||
|
||||
# Fetch dependencies
|
||||
mkdir -p ./solc/deps/downloads/ 2>/dev/null || true
|
||||
wget -O ./solc/deps/downloads/jsoncpp-1.9.3.tar.gz https://github.com/open-source-parsers/jsoncpp/archive/1.9.3.tar.gz
|
||||
wget -O ./solc/deps/downloads/range-v3-0.12.0.tar.gz https://github.com/ericniebler/range-v3/archive/0.12.0.tar.gz
|
||||
wget -O ./solc/deps/downloads/fmt-8.0.1.tar.gz https://github.com/fmtlib/fmt/archive/8.0.1.tar.gz
|
||||
wget -O ./solc/deps/nlohmann/json/json.hpp https://github.com/nlohmann/json/releases/download/v3.10.2/json.hpp
|
||||
|
||||
# Determine version
|
||||
cd solc
|
||||
|
@ -280,23 +280,23 @@ void CommandLineInterface::handleSignatureHashes(string const& _contract)
|
||||
if (!m_options.compiler.outputs.signatureHashes)
|
||||
return;
|
||||
|
||||
Json::Value interfaceSymbols = m_compiler->interfaceSymbols(_contract);
|
||||
Json interfaceSymbols = m_compiler->interfaceSymbols(_contract);
|
||||
string out = "Function signatures:\n";
|
||||
for (auto const& name: interfaceSymbols["methods"].getMemberNames())
|
||||
out += interfaceSymbols["methods"][name].asString() + ": " + name + "\n";
|
||||
for (auto const& [name, value]: interfaceSymbols["methods"].items())
|
||||
out += value.get<string>() + ": " + name + "\n";
|
||||
|
||||
if (interfaceSymbols.isMember("errors"))
|
||||
if (interfaceSymbols.contains("errors"))
|
||||
{
|
||||
out += "\nError signatures:\n";
|
||||
for (auto const& name: interfaceSymbols["errors"].getMemberNames())
|
||||
out += interfaceSymbols["errors"][name].asString() + ": " + name + "\n";
|
||||
for (auto const& [name, value]: interfaceSymbols["errors"].items())
|
||||
out += value.get<string>() + ": " + name + "\n";
|
||||
}
|
||||
|
||||
if (interfaceSymbols.isMember("events"))
|
||||
if (interfaceSymbols.contains("events"))
|
||||
{
|
||||
out += "\nEvent signatures:\n";
|
||||
for (auto const& name: interfaceSymbols["events"].getMemberNames())
|
||||
out += interfaceSymbols["events"][name].asString() + ": " + name + "\n";
|
||||
for (auto const& [name, value]: interfaceSymbols["events"].items())
|
||||
out += value.get<string>() + ": " + name + "\n";
|
||||
}
|
||||
|
||||
if (!m_options.output.dir.empty())
|
||||
@ -394,40 +394,40 @@ void CommandLineInterface::handleGasEstimation(string const& _contract)
|
||||
{
|
||||
solAssert(CompilerInputModes.count(m_options.input.mode) == 1);
|
||||
|
||||
Json::Value estimates = m_compiler->gasEstimates(_contract);
|
||||
Json estimates = m_compiler->gasEstimates(_contract);
|
||||
sout() << "Gas estimation:" << endl;
|
||||
|
||||
if (estimates["creation"].isObject())
|
||||
if (estimates["creation"].is_object())
|
||||
{
|
||||
Json::Value creation = estimates["creation"];
|
||||
Json creation = estimates["creation"];
|
||||
sout() << "construction:" << endl;
|
||||
sout() << " " << creation["executionCost"].asString();
|
||||
sout() << " + " << creation["codeDepositCost"].asString();
|
||||
sout() << " = " << creation["totalCost"].asString() << endl;
|
||||
sout() << " " << creation["executionCost"].get<string>();
|
||||
sout() << " + " << creation["codeDepositCost"].get<string>();
|
||||
sout() << " = " << creation["totalCost"].get<string>() << endl;
|
||||
}
|
||||
|
||||
if (estimates["external"].isObject())
|
||||
if (estimates["external"].is_object())
|
||||
{
|
||||
Json::Value externalFunctions = estimates["external"];
|
||||
Json externalFunctions = estimates["external"];
|
||||
sout() << "external:" << endl;
|
||||
for (auto const& name: externalFunctions.getMemberNames())
|
||||
for (auto const& [name, gas]: externalFunctions.items())
|
||||
{
|
||||
if (name.empty())
|
||||
sout() << " fallback:\t";
|
||||
else
|
||||
sout() << " " << name << ":\t";
|
||||
sout() << externalFunctions[name].asString() << endl;
|
||||
sout() << gas.get<string>() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (estimates["internal"].isObject())
|
||||
if (estimates["internal"].is_object())
|
||||
{
|
||||
Json::Value internalFunctions = estimates["internal"];
|
||||
Json internalFunctions = estimates["internal"];
|
||||
sout() << "internal:" << endl;
|
||||
for (auto const& name: internalFunctions.getMemberNames())
|
||||
for (auto const& [name, gas]: internalFunctions.items())
|
||||
{
|
||||
sout() << " " << name << ":\t";
|
||||
sout() << internalFunctions[name].asString() << endl;
|
||||
sout() << gas.get<string>() << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -537,25 +537,25 @@ void CommandLineInterface::readInputFiles()
|
||||
solThrow(CommandLineValidationError, "All specified input files either do not exist or are not regular files.");
|
||||
}
|
||||
|
||||
map<string, Json::Value> CommandLineInterface::parseAstFromInput()
|
||||
map<string, Json> CommandLineInterface::parseAstFromInput()
|
||||
{
|
||||
solAssert(m_options.input.mode == InputMode::CompilerWithASTImport);
|
||||
|
||||
map<string, Json::Value> sourceJsons;
|
||||
map<string, Json> sourceJsons;
|
||||
map<string, string> tmpSources;
|
||||
|
||||
for (SourceCode const& sourceCode: m_fileReader.sourceUnits() | ranges::views::values)
|
||||
{
|
||||
Json::Value ast;
|
||||
Json ast;
|
||||
astAssert(jsonParseStrict(sourceCode, ast), "Input file could not be parsed to JSON");
|
||||
astAssert(ast.isMember("sources"), "Invalid Format for import-JSON: Must have 'sources'-object");
|
||||
astAssert(ast.contains("sources"), "Invalid Format for import-JSON: Must have 'sources'-object");
|
||||
|
||||
for (auto& src: ast["sources"].getMemberNames())
|
||||
for (auto const& [src, _]: ast["sources"].items())
|
||||
{
|
||||
std::string astKey = ast["sources"][src].isMember("ast") ? "ast" : "AST";
|
||||
std::string astKey = ast["sources"][src].contains("ast") ? "ast" : "AST";
|
||||
|
||||
astAssert(ast["sources"][src].isMember(astKey), "astkey is not member");
|
||||
astAssert(ast["sources"][src][astKey]["nodeType"].asString() == "SourceUnit", "Top-level node should be a 'SourceUnit'");
|
||||
astAssert(ast["sources"][src].contains(astKey), "astkey is not member");
|
||||
astAssert(ast["sources"][src][astKey]["nodeType"].get<string>() == "SourceUnit", "Top-level node should be a 'SourceUnit'");
|
||||
astAssert(sourceJsons.count(src) == 0, "All sources must have unique names");
|
||||
sourceJsons.emplace(src, std::move(ast["sources"][src][astKey]));
|
||||
tmpSources[src] = util::jsonCompactPrint(ast);
|
||||
@ -806,16 +806,16 @@ void CommandLineInterface::handleCombinedJSON()
|
||||
if (!m_options.compiler.combinedJsonRequests.has_value())
|
||||
return;
|
||||
|
||||
Json::Value output(Json::objectValue);
|
||||
Json output(Json::object());
|
||||
|
||||
output[g_strVersion] = frontend::VersionString;
|
||||
vector<string> contracts = m_compiler->contractNames();
|
||||
|
||||
if (!contracts.empty())
|
||||
output[g_strContracts] = Json::Value(Json::objectValue);
|
||||
output[g_strContracts] = Json::object();
|
||||
for (string const& contractName: contracts)
|
||||
{
|
||||
Json::Value& contractData = output[g_strContracts][contractName] = Json::objectValue;
|
||||
Json& contractData = output[g_strContracts][contractName] = Json::object();
|
||||
if (m_options.compiler.combinedJsonRequests->abi)
|
||||
contractData[g_strAbi] = m_compiler->contractABI(contractName);
|
||||
if (m_options.compiler.combinedJsonRequests->metadata)
|
||||
@ -867,19 +867,19 @@ void CommandLineInterface::handleCombinedJSON()
|
||||
if (needsSourceList)
|
||||
{
|
||||
// Indices into this array are used to abbreviate source names in source locations.
|
||||
output[g_strSourceList] = Json::Value(Json::arrayValue);
|
||||
output[g_strSourceList] = Json::array();
|
||||
|
||||
for (auto const& source: m_compiler->sourceNames())
|
||||
output[g_strSourceList].append(source);
|
||||
output[g_strSourceList].emplace_back(source);
|
||||
}
|
||||
|
||||
if (m_options.compiler.combinedJsonRequests->ast)
|
||||
{
|
||||
output[g_strSources] = Json::Value(Json::objectValue);
|
||||
output[g_strSources] = Json(Json::object());
|
||||
for (auto const& sourceCode: m_fileReader.sourceUnits())
|
||||
{
|
||||
ASTJsonExporter converter(m_compiler->state(), m_compiler->sourceIndices());
|
||||
output[g_strSources][sourceCode.first] = Json::Value(Json::objectValue);
|
||||
output[g_strSources][sourceCode.first] = Json(Json::object());
|
||||
output[g_strSources][sourceCode.first]["AST"] = converter.toJson(m_compiler->ast(sourceCode.first));
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ private:
|
||||
/// such that they can be imported into the compiler (importASTs())
|
||||
/// (produced by --combined-json ast <file.sol>
|
||||
/// or standard-json output
|
||||
std::map<std::string, Json::Value> parseAstFromInput();
|
||||
std::map<std::string, Json> parseAstFromInput();
|
||||
|
||||
/// Create a file in the given directory
|
||||
/// @arg _fileName the name of the file
|
||||
|
@ -174,33 +174,33 @@ std::optional<map<string, string>> parseCBORMetadata(bytes const& _metadata)
|
||||
|
||||
bool isValidMetadata(string const& _serialisedMetadata)
|
||||
{
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
if (!util::jsonParseStrict(_serialisedMetadata, metadata))
|
||||
return false;
|
||||
|
||||
return isValidMetadata(metadata);
|
||||
}
|
||||
|
||||
bool isValidMetadata(Json::Value const& _metadata)
|
||||
bool isValidMetadata(Json const& _metadata)
|
||||
{
|
||||
if (
|
||||
!_metadata.isObject() ||
|
||||
!_metadata.isMember("version") ||
|
||||
!_metadata.isMember("language") ||
|
||||
!_metadata.isMember("compiler") ||
|
||||
!_metadata.isMember("settings") ||
|
||||
!_metadata.isMember("sources") ||
|
||||
!_metadata.isMember("output") ||
|
||||
!_metadata["settings"].isMember("evmVersion") ||
|
||||
!_metadata["settings"].isMember("metadata") ||
|
||||
!_metadata["settings"]["metadata"].isMember("bytecodeHash")
|
||||
!_metadata.is_object() ||
|
||||
!_metadata.contains("version") ||
|
||||
!_metadata.contains("language") ||
|
||||
!_metadata.contains("compiler") ||
|
||||
!_metadata.contains("settings") ||
|
||||
!_metadata.contains("sources") ||
|
||||
!_metadata.contains("output") ||
|
||||
!_metadata["settings"].contains("evmVersion") ||
|
||||
!_metadata["settings"].contains("metadata") ||
|
||||
!_metadata["settings"]["metadata"].contains("bytecodeHash")
|
||||
)
|
||||
return false;
|
||||
|
||||
if (!_metadata["version"].isNumeric() || _metadata["version"] != 1)
|
||||
if (!_metadata["version"].is_number() || _metadata["version"] != 1)
|
||||
return false;
|
||||
|
||||
if (!_metadata["language"].isString() || _metadata["language"].asString() != "Solidity")
|
||||
if (!_metadata["language"].is_string() || _metadata["language"].get<string>() != "Solidity")
|
||||
return false;
|
||||
|
||||
/// @TODO add more strict checks
|
||||
|
@ -53,6 +53,6 @@ std::optional<std::map<std::string, std::string>> parseCBORMetadata(bytes const&
|
||||
bool isValidMetadata(std::string const& _serialisedMetadata);
|
||||
|
||||
/// Expects a deserialised metadata JSON and returns true if the content is valid metadata.
|
||||
bool isValidMetadata(Json::Value const& _metadata);
|
||||
bool isValidMetadata(Json const& _metadata);
|
||||
|
||||
} // end namespaces
|
||||
|
@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(all_assembly_items)
|
||||
"{\"begin\":8,\"end\":18,\"name\":\"MSTORE\",\"source\":2}"
|
||||
"]},\"A6885B3731702DA62E8E4A8F584AC46A7F6822F4E2BA50FBA902F67B1588D23B\":\"01020304\"},\"sourceList\":[\"root.asm\",\"sub.asm\",\"verbatim.asm\"]}"
|
||||
};
|
||||
Json::Value jsonValue;
|
||||
Json jsonValue;
|
||||
BOOST_CHECK(util::jsonParseStrict(json, jsonValue));
|
||||
BOOST_CHECK_EQUAL(util::jsonCompactPrint(_assembly.assemblyJSON(indices)), util::jsonCompactPrint(jsonValue));
|
||||
}
|
||||
|
@ -82,18 +82,15 @@ void GasTest::parseExpectations(std::istream& _stream)
|
||||
|
||||
void GasTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const
|
||||
{
|
||||
Json::Value estimates = compiler().gasEstimates(compiler().lastContractName());
|
||||
for (auto groupIt = estimates.begin(); groupIt != estimates.end(); ++groupIt)
|
||||
Json estimates = compiler().gasEstimates(compiler().lastContractName());
|
||||
for (auto const& [group, content]: estimates.items())
|
||||
{
|
||||
_stream << _linePrefix << groupIt.key().asString() << ":" << std::endl;
|
||||
for (auto it = groupIt->begin(); it != groupIt->end(); ++it)
|
||||
_stream << _linePrefix << group << ":" << std::endl;
|
||||
for (auto const& [function, gas]: content.items())
|
||||
{
|
||||
_stream << _linePrefix << " ";
|
||||
if (it.key().asString().empty())
|
||||
_stream << "fallback";
|
||||
else
|
||||
_stream << it.key().asString();
|
||||
_stream << ": " << it->asString() << std::endl;
|
||||
_stream << (function.empty() ? "fallback" : function);
|
||||
_stream << ": " << gas << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -123,14 +120,14 @@ TestCase::TestResult GasTest::run(ostream& _stream, string const& _linePrefix, b
|
||||
return TestResult::FatalError;
|
||||
}
|
||||
|
||||
Json::Value estimateGroups = compiler().gasEstimates(compiler().lastContractName());
|
||||
Json estimateGroups = compiler().gasEstimates(compiler().lastContractName());
|
||||
if (
|
||||
m_expectations.size() == estimateGroups.size() &&
|
||||
boost::all(m_expectations, [&](auto const& expectations) {
|
||||
auto const& estimates = estimateGroups[expectations.first];
|
||||
Json const& estimates = estimateGroups[expectations.first];
|
||||
return estimates.size() == expectations.second.size() &&
|
||||
boost::all(expectations.second, [&](auto const& entry) {
|
||||
return entry.second == estimates[entry.first].asString();
|
||||
return entry.second == estimates[entry.first].template get<string>();
|
||||
});
|
||||
})
|
||||
)
|
||||
|
@ -37,30 +37,30 @@ namespace
|
||||
|
||||
/// TODO: share this between StandardCompiler.cpp
|
||||
/// Helper to match a specific error type and message
|
||||
bool containsError(Json::Value const& _compilerResult, string const& _type, string const& _message)
|
||||
bool containsError(Json const& _compilerResult, string const& _type, string const& _message)
|
||||
{
|
||||
if (!_compilerResult.isMember("errors"))
|
||||
if (!_compilerResult.contains("errors"))
|
||||
return false;
|
||||
|
||||
for (auto const& error: _compilerResult["errors"])
|
||||
{
|
||||
BOOST_REQUIRE(error.isObject());
|
||||
BOOST_REQUIRE(error["type"].isString());
|
||||
BOOST_REQUIRE(error["message"].isString());
|
||||
if ((error["type"].asString() == _type) && (error["message"].asString() == _message))
|
||||
BOOST_REQUIRE(error.is_object());
|
||||
BOOST_REQUIRE(error["type"].is_string());
|
||||
BOOST_REQUIRE(error["message"].is_string());
|
||||
if ((error["type"].get<string>() == _type) && (error["message"].get<string>() == _message))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Json::Value compile(string const& _input, CStyleReadFileCallback _callback = nullptr)
|
||||
Json compile(string const& _input, CStyleReadFileCallback _callback = nullptr)
|
||||
{
|
||||
char* output_ptr = solidity_compile(_input.c_str(), _callback, nullptr);
|
||||
string output(output_ptr);
|
||||
solidity_free(output_ptr);
|
||||
solidity_reset();
|
||||
Json::Value ret;
|
||||
Json ret;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(output, ret));
|
||||
return ret;
|
||||
}
|
||||
@ -101,14 +101,14 @@ BOOST_AUTO_TEST_CASE(standard_compilation)
|
||||
}
|
||||
}
|
||||
)";
|
||||
Json::Value result = compile(input);
|
||||
BOOST_REQUIRE(result.isObject());
|
||||
Json result = compile(input);
|
||||
BOOST_REQUIRE(result.is_object());
|
||||
|
||||
// Only tests some assumptions. The StandardCompiler is tested properly in another suite.
|
||||
BOOST_CHECK(result.isMember("sources"));
|
||||
BOOST_CHECK(result.contains("sources"));
|
||||
// This used to test that it is a member, but we did not actually request any output,
|
||||
// so there should not be a contract member.
|
||||
BOOST_CHECK(!result.isMember("contracts"));
|
||||
BOOST_CHECK(!result.contains("contracts"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(missing_callback)
|
||||
@ -123,8 +123,8 @@ BOOST_AUTO_TEST_CASE(missing_callback)
|
||||
}
|
||||
}
|
||||
)";
|
||||
Json::Value result = compile(input);
|
||||
BOOST_REQUIRE(result.isObject());
|
||||
Json result = compile(input);
|
||||
BOOST_REQUIRE(result.is_object());
|
||||
|
||||
BOOST_CHECK(containsError(result, "ParserError", "Source \"missing.sol\" not found: File not supplied initially."));
|
||||
}
|
||||
@ -169,8 +169,8 @@ BOOST_AUTO_TEST_CASE(with_callback)
|
||||
}
|
||||
};
|
||||
|
||||
Json::Value result = compile(input, callback);
|
||||
BOOST_REQUIRE(result.isObject());
|
||||
Json result = compile(input, callback);
|
||||
BOOST_REQUIRE(result.is_object());
|
||||
|
||||
// This ensures that "found.sol" was properly loaded which triggered the second import statement.
|
||||
BOOST_CHECK(containsError(result, "ParserError", "Source \"missing.sol\" not found: Missing file."));
|
||||
|
@ -58,17 +58,17 @@ optional<string> compileAndCheckLicenseMetadata(string const& _contractName, cha
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
string const& serialisedMetadata = compilerStack.metadata(_contractName);
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
|
||||
BOOST_CHECK_EQUAL(metadata["sources"].size(), 1);
|
||||
BOOST_REQUIRE(metadata["sources"].isMember("A.sol"));
|
||||
BOOST_REQUIRE(metadata["sources"].contains("A.sol"));
|
||||
|
||||
if (metadata["sources"]["A.sol"].isMember("license"))
|
||||
if (metadata["sources"]["A.sol"].contains("license"))
|
||||
{
|
||||
BOOST_REQUIRE(metadata["sources"]["A.sol"]["license"].isString());
|
||||
return metadata["sources"]["A.sol"]["license"].asString();
|
||||
BOOST_REQUIRE(metadata["sources"]["A.sol"]["license"].is_string());
|
||||
return metadata["sources"]["A.sol"]["license"].get<string>();
|
||||
}
|
||||
else
|
||||
return nullopt;
|
||||
@ -250,12 +250,12 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources)
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
string const& serialisedMetadata = compilerStack.metadata("A");
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
|
||||
BOOST_CHECK_EQUAL(metadata["sources"].size(), 1);
|
||||
BOOST_CHECK(metadata["sources"].isMember("A"));
|
||||
BOOST_CHECK(metadata["sources"].contains("A"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
|
||||
@ -291,14 +291,14 @@ BOOST_AUTO_TEST_CASE(metadata_relevant_sources_imports)
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
string const& serialisedMetadata = compilerStack.metadata("C");
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
|
||||
BOOST_CHECK_EQUAL(metadata["sources"].size(), 3);
|
||||
BOOST_CHECK(metadata["sources"].isMember("A"));
|
||||
BOOST_CHECK(metadata["sources"].isMember("B"));
|
||||
BOOST_CHECK(metadata["sources"].isMember("C"));
|
||||
BOOST_CHECK(metadata["sources"].contains("A"));
|
||||
BOOST_CHECK(metadata["sources"].contains("B"));
|
||||
BOOST_CHECK(metadata["sources"].contains("C"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(metadata_useLiteralContent)
|
||||
@ -319,16 +319,16 @@ BOOST_AUTO_TEST_CASE(metadata_useLiteralContent)
|
||||
compilerStack.useMetadataLiteralSources(_literal);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
string metadata_str = compilerStack.metadata("test");
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(metadata_str, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
BOOST_CHECK(metadata.isMember("settings"));
|
||||
BOOST_CHECK(metadata["settings"].isMember("metadata"));
|
||||
BOOST_CHECK(metadata["settings"]["metadata"].isMember("bytecodeHash"));
|
||||
BOOST_CHECK(metadata.contains("settings"));
|
||||
BOOST_CHECK(metadata["settings"].contains("metadata"));
|
||||
BOOST_CHECK(metadata["settings"]["metadata"].contains("bytecodeHash"));
|
||||
if (_literal)
|
||||
{
|
||||
BOOST_CHECK(metadata["settings"]["metadata"].isMember("useLiteralContent"));
|
||||
BOOST_CHECK(metadata["settings"]["metadata"]["useLiteralContent"].asBool());
|
||||
BOOST_CHECK(metadata["settings"]["metadata"].contains("useLiteralContent"));
|
||||
BOOST_CHECK(metadata["settings"]["metadata"]["useLiteralContent"].get<bool>());
|
||||
}
|
||||
};
|
||||
|
||||
@ -353,17 +353,17 @@ BOOST_AUTO_TEST_CASE(metadata_viair)
|
||||
compilerStack.setViaIR(_viaIR);
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(compilerStack.metadata("test"), metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
BOOST_CHECK(metadata.isMember("settings"));
|
||||
BOOST_CHECK(metadata.contains("settings"));
|
||||
if (_viaIR)
|
||||
{
|
||||
BOOST_CHECK(metadata["settings"].isMember("viaIR"));
|
||||
BOOST_CHECK(metadata["settings"]["viaIR"].asBool());
|
||||
BOOST_CHECK(metadata["settings"].contains("viaIR"));
|
||||
BOOST_CHECK(metadata["settings"]["viaIR"].get<bool>());
|
||||
}
|
||||
else
|
||||
BOOST_CHECK(!metadata["settings"].isMember("viaIR"));
|
||||
BOOST_CHECK(!metadata["settings"].contains("viaIR"));
|
||||
|
||||
BOOST_CHECK(compilerStack.cborMetadata("test") == compilerStack.cborMetadata("test", _viaIR));
|
||||
BOOST_CHECK(compilerStack.cborMetadata("test") != compilerStack.cborMetadata("test", !_viaIR));
|
||||
@ -393,7 +393,7 @@ BOOST_AUTO_TEST_CASE(metadata_revert_strings)
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
string const& serialisedMetadata = compilerStack.metadata("A");
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
|
||||
@ -431,14 +431,14 @@ BOOST_AUTO_TEST_CASE(metadata_optimiser_sequence)
|
||||
BOOST_REQUIRE_MESSAGE(compilerStack.compile(), "Compiling contract failed");
|
||||
|
||||
string const& serialisedMetadata = compilerStack.metadata("C");
|
||||
Json::Value metadata;
|
||||
Json metadata;
|
||||
BOOST_REQUIRE(util::jsonParseStrict(serialisedMetadata, metadata));
|
||||
BOOST_CHECK(solidity::test::isValidMetadata(metadata));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"].isMember("details"));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"]["details"].isMember("yulDetails"));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].isMember("optimizerSteps"));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"].contains("details"));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"]["details"].contains("yulDetails"));
|
||||
BOOST_CHECK(metadata["settings"]["optimizer"]["details"]["yulDetails"].contains("optimizerSteps"));
|
||||
|
||||
string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].asString();
|
||||
string const metadataOptimizerSteps = metadata["settings"]["optimizer"]["details"]["yulDetails"]["optimizerSteps"].get<string>();
|
||||
string const expectedMetadataOptimiserSteps = _optimizerSequence + ":" + _optimizerCleanupSequence;
|
||||
BOOST_CHECK_EQUAL(metadataOptimizerSteps, expectedMetadataOptimiserSteps);
|
||||
};
|
||||
|
@ -431,7 +431,7 @@ TestCase::TestResult SemanticTest::runTest(
|
||||
{
|
||||
soltestAssert(
|
||||
m_allowNonExistingFunctions ||
|
||||
m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].isMember(test.call().signature),
|
||||
m_compiler.interfaceSymbols(m_compiler.lastContractName(m_sources.mainSourceFile))["methods"].contains(test.call().signature),
|
||||
"The function " + test.call().signature + " is not known to the compiler"
|
||||
);
|
||||
|
||||
|
@ -50,17 +50,17 @@ public:
|
||||
m_compilerStack.setEVMVersion(solidity::test::CommonOptions::get().evmVersion());
|
||||
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
|
||||
|
||||
Json::Value generatedDocumentation;
|
||||
Json generatedDocumentation;
|
||||
if (_userDocumentation)
|
||||
generatedDocumentation = m_compilerStack.natspecUser(_contractName);
|
||||
else
|
||||
generatedDocumentation = m_compilerStack.natspecDev(_contractName);
|
||||
Json::Value expectedDocumentation;
|
||||
Json expectedDocumentation;
|
||||
std::string parseError;
|
||||
BOOST_REQUIRE_MESSAGE(util::jsonParseStrict(_expectedDocumentationString, expectedDocumentation, &parseError), parseError);
|
||||
|
||||
expectedDocumentation["version"] = Json::Value(Natspec::c_natspecVersion);
|
||||
expectedDocumentation["kind"] = Json::Value(_userDocumentation ? "user" : "dev");
|
||||
expectedDocumentation["version"] = Natspec::c_natspecVersion;
|
||||
expectedDocumentation["kind"] = _userDocumentation ? "user" : "dev";
|
||||
|
||||
BOOST_CHECK_MESSAGE(
|
||||
expectedDocumentation == generatedDocumentation,
|
||||
@ -2125,12 +2125,12 @@ BOOST_AUTO_TEST_CASE(dev_explicit_inehrit_complex)
|
||||
|
||||
BOOST_REQUIRE_MESSAGE(m_compilerStack.parseAndAnalyze(), "Parsing contract failed");
|
||||
|
||||
Json::Value generatedDocumentation = m_compilerStack.natspecDev("Token");
|
||||
Json::Value expectedDocumentation;
|
||||
Json generatedDocumentation = m_compilerStack.natspecDev("Token");
|
||||
Json expectedDocumentation;
|
||||
util::jsonParseStrict(natspec, expectedDocumentation);
|
||||
|
||||
expectedDocumentation["version"] = Json::Value(Natspec::c_natspecVersion);
|
||||
expectedDocumentation["kind"] = Json::Value("dev");
|
||||
expectedDocumentation["version"] = Natspec::c_natspecVersion;
|
||||
expectedDocumentation["kind"] = "dev";
|
||||
|
||||
BOOST_CHECK_MESSAGE(
|
||||
expectedDocumentation == generatedDocumentation,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -141,16 +141,16 @@ optional<ABIType> isFixedPoint(string const& type)
|
||||
return fixedPointType;
|
||||
}
|
||||
|
||||
string functionSignatureFromABI(Json::Value const& _functionABI)
|
||||
string functionSignatureFromABI(Json const& _functionABI)
|
||||
{
|
||||
auto inputs = _functionABI["inputs"];
|
||||
string signature = {_functionABI["name"].asString() + "("};
|
||||
string signature = {_functionABI["name"].get<string>() + "("};
|
||||
size_t parameterCount = 0;
|
||||
|
||||
for (auto const& input: inputs)
|
||||
{
|
||||
parameterCount++;
|
||||
signature += input["type"].asString();
|
||||
signature += input["type"].get<string>();
|
||||
if (parameterCount < inputs.size())
|
||||
signature += ",";
|
||||
}
|
||||
@ -162,7 +162,7 @@ string functionSignatureFromABI(Json::Value const& _functionABI)
|
||||
|
||||
std::optional<solidity::frontend::test::ParameterList> ContractABIUtils::parametersFromJsonOutputs(
|
||||
ErrorReporter& _errorReporter,
|
||||
Json::Value const& _contractABI,
|
||||
Json const& _contractABI,
|
||||
string const& _functionSignature
|
||||
)
|
||||
{
|
||||
@ -178,7 +178,7 @@ std::optional<solidity::frontend::test::ParameterList> ContractABIUtils::paramet
|
||||
|
||||
for (auto const& output: function["outputs"])
|
||||
{
|
||||
string type = output["type"].asString();
|
||||
string type = output["type"].get<string>();
|
||||
|
||||
ABITypes inplaceTypes;
|
||||
ABITypes dynamicTypes;
|
||||
@ -210,13 +210,13 @@ std::optional<solidity::frontend::test::ParameterList> ContractABIUtils::paramet
|
||||
}
|
||||
|
||||
bool ContractABIUtils::appendTypesFromName(
|
||||
Json::Value const& _functionOutput,
|
||||
Json const& _functionOutput,
|
||||
ABITypes& _inplaceTypes,
|
||||
ABITypes& _dynamicTypes,
|
||||
bool _isCompoundType
|
||||
)
|
||||
{
|
||||
string type = _functionOutput["type"].asString();
|
||||
string type = _functionOutput["type"].get<string>();
|
||||
if (isBool(type))
|
||||
_inplaceTypes.push_back(ABIType{ABIType::Boolean});
|
||||
else if (isUint(type))
|
||||
|
@ -19,8 +19,7 @@
|
||||
#include <test/libsolidity/util/SoltestErrors.h>
|
||||
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <json/json.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
namespace solidity::frontend::test
|
||||
{
|
||||
@ -40,7 +39,7 @@ public:
|
||||
/// auto-correction during interactive update routine.
|
||||
static std::optional<ParameterList> parametersFromJsonOutputs(
|
||||
ErrorReporter& _errorReporter,
|
||||
Json::Value const& _contractABI,
|
||||
Json const& _contractABI,
|
||||
std::string const& _functionSignature
|
||||
);
|
||||
|
||||
@ -86,7 +85,7 @@ private:
|
||||
/// `bytes` -> [`Unsigned`, `Unsigned`, `HexString`]
|
||||
/// ...
|
||||
static bool appendTypesFromName(
|
||||
Json::Value const& _functionOutput,
|
||||
Json const& _functionOutput,
|
||||
ABITypes& _inplaceTypes,
|
||||
ABITypes& _dynamicTypes,
|
||||
bool _isCompoundType = false
|
||||
|
@ -368,7 +368,7 @@ void TestFunctionCall::reset()
|
||||
{
|
||||
m_rawBytes = bytes{};
|
||||
m_failure = true;
|
||||
m_contractABI = Json::Value{};
|
||||
m_contractABI = Json{};
|
||||
m_calledNonExistingFunction = false;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include <libsolutil/CommonData.h>
|
||||
#include <libsolutil/JSON.h>
|
||||
|
||||
#include <json/json.h>
|
||||
|
||||
#include <iosfwd>
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
@ -94,7 +92,7 @@ public:
|
||||
void setFailure(const bool _failure) { m_failure = _failure; }
|
||||
void setRawBytes(const bytes _rawBytes) { m_rawBytes = _rawBytes; }
|
||||
void setGasCost(std::string const& _runType, u256 const& _gasCost) { m_gasCosts[_runType] = _gasCost; }
|
||||
void setContractABI(Json::Value _contractABI) { m_contractABI = std::move(_contractABI); }
|
||||
void setContractABI(Json _contractABI) { m_contractABI = std::move(_contractABI); }
|
||||
void setSideEffects(std::vector<std::string> _sideEffects) { m_call.actualSideEffects = _sideEffects; }
|
||||
|
||||
private:
|
||||
@ -147,7 +145,7 @@ private:
|
||||
bool m_failure = true;
|
||||
/// JSON object which holds the contract ABI and that is used to set the output formatting
|
||||
/// in the interactive update routine.
|
||||
Json::Value m_contractABI = Json::Value{};
|
||||
Json m_contractABI = Json{};
|
||||
/// Flags that the test failed because the called function is not known to exist on the contract.
|
||||
bool m_calledNonExistingFunction = false;
|
||||
};
|
||||
|
@ -35,50 +35,46 @@ BOOST_AUTO_TEST_SUITE(JsonTest, *boost::unit_test::label("nooptions"))
|
||||
|
||||
BOOST_AUTO_TEST_CASE(json_types)
|
||||
{
|
||||
auto check = [](Json::Value value, string const& expectation) {
|
||||
auto check = [](Json value, string const& expectation) {
|
||||
BOOST_CHECK(jsonCompactPrint(value) == expectation);
|
||||
};
|
||||
|
||||
Json::Value value;
|
||||
Json value;
|
||||
BOOST_CHECK(value.empty());
|
||||
value = {};
|
||||
BOOST_CHECK(value.empty());
|
||||
value = Json::Value();
|
||||
value = Json();
|
||||
BOOST_CHECK(value.empty());
|
||||
value = Json::nullValue;
|
||||
value = Json(nullptr);
|
||||
BOOST_CHECK(value.empty());
|
||||
|
||||
check(value, "null");
|
||||
check({}, "null");
|
||||
check(Json::Value(), "null");
|
||||
check(Json::nullValue, "null");
|
||||
check(Json::objectValue, "{}");
|
||||
check(Json::arrayValue, "[]");
|
||||
check(Json::UInt(1), "1");
|
||||
check(Json::UInt(-1), "4294967295");
|
||||
check(Json::UInt64(1), "1");
|
||||
check(Json::UInt64(-1), "18446744073709551615");
|
||||
check(Json::LargestUInt(1), "1");
|
||||
check(Json::LargestUInt(-1), "18446744073709551615");
|
||||
check(Json::LargestUInt(0xffffffff), "4294967295");
|
||||
check(Json::Value("test"), "\"test\"");
|
||||
check(Json(), "null");
|
||||
check(Json(nullptr), "null");
|
||||
check(Json::object(), "{}");
|
||||
check(Json::array(), "[]");
|
||||
check(Json::number_unsigned_t(1), "1");
|
||||
check(Json::number_unsigned_t(-1), "18446744073709551615");
|
||||
check(Json::number_unsigned_t(0xffffffff), "4294967295");
|
||||
check(Json("test"), "\"test\"");
|
||||
check("test", "\"test\"");
|
||||
check(true, "true");
|
||||
|
||||
value = Json::objectValue;
|
||||
value = Json::object();
|
||||
value["key"] = "value";
|
||||
check(value, "{\"key\":\"value\"}");
|
||||
|
||||
value = Json::arrayValue;
|
||||
value.append(1);
|
||||
value.append(2);
|
||||
value = Json::array();
|
||||
value.emplace_back(1);
|
||||
value.emplace_back(2);
|
||||
check(value, "[1,2]");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(json_pretty_print)
|
||||
{
|
||||
Json::Value json;
|
||||
Json::Value jsonChild;
|
||||
Json json;
|
||||
Json jsonChild;
|
||||
|
||||
jsonChild["3.1"] = "3.1";
|
||||
jsonChild["3.2"] = 2;
|
||||
@ -104,8 +100,8 @@ BOOST_AUTO_TEST_CASE(json_pretty_print)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(json_compact_print)
|
||||
{
|
||||
Json::Value json;
|
||||
Json::Value jsonChild;
|
||||
Json json;
|
||||
Json jsonChild;
|
||||
|
||||
jsonChild["3.1"] = "3.1";
|
||||
jsonChild["3.2"] = 2;
|
||||
@ -123,7 +119,7 @@ BOOST_AUTO_TEST_CASE(parse_json_strict)
|
||||
// In this test we check conformance against JSON.parse (https://tc39.es/ecma262/multipage/structured-data.html#sec-json.parse)
|
||||
// and ECMA-404 (https://www.ecma-international.org/publications-and-standards/standards/ecma-404/)
|
||||
|
||||
Json::Value json;
|
||||
Json json;
|
||||
std::string errors;
|
||||
|
||||
// Just parse a valid json input
|
||||
@ -135,31 +131,28 @@ BOOST_AUTO_TEST_CASE(parse_json_strict)
|
||||
|
||||
// Trailing garbage is not allowed in ECMA-262
|
||||
BOOST_CHECK(!jsonParseStrict("{\"1\":2,\"2\":\"2\",\"3\":{\"3.1\":\"3.1\",\"3.2\":3}}}}}}}}}}", json, &errors));
|
||||
BOOST_CHECK(errors == "[json.exception.parse_error.101] parse error at line 1, column 42: syntax error while parsing value - unexpected '}'; expected end of input");
|
||||
|
||||
// Comments are not allowed in ECMA-262
|
||||
// ... but JSONCPP allows them
|
||||
BOOST_CHECK(jsonParseStrict(
|
||||
BOOST_CHECK(!jsonParseStrict(
|
||||
"{\"1\":3, // awesome comment\n\"2\":\"2\",\"3\":{\"3.1\":\"3.1\",\"3.2\":5}}", json, &errors
|
||||
));
|
||||
BOOST_CHECK(json["1"] == 3);
|
||||
BOOST_CHECK(json["2"] == "2");
|
||||
BOOST_CHECK(json["3"]["3.1"] == "3.1");
|
||||
BOOST_CHECK(json["3"]["3.2"] == 5);
|
||||
BOOST_CHECK(errors == "[json.exception.parse_error.101] parse error at line 1, column 9: syntax error while parsing object key - invalid literal; last read: '3, /'; expected string literal");
|
||||
|
||||
// According to ECMA-404 object, array, number, string, true, false, null are allowed
|
||||
// ... but JSONCPP disallows value types
|
||||
BOOST_CHECK(jsonParseStrict("[]", json, &errors));
|
||||
BOOST_CHECK(json.isArray());
|
||||
BOOST_CHECK(json.is_array());
|
||||
BOOST_CHECK(jsonParseStrict("{}", json, &errors));
|
||||
BOOST_CHECK(json.isObject());
|
||||
BOOST_CHECK(!jsonParseStrict("1", json, &errors));
|
||||
// BOOST_CHECK(json.isNumeric());
|
||||
BOOST_CHECK(!jsonParseStrict("\"hello\"", json, &errors));
|
||||
// BOOST_CHECK(json.isString());
|
||||
BOOST_CHECK(!jsonParseStrict("true", json, &errors));
|
||||
// BOOST_CHECK(json.isBool());
|
||||
BOOST_CHECK(!jsonParseStrict("null", json, &errors));
|
||||
// BOOST_CHECK(json.isNull());
|
||||
BOOST_CHECK(json.is_object());
|
||||
BOOST_CHECK(jsonParseStrict("1", json, &errors));
|
||||
BOOST_CHECK(json.is_number());
|
||||
BOOST_CHECK(jsonParseStrict("\"hello\"", json, &errors));
|
||||
BOOST_CHECK(json.is_string());
|
||||
BOOST_CHECK(jsonParseStrict("true", json, &errors));
|
||||
BOOST_CHECK(json.is_boolean());
|
||||
BOOST_CHECK(jsonParseStrict("null", json, &errors));
|
||||
BOOST_CHECK(json.is_null());
|
||||
|
||||
// Single quotes are also disallowed by ECMA-404
|
||||
BOOST_CHECK(!jsonParseStrict("'hello'", json, &errors));
|
||||
@ -172,15 +165,12 @@ BOOST_AUTO_TEST_CASE(parse_json_strict)
|
||||
// a few control characters (\b, \f, \n, \r, \t)
|
||||
//
|
||||
// More lenient parsers allow hex escapes as long as they translate to a valid UTF-8 encoding.
|
||||
//
|
||||
// ... but JSONCPP allows any hex escapes
|
||||
BOOST_CHECK(jsonParseStrict("[ \"\x80\xec\x80\" ]", json, &errors));
|
||||
BOOST_CHECK(json.isArray());
|
||||
BOOST_CHECK(json[0] == "\x80\xec\x80");
|
||||
BOOST_CHECK(!jsonParseStrict("[ \"\x80\xec\x80\" ]", json, &errors));
|
||||
BOOST_CHECK(errors == "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - invalid string: ill-formed UTF-8 byte; last read: '\"?'");
|
||||
|
||||
// This would be valid more lenient parsers.
|
||||
BOOST_CHECK(jsonParseStrict("[ \"\xF0\x9F\x98\x8A\" ]", json, &errors));
|
||||
BOOST_CHECK(json.isArray());
|
||||
BOOST_CHECK(json.is_array());
|
||||
BOOST_CHECK(json[0] == "😊");
|
||||
}
|
||||
|
||||
|
@ -1018,6 +1018,16 @@ BOOST_AUTO_TEST_CASE(cli_include_paths)
|
||||
BOOST_TEST(result.reader.basePath() == expectedWorkDir / "base/");
|
||||
}
|
||||
|
||||
namespace {
|
||||
set<string> getMemberNames(Json const& _json)
|
||||
{
|
||||
set<string> keys;
|
||||
for (auto const& [key, _]: _json.items())
|
||||
keys.insert(key);
|
||||
return keys;
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(standard_json_include_paths)
|
||||
{
|
||||
TemporaryDirectory tempDir({"base/", "include/", "lib/nested/"}, TEST_CASE_NAME);
|
||||
@ -1094,15 +1104,15 @@ BOOST_AUTO_TEST_CASE(standard_json_include_paths)
|
||||
|
||||
OptionsReaderAndMessages result = runCLI(commandLine, standardJsonInput);
|
||||
|
||||
Json::Value parsedStdout;
|
||||
Json parsedStdout;
|
||||
string jsonParsingErrors;
|
||||
BOOST_TEST(util::jsonParseStrict(result.stdoutContent, parsedStdout, &jsonParsingErrors));
|
||||
BOOST_TEST(jsonParsingErrors == "");
|
||||
for (Json::Value const& errorDict: parsedStdout["errors"])
|
||||
for (Json const& errorDict: parsedStdout["errors"])
|
||||
// The error list might contain pre-release compiler warning
|
||||
BOOST_TEST(errorDict["severity"] != "error");
|
||||
BOOST_TEST(
|
||||
(parsedStdout["sources"].getMemberNames() | ranges::to<set>) ==
|
||||
(getMemberNames(parsedStdout["sources"]) | ranges::to<set>) ==
|
||||
(expectedSources | ranges::views::keys | ranges::to<set>) + set<string>{"main.sol"}
|
||||
);
|
||||
|
||||
|
@ -56,13 +56,13 @@ void FuzzerUtil::testCompilerJsonInterface(string const& _input, bool _optimize,
|
||||
if (!_quiet)
|
||||
cout << "Testing compiler " << (_optimize ? "with" : "without") << " optimizer." << endl;
|
||||
|
||||
Json::Value config = Json::objectValue;
|
||||
Json config = Json::object();
|
||||
config["language"] = "Solidity";
|
||||
config["sources"] = Json::objectValue;
|
||||
config["sources"][""] = Json::objectValue;
|
||||
config["sources"] = Json::object();
|
||||
config["sources"][""] = Json::object();
|
||||
config["sources"][""]["content"] = _input;
|
||||
config["settings"] = Json::objectValue;
|
||||
config["settings"]["optimizer"] = Json::objectValue;
|
||||
config["settings"] = Json::object();
|
||||
config["settings"]["optimizer"] = Json::object();
|
||||
config["settings"]["optimizer"]["enabled"] = _optimize;
|
||||
config["settings"]["optimizer"]["runs"] = static_cast<int>(OptimiserSettings{}.expectedExecutionsPerDeployment);
|
||||
config["settings"]["evmVersion"] = "berlin";
|
||||
@ -146,23 +146,23 @@ void FuzzerUtil::runCompiler(string const& _input, bool _quiet)
|
||||
// This should be safe given the above copies the output.
|
||||
solidity_reset();
|
||||
|
||||
Json::Value output;
|
||||
Json output;
|
||||
if (!jsonParseStrict(outputString, output))
|
||||
{
|
||||
string msg{"Compiler produced invalid JSON output."};
|
||||
cout << msg << endl;
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg)));
|
||||
}
|
||||
if (output.isMember("errors"))
|
||||
if (output.contains("errors"))
|
||||
for (auto const& error: output["errors"])
|
||||
{
|
||||
string invalid = findAnyOf(error["type"].asString(), vector<string>{
|
||||
string invalid = findAnyOf(error["type"].get<string>(), vector<string>{
|
||||
"Exception",
|
||||
"InternalCompilerError"
|
||||
});
|
||||
if (!invalid.empty())
|
||||
{
|
||||
string msg = "Invalid error: \"" + error["type"].asString() + "\"";
|
||||
string msg = "Invalid error: \"" + error["type"].get<string>() + "\"";
|
||||
cout << msg << endl;
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error(std::move(msg)));
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ optional<CompilerOutput> SolidityCompilationFramework::compileContract()
|
||||
else
|
||||
contractName = m_compilerInput.contractName;
|
||||
evmasm::LinkerObject obj = m_compiler.object(contractName);
|
||||
Json::Value methodIdentifiers = m_compiler.interfaceSymbols(contractName)["methods"];
|
||||
Json methodIdentifiers = m_compiler.interfaceSymbols(contractName)["methods"];
|
||||
return CompilerOutput{obj.bytecode, methodIdentifiers};
|
||||
}
|
||||
}
|
||||
@ -164,10 +164,10 @@ evmc::result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle)
|
||||
// isabelle test entry point. At the moment, we are sure that the
|
||||
// entry point is the second method in the contract (hence the ++)
|
||||
// but not its name.
|
||||
methodName = (++cOutput->methodIdentifiersInContract.begin())->asString() +
|
||||
methodName = (++cOutput->methodIdentifiersInContract.begin())->get<string>() +
|
||||
_fuzzIsabelle.substr(2, _fuzzIsabelle.size());
|
||||
else
|
||||
methodName = cOutput->methodIdentifiersInContract[m_methodName].asString();
|
||||
methodName = cOutput->methodIdentifiersInContract[m_methodName].get<string>();
|
||||
|
||||
return deployAndExecute(
|
||||
cOutput->byteCode,
|
||||
|
@ -35,7 +35,7 @@ struct CompilerOutput
|
||||
/// EVM bytecode returned by compiler
|
||||
solidity::bytes byteCode;
|
||||
/// Method identifiers in a contract
|
||||
Json::Value methodIdentifiersInContract;
|
||||
Json methodIdentifiersInContract;
|
||||
};
|
||||
|
||||
struct CompilerInput
|
||||
@ -89,7 +89,7 @@ public:
|
||||
m_compilerInput.libraryAddresses = std::move(_libraryAddresses);
|
||||
}
|
||||
/// @returns method identifiers in contract called @param _contractName.
|
||||
Json::Value methodIdentifiers(std::string const& _contractName)
|
||||
Json methodIdentifiers(std::string const& _contractName)
|
||||
{
|
||||
return m_compiler.interfaceSymbols(_contractName)["methods"];
|
||||
}
|
||||
|
@ -381,7 +381,7 @@ BOOST_AUTO_TEST_CASE(toJson)
|
||||
CharStream sourceStream(sourceCode, current_test_case().p_name);
|
||||
Program program = get<Program>(Program::load(sourceStream));
|
||||
|
||||
Json::Value parsingResult;
|
||||
Json parsingResult;
|
||||
string errors;
|
||||
BOOST_TEST(jsonParseStrict(program.toJson(), parsingResult, &errors));
|
||||
BOOST_TEST(errors.empty());
|
||||
|
@ -112,7 +112,7 @@ ostream& phaser::operator<<(ostream& _stream, Program const& _program)
|
||||
|
||||
string Program::toJson() const
|
||||
{
|
||||
Json::Value serializedAst = AsmJsonConverter(0)(*m_ast);
|
||||
Json serializedAst = AsmJsonConverter(0)(*m_ast);
|
||||
return jsonPrettyPrint(removeNullMembers(std::move(serializedAst)));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user