func ascg(txt string) *ast.CommentGroup { var cg ast.CommentGroup for _, line := range strings.Split(txt, "\n") { var cmt ast.Comment cmt.Text = "// " + line cg.List = append(cg.List, &cmt) } return &cg }
func determineFuncType(cg *ast.CommentGroup) FuncType { if cg == nil { return ChainFunc } for i, l := range cg.List { s := strings.TrimSpace(strings.TrimLeft(l.Text, "/")) if s == tickProperty { cg.List = append(cg.List[:i], cg.List[i+1:]...) return PropertyFunc } } return ChainFunc }
// Decl generates Go source for a Func. an error is returned if the // body, or parameters cannot be parsed. func (fn *Function) Decl() (*ast.FuncDecl, error) { var err error var comments *ast.CommentGroup if fn.name == "" { return nil, errors.New("function name unset") } if len(fn.body) == 0 { return nil, fmt.Errorf("function body for %s unset") } if fn.godoc != "" { comments = &ast.CommentGroup{List: []*ast.Comment{}} for _, line := range strings.Split(fn.godoc, "\n") { comments.List = append(comments.List, &ast.Comment{Text: line}) } } fl := func(args ...string) (list *ast.FieldList) { if len(args) == 0 || len(args[0]) == 0 || err != nil { return nil } list, err = FieldList(args...) return list } args := fl(fn.args...) returns := fl(fn.returns...) receiver := fl(fn.receiver) if err != nil { return nil, err } body, err := parseBlock(fn.body) if err != nil { return nil, fmt.Errorf("could not parse function body of %s: %v", fn.name, err) } return &ast.FuncDecl{ Doc: comments, Recv: receiver, Name: ast.NewIdent(fn.name), Type: &ast.FuncType{ Params: args, Results: returns, }, Body: body, }, nil }
func (rp *routesParser) Parse(gofile *ast.File, target interface{}) error { tgt := target.(*spec.Paths) for _, comsec := range gofile.Comments { // check if this is a route comment section var method, path, id string var tags []string var remaining *ast.CommentGroup var justMatched bool for _, cmt := range comsec.List { for _, line := range strings.Split(cmt.Text, "\n") { matches := rxRoute.FindStringSubmatch(line) if len(matches) > 3 && len(matches[3]) > 0 { method, path, id = matches[1], matches[2], matches[len(matches)-1] tags = rxSpace.Split(matches[3], -1) justMatched = true } else if method != "" { if remaining == nil { remaining = new(ast.CommentGroup) } if !justMatched || strings.TrimSpace(rxStripComments.ReplaceAllString(line, "")) != "" { cc := new(ast.Comment) cc.Slash = cmt.Slash cc.Text = line remaining.List = append(remaining.List, cc) justMatched = false } } } } if method == "" { continue // it's not, next! } pthObj := tgt.Paths[path] op := rp.operations[id] if op == nil { op = new(spec.Operation) op.ID = id } switch strings.ToUpper(method) { case "GET": if pthObj.Get != nil { if id == pthObj.Get.ID { op = pthObj.Get } else { pthObj.Get = op } } else { pthObj.Get = op } case "POST": if pthObj.Post != nil { if id == pthObj.Post.ID { op = pthObj.Post } else { pthObj.Post = op } } else { pthObj.Post = op } case "PUT": if pthObj.Put != nil { if id == pthObj.Put.ID { op = pthObj.Put } else { pthObj.Put = op } } else { pthObj.Put = op } case "PATCH": if pthObj.Patch != nil { if id == pthObj.Patch.ID { op = pthObj.Patch } else { pthObj.Patch = op } } else { pthObj.Patch = op } case "HEAD": if pthObj.Head != nil { if id == pthObj.Head.ID { op = pthObj.Head } else { pthObj.Head = op } } else { pthObj.Head = op } case "DELETE": if pthObj.Delete != nil { if id == pthObj.Delete.ID { op = pthObj.Delete } else { pthObj.Delete = op } } else { pthObj.Delete = op } case "OPTIONS": if pthObj.Options != nil { if id == pthObj.Options.ID { op = pthObj.Options } else { pthObj.Options = op } } else { pthObj.Options = op } } op.Tags = tags sp := new(sectionedParser) sp.setTitle = func(lines []string) { op.Summary = joinDropLast(lines) } sp.setDescription = func(lines []string) { op.Description = joinDropLast(lines) } sr := newSetResponses(rp.definitions, rp.responses, opResponsesSetter(op)) sp.taggers = []tagParser{ newMultiLineTagParser("Consumes", newMultilineDropEmptyParser(rxConsumes, opConsumesSetter(op))), newMultiLineTagParser("Produces", newMultilineDropEmptyParser(rxProduces, opProducesSetter(op))), newSingleLineTagParser("Schemes", newSetSchemes(opSchemeSetter(op))), newMultiLineTagParser("Security", newSetSecurityDefinitions(rxSecuritySchemes, opSecurityDefsSetter(op))), newMultiLineTagParser("Responses", sr), } if err := sp.Parse(remaining); err != nil { return fmt.Errorf("operation (%s): %v", op.ID, err) } if tgt.Paths == nil { tgt.Paths = make(map[string]spec.PathItem) } tgt.Paths[path] = pthObj } return nil }