Repository: goadesign/goa
Pull request #3599 (2024-10-04 11:11:58)

Use doc.IsPredeclared() and token.IsKeyword() for codegen.fixReservedGo()

tchssk: Oops! I added a condition.
raphael: Perfect, thank you!

Patch:
diff --git a/codegen/goify.go b/codegen/goify.go
index b6caae55..3c26c8d3 100644
--- a/codegen/goify.go
+++ b/codegen/goify.go
@@ -1,6 +1,8 @@
 package codegen
 
 import (
+	"go/doc"
+	"go/token"
 	"strings"
 
 	"goa.design/goa/v3/expr"
@@ -54,70 +56,14 @@ func UnionValTypeName(unionName string) string {
 
 // fixReservedGo appends an underscore on to Go reserved keywords.
 func fixReservedGo(w string) string {
-	if reservedGo[w] {
+	if doc.IsPredeclared(w) || token.IsKeyword(w) || isPackage[w] {
 		w += "_"
 	}
 	return w
 }
 
 var (
-	// reserved golang keywords and package names
-	reservedGo = map[string]bool{
-		// predeclared types
-		"bool":       true,
-		"byte":       true,
-		"complex128": true,
-		"complex64":  true,
-		"float32":    true,
-		"float64":    true,
-		"int":        true,
-		"int16":      true,
-		"int32":      true,
-		"int64":      true,
-		"int8":       true,
-		"rune":       true,
-		"string":     true,
-		"uint":       true,
-		"uint16":     true,
-		"uint32":     true,
-		"uint64":     true,
-		"uint8":      true,
-		"uintptr":    true,
-
-		// reserved keywords
-		"break":       true,
-		"case":        true,
-		"chan":        true,
-		"const":       true,
-		"continue":    true,
-		"default":     true,
-		"defer":       true,
-		"delete":      true,
-		"else":        true,
-		"fallthrough": true,
-		"for":         true,
-		"func":        true,
-		"go":          true,
-		"goto":        true,
-		"if":          true,
-		"import":      true,
-		"interface":   true,
-		"map":         true,
-		"package":     true,
-		"range":       true,
-		"return":      true,
-		"select":      true,
-		"struct":      true,
-		"switch":      true,
-		"type":        true,
-		"var":         true,
-
-		// predeclared constants
-		"true":  true,
-		"false": true,
-		"iota":  true,
-		"nil":   true,
-
+	isPackage = map[string]bool{
 		// stdlib and goa packages used by generated code
 		"fmt":  true,
 		"http": true,


Test patch:
diff --git a/codegen/goify_test.go b/codegen/goify_test.go
new file mode 100644
index 00000000..d7d4339f
--- /dev/null
+++ b/codegen/goify_test.go
@@ -0,0 +1,26 @@
+package codegen
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestFixReservedGo(t *testing.T) {
+	cases := map[string]struct {
+		w    string
+		want string
+	}{
+		"predeclared type":           {w: "bool", want: "bool_"},
+		"predeclared constant":       {w: "true", want: "true_"},
+		"predeclared zero value":     {w: "nil", want: "nil_"},
+		"predeclared function":       {w: "append", want: "append_"},
+		"non predeclared identifier": {w: "foo", want: "foo"},
+		"package":                    {w: "fmt", want: "fmt_"},
+	}
+	for k, tc := range cases {
+		t.Run(k, func(t *testing.T) {
+			assert.Equal(t, tc.want, fixReservedGo(tc.w))
+		})
+	}
+}
diff --git a/http/codegen/testdata/result_decode_functions.go b/http/codegen/testdata/result_decode_functions.go
index 4d91cfa9..6e08aae0 100644
--- a/http/codegen/testdata/result_decode_functions.go
+++ b/http/codegen/testdata/result_decode_functions.go
@@ -789,15 +789,15 @@ func DecodeMethodAResponse(decoder func(*http.Response) goahttp.Decoder, restore
 			return res, nil
 		case http.StatusBadRequest:
 			var (
-				error    string
+				error_   string
 				numOccur *int
 				err      error
 			)
-			errorRaw := resp.Header.Get("X-Application-Error")
-			if errorRaw == "" {
+			error_Raw := resp.Header.Get("X-Application-Error")
+			if error_Raw == "" {
 				err = goa.MergeErrors(err, goa.MissingFieldError("error", "header"))
 			}
-			error = errorRaw
+			error_ = error_Raw
 			{
 				numOccurRaw := resp.Header.Get("X-Occur")
 				if numOccurRaw != "" {
@@ -817,7 +817,7 @@ func DecodeMethodAResponse(decoder func(*http.Response) goahttp.Decoder, restore
 			if err != nil {
 				return nil, goahttp.ErrValidationError("ValidateErrorResponseType", "MethodA", err)
 			}
-			return nil, NewMethodASomeError(error, numOccur)
+			return nil, NewMethodASomeError(error_, numOccur)
 		default:
 			body, _ := io.ReadAll(resp.Body)
 			return nil, goahttp.ErrInvalidResponse("ValidateErrorResponseType", "MethodA", resp.StatusCode, string(body))