Skip to content

Commit 134a1f1

Browse files
authored
Embedded Structs in Code Generation (#1909)
This allows code generation to properly embed structs when embedded in the original types. It affects the generation of `gotypes.d.ts` and `metaconsts.go`. Additionally, the `AiSettingsType` has been split off and embedded into the original `SettingsType` to make schema generation easier.
1 parent 6139fee commit 134a1f1

File tree

5 files changed

+55
-19
lines changed

5 files changed

+55
-19
lines changed

cmd/generatego/main-generatego.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func GenerateWaveObjMetaConsts() error {
5656
fmt.Fprintf(os.Stderr, "generating waveobj meta consts file to %s\n", WaveObjMetaConstsFileName)
5757
var buf strings.Builder
5858
gogen.GenerateBoilerplate(&buf, "waveobj", []string{})
59-
gogen.GenerateMetaMapConsts(&buf, "MetaKey_", reflect.TypeOf(waveobj.MetaTSType{}))
59+
gogen.GenerateMetaMapConsts(&buf, "MetaKey_", reflect.TypeOf(waveobj.MetaTSType{}), false)
6060
buf.WriteString("\n")
6161
written, err := utilfn.WriteFileIfDifferent(WaveObjMetaConstsFileName, []byte(buf.String()))
6262
if !written {
@@ -69,7 +69,7 @@ func GenerateSettingsMetaConsts() error {
6969
fmt.Fprintf(os.Stderr, "generating settings meta consts file to %s\n", SettingsMetaConstsFileName)
7070
var buf strings.Builder
7171
gogen.GenerateBoilerplate(&buf, "wconfig", []string{})
72-
gogen.GenerateMetaMapConsts(&buf, "ConfigKey_", reflect.TypeOf(wconfig.SettingsType{}))
72+
gogen.GenerateMetaMapConsts(&buf, "ConfigKey_", reflect.TypeOf(wconfig.SettingsType{}), false)
7373
buf.WriteString("\n")
7474
written, err := utilfn.WriteFileIfDifferent(SettingsMetaConstsFileName, []byte(buf.String()))
7575
if !written {

frontend/types/gotypes.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,16 @@ declare global {
799799

800800
// telemetrydata.TEventProps
801801
type TEventProps = {
802+
"client:arch"?: string;
803+
"client:version"?: string;
804+
"client:initial_version"?: string;
805+
"client:buildtime"?: string;
806+
"client:osrelease"?: string;
807+
"client:isdev"?: boolean;
808+
"autoupdate:channel"?: string;
809+
"autoupdate:enabled"?: boolean;
810+
"loc:countrycode"?: string;
811+
"loc:regioncode"?: string;
802812
"activity:activeminutes"?: number;
803813
"activity:fgminutes"?: number;
804814
"activity:openminutes"?: number;

pkg/gogen/gogen.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,25 @@ func getBeforeColonPart(s string) string {
3333
return s
3434
}
3535

36-
func GenerateMetaMapConsts(buf *strings.Builder, constPrefix string, rtype reflect.Type) {
37-
buf.WriteString("const (\n")
36+
func GenerateMetaMapConsts(buf *strings.Builder, constPrefix string, rtype reflect.Type, embedded bool) {
37+
if !embedded {
38+
buf.WriteString("const (\n")
39+
} else {
40+
buf.WriteString("\n")
41+
}
3842
var lastBeforeColon = ""
3943
isFirst := true
4044
for idx := 0; idx < rtype.NumField(); idx++ {
4145
field := rtype.Field(idx)
4246
if field.PkgPath != "" {
4347
continue
4448
}
49+
if field.Anonymous {
50+
var embeddedBuf strings.Builder
51+
GenerateMetaMapConsts(&embeddedBuf, constPrefix, field.Type, true)
52+
buf.WriteString(embeddedBuf.String())
53+
continue
54+
}
4555
fieldName := field.Name
4656
jsonTag := utilfn.GetJsonTag(field)
4757
if jsonTag == "" {
@@ -58,7 +68,9 @@ func GenerateMetaMapConsts(buf *strings.Builder, constPrefix string, rtype refle
5868
buf.WriteString(fmt.Sprintf("\t%-40s = %q\n", cname, jsonTag))
5969
isFirst = false
6070
}
61-
buf.WriteString(")\n")
71+
if !embedded {
72+
buf.WriteString(")\n")
73+
}
6274
}
6375

6476
func GenMethod_Call(buf *strings.Builder, methodDecl *wshrpc.WshRpcMethodDecl) {

pkg/tsgen/tsgen.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,34 @@ var tsRenameMap = map[string]string{
176176
"MetaSettingsType": "SettingsType",
177177
}
178178

179-
func generateTSTypeInternal(rtype reflect.Type, tsTypesMap map[reflect.Type]string) (string, []reflect.Type) {
179+
func generateTSTypeInternal(rtype reflect.Type, tsTypesMap map[reflect.Type]string, embedded bool) (string, []reflect.Type) {
180180
var buf bytes.Buffer
181181
tsTypeName := rtype.Name()
182182
if tsRename, ok := tsRenameMap[tsTypeName]; ok {
183183
tsTypeName = tsRename
184184
}
185185
var isWaveObj bool
186-
buf.WriteString(fmt.Sprintf("// %s\n", rtype.String()))
187-
if rtype.Implements(waveObjRType) || reflect.PointerTo(rtype).Implements(waveObjRType) {
188-
isWaveObj = true
189-
buf.WriteString(fmt.Sprintf("type %s = WaveObj & {\n", tsTypeName))
190-
} else {
191-
buf.WriteString(fmt.Sprintf("type %s = {\n", tsTypeName))
186+
if !embedded {
187+
buf.WriteString(fmt.Sprintf("// %s\n", rtype.String()))
188+
if rtype.Implements(waveObjRType) || reflect.PointerTo(rtype).Implements(waveObjRType) {
189+
isWaveObj = true
190+
buf.WriteString(fmt.Sprintf("type %s = WaveObj & {\n", tsTypeName))
191+
} else {
192+
buf.WriteString(fmt.Sprintf("type %s = {\n", tsTypeName))
193+
}
192194
}
193195
var subTypes []reflect.Type
194196
for i := 0; i < rtype.NumField(); i++ {
195197
field := rtype.Field(i)
196198
if field.PkgPath != "" {
197199
continue
198200
}
201+
if field.Anonymous {
202+
embeddedBuf, embeddedTypes := generateTSTypeInternal(field.Type, tsTypesMap, true)
203+
buf.WriteString(embeddedBuf)
204+
subTypes = append(subTypes, embeddedTypes...)
205+
continue
206+
}
199207
fieldName := getTSFieldName(field)
200208
if fieldName == "" {
201209
continue
@@ -225,7 +233,9 @@ func generateTSTypeInternal(rtype reflect.Type, tsTypesMap map[reflect.Type]stri
225233
}
226234
buf.WriteString(fmt.Sprintf(" %s%s: %s;\n", fieldName, optMarker, tsType))
227235
}
228-
buf.WriteString("};\n")
236+
if !embedded {
237+
buf.WriteString("};\n")
238+
}
229239
return buf.String(), subTypes
230240
}
231241

@@ -303,7 +313,7 @@ func GenerateTSType(rtype reflect.Type, tsTypesMap map[reflect.Type]string) {
303313
if rtype.Kind() != reflect.Struct {
304314
return
305315
}
306-
tsType, subTypes := generateTSTypeInternal(rtype, tsTypesMap)
316+
tsType, subTypes := generateTSTypeInternal(rtype, tsTypesMap, false)
307317
tsTypesMap[rtype] = tsType
308318
for _, subType := range subTypes {
309319
GenerateTSType(subType, tsTypesMap)

pkg/wconfig/settingsconfig.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ const AnySchema = `
3232
}
3333
`
3434

35-
type SettingsType struct {
36-
AppClear bool `json:"app:*,omitempty"`
37-
AppGlobalHotkey string `json:"app:globalhotkey,omitempty"`
38-
AppDismissArchitectureWarning bool `json:"app:dismissarchitecturewarning,omitempty"`
39-
35+
type AiSettingsType struct {
4036
AiClear bool `json:"ai:*,omitempty"`
4137
AiPreset string `json:"ai:preset,omitempty"`
4238
AiApiType string `json:"ai:apitype,omitempty"`
@@ -50,6 +46,14 @@ type SettingsType struct {
5046
AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"`
5147
AiFontSize float64 `json:"ai:fontsize,omitempty"`
5248
AiFixedFontSize float64 `json:"ai:fixedfontsize,omitempty"`
49+
}
50+
51+
type SettingsType struct {
52+
AppClear bool `json:"app:*,omitempty"`
53+
AppGlobalHotkey string `json:"app:globalhotkey,omitempty"`
54+
AppDismissArchitectureWarning bool `json:"app:dismissarchitecturewarning,omitempty"`
55+
56+
AiSettingsType
5357

5458
TermClear bool `json:"term:*,omitempty"`
5559
TermFontSize float64 `json:"term:fontsize,omitempty"`

0 commit comments

Comments
 (0)