Skip to content

Commit

Permalink
Merge pull request #35 from mtt0/main
Browse files Browse the repository at this point in the history
feat: support embed struct fields without `tstype: ",extends"`
  • Loading branch information
gzuidhof committed Aug 25, 2023
2 parents 57dbd87 + abe1cc9 commit 09625a8
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 2 deletions.
2 changes: 1 addition & 1 deletion examples/bookstore/book.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ type Book struct {
}

type TextBook[T int] struct {
Book ` tstype:",inline"`
Book `tstype:",extends"`
Pages T ` json:"pages"`
}
2 changes: 1 addition & 1 deletion examples/bookstore/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ export interface Book {
chapters: Chapter[];
published_at?: string /* RFC 3339 formatted */;
}
export interface TextBook<T extends number /* int */> {
export interface TextBook<T extends number /* int */> extends Book {
pages: T;
}
16 changes: 16 additions & 0 deletions examples/embed/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package embed

import bookapp "github.com/gzuidhof/tygo/examples/bookstore"

// TokenType Built-in type alias
type TokenType string

type StructEmbed struct {
Base `json:",inline" tstype:",extends"` // embed struct with `tstype:"extends"`
TokenType `json:"tokenType"` // built-in type field without `tstype:"extends"`
Reference `json:"reference"` // embed struct without `tstype:"extends"`
OtherReference Reference `json:"other_reference"`
Bar string `json:"bar"`
bookapp.Book `json:"book"` // embed external struct without `tstype:"extends"`
*bookapp.Chapter `json:"chapter"` // embed external struct pointer without `tstype:"extends"`
}
34 changes: 34 additions & 0 deletions examples/embed/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Code generated by tygo. DO NOT EDIT.
import * as bookapp from "../bookstore"

//////////
// source: embed.go

/**
* TokenType Built-in type alias
*/
export type TokenType = string;
export interface StructEmbed extends Base {
tokenType: TokenType; // built-in type field without `tstype:"extends"`
reference: Reference; // embed struct without `tstype:"extends"`
other_reference: Reference;
bar: string;
book: bookapp.Book; // embed external struct without `tstype:"extends"`
chapter?: bookapp.Chapter; // embed external struct pointer without `tstype:"extends"`
}

//////////
// source: types.go
/*
Package embed types defined in the Go file after the parsed file in the same package
*/

export interface Base {
id: string;
}
/**
* Reference struct type, defined after embed.go, the same pkg but not the same file
*/
export interface Reference {
foo: string;
}
11 changes: 11 additions & 0 deletions examples/embed/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Package embed types defined in the Go file after the parsed file in the same package
package embed

type Base struct {
ID string `json:"id"`
}

// Reference struct type, defined after embed.go, the same pkg but not the same file
type Reference struct {
Foo string `json:"foo"`
}
8 changes: 8 additions & 0 deletions tygo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ packages:
frontmatter:
| # We can define some additional text to put at the start of the file.
import * as bookapp from "../bookstore"
- path: "github.com/gzuidhof/tygo/examples/embed"
fallback_type: unknown
type_mappings:
bookapp.Book: "bookapp.Book"
bookapp.Chapter: "bookapp.Chapter"
frontmatter:
| # We can define some additional text to put at the start of the file.
import * as bookapp from "../bookstore"
- path: "github.com/gzuidhof/tygo/examples/generic"
fallback_type: unknown
- path: "github.com/gzuidhof/tygo/examples/preserveTypeComments"
Expand Down
5 changes: 5 additions & 0 deletions tygo/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@ func (g *PackageGenerator) writeStructFields(s *strings.Builder, fields []*ast.F
readonly := false

var fieldName string
if len(f.Names) == 0 { // anonymous field
if name, valid := getAnonymousFieldName(f.Type); valid {
fieldName = name
}
}
if len(f.Names) != 0 && f.Names[0] != nil && len(f.Names[0].Name) != 0 {
fieldName = f.Names[0].Name
}
Expand Down
32 changes: 32 additions & 0 deletions tygo/write_toplevel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tygo
import (
"fmt"
"go/ast"
"go/token"
"strings"

"github.com/fatih/structtag"
Expand Down Expand Up @@ -241,6 +242,10 @@ func getInheritedType(f ast.Expr, tag *structtag.Tag) (name string, valid bool)
valid = isStruct && dcl.Name.IsExported()
name = dcl.Name.Name
}
} else {
// Types defined in the Go file after the parsed file in the same package
valid = token.IsExported(ft.Name)
name = ft.Name
}
case *ast.IndexExpr:
name, valid = getInheritedType(ft.X, tag)
Expand Down Expand Up @@ -272,3 +277,30 @@ func getInheritedType(f ast.Expr, tag *structtag.Tag) (name string, valid bool)
}
return
}

func getAnonymousFieldName(f ast.Expr) (name string, valid bool) {
switch ft := f.(type) {
case *ast.Ident:
name = ft.Name
if ft.Obj != nil && ft.Obj.Decl != nil {
dcl, ok := ft.Obj.Decl.(*ast.TypeSpec)
if ok {
valid = dcl.Name.IsExported()
}
} else {
// Types defined in the Go file after the parsed file in the same package
valid = token.IsExported(name)
}
case *ast.IndexExpr:
return getAnonymousFieldName(ft.X)
case *ast.IndexListExpr:
return getAnonymousFieldName(ft.X)
case *ast.SelectorExpr:
valid = ft.Sel.IsExported()
name = ft.Sel.String()
case *ast.StarExpr:
return getAnonymousFieldName(ft.X)
}

return
}

0 comments on commit 09625a8

Please sign in to comment.