Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

service/dap: use address, not index to differentiate compound map keys #2291

Merged
merged 2 commits into from
Jan 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions service/dap/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -915,7 +915,8 @@ func (s *Server) onVariablesRequest(request *dap.VariablesRequest) {
// A map will have twice as many children as there are key-value elements.
kvIndex := i / 2
// Process children in pairs: even indices are map keys, odd indices are values.
key, keyref := s.convertVariable(&v.Children[i])
keyv := &v.Children[i]
key, keyref := s.convertVariable(keyv)
val, valref := s.convertVariable(&v.Children[i+1])
// If key or value or both are scalars, we can use
// a single variable to represet key:value format.
Expand All @@ -938,7 +939,7 @@ func (s *Server) onVariablesRequest(request *dap.VariablesRequest) {
Value: val,
}
if keyref != 0 { // key is a type to be expanded
kvvar.Name = fmt.Sprintf("%s[%d]", kvvar.Name, kvIndex) // Make the name unique
kvvar.Name = fmt.Sprintf("%s(%#x)", kvvar.Name, keyv.Addr) // Make the name unique
kvvar.VariablesReference = keyref
} else if valref != 0 { // val is a type to be expanded
kvvar.VariablesReference = valref
Expand Down
38 changes: 22 additions & 16 deletions service/dap/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ func expectChildren(t *testing.T, got *dap.VariablesResponse, parentName string,
// i - index of the variable within VariablesRespose.Body.Variables array (-1 will search all vars for a match)
// name - name of the variable
// value - the value of the variable
// useExactMatch - true if value is to be compared to exactly, false if to be used as regex
// useExactMatch - true if name and value are to be compared to exactly, false if to be used as regex
// hasRef - true if the variable should have children and therefore a non-0 variable reference
// ref - reference to retrieve children of this variable (0 if none)
func expectVar(t *testing.T, got *dap.VariablesResponse, i int, name, value string, useExactMatch, hasRef bool) (ref int) {
Expand All @@ -604,16 +604,22 @@ func expectVar(t *testing.T, got *dap.VariablesResponse, i int, name, value stri
}

goti := got.Body.Variables[i]
if goti.Name != name || (goti.VariablesReference > 0) != hasRef {
matchedName := false
if useExactMatch {
matchedName = (goti.Name == name)
} else {
matchedName, _ = regexp.MatchString(name, goti.Name)
}
if !matchedName || (goti.VariablesReference > 0) != hasRef {
t.Errorf("\ngot %#v\nwant Name=%q hasRef=%t", goti, name, hasRef)
}
matched := false
matchedValue := false
if useExactMatch {
matched = (goti.Value == value)
matchedValue = (goti.Value == value)
} else {
matched, _ = regexp.MatchString(value, goti.Value)
matchedValue, _ = regexp.MatchString(value, goti.Value)
}
if !matched {
if !matchedValue {
t.Errorf("\ngot %s=%q\nwant %q", name, goti.Value, value)
}
return goti.VariablesReference
Expand All @@ -625,7 +631,7 @@ func expectVarExact(t *testing.T, got *dap.VariablesResponse, i int, name, value
return expectVar(t, got, i, name, value, true, hasRef)
}

// expectVarRegex is a helper like expectVar that treats value as a regex.
// expectVarRegex is a helper like expectVar that treats name and value as a regex.
func expectVarRegex(t *testing.T, got *dap.VariablesResponse, i int, name, value string, hasRef bool) (ref int) {
t.Helper()
return expectVar(t, got, i, name, value, false, hasRef)
Expand Down Expand Up @@ -837,7 +843,7 @@ func TestScopesAndVariablesRequests(t *testing.T) {
// reflect.Kind == Interface - see testvariables2
// reflect.Kind == Map - see testvariables2
// reflect.Kind == Ptr
ref = expectVarRegex(t, locals, -1, "a7", "<\\*main\\.FooBar>\\(0x[0-9a-f]+\\)", hasChildren)
ref = expectVarRegex(t, locals, -1, "a7", `<\*main\.FooBar>\(0x[0-9a-f]+\)`, hasChildren)
if ref > 0 {
client.VariablesRequest(ref)
a7 := client.ExpectVariablesResponse(t)
Expand Down Expand Up @@ -882,9 +888,9 @@ func TestScopesAndVariablesRequests(t *testing.T) {
client.VariablesRequest(ref)
a13 := client.ExpectVariablesResponse(t)
expectChildren(t, a13, "a13", 3)
expectVarRegex(t, a13, 0, "[0]", "<\\*main\\.FooBar>\\(0x[0-9a-f]+\\)", hasChildren)
expectVarRegex(t, a13, 1, "[1]", "<\\*main\\.FooBar>\\(0x[0-9a-f]+\\)", hasChildren)
ref = expectVarRegex(t, a13, 2, "[2]", "<\\*main\\.FooBar>\\(0x[0-9a-f]+\\)", hasChildren)
expectVarRegex(t, a13, 0, `\[0\]`, `<\*main\.FooBar>\(0x[0-9a-f]+\)`, hasChildren)
expectVarRegex(t, a13, 1, `\[1\]`, `<\*main\.FooBar>\(0x[0-9a-f]+\)`, hasChildren)
ref = expectVarRegex(t, a13, 2, `\[2\]`, `<\*main\.FooBar>\(0x[0-9a-f]+\)`, hasChildren)
if ref > 0 {
client.VariablesRequest(ref)
a13_2 := client.ExpectVariablesResponse(t)
Expand Down Expand Up @@ -1086,7 +1092,7 @@ func TestScopesAndVariablesRequests2(t *testing.T) {
client.VariablesRequest(ref)
m2 := client.ExpectVariablesResponse(t)
expectChildren(t, m2, "m2", 1)
ref = expectVarRegex(t, m2, 0, "1", "<\\*main\\.astruct>\\(0x[0-9a-f]+\\)", hasChildren)
ref = expectVarRegex(t, m2, 0, "1", `<\*main\.astruct>\(0x[0-9a-f]+\)`, hasChildren)
if ref > 0 {
client.VariablesRequest(ref)
m2_1 := client.ExpectVariablesResponse(t)
Expand All @@ -1106,15 +1112,15 @@ func TestScopesAndVariablesRequests2(t *testing.T) {
client.VariablesRequest(ref)
m3 := client.ExpectVariablesResponse(t)
expectChildren(t, m3, "m3", 2)
ref = expectVarExact(t, m3, 0, "<main.astruct>[0]", "42", hasChildren)
ref = expectVarRegex(t, m3, 0, `<main\.astruct>\(0x[0-9a-f]+\)`, "42", hasChildren)
if ref > 0 {
client.VariablesRequest(ref)
m3_0 := client.ExpectVariablesResponse(t)
expectChildren(t, m3_0, "m3[0]", 2)
expectVarExact(t, m3_0, 0, "A", "1", noChildren)
expectVarExact(t, m3_0, 1, "B", "1", noChildren)
}
ref = expectVarExact(t, m3, 1, "<main.astruct>[1]", "43", hasChildren)
ref = expectVarRegex(t, m3, 1, `<main\.astruct>\(0x[0-9a-f]+\)`, "43", hasChildren)
if ref > 0 {
client.VariablesRequest(ref)
m3_1 := client.ExpectVariablesResponse(t)
Expand Down Expand Up @@ -1164,8 +1170,8 @@ func TestScopesAndVariablesRequests2(t *testing.T) {
expectVarExact(t, locals, -1, "zsvar", "<struct {}>", noChildren)
// reflect.Kind == UnsafePointer
// TODO(polina): how do I test for unsafe.Pointer(nil)?
expectVarRegex(t, locals, -1, "upnil", "unsafe\\.Pointer\\(0x0\\)", noChildren)
expectVarRegex(t, locals, -1, "up1", "unsafe\\.Pointer\\(0x[0-9a-f]+\\)", noChildren)
expectVarRegex(t, locals, -1, "upnil", `unsafe\.Pointer\(0x0\)`, noChildren)
expectVarRegex(t, locals, -1, "up1", `unsafe\.Pointer\(0x[0-9a-f]+\)`, noChildren)

// Test unreadable variable
ref = expectVarExact(t, locals, -1, "unread", "<*int>(0x3039)", hasChildren)
Expand Down