*: support _initialize method in contracts

Invoke `_initialize` method on every call if present.
In NEO3 there is no entrypoint and methods are invoked by offset,
thus `Main` function is no longer required.
We still have special `Main` method in tests to simplify them.
This commit is contained in:
Evgenii Stratonikov 2020-07-24 13:40:54 +03:00
parent 466af55dea
commit 685d44dbc1
9 changed files with 156 additions and 40 deletions

View file

@ -17,6 +17,7 @@ import (
// DebugInfo represents smart-contract debug information.
type DebugInfo struct {
MainPkg string `json:"-"`
Hash util.Uint160 `json:"hash"`
Documents []string `json:"documents"`
Methods []MethodDebugInfo `json:"methods"`
@ -102,8 +103,24 @@ func (c *codegen) saveSequencePoint(n ast.Node) {
func (c *codegen) emitDebugInfo(contract []byte) *DebugInfo {
d := &DebugInfo{
Hash: hash.Hash160(contract),
Events: []EventDebugInfo{},
MainPkg: c.mainPkg.Pkg.Name(),
Hash: hash.Hash160(contract),
Events: []EventDebugInfo{},
}
if c.initEndOffset > 0 {
d.Methods = append(d.Methods, MethodDebugInfo{
ID: manifest.MethodInit,
Name: DebugMethodName{
Name: manifest.MethodInit,
Namespace: c.mainPkg.Pkg.Name(),
},
IsExported: true,
Range: DebugRange{
Start: 0,
End: uint16(c.initEndOffset),
},
ReturnType: "Void",
})
}
for name, scope := range c.funcs {
m := c.methodInfoFromScope(name, scope)
@ -341,22 +358,13 @@ func parsePairJSON(data []byte, sep string) (string, string, error) {
// ConvertToManifest converts contract to the manifest.Manifest struct for debugger.
// Note: manifest is taken from the external source, however it can be generated ad-hoc. See #1038.
func (di *DebugInfo) ConvertToManifest(fs smartcontract.PropertyState) (*manifest.Manifest, error) {
var (
mainNamespace string
err error
)
for _, method := range di.Methods {
if method.Name.Name == mainIdent {
mainNamespace = method.Name.Namespace
break
}
}
if mainNamespace == "" {
var err error
if di.MainPkg == "" {
return nil, errors.New("no Main method was found")
}
methods := make([]manifest.Method, 0)
for _, method := range di.Methods {
if method.IsExported && method.Name.Namespace == mainNamespace {
if method.IsExported && method.Name.Namespace == di.MainPkg {
mMethod, err := method.ToManifestMethod()
if err != nil {
return nil, err