@@ -48,26 +48,48 @@ const (
48
48
externalTypesTagName = "k8s:conversion-gen-external-types"
49
49
)
50
50
51
- func extractTag (comments []string ) []string {
52
- return gengo .ExtractCommentTags ("+" , comments )[tagName ]
51
+ func extractTagValues (tagName string , comments []string ) ([]string , error ) {
52
+ tags , err := gengo .ExtractFunctionStyleCommentTags ("+" , []string {tagName }, comments )
53
+ if err != nil {
54
+ return nil , err
55
+ }
56
+ tagList , exists := tags [tagName ]
57
+ if ! exists {
58
+ return nil , nil
59
+ }
60
+ values := make ([]string , len (tagList ))
61
+ for i , v := range tagList {
62
+ values [i ] = v .Value
63
+ }
64
+ return values , nil
53
65
}
54
66
55
- func extractExplicitFromTag (comments []string ) []string {
56
- return gengo . ExtractCommentTags ( "+" , comments )[ explicitFromTagName ]
67
+ func extractTag (comments []string ) ( []string , error ) {
68
+ return extractTagValues ( tagName , comments )
57
69
}
58
70
59
- func extractExternalTypesTag (comments []string ) []string {
60
- return gengo . ExtractCommentTags ( "+" , comments )[ externalTypesTagName ]
71
+ func extractExplicitFromTag (comments []string ) ( []string , error ) {
72
+ return extractTagValues ( explicitFromTagName , comments )
61
73
}
62
74
63
- func isCopyOnly (comments []string ) bool {
64
- values := gengo .ExtractCommentTags ("+" , comments )["k8s:conversion-fn" ]
65
- return len (values ) == 1 && values [0 ] == "copy-only"
75
+ func extractExternalTypesTag (comments []string ) ([]string , error ) {
76
+ return extractTagValues (externalTypesTagName , comments )
66
77
}
67
78
68
- func isDrop (comments []string ) bool {
69
- values := gengo .ExtractCommentTags ("+" , comments )["k8s:conversion-fn" ]
70
- return len (values ) == 1 && values [0 ] == "drop"
79
+ func isCopyOnly (comments []string ) (bool , error ) {
80
+ values , err := extractTagValues ("k8s:conversion-fn" , comments )
81
+ if err != nil {
82
+ return false , err
83
+ }
84
+ return len (values ) == 1 && values [0 ] == "copy-only" , nil
85
+ }
86
+
87
+ func isDrop (comments []string ) (bool , error ) {
88
+ values , err := extractTagValues ("k8s:conversion-fn" , comments )
89
+ if err != nil {
90
+ return false , err
91
+ }
92
+ return len (values ) == 1 && values [0 ] == "drop" , nil
71
93
}
72
94
73
95
// TODO: This is created only to reduce number of changes in a single PR.
@@ -229,11 +251,15 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target
229
251
// Only generate conversions for packages which explicitly request it
230
252
// by specifying one or more "+k8s:conversion-gen=<peer-pkg>"
231
253
// in their doc.go file.
232
- peerPkgs := extractTag (pkg .Comments )
254
+ peerPkgs , err := extractTag (pkg .Comments )
233
255
if peerPkgs == nil {
234
256
klog .V (3 ).Infof (" no tag" )
235
257
continue
236
258
}
259
+ if err != nil {
260
+ klog .Errorf ("failed to extract tag %s" , err )
261
+ continue
262
+ }
237
263
klog .V (3 ).Infof (" tags: %q" , peerPkgs )
238
264
if len (peerPkgs ) == 1 && peerPkgs [0 ] == "false" {
239
265
// If a single +k8s:conversion-gen=false tag is defined, we still want
@@ -250,7 +276,10 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target
250
276
251
277
// if the external types are not in the same package where the
252
278
// conversion functions to be generated
253
- externalTypesValues := extractExternalTypesTag (pkg .Comments )
279
+ externalTypesValues , err := extractExternalTypesTag (pkg .Comments )
280
+ if err != nil {
281
+ klog .Fatalf ("Failed to extract external types tag for package %q: %v" , i , err )
282
+ }
254
283
if externalTypesValues != nil {
255
284
if len (externalTypesValues ) != 1 {
256
285
klog .Fatalf (" expect only one value for %q tag, got: %q" , externalTypesTagName , externalTypesValues )
@@ -337,7 +366,10 @@ func GetTargets(context *generator.Context, args *args.Args) []generator.Target
337
366
// If there is a manual conversion defined between two types, exclude it
338
367
// from being a candidate for unsafe conversion
339
368
for k , v := range manualConversions {
340
- if isCopyOnly (v .CommentLines ) {
369
+ copyOnly , err := isCopyOnly (v .CommentLines )
370
+ if err != nil {
371
+ klog .Errorf ("error extracting tags: %v" , err )
372
+ } else if copyOnly {
341
373
klog .V (4 ).Infof ("Conversion function %s will not block memory copy because it is copy-only" , v .Name )
342
374
continue
343
375
}
@@ -520,7 +552,12 @@ func (g *genConversion) convertibleOnlyWithinPackage(inType, outType *types.Type
520
552
return false
521
553
}
522
554
// If the type has opted out, skip it.
523
- tagvals := extractTag (t .CommentLines )
555
+ tagvals , err := extractTag (t .CommentLines )
556
+ if err != nil {
557
+ klog .Errorf ("Type %v: error extracting tags: %v" , t , err )
558
+ return false
559
+ }
560
+
524
561
if tagvals != nil {
525
562
if tagvals [0 ] != "false" {
526
563
klog .Fatalf ("Type %v: unsupported %s value: %q" , t , tagName , tagvals [0 ])
@@ -542,8 +579,12 @@ func (g *genConversion) convertibleOnlyWithinPackage(inType, outType *types.Type
542
579
func getExplicitFromTypes (t * types.Type ) []types.Name {
543
580
comments := t .SecondClosestCommentLines
544
581
comments = append (comments , t .CommentLines ... )
545
- paths := extractExplicitFromTag (comments )
546
582
result := []types.Name {}
583
+ paths , err := extractExplicitFromTag (comments )
584
+ if err != nil {
585
+ klog .Errorf ("Error extracting explicit-from tag for %v: %v" , t .Name , err )
586
+ return result
587
+ }
547
588
for _ , path := range paths {
548
589
items := strings .Split (path , "." )
549
590
if len (items ) != 2 {
@@ -869,7 +910,11 @@ func (g *genConversion) doSlice(inType, outType *types.Type, sw *generator.Snipp
869
910
870
911
func (g * genConversion ) doStruct (inType , outType * types.Type , sw * generator.SnippetWriter ) {
871
912
for _ , inMember := range inType .Members {
872
- if tagvals := extractTag (inMember .CommentLines ); tagvals != nil && tagvals [0 ] == "false" {
913
+ tagvals , err := extractTag (inMember .CommentLines )
914
+ if err != nil {
915
+ klog .Errorf ("Member %v.%v: error extracting tags: %v" , inType , inMember .Name , err )
916
+ }
917
+ if tagvals != nil && tagvals [0 ] == "false" {
873
918
// This field is excluded from conversion.
874
919
sw .Do ("// INFO: in." + inMember .Name + " opted out of conversion generation\n " , nil )
875
920
continue
@@ -918,15 +963,23 @@ func (g *genConversion) doStruct(inType, outType *types.Type, sw *generator.Snip
918
963
919
964
// check based on the top level name, not the underlying names
920
965
if function , ok := g .preexists (inMember .Type , outMember .Type ); ok {
921
- if isDrop (function .CommentLines ) {
966
+ dropFn , err := isDrop (function .CommentLines )
967
+ if err != nil {
968
+ klog .Errorf ("Error extracting drop tag for function %s: %v" , function .Name , err )
969
+ } else if dropFn {
922
970
continue
923
971
}
924
972
// copy-only functions that are directly assignable can be inlined instead of invoked.
925
973
// As an example, conversion functions exist that allow types with private fields to be
926
974
// correctly copied between types. These functions are equivalent to a memory assignment,
927
975
// and are necessary for the reflection path, but should not block memory conversion.
928
976
// Convert_unversioned_Time_to_unversioned_Time is an example of this logic.
929
- if ! isCopyOnly (function .CommentLines ) || ! g .isFastConversion (inMemberType , outMemberType ) {
977
+ copyOnly , copyErr := isCopyOnly (function .CommentLines )
978
+ if copyErr != nil {
979
+ klog .Errorf ("Error extracting copy-only tag for function %s: %v" , function .Name , copyErr )
980
+ copyOnly = false
981
+ }
982
+ if ! copyOnly || ! g .isFastConversion (inMemberType , outMemberType ) {
930
983
args ["function" ] = function
931
984
sw .Do ("if err := $.function|raw$(&in.$.name$, &out.$.name$, s); err != nil {\n " , args )
932
985
sw .Do ("return err\n " , nil )
@@ -1080,7 +1133,11 @@ func (g *genConversion) generateFromURLValues(inType, outType *types.Type, sw *g
1080
1133
}
1081
1134
sw .Do ("func auto" + nameTmpl + "(in *$.inType|raw$, out *$.outType|raw$, s $.Scope|raw$) error {\n " , args )
1082
1135
for _ , outMember := range outType .Members {
1083
- if tagvals := extractTag (outMember .CommentLines ); tagvals != nil && tagvals [0 ] == "false" {
1136
+ tagvals , err := extractTag (outMember .CommentLines )
1137
+ if err != nil {
1138
+ klog .Errorf ("Member %v.%v: error extracting tags: %v" , outType , outMember .Name , err )
1139
+ }
1140
+ if tagvals != nil && tagvals [0 ] == "false" {
1084
1141
// This field is excluded from conversion.
1085
1142
sw .Do ("// INFO: in." + outMember .Name + " opted out of conversion generation\n " , nil )
1086
1143
continue
0 commit comments