object.go raw
1 package typecheck
2
3 import "fmt"
4
5 // Object is a named entity declared in the source: Var, Func, TypeName,
6 // Const, PkgName, Builtin, or Label.
7 type Object interface {
8 Name() string
9 Type() Type
10 Pkg() *Package
11 Exported() bool
12 objectTag() // type-tag to prevent accidental interface satisfaction
13 }
14
15 type object struct {
16 pkg *Package
17 name string
18 typ Type
19 }
20
21 func (o *object) Name() string { return o.name }
22 func (o *object) Type() Type { return o.typ }
23 func (o *object) Pkg() *Package { return o.pkg }
24 func (o *object) Exported() bool { return len(o.name) > 0 && o.name[0] >= 'A' && o.name[0] <= 'Z' }
25 func (o *object) objectTag() {}
26
27 // ----------------------------------------------------------------------------
28 // TypeName
29
30 type TypeName struct {
31 object
32 }
33
34 func NewTypeName(pkg *Package, name string, typ Type) *TypeName {
35 return &TypeName{object{pkg: pkg, name: name, typ: typ}}
36 }
37 func (o *TypeName) String() string { return "type " + o.name }
38
39 // ----------------------------------------------------------------------------
40 // Func
41
42 type Func struct {
43 object
44 hasPtrRecv bool
45 }
46
47 func NewFunc(pkg *Package, name string, sig *Signature) *Func {
48 return &Func{object: object{pkg: pkg, name: name, typ: sig}}
49 }
50 func (o *Func) Signature() *Signature {
51 if sig, ok := o.typ.(*Signature); ok {
52 return sig
53 }
54 return nil
55 }
56 func (o *Func) HasPtrRecv() bool { return o.hasPtrRecv }
57 func (o *Func) String() string { return "func " + o.name }
58
59 // ----------------------------------------------------------------------------
60 // Const
61
62 type Const struct {
63 object
64 val ConstVal
65 }
66
67 func NewConst(pkg *Package, name string, typ Type, val ConstVal) *Const {
68 return &Const{object: object{pkg: pkg, name: name, typ: typ}, val: val}
69 }
70 func (o *Const) Val() ConstVal { return o.val }
71 func (o *Const) String() string { return fmt.Sprintf("const %s = %v", o.name, o.val) }
72
73 // ConstVal wraps go/constant.Value for constant evaluation.
74 // We re-export it as an opaque type here so consumers don't need to import go/constant.
75 // In B4 (full Moxie rewrite) this becomes a native Moxie type.
76 type ConstVal = interface{ String() string }
77
78 // ----------------------------------------------------------------------------
79 // PkgName (an imported package)
80
81 type PkgName struct {
82 object
83 imported *Package
84 }
85
86 func NewPkgName(pkg *Package, name string, imported *Package) *PkgName {
87 return &PkgName{object: object{pkg: pkg, name: name}, imported: imported}
88 }
89 func (o *PkgName) Imported() *Package { return o.imported }
90 func (o *PkgName) String() string { return "package " + o.name }
91
92 // ----------------------------------------------------------------------------
93 // Builtin
94
95 type BuiltinID int
96
97 const (
98 BuiltinAppend BuiltinID = iota
99 BuiltinCap
100 BuiltinClear
101 BuiltinClose
102 BuiltinComplex // not valid in Moxie, rejected by checker
103 BuiltinCopy
104 BuiltinDelete
105 BuiltinImag // not valid in Moxie
106 BuiltinLen
107 BuiltinMake // rejected by checker (use literal syntax)
108 BuiltinNew // rejected by checker (use &T{})
109 BuiltinPanic
110 BuiltinPrint
111 BuiltinPrintln
112 BuiltinReal // not valid in Moxie
113 BuiltinRecover
114 BuiltinSpawn // Moxie-specific
115 BuiltinMin // Go 1.21
116 BuiltinMax // Go 1.21
117 )
118
119 type Builtin struct {
120 object
121 id BuiltinID
122 }
123
124 func newBuiltin(name string, id BuiltinID) *Builtin {
125 return &Builtin{object: object{name: name}, id: id}
126 }
127 func (o *Builtin) ID() BuiltinID { return o.id }
128 func (o *Builtin) String() string { return "builtin " + o.name }
129
130 // ----------------------------------------------------------------------------
131 // Label
132
133 type Label struct {
134 object
135 used bool
136 }
137
138 func NewLabel(pkg *Package, name string) *Label {
139 return &Label{object: object{pkg: pkg, name: name}}
140 }
141 func (o *Label) String() string { return "label " + o.name }
142