gotype: support function types
This commit is contained in:
parent
3f8377d9fe
commit
fc0008a208
46
gotype.go
46
gotype.go
@ -1,14 +1,31 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
type gotype struct {
|
type gotype struct {
|
||||||
SliceOf *gotype
|
SliceOf *gotype
|
||||||
MapKey *gotype
|
MapKey *gotype
|
||||||
MapVal *gotype
|
MapVal *gotype
|
||||||
PtrTo *gotype
|
PtrTo *gotype
|
||||||
Plain string
|
|
||||||
|
IsFunc bool
|
||||||
|
FuncParams []gotype
|
||||||
|
FuncReturn []gotype
|
||||||
|
|
||||||
|
Plain string
|
||||||
// TODO channel-of (although we will never? construct one from PHP source)
|
// TODO channel-of (although we will never? construct one from PHP source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func goTypeListToString(gotypes []gotype) string {
|
||||||
|
ret := make([]string, 0, len(gotypes))
|
||||||
|
for _, gt := range gotypes {
|
||||||
|
ret = append(ret, gt.AsGoString())
|
||||||
|
}
|
||||||
|
return strings.Join(ret, `, `)
|
||||||
|
}
|
||||||
|
|
||||||
func (gt gotype) AsGoString() string {
|
func (gt gotype) AsGoString() string {
|
||||||
if gt.SliceOf != nil {
|
if gt.SliceOf != nil {
|
||||||
return "[]" + gt.SliceOf.AsGoString()
|
return "[]" + gt.SliceOf.AsGoString()
|
||||||
@ -19,17 +36,38 @@ func (gt gotype) AsGoString() string {
|
|||||||
} else if gt.PtrTo != nil {
|
} else if gt.PtrTo != nil {
|
||||||
return "*" + gt.PtrTo.AsGoString()
|
return "*" + gt.PtrTo.AsGoString()
|
||||||
|
|
||||||
|
} else if gt.IsFunc {
|
||||||
|
|
||||||
|
ret := "func(" + goTypeListToString(gt.FuncParams) + `)`
|
||||||
|
if len(gt.FuncReturn) == 1 {
|
||||||
|
ret += ` ` + gt.FuncReturn[0].AsGoString()
|
||||||
|
} else if len(gt.FuncReturn) >= 2 {
|
||||||
|
ret += ` (` + goTypeListToString(gt.FuncReturn) + `)`
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return gt.Plain
|
return gt.Plain
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gt gotype) IsPlain() bool {
|
||||||
|
if gt.SliceOf != nil || gt.MapKey != nil || gt.PtrTo != nil || gt.IsFunc {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gt gotype) Equals(other *gotype) bool {
|
||||||
|
return gt.AsGoString() == other.AsGoString()
|
||||||
|
}
|
||||||
|
|
||||||
// ZeroValue returns a Go literal string for the zero value of this type.
|
// ZeroValue returns a Go literal string for the zero value of this type.
|
||||||
func (gt gotype) ZeroValue() string {
|
func (gt gotype) ZeroValue() string {
|
||||||
if gt.SliceOf != nil || gt.MapKey != nil || gt.PtrTo != nil {
|
if !gt.IsPlain() {
|
||||||
return `nil` // gt.AsGoString() + "{}"
|
return `nil`
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's a plain type
|
// It's a plain type
|
||||||
|
6
scope.go
6
scope.go
@ -43,11 +43,11 @@ func (this *Scope) Set(Name string, Type gotype) *LocalVar {
|
|||||||
|
|
||||||
if lv := this.Has(Name); lv != nil {
|
if lv := this.Has(Name); lv != nil {
|
||||||
// Update known type for existing variable
|
// Update known type for existing variable
|
||||||
if lv.Type == unknownVarType {
|
if lv.Type.Equals(&unknownVarType) {
|
||||||
lv.Type = Type
|
lv.Type = Type
|
||||||
} else if lv.Type == Type {
|
} else if lv.Type.Equals(&Type) {
|
||||||
// no-op, more evidence for the same type
|
// no-op, more evidence for the same type
|
||||||
} else if lv.Type != Type {
|
} else if !lv.Type.Equals(&Type) {
|
||||||
// conflicting type information
|
// conflicting type information
|
||||||
lv.Type = mixedVarType
|
lv.Type = mixedVarType
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user