func (c *funcContext) loadStruct(array, target string, s *types.Struct) string { view := c.newVariable("_view") code := fmt.Sprintf("%s = new DataView(%s.buffer, %s.byteOffset)", view, array, array) var fields []*types.Var var collectFields func(s *types.Struct, path string) collectFields = func(s *types.Struct, path string) { for i := 0; i < s.NumFields(); i++ { field := s.Field(i) if fs, isStruct := field.Type().Underlying().(*types.Struct); isStruct { collectFields(fs, path+"."+fieldName(s, i)) continue } fields = append(fields, types.NewVar(0, nil, path+"."+fieldName(s, i), field.Type())) } } collectFields(s, target) offsets := sizes32.Offsetsof(fields) for i, field := range fields { switch t := field.Type().Underlying().(type) { case *types.Basic: if isNumeric(t) { if is64Bit(t) { code += fmt.Sprintf(", %s = new %s(%s.getUint32(%d, true), %s.getUint32(%d, true))", field.Name(), c.typeName(field.Type()), view, offsets[i]+4, view, offsets[i]) break } code += fmt.Sprintf(", %s = %s.get%s(%d, true)", field.Name(), view, toJavaScriptType(t), offsets[i]) } case *types.Array: code += fmt.Sprintf(`, %s = new ($nativeArray(%s))(%s.buffer, $min(%s.byteOffset + %d, %s.buffer.byteLength))`, field.Name(), typeKind(t.Elem()), array, array, offsets[i], array) } } return code }
func (d *DIBuilder) descriptorStruct(t *types.Struct, name string) llvm.Value { fields := make([]*types.Var, t.NumFields()) for i := range fields { fields[i] = t.Field(i) } offsets := d.sizes.Offsetsof(fields) members := make([]llvm.Value, len(fields)) for i, f := range fields { // TODO(axw) file/line where member is defined. t := f.Type() members[i] = d.builder.CreateMemberType(d.cu, llvm.DIMemberType{ Name: f.Name(), Type: d.DIType(t), SizeInBits: uint64(d.sizes.Sizeof(t) * 8), AlignInBits: uint64(d.sizes.Alignof(t) * 8), OffsetInBits: uint64(offsets[i] * 8), }) } // TODO(axw) file/line where struct is defined. return d.builder.CreateStructType(d.cu, llvm.DIStructType{ Name: name, SizeInBits: uint64(d.sizes.Sizeof(t) * 8), AlignInBits: uint64(d.sizes.Alignof(t) * 8), Elements: members, }) }
func fieldOffset(str *types.Struct, fldNum int) int64 { fieldList := make([]*types.Var, str.NumFields()) for f := 0; f < str.NumFields(); f++ { fieldList[f] = str.Field(f) } return haxeStdSizes.Offsetsof(fieldList)[fldNum] }
// matchStructArgType reports whether all the elements of the struct match the expected // type. For instance, with "%d" all the elements must be printable with the "%d" format. func (f *File) matchStructArgType(t printfArgType, typ *types.Struct, arg ast.Expr, inProgress map[types.Type]bool) bool { for i := 0; i < typ.NumFields(); i++ { if !f.matchArgTypeInternal(t, typ.Field(i).Type(), arg, inProgress) { return false } } return true }
func exportedFields(T *types.Struct) []*types.Var { var fields []*types.Var for i := 0; i < T.NumFields(); i++ { f := T.Field(i) if !f.Exported() { continue } fields = append(fields, f) } return fields }
func (g *goGen) genStruct(obj *types.TypeName, typ *types.Struct) { //fmt.Printf("obj: %#v\ntyp: %#v\n", obj, typ) pkgname := obj.Pkg().Name() g.Printf("//export GoPy_%[1]s\n", obj.Name()) g.Printf("type GoPy_%[1]s unsafe.Pointer\n\n", obj.Name()) for i := 0; i < typ.NumFields(); i++ { f := typ.Field(i) if !f.Exported() { continue } ft := f.Type() ftname := g.qualifiedType(ft) if needWrapType(ft) { ftname = fmt.Sprintf("GoPy_%[1]s_field_%d", obj.Name(), i+1) g.Printf("//export %s\n", ftname) g.Printf("type %s unsafe.Pointer\n\n", ftname) } g.Printf("//export GoPy_%[1]s_getter_%[2]d\n", obj.Name(), i+1) g.Printf("func GoPy_%[1]s_getter_%[2]d(self GoPy_%[1]s) %[3]s {\n", obj.Name(), i+1, ftname, ) g.Indent() g.Printf( "ret := (*%[1]s)(unsafe.Pointer(self))\n", pkgname+"."+obj.Name(), ) if needWrapType(f.Type()) { dt := getTypedesc(f.Type()) g.Printf("%s(unsafe.Pointer(&ret.%s))\n", dt.cgotype, f.Name()) } else { g.Printf("return ret.%s\n", f.Name()) } g.Outdent() g.Printf("}\n\n") } g.Printf("//export GoPy_%[1]s_new\n", obj.Name()) g.Printf("func GoPy_%[1]s_new() GoPy_%[1]s {\n", obj.Name()) g.Indent() g.Printf("return (GoPy_%[1]s)(unsafe.Pointer(&%[2]s.%[1]s{}))\n", obj.Name(), pkgname, ) g.Outdent() g.Printf("}\n\n") }
func optimalSize(str *types.Struct, sizes *gcSizes) int64 { nf := str.NumFields() fields := make([]*types.Var, nf) alignofs := make([]int64, nf) sizeofs := make([]int64, nf) for i := 0; i < nf; i++ { fields[i] = str.Field(i) ft := fields[i].Type() alignofs[i] = sizes.Alignof(ft) sizeofs[i] = sizes.Sizeof(ft) } sort.Sort(&byAlignAndSize{fields, alignofs, sizeofs}) return sizes.Sizeof(types.NewStruct(fields, nil)) }
func (g *Grapher) assignStructFieldPaths(styp *types.Struct, prefix []string, pkgscope bool) { for i := 0; i < styp.NumFields(); i++ { f := styp.Field(i) path := append(append([]string{}, prefix...), f.Name()) g.paths[f] = path g.exported[f] = ast.IsExported(f.Name()) g.pkgscope[f] = pkgscope // recurse to anonymous structs (named structs are assigned directly) // TODO(sqs): handle arrays of structs, etc. if styp, ok := derefType(f.Type()).(*types.Struct); ok { g.assignStructFieldPaths(styp, path, pkgscope) } } }
// Returns which field index is an embedded storable.Document, or -1 if none. func (p *Processor) processFields(s *types.Struct, done []*types.Struct) (base int, fields []*Field) { c := s.NumFields() base = -1 fields = make([]*Field, 0) for i := 0; i < c; i++ { f := s.Field(i) if !f.Exported() { continue } t := reflect.StructTag(s.Tag(i)) if f.Type().String() == BaseDocument { base = i } field := NewField(f.Name(), f.Type().Underlying().String(), t) field.CheckedNode = f str := p.tryGetStruct(f.Type()) if f.Type().String() != BaseDocument && str != nil { field.Type = getStructType(f.Type()) d := false for _, v := range done { if v == str { d = true break } } if !d { _, subfs := p.processFields(str, append(done, str)) field.SetFields(subfs) } } fields = append(fields, field) } return base, fields }
//iterate over a struct's fields recursively and add its fields to the candidate list func findStructFields(str *types.Struct, prefix string, fset *token.FileSet) []UnexportCandidate { candidates := []UnexportCandidate{} for i := 0; i < str.NumFields(); i++ { field := str.Field(i) if !field.Exported() || field.Anonymous() { continue } // Tags are a likely indicator that this field is used by something // like json or xml that uses reflection. Skip it to be safe. // TODO: override flag? whitelist? if str.Tag(i) != "" { continue } candidate := UnexportCandidate{field.Name(), prefix + "." + field.Name(), fset.Position(field.Pos())} candidates = append(candidates, candidate) if nested, ok := field.Type().(*types.Struct); ok { candidates = append(candidates, findStructFields(nested, candidate.DisplayName, fset)...) } } return candidates }
func Struct(path string, st reflect.StructTag, u *types.Struct, named *types.Named) IObj { rv := IStruct{} rv.name = strings.Split(st.Get("json"), ",")[0] rv.typ = getname(named, u) rv.description = st.Get("description") rv.path = pathAppend(path, rv.name) for i := 0; i < u.NumFields(); i++ { rv2 := dump(rv.path, u.Field(i).Type(), reflect.StructTag(u.Tag(i))) if rv2 == nil { continue } if st, ok := rv2.(IStruct); ok && st.name == "" { for _, j := range st.items { rv.items = append(rv.items, j) } } else { rv.items = append(rv.items, rv2) } } return rv }
func (p *Processor) processFields(s *types.Struct) int { c := s.NumFields() base := -1 fields := make([]*Field, 0) if _, ok := p.fieldsForStr[s]; !ok { p.fieldsForStr[s] = &fields } for i := 0; i < c; i++ { f := s.Field(i) if !f.Exported() { continue } t := reflect.StructTag(s.Tag(i)) if f.Type().String() == BaseDocument { base = i } field := NewField(f.Name(), f.Type().Underlying().String(), t) str := p.tryGetStruct(f.Type()) if f.Type().String() != BaseDocument && str != nil { field.Type = getStructType(f.Type()) field.CheckedNode = f _, ok := p.fieldsForStr[str] if !ok { p.processFields(str) } } fields = append(fields, field) } return base }