@@ -127,6 +127,11 @@ func run() error {
127127 if err != nil {
128128 return fmt .Errorf ("error while parsing internal files: %v" , err )
129129 }
130+
131+ err = checkInternalDocs (path , file , publicToInternal )
132+ if err != nil {
133+ return fmt .Errorf ("error while checking internal docs: %v" , err )
134+ }
130135 }
131136 return nil
132137 })
@@ -587,3 +592,84 @@ func isValidDefinitionWithMatch(line, private string, inGroup string, insideStru
587592 }
588593 return false
589594}
595+
596+ func checkInternalDocs (path string , file * os.File , pairs map [string ]map [string ]string ) error {
597+ fs := token .NewFileSet ()
598+
599+ // Reset file pointer to start
600+ _ , err := file .Seek (0 , 0 )
601+ if err != nil {
602+ return fmt .Errorf ("failed to seek: %v" , err )
603+ }
604+
605+ node , err := parser .ParseFile (fs , path , file , parser .ParseComments )
606+ if err != nil {
607+ return fmt .Errorf ("failed to parse file %s: %v" , path , err )
608+ }
609+
610+ exposedTypes := make (map [string ]bool )
611+ for _ , pair := range pairs {
612+ for _ , private := range pair {
613+ exposedTypes [private ] = true
614+ }
615+ }
616+
617+ ast .Inspect (node , func (n ast.Node ) bool {
618+ if genDecl , ok := n .(* ast.GenDecl ); ok && genDecl .Tok == token .TYPE {
619+ for _ , spec := range genDecl .Specs {
620+ if typeSpec , ok := spec .(* ast.TypeSpec ); ok {
621+ if ! exposedTypes [typeSpec .Name .Name ] {
622+ continue
623+ }
624+ if structType , ok := typeSpec .Type .(* ast.StructType ); ok {
625+ for _ , field := range structType .Fields .List {
626+ isExported := false
627+ var fieldName string
628+ if len (field .Names ) > 0 {
629+ for _ , name := range field .Names {
630+ if ast .IsExported (name .Name ) {
631+ isExported = true
632+ fieldName = name .Name
633+ break
634+ }
635+ }
636+ } else {
637+ // Check anonymous field
638+ if ident , ok := field .Type .(* ast.Ident ); ok {
639+ if ast .IsExported (ident .Name ) {
640+ isExported = true
641+ fieldName = ident .Name
642+ }
643+ } else if sel , ok := field .Type .(* ast.SelectorExpr ); ok {
644+ if ast .IsExported (sel .Sel .Name ) {
645+ isExported = true
646+ fieldName = sel .Sel .Name
647+ }
648+ } else if star , ok := field .Type .(* ast.StarExpr ); ok {
649+ if ident , ok := star .X .(* ast.Ident ); ok {
650+ if ast .IsExported (ident .Name ) {
651+ isExported = true
652+ fieldName = ident .Name
653+ }
654+ } else if sel , ok := star .X .(* ast.SelectorExpr ); ok {
655+ if ast .IsExported (sel .Sel .Name ) {
656+ isExported = true
657+ fieldName = sel .Sel .Name
658+ }
659+ }
660+ }
661+ }
662+
663+ if isExported && field .Doc == nil && field .Comment == nil {
664+ changesNeeded = true
665+ fmt .Printf ("Missing doc for exposed struct %s field %s in %s\n " , typeSpec .Name .Name , fieldName , path )
666+ }
667+ }
668+ }
669+ }
670+ }
671+ }
672+ return true
673+ })
674+ return nil
675+ }
0 commit comments