Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.

Commit 973f7ed

Browse files
feat: support type aliases and redefinitions (#721)
1 parent b6b4e3b commit 973f7ed

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
- fix: remove fallback to default time zone [#706](https://github.com/hypermodeinc/modus/pull/706)
1212
- feat: improve OpenAI model APIs and examples to better support audio, images, and tool calling
1313
[#707](https://github.com/hypermodeinc/modus/pull/707)
14+
- feat: support type aliases and redefinitions
15+
[#721](https://github.com/hypermodeinc/modus/pull/721)
1416

1517
## 2025-01-09 - CLI 0.16.6
1618

sdk/go/tools/modus-go-build/extractor/extractor.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package extractor
1111

1212
import (
13+
"fmt"
1314
"go/types"
1415
"sort"
1516

@@ -49,8 +50,27 @@ func CollectProgramInfo(config *config.Config, meta *metadata.Metadata) error {
4950
sort.Strings(keys)
5051
for _, name := range keys {
5152
t := requiredTypes[name]
53+
54+
// resolve type aliases
55+
for {
56+
if a, ok := t.(*types.Alias); ok {
57+
t = a.Rhs()
58+
} else {
59+
break
60+
}
61+
}
62+
63+
resolvedName := name
64+
if n, ok := t.(*types.Named); ok {
65+
resolvedName = n.String()
66+
t = n.Underlying()
67+
}
68+
5269
if s, ok := t.(*types.Struct); ok && !wellKnownTypes[name] {
53-
t := transformStruct(name, s, pkgs)
70+
t := transformStruct(resolvedName, s, pkgs)
71+
if t == nil {
72+
return fmt.Errorf("failed to transform struct %s", resolvedName)
73+
}
5474
t.Id = id
5575
meta.Types[name] = t
5676
} else {

sdk/go/tools/modus-go-build/extractor/functions.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ func addRequiredTypes(t types.Type, m map[string]types.Type) bool {
227227
m[name] = t
228228
return true
229229
}
230+
case *types.Alias:
231+
if addRequiredTypes(t.Rhs(), m) {
232+
m[name] = t
233+
return true
234+
}
230235
case *types.Struct:
231236
// TODO: handle unnamed structs
232237
case *types.Slice:

sdk/go/tools/modus-go-build/extractor/transform.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,17 @@ func getStructDeclarationAndType(name string, pkgs map[string]*packages.Package)
109109
if typeSpec.Name.Name == objName {
110110
if structType, ok := typeSpec.Type.(*ast.StructType); ok {
111111
return genDecl, structType
112+
} else if ident, ok := typeSpec.Type.(*ast.Ident); ok {
113+
typePath := pkgName + "." + ident.Name
114+
return getStructDeclarationAndType(typePath, pkgs)
115+
} else if selExp, ok := typeSpec.Type.(*ast.SelectorExpr); ok {
116+
if pkgIdent, ok := selExp.X.(*ast.Ident); !ok {
117+
return nil, nil
118+
} else {
119+
pkgPath := getFullImportPath(file, pkgIdent.Name)
120+
typePath := pkgPath + "." + selExp.Sel.Name
121+
return getStructDeclarationAndType(typePath, pkgs)
122+
}
112123
}
113124
}
114125
}
@@ -120,6 +131,24 @@ func getStructDeclarationAndType(name string, pkgs map[string]*packages.Package)
120131
return nil, nil
121132
}
122133

134+
func getFullImportPath(file *ast.File, pkgName string) string {
135+
for _, imp := range file.Imports {
136+
path := strings.Trim(imp.Path.Value, `"`)
137+
if imp.Name == nil {
138+
parts := strings.Split(path, "/")
139+
if len(parts) == 0 {
140+
return ""
141+
}
142+
if parts[len(parts)-1] == pkgName {
143+
return path
144+
}
145+
} else if imp.Name.Name == pkgName {
146+
return path
147+
}
148+
}
149+
return ""
150+
}
151+
123152
func getDocs(comments *ast.CommentGroup) *metadata.Docs {
124153
if comments == nil {
125154
return nil

0 commit comments

Comments
 (0)