/* from the SSA documentation: The ChangeType instruction applies to X a value-preserving type change to Type(). Type changes are permitted: - between a named type and its underlying type. - between two named types of the same underlying type. - between (possibly named) pointers to identical base types. - between f(T) functions and (T) func f() methods. - from a bidirectional channel to a read- or write-channel, optionally adding/removing a name. */ func (l langType) ChangeType(register string, regTyp interface{}, v interface{}, errorInfo string) string { //fmt.Printf("DEBUG CHANGE TYPE: %v -- %v\n", regTyp, v) switch v.(ssa.Value).(type) { case *ssa.Function: return register + "=" + "new Closure(Go_" + l.LangName(pogo.FuncPathName(v.(*ssa.Function))) + ".call,[]);" default: hType := getHaxeClass(regTyp.(types.Type).String()) if hType != "" { switch v.(ssa.Value).Type().Underlying().(type) { case *types.Interface: return register + "=" + l.IndirectValue(v, errorInfo) + ".val;" default: return register + "=cast " + l.IndirectValue(v, errorInfo) + ";" // unsafe cast! } } switch v.(ssa.Value).Type().Underlying().(type) { case *types.Basic: if v.(ssa.Value).Type().Underlying().(*types.Basic).Kind() == types.UnsafePointer { /* from https://groups.google.com/forum/#!topic/golang-dev/6eDTDZPWvoM Treat unsafe.Pointer -> *T conversions by returning new(T). This is incorrect but at least preserves type-safety... TODO decide if the above method is better than just copying the value as below */ return register + "=" + l.LangType(regTyp.(types.Type), true, errorInfo) + ";" } } } return register + `=` + l.IndirectValue(v, errorInfo) + ";" // usually, this is a no-op as far as Haxe is concerned }
func (l langType) FuncName(fnx *ssa.Function) string { pn := "" if fnx.Signature.Recv() != nil { pn = fnx.Signature.Recv().Type().String() // NOTE no use of underlying here } else { pn, _ = pogo.FuncPathName(fnx) //fmt.Sprintf("fn%d", fnx.Pos()) fn := ssa.EnclosingFunction(fnx.Package(), []ast.Node{fnx.Syntax()}) if fn == nil { fn = fnx } if fn.Pkg != nil { if fn.Pkg.Object != nil { pn = fn.Pkg.Object.Path() // was .Name() } } else { if fn.Object() != nil { if fn.Object().Pkg() != nil { pn = fn.Object().Pkg().Path() // was .Name() } } } } return l.LangName(pn, fnx.Name()) }