microsoft / vscode-go

An extension for VS Code which provides support for the Go language. We have moved to https://github.com/golang/vscode-go
Other
5.93k stars 648 forks source link

Cannot view nested maps on watch/variables panes - "Failed to eval expression" #3198

Closed lggomez closed 4 years ago

lggomez commented 4 years ago

What version of Go, VS Code & VS Code Go extension are you using?

Describe the bug

1- Have a nested map variable:

    nestedmap := map[string]interface{}{}
    nestedmap["issuer"] = map[string]interface{}{
        "foo": "bar",
    }

2- Expand the variable in the variables pane up to foo, and the debug adapter request will fail with the following:

VariablesRequest
Failed to eval expression:  {
 "Expr": "nestedmap.data.data[\"foo\"]",
 "Scope": {
  "goroutineID": -1,
  "frame": 0
 },
 "Cfg": {
  "followPointers": true,
  "maxVariableRecurse": 1,
  "maxStringLen": 100,
  "maxArrayValues": 5,
  "maxStructFields": -1
 }
} 

Eval error: nestedmap (type map[string]interface {}) is not a struct
Failed to evaluate expression - nestedmap (type map[string]interface {}) is not a struct

 Screenshot

Screen Shot 2020-04-20 at 20 43 16

The watch and variables pane expect a tree object which we create from the delve response in order to show the key and value properties of the map, and on traversal from the pane we're not converting back this object to go syntax, thus being b.data.data["issuer"] instead of b["issuer"] and/or b["issuer"]["foo"]

lggomez commented 4 years ago

Here is the relevant code which does the variables request to delve and converts said response's variable representations from delve into DAP variables:

request: https://github.com/microsoft/vscode-go/blob/master/src/debugAdapter/goDebug.ts#L1189-L1209

variable mapper: https://github.com/microsoft/vscode-go/blob/master/src/debugAdapter/goDebug.ts#L1614-L1694

Aisuko commented 4 years ago

@lggomez Thanks for helping create the issue. Mark and waiting for fixing.

lggomez commented 4 years ago

For reference, the correct expression to get the innermost property of this map:

    nestedmap := map[string]interface{}{
        "issuer": map[string]interface{}{
            "foo1": map[string]interface{}{
                "foo2": "bar2",
            },
        },
    }

is the following:

(dlv) p nestedmap["issuer"].(data)["foo1"].(data)["foo2"]
interface {}(string) "bar2"
ramya-rao-a commented 4 years ago

Closing this in favor of https://github.com/golang/vscode-go/issues/135 as we are moving!

Please subscribe to the new issue for further updates