func MustWriteGoTypes(thisPackagePath string, typi types.Type) (s string, addPkgPathList []string) { switch typ := typi.(type) { case *types.Basic: return typ.String(), nil case *types.Named: if typ.Obj().Pkg() == nil { return typ.Obj().Name(), nil } typPkgPath := typ.Obj().Pkg().Path() if thisPackagePath == typPkgPath { return typ.Obj().Name(), nil } return path.Base(typPkgPath) + "." + typ.Obj().Name(), []string{typPkgPath} case *types.Pointer: s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) return "*" + s, addPkgPathList case *types.Slice: s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) return "[]" + s, addPkgPathList case *types.Interface: return typ.String(), nil //s, addPkgPathList = MustWriteGoTypes(thisPackagePath, typ.Elem()) //return "[]" + s, addPkgPathList default: panic(fmt.Errorf("[MustWriteGoTypes] Not implement go/types [%T] [%s]", typi, typi.String())) } return "", nil }
func sizeof(t types.Type) uint { switch t := t.(type) { case *types.Tuple: // TODO: usage of reflect most likely wrong! // uint(reflect.TypeOf(t).Elem().Size()) panic("Tuples are unsupported") case *types.Basic: return sizeBasic(t.Kind()) case *types.Pointer: return sizePtr() case *types.Slice: return sizeSlice(t) case *types.Array: return sizeArray(t) case *types.Named: if sse2, ok := sse2Info(t); ok { return sse2.size } else if info, ok := simdInfo(t); ok { return info.size } else { panic(ice(fmt.Sprintf("unknown named type \"%v\"", t.String()))) } } panic(ice(fmt.Sprintf("unknown type: %v", t))) }
func getStructType(t types.Type) string { ts := t.String() if ts != "time.Time" && ts != "bson.ObjectId" { return "struct" } return ts }
func typefmt(typ types.Type) string { // Ugh. typename := typ.String() for _, p := range strings.Split(os.Getenv("GOPATH"), ":") { typename = strings.Replace(typename, p+"/src/", "", -1) } return typename }
func (l langType) MakeInterface(register string, regTyp types.Type, v interface{}, errorInfo string) string { ret := `new Interface(` + l.PogoComp().LogTypeUse(v.(ssa.Value).Type() /*NOT underlying()*/) + `,` + l.IndirectValue(v, errorInfo) + ")" if getHaxeClass(regTyp.String()) != "" { ret = "Force.toHaxeParam(" + ret + ")" // as interfaces are not native to haxe, so need to convert // TODO optimize when stable } return register + `=` + ret + ";" }
func makeImplementsType(T types.Type, fset *token.FileSet) serial.ImplementsType { var pos token.Pos if nt, ok := deref(T).(*types.Named); ok { // implementsResult.t may be non-named pos = nt.Obj().Pos() } return serial.ImplementsType{ Name: T.String(), Pos: fset.Position(pos).String(), Kind: typeKind(T), } }
func cgoTypeName(typ types.Type) string { switch typ := typ.(type) { case *types.Basic: kind := typ.Kind() o, ok := typedescr[kind] if ok { return o.cgotype } } return typ.String() }
func newVar(p *Package, typ types.Type, objname, name, doc string) *Var { sym := p.syms.symtype(typ) if sym == nil { panic(fmt.Errorf("could not find symbol for type [%s]!", typ.String())) } return &Var{ pkg: p, sym: sym, id: p.Name() + "_" + objname, doc: doc, name: name, } }
func align(t types.Type) uint { switch t := t.(type) { case *types.Tuple: return alignTuple(t) case *types.Array, *types.Basic, *types.Pointer, *types.Slice: return uint(reflectType(t).Align()) case *types.Named: if sse2, ok := sse2Info(t); ok { return sse2.align } else if info, ok := simdInfo(t); ok { return info.align } else { panic(ice(fmt.Sprintf("unknown named type \"%v\"", t.String()))) } } panic(ice(fmt.Sprintf("unknown type (%v)", t))) }
func (g *goGen) qualifiedType(typ types.Type) string { switch typ := typ.(type) { case *types.Basic: return typ.Name() case *types.Named: obj := typ.Obj() //return obj.Pkg().Name() + "." + obj.Name() return "GoPy_" + obj.Name() switch typ := typ.Underlying().(type) { case *types.Struct: return typ.String() default: return "GoPy_ooops_" + obj.Name() } } return fmt.Sprintf("%#T", typ) }
func sizeofElem(t types.Type) uint { var e types.Type switch t := t.(type) { default: panic(ice(fmt.Sprintf("type (%v) not an array or slice\n", t.String()))) case *types.Slice: e = t.Elem() case *types.Array: e = t.Elem() case *types.Named: if typeinfo, ok := simdInfo(t); ok { return typeinfo.elemSize } panic(ice( fmt.Sprintf("t (%v), isSimd (%v)\n", t.String(), isSimd(t)))) } return sizeof(e) }
func (l langType) rtypeBuild(i int, sizes types.Sizes, t types.Type, name string) (string, reflect.Kind) { var kind reflect.Kind kind, name = getTypeInfo(t, name) sof := int64(4) aof := int64(4) if kind != reflect.Invalid { sof = sizes.Sizeof(t) aof = sizes.Alignof(t) } ret := "Go_haxegoruntime_newRRtype.callFromRT(0,\n" ret += fmt.Sprintf("\t/*size:*/ %d,\n", sof) ret += fmt.Sprintf("\t/*align:*/ %d,\n", aof) ret += fmt.Sprintf("\t/*fieldAlign:*/ %d,\n", aof) // TODO check correct for fieldAlign ret += fmt.Sprintf("\t/*kind:*/ %d, // %s\n", kind, (kind & ((1 << 5) - 1)).String()) alg := "false" if types.Comparable(t) { alg = "true" } ret += fmt.Sprintf("\t/*comprable:*/ %s,\n", alg) // TODO change this to be the actual function ret += fmt.Sprintf("\t/*string:*/ \"%s\", // %s\n", escapedTypeString(t.String()), t.String()) ret += fmt.Sprintf("\t/*uncommonType:*/ %s,\n", l.uncommonBuild(i, sizes, name, t)) ptt := "null" for pti, pt := range l.hc.typesByID { _, isPtr := pt.(*types.Pointer) if isPtr { ele := l.hc.pte.At(pt.(*types.Pointer).Elem()) if ele != nil { if i == ele.(int) { ptt = fmt.Sprintf("type%d()", pti) } } } } ret += fmt.Sprintf("\t/*ptrToThis:*/ %s", ptt) ret += ")" return ret, kind }
func (tm *llvmTypeMap) getBackendType(t types.Type) backendType { switch t := t.(type) { case *types.Named: return tm.getBackendType(t.Underlying()) case *types.Basic: switch t.Kind() { case types.Bool, types.Uint8: return &intBType{1, false} case types.Int8: return &intBType{1, true} case types.Uint16: return &intBType{2, false} case types.Int16: return &intBType{2, true} case types.Uint32: return &intBType{4, false} case types.Int32: return &intBType{4, true} case types.Uint64: return &intBType{8, false} case types.Int64: return &intBType{8, true} case types.Uint, types.Uintptr: return &intBType{tm.target.PointerSize(), false} case types.Int: return &intBType{tm.target.PointerSize(), true} case types.Float32: return &floatBType{false} case types.Float64: return &floatBType{true} case types.UnsafePointer: return &ptrBType{} case types.Complex64: f32 := &floatBType{false} return &structBType{[]backendType{f32, f32}} case types.Complex128: f64 := &floatBType{true} return &structBType{[]backendType{f64, f64}} case types.String: return &structBType{[]backendType{&ptrBType{}, &intBType{tm.target.PointerSize(), false}}} } case *types.Struct: var fields []backendType for i := 0; i != t.NumFields(); i++ { f := t.Field(i) fields = append(fields, tm.getBackendType(f.Type())) } return &structBType{fields} case *types.Pointer, *types.Signature, *types.Map, *types.Chan: return &ptrBType{} case *types.Interface: i8ptr := &ptrBType{} return &structBType{[]backendType{i8ptr, i8ptr}} case *types.Slice: return tm.sliceBackendType() case *types.Array: return &arrayBType{uint64(t.Len()), tm.getBackendType(t.Elem())} } panic("unhandled type: " + t.String()) }
func (l langType) typeBuild(i int, t types.Type) string { sizes := &haxeStdSizes ret := fmt.Sprintf( // sizeof largest struct (funcType) is 76 "private static var type%dptr:Pointer=null; // %s\npublic static function type%d():Pointer { if(type%dptr==null) { type%dptr=Pointer.make(Object.make(80));", i, t.String(), i, i, i) ret += "" name := "" if namedT, named := t.(*types.Named); named { name = namedT.Obj().Name() } if basic, isBasic := t.(*types.Basic); isBasic { name = basic.Name() } rtype, kind := l.rtypeBuild(i, sizes, t, name) switch t.(type) { case *types.Named: t = t.(*types.Named).Underlying() } switch kind & kindMask { case reflect.Invalid, reflect.Bool, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128, reflect.String, reflect.UnsafePointer: ret += fmt.Sprintf("Go_haxegoruntime_fillRRtype.callFromRT(0,type%dptr,%s)", i, rtype) case reflect.Ptr: ret += fmt.Sprintf("Go_haxegoruntime_fillPPtrTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" if l.hc.pte.At(t.(*types.Pointer).Elem()) == nil { ret += fmt.Sprintf("/*elem:*/ nil,\n") } else { ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Pointer).Elem()).(int)) } ret += ")" case reflect.Array: ret += fmt.Sprintf("Go_haxegoruntime_fillAArrayTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d(),\n", l.hc.pte.At(t.(*types.Array).Elem()).(int)) asl := "null" // slice type for _, tt := range l.hc.pte.Keys() { slt, isSlice := tt.(*types.Slice) if isSlice { if l.hc.pte.At(slt.Elem()) == l.hc.pte.At(t.(*types.Array).Elem()) { asl = fmt.Sprintf("type%d()", l.hc.pte.At(slt).(int)) break } } } // TODO make missing slice types before we start outputting types to avoid not having one? ret += fmt.Sprintf("/*slice:*/ %s,\n", asl) ret += fmt.Sprintf("/*len:*/ %d\n", t.(*types.Array).Len()) ret += ")" case reflect.Slice: ret += fmt.Sprintf("Go_haxegoruntime_fillSSliceTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Slice).Elem()).(int)) ret += ")" case reflect.Struct: fields := []*types.Var{} for fld := 0; fld < t.(*types.Struct).NumFields(); fld++ { fldInfo := t.(*types.Struct).Field(fld) //if fldInfo.IsField() { fields = append(fields, fldInfo) //} } offs := sizes.Offsetsof(fields) ret += fmt.Sprintf("Go_haxegoruntime_fillSStructTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n/*fields:*/ " fret := "Go_haxegoruntime_newSStructFFieldSSlice.callFromRT(0)" numFlds := t.(*types.Struct).NumFields() for fld := 0; fld < numFlds; fld++ { fldInfo := t.(*types.Struct).Field(fld) name := fldInfo.Name() path := fldInfo.Pkg().Path() if fldInfo.Exported() { path = "" } if fldInfo.Anonymous() { name = "" } fret = "\tGo_haxegoruntime_addSStructFFieldSSlice.callFromRT(0," + fret + "," fret += "\n\t\t/*name:*/ \"" + name + "\",\n" fret += "\t\t/*pkgPath:*/ \"" + path + "\",\n" fret += fmt.Sprintf("\t\t/*typ:*/ type%d(),// %s\n", l.hc.pte.At(fldInfo.Type()), fldInfo.Type().String()) fret += "\t\t/*tag:*/ \"" + escapedTypeString(t.(*types.Struct).Tag(fld)) + "\", // " + t.(*types.Struct).Tag(fld) + "\n" fret += fmt.Sprintf("\t\t/*offset:*/ %d\n", offs[fld]) fret += "\t)" } ret += fret + ")" case reflect.Interface: ret += fmt.Sprintf("Go_haxegoruntime_fillIInterfaceTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n/*methods:*/ " mret := "Go_haxegoruntime_newIImethodSSlice.callFromRT(0)" for m := 0; m < t.(*types.Interface).NumMethods(); m++ { meth := t.(*types.Interface).Method(m) mret = "Go_haxegoruntime_addIImethodSSlice.callFromRT(0," + mret + "," mret += "\t\t/*name:*/ \"" + meth.Name() + "\",\n" path := "\"\"" if !meth.Exported() { path = "\"" + meth.Pkg().Path() + "\"" } mret += "\t\t/*pkgPath:*/ " + path + ",\n" typ := "null" iface := l.hc.pte.At(meth.Type()) if iface != interface{}(nil) { typ = fmt.Sprintf("type%d()", iface.(int)) } mret += fmt.Sprintf("\t\t/*typ:*/ %s // %s\n", typ, meth.String()) mret += "\t)\n" } ret += mret + ")" case reflect.Map: ret += fmt.Sprintf("Go_haxegoruntime_fillMMapTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*key:*/ type%d(),\n", l.hc.pte.At(t.(*types.Map).Key()).(int)) ret += fmt.Sprintf("/*elem:*/ type%d()\n", l.hc.pte.At(t.(*types.Map).Elem()).(int)) ret += ")" case reflect.Func: ret += fmt.Sprintf("Go_haxegoruntime_fillFFuncTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*dotdotdot:*/ %v,\n", t.(*types.Signature).Variadic()) ret += "/*in:*/ " iret := "Go_haxegoruntime_newPPtrTToRRtypeSSlice.callFromRT(0)" for i := 0; i < t.(*types.Signature).Params().Len(); i++ { iret = fmt.Sprintf("Go_haxegoruntime_addPPtrTToRRtypeSSlice.callFromRT(0,%s,\n\ttype%d())", iret, l.hc.pte.At((t.(*types.Signature).Params().At(i).Type())).(int)) } ret += iret + ",\n/*out:*/ " oret := "Go_haxegoruntime_newPPtrTToRRtypeSSlice.callFromRT(0)" for o := 0; o < t.(*types.Signature).Results().Len(); o++ { oret = fmt.Sprintf("Go_haxegoruntime_addPPtrTToRRtypeSSlice.callFromRT(0,%s,\n\ttype%d())", oret, l.hc.pte.At((t.(*types.Signature).Results().At(o).Type())).(int)) } ret += oret + " )\n" case reflect.Chan: ret += fmt.Sprintf("Go_haxegoruntime_fillCChanTType.callFromRT(0,type%dptr,\n/*rtype:*/ ", i) + rtype + ",\n" ret += fmt.Sprintf("/*elem:*/ type%d(),\n", l.hc.pte.At(t.(*types.Chan).Elem()).(int)) reflectDir := reflect.ChanDir(0) switch t.(*types.Chan).Dir() { case types.SendRecv: reflectDir = reflect.BothDir case types.SendOnly: reflectDir = reflect.SendDir case types.RecvOnly: reflectDir = reflect.RecvDir } ret += fmt.Sprintf("/*dir:*/ %d\n", reflectDir) ret += ")" default: panic("unhandled reeflect.type") } ret += ";" ret += fmt.Sprintf("}; return type%dptr; }\n", i) return ret }