Skip to content

Commit

Permalink
Add ShortenType function
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanhaller committed Oct 20, 2023
1 parent 909add7 commit e039584
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 0 deletions.
102 changes: 102 additions & 0 deletions service/api/shorten_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package api

import (
"strings"
"unicode"
)

func ShortenType(typ string) string {
out, ok := shortenTypeEx(typ)
if !ok {
return typ
}
return out
}

func shortenTypeEx(typ string) (string, bool) {
switch {
case strings.HasPrefix(typ, "["):
for i := range typ {
if typ[i] == ']' {
sub, ok := shortenTypeEx(typ[i+1:])
return typ[:i+1] + sub, ok
}
}
return "", false
case strings.HasPrefix(typ, "*"):
sub, ok := shortenTypeEx(typ[1:])
return "*" + sub, ok
case strings.HasPrefix(typ, "map["):
depth := 1
for i := 4; i < len(typ); i++ {
switch typ[i] {
case '[':
depth++
case ']':
depth--
if depth == 0 {
key, keyok := shortenTypeEx(typ[4:i])
val, valok := shortenTypeEx(typ[i+1:])
return "map[" + key + "]" + val, keyok && valok
}
}
}
return "", false
case typ == "interface {}" || typ == "interface{}":
return typ, true
case typ == "struct {}" || typ == "struct{}":
return typ, true
default:
if containsAnonymousType(typ) {
return "", false
}

if lbrk := strings.Index(typ, "["); lbrk >= 0 {
if typ[len(typ)-1] != ']' {
return "", false
}
typ0, ok := shortenTypeEx(typ[:lbrk])
if !ok {
return "", false
}
args := strings.Split(typ[lbrk+1:len(typ)-1], ",")
for i := range args {
var ok bool
args[i], ok = shortenTypeEx(strings.TrimSpace(args[i]))
if !ok {
return "", false
}
}
return typ0 + "[" + strings.Join(args, ", ") + "]", true
}

slashnum := 0
slash := -1
for i, ch := range typ {
if !unicode.IsLetter(ch) && !unicode.IsDigit(ch) && ch != '_' && ch != '.' && ch != '/' && ch != '@' && ch != '%' && ch != '-' {
return "", false
}
if ch == '/' {
slash = i
slashnum++
}
}
if slashnum <= 1 || slash < 0 {
return typ, true
}
return typ[slash+1:], true
}
}

func containsAnonymousType(typ string) bool {
for _, thing := range []string{"interface {", "interface{", "struct {", "struct{", "func (", "func("} {
idx := strings.Index(typ, thing)
if idx >= 0 && idx+len(thing) < len(typ) {
ch := typ[idx+len(thing)]
if ch != '}' && ch != ')' {
return true
}
}
}
return false
}
36 changes: 36 additions & 0 deletions service/api/shorten_type_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package api

import "testing"

func TestShortenType(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"long/package/path/pkg.A", "pkg.A"},
{"[]long/package/path/pkg.A", "[]pkg.A"},
{"map[long/package/path/pkg.A]long/package/path/pkg.B", "map[pkg.A]pkg.B"},
{"map[long/package/path/pkg.A]interface {}", "map[pkg.A]interface {}"},
{"map[long/package/path/pkg.A]interface{}", "map[pkg.A]interface{}"},
{"map[long/package/path/pkg.A]struct {}", "map[pkg.A]struct {}"},
{"map[long/package/path/pkg.A]struct{}", "map[pkg.A]struct{}"},
{"map[long/package/path/pkg.A]map[long/package/path/pkg.B]long/package/path/pkg.C", "map[pkg.A]map[pkg.B]pkg.C"},
{"map[long/package/path/pkg.A][]long/package/path/pkg.B", "map[pkg.A][]pkg.B"},
{"map[uint64]*github.com/aarzilli/dwarf5/dwarf.typeUnit", "map[uint64]*dwarf.typeUnit"},
{"uint8", "uint8"},
{"encoding/binary", "encoding/binary"},
{"*github.com/go-delve/delve/pkg/proc.Target", "*proc.Target"},
{"long/package/path/pkg.Parametric[long/package/path/pkg.A, map[long/package/path/pkg.B]long/package/path/pkg.A]", "pkg.Parametric[pkg.A, map[pkg.B]pkg.A]"},
{"[]long/package/path/pkg.Parametric[long/package/path/pkg.A]", "[]pkg.Parametric[pkg.A]"},
{"[24]long/package/path/pkg.A", "[24]pkg.A"},
{"chan func()", "chan func()"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
result := ShortenType(tt.input)
if result != tt.expected {
t.Errorf("shortenTypeEx() got = %v, want %v", result, tt.expected)
}
})
}
}

0 comments on commit e039584

Please sign in to comment.