Exemple #1
0
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 dump(path string, typ types.Type, st reflect.StructTag) IObj {
	named, _ := typ.(*types.Named)
	if named != nil {
		typ = typ.Underlying()
	}

	if strings.Split(st.Get("json"), ",")[0] == "" {
		if _, ok := typ.(*types.Struct); !ok {
			if _, ok := typ.(*types.Pointer); !ok {
				return nil
			}
		}
	}

	switch u := typ.(type) {
	case *types.Struct:
		return Struct(path, st, u, named)

	case *types.Map:
		return Map(path, st, u, named)

	case *types.Slice:
		return Slice(path, st, u)

	case *types.Pointer:
		return Pointer(path, st, u)

	case *types.Basic:
		return Basic(path, st, u, named)

	default:
		panic("unsupported")
	}
}
Exemple #3
0
// lockPath returns a typePath describing the location of a lock value
// contained in typ. If there is no contained lock, it returns nil.
func lockPath(tpkg *types.Package, typ types.Type) typePath {
	if typ == nil {
		return nil
	}

	// We're only interested in the case in which the underlying
	// type is a struct. (Interfaces and pointers are safe to copy.)
	styp, ok := typ.Underlying().(*types.Struct)
	if !ok {
		return nil
	}

	// We're looking for cases in which a reference to this type
	// can be locked, but a value cannot. This differentiates
	// embedded interfaces from embedded values.
	if plock := types.NewMethodSet(types.NewPointer(typ)).Lookup(tpkg, "Lock"); plock != nil {
		if lock := types.NewMethodSet(typ).Lookup(tpkg, "Lock"); lock == nil {
			return []types.Type{typ}
		}
	}

	nfields := styp.NumFields()
	for i := 0; i < nfields; i++ {
		ftyp := styp.Field(i).Type()
		subpath := lockPath(tpkg, ftyp)
		if subpath != nil {
			return append(subpath, typ)
		}
	}

	return nil
}
Exemple #4
0
func (g *goGen) genWrite(valName, seqName string, T types.Type) {
	if isErrorType(T) {
		g.Printf("if %s == nil {\n", valName)
		g.Printf("    %s.WriteString(\"\");\n", seqName)
		g.Printf("} else {\n")
		g.Printf("    %s.WriteString(%s.Error());\n", seqName, valName)
		g.Printf("}\n")
		return
	}
	switch T := T.(type) {
	case *types.Pointer:
		// TODO(crawshaw): test *int
		// TODO(crawshaw): test **Generator
		switch T := T.Elem().(type) {
		case *types.Named:
			obj := T.Obj()
			if obj.Pkg() != g.pkg {
				g.errorf("type %s not defined in package %s", T, g.pkg)
				return
			}
			g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
		default:
			g.errorf("unsupported type %s", T)
		}
	case *types.Named:
		switch u := T.Underlying().(type) {
		case *types.Interface, *types.Pointer:
			g.Printf("%s.WriteGoRef(%s)\n", seqName, valName)
		default:
			g.errorf("unsupported, direct named type %s: %s", T, u)
		}
	default:
		g.Printf("%s.Write%s(%s);\n", seqName, seqType(T), valName)
	}
}
Exemple #5
0
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)))
}
Exemple #6
0
func needWrapType(typ types.Type) bool {
	switch typ := typ.(type) {
	case *types.Basic:
		return false
	case *types.Struct:
		return true
	case *types.Named:
		switch ut := typ.Underlying().(type) {
		case *types.Basic:
			return false
		default:
			return needWrapType(ut)
		}
	case *types.Array:
		return true
	case *types.Map:
		return true
	case *types.Slice:
		return true
	case *types.Interface:
		wrap := true
		if typ.Underlying() == universe.syms["error"].GoType().Underlying() {
			wrap = false
		}
		return wrap
	case *types.Signature:
		return true
	case *types.Pointer:
		return needWrapType(typ.Elem())
	}
	return false
}
// MethodSet returns the method set of type T.  It is thread-safe.
//
// If cache is nil, this function is equivalent to types.NewMethodSet(T).
// Utility functions can thus expose an optional *MethodSetCache
// parameter to clients that care about performance.
//
func (cache *MethodSetCache) MethodSet(T types.Type) *types.MethodSet {
	if cache == nil {
		return types.NewMethodSet(T)
	}
	cache.mu.Lock()
	defer cache.mu.Unlock()

	switch T := T.(type) {
	case *types.Named:
		return cache.lookupNamed(T).value

	case *types.Pointer:
		if N, ok := T.Elem().(*types.Named); ok {
			return cache.lookupNamed(N).pointer
		}
	}

	// all other types
	// (The map uses pointer equivalence, not type identity.)
	mset := cache.others[T]
	if mset == nil {
		mset = types.NewMethodSet(T)
		if cache.others == nil {
			cache.others = make(map[types.Type]*types.MethodSet)
		}
		cache.others[T] = mset
	}
	return mset
}
Exemple #8
0
func (sym *symtab) addInterfaceType(pkg *types.Package, obj types.Object, t types.Type, kind symkind, id, n string) {
	fn := sym.typename(t, nil)
	typ := t.Underlying().(*types.Interface)
	kind |= skInterface
	// special handling of 'error'
	if isErrorType(typ) {
		return
	}

	sym.syms[fn] = &symbol{
		gopkg:   pkg,
		goobj:   obj,
		gotyp:   t,
		kind:    kind,
		id:      id,
		goname:  n,
		cgoname: "cgo_type_" + id,
		cpyname: "cpy_type_" + id,
		pyfmt:   "O&",
		pybuf:   "P",
		pysig:   "object",
		c2py:    "cgopy_cnv_c2py_" + id,
		py2c:    "cgopy_cnv_py2c_" + id,
		pychk:   fmt.Sprintf("cpy_func_%[1]s_check(%%s)", id),
	}

}
Exemple #9
0
func getStructType(t types.Type) string {
	ts := t.String()
	if ts != "time.Time" && ts != "bson.ObjectId" {
		return "struct"
	}

	return ts
}
Exemple #10
0
func (fr *frame) makeInterface(llv llvm.Value, vty types.Type, iface types.Type) *govalue {
	if _, ok := vty.Underlying().(*types.Pointer); !ok {
		ptr := fr.createTypeMalloc(vty)
		fr.builder.CreateStore(llv, ptr)
		llv = ptr
	}
	return fr.makeInterfaceFromPointer(llv, vty, iface)
}
Exemple #11
0
func (x array) hash(t types.Type) int {
	h := 0
	tElt := t.Underlying().(*types.Array).Elem()
	for _, xi := range x {
		h += hash(tElt, xi)
	}
	return h
}
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
}
Exemple #13
0
// Reads the value from the given interface type, assuming that the
// interface holds a value of the correct type.
func (fr *frame) getInterfaceValue(v *govalue, ty types.Type) *govalue {
	val := fr.builder.CreateExtractValue(v.value, 1, "")
	if _, ok := ty.Underlying().(*types.Pointer); !ok {
		typedval := fr.builder.CreateBitCast(val, llvm.PointerType(fr.types.ToLLVM(ty), 0), "")
		val = fr.builder.CreateLoad(typedval, "")
	}
	return newValue(val, ty)
}
Exemple #14
0
func signed(t types.Type) bool {

	switch t := t.(type) {
	case *types.Basic:
		return signedBasic(t.Kind())
	}
	panic(ice(fmt.Sprintf("unknown type: %v", t)))
}
Exemple #15
0
func catchReferencedTypes(et types.Type) {
	id := LogTypeUse(et)
	_, seen := catchReferencedTypesSeen[id]
	if seen {
		return
	}
	catchReferencedTypesSeen[id] = true

	// check that we have all the required methods?
	/*
		for t := 1; t < NextTypeID; t++ { // make sure we do this in a consistent order
			for _, k := range TypesEncountered.Keys() {
				if TypesEncountered.At(k).(int) == t {
					switch k.(type) {
					case *types.Interface:
						if types.Implements(et,k.(*types.Interface)) {
							// TODO call missing method?
						}
					}
				}
			}
		}
	*/

	//LogTypeUse(types.NewPointer(et))
	switch et.(type) {
	case *types.Named:
		catchReferencedTypes(et.Underlying())
		for m := 0; m < et.(*types.Named).NumMethods(); m++ {
			catchReferencedTypes(et.(*types.Named).Method(m).Type())
		}
	case *types.Array:
		catchReferencedTypes(et.(*types.Array).Elem())
		//catchReferencedTypes(types.NewSlice(et.(*types.Array).Elem()))
	case *types.Pointer:
		catchReferencedTypes(et.(*types.Pointer).Elem())
	case *types.Slice:
		catchReferencedTypes(et.(*types.Slice).Elem())
	case *types.Struct:
		for f := 0; f < et.(*types.Struct).NumFields(); f++ {
			if et.(*types.Struct).Field(f).IsField() {
				catchReferencedTypes(et.(*types.Struct).Field(f).Type())
			}
		}
	case *types.Map:
		catchReferencedTypes(et.(*types.Map).Key())
		catchReferencedTypes(et.(*types.Map).Elem())
	case *types.Signature:
		for i := 0; i < et.(*types.Signature).Params().Len(); i++ {
			catchReferencedTypes(et.(*types.Signature).Params().At(i).Type())
		}
		for o := 0; o < et.(*types.Signature).Results().Len(); o++ {
			catchReferencedTypes(et.(*types.Signature).Results().At(o).Type())
		}
	case *types.Chan:
		catchReferencedTypes(et.(*types.Chan).Elem())
	}
}
Exemple #16
0
// If cond is true, reads the value from the given interface type, otherwise
// returns a nil value.
func (fr *frame) getInterfaceValueOrNull(cond llvm.Value, v *govalue, ty types.Type) *govalue {
	val := fr.builder.CreateExtractValue(v.value, 1, "")
	if _, ok := ty.Underlying().(*types.Pointer); ok {
		val = fr.builder.CreateSelect(cond, val, llvm.ConstNull(val.Type()), "")
	} else {
		val = fr.loadOrNull(cond, val, ty).value
	}
	return newValue(val, ty)
}
Exemple #17
0
func isInt(t types.Type) bool {
	if t, ok := t.(*types.Basic); ok {
		switch t.Kind() {
		case types.Int, types.Int8, types.Int16, types.Int32, types.Int64:
			return true
		}
	}
	return false
}
Exemple #18
0
func (fr *frame) makeInterfaceFromPointer(vptr llvm.Value, vty types.Type, iface types.Type) *govalue {
	i8ptr := llvm.PointerType(llvm.Int8Type(), 0)
	llv := fr.builder.CreateBitCast(vptr, i8ptr, "")
	value := llvm.Undef(fr.types.ToLLVM(iface))
	itab := fr.types.getItabPointer(vty, iface.Underlying().(*types.Interface))
	value = fr.builder.CreateInsertValue(value, itab, 0, "")
	value = fr.builder.CreateInsertValue(value, llv, 1, "")
	return newValue(value, iface)
}
Exemple #19
0
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 + ";"
}
Exemple #20
0
func (x structure) hash(t types.Type) int {
	tStruct := t.Underlying().(*types.Struct)
	h := 0
	for i, n := 0, tStruct.NumFields(); i < n; i++ {
		if f := tStruct.Field(i); !f.Anonymous() {
			h += hash(f.Type(), x[i])
		}
	}
	return h
}
Exemple #21
0
func (x array) eq(t types.Type, _y interface{}) bool {
	y := _y.(array)
	tElt := t.Underlying().(*types.Array).Elem()
	for i, xi := range x {
		if !equals(tElt, xi, y[i]) {
			return false
		}
	}
	return true
}
Exemple #22
0
// usesBuiltinMap returns true if the built-in hash function and
// equivalence relation for type t are consistent with those of the
// interpreter's representation of type t.  Such types are: all basic
// types (bool, numbers, string), pointers and channels.
//
// usesBuiltinMap returns false for types that require a custom map
// implementation: interfaces, arrays and structs.
//
// Panic ensues if t is an invalid map key type: function, map or slice.
func usesBuiltinMap(t types.Type) bool {
	switch t := t.(type) {
	case *types.Basic, *types.Chan, *types.Pointer:
		return true
	case *types.Named:
		return usesBuiltinMap(t.Underlying())
	case *types.Interface, *types.Array, *types.Struct:
		return false
	}
	panic(fmt.Sprintf("invalid map key type: %T", t))
}
Exemple #23
0
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),
	}
}
Exemple #24
0
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()
}
Exemple #25
0
func (x structure) eq(t types.Type, _y interface{}) bool {
	y := _y.(structure)
	tStruct := t.Underlying().(*types.Struct)
	for i, n := 0, tStruct.NumFields(); i < n; i++ {
		if f := tStruct.Field(i); !f.Anonymous() {
			if !equals(f.Type(), x[i], y[i]) {
				return false
			}
		}
	}
	return true
}
Exemple #26
0
func (fr *frame) interfaceTypeAssert(val *govalue, ty types.Type) *govalue {
	if _, ok := ty.Underlying().(*types.Interface); ok {
		return fr.changeInterface(val, ty, true)
	} else {
		valtytd := fr.types.ToRuntime(val.Type())
		valtd := fr.getInterfaceTypeDescriptor(val)
		tytd := fr.types.ToRuntime(ty)
		fr.runtime.checkInterfaceType.call(fr, valtd, tytd, valtytd)

		return fr.getInterfaceValue(val, ty)
	}
}
Exemple #27
0
// CanHaveDynamicTypes reports whether the type T can "hold" dynamic types,
// i.e. is an interface (incl. reflect.Type) or a reflect.Value.
//
func CanHaveDynamicTypes(T types.Type) bool {
	switch T := T.(type) {
	case *types.Named:
		if obj := T.Obj(); obj.Name() == "Value" && obj.Pkg().Path() == "reflect" {
			return true // reflect.Value
		}
		return CanHaveDynamicTypes(T.Underlying())
	case *types.Interface:
		return true
	}
	return false
}
Exemple #28
0
// TypeChainString returns the full type chain as a string.
func TypeChainString(t types.Type) string {
	out := fmt.Sprintf("%s", t)
	for {
		if t == t.Underlying() {
			break
		} else {
			t = t.Underlying()
		}
		out += fmt.Sprintf(" -> %s", t)
	}
	return out
}
Exemple #29
0
// javaType returns a string that can be used as a Java type.
func (g *javaGen) javaType(T types.Type) string {
	switch T := T.(type) {
	case *types.Basic:
		switch T.Kind() {
		case types.Bool:
			return "boolean"
		case types.Int:
			return "long"
		case types.Int8:
			return "byte"
		case types.Int16:
			return "short"
		case types.Int32:
			return "int"
		case types.Int64:
			return "long"
		case types.Uint8:
			// TODO(crawshaw): Java bytes are signed, so this is
			// questionable, but vital.
			return "byte"
		// TODO(crawshaw): case types.Uint, types.Uint16, types.Uint32, types.Uint64:
		case types.Float32:
			return "float"
		case types.Float64:
			return "double"
		case types.String:
			return "String"
		default:
			g.errorf("unsupported return type: %s", T)
			return "TODO"
		}
	case *types.Slice:
		elem := g.javaType(T.Elem())
		return elem + "[]"

	case *types.Pointer:
		if _, ok := T.Elem().(*types.Named); ok {
			return g.javaType(T.Elem())
		}
		panic(fmt.Sprintf("unsupporter pointer to type: %s", T))
	case *types.Named:
		n := T.Obj()
		if n.Pkg() != g.pkg {
			panic(fmt.Sprintf("type %s is in package %s, must be defined in package %s", n.Name(), n.Pkg().Name(), g.pkg.Name()))
		}
		// TODO(crawshaw): more checking here
		return n.Name()
	default:
		g.errorf("unsupported javaType: %#+v, %s\n", T, T)
		return "TODO"
	}
}
Exemple #30
0
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,
	}
}