github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/lint/utils.go (about)

     1  package lint
     2  
     3  import (
     4  	"strings"
     5  	"unicode"
     6  )
     7  
     8  // Name returns a different name if it should be different.
     9  func Name(name string, whitelist, blacklist []string) (should string) {
    10  	// Fast path for simple cases: "_" and all lowercase.
    11  	if name == "_" {
    12  		return name
    13  	}
    14  	allLower := true
    15  	for _, r := range name {
    16  		if !unicode.IsLower(r) {
    17  			allLower = false
    18  			break
    19  		}
    20  	}
    21  	if allLower {
    22  		return name
    23  	}
    24  
    25  	// Split camelCase at any lower->upper transition, and split on underscores.
    26  	// Check each word for common initialisms.
    27  	runes := []rune(name)
    28  	w, i := 0, 0 // index of start of word, scan
    29  	for i+1 <= len(runes) {
    30  		eow := false // whether we hit the end of a word
    31  		if i+1 == len(runes) {
    32  			eow = true
    33  		} else if runes[i+1] == '_' {
    34  			// underscore; shift the remainder forward over any run of underscores
    35  			eow = true
    36  			n := 1
    37  			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
    38  				n++
    39  			}
    40  
    41  			// Leave at most one underscore if the underscore is between two digits
    42  			if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
    43  				n--
    44  			}
    45  
    46  			copy(runes[i+1:], runes[i+n+1:])
    47  			runes = runes[:len(runes)-n]
    48  		} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
    49  			// lower->non-lower
    50  			eow = true
    51  		}
    52  		i++
    53  		if !eow {
    54  			continue
    55  		}
    56  
    57  		// [w,i) is a word.
    58  		word := string(runes[w:i])
    59  		ignoreInitWarnings := map[string]bool{}
    60  		for _, i := range whitelist {
    61  			ignoreInitWarnings[i] = true
    62  		}
    63  
    64  		extraInits := map[string]bool{}
    65  		for _, i := range blacklist {
    66  			extraInits[i] = true
    67  		}
    68  
    69  		if u := strings.ToUpper(word); (commonInitialisms[u] || extraInits[u]) && !ignoreInitWarnings[u] {
    70  			// Keep consistent case, which is lowercase only at the start.
    71  			if w == 0 && unicode.IsLower(runes[w]) {
    72  				u = strings.ToLower(u)
    73  			}
    74  			// All the common initialisms are ASCII,
    75  			// so we can replace the bytes exactly.
    76  			copy(runes[w:], []rune(u))
    77  		} else if w > 0 && strings.ToLower(word) == word {
    78  			// already all lowercase, and not the first word, so uppercase the first character.
    79  			runes[w] = unicode.ToUpper(runes[w])
    80  		}
    81  		w = i
    82  	}
    83  	return string(runes)
    84  }
    85  
    86  // commonInitialisms is a set of common initialisms.
    87  // Only add entries that are highly unlikely to be non-initialisms.
    88  // For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
    89  var commonInitialisms = map[string]bool{
    90  	"ACL":   true,
    91  	"API":   true,
    92  	"ASCII": true,
    93  	"CPU":   true,
    94  	"CSS":   true,
    95  	"DNS":   true,
    96  	"EOF":   true,
    97  	"GUID":  true,
    98  	"HTML":  true,
    99  	"HTTP":  true,
   100  	"HTTPS": true,
   101  	"ID":    true,
   102  	"IP":    true,
   103  	"JSON":  true,
   104  	"LHS":   true,
   105  	"QPS":   true,
   106  	"RAM":   true,
   107  	"RHS":   true,
   108  	"RPC":   true,
   109  	"SLA":   true,
   110  	"SMTP":  true,
   111  	"SQL":   true,
   112  	"SSH":   true,
   113  	"TCP":   true,
   114  	"TLS":   true,
   115  	"TTL":   true,
   116  	"UDP":   true,
   117  	"UI":    true,
   118  	"UID":   true,
   119  	"UUID":  true,
   120  	"URI":   true,
   121  	"URL":   true,
   122  	"UTF8":  true,
   123  	"VM":    true,
   124  	"XML":   true,
   125  	"XMPP":  true,
   126  	"XSRF":  true,
   127  	"XSS":   true,
   128  }