예제 #1
0
func packageFromInfo(prog *loader.Program, pkgInfo *loader.PackageInfo) *Package {
	files := map[string]*ast.File{}
	for _, f := range pkgInfo.Files {
		files[prog.Fset.File(f.Pos()).Name()] = f
	}

	// Ignore (perhaps) "unresolved identifier" errors
	astPkg, _ := ast.NewPackage(prog.Fset, files, nil, nil)

	var mode doc.Mode
	docPkg := doc.New(astPkg, pkgInfo.String(), mode)

	return NewPackage(prog.Fset, docPkg, pkgInfo.Pkg)
}
예제 #2
0
func findSourceFile(pkg *loader.PackageInfo, typeName string) (*ast.File, *ast.GenDecl, *ast.TypeSpec, error) {
	for _, file := range pkg.Files {
		for _, decl := range file.Decls {
			if gd, ok := decl.(*ast.GenDecl); ok {
				for _, gs := range gd.Specs {
					if ts, ok := gs.(*ast.TypeSpec); ok {
						strfmtNme, isStrfmt := strfmtName(gd.Doc)
						if (isStrfmt && strfmtNme == typeName) || ts.Name != nil && ts.Name.Name == typeName {
							return file, gd, ts, nil
						}
					}
				}
			}
		}
	}
	return nil, nil, nil, fmt.Errorf("unable to find %s in %s", typeName, pkg.String())
}
예제 #3
0
파일: schema.go 프로젝트: xiwenc/go-swagger
func (scp *schemaParser) parseIdentProperty(pkg *loader.PackageInfo, expr *ast.Ident, prop swaggerTypable) error {
	// find the file this selector points to
	file, gd, ts, err := findSourceFile(pkg, expr.Name)
	if err != nil {
		err := swaggerSchemaForType(expr.Name, prop)
		if err != nil {
			return fmt.Errorf("package %s, error is: %v", pkg.String(), err)
		}
		return nil
	}
	if at, ok := ts.Type.(*ast.ArrayType); ok {
		// the swagger spec defines strfmt base64 as []byte.
		// in that case we don't actually want to turn it into an array
		// but we want to turn it into a string
		if _, ok := at.Elt.(*ast.Ident); ok {
			if strfmtName, ok := strfmtName(gd.Doc); ok {
				prop.Typed("string", strfmtName)
				return nil
			}
		}
		// this is a selector, so most likely not base64
		if strfmtName, ok := strfmtName(gd.Doc); ok {
			prop.Items().Typed("string", strfmtName)
			return nil
		}
	}

	// look at doc comments for swagger:strfmt [name]
	// when found this is the format name, create a schema with that name
	if strfmtName, ok := strfmtName(gd.Doc); ok {
		prop.Typed("string", strfmtName)
		return nil
	}
	switch tpe := ts.Type.(type) {
	case *ast.ArrayType:
		switch atpe := tpe.Elt.(type) {
		case *ast.Ident:
			return scp.parseIdentProperty(pkg, atpe, prop.Items())
		case *ast.SelectorExpr:
			return scp.typeForSelector(file, atpe, prop.Items())
		case *ast.StarExpr:
			return parseProperty(scp, file, atpe.X, prop.Items())
		default:
			return fmt.Errorf("unknown selector type: %#v", atpe)
		}
	case *ast.StructType:
		sd := newSchemaDecl(file, gd, ts)
		sd.inferNames()
		ref, err := spec.NewRef("#/definitions/" + sd.Name)
		if err != nil {
			return err
		}
		prop.SetRef(ref)
		scp.postDecls = append(scp.postDecls, *sd)
		return nil

	case *ast.Ident:
		return scp.parseIdentProperty(pkg, tpe, prop)

	case *ast.SelectorExpr:
		return scp.typeForSelector(file, tpe, prop)

	case *ast.InterfaceType:
		sd := newSchemaDecl(file, gd, ts)
		sd.inferNames()
		ref, err := spec.NewRef("#/definitions/" + sd.Name)
		if err != nil {
			return err
		}
		prop.SetRef(ref)
		scp.postDecls = append(scp.postDecls, *sd)
		return nil

	default:
		err := swaggerSchemaForType(expr.Name, prop)
		if err != nil {
			return fmt.Errorf("package %s, error is: %v", pkg.String(), err)
		}
		return nil
	}

}