Beispiel #1
0
func (en *Encoder) writeStruct(spec *ast.StructType, name string) {
	for _, field := range spec.Fields.List {
		tag := reflect.StructTag("")
		if field.Tag != nil {
			tag = reflect.StructTag(field.Tag.Value[1 : len(field.Tag.Value)-1])
		}

		var c string
		if tag.Get("if") != "" && tag.Get("noreplace") != "true" {
			c = strings.Replace(tag.Get("if"), ".", name+".", -1)
		}

		if c != "" {
			fmt.Fprintf(en.buf, "if %s {\n", c)
		}

		for _, n := range field.Names {
			en.writeType(field.Type, fmt.Sprintf("%s.%s", name, n), tag)
		}

		if c != "" {
			fmt.Fprint(en.buf, "}\n")
		}
	}
}
Beispiel #2
0
func (w *writing) writeStruct(spec *ast.StructType, name string) {
	var lastCondition conditions
	for _, field := range spec.Fields.List {
		tag := reflect.StructTag("")
		if field.Tag != nil {
			tag = reflect.StructTag(field.Tag.Value[1 : len(field.Tag.Value)-1])
		}

		var condition conditions
		if ifTag := tag.Get("if"); ifTag != "" {
			condition = parseCondition(ifTag)
		}

		if !lastCondition.equals(condition) {
			if lastCondition != nil {
				w.buf.WriteString("}\n")
			}
			if condition != nil {
				condition.print(name, &w.buf)
			}
		}
		lastCondition = condition

		for _, n := range field.Names {
			w.writeType(field.Type, fmt.Sprintf("%s.%s", name, n), tag)
		}
	}
	if lastCondition != nil {
		w.buf.WriteString("}\n")
	}
}
Beispiel #3
0
// checkCanonicalFieldTag checks a single struct field tag.
func checkCanonicalFieldTag(f *File, field *ast.Field, seen *map[[2]string]token.Pos) {
	if field.Tag == nil {
		return
	}

	tag, err := strconv.Unquote(field.Tag.Value)
	if err != nil {
		f.Badf(field.Pos(), "unable to read struct tag %s", field.Tag.Value)
		return
	}

	if err := validateStructTag(tag); err != nil {
		raw, _ := strconv.Unquote(field.Tag.Value) // field.Tag.Value is known to be a quoted string
		f.Badf(field.Pos(), "struct field tag %#q not compatible with reflect.StructTag.Get: %s", raw, err)
	}

	for _, key := range checkTagDups {
		val := reflect.StructTag(tag).Get(key)
		if val == "" || val == "-" || val[0] == ',' {
			continue
		}
		if i := strings.Index(val, ","); i >= 0 {
			val = val[:i]
		}
		if *seen == nil {
			*seen = map[[2]string]token.Pos{}
		}
		if pos, ok := (*seen)[[2]string{key, val}]; ok {
			f.Badf(field.Pos(), "struct field %s repeats %s tag %q also at %s", field.Names[0].Name, key, val, f.loc(pos))
		} else {
			(*seen)[[2]string{key, val}] = field.Pos()
		}
	}

	// Check for use of json or xml tags with unexported fields.

	// Embedded struct. Nothing to do for now, but that
	// may change, depending on what happens with issue 7363.
	if len(field.Names) == 0 {
		return
	}

	if field.Names[0].IsExported() {
		return
	}

	for _, enc := range [...]string{"json", "xml"} {
		if reflect.StructTag(tag).Get(enc) != "" {
			f.Badf(field.Pos(), "struct field %s has %s tag but is not exported", field.Names[0].Name, enc)
			return
		}
	}
}
Beispiel #4
0
func typeSchema(title string, t reflect.Type, tag reflect.StructTag) *Value {
	fieldType := fieldType(t, tag)

	isReadOnly := tag.Get("readOnly") != ""

	value := &Value{
		Title:       title,
		Type:        fieldType,
		Required:    isRequired(tag),
		Enum:        enum(tag),
		Description: tag.Get("description"),
		Format:      Format(tag.Get("format")),
		ReadOnly:    isReadOnly,
	}

	switch fieldType {
	case Map:
		value.Title = t.Name()
		value.Format = "tabs"

		// map items
		value.Items = &Value{
			Type:           Object,
			HeaderTemplate: "{{self.key}}",
			Properties: map[string]*Value{
				"key":   typeSchema("key", t.Key(), reflect.StructTag("")),
				"value": typeSchema("value", t.Elem(), reflect.StructTag("")),
			},
		}

		// the enum annotation for maps is for the key not for the map itself
		value.Items.Properties["key"].Enum = enum(tag)
		value.Enum = make([]string, 0)

		// if there is valueEnum then the value is considered enum
		if tag.Get("valueEnum") != "" {
			value.Items.Properties["value"].Enum = strings.Split(tag.Get("valueEnum"), ",")
		} else {
			value.Items.Properties["value"].Enum = make([]string, 0)
		}
	case Array:
		value.Items = typeSchema(t.Name(), t.Elem(), tag)
		value.Items.HeaderTemplate = tag.Get("headerTemplate")
	case ProtoEnum:
		value.Enum = getProtoEnumValues(t)
	case Object:
		value = structSchema(title, t, tag)
	}

	return value
}
Beispiel #5
0
func (this Injector) Apply(target interface{}) {
	elem := reflect.ValueOf(target)
	for elem.Kind() == reflect.Ptr {
		elem = elem.Elem()
	}
	//fmt.Println(elem, elem.Kind())

	if elem.Kind() != reflect.Struct {
		return
	}

	//fmt.Println(elem, elem.NumField())
	t := elem.Type()
	fieldTagMap := make(map[reflect.StructTag]string)
	for i := 0; i < elem.NumField(); i++ {
		structField := t.Field(i)
		//fmt.Println(elem.Field(i).CanSet())
		if elem.Field(i).CanSet() {
			fieldTagMap[structField.Tag] = structField.Name
		}
	}

	for key, value := range this.valueMap {
		for k, v := range fieldTagMap {
			if k == reflect.StructTag(key) {
				elem.FieldByName(v).Set(reflect.ValueOf(value))
				break
			}
		}
	}
}
Beispiel #6
0
func toTable(typeInfo *genbase.TypeInfo) (*Table, error) {
	table := new(Table)
	table.PackageName = typeInfo.FileInfo.Name.Name

	comment := typeInfo.AnnotatedComment.Text
	tableName := strings.TrimPrefix(comment, "//+table: ")
	table.Name = tableName

	table.StructName = typeInfo.Name()

	structType, err := typeInfo.StructType()
	if err != nil {
		return nil, err
	}

	fieldInfos := structType.FieldInfos()
	for _, fieldInfo := range fieldInfos {
		tagText := fieldInfo.Tag.Value[1 : len(fieldInfo.Tag.Value)-1]
		tag := reflect.StructTag(tagText)
		columnInfo := tag.Get("db")
		columnMaps := strings.Split(columnInfo, ",")
		columnName := columnMaps[0]
		isPk := false
		for _, cm := range columnMaps {
			if cm == "primarykey" {
				isPk = true
				break
			}
		}
		column := Column{FieldInfo: fieldInfo, Name: columnName, IsPk: isPk}
		table.AddColumn(column)
	}

	return table, nil
}
Beispiel #7
0
func getFlag(field reflect.StructField) (ths flagSpec) {
	ftlen := len(field.Tag)
	if ftlen > 0 && string(field.Tag[ftlen-1]) == "!" {
		if ftlen > 1 && string(field.Tag[ftlen-2]) != "\\" {
			field.Tag = field.Tag[:ftlen-1]
			ths.imperitive = true
		} else if ftlen > 2 {
			field.Tag = reflect.StructTag(string(field.Tag[:len(field.Tag)-2]) + "!")
		} else {
			ths.imperitive = true
		}
	}
	parts := strings.Split(string(field.Tag), ";")
	switch useName := true; len(parts) {
	case 3:
		useName = false
		ths.names = strings.Split(parts[2], ",")
		fallthrough
	case 2:
		ths.deflt = parts[1]
		fallthrough
	case 1:
		ths.usage = parts[0]
		fallthrough
	case 0:
		ths.typ = field.Type
		if useName {
			ths.names = append(ths.names, strings.ToLower(field.Name))
		}
	default:
		panic("Too many fields!")
	}
	return
}
Beispiel #8
0
// Creates a new resource
// Receives the object to be mappen in a new Resource
// and receive the field name and field tag as optional arguments
func NewResource(object interface{}, args ...string) *Resource {

	value := reflect.ValueOf(object)

	name := value.Type().Name()
	tag := ""

	// Defining a name as an opitional secound argument
	if len(args) >= 1 {
		name = args[0]
	}

	// Defining a tag as an opitional thrid argument
	if len(args) >= 2 {
		tag = args[1]
	}

	field := reflect.StructField{
		Name:      name,
		Tag:       reflect.StructTag(tag),
		Anonymous: false,
	}

	//log.Printf("field: %#v\n", field)

	return scanStruct(value, field, nil)
}
Beispiel #9
0
// hasOptionalTag returns true if the member has +optional in its comments or
// omitempty in its json tags.
func hasOptionalTag(m *types.Member) bool {
	hasOptionalCommentTag := types.ExtractCommentTags(
		"+", m.CommentLines)[tagOptional] != nil
	hasOptionalJsonTag := strings.Contains(
		reflect.StructTag(m.Tags).Get("json"), "omitempty")
	return hasOptionalCommentTag || hasOptionalJsonTag
}
Beispiel #10
0
func (b *xmlBuilder) buildValue(value reflect.Value, current *XMLNode, tag reflect.StructTag) error {
	value = elemOf(value)
	if !value.IsValid() { // no need to handle zero values
		return nil
	} else if tag.Get("location") != "" { // don't handle non-body location values
		return nil
	}

	t := tag.Get("type")
	if t == "" {
		switch value.Kind() {
		case reflect.Struct:
			t = "structure"
		case reflect.Slice:
			t = "list"
		case reflect.Map:
			t = "map"
		}
	}

	switch t {
	case "structure":
		if field, ok := value.Type().FieldByName("SDKShapeTraits"); ok {
			tag = tag + reflect.StructTag(" ") + field.Tag
		}
		return b.buildStruct(value, current, tag)
	case "list":
		return b.buildList(value, current, tag)
	case "map":
		return b.buildMap(value, current, tag)
	default:
		return b.buildScalar(value, current, tag)
	}
}
Beispiel #11
0
//Takes a value of a struct representing a service.
func registerService(root string, h interface{}) {

	if _, ok := h.(GoRestService); !ok {
		panic(ERROR_INVALID_INTERFACE)
	}

	t := reflect.TypeOf(h)

	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	} else {
		panic(ERROR_INVALID_INTERFACE)
	}

	if t.Kind() == reflect.Struct {
		if field, found := t.FieldByName("RestService"); found {
			temp := strings.Join(strings.Fields(string(field.Tag)), " ")
			meta := prepServiceMetaData(root, reflect.StructTag(temp), h, t.Name())
			tFullName := _manager().addType(t.PkgPath()+"/"+t.Name(), meta)
			for i := 0; i < t.NumField(); i++ {
				f := t.Field(i)
				mapFieldsToMethods(t, f, tFullName, meta.root)
			}
		}
		return
	}

	panic(ERROR_INVALID_INTERFACE)
}
Beispiel #12
0
func (si *StructInfo) AddField(field *ast.Field) error {
	if field.Names == nil || len(field.Names) != 1 {
		return errors.New(fmt.Sprintf("Field contains no name: %v", field))
	}

	jsonName := field.Names[0].Name

	opts := tagOptions("")
	if field.Tag != nil {
		var tagName string
		// the Tag.Value contains wrapping `` which we slice off here. We hope.
		v := tagRe.ReplaceAllString(field.Tag.Value, "$1")
		tag := reflect.StructTag(v).Get("json")
		tagName, opts = parseTag(tag)
		if tagName != "" {
			jsonName = tagName
		}
	}

	si.Fields = append(si.Fields, StructField{
		Name:        field.Names[0].Name,
		JsonName:    jsonName,
		OmitEmpty:   opts.Contains("omitempty"),
		ForceString: opts.Contains("string"),
	})
	return nil
}
Beispiel #13
0
// ExtractArgs parses the arguments out of a template invocation, using
// the invoking fields tags.
func ExtractArgs(ctx *Context, stp *ast.StructType, name string) ([]string, error) {
	var found *ast.Field

	for _, f := range stp.Fields.List {
		fname, err := nameFromFieldType(ctx, f.Type)
		if err != nil {
			return nil, err
		}

		if name == fname {
			found = f
		}
	}

	if found == nil {
		return nil, errors.New("Couldn't find template invocation: " + name)
	}

	if found.Tag == nil {
		return nil, nil
	}

	tag := reflect.StructTag(found.Tag.Value[1 : len(found.Tag.Value)-1])

	return strings.Split(tag.Get("template"), ","), nil
}
Beispiel #14
0
func parseStruct(fset *token.FileSet, s *ast.StructType) *Struct {
	parsedStruct := &Struct{}
	if s.Fields.List != nil {
		parsedStruct.Fields = make([]StructField, 0, len(s.Fields.List))
	}
	for _, field := range s.Fields.List {
		parsedField := StructField{}
		for i, name := range field.Names {
			parsedField.Name += name.Name
			if i != len(field.Names)-1 {
				parsedField.Name += ", "
			}
		}
		parsedField.Doc = parseComments(field.Doc)
		parsedField.Comments = parseComments(field.Comment)
		if field.Tag != nil {
			raw := field.Tag.Value
			parsedField.RawTag = raw
			if len(raw) >= 2 {
				// Strip leading/trailing back-ticks:
				parsedField.Tag = reflect.StructTag(raw[1 : len(raw)-1])
			}
		}
		parsedField.Type = formatTypeExpr(fset, field.Type)
		parsedField.StructType = parseEmbeddedStructType(fset, field.Type)
		parsedStruct.Fields = append(parsedStruct.Fields, parsedField)
	}
	return parsedStruct
}
func getJsonTags(m *types.Member) []string {
	jsonTag := reflect.StructTag(m.Tags).Get("json")
	if jsonTag == "" {
		return []string{}
	}
	return strings.Split(jsonTag, ",")
}
Beispiel #16
0
// Parse value from string and return position after parsing and error.
// This function parses value using PEG parser.
// Here: result is pointer to value,
// str is string to parse,
// params is parsing parameters.
// Function returns newLocation - location after the parsed string. On errors err != nil.
func Parse(result interface{}, str []byte, params *Options) (newLocation int, err error) {
	typeOf := reflect.TypeOf(result)
	valueOf := reflect.ValueOf(result)

	if typeOf.Kind() != reflect.Ptr {
		return -1, errors.New("Invalid argument for Parse: waiting for pointer")
	}

	if params == nil {
		params = &Options{SkipWhite: SkipSpaces}
	}

	p, err := compile(typeOf.Elem(), reflect.StructTag(""))
	if err != nil {
		return -1, err
	}

	C := new(parseContext)
	C.params = params
	C.str = str
	C.packrat = make(map[packratKey]*packratValue)
	C.recursiveLocations = make(map[int]bool)

	e := Error{str, 0, ""}
	newLocation = C.parse(valueOf.Elem(), p, 0, &e)
	if newLocation < 0 {
		return newLocation, e
	}

	return newLocation, nil
}
Beispiel #17
0
func (p Parser) parseStruct(spec *ast.StructType, attrs *Attrs) (err error) {
	defer nonTypeEnd(&err)

	for _, f := range spec.Fields.List {
		attrs.S.Type = ""
		attrs.S.Doc = p.parseDoc(f.Doc)

		if f.Type != nil {
			attrs.S.Type = fmt.Sprint(f.Type)
		}

		for _, n := range f.Names {
			attrs.S.Field = n.Name
			attrs.S.Tag = ""

			if f.Tag != nil {
				tag, _ := strings2.TrimQuote(f.Tag.Value)
				attrs.S.Tag = reflect.StructTag(tag)
			}

			if err = p.Struct(attrs); err != nil {
				return
			}
		}
	}

	if len(spec.Fields.List) == 0 {
		p.Struct(attrs)
	}

	return
}
Beispiel #18
0
// getJSONTags returns the JSON tags on a field.
func getJSONTags(field *ast.Field) []string {
	var tag string
	if field.Tag != nil {
		tag = field.Tag.Value[1 : len(field.Tag.Value)-1]
		tag = reflect.StructTag(tag).Get("json")
	}
	return strings.Split(tag, ",")
}
Beispiel #19
0
// Copy from the method Get() from reflect.StructTag. But it returns all the
// tags defined in the fields by the order that they appear, not the value of
// the specific tag.
//
// The type of the argument tag must be eithor string or reflect.StructTag.
// Or panic.
func GetAllTags(t interface{}) []TV {
	var tag reflect.StructTag
	if _tag, ok := t.(reflect.StructTag); ok {
		tag = _tag
	} else if _tag, ok := t.(string); ok {
		tag = reflect.StructTag(_tag)
	} else {
		panic("The type of the argument must be eithor string or reflect.StructTag")
	}

	_tags := make([]TV, 0)
	for tag != "" {
		// Skip leading space.
		i := 0
		for i < len(tag) && tag[i] == ' ' {
			i++
		}
		tag = tag[i:]
		if tag == "" {
			break
		}

		// Scan to colon. A space, a quote or a control character is a syntax error.
		// Strictly speaking, control chars include the range [0x7f, 0x9f], not just
		// [0x00, 0x1f], but in practice, we ignore the multi-byte control characters
		// as it is simpler to inspect the tag's bytes than the tag's runes.
		i = 0
		for i < len(tag) && tag[i] > ' ' && tag[i] != ':' && tag[i] != '"' && tag[i] != 0x7f {
			i++
		}
		if i == 0 || i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
			break
		}
		name := string(tag[:i])
		tag = tag[i+1:]

		// Scan quoted string to find value.
		i = 1
		for i < len(tag) && tag[i] != '"' {
			if tag[i] == '\\' {
				i++
			}
			i++
		}
		if i >= len(tag) {
			break
		}
		qvalue := string(tag[:i+1])
		tag = tag[i+1:]

		if value, err := strconv.Unquote(qvalue); err == nil {
			if strings.TrimSpace(value) != "" {
				_tags = append(_tags, TV{Tag: name, Value: value})
			}
		}
	}
	return _tags
}
func ParseStructFileContent(content string) (sdList []StructDescription, prop Property) {
	var structFirstLineRegex *regexp.Regexp
	structFirstLineRegex, _ = regexp.Compile("^type ([A-Za-z0-9_]+) struct[ \t]?{")
	var isStartingParseStruct bool
	var sd StructDescription

	content = strings.Replace(content, "\r", "", -1) //
	lines := strings.Split(content, "\n")
	lines = removeEmptyLineAndCommentLine(lines)
	for _, line := range lines {
		if prop.PackageName == "" {
			idx := strings.Index(line, "package ")
			if idx == 0 {
				prop.PackageName = strings.TrimSpace(line[len("package ")+idx:])
			}
			continue
		}
		line = removeCommentPart(line)
		if !isStartingParseStruct {
			matched := structFirstLineRegex.FindStringSubmatch(line)
			if len(matched) >= 2 {
				sd.Reset()
				sd.StructName = matched[1]
				isStartingParseStruct = true
			}
			continue
		}
		if line == "}" { // 解析完一个struct
			isStartingParseStruct = false
			if sd.StructName != "" && len(sd.Fields) != 0 {
				sdList = append(sdList, sd)
				sd.Reset()
			}

			continue
		}
		if isStartingParseStruct { // 在解析field 中
			fd := FieldDescriptoin{}
			tagStartIdx := strings.Index(line, "`")
			tagEndIdx := strings.LastIndex(line, "`")
			if tagStartIdx != -1 && tagEndIdx != -1 && tagEndIdx != tagStartIdx {
				fd.TagString = line[tagStartIdx+1 : tagEndIdx]
				fd.MysqlTagFieldList = parseTag(reflect.StructTag(fd.TagString).Get("mysql"))
				line = line[:tagStartIdx]
			}
			tokens := strings.Fields(line)
			if len(tokens) < 2 {
				continue
			}
			fd.FieldName = tokens[0]
			fd.FieldGoType = tokens[1]
			sd.Fields = append(sd.Fields, fd)
		}

	}

	return
}
Beispiel #21
0
func (b *BuildSource) parseField(st *BuildStruct, typeInfo *genbase.TypeInfo, fieldInfo *genbase.FieldInfo, name string) error {
	field := &BuildField{
		parent:    st,
		fieldInfo: fieldInfo,
		Name:      name,
	}
	st.Fields = append(st.Fields, field)

	tag := &BuildTag{
		field: field,
		Name:  name,
	}
	field.Tag = tag

	if fieldInfo.Tag != nil {
		// remove back quote
		tagBody := fieldInfo.Tag.Value[1 : len(fieldInfo.Tag.Value)-1]
		structTag := reflect.StructTag(tagBody)

		searchTag := structTag.Get("search")
		if searchTag == "-" {
			tag.Ignore = true
		} else if idx := strings.Index(searchTag, ","); idx == -1 {
			// nothing to do
		} else {
			for idx != -1 || searchTag != "" {
				value := searchTag
				if idx != -1 {
					value = searchTag[:idx]
					searchTag = searchTag[idx+1:]
				} else {
					searchTag = searchTag[len(value):]
				}
				idx = strings.Index(searchTag, ",")

				switch value {
				case "id":
					tag.ID = true
				case "ngram":
					tag.Ngram = true
				case "json":
					tag.JSON = true
				case "rank":
					tag.Rank = true
				case "string":
					tag.String = true
				case "unixtime":
					tag.UnixTime = true
				}
			}
		}
	}

	return nil
}
Beispiel #22
0
// assignGoTypeToProtoPackage looks for Go and Protobuf types that are referenced by a type in
// a package. It will not recurse into protobuf types.
func assignGoTypeToProtoPackage(p *protobufPackage, t *types.Type, local, global typeNameSet, optional map[types.Name]struct{}) {
	newT, isProto := isFundamentalProtoType(t)
	if isProto {
		t = newT
	}
	if otherP, ok := global[t.Name]; ok {
		if _, ok := local[t.Name]; !ok {
			p.Imports.AddType(&types.Type{
				Kind: types.Protobuf,
				Name: otherP.ProtoTypeName(),
			})
		}
		return
	}
	global[t.Name] = p
	if _, ok := local[t.Name]; ok {
		return
	}
	// don't recurse into existing proto types
	if isProto {
		p.Imports.AddType(t)
		return
	}

	local[t.Name] = p
	for _, m := range t.Members {
		if namer.IsPrivateGoName(m.Name) {
			continue
		}
		field := &protoField{}
		tag := reflect.StructTag(m.Tags).Get("protobuf")
		if tag == "-" {
			continue
		}
		if err := protobufTagToField(tag, field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
			assignGoTypeToProtoPackage(p, field.Type, local, global, optional)
			continue
		}
		assignGoTypeToProtoPackage(p, m.Type, local, global, optional)
	}
	// TODO: should methods be walked?
	if t.Elem != nil {
		assignGoTypeToProtoPackage(p, t.Elem, local, global, optional)
	}
	if t.Key != nil {
		assignGoTypeToProtoPackage(p, t.Key, local, global, optional)
	}
	if t.Underlying != nil {
		if t.Kind == types.Alias && isOptionalAlias(t) {
			optional[t.Name] = struct{}{}
		}
		assignGoTypeToProtoPackage(p, t.Underlying, local, global, optional)
	}
}
Beispiel #23
0
// Write encoded value into output stream.
func Write(out io.Writer, value interface{}) error {
	valueOf := reflect.ValueOf(value)
	typeOf := valueOf.Type()

	p, err := compile(typeOf, reflect.StructTag(""))
	if err != nil {
		return err
	}

	return p.WriteValue(out, valueOf)
}
Beispiel #24
0
func structProperties(structType *ast.StructType) (props []PropertyDocs, err error) {
	for _, f := range structType.Fields.List {
		names := f.Names
		if names == nil {
			// Anonymous fields have no name, use the type as the name
			// TODO: hide the name and make the properties show up in the embedding struct
			if t, ok := f.Type.(*ast.Ident); ok {
				names = append(names, t)
			}
		}
		for _, n := range names {
			var name, typ, tag, text string
			var innerProps []PropertyDocs
			if n != nil {
				name = proptools.PropertyNameForField(n.Name)
			}
			if f.Doc != nil {
				text = f.Doc.Text()
			}
			if f.Tag != nil {
				tag, err = strconv.Unquote(f.Tag.Value)
				if err != nil {
					return nil, err
				}
			}
			switch a := f.Type.(type) {
			case *ast.ArrayType:
				typ = "list of strings"
			case *ast.InterfaceType:
				typ = "interface"
			case *ast.Ident:
				typ = a.Name
			case *ast.StructType:
				innerProps, err = structProperties(a)
				if err != nil {
					return nil, err
				}
			default:
				typ = fmt.Sprintf("%T", f.Type)
			}

			props = append(props, PropertyDocs{
				Name:       name,
				Type:       typ,
				Tag:        reflect.StructTag(tag),
				Text:       text,
				Properties: innerProps,
			})
		}
	}

	return props, nil
}
Beispiel #25
0
func fieldNameFor(name string, tag string) string {
	st := reflect.StructTag(tag)
	yaml := st.Get("yaml")
	if len(yaml) > 0 {
		return strings.SplitN(yaml, ",", 2)[0]
	}
	json := st.Get("json")
	if len(json) > 0 {
		return strings.SplitN(json, ",", 2)[0]
	}
	return name
}
Beispiel #26
0
func (s *ProcessorSuite) TestTags(c *C) {
	fixtureSrc := `
	package fixture

	import 	"gopkg.in/src-d/storable.v1"

	type Foo struct {
		storable.Document
		Int int "foo"
	}
	`

	pkg := s.processFixture(fixtureSrc)
	c.Assert(pkg.Models[0].Fields[1].Tag, Equals, reflect.StructTag("foo"))
}
Beispiel #27
0
func isGenProcField(f *ast.Field) bool {
	if f.Tag == nil {
		return false
	}
	t, err := strconv.Unquote(f.Tag.Value)
	if err != nil {
		fmt.Fprintf(os.Stderr, "parsing tag %s: %v", f.Tag.Value, err)
		os.Exit(1)
	}
	procspec := reflect.StructTag(t).Get("gen_proc")
	if procspec == "" {
		return false
	}
	split := strings.Split(procspec, ",")
	return split[0] == "gen_server"
}
Beispiel #28
0
//
//
// Parse the tags
//
//
func sqlTags(typeName string, fields *ast.FieldList) *SQLInfo {
	info := SQLInfo{}
	info.Fields = make(map[string]string) // [memberName]sqlName
	info.NoUpdate = make(map[string]struct{})
	good := false
	for _, field := range fields.List {
		if t := field.Tag; t != nil {
			s := string(t.Value)
			// the code uses backticks to metaquote, need to strip them whilst evaluating
			tag := reflect.StructTag(s[1 : len(s)-1])
			if sql := tag.Get("sql"); len(sql) > 0 {
				//fmt.Println("SQL:", sql)
				if table := tag.Get("table"); len(table) > 0 {
					info.Table = table
				}
				if key := tag.Get("key"); len(key) > 0 {
					info.KeyName = string(field.Names[0].Name)
					info.KeyField = sql
				} else {
					info.Fields[field.Names[0].Name] = sql
				}
				good = true
			}
			if audit := tag.Get("audit"); len(audit) > 0 {
				//fmt.Println("AUDIT:", audit, "N:", string(field.Names[0].Name))
				switch {
				case audit == "user":
					info.UserField = string(field.Names[0].Name)
				case audit == "time":
					info.TimeField = string(field.Names[0].Name)
				}
			}
			if update := tag.Get("update"); len(update) > 0 {
				if up, err := strconv.ParseBool(update); err == nil && up == false {
					//if _, err := strconv.ParseBool(update); err == nil {
					//fmt.Println("NO UPDATE:", field.Names[0].Name)
					info.NoUpdate[field.Names[0].Name] = struct{}{}
				}
			}
		}
	}
	if good {
		return &info
	}
	return nil
}
func TestGetMemberNameFromTag(t *testing.T) {
	tags := map[string]string{
		`bson:"membername,omitempty"`:  "membername",
		`bson:",omitempty"`:            "",
		"membername,omitempty,minsize": "membername",
		"membername":                   "membername",
		",minsize":                     "",
		`json:"name" binding:"required" validate:"nonzero"`: "",
	}

	for tag, name := range tags {
		m := getFieldNameFromTag(reflect.StructTag(tag))
		if m != name {
			t.Errorf("wrong membername detected: '%s'", m)
		}
	}
}
Beispiel #30
0
func structProperties(structType *ast.StructType) (props []PropertyDocs, err error) {
	for _, f := range structType.Fields.List {
		//fmt.Printf("%T %#v\n", f, f)
		for _, n := range f.Names {
			var name, typ, tag, text string
			var innerProps []PropertyDocs
			if n != nil {
				name = proptools.PropertyNameForField(n.Name)
			}
			if f.Doc != nil {
				text = f.Doc.Text()
			}
			if f.Tag != nil {
				tag, err = strconv.Unquote(f.Tag.Value)
				if err != nil {
					return nil, err
				}
			}
			switch a := f.Type.(type) {
			case *ast.ArrayType:
				typ = "list of strings"
			case *ast.InterfaceType:
				typ = "interface"
			case *ast.Ident:
				typ = a.Name
			case *ast.StructType:
				innerProps, err = structProperties(a)
				if err != nil {
					return nil, err
				}
			default:
				typ = fmt.Sprintf("%T", f.Type)
			}

			props = append(props, PropertyDocs{
				Name:       name,
				Type:       typ,
				Tag:        reflect.StructTag(tag),
				Text:       text,
				Properties: innerProps,
			})
		}
	}

	return props, nil
}