diff --git a/docs/reference/rpc-endpoints.md b/docs/reference/rpc-endpoints.md index ecbbde8262b..f163cfe077a 100644 --- a/docs/reference/rpc-endpoints.md +++ b/docs/reference/rpc-endpoints.md @@ -459,6 +459,7 @@ Call with the `/abci_query` to get information via the ABCI Query. | `bank/balances/{ADDRESS}` | Returns the balance information about the account. | | `vm/qfuncs` | Returns public facing function signatures as JSON. | | `vm/qfile` | Returns the file bytes, or list of files if directory. | +| `vm/qdoc` | Returns JSON of the package doc, suitable for printing. | | `vm/qrender` | Calls `.Render()` in readonly mode. | | `vm/qeval` | Evaluates any expression in readonly mode and returns the results. | | `vm/store` | (not yet supported) Fetches items from the store. | diff --git a/gno.land/pkg/sdk/vm/handler.go b/gno.land/pkg/sdk/vm/handler.go index c484e07e887..005e0f4d2f4 100644 --- a/gno.land/pkg/sdk/vm/handler.go +++ b/gno.land/pkg/sdk/vm/handler.go @@ -74,6 +74,7 @@ const ( QueryFuncs = "qfuncs" QueryEval = "qeval" QueryFile = "qfile" + QueryDoc = "qdoc" ) func (vh vmHandler) Query(ctx sdk.Context, req abci.RequestQuery) abci.ResponseQuery { @@ -95,6 +96,8 @@ func (vh vmHandler) Query(ctx sdk.Context, req abci.RequestQuery) abci.ResponseQ res = vh.queryEval(ctx, req) case QueryFile: res = vh.queryFile(ctx, req) + case QueryDoc: + res = vh.queryDoc(ctx, req) default: return sdk.ABCIResponseQueryFromError( std.ErrUnknownRequest(fmt.Sprintf( @@ -197,6 +200,20 @@ func (vh vmHandler) queryFile(ctx sdk.Context, req abci.RequestQuery) (res abci. return } +// queryDoc returns the file bytes, or list of files if directory. +// if file, res.Value is []byte("file"). +// if dir, res.Value is []byte("dir"). +func (vh vmHandler) queryDoc(ctx sdk.Context, req abci.RequestQuery) (res abci.ResponseQuery) { + filepath := string(req.Data) + jsonDoc, err := vh.vm.QueryDoc(ctx, filepath) + if err != nil { + res = sdk.ABCIResponseQueryFromError(err) + return + } + res.Data = []byte(jsonDoc.JSON()) + return +} + // ---------------------------------------- // misc diff --git a/gno.land/pkg/sdk/vm/keeper.go b/gno.land/pkg/sdk/vm/keeper.go index bf16cd44243..1abfd16c5e4 100644 --- a/gno.land/pkg/sdk/vm/keeper.go +++ b/gno.land/pkg/sdk/vm/keeper.go @@ -16,6 +16,7 @@ import ( "time" "github.com/gnolang/gno/gnovm" + "github.com/gnolang/gno/gnovm/pkg/doc" gno "github.com/gnolang/gno/gnovm/pkg/gnolang" "github.com/gnolang/gno/gnovm/stdlibs" "github.com/gnolang/gno/tm2/pkg/crypto" @@ -843,6 +844,27 @@ func (vm *VMKeeper) QueryFile(ctx sdk.Context, filepath string) (res string, err } } +var rePkgPathAndSymbol = regexp.MustCompile(`^(.+)\.([a-zA-Z0-9_]+)$`) + +func (vm *VMKeeper) QueryDoc(ctx sdk.Context, input string) (*doc.JSONDocumentation, error) { + store := vm.newGnoTransactionStore(ctx) // throwaway (never committed) + pkgPath := input + symbol := "" + match := rePkgPathAndSymbol.FindStringSubmatch(input) + if len(match) == 3 { + // The input is [. + pkgPath = match[1] + symbol = match[2] + } + + memPkg := store.GetMemPackage(pkgPath) + d, err := doc.NewDocumentableFromMemPkg(memPkg, true, symbol, "") + if err != nil { + return nil, err + } + return d.WriteJSONDocumentation() +} + // logTelemetry logs the VM processing telemetry func logTelemetry( gasUsed int64,