Custom resource definition
Co-authored-by: Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
This commit is contained in:
parent
cfaf47c8a2
commit
4c060a78cc
1348 changed files with 92364 additions and 55766 deletions
31
vendor/k8s.io/gengo/namer/doc.go
generated
vendored
Normal file
31
vendor/k8s.io/gengo/namer/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Package namer has support for making different type naming systems.
|
||||
//
|
||||
// This is because sometimes you want to refer to the literal type, sometimes
|
||||
// you want to make a name for the thing you're generating, and you want to
|
||||
// make the name based on the type. For example, if you have `type foo string`,
|
||||
// you want to be able to generate something like `func FooPrinter(f *foo) {
|
||||
// Print(string(*f)) }`; that is, you want to refer to a public name, a literal
|
||||
// name, and the underlying literal name.
|
||||
//
|
||||
// This package supports the idea of a "Namer" and a set of "NameSystems" to
|
||||
// support these use cases.
|
||||
//
|
||||
// Additionally, a "RawNamer" can optionally keep track of what needs to be
|
||||
// imported.
|
||||
package namer // import "k8s.io/gengo/namer"
|
112
vendor/k8s.io/gengo/namer/import_tracker.go
generated
vendored
Normal file
112
vendor/k8s.io/gengo/namer/import_tracker.go
generated
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namer
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// ImportTracker may be passed to a namer.RawNamer, to track the imports needed
|
||||
// for the types it names.
|
||||
//
|
||||
// TODO: pay attention to the package name (instead of renaming every package).
|
||||
type DefaultImportTracker struct {
|
||||
pathToName map[string]string
|
||||
// forbidden names are in here. (e.g. "go" is a directory in which
|
||||
// there is code, but "go" is not a legal name for a package, so we put
|
||||
// it here to prevent us from naming any package "go")
|
||||
nameToPath map[string]string
|
||||
local types.Name
|
||||
|
||||
// Returns true if a given types is an invalid type and should be ignored.
|
||||
IsInvalidType func(*types.Type) bool
|
||||
// Returns the final local name for the given name
|
||||
LocalName func(types.Name) string
|
||||
// Returns the "import" line for a given (path, name).
|
||||
PrintImport func(string, string) string
|
||||
}
|
||||
|
||||
func NewDefaultImportTracker(local types.Name) DefaultImportTracker {
|
||||
return DefaultImportTracker{
|
||||
pathToName: map[string]string{},
|
||||
nameToPath: map[string]string{},
|
||||
local: local,
|
||||
}
|
||||
}
|
||||
|
||||
func (tracker *DefaultImportTracker) AddTypes(types ...*types.Type) {
|
||||
for _, t := range types {
|
||||
tracker.AddType(t)
|
||||
}
|
||||
}
|
||||
func (tracker *DefaultImportTracker) AddType(t *types.Type) {
|
||||
if tracker.local.Package == t.Name.Package {
|
||||
return
|
||||
}
|
||||
|
||||
if tracker.IsInvalidType(t) {
|
||||
if t.Kind == types.Builtin {
|
||||
return
|
||||
}
|
||||
if _, ok := tracker.nameToPath[t.Name.Package]; !ok {
|
||||
tracker.nameToPath[t.Name.Package] = ""
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if len(t.Name.Package) == 0 {
|
||||
return
|
||||
}
|
||||
path := t.Name.Path
|
||||
if len(path) == 0 {
|
||||
path = t.Name.Package
|
||||
}
|
||||
if _, ok := tracker.pathToName[path]; ok {
|
||||
return
|
||||
}
|
||||
name := tracker.LocalName(t.Name)
|
||||
tracker.nameToPath[name] = path
|
||||
tracker.pathToName[path] = name
|
||||
}
|
||||
|
||||
func (tracker *DefaultImportTracker) ImportLines() []string {
|
||||
importPaths := []string{}
|
||||
for path := range tracker.pathToName {
|
||||
importPaths = append(importPaths, path)
|
||||
}
|
||||
sort.Sort(sort.StringSlice(importPaths))
|
||||
out := []string{}
|
||||
for _, path := range importPaths {
|
||||
out = append(out, tracker.PrintImport(path, tracker.pathToName[path]))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// LocalNameOf returns the name you would use to refer to the package at the
|
||||
// specified path within the body of a file.
|
||||
func (tracker *DefaultImportTracker) LocalNameOf(path string) string {
|
||||
return tracker.pathToName[path]
|
||||
}
|
||||
|
||||
// PathOf returns the path that a given localName is referring to within the
|
||||
// body of a file.
|
||||
func (tracker *DefaultImportTracker) PathOf(localName string) (string, bool) {
|
||||
name, ok := tracker.nameToPath[localName]
|
||||
return name, ok
|
||||
}
|
383
vendor/k8s.io/gengo/namer/namer.go
generated
vendored
Normal file
383
vendor/k8s.io/gengo/namer/namer.go
generated
vendored
Normal file
|
@ -0,0 +1,383 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namer
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
const (
|
||||
// GoSeperator is used to split go import paths.
|
||||
// Forward slash is used instead of filepath.Seperator because it is the
|
||||
// only universally-accepted path delimiter and the only delimiter not
|
||||
// potentially forbidden by Go compilers. (In particular gc does not allow
|
||||
// the use of backslashes in import paths.)
|
||||
// See https://golang.org/ref/spec#Import_declarations.
|
||||
// See also https://github.com/kubernetes/gengo/issues/83#issuecomment-367040772.
|
||||
GoSeperator = "/"
|
||||
)
|
||||
|
||||
// Returns whether a name is a private Go name.
|
||||
func IsPrivateGoName(name string) bool {
|
||||
return len(name) == 0 || strings.ToLower(name[:1]) == name[:1]
|
||||
}
|
||||
|
||||
// NewPublicNamer is a helper function that returns a namer that makes
|
||||
// CamelCase names. See the NameStrategy struct for an explanation of the
|
||||
// arguments to this constructor.
|
||||
func NewPublicNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy {
|
||||
n := &NameStrategy{
|
||||
Join: Joiner(IC, IC),
|
||||
IgnoreWords: map[string]bool{},
|
||||
PrependPackageNames: prependPackageNames,
|
||||
}
|
||||
for _, w := range ignoreWords {
|
||||
n.IgnoreWords[w] = true
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// NewPrivateNamer is a helper function that returns a namer that makes
|
||||
// camelCase names. See the NameStrategy struct for an explanation of the
|
||||
// arguments to this constructor.
|
||||
func NewPrivateNamer(prependPackageNames int, ignoreWords ...string) *NameStrategy {
|
||||
n := &NameStrategy{
|
||||
Join: Joiner(IL, IC),
|
||||
IgnoreWords: map[string]bool{},
|
||||
PrependPackageNames: prependPackageNames,
|
||||
}
|
||||
for _, w := range ignoreWords {
|
||||
n.IgnoreWords[w] = true
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// NewRawNamer will return a Namer that makes a name by which you would
|
||||
// directly refer to a type, optionally keeping track of the import paths
|
||||
// necessary to reference the names it provides. Tracker may be nil.
|
||||
// The 'pkg' is the full package name, in which the Namer is used - all
|
||||
// types from that package will be referenced by just type name without
|
||||
// referencing the package.
|
||||
//
|
||||
// For example, if the type is map[string]int, a raw namer will literally
|
||||
// return "map[string]int".
|
||||
//
|
||||
// Or if the type, in package foo, is "type Bar struct { ... }", then the raw
|
||||
// namer will return "foo.Bar" as the name of the type, and if 'tracker' was
|
||||
// not nil, will record that package foo needs to be imported.
|
||||
func NewRawNamer(pkg string, tracker ImportTracker) *rawNamer {
|
||||
return &rawNamer{pkg: pkg, tracker: tracker}
|
||||
}
|
||||
|
||||
// Names is a map from Type to name, as defined by some Namer.
|
||||
type Names map[*types.Type]string
|
||||
|
||||
// Namer takes a type, and assigns a name.
|
||||
//
|
||||
// The purpose of this complexity is so that you can assign coherent
|
||||
// side-by-side systems of names for the types. For example, you might want a
|
||||
// public interface, a private implementation struct, and also to reference
|
||||
// literally the type name.
|
||||
//
|
||||
// Note that it is safe to call your own Name() function recursively to find
|
||||
// the names of keys, elements, etc. This is because anonymous types can't have
|
||||
// cycles in their names, and named types don't require the sort of recursion
|
||||
// that would be problematic.
|
||||
type Namer interface {
|
||||
Name(*types.Type) string
|
||||
}
|
||||
|
||||
// NameSystems is a map of a system name to a namer for that system.
|
||||
type NameSystems map[string]Namer
|
||||
|
||||
// NameStrategy is a general Namer. The easiest way to use it is to copy the
|
||||
// Public/PrivateNamer variables, and modify the members you wish to change.
|
||||
//
|
||||
// The Name method produces a name for the given type, of the forms:
|
||||
// Anonymous types: <Prefix><Type description><Suffix>
|
||||
// Named types: <Prefix><Optional Prepended Package name(s)><Original name><Suffix>
|
||||
//
|
||||
// In all cases, every part of the name is run through the capitalization
|
||||
// functions.
|
||||
//
|
||||
// The IgnoreWords map can be set if you have directory names that are
|
||||
// semantically meaningless for naming purposes, e.g. "proto".
|
||||
//
|
||||
// Prefix and Suffix can be used to disambiguate parallel systems of type
|
||||
// names. For example, if you want to generate an interface and an
|
||||
// implementation, you might want to suffix one with "Interface" and the other
|
||||
// with "Implementation". Another common use-- if you want to generate private
|
||||
// types, and one of your source types could be "string", you can't use the
|
||||
// default lowercase private namer. You'll have to add a suffix or prefix.
|
||||
type NameStrategy struct {
|
||||
Prefix, Suffix string
|
||||
Join func(pre string, parts []string, post string) string
|
||||
|
||||
// Add non-meaningful package directory names here (e.g. "proto") and
|
||||
// they will be ignored.
|
||||
IgnoreWords map[string]bool
|
||||
|
||||
// If > 0, prepend exactly that many package directory names (or as
|
||||
// many as there are). Package names listed in "IgnoreWords" will be
|
||||
// ignored.
|
||||
//
|
||||
// For example, if Ignore words lists "proto" and type Foo is in
|
||||
// pkg/server/frobbing/proto, then a value of 1 will give a type name
|
||||
// of FrobbingFoo, 2 gives ServerFrobbingFoo, etc.
|
||||
PrependPackageNames int
|
||||
|
||||
// A cache of names thus far assigned by this namer.
|
||||
Names
|
||||
}
|
||||
|
||||
// IC ensures the first character is uppercase.
|
||||
func IC(in string) string {
|
||||
if in == "" {
|
||||
return in
|
||||
}
|
||||
return strings.ToUpper(in[:1]) + in[1:]
|
||||
}
|
||||
|
||||
// IL ensures the first character is lowercase.
|
||||
func IL(in string) string {
|
||||
if in == "" {
|
||||
return in
|
||||
}
|
||||
return strings.ToLower(in[:1]) + in[1:]
|
||||
}
|
||||
|
||||
// Joiner lets you specify functions that preprocess the various components of
|
||||
// a name before joining them. You can construct e.g. camelCase or CamelCase or
|
||||
// any other way of joining words. (See the IC and IL convenience functions.)
|
||||
func Joiner(first, others func(string) string) func(pre string, in []string, post string) string {
|
||||
return func(pre string, in []string, post string) string {
|
||||
tmp := []string{others(pre)}
|
||||
for i := range in {
|
||||
tmp = append(tmp, others(in[i]))
|
||||
}
|
||||
tmp = append(tmp, others(post))
|
||||
return first(strings.Join(tmp, ""))
|
||||
}
|
||||
}
|
||||
|
||||
func (ns *NameStrategy) removePrefixAndSuffix(s string) string {
|
||||
// The join function may have changed capitalization.
|
||||
lowerIn := strings.ToLower(s)
|
||||
lowerP := strings.ToLower(ns.Prefix)
|
||||
lowerS := strings.ToLower(ns.Suffix)
|
||||
b, e := 0, len(s)
|
||||
if strings.HasPrefix(lowerIn, lowerP) {
|
||||
b = len(ns.Prefix)
|
||||
}
|
||||
if strings.HasSuffix(lowerIn, lowerS) {
|
||||
e -= len(ns.Suffix)
|
||||
}
|
||||
return s[b:e]
|
||||
}
|
||||
|
||||
var (
|
||||
importPathNameSanitizer = strings.NewReplacer("-", "_", ".", "")
|
||||
)
|
||||
|
||||
// filters out unwanted directory names and sanitizes remaining names.
|
||||
func (ns *NameStrategy) filterDirs(path string) []string {
|
||||
allDirs := strings.Split(path, GoSeperator)
|
||||
dirs := make([]string, 0, len(allDirs))
|
||||
for _, p := range allDirs {
|
||||
if ns.IgnoreWords == nil || !ns.IgnoreWords[p] {
|
||||
dirs = append(dirs, importPathNameSanitizer.Replace(p))
|
||||
}
|
||||
}
|
||||
return dirs
|
||||
}
|
||||
|
||||
// See the comment on NameStrategy.
|
||||
func (ns *NameStrategy) Name(t *types.Type) string {
|
||||
if ns.Names == nil {
|
||||
ns.Names = Names{}
|
||||
}
|
||||
if s, ok := ns.Names[t]; ok {
|
||||
return s
|
||||
}
|
||||
|
||||
if t.Name.Package != "" {
|
||||
dirs := append(ns.filterDirs(t.Name.Package), t.Name.Name)
|
||||
i := ns.PrependPackageNames + 1
|
||||
dn := len(dirs)
|
||||
if i > dn {
|
||||
i = dn
|
||||
}
|
||||
name := ns.Join(ns.Prefix, dirs[dn-i:], ns.Suffix)
|
||||
ns.Names[t] = name
|
||||
return name
|
||||
}
|
||||
|
||||
// Only anonymous types remain.
|
||||
var name string
|
||||
switch t.Kind {
|
||||
case types.Builtin:
|
||||
name = ns.Join(ns.Prefix, []string{t.Name.Name}, ns.Suffix)
|
||||
case types.Map:
|
||||
name = ns.Join(ns.Prefix, []string{
|
||||
"Map",
|
||||
ns.removePrefixAndSuffix(ns.Name(t.Key)),
|
||||
"To",
|
||||
ns.removePrefixAndSuffix(ns.Name(t.Elem)),
|
||||
}, ns.Suffix)
|
||||
case types.Slice:
|
||||
name = ns.Join(ns.Prefix, []string{
|
||||
"Slice",
|
||||
ns.removePrefixAndSuffix(ns.Name(t.Elem)),
|
||||
}, ns.Suffix)
|
||||
case types.Pointer:
|
||||
name = ns.Join(ns.Prefix, []string{
|
||||
"Pointer",
|
||||
ns.removePrefixAndSuffix(ns.Name(t.Elem)),
|
||||
}, ns.Suffix)
|
||||
case types.Struct:
|
||||
names := []string{"Struct"}
|
||||
for _, m := range t.Members {
|
||||
names = append(names, ns.removePrefixAndSuffix(ns.Name(m.Type)))
|
||||
}
|
||||
name = ns.Join(ns.Prefix, names, ns.Suffix)
|
||||
case types.Chan:
|
||||
name = ns.Join(ns.Prefix, []string{
|
||||
"Chan",
|
||||
ns.removePrefixAndSuffix(ns.Name(t.Elem)),
|
||||
}, ns.Suffix)
|
||||
case types.Interface:
|
||||
// TODO: add to name test
|
||||
names := []string{"Interface"}
|
||||
for _, m := range t.Methods {
|
||||
// TODO: include function signature
|
||||
names = append(names, m.Name.Name)
|
||||
}
|
||||
name = ns.Join(ns.Prefix, names, ns.Suffix)
|
||||
case types.Func:
|
||||
// TODO: add to name test
|
||||
parts := []string{"Func"}
|
||||
for _, pt := range t.Signature.Parameters {
|
||||
parts = append(parts, ns.removePrefixAndSuffix(ns.Name(pt)))
|
||||
}
|
||||
parts = append(parts, "Returns")
|
||||
for _, rt := range t.Signature.Results {
|
||||
parts = append(parts, ns.removePrefixAndSuffix(ns.Name(rt)))
|
||||
}
|
||||
name = ns.Join(ns.Prefix, parts, ns.Suffix)
|
||||
default:
|
||||
name = "unnameable_" + string(t.Kind)
|
||||
}
|
||||
ns.Names[t] = name
|
||||
return name
|
||||
}
|
||||
|
||||
// ImportTracker allows a raw namer to keep track of the packages needed for
|
||||
// import. You can implement yourself or use the one in the generation package.
|
||||
type ImportTracker interface {
|
||||
AddType(*types.Type)
|
||||
LocalNameOf(packagePath string) string
|
||||
PathOf(localName string) (string, bool)
|
||||
ImportLines() []string
|
||||
}
|
||||
|
||||
type rawNamer struct {
|
||||
pkg string
|
||||
tracker ImportTracker
|
||||
Names
|
||||
}
|
||||
|
||||
// Name makes a name the way you'd write it to literally refer to type t,
|
||||
// making ordinary assumptions about how you've imported t's package (or using
|
||||
// r.tracker to specifically track the package imports).
|
||||
func (r *rawNamer) Name(t *types.Type) string {
|
||||
if r.Names == nil {
|
||||
r.Names = Names{}
|
||||
}
|
||||
if name, ok := r.Names[t]; ok {
|
||||
return name
|
||||
}
|
||||
if t.Name.Package != "" {
|
||||
var name string
|
||||
if r.tracker != nil {
|
||||
r.tracker.AddType(t)
|
||||
if t.Name.Package == r.pkg {
|
||||
name = t.Name.Name
|
||||
} else {
|
||||
name = r.tracker.LocalNameOf(t.Name.Package) + "." + t.Name.Name
|
||||
}
|
||||
} else {
|
||||
if t.Name.Package == r.pkg {
|
||||
name = t.Name.Name
|
||||
} else {
|
||||
name = filepath.Base(t.Name.Package) + "." + t.Name.Name
|
||||
}
|
||||
}
|
||||
r.Names[t] = name
|
||||
return name
|
||||
}
|
||||
var name string
|
||||
switch t.Kind {
|
||||
case types.Builtin:
|
||||
name = t.Name.Name
|
||||
case types.Map:
|
||||
name = "map[" + r.Name(t.Key) + "]" + r.Name(t.Elem)
|
||||
case types.Slice:
|
||||
name = "[]" + r.Name(t.Elem)
|
||||
case types.Pointer:
|
||||
name = "*" + r.Name(t.Elem)
|
||||
case types.Struct:
|
||||
elems := []string{}
|
||||
for _, m := range t.Members {
|
||||
elems = append(elems, m.Name+" "+r.Name(m.Type))
|
||||
}
|
||||
name = "struct{" + strings.Join(elems, "; ") + "}"
|
||||
case types.Chan:
|
||||
// TODO: include directionality
|
||||
name = "chan " + r.Name(t.Elem)
|
||||
case types.Interface:
|
||||
// TODO: add to name test
|
||||
elems := []string{}
|
||||
for _, m := range t.Methods {
|
||||
// TODO: include function signature
|
||||
elems = append(elems, m.Name.Name)
|
||||
}
|
||||
name = "interface{" + strings.Join(elems, "; ") + "}"
|
||||
case types.Func:
|
||||
// TODO: add to name test
|
||||
params := []string{}
|
||||
for _, pt := range t.Signature.Parameters {
|
||||
params = append(params, r.Name(pt))
|
||||
}
|
||||
results := []string{}
|
||||
for _, rt := range t.Signature.Results {
|
||||
results = append(results, r.Name(rt))
|
||||
}
|
||||
name = "func(" + strings.Join(params, ",") + ")"
|
||||
if len(results) == 1 {
|
||||
name += " " + results[0]
|
||||
} else if len(results) > 1 {
|
||||
name += " (" + strings.Join(results, ",") + ")"
|
||||
}
|
||||
default:
|
||||
name = "unnameable_" + string(t.Kind)
|
||||
}
|
||||
r.Names[t] = name
|
||||
return name
|
||||
}
|
69
vendor/k8s.io/gengo/namer/order.go
generated
vendored
Normal file
69
vendor/k8s.io/gengo/namer/order.go
generated
vendored
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namer
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
// Orderer produces an ordering of types given a Namer.
|
||||
type Orderer struct {
|
||||
Namer
|
||||
}
|
||||
|
||||
// OrderUniverse assigns a name to every type in the Universe, including Types,
|
||||
// Functions and Variables, and returns a list sorted by those names.
|
||||
func (o *Orderer) OrderUniverse(u types.Universe) []*types.Type {
|
||||
list := tList{
|
||||
namer: o.Namer,
|
||||
}
|
||||
for _, p := range u {
|
||||
for _, t := range p.Types {
|
||||
list.types = append(list.types, t)
|
||||
}
|
||||
for _, f := range p.Functions {
|
||||
list.types = append(list.types, f)
|
||||
}
|
||||
for _, v := range p.Variables {
|
||||
list.types = append(list.types, v)
|
||||
}
|
||||
}
|
||||
sort.Sort(list)
|
||||
return list.types
|
||||
}
|
||||
|
||||
// OrderTypes assigns a name to every type, and returns a list sorted by those
|
||||
// names.
|
||||
func (o *Orderer) OrderTypes(typeList []*types.Type) []*types.Type {
|
||||
list := tList{
|
||||
namer: o.Namer,
|
||||
types: typeList,
|
||||
}
|
||||
sort.Sort(list)
|
||||
return list.types
|
||||
}
|
||||
|
||||
type tList struct {
|
||||
namer Namer
|
||||
types []*types.Type
|
||||
}
|
||||
|
||||
func (t tList) Len() int { return len(t.types) }
|
||||
func (t tList) Less(i, j int) bool { return t.namer.Name(t.types[i]) < t.namer.Name(t.types[j]) }
|
||||
func (t tList) Swap(i, j int) { t.types[i], t.types[j] = t.types[j], t.types[i] }
|
120
vendor/k8s.io/gengo/namer/plural_namer.go
generated
vendored
Normal file
120
vendor/k8s.io/gengo/namer/plural_namer.go
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package namer
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/types"
|
||||
)
|
||||
|
||||
var consonants = "bcdfghjklmnpqrsttvwxyz"
|
||||
|
||||
type pluralNamer struct {
|
||||
// key is the case-sensitive type name, value is the case-insensitive
|
||||
// intended output.
|
||||
exceptions map[string]string
|
||||
finalize func(string) string
|
||||
}
|
||||
|
||||
// NewPublicPluralNamer returns a namer that returns the plural form of the input
|
||||
// type's name, starting with a uppercase letter.
|
||||
func NewPublicPluralNamer(exceptions map[string]string) *pluralNamer {
|
||||
return &pluralNamer{exceptions, IC}
|
||||
}
|
||||
|
||||
// NewPrivatePluralNamer returns a namer that returns the plural form of the input
|
||||
// type's name, starting with a lowercase letter.
|
||||
func NewPrivatePluralNamer(exceptions map[string]string) *pluralNamer {
|
||||
return &pluralNamer{exceptions, IL}
|
||||
}
|
||||
|
||||
// NewAllLowercasePluralNamer returns a namer that returns the plural form of the input
|
||||
// type's name, with all letters in lowercase.
|
||||
func NewAllLowercasePluralNamer(exceptions map[string]string) *pluralNamer {
|
||||
return &pluralNamer{exceptions, strings.ToLower}
|
||||
}
|
||||
|
||||
// Name returns the plural form of the type's name. If the type's name is found
|
||||
// in the exceptions map, the map value is returned.
|
||||
func (r *pluralNamer) Name(t *types.Type) string {
|
||||
singular := t.Name.Name
|
||||
var plural string
|
||||
var ok bool
|
||||
if plural, ok = r.exceptions[singular]; ok {
|
||||
return r.finalize(plural)
|
||||
}
|
||||
if len(singular) < 2 {
|
||||
return r.finalize(singular)
|
||||
}
|
||||
|
||||
switch rune(singular[len(singular)-1]) {
|
||||
case 's', 'x', 'z':
|
||||
plural = esPlural(singular)
|
||||
case 'y':
|
||||
sl := rune(singular[len(singular)-2])
|
||||
if isConsonant(sl) {
|
||||
plural = iesPlural(singular)
|
||||
} else {
|
||||
plural = sPlural(singular)
|
||||
}
|
||||
case 'h':
|
||||
sl := rune(singular[len(singular)-2])
|
||||
if sl == 'c' || sl == 's' {
|
||||
plural = esPlural(singular)
|
||||
} else {
|
||||
plural = sPlural(singular)
|
||||
}
|
||||
case 'e':
|
||||
sl := rune(singular[len(singular)-2])
|
||||
if sl == 'f' {
|
||||
plural = vesPlural(singular[:len(singular)-1])
|
||||
} else {
|
||||
plural = sPlural(singular)
|
||||
}
|
||||
case 'f':
|
||||
plural = vesPlural(singular)
|
||||
default:
|
||||
plural = sPlural(singular)
|
||||
}
|
||||
return r.finalize(plural)
|
||||
}
|
||||
|
||||
func iesPlural(singular string) string {
|
||||
return singular[:len(singular)-1] + "ies"
|
||||
}
|
||||
|
||||
func vesPlural(singular string) string {
|
||||
return singular[:len(singular)-1] + "ves"
|
||||
}
|
||||
|
||||
func esPlural(singular string) string {
|
||||
return singular + "es"
|
||||
}
|
||||
|
||||
func sPlural(singular string) string {
|
||||
return singular + "s"
|
||||
}
|
||||
|
||||
func isConsonant(char rune) bool {
|
||||
for _, c := range consonants {
|
||||
if char == c {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue