1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
#include <libsolidity/InterfaceHandler.h>
#include <libsolidity/AST.h>
#include <libsolidity/CompilerStack.h>
namespace dev {
namespace solidity {
/* -- public -- */
InterfaceHandler::InterfaceHandler()
{
}
std::unique_ptr<std::string> InterfaceHandler::getDocumentation(std::shared_ptr<ContractDefinition> _contractDef,
enum documentationType _type)
{
switch(_type)
{
case NATSPEC_USER:
return getUserDocumentation(_contractDef);
case NATSPEC_DEV:
return getDevDocumentation(_contractDef);
case ABI_INTERFACE:
return getABIInterface(_contractDef);
}
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Internal error"));
return nullptr;
}
std::unique_ptr<std::string> InterfaceHandler::getABIInterface(std::shared_ptr<ContractDefinition> _contractDef)
{
Json::Value methods(Json::arrayValue);
std::vector<FunctionDefinition const*> exportedFunctions = _contractDef->getInterfaceFunctions();
for (FunctionDefinition const* f: exportedFunctions)
{
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)
{
user["notice"] = Json::Value(*strPtr);
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)
{
Json::Value doc;
Json::Value methods(Json::objectValue);
for (FunctionDefinition const* f: _contractDef->getInterfaceFunctions())
{
Json::Value method;
auto strPtr = f->getDocumentation();
if (strPtr)
{
m_dev.clear();
parseDocString(*strPtr);
method["dev"] = Json::Value(m_dev);
methods[f->getName()] = method;
}
}
doc["methods"] = methods;
return std::unique_ptr<std::string>(new std::string(m_writer.write(doc)));
}
/* -- private -- */
size_t InterfaceHandler::parseDocTag(std::string const& _string, std::string const& _tag, size_t _pos)
{
size_t nlPos = _pos;
if (_tag == "dev")
{
nlPos = _string.find("\n", _pos);
m_dev += _string.substr(_pos,
nlPos == std::string::npos ?
_string.length() :
nlPos - _pos);
}
else if (_tag == "notice")
{
nlPos = _string.find("\n", _pos);
m_notice += _string.substr(_pos,
nlPos == std::string::npos ?
_string.length() :
nlPos - _pos);
}
else
{
//TODO: Some form of warning
}
return nlPos;
}
void InterfaceHandler::parseDocString(std::string const& _string, size_t _startPos)
{
size_t pos2;
size_t pos1 = _string.find("@", _startPos);
if (pos1 == std::string::npos)
return; // no doxytags found
pos2 = _string.find(" ", pos1);
if (pos2 == std::string::npos)
return; //no end of tag found
size_t newPos = parseDocTag(_string, _string.substr(pos1 + 1, pos2 - pos1), pos2);
parseDocString(_string, newPos);
}
} //solidity NS
} // dev NS
|