gitlab.com/Raven-IO/raven-delve@v1.22.4/service/api/shorten_type.go (about)

     1  package api
     2  
     3  import (
     4  	"strings"
     5  	"unicode"
     6  )
     7  
     8  func ShortenType(typ string) string {
     9  	out, ok := shortenTypeEx(typ)
    10  	if !ok {
    11  		return typ
    12  	}
    13  	return out
    14  }
    15  
    16  func shortenTypeEx(typ string) (string, bool) {
    17  	switch {
    18  	case strings.HasPrefix(typ, "["):
    19  		for i := range typ {
    20  			if typ[i] == ']' {
    21  				sub, ok := shortenTypeEx(typ[i+1:])
    22  				return typ[:i+1] + sub, ok
    23  			}
    24  		}
    25  		return "", false
    26  	case strings.HasPrefix(typ, "*"):
    27  		sub, ok := shortenTypeEx(typ[1:])
    28  		return "*" + sub, ok
    29  	case strings.HasPrefix(typ, "map["):
    30  		depth := 1
    31  		for i := 4; i < len(typ); i++ {
    32  			switch typ[i] {
    33  			case '[':
    34  				depth++
    35  			case ']':
    36  				depth--
    37  				if depth == 0 {
    38  					key, keyok := shortenTypeEx(typ[4:i])
    39  					val, valok := shortenTypeEx(typ[i+1:])
    40  					return "map[" + key + "]" + val, keyok && valok
    41  				}
    42  			}
    43  		}
    44  		return "", false
    45  	case typ == "interface {}" || typ == "interface{}":
    46  		return typ, true
    47  	case typ == "struct {}" || typ == "struct{}":
    48  		return typ, true
    49  	default:
    50  		if containsAnonymousType(typ) {
    51  			return "", false
    52  		}
    53  
    54  		if lbrk := strings.Index(typ, "["); lbrk >= 0 {
    55  			if typ[len(typ)-1] != ']' {
    56  				return "", false
    57  			}
    58  			typ0, ok := shortenTypeEx(typ[:lbrk])
    59  			if !ok {
    60  				return "", false
    61  			}
    62  			args := strings.Split(typ[lbrk+1:len(typ)-1], ",")
    63  			for i := range args {
    64  				var ok bool
    65  				args[i], ok = shortenTypeEx(strings.TrimSpace(args[i]))
    66  				if !ok {
    67  					return "", false
    68  				}
    69  			}
    70  			return typ0 + "[" + strings.Join(args, ", ") + "]", true
    71  		}
    72  
    73  		slashnum := 0
    74  		slash := -1
    75  		for i, ch := range typ {
    76  			if !unicode.IsLetter(ch) && !unicode.IsDigit(ch) && ch != '_' && ch != '.' && ch != '/' && ch != '@' && ch != '%' && ch != '-' {
    77  				return "", false
    78  			}
    79  			if ch == '/' {
    80  				slash = i
    81  				slashnum++
    82  			}
    83  		}
    84  		if slashnum <= 1 || slash < 0 {
    85  			return typ, true
    86  		}
    87  		return typ[slash+1:], true
    88  	}
    89  }
    90  
    91  func containsAnonymousType(typ string) bool {
    92  	for _, thing := range []string{"interface {", "interface{", "struct {", "struct{", "func (", "func("} {
    93  		idx := strings.Index(typ, thing)
    94  		if idx >= 0 && idx+len(thing) < len(typ) {
    95  			ch := typ[idx+len(thing)]
    96  			if ch != '}' && ch != ')' {
    97  				return true
    98  			}
    99  		}
   100  	}
   101  	return false
   102  }