mirror of
				https://github.com/beego/bee.git
				synced 2025-10-31 17:33:26 +00:00 
			
		
		
		
	add support for controller methods with paramaters
- allow automatic mapping of type from method params - generate swagger for parameters not covered by comment annotations
This commit is contained in:
		| @@ -362,11 +362,11 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) { | ||||
| 		pkgRealpath = wg | ||||
| 	} else { | ||||
| 		wgopath := gopaths | ||||
| 		for _, wg := range wgopath { | ||||
| 			wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", pkgpath)) | ||||
| 			if utils.FileExists(wg) { | ||||
| 				pkgRealpath = wg | ||||
| 				break | ||||
| 	for _, wg := range wgopath { | ||||
| 		wg, _ = filepath.EvalSymlinks(filepath.Join(wg, "src", pkgpath)) | ||||
| 		if utils.FileExists(wg) { | ||||
| 			pkgRealpath = wg | ||||
| 			break | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -395,7 +395,7 @@ func analyseControllerPkg(vendorPath, localName, pkgpath string) { | ||||
| 					if specDecl.Recv != nil && len(specDecl.Recv.List) > 0 { | ||||
| 						if t, ok := specDecl.Recv.List[0].Type.(*ast.StarExpr); ok { | ||||
| 							// Parse controller method | ||||
| 							parserComments(specDecl.Doc, specDecl.Name.String(), fmt.Sprint(t.X), pkgpath) | ||||
| 							parserComments(specDecl, fmt.Sprint(t.X), pkgpath) | ||||
| 						} | ||||
| 					} | ||||
| 				case *ast.GenDecl: | ||||
| @@ -448,12 +448,16 @@ func peekNextSplitString(ss string) (s string, spacePos int) { | ||||
| } | ||||
|  | ||||
| // parse the func comments | ||||
| func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpath string) error { | ||||
| func parserComments(f *ast.FuncDecl, controllerName, pkgpath string) error { | ||||
| 	var routerPath string | ||||
| 	var HTTPMethod string | ||||
| 	opts := swagger.Operation{ | ||||
| 		Responses: make(map[string]swagger.Response), | ||||
| 	} | ||||
| 	funcName := f.Name.String() | ||||
| 	comments := f.Doc | ||||
| 	funcParamMap := buildParamMap(f.Type.Params) | ||||
| 	//TODO: resultMap := buildParamMap(f.Type.Results) | ||||
| 	if comments != nil && comments.List != nil { | ||||
| 		for _, c := range comments.List { | ||||
| 			t := strings.TrimSpace(strings.TrimLeft(c.Text, "//")) | ||||
| @@ -526,7 +530,17 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat | ||||
| 				if len(p) < 4 { | ||||
| 					beeLogger.Log.Fatal(controllerName + "_" + funcName + "'s comments @Param should have at least 4 params") | ||||
| 				} | ||||
| 				para.Name = p[0] | ||||
| 				paramNames := strings.SplitN(p[0], "=>", 2) | ||||
| 				para.Name = paramNames[0] | ||||
| 				funcParamName := para.Name | ||||
| 				if len(paramNames) > 1 { | ||||
| 					funcParamName = paramNames[1] | ||||
| 				} | ||||
| 				paramType, ok := funcParamMap[funcParamName] | ||||
| 				if ok { | ||||
| 					delete(funcParamMap, funcParamName) | ||||
| 				} | ||||
|  | ||||
| 				switch p[1] { | ||||
| 				case "query": | ||||
| 					fallthrough | ||||
| @@ -555,33 +569,10 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat | ||||
| 					modelsList[pkgpath+controllerName][typ] = mod | ||||
| 					appendModels(pkgpath, controllerName, realTypes) | ||||
| 				} else { | ||||
| 					isArray := false | ||||
| 					paraType := "" | ||||
| 					paraFormat := "" | ||||
| 					if strings.HasPrefix(typ, "[]") { | ||||
| 						typ = typ[2:] | ||||
| 						isArray = true | ||||
| 					} | ||||
| 					if typ == "string" || typ == "number" || typ == "integer" || typ == "boolean" || | ||||
| 						typ == "array" || typ == "file" { | ||||
| 						paraType = typ | ||||
| 					} else if sType, ok := basicTypes[typ]; ok { | ||||
| 						typeFormat := strings.Split(sType, ":") | ||||
| 						paraType = typeFormat[0] | ||||
| 						paraFormat = typeFormat[1] | ||||
| 					} else { | ||||
| 						beeLogger.Log.Warnf("[%s.%s] Unknown param type: %s\n", controllerName, funcName, typ) | ||||
| 					} | ||||
| 					if isArray { | ||||
| 						para.Type = "array" | ||||
| 						para.Items = &swagger.ParameterItems{ | ||||
| 							Type:   paraType, | ||||
| 							Format: paraFormat, | ||||
| 						} | ||||
| 					} else { | ||||
| 						para.Type = paraType | ||||
| 						para.Format = paraFormat | ||||
| 					if typ == "auto" { | ||||
| 						typ = paramType | ||||
| 					} | ||||
| 					setParamType(¶, typ, pkgpath, controllerName) | ||||
| 				} | ||||
| 				switch len(p) { | ||||
| 				case 5: | ||||
| @@ -636,7 +627,21 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if routerPath != "" { | ||||
| 		//Go over function parameters which were not mapped and create swagger params for them | ||||
| 		for name, typ := range funcParamMap { | ||||
| 			para := swagger.Parameter{} | ||||
| 			para.Name = name | ||||
| 			setParamType(¶, typ, pkgpath, controllerName) | ||||
| 			if paramInPath(name, routerPath) { | ||||
| 				para.In = "path" | ||||
| 			} else { | ||||
| 				para.In = "query" | ||||
| 			} | ||||
| 			opts.Parameters = append(opts.Parameters, para) | ||||
| 		} | ||||
|  | ||||
| 		var item *swagger.Item | ||||
| 		if itemList, ok := controllerList[pkgpath+controllerName]; ok { | ||||
| 			if it, ok := itemList[routerPath]; !ok { | ||||
| @@ -669,6 +674,91 @@ func parserComments(comments *ast.CommentGroup, funcName, controllerName, pkgpat | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func setParamType(para *swagger.Parameter, typ string, pkgpath, controllerName string) { | ||||
| 	isArray := false | ||||
| 	paraType := "" | ||||
| 	paraFormat := "" | ||||
|  | ||||
| 	if strings.HasPrefix(typ, "[]") { | ||||
| 		typ = typ[2:] | ||||
| 		isArray = true | ||||
| 	} | ||||
| 	if typ == "string" || typ == "number" || typ == "integer" || typ == "boolean" || | ||||
| 		typ == "array" || typ == "file" { | ||||
| 		paraType = typ | ||||
| 	} else if sType, ok := basicTypes[typ]; ok { | ||||
| 		typeFormat := strings.Split(sType, ":") | ||||
| 		paraType = typeFormat[0] | ||||
| 		paraFormat = typeFormat[1] | ||||
| 	} else { | ||||
| 		m, mod, realTypes := getModel(typ) | ||||
| 		para.Schema = &swagger.Schema{ | ||||
| 			Ref: "#/definitions/" + m, | ||||
| 		} | ||||
| 		if _, ok := modelsList[pkgpath+controllerName]; !ok { | ||||
| 			modelsList[pkgpath+controllerName] = make(map[string]swagger.Schema) | ||||
| 		} | ||||
| 		modelsList[pkgpath+controllerName][typ] = mod | ||||
| 		appendModels(pkgpath, controllerName, realTypes) | ||||
| 	} | ||||
| 	if isArray { | ||||
| 		para.Type = "array" | ||||
| 		para.Items = &swagger.ParameterItems{ | ||||
| 			Type:   paraType, | ||||
| 			Format: paraFormat, | ||||
| 		} | ||||
| 	} else { | ||||
| 		para.Type = paraType | ||||
| 		para.Format = paraFormat | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| func paramInPath(name, route string) bool { | ||||
| 	return strings.HasSuffix(route, ":"+name) || | ||||
| 		strings.Contains(route, ":"+name+"/") | ||||
| } | ||||
|  | ||||
| func getFunctionParamType(t ast.Expr) string { | ||||
| 	switch paramType := t.(type) { | ||||
| 	case *ast.Ident: | ||||
| 		return paramType.Name | ||||
| 	// case *ast.Ellipsis: | ||||
| 	// 	result := getFunctionParamType(paramType.Elt) | ||||
| 	// 	result.array = true | ||||
| 	// 	return result | ||||
| 	case *ast.ArrayType: | ||||
| 		return "[]" + getFunctionParamType(paramType.Elt) | ||||
| 	case *ast.StarExpr: | ||||
| 		return getFunctionParamType(paramType.X) | ||||
| 	case *ast.SelectorExpr: | ||||
| 		return getFunctionParamType(paramType.X) + "." + paramType.Sel.Name | ||||
| 	default: | ||||
| 		return "" | ||||
|  | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func buildParamMap(list *ast.FieldList) map[string]string { | ||||
| 	i := 0 | ||||
| 	result := map[string]string{} | ||||
| 	if list != nil { | ||||
| 		funcParams := list.List | ||||
| 		for _, fparam := range funcParams { | ||||
| 			param := getFunctionParamType(fparam.Type) | ||||
| 			var paramName string | ||||
| 			if len(fparam.Names) > 0 { | ||||
| 				paramName = fparam.Names[0].Name | ||||
| 			} else { | ||||
| 				paramName = fmt.Sprint(i) | ||||
| 				i++ | ||||
| 			} | ||||
| 			result[paramName] = param | ||||
| 		} | ||||
| 	} | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // analisys params return []string | ||||
| // @Param	query		form	 string	true		"The email for login" | ||||
| // [query form string true "The email for login"] | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 eyalpost
					eyalpost