mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' into build_enhancement
This commit is contained in:
commit
2d8eaf8482
2
AST.h
2
AST.h
@ -204,7 +204,7 @@ public:
|
|||||||
Block& getBody() { return *m_body; }
|
Block& getBody() { return *m_body; }
|
||||||
/// @return A shared pointer of an ASTString.
|
/// @return A shared pointer of an ASTString.
|
||||||
/// Can contain a nullptr in which case indicates absence of documentation
|
/// Can contain a nullptr in which case indicates absence of documentation
|
||||||
ASTPointer<ASTString> const& getDocumentation() { return m_documentation; }
|
ASTPointer<ASTString> const& getDocumentation() const { return m_documentation; }
|
||||||
|
|
||||||
void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); }
|
void addLocalVariable(VariableDeclaration const& _localVariable) { m_localVariables.push_back(&_localVariable); }
|
||||||
std::vector<VariableDeclaration const*> const& getLocalVariables() const { return m_localVariables; }
|
std::vector<VariableDeclaration const*> const& getLocalVariables() const { return m_localVariables; }
|
||||||
|
@ -18,6 +18,10 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${EXECUTABLE} evmcore devcore)
|
target_link_libraries(${EXECUTABLE} evmcore devcore)
|
||||||
|
# TODO: Temporary until PR 532 https://github.com/ethereum/cpp-ethereum/pull/532
|
||||||
|
# gets accepted. Then we can simply add jsoncpp as a dependency and not the
|
||||||
|
# whole of JSONRPC as we are doing right here
|
||||||
|
target_link_libraries(${EXECUTABLE} ${JSONRPC_LS})
|
||||||
|
|
||||||
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
|
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
|
||||||
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
|
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include <libsolidity/NameAndTypeResolver.h>
|
#include <libsolidity/NameAndTypeResolver.h>
|
||||||
#include <libsolidity/Compiler.h>
|
#include <libsolidity/Compiler.h>
|
||||||
#include <libsolidity/CompilerStack.h>
|
#include <libsolidity/CompilerStack.h>
|
||||||
|
#include <libsolidity/InterfaceHandler.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -35,6 +36,8 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
|
CompilerStack::CompilerStack(): m_interfaceHandler(make_shared<InterfaceHandler>()) {}
|
||||||
|
|
||||||
void CompilerStack::setSource(string const& _sourceCode)
|
void CompilerStack::setSource(string const& _sourceCode)
|
||||||
{
|
{
|
||||||
reset();
|
reset();
|
||||||
@ -81,48 +84,31 @@ void CompilerStack::streamAssembly(ostream& _outStream)
|
|||||||
m_compiler->streamAssembly(_outStream);
|
m_compiler->streamAssembly(_outStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
string const& CompilerStack::getInterface()
|
std::string const& CompilerStack::getJsonDocumentation(DocumentationType _type)
|
||||||
{
|
{
|
||||||
if (!m_parseSuccessful)
|
if (!m_parseSuccessful)
|
||||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
||||||
if (m_interface.empty())
|
|
||||||
|
auto createDocIfNotThere = [this, _type](std::unique_ptr<string>& _doc)
|
||||||
{
|
{
|
||||||
stringstream interface;
|
if (!_doc)
|
||||||
interface << '[';
|
_doc = m_interfaceHandler->getDocumentation(m_contractASTNode, _type);
|
||||||
vector<FunctionDefinition const*> exportedFunctions = m_contractASTNode->getInterfaceFunctions();
|
|
||||||
unsigned functionsCount = exportedFunctions.size();
|
|
||||||
for (FunctionDefinition const* f: exportedFunctions)
|
|
||||||
{
|
|
||||||
auto streamVariables = [&](vector<ASTPointer<VariableDeclaration>> const& _vars)
|
|
||||||
{
|
|
||||||
unsigned varCount = _vars.size();
|
|
||||||
for (ASTPointer<VariableDeclaration> const& var: _vars)
|
|
||||||
{
|
|
||||||
interface << "{"
|
|
||||||
<< "\"name\":" << escaped(var->getName(), false) << ","
|
|
||||||
<< "\"type\":" << escaped(var->getType()->toString(), false)
|
|
||||||
<< "}";
|
|
||||||
if (--varCount > 0)
|
|
||||||
interface << ",";
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface << '{'
|
switch (_type)
|
||||||
<< "\"name\":" << escaped(f->getName(), false) << ","
|
{
|
||||||
<< "\"inputs\":[";
|
case DocumentationType::NATSPEC_USER:
|
||||||
streamVariables(f->getParameters());
|
createDocIfNotThere(m_userDocumentation);
|
||||||
interface << "],"
|
return *m_userDocumentation;
|
||||||
<< "\"outputs\":[";
|
case DocumentationType::NATSPEC_DEV:
|
||||||
streamVariables(f->getReturnParameters());
|
createDocIfNotThere(m_devDocumentation);
|
||||||
interface << "]"
|
return *m_devDocumentation;
|
||||||
<< "}";
|
case DocumentationType::ABI_INTERFACE:
|
||||||
if (--functionsCount > 0)
|
createDocIfNotThere(m_interface);
|
||||||
interface << ",";
|
return *m_interface;
|
||||||
}
|
}
|
||||||
interface << ']';
|
|
||||||
m_interface = interface.str();
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal documentation type."));
|
||||||
}
|
|
||||||
return m_interface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes CompilerStack::staticCompile(std::string const& _sourceCode, bool _optimize)
|
bytes CompilerStack::staticCompile(std::string const& _sourceCode, bool _optimize)
|
||||||
|
@ -35,6 +35,14 @@ class Scanner;
|
|||||||
class ContractDefinition;
|
class ContractDefinition;
|
||||||
class Compiler;
|
class Compiler;
|
||||||
class GlobalContext;
|
class GlobalContext;
|
||||||
|
class InterfaceHandler;
|
||||||
|
|
||||||
|
enum class DocumentationType: uint8_t
|
||||||
|
{
|
||||||
|
NATSPEC_USER = 1,
|
||||||
|
NATSPEC_DEV,
|
||||||
|
ABI_INTERFACE
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
|
* Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
|
||||||
@ -44,7 +52,7 @@ class GlobalContext;
|
|||||||
class CompilerStack
|
class CompilerStack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CompilerStack() {}
|
CompilerStack();
|
||||||
void reset() { *this = CompilerStack(); }
|
void reset() { *this = CompilerStack(); }
|
||||||
void setSource(std::string const& _sourceCode);
|
void setSource(std::string const& _sourceCode);
|
||||||
void parse();
|
void parse();
|
||||||
@ -62,6 +70,11 @@ public:
|
|||||||
/// Returns a string representing the contract interface in JSON.
|
/// Returns a string representing the contract interface in JSON.
|
||||||
/// Prerequisite: Successful call to parse or compile.
|
/// Prerequisite: Successful call to parse or compile.
|
||||||
std::string const& getInterface();
|
std::string const& getInterface();
|
||||||
|
/// Returns a string representing the contract's documentation in JSON.
|
||||||
|
/// Prerequisite: Successful call to parse or compile.
|
||||||
|
/// @param type The type of the documentation to get.
|
||||||
|
/// Can be one of 3 types defined at @c documentation_type
|
||||||
|
std::string const& getJsonDocumentation(DocumentationType type);
|
||||||
|
|
||||||
/// Returns the previously used scanner, useful for counting lines during error reporting.
|
/// Returns the previously used scanner, useful for counting lines during error reporting.
|
||||||
Scanner const& getScanner() const { return *m_scanner; }
|
Scanner const& getScanner() const { return *m_scanner; }
|
||||||
@ -76,8 +89,11 @@ private:
|
|||||||
std::shared_ptr<GlobalContext> m_globalContext;
|
std::shared_ptr<GlobalContext> m_globalContext;
|
||||||
std::shared_ptr<ContractDefinition> m_contractASTNode;
|
std::shared_ptr<ContractDefinition> m_contractASTNode;
|
||||||
bool m_parseSuccessful;
|
bool m_parseSuccessful;
|
||||||
std::string m_interface;
|
std::unique_ptr<std::string> m_interface;
|
||||||
|
std::unique_ptr<std::string> m_userDocumentation;
|
||||||
|
std::unique_ptr<std::string> m_devDocumentation;
|
||||||
std::shared_ptr<Compiler> m_compiler;
|
std::shared_ptr<Compiler> m_compiler;
|
||||||
|
std::shared_ptr<InterfaceHandler> m_interfaceHandler;
|
||||||
bytes m_bytecode;
|
bytes m_bytecode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ struct TypeError: virtual Exception {};
|
|||||||
struct DeclarationError: virtual Exception {};
|
struct DeclarationError: virtual Exception {};
|
||||||
struct CompilerError: virtual Exception {};
|
struct CompilerError: virtual Exception {};
|
||||||
struct InternalCompilerError: virtual Exception {};
|
struct InternalCompilerError: virtual Exception {};
|
||||||
|
struct DocstringParsingError: virtual Exception {};
|
||||||
|
|
||||||
typedef boost::error_info<struct tag_sourcePosition, int> errinfo_sourcePosition;
|
typedef boost::error_info<struct tag_sourcePosition, int> errinfo_sourcePosition;
|
||||||
typedef boost::error_info<struct tag_sourceLocation, Location> errinfo_sourceLocation;
|
typedef boost::error_info<struct tag_sourceLocation, Location> errinfo_sourceLocation;
|
||||||
|
278
InterfaceHandler.cpp
Normal file
278
InterfaceHandler.cpp
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
|
||||||
|
#include <libsolidity/InterfaceHandler.h>
|
||||||
|
#include <libsolidity/AST.h>
|
||||||
|
#include <libsolidity/CompilerStack.h>
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace solidity
|
||||||
|
{
|
||||||
|
|
||||||
|
/* -- public -- */
|
||||||
|
|
||||||
|
InterfaceHandler::InterfaceHandler()
|
||||||
|
{
|
||||||
|
m_lastTag = DocTagType::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<std::string> InterfaceHandler::getDocumentation(std::shared_ptr<ContractDefinition> _contractDef,
|
||||||
|
DocumentationType _type)
|
||||||
|
{
|
||||||
|
switch(_type)
|
||||||
|
{
|
||||||
|
case DocumentationType::NATSPEC_USER:
|
||||||
|
return getUserDocumentation(_contractDef);
|
||||||
|
case DocumentationType::NATSPEC_DEV:
|
||||||
|
return getDevDocumentation(_contractDef);
|
||||||
|
case DocumentationType::ABI_INTERFACE:
|
||||||
|
return getABIInterface(_contractDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown documentation type"));
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<std::string> InterfaceHandler::getABIInterface(std::shared_ptr<ContractDefinition> _contractDef)
|
||||||
|
{
|
||||||
|
Json::Value methods(Json::arrayValue);
|
||||||
|
|
||||||
|
for (FunctionDefinition const* f: _contractDef->getInterfaceFunctions())
|
||||||
|
{
|
||||||
|
Json::Value method;
|
||||||
|
Json::Value inputs(Json::arrayValue);
|
||||||
|
Json::Value outputs(Json::arrayValue);
|
||||||
|
|
||||||
|
auto populateParameters = [](std::vector<ASTPointer<VariableDeclaration>> const& _vars)
|
||||||
|
{
|
||||||
|
Json::Value params(Json::arrayValue);
|
||||||
|
for (ASTPointer<VariableDeclaration> const& var: _vars)
|
||||||
|
{
|
||||||
|
Json::Value input;
|
||||||
|
input["name"] = var->getName();
|
||||||
|
input["type"] = var->getType()->toString();
|
||||||
|
params.append(input);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
|
||||||
|
method["name"] = f->getName();
|
||||||
|
method["inputs"] = populateParameters(f->getParameters());
|
||||||
|
method["outputs"] = populateParameters(f->getReturnParameters());
|
||||||
|
methods.append(method);
|
||||||
|
}
|
||||||
|
return std::unique_ptr<std::string>(new std::string(m_writer.write(methods)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(std::shared_ptr<ContractDefinition> _contractDef)
|
||||||
|
{
|
||||||
|
Json::Value doc;
|
||||||
|
Json::Value methods(Json::objectValue);
|
||||||
|
|
||||||
|
for (FunctionDefinition const* f: _contractDef->getInterfaceFunctions())
|
||||||
|
{
|
||||||
|
Json::Value user;
|
||||||
|
auto strPtr = f->getDocumentation();
|
||||||
|
if (strPtr)
|
||||||
|
{
|
||||||
|
resetUser();
|
||||||
|
parseDocString(*strPtr);
|
||||||
|
if (!m_notice.empty())
|
||||||
|
{// since @notice is the only user tag if missing function should not appear
|
||||||
|
user["notice"] = Json::Value(m_notice);
|
||||||
|
methods[f->getName()] = user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doc["methods"] = methods;
|
||||||
|
|
||||||
|
return std::unique_ptr<std::string>(new std::string(m_writer.write(doc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(std::shared_ptr<ContractDefinition> _contractDef)
|
||||||
|
{
|
||||||
|
// LTODO: Somewhere in this function warnings for mismatch of param names
|
||||||
|
// should be thrown
|
||||||
|
Json::Value doc;
|
||||||
|
Json::Value methods(Json::objectValue);
|
||||||
|
|
||||||
|
for (FunctionDefinition const* f: _contractDef->getInterfaceFunctions())
|
||||||
|
{
|
||||||
|
Json::Value method;
|
||||||
|
auto strPtr = f->getDocumentation();
|
||||||
|
if (strPtr)
|
||||||
|
{
|
||||||
|
resetDev();
|
||||||
|
parseDocString(*strPtr);
|
||||||
|
|
||||||
|
if (!m_dev.empty())
|
||||||
|
method["details"] = Json::Value(m_dev);
|
||||||
|
Json::Value params(Json::objectValue);
|
||||||
|
for (auto const& pair: m_params)
|
||||||
|
params[pair.first] = pair.second;
|
||||||
|
|
||||||
|
if (!m_params.empty())
|
||||||
|
method["params"] = params;
|
||||||
|
if (!m_return.empty())
|
||||||
|
method["return"] = m_return;
|
||||||
|
|
||||||
|
if (!method.empty()) // add the function, only if we have any documentation to add
|
||||||
|
methods[f->getName()] = method;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doc["methods"] = methods;
|
||||||
|
|
||||||
|
return std::unique_ptr<std::string>(new std::string(m_writer.write(doc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- private -- */
|
||||||
|
void InterfaceHandler::resetUser()
|
||||||
|
{
|
||||||
|
m_notice.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceHandler::resetDev()
|
||||||
|
{
|
||||||
|
m_dev.clear();
|
||||||
|
m_return.clear();
|
||||||
|
m_params.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string::const_iterator skipLineOrEOS(std::string::const_iterator _nlPos,
|
||||||
|
std::string::const_iterator _end)
|
||||||
|
{
|
||||||
|
return (_nlPos == _end) ? _end : ++_nlPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::const_iterator InterfaceHandler::parseDocTagLine(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end,
|
||||||
|
std::string& _tagString,
|
||||||
|
DocTagType _tagType)
|
||||||
|
{
|
||||||
|
auto nlPos = std::find(_pos, _end, '\n');
|
||||||
|
std::copy(_pos, nlPos, back_inserter(_tagString));
|
||||||
|
m_lastTag = _tagType;
|
||||||
|
return skipLineOrEOS(nlPos, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::const_iterator InterfaceHandler::parseDocTagParam(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end)
|
||||||
|
{
|
||||||
|
// find param name
|
||||||
|
auto currPos = std::find(_pos, _end, ' ');
|
||||||
|
if (currPos == _end)
|
||||||
|
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("End of param name not found" + std::string(_pos, _end)));
|
||||||
|
|
||||||
|
|
||||||
|
auto paramName = std::string(_pos, currPos);
|
||||||
|
|
||||||
|
currPos += 1;
|
||||||
|
auto nlPos = std::find(currPos, _end, '\n');
|
||||||
|
auto paramDesc = std::string(currPos, nlPos);
|
||||||
|
m_params.push_back(std::make_pair(paramName, paramDesc));
|
||||||
|
|
||||||
|
m_lastTag = DocTagType::PARAM;
|
||||||
|
return skipLineOrEOS(nlPos, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end)
|
||||||
|
{
|
||||||
|
// Should never be called with an empty vector
|
||||||
|
if (asserts(!m_params.empty()))
|
||||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Tried to append to empty parameter"));
|
||||||
|
|
||||||
|
auto pair = m_params.back();
|
||||||
|
pair.second += " ";
|
||||||
|
auto nlPos = std::find(_pos, _end, '\n');
|
||||||
|
std::copy(_pos, nlPos, back_inserter(pair.second));
|
||||||
|
|
||||||
|
m_params.at(m_params.size() - 1) = pair;
|
||||||
|
|
||||||
|
return skipLineOrEOS(nlPos, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end,
|
||||||
|
std::string const& _tag)
|
||||||
|
{
|
||||||
|
// LTODO: need to check for @(start of a tag) between here and the end of line
|
||||||
|
// for all cases
|
||||||
|
if (m_lastTag == DocTagType::NONE || _tag != "")
|
||||||
|
{
|
||||||
|
if (_tag == "dev")
|
||||||
|
return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
|
||||||
|
else if (_tag == "notice")
|
||||||
|
return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
|
||||||
|
else if (_tag == "return")
|
||||||
|
return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
|
||||||
|
else if (_tag == "param")
|
||||||
|
return parseDocTagParam(_pos, _end);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// LTODO: Unknown tag, throw some form of warning and not just an exception
|
||||||
|
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("Unknown tag " + _tag + " encountered"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return appendDocTag(_pos, _end);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::const_iterator InterfaceHandler::appendDocTag(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end)
|
||||||
|
{
|
||||||
|
switch (m_lastTag)
|
||||||
|
{
|
||||||
|
case DocTagType::DEV:
|
||||||
|
m_dev += " ";
|
||||||
|
return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
|
||||||
|
case DocTagType::NOTICE:
|
||||||
|
m_notice += " ";
|
||||||
|
return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
|
||||||
|
case DocTagType::RETURN:
|
||||||
|
m_return += " ";
|
||||||
|
return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
|
||||||
|
case DocTagType::PARAM:
|
||||||
|
return appendDocTagParam(_pos, _end);
|
||||||
|
default:
|
||||||
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Illegal documentation tag type"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string::const_iterator getFirstSpaceOrNl(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end)
|
||||||
|
{
|
||||||
|
auto spacePos = std::find(_pos, _end, ' ');
|
||||||
|
auto nlPos = std::find(_pos, _end, '\n');
|
||||||
|
return (spacePos < nlPos) ? spacePos : nlPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InterfaceHandler::parseDocString(std::string const& _string)
|
||||||
|
{
|
||||||
|
auto currPos = _string.begin();
|
||||||
|
auto end = _string.end();
|
||||||
|
|
||||||
|
while (currPos != end)
|
||||||
|
{
|
||||||
|
auto tagPos = std::find(currPos, end, '@');
|
||||||
|
auto nlPos = std::find(currPos, end, '\n');
|
||||||
|
|
||||||
|
if (tagPos != end && tagPos < nlPos)
|
||||||
|
{
|
||||||
|
// we found a tag
|
||||||
|
auto tagNameEndPos = getFirstSpaceOrNl(tagPos, end);
|
||||||
|
if (tagNameEndPos == end)
|
||||||
|
BOOST_THROW_EXCEPTION(DocstringParsingError() <<
|
||||||
|
errinfo_comment("End of tag " + std::string(tagPos, tagNameEndPos) + "not found"));
|
||||||
|
|
||||||
|
currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos));
|
||||||
|
}
|
||||||
|
else if (m_lastTag != DocTagType::NONE) // continuation of the previous tag
|
||||||
|
currPos = appendDocTag(currPos + 1, end);
|
||||||
|
else if (currPos != end) // skip the line if a newline was found
|
||||||
|
currPos = nlPos + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} //solidity NS
|
||||||
|
} // dev NS
|
110
InterfaceHandler.h
Normal file
110
InterfaceHandler.h
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
This file is part of cpp-ethereum.
|
||||||
|
|
||||||
|
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
cpp-ethereum is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @author Lefteris <lefteris@ethdev.com>
|
||||||
|
* @date 2014
|
||||||
|
* Takes the parsed AST and produces the Natspec
|
||||||
|
* documentation and the ABI interface
|
||||||
|
* https://github.com/ethereum/wiki/wiki/Ethereum-Natural-Specification-Format
|
||||||
|
*
|
||||||
|
* Can generally deal with JSON files
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <jsonrpc/json/json.h>
|
||||||
|
|
||||||
|
namespace dev
|
||||||
|
{
|
||||||
|
namespace solidity
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class ContractDefinition;
|
||||||
|
enum class DocumentationType: uint8_t;
|
||||||
|
|
||||||
|
enum class DocTagType: uint8_t
|
||||||
|
{
|
||||||
|
NONE = 0,
|
||||||
|
DEV,
|
||||||
|
NOTICE,
|
||||||
|
PARAM,
|
||||||
|
RETURN
|
||||||
|
};
|
||||||
|
|
||||||
|
class InterfaceHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InterfaceHandler();
|
||||||
|
|
||||||
|
/// Get the given type of documentation
|
||||||
|
/// @param _contractDef The contract definition
|
||||||
|
/// @param _type The type of the documentation. Can be one of the
|
||||||
|
/// types provided by @c DocumentationType
|
||||||
|
/// @return A unique pointer contained string with the json
|
||||||
|
/// representation of provided type
|
||||||
|
std::unique_ptr<std::string> getDocumentation(std::shared_ptr<ContractDefinition> _contractDef,
|
||||||
|
DocumentationType _type);
|
||||||
|
/// Get the ABI Interface of the contract
|
||||||
|
/// @param _contractDef The contract definition
|
||||||
|
/// @return A unique pointer contained string with the json
|
||||||
|
/// representation of the contract's ABI Interface
|
||||||
|
std::unique_ptr<std::string> getABIInterface(std::shared_ptr<ContractDefinition> _contractDef);
|
||||||
|
/// Get the User documentation of the contract
|
||||||
|
/// @param _contractDef The contract definition
|
||||||
|
/// @return A unique pointer contained string with the json
|
||||||
|
/// representation of the contract's user documentation
|
||||||
|
std::unique_ptr<std::string> getUserDocumentation(std::shared_ptr<ContractDefinition> _contractDef);
|
||||||
|
/// Get the Developer's documentation of the contract
|
||||||
|
/// @param _contractDef The contract definition
|
||||||
|
/// @return A unique pointer contained string with the json
|
||||||
|
/// representation of the contract's developer documentation
|
||||||
|
std::unique_ptr<std::string> getDevDocumentation(std::shared_ptr<ContractDefinition> _contractDef);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void resetUser();
|
||||||
|
void resetDev();
|
||||||
|
|
||||||
|
std::string::const_iterator parseDocTagLine(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end,
|
||||||
|
std::string& _tagString,
|
||||||
|
DocTagType _tagType);
|
||||||
|
std::string::const_iterator parseDocTagParam(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end);
|
||||||
|
std::string::const_iterator appendDocTagParam(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end);
|
||||||
|
void parseDocString(std::string const& _string);
|
||||||
|
std::string::const_iterator appendDocTag(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end);
|
||||||
|
std::string::const_iterator parseDocTag(std::string::const_iterator _pos,
|
||||||
|
std::string::const_iterator _end,
|
||||||
|
std::string const& _tag);
|
||||||
|
|
||||||
|
Json::StyledWriter m_writer;
|
||||||
|
|
||||||
|
// internal state
|
||||||
|
DocTagType m_lastTag;
|
||||||
|
std::string m_notice;
|
||||||
|
std::string m_dev;
|
||||||
|
std::string m_return;
|
||||||
|
std::vector<std::pair<std::string, std::string>> m_params;
|
||||||
|
};
|
||||||
|
|
||||||
|
} //solidity NS
|
||||||
|
} // dev NS
|
Loading…
Reference in New Issue
Block a user