mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-10-31 14:31:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			128 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			128 lines
		
	
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| package lint
 | |
| 
 | |
| import (
 | |
| 	"strings"
 | |
| 	"unicode"
 | |
| )
 | |
| 
 | |
| // Name returns a different name if it should be different.
 | |
| func Name(name string, whitelist, blacklist []string) (should string) {
 | |
| 	// Fast path for simple cases: "_" and all lowercase.
 | |
| 	if name == "_" {
 | |
| 		return name
 | |
| 	}
 | |
| 	allLower := true
 | |
| 	for _, r := range name {
 | |
| 		if !unicode.IsLower(r) {
 | |
| 			allLower = false
 | |
| 			break
 | |
| 		}
 | |
| 	}
 | |
| 	if allLower {
 | |
| 		return name
 | |
| 	}
 | |
| 
 | |
| 	// Split camelCase at any lower->upper transition, and split on underscores.
 | |
| 	// Check each word for common initialisms.
 | |
| 	runes := []rune(name)
 | |
| 	w, i := 0, 0 // index of start of word, scan
 | |
| 	for i+1 <= len(runes) {
 | |
| 		eow := false // whether we hit the end of a word
 | |
| 		if i+1 == len(runes) {
 | |
| 			eow = true
 | |
| 		} else if runes[i+1] == '_' {
 | |
| 			// underscore; shift the remainder forward over any run of underscores
 | |
| 			eow = true
 | |
| 			n := 1
 | |
| 			for i+n+1 < len(runes) && runes[i+n+1] == '_' {
 | |
| 				n++
 | |
| 			}
 | |
| 
 | |
| 			// Leave at most one underscore if the underscore is between two digits
 | |
| 			if i+n+1 < len(runes) && unicode.IsDigit(runes[i]) && unicode.IsDigit(runes[i+n+1]) {
 | |
| 				n--
 | |
| 			}
 | |
| 
 | |
| 			copy(runes[i+1:], runes[i+n+1:])
 | |
| 			runes = runes[:len(runes)-n]
 | |
| 		} else if unicode.IsLower(runes[i]) && !unicode.IsLower(runes[i+1]) {
 | |
| 			// lower->non-lower
 | |
| 			eow = true
 | |
| 		}
 | |
| 		i++
 | |
| 		if !eow {
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		// [w,i) is a word.
 | |
| 		word := string(runes[w:i])
 | |
| 		ignoreInitWarnings := map[string]bool{}
 | |
| 		for _, i := range whitelist {
 | |
| 			ignoreInitWarnings[i] = true
 | |
| 		}
 | |
| 
 | |
| 		extraInits := map[string]bool{}
 | |
| 		for _, i := range blacklist {
 | |
| 			extraInits[i] = true
 | |
| 		}
 | |
| 
 | |
| 		if u := strings.ToUpper(word); (commonInitialisms[u] || extraInits[u]) && !ignoreInitWarnings[u] {
 | |
| 			// Keep consistent case, which is lowercase only at the start.
 | |
| 			if w == 0 && unicode.IsLower(runes[w]) {
 | |
| 				u = strings.ToLower(u)
 | |
| 			}
 | |
| 			// All the common initialisms are ASCII,
 | |
| 			// so we can replace the bytes exactly.
 | |
| 			copy(runes[w:], []rune(u))
 | |
| 		} else if w > 0 && strings.ToLower(word) == word {
 | |
| 			// already all lowercase, and not the first word, so uppercase the first character.
 | |
| 			runes[w] = unicode.ToUpper(runes[w])
 | |
| 		}
 | |
| 		w = i
 | |
| 	}
 | |
| 	return string(runes)
 | |
| }
 | |
| 
 | |
| // commonInitialisms is a set of common initialisms.
 | |
| // Only add entries that are highly unlikely to be non-initialisms.
 | |
| // For instance, "ID" is fine (Freudian code is rare), but "AND" is not.
 | |
| var commonInitialisms = map[string]bool{
 | |
| 	"ACL":   true,
 | |
| 	"API":   true,
 | |
| 	"ASCII": true,
 | |
| 	"CPU":   true,
 | |
| 	"CSS":   true,
 | |
| 	"DNS":   true,
 | |
| 	"EOF":   true,
 | |
| 	"GUID":  true,
 | |
| 	"HTML":  true,
 | |
| 	"HTTP":  true,
 | |
| 	"HTTPS": true,
 | |
| 	"ID":    true,
 | |
| 	"IP":    true,
 | |
| 	"JSON":  true,
 | |
| 	"LHS":   true,
 | |
| 	"QPS":   true,
 | |
| 	"RAM":   true,
 | |
| 	"RHS":   true,
 | |
| 	"RPC":   true,
 | |
| 	"SLA":   true,
 | |
| 	"SMTP":  true,
 | |
| 	"SQL":   true,
 | |
| 	"SSH":   true,
 | |
| 	"TCP":   true,
 | |
| 	"TLS":   true,
 | |
| 	"TTL":   true,
 | |
| 	"UDP":   true,
 | |
| 	"UI":    true,
 | |
| 	"UID":   true,
 | |
| 	"UUID":  true,
 | |
| 	"URI":   true,
 | |
| 	"URL":   true,
 | |
| 	"UTF8":  true,
 | |
| 	"VM":    true,
 | |
| 	"XML":   true,
 | |
| 	"XMPP":  true,
 | |
| 	"XSRF":  true,
 | |
| 	"XSS":   true,
 | |
| }
 |