Exemplo n.º 1
0
// ParseStruct will create a structure
// with parameters given and return it
func ParseStruct(spec *ast.TypeSpec, parent *ast.StructType, comments ast.CommentMap) *Structure {
	fMap := make(map[string]*StructField)
	for _, field := range parent.Fields.List {
		if len(field.Names) == 0 {
			continue
		}
		fMap[field.Names[0].Name] = ParseStructField(field, comments.Filter(field))
	}

	s := NewStructure(parent, spec, fMap, ParseTags(comments))

	return s
}
Exemplo n.º 2
0
// ParseFileAST creates a File parse with all necessary
// structures.
func ParseFileAST(name string, tree *ast.File, commentMap ast.CommentMap) (*File, error) {
	f := NewFile(name, tree)

	for _, i := range tree.Imports {
		f.AddImport(ParseImport(i, commentMap.Filter(i)))
	}

	for _, declaration := range tree.Decls {
		switch decValue := declaration.(type) {
		// catch only generic declarations
		case *ast.GenDecl:
			for _, spec := range decValue.Specs {
				switch specValue := spec.(type) {
				case *ast.TypeSpec:
					// all cases should pass in also specValue as
					// it is the underlying spec
					switch typeValue := specValue.Type.(type) {
					case *ast.StructType:
						f.AddStruct(ParseStruct(specValue, typeValue, commentMap.Filter(declaration)))
					case *ast.InterfaceType:
						f.AddInterface(ParseInterface(specValue, typeValue, commentMap.Filter(declaration)))
					}
				case *ast.ImportSpec:
					// just ignore for now
				case *ast.ValueSpec:
					f.AddConstant(ParseConstant(specValue, commentMap.Filter(declaration)))
				default:
					fmt.Println("Generic value not recognized: ", specValue)
				}
			}
		// catch function declarations
		case *ast.FuncDecl:
			fun := ParseFunction(decValue, commentMap.Filter(declaration))
			if !fun.IsMethod() {
				// add the function to the top level map
				f.AddFunction(fun)
			} else {
				// add the function to the structure it belongs to
				if len(fun.parent.Recv.List) <= 0 {
					// TODO: no receiver defined report?
					break
				}

				// struct that should be assigned the method
				var structType *ast.StructType

				switch receiver := fun.parent.Recv.List[0].Type.(type) {
				// pointer receiver
				case *ast.StarExpr:
					structType = receiver.X.(*ast.Ident).Obj.Decl.(*ast.TypeSpec).Type.(*ast.StructType)
				// copy receiver
				case *ast.Ident:
					structType = receiver.Obj.Decl.(*ast.TypeSpec).Type.(*ast.StructType)
				}

				// search for the structures that receive the method
				// and bind it
				for _, st := range f.structures {
					if st.parent == structType {
						st.AddMethod(fun)
					}
				}
			}
		}
	}

	return f, nil
}