Newer
Older
package templates
import (
"bytes"
"fmt"
"strings"
"text/template"
"github.com/eris-ltd/eris-db/manager/eris-mint/evm"
)
const contractTemplateText = `/**
[[.Comment]]
* @dev These functions can be accessed as if this contract were deployed at the address [[.Address]]
*/
contract [[.Name]] {[[range .Functions]]
[[.SolidityIndent 1]]
[[end]]}
`
const functionTemplateText = `/**
[[.Comment]]
*/
function [[.Name]]([[.ArgList]]) constant returns ([[.Return.Type]] [[.Return.Name]]);`
Silas Davis
committed
// Solidity style guide recommends 4 spaces per indentation level
// (see: http://solidity.readthedocs.io/en/develop/style-guide.html)
const indentString = " "
var contractTemplate *template.Template
var functionTemplate *template.Template
func init() {
var err error
functionTemplate, err = template.New("SolidityFunctionTemplate").
Delims("[[", "]]").
Parse(functionTemplateText)
if err != nil {
panic(fmt.Errorf("Couldn't parse SNative function template: %s", err))
}
contractTemplate, err = template.New("SolidityContractTemplate").
Delims("[[", "]]").
Parse(contractTemplateText)
if err != nil {
panic(fmt.Errorf("Couldn't parse SNative contract template: %s", err))
}
}
type solidityContract struct {
*vm.SNativeContractDescription
}
type solidityFunction struct {
*vm.SNativeFunctionDescription
}
// Create a templated solidityContract from an SNative contract description
func NewSolidityContract(contract *vm.SNativeContractDescription) *solidityContract {
return &solidityContract{contract}
}
func (contract *solidityContract) Address() string {
return fmt.Sprintf("0x%x",
contract.SNativeContractDescription.Address().Postfix(20))
}
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
// Generate Solidity code for this SNative contract
func (contract *solidityContract) Solidity() (string, error) {
buf := new(bytes.Buffer)
err := contractTemplate.Execute(buf, contract)
if err != nil {
return "", err
}
return buf.String(), nil
}
func (contract *solidityContract) Functions() []*solidityFunction {
functions := contract.SNativeContractDescription.Functions()
solidityFunctions := make([]*solidityFunction, len(functions))
for i, function := range functions {
solidityFunctions[i] = NewSolidityFunction(function)
}
return solidityFunctions
}
// Create a templated solidityFunction from an SNative function description
func NewSolidityFunction(function *vm.SNativeFunctionDescription) *solidityFunction {
return &solidityFunction{function}
}
func (function *solidityFunction) ArgList() string {
argList := make([]string, len(function.Args))
for i, arg := range function.Args {
argList[i] = fmt.Sprintf("%s %s", arg.Type, arg.Name)
}
return strings.Join(argList, ", ")
}
func (function *solidityFunction) Comment() string {
return comment(function.SNativeFunctionDescription.Comment)
}
func (function *solidityFunction) SolidityIndent(indentLevel uint) (string, error) {
return function.solidity(indentLevel)
}
func (function *solidityFunction) Solidity() (string, error) {
return function.solidity(0)
}
func (function *solidityFunction) solidity(indentLevel uint) (string, error) {
buf := new(bytes.Buffer)
iw := NewIndentWriter(indentLevel, indentString, buf)
err := functionTemplate.Execute(iw, function)
if err != nil {
return "", err
}
return buf.String(), nil
}
func (contract *solidityContract) Comment() string {
return comment(contract.SNativeContractDescription.Comment)
}
func comment(comment string) string {
commentLines := make([]string, 0, 5)
for _, line := range strings.Split(comment, "\n") {
trimLine := strings.TrimLeft(line, " \t\n")
if trimLine != "" {
commentLines = append(commentLines, trimLine)
}
}
return strings.Join(commentLines, "\n")
}