| 31 | } |
| 32 | |
| 33 | func processFile(packageName string, pkg *packages.Package, file *ast.File, m map[string]string) { |
| 34 | var lastComment string |
| 35 | var typ string |
| 36 | ast.Inspect(file, func(n ast.Node) bool { |
| 37 | switch x := n.(type) { |
| 38 | case *ast.TypeSpec: |
| 39 | typ = x.Name.String() |
| 40 | if !ast.IsExported(typ) { |
| 41 | break |
| 42 | } |
| 43 | typeID := fmt.Sprintf("%s.%s", packageName, typ) |
| 44 | if lastComment != "" { |
| 45 | m[typeID] = lastComment |
| 46 | } |
| 47 | case *ast.GenDecl: |
| 48 | lastComment = strings.TrimSpace(x.Doc.Text()) |
| 49 | case *ast.ValueSpec: |
| 50 | // Get comments on constants, since they may appear in string and integer enums. |
| 51 | for _, name := range x.Names { |
| 52 | c, isConstant := pkg.TypesInfo.ObjectOf(name).(*types.Const) |
| 53 | if !isConstant { |
| 54 | continue |
| 55 | } |
| 56 | typeID := fmt.Sprintf("%s.%s", packageName, c.Name()) |
| 57 | comments := lastComment |
| 58 | if strings.TrimSpace(x.Doc.Text()) != "" { |
| 59 | comments = strings.TrimSpace(x.Doc.Text()) |
| 60 | } |
| 61 | if comments != "" { |
| 62 | m[typeID] = comments |
| 63 | } |
| 64 | } |
| 65 | case *ast.FuncDecl: |
| 66 | // Skip functions, since they can't appear in schema. |
| 67 | return false |
| 68 | case *ast.Field: |
| 69 | if typ == "" { |
| 70 | break |
| 71 | } |
| 72 | if !ast.IsExported(typ) { |
| 73 | break |
| 74 | } |
| 75 | fieldName := getFieldName(x) |
| 76 | if !ast.IsExported(fieldName) { |
| 77 | break |
| 78 | } |
| 79 | typeID := fmt.Sprintf("%s.%s.%s", packageName, typ, fieldName) |
| 80 | comments := strings.TrimSpace(x.Doc.Text()) |
| 81 | if comments != "" { |
| 82 | m[typeID] = comments |
| 83 | } |
| 84 | } |
| 85 | return true |
| 86 | }) |
| 87 | } |
| 88 | |
| 89 | func getFieldName(field *ast.Field) string { |
| 90 | var names []string |