mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
split Package.Types to Types, Variables and Functions;
add DeclarationOf Kind.
This commit is contained in:
parent
611770778f
commit
0d7d4c04a2
@ -57,12 +57,12 @@ func (g *genGroup) GenerateType(c *generator.Context, t *types.Type, w io.Writer
|
|||||||
"group": g.group,
|
"group": g.group,
|
||||||
"Group": namer.IC(g.group),
|
"Group": namer.IC(g.group),
|
||||||
"types": g.types,
|
"types": g.types,
|
||||||
"Config": c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "Config"}),
|
"Config": c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "Config"}),
|
||||||
"DefaultKubernetesUserAgent": c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
|
"DefaultKubernetesUserAgent": c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "DefaultKubernetesUserAgent"}),
|
||||||
"RESTClient": c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
|
"RESTClient": c.Universe.Type(types.Name{Package: pkgUnversioned, Name: "RESTClient"}),
|
||||||
"RESTClientFor": c.Universe.Get(types.Name{Package: pkgUnversioned, Name: "RESTClientFor"}),
|
"RESTClientFor": c.Universe.Function(types.Name{Package: pkgUnversioned, Name: "RESTClientFor"}),
|
||||||
"latestGroup": c.Universe.Get(types.Name{Package: pkgLatest, Name: "Group"}),
|
"latestGroup": c.Universe.Variable(types.Name{Package: pkgLatest, Name: "Group"}),
|
||||||
"GroupOrDie": c.Universe.Get(types.Name{Package: pkgLatest, Name: "GroupOrDie"}),
|
"GroupOrDie": c.Universe.Variable(types.Name{Package: pkgLatest, Name: "GroupOrDie"}),
|
||||||
}
|
}
|
||||||
sw.Do(groupInterfaceTemplate, m)
|
sw.Do(groupInterfaceTemplate, m)
|
||||||
sw.Do(groupClientTemplate, m)
|
sw.Do(groupClientTemplate, m)
|
||||||
|
@ -54,9 +54,9 @@ func (g *genClientForType) GenerateType(c *generator.Context, t *types.Type, w i
|
|||||||
"type": t,
|
"type": t,
|
||||||
"package": pkg,
|
"package": pkg,
|
||||||
"Package": namer.IC(pkg),
|
"Package": namer.IC(pkg),
|
||||||
"watchInterface": c.Universe.Get(types.Name{Package: "k8s.io/kubernetes/pkg/watch", Name: "Interface"}),
|
"watchInterface": c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/watch", Name: "Interface"}),
|
||||||
"apiDeleteOptions": c.Universe.Get(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "DeleteOptions"}),
|
"apiDeleteOptions": c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api", Name: "DeleteOptions"}),
|
||||||
"unvListOptions": c.Universe.Get(types.Name{Package: "k8s.io/kubernetes/pkg/api/unversioned", Name: "ListOptions"}),
|
"unvListOptions": c.Universe.Type(types.Name{Package: "k8s.io/kubernetes/pkg/api/unversioned", Name: "ListOptions"}),
|
||||||
}
|
}
|
||||||
sw.Do(namespacerTemplate, m)
|
sw.Do(namespacerTemplate, m)
|
||||||
sw.Do(interfaceTemplate, m)
|
sw.Do(interfaceTemplate, m)
|
||||||
|
@ -27,26 +27,26 @@ func TestNameStrategy(t *testing.T) {
|
|||||||
u := types.Universe{}
|
u := types.Universe{}
|
||||||
|
|
||||||
// Add some types.
|
// Add some types.
|
||||||
base := u.Get(types.Name{Package: "foo/bar", Name: "Baz"})
|
base := u.Type(types.Name{Package: "foo/bar", Name: "Baz"})
|
||||||
base.Kind = types.Struct
|
base.Kind = types.Struct
|
||||||
|
|
||||||
tmp := u.Get(types.Name{Package: "", Name: "[]bar.Baz"})
|
tmp := u.Type(types.Name{Package: "", Name: "[]bar.Baz"})
|
||||||
tmp.Kind = types.Slice
|
tmp.Kind = types.Slice
|
||||||
tmp.Elem = base
|
tmp.Elem = base
|
||||||
|
|
||||||
tmp = u.Get(types.Name{Package: "", Name: "map[string]bar.Baz"})
|
tmp = u.Type(types.Name{Package: "", Name: "map[string]bar.Baz"})
|
||||||
tmp.Kind = types.Map
|
tmp.Kind = types.Map
|
||||||
tmp.Key = types.String
|
tmp.Key = types.String
|
||||||
tmp.Elem = base
|
tmp.Elem = base
|
||||||
|
|
||||||
tmp = u.Get(types.Name{Package: "foo/other", Name: "Baz"})
|
tmp = u.Type(types.Name{Package: "foo/other", Name: "Baz"})
|
||||||
tmp.Kind = types.Struct
|
tmp.Kind = types.Struct
|
||||||
tmp.Members = []types.Member{{
|
tmp.Members = []types.Member{{
|
||||||
Embedded: true,
|
Embedded: true,
|
||||||
Type: base,
|
Type: base,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
u.Get(types.Name{Package: "", Name: "string"})
|
u.Type(types.Name{Package: "", Name: "string"})
|
||||||
|
|
||||||
o := Orderer{NewPublicNamer(0)}
|
o := Orderer{NewPublicNamer(0)}
|
||||||
order := o.Order(u)
|
order := o.Order(u)
|
||||||
|
@ -37,6 +37,12 @@ func (o *Orderer) Order(u types.Universe) []*types.Type {
|
|||||||
for _, t := range p.Types {
|
for _, t := range p.Types {
|
||||||
list.types = append(list.types, t)
|
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)
|
sort.Sort(list)
|
||||||
return list.types
|
return list.types
|
||||||
|
@ -303,8 +303,13 @@ func (b *Builder) FindTypes() (types.Universe, error) {
|
|||||||
t.CommentLines = b.priorCommentLines(obj.Pos())
|
t.CommentLines = b.priorCommentLines(obj.Pos())
|
||||||
}
|
}
|
||||||
tf, ok := obj.(*tc.Func)
|
tf, ok := obj.(*tc.Func)
|
||||||
if ok {
|
// We only care about functions, not concrete/abstract methods.
|
||||||
b.addFunc(u, nil, tf)
|
if ok && tf.Type() != nil && tf.Type().(*tc.Signature).Recv() == nil {
|
||||||
|
b.addFunction(u, nil, tf)
|
||||||
|
}
|
||||||
|
tv, ok := obj.(*tc.Var)
|
||||||
|
if ok && !tv.IsField() {
|
||||||
|
b.addVariable(u, nil, tv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for p := range b.importGraph[pkgName] {
|
for p := range b.importGraph[pkgName] {
|
||||||
@ -330,6 +335,13 @@ func tcFuncNameToName(in string) types.Name {
|
|||||||
return tcNameToName(nameParts[0])
|
return tcNameToName(nameParts[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tcVarNameToName(in string) types.Name {
|
||||||
|
nameParts := strings.Split(in, " ")
|
||||||
|
// nameParts[0] is "var".
|
||||||
|
// nameParts[2:] is the type of the variable, we ignore it for now.
|
||||||
|
return tcNameToName(nameParts[1])
|
||||||
|
}
|
||||||
|
|
||||||
func tcNameToName(in string) types.Name {
|
func tcNameToName(in string) types.Name {
|
||||||
// Detect anonymous type names. (These may have '.' characters because
|
// Detect anonymous type names. (These may have '.' characters because
|
||||||
// embedded types may have packages, so we detect them specially.)
|
// embedded types may have packages, so we detect them specially.)
|
||||||
@ -377,7 +389,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
|
|
||||||
switch t := in.(type) {
|
switch t := in.(type) {
|
||||||
case *tc.Struct:
|
case *tc.Struct:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -395,7 +407,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
case *tc.Map:
|
case *tc.Map:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -404,7 +416,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
out.Key = b.walkType(u, nil, t.Key())
|
out.Key = b.walkType(u, nil, t.Key())
|
||||||
return out
|
return out
|
||||||
case *tc.Pointer:
|
case *tc.Pointer:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -412,7 +424,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
out.Elem = b.walkType(u, nil, t.Elem())
|
out.Elem = b.walkType(u, nil, t.Elem())
|
||||||
return out
|
return out
|
||||||
case *tc.Slice:
|
case *tc.Slice:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -420,7 +432,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
out.Elem = b.walkType(u, nil, t.Elem())
|
out.Elem = b.walkType(u, nil, t.Elem())
|
||||||
return out
|
return out
|
||||||
case *tc.Array:
|
case *tc.Array:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -430,7 +442,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
// cannot be properly written.
|
// cannot be properly written.
|
||||||
return out
|
return out
|
||||||
case *tc.Chan:
|
case *tc.Chan:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -440,7 +452,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
// cannot be properly written.
|
// cannot be properly written.
|
||||||
return out
|
return out
|
||||||
case *tc.Basic:
|
case *tc.Basic:
|
||||||
out := u.Get(types.Name{
|
out := u.Type(types.Name{
|
||||||
Package: "",
|
Package: "",
|
||||||
Name: t.Name(),
|
Name: t.Name(),
|
||||||
})
|
})
|
||||||
@ -450,7 +462,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
out.Kind = types.Unsupported
|
out.Kind = types.Unsupported
|
||||||
return out
|
return out
|
||||||
case *tc.Signature:
|
case *tc.Signature:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -458,7 +470,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
out.Signature = b.convertSignature(u, t)
|
out.Signature = b.convertSignature(u, t)
|
||||||
return out
|
return out
|
||||||
case *tc.Interface:
|
case *tc.Interface:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -472,7 +484,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
switch t.Underlying().(type) {
|
switch t.Underlying().(type) {
|
||||||
case *tc.Named, *tc.Basic:
|
case *tc.Named, *tc.Basic:
|
||||||
name := tcNameToName(t.String())
|
name := tcNameToName(t.String())
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -485,7 +497,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
// "feature" for users. This flattens those types
|
// "feature" for users. This flattens those types
|
||||||
// together.
|
// together.
|
||||||
name := tcNameToName(t.String())
|
name := tcNameToName(t.String())
|
||||||
if out := u.Get(name); out.Kind != types.Unknown {
|
if out := u.Type(name); out.Kind != types.Unknown {
|
||||||
return out // short circuit if we've already made this.
|
return out // short circuit if we've already made this.
|
||||||
}
|
}
|
||||||
out := b.walkType(u, &name, t.Underlying())
|
out := b.walkType(u, &name, t.Underlying())
|
||||||
@ -500,7 +512,7 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
out := u.Get(name)
|
out := u.Type(name)
|
||||||
if out.Kind != types.Unknown {
|
if out.Kind != types.Unknown {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
@ -510,13 +522,24 @@ func (b *Builder) walkType(u types.Universe, useName *types.Name, in tc.Type) *t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) addFunc(u types.Universe, useName *types.Name, in *tc.Func) *types.Type {
|
func (b *Builder) addFunction(u types.Universe, useName *types.Name, in *tc.Func) *types.Type {
|
||||||
name := tcFuncNameToName(in.String())
|
name := tcFuncNameToName(in.String())
|
||||||
if useName != nil {
|
if useName != nil {
|
||||||
name = *useName
|
name = *useName
|
||||||
}
|
}
|
||||||
out := u.Get(name)
|
out := u.Function(name)
|
||||||
out.Kind = types.Func
|
out.Kind = types.DeclarationOf
|
||||||
out.Signature = b.convertSignature(u, in.Type().(*tc.Signature))
|
out.Underlying = b.walkType(u, nil, in.Type())
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Builder) addVariable(u types.Universe, useName *types.Name, in *tc.Var) *types.Type {
|
||||||
|
name := tcVarNameToName(in.String())
|
||||||
|
if useName != nil {
|
||||||
|
name = *useName
|
||||||
|
}
|
||||||
|
out := u.Variable(name)
|
||||||
|
out.Kind = types.DeclarationOf
|
||||||
|
out.Underlying = b.walkType(u, nil, in.Type())
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,11 @@ type Object struct {
|
|||||||
func AFunc(obj1 common.Object, obj2 Object) Frobber {
|
func AFunc(obj1 common.Object, obj2 Object) Frobber {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var AVar Frobber
|
||||||
|
|
||||||
|
var (
|
||||||
|
AnotherVar = Frobber{}
|
||||||
|
)
|
||||||
`,
|
`,
|
||||||
"base/common/proto/common.go": `
|
"base/common/proto/common.go": `
|
||||||
package common
|
package common
|
||||||
@ -91,16 +96,21 @@ package o
|
|||||||
}
|
}
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
{{define "Func"}}{{$s := .Signature}}func {{Raw .}}( {{range $s.Parameters}}{{Raw .}} {{end}}) {{range $s.Results}}{{Raw .}} {{end}}{}
|
{{define "Func"}}{{$s := .Underlying.Signature}}var {{Name .}} func({{range $index,$elem := $s.Parameters}}{{if $index}}, {{end}}{{Raw $elem}}{{end}}) {{if $s.Results|len |gt 1}}({{end}}{{range $index,$elem := $s.Results}}{{if $index}}, {{end}}{{Raw .}}{{end}}{{if $s.Results|len |gt 1}}){{end}} = {{Raw .}}
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
{{define "Var"}}{{$t := .Underlying}}var {{Name .}} {{Raw $t}} = {{Raw .}}
|
||||||
|
|
||||||
{{end}}
|
{{end}}
|
||||||
{{range $t := .}}{{if eq $t.Kind "Struct"}}{{template "Struct" $t}}{{end}}{{end}}
|
{{range $t := .}}{{if eq $t.Kind "Struct"}}{{template "Struct" $t}}{{end}}{{end}}
|
||||||
{{range $t := .}}{{if eq $t.Kind "Func"}}{{template "Func" $t}}{{end}}{{end}}`
|
{{range $t := .}}{{if eq $t.Kind "DeclarationOf"}}{{if eq $t.Underlying.Kind "Func"}}{{template "Func" $t}}{{end}}{{end}}{{end}}
|
||||||
|
{{range $t := .}}{{if eq $t.Kind "DeclarationOf"}}{{if ne $t.Underlying.Kind "Func"}}{{template "Var" $t}}{{end}}{{end}}{{end}}`
|
||||||
|
|
||||||
var expect = `
|
var expect = `
|
||||||
package o
|
package o
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type CommonObject interface {
|
type CommonObject interface {
|
||||||
ID() Int64
|
ID() Int64
|
||||||
SetID(Int64)
|
SetID(Int64)
|
||||||
@ -128,7 +138,12 @@ type FooObject interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func proto.AFunc( proto.Object proto.Object ) proto.Frobber {}
|
var FooAFunc func(proto.Object, proto.Object) proto.Frobber = proto.AFunc
|
||||||
|
|
||||||
|
|
||||||
|
var FooAVar proto.Frobber = proto.AVar
|
||||||
|
|
||||||
|
var FooAnotherVar proto.Frobber = proto.AnotherVar
|
||||||
|
|
||||||
`
|
`
|
||||||
testNamer := namer.NewPublicNamer(1, "proto")
|
testNamer := namer.NewPublicNamer(1, "proto")
|
||||||
@ -149,7 +164,6 @@ func proto.AFunc( proto.Object proto.Object ) proto.Frobber {}
|
|||||||
if e, a := expect, buf.String(); e != a {
|
if e, a := expect, buf.String(); e != a {
|
||||||
t.Errorf("Wanted, got:\n%v\n-----\n%v\n", e, a)
|
t.Errorf("Wanted, got:\n%v\n-----\n%v\n", e, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if p := u.Package("base/foo/proto"); !p.HasImport("base/common/proto") {
|
if p := u.Package("base/foo/proto"); !p.HasImport("base/common/proto") {
|
||||||
t.Errorf("Unexpected lack of import line: %#s", p.Imports)
|
t.Errorf("Unexpected lack of import line: %#s", p.Imports)
|
||||||
}
|
}
|
||||||
@ -175,7 +189,7 @@ type Blah struct {
|
|||||||
|
|
||||||
_, u, o := construct(t, structTest, namer.NewPublicNamer(0))
|
_, u, o := construct(t, structTest, namer.NewPublicNamer(0))
|
||||||
t.Logf("%#v", o)
|
t.Logf("%#v", o)
|
||||||
blahT := u.Get(types.Name{Package: "base/foo/proto", Name: "Blah"})
|
blahT := u.Type(types.Name{Package: "base/foo/proto", Name: "Blah"})
|
||||||
if blahT == nil {
|
if blahT == nil {
|
||||||
t.Fatal("type not found")
|
t.Fatal("type not found")
|
||||||
}
|
}
|
||||||
@ -330,7 +344,7 @@ type Interface interface{Method(a, b string) (c, d string)}
|
|||||||
|
|
||||||
for _, item := range assertions {
|
for _, item := range assertions {
|
||||||
n := types.Name{Package: item.Package, Name: item.Name}
|
n := types.Name{Package: item.Package, Name: item.Name}
|
||||||
thisType := u.Get(n)
|
thisType := u.Type(n)
|
||||||
if thisType == nil {
|
if thisType == nil {
|
||||||
t.Errorf("type %s not found", n)
|
t.Errorf("type %s not found", n)
|
||||||
continue
|
continue
|
||||||
@ -344,11 +358,11 @@ type Interface interface{Method(a, b string) (c, d string)}
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Also do some one-off checks
|
// Also do some one-off checks
|
||||||
gtest := u.Get(types.Name{Package: "g", Name: "Test"})
|
gtest := u.Type(types.Name{Package: "g", Name: "Test"})
|
||||||
if e, a := 1, len(gtest.Methods); e != a {
|
if e, a := 1, len(gtest.Methods); e != a {
|
||||||
t.Errorf("expected %v but found %v methods: %#v", e, a, gtest)
|
t.Errorf("expected %v but found %v methods: %#v", e, a, gtest)
|
||||||
}
|
}
|
||||||
iface := u.Get(types.Name{Package: "g", Name: "Interface"})
|
iface := u.Type(types.Name{Package: "g", Name: "Interface"})
|
||||||
if e, a := 1, len(iface.Methods); e != a {
|
if e, a := 1, len(iface.Methods); e != a {
|
||||||
t.Errorf("expected %v but found %v methods: %#v", e, a, iface)
|
t.Errorf("expected %v but found %v methods: %#v", e, a, iface)
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,17 @@ const (
|
|||||||
|
|
||||||
// The remaining types are included for completeness, but are not well
|
// The remaining types are included for completeness, but are not well
|
||||||
// supported.
|
// supported.
|
||||||
Array Kind = "Array" // Array is just like slice, but has a fixed length.
|
Array Kind = "Array" // Array is just like slice, but has a fixed length.
|
||||||
Chan Kind = "Chan"
|
Chan Kind = "Chan"
|
||||||
Func Kind = "Func"
|
Func Kind = "Func"
|
||||||
Unknown Kind = ""
|
|
||||||
Unsupported Kind = "Unsupported"
|
// DeclarationOf is different from other Kinds; it indicates that instead of
|
||||||
|
// representing an actual Type, the type is a declaration of an instance of
|
||||||
|
// a type. E.g., a top-level function, variable, or constant. See the
|
||||||
|
// comment for Type.Name for more detail.
|
||||||
|
DeclarationOf Kind = "DeclarationOf"
|
||||||
|
Unknown Kind = ""
|
||||||
|
Unsupported Kind = "Unsupported"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Package holds package-level information.
|
// Package holds package-level information.
|
||||||
@ -84,6 +90,14 @@ type Package struct {
|
|||||||
// package name).
|
// package name).
|
||||||
Types map[string]*Type
|
Types map[string]*Type
|
||||||
|
|
||||||
|
// Functions within this package, indexed by their name (*not* including
|
||||||
|
// package name).
|
||||||
|
Functions map[string]*Type
|
||||||
|
|
||||||
|
// Global variables within this package, indexed by their name (*not* including
|
||||||
|
// package name).
|
||||||
|
Variables map[string]*Type
|
||||||
|
|
||||||
// Packages imported by this package, indexed by (canonicalized)
|
// Packages imported by this package, indexed by (canonicalized)
|
||||||
// package path.
|
// package path.
|
||||||
Imports map[string]*Package
|
Imports map[string]*Package
|
||||||
@ -96,7 +110,7 @@ func (p *Package) Has(name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get (or add) the given type
|
// Get (or add) the given type
|
||||||
func (p *Package) Get(typeName string) *Type {
|
func (p *Package) Type(typeName string) *Type {
|
||||||
if t, ok := p.Types[typeName]; ok {
|
if t, ok := p.Types[typeName]; ok {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
@ -112,6 +126,32 @@ func (p *Package) Get(typeName string) *Type {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get (or add) the given function. If a function is added, it's the caller's
|
||||||
|
// responsibility to finish construction of the function by setting Underlying
|
||||||
|
// to the correct type.
|
||||||
|
func (p *Package) Function(funcName string) *Type {
|
||||||
|
if t, ok := p.Functions[funcName]; ok {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
t := &Type{Name: Name{Package: p.Path, Name: funcName}}
|
||||||
|
t.Kind = DeclarationOf
|
||||||
|
p.Functions[funcName] = t
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get (or add) the given varaible. If a variable is added, it's the caller's
|
||||||
|
// responsibility to finish construction of the variable by setting Underlying
|
||||||
|
// to the correct type.
|
||||||
|
func (p *Package) Variable(varName string) *Type {
|
||||||
|
if t, ok := p.Variables[varName]; ok {
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
t := &Type{Name: Name{Package: p.Path, Name: varName}}
|
||||||
|
t.Kind = DeclarationOf
|
||||||
|
p.Variables[varName] = t
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
// HasImport returns true if p imports packageName. Package names include the
|
// HasImport returns true if p imports packageName. Package names include the
|
||||||
// package directory.
|
// package directory.
|
||||||
func (p *Package) HasImport(packageName string) bool {
|
func (p *Package) HasImport(packageName string) bool {
|
||||||
@ -127,8 +167,24 @@ type Universe map[string]*Package
|
|||||||
// types will always be found, even if they haven't been explicitly added to
|
// types will always be found, even if they haven't been explicitly added to
|
||||||
// the map. If a non-existing type is requested, u will create (a marker for)
|
// the map. If a non-existing type is requested, u will create (a marker for)
|
||||||
// it.
|
// it.
|
||||||
func (u Universe) Get(n Name) *Type {
|
func (u Universe) Type(n Name) *Type {
|
||||||
return u.Package(n.Package).Get(n.Name)
|
return u.Package(n.Package).Type(n.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function returns the canonical function for the given fully-qualified name.
|
||||||
|
// If a non-existing function is requested, u will create (a marker for) it.
|
||||||
|
// If a marker is created, it's the caller's responsibility to finish
|
||||||
|
// construction of the function by setting Underlying to the correct type.
|
||||||
|
func (u Universe) Function(n Name) *Type {
|
||||||
|
return u.Package(n.Package).Function(n.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Variable returns the canonical variable for the given fully-qualified name.
|
||||||
|
// If a non-existing variable is requested, u will create (a marker for) it.
|
||||||
|
// If a marker is created, it's the caller's responsibility to finish
|
||||||
|
// construction of the variable by setting Underlying to the correct type.
|
||||||
|
func (u Universe) Variable(n Name) *Type {
|
||||||
|
return u.Package(n.Package).Variable(n.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddImports registers import lines for packageName. May be called multiple times.
|
// AddImports registers import lines for packageName. May be called multiple times.
|
||||||
@ -146,9 +202,11 @@ func (u Universe) Package(packagePath string) *Package {
|
|||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
p := &Package{
|
p := &Package{
|
||||||
Path: packagePath,
|
Path: packagePath,
|
||||||
Types: map[string]*Type{},
|
Types: map[string]*Type{},
|
||||||
Imports: map[string]*Package{},
|
Functions: map[string]*Type{},
|
||||||
|
Variables: map[string]*Type{},
|
||||||
|
Imports: map[string]*Package{},
|
||||||
}
|
}
|
||||||
u[packagePath] = p
|
u[packagePath] = p
|
||||||
return p
|
return p
|
||||||
@ -159,6 +217,11 @@ type Type struct {
|
|||||||
// There are two general categories of types, those explicitly named
|
// There are two general categories of types, those explicitly named
|
||||||
// and those anonymous. Named ones will have a non-empty package in the
|
// and those anonymous. Named ones will have a non-empty package in the
|
||||||
// name field.
|
// name field.
|
||||||
|
//
|
||||||
|
// An exception: If Kind == DeclarationOf, then this name is the name of a
|
||||||
|
// top-level function, variable, or const, and the type can be found in Underlying.
|
||||||
|
// We do this to allow the naming system to work against these objects, even
|
||||||
|
// though they aren't strictly speaking types.
|
||||||
Name Name
|
Name Name
|
||||||
|
|
||||||
// The general kind of this type.
|
// The general kind of this type.
|
||||||
@ -178,6 +241,7 @@ type Type struct {
|
|||||||
Key *Type
|
Key *Type
|
||||||
|
|
||||||
// If Kind == Alias, this is the underlying type.
|
// If Kind == Alias, this is the underlying type.
|
||||||
|
// If Kind == DeclarationOf, this is the type of the declaration.
|
||||||
Underlying *Type
|
Underlying *Type
|
||||||
|
|
||||||
// If Kind == Interface, this is the list of all required functions.
|
// If Kind == Interface, this is the list of all required functions.
|
||||||
|
@ -25,7 +25,7 @@ func TestGetBuiltin(t *testing.T) {
|
|||||||
if builtinPkg := u.Package(""); builtinPkg.Has("string") {
|
if builtinPkg := u.Package(""); builtinPkg.Has("string") {
|
||||||
t.Errorf("Expected builtin package to not have builtins until they're asked for explicitly. %#v", builtinPkg)
|
t.Errorf("Expected builtin package to not have builtins until they're asked for explicitly. %#v", builtinPkg)
|
||||||
}
|
}
|
||||||
s := u.Get(Name{Package: "", Name: "string"})
|
s := u.Type(Name{Package: "", Name: "string"})
|
||||||
if s != String {
|
if s != String {
|
||||||
t.Errorf("Expected canonical string type.")
|
t.Errorf("Expected canonical string type.")
|
||||||
}
|
}
|
||||||
@ -40,7 +40,7 @@ func TestGetBuiltin(t *testing.T) {
|
|||||||
func TestGetMarker(t *testing.T) {
|
func TestGetMarker(t *testing.T) {
|
||||||
u := Universe{}
|
u := Universe{}
|
||||||
n := Name{Package: "path/to/package", Name: "Foo"}
|
n := Name{Package: "path/to/package", Name: "Foo"}
|
||||||
f := u.Get(n)
|
f := u.Type(n)
|
||||||
if f == nil || f.Name != n {
|
if f == nil || f.Name != n {
|
||||||
t.Errorf("Expected marker type.")
|
t.Errorf("Expected marker type.")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user