Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
// 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
}
Пример #4
0
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
}