diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..312925e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,23 @@ +name: Test Tygo +on: + pull_request: + push: + +jobs: + test: + runs-on: ubuntu-latest + strategy: + matrix: + go-version: + - 1.22.x + steps: + - name: checkout + uses: actions/checkout@v4 + - name: install + uses: actions/setup-go@v5 + with: + go-version: '${{ matrix.go-version }}' + - name: vet + run: go vet ./... + - name: test + run: go test -v -race ./... \ No newline at end of file diff --git a/config/config.go b/config/config.go index d2cad77..2eadd0a 100644 --- a/config/config.go +++ b/config/config.go @@ -8,9 +8,6 @@ import ( "gopkg.in/yaml.v2" ) -const defaultFallbackType = "any" -const defaultPreserveComments = "default" - func ReadFromFilepath(cfgFilepath string) tygo.Config { b, err := ioutil.ReadFile(cfgFilepath) if err != nil { @@ -22,16 +19,5 @@ func ReadFromFilepath(cfgFilepath string) tygo.Config { log.Fatalf("Could not parse config file from: %v", err) } - // apply defaults - for _, packageConf := range conf.Packages { - if packageConf.FallbackType == "" { - packageConf.FallbackType = defaultFallbackType - } - - if packageConf.PreserveComments == "" { - packageConf.PreserveComments = defaultPreserveComments - } - } - return conf } diff --git a/go.mod b/go.mod index 4c2d47b..704bb6e 100644 --- a/go.mod +++ b/go.mod @@ -8,9 +8,12 @@ require ( ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect golang.org/x/mod v0.5.1 // indirect golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( @@ -18,6 +21,7 @@ require ( github.com/google/uuid v1.3.0 github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/testify v1.9.0 golang.org/x/tools v0.1.9 gopkg.in/guregu/null.v4 v4.0.0 ) diff --git a/go.sum b/go.sum index e3f22f3..b622dc8 100644 --- a/go.sum +++ b/go.sum @@ -89,6 +89,7 @@ github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -281,6 +282,7 @@ github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= @@ -322,6 +324,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -762,6 +766,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/tygo/config.go b/tygo/config.go index 0505450..105b86a 100644 --- a/tygo/config.go +++ b/tygo/config.go @@ -8,6 +8,8 @@ import ( ) const defaultOutputFilename = "index.ts" +const defaultFallbackType = "any" +const defaultPreserveComments = "default" type PackageConfig struct { // The package path just like you would import it in Go @@ -77,27 +79,12 @@ func (c Config) PackageNames() []string { func (c Config) PackageConfig(packagePath string) *PackageConfig { for _, pc := range c.Packages { if pc.Path == packagePath { - if pc.Indent == "" { - pc.Indent = " " - } - - var err error - pc.Flavor, err = normalizeFlavor(pc.Flavor) - if err != nil { - log.Fatalf("Invalid config for package %s: %s", packagePath, err) - } - - pc.PreserveComments, err = normalizePreserveComments(pc.PreserveComments) + pcNormalized, err := pc.Normalize() if err != nil { - log.Fatalf("Invalid config for package %s: %s", packagePath, err) + log.Fatalf("Error in config for package %s: %s", packagePath, err) } - pc.OptionalType, err = normalizeOptionalType(pc.OptionalType) - if err != nil { - log.Fatalf("Invalid config for package %s: %s", packagePath, err) - } - - return pc + return &pcNormalized } } log.Fatalf("Config not found for package %s", packagePath) @@ -168,3 +155,36 @@ func (c PackageConfig) ResolvedOutputPath(packageDir string) string { } return c.OutputPath } + +// Normalize returns a new PackageConfig with default values set. +func (pc PackageConfig) Normalize() (PackageConfig, error) { + if pc.Indent == "" { + pc.Indent = " " + } + + if pc.FallbackType == "" { + pc.FallbackType = defaultFallbackType + } + + if pc.PreserveComments == "" { + pc.PreserveComments = defaultPreserveComments + } + + var err error + pc.Flavor, err = normalizeFlavor(pc.Flavor) + if err != nil { + return pc, fmt.Errorf("invalid flavor config for package %s: %s", pc.Path, err) + } + + pc.PreserveComments, err = normalizePreserveComments(pc.PreserveComments) + if err != nil { + return pc, fmt.Errorf("invalid preserve_comments config for package %s: %s", pc.Path, err) + } + + pc.OptionalType, err = normalizeOptionalType(pc.OptionalType) + if err != nil { + return pc, fmt.Errorf("invalid optional_type config for package %s: %s", pc.Path, err) + } + + return pc, nil +} diff --git a/tygo/convert_string.go b/tygo/convert_string.go new file mode 100644 index 0000000..60ea801 --- /dev/null +++ b/tygo/convert_string.go @@ -0,0 +1,41 @@ +package tygo + +import ( + "fmt" + "go/parser" + "go/token" + "strings" +) + +// ConvertGoToTypescript converts Go code string to Typescript. +// +// This is mostly useful for testing purposes inside tygo itself. +func ConvertGoToTypescript(goCode string, pkgConfig PackageConfig) (string, error) { + src := fmt.Sprintf(`package tygoconvert + +%s`, goCode) + + fset := token.NewFileSet() + + f, err := parser.ParseFile(fset, "", src, parser.AllErrors|parser.ParseComments) + if err != nil { + return "", fmt.Errorf("failed to parse source: %w", err) + } + + pkgConfig, err = pkgConfig.Normalize() + if err != nil { + return "", fmt.Errorf("failed to normalize package config: %w", err) + } + + pkgGen := &PackageGenerator{ + conf: &pkgConfig, + pkg: nil, + } + + s := new(strings.Builder) + + pkgGen.generateFile(s, f, "") + code := s.String() + + return code, nil +} diff --git a/tygo/fixtures_test.go b/tygo/fixtures_test.go new file mode 100644 index 0000000..117856f --- /dev/null +++ b/tygo/fixtures_test.go @@ -0,0 +1,113 @@ +package tygo + +import ( + "embed" + "fmt" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v3" +) + +// Embed markdown test fixtures +// +//go:embed testdata/fixtures/*.md +var mdfs embed.FS + +type MarkdownFixture struct { + PackageConfig PackageConfig + GoCode string + TsCode string +} + +func TestConvertGoToTypescriptSmoketest(t *testing.T) { + t.Parallel() + + goCode := "type MyType uint8" + tsCode, err := ConvertGoToTypescript(goCode, PackageConfig{}) + require.NoError(t, err) + + expected := `export type MyType = number /* uint8 */; +` + assert.Equal(t, expected, tsCode) +} + +func parseMarkdownFixtures(fileContents []byte) ([]MarkdownFixture, error) { + fixtures := make([]MarkdownFixture, 0) + currentFixture := MarkdownFixture{} + + currentBlockContents := "" + currentBlockLanguage := "" + inCodeBlock := false + for _, line := range strings.Split(string(fileContents), "\n") { + if strings.HasPrefix(line, "```") { + if inCodeBlock { + // End of code block + if currentBlockLanguage == "ts" || currentBlockLanguage == "typescript" { + // Every fixture ends with a typescript block + currentFixture.TsCode = currentBlockContents + fixtures = append(fixtures, currentFixture) + currentFixture = MarkdownFixture{} + } else if currentBlockLanguage == "go" { + currentFixture.GoCode = currentBlockContents + } else if currentBlockLanguage == "yml" || currentBlockLanguage == "yaml" { + // Parse package config + pc := PackageConfig{} + err := yaml.Unmarshal([]byte(currentBlockContents), &pc) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal package config: %w", err) + } + currentFixture.PackageConfig = pc + } + currentBlockContents = "" + currentBlockLanguage = "" + } else { // Start of code block + language := strings.TrimPrefix(line, "```") + language = strings.TrimSpace(language) + currentBlockLanguage = language + } + inCodeBlock = !inCodeBlock + continue + } + + if inCodeBlock { + currentBlockContents += line + "\n" + } + } + + return fixtures, nil + +} + +// Tests all markdown files in `testdata/fixtures/` directory. +func TestMarkdownFixtures(t *testing.T) { + t.Parallel() + + fixtures, err := mdfs.ReadDir("testdata/fixtures") + require.NoError(t, err) + + for _, fixture := range fixtures { + fixture := fixture + + // Read markdown file + md, err := mdfs.ReadFile("testdata/fixtures/" + fixture.Name()) + require.NoError(t, err) + + testCases, err := parseMarkdownFixtures(md) + require.NoError(t, err) + + for _, tc := range testCases { + tc := tc + t.Run(fixture.Name(), func(t *testing.T) { + t.Parallel() + + tsCode, err := ConvertGoToTypescript(tc.GoCode, tc.PackageConfig) + require.NoError(t, err) + + assert.Equal(t, tc.TsCode, tsCode) + }) + } + } +} diff --git a/tygo/generator.go b/tygo/generator.go index c4137f7..788453d 100644 --- a/tygo/generator.go +++ b/tygo/generator.go @@ -2,7 +2,6 @@ package tygo import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -73,7 +72,7 @@ func (g *Tygo) Generate() error { return nil } - err = ioutil.WriteFile(outPath, []byte(code), 0664) + err = os.WriteFile(outPath, []byte(code), 0664) if err != nil { return nil } diff --git a/tygo/package_generator.go b/tygo/package_generator.go index 615f985..9af6a8a 100644 --- a/tygo/package_generator.go +++ b/tygo/package_generator.go @@ -6,6 +6,43 @@ import ( "strings" ) +// generateFile writes the generated code for a single file to the given strings.Builder. +func (g *PackageGenerator) generateFile(s *strings.Builder, file *ast.File, filepath string) { + first := true + + ast.Inspect(file, func(n ast.Node) bool { + switch x := n.(type) { + + // GenDecl can be an import, type, var, or const expression + case *ast.GenDecl: + if x.Tok == token.IMPORT { + return false + } + isEmit := false + if x.Tok == token.VAR { + isEmit = g.isEmitVar(x) + if !isEmit { + return false + } + } + + if first { + if filepath != "" { + g.writeFileSourceHeader(s, filepath, file) + } + first = false + } + if isEmit { + g.emitVar(s, x) + return false + } + g.writeGroupDecl(s, x) + return false + } + return true + }) +} + func (g *PackageGenerator) Generate() (string, error) { s := new(strings.Builder) @@ -19,39 +56,7 @@ func (g *PackageGenerator) Generate() (string, error) { continue } - first := true - - ast.Inspect(file, func(n ast.Node) bool { - switch x := n.(type) { - - // GenDecl can be an import, type, var, or const expression - case *ast.GenDecl: - if x.Tok == token.IMPORT { - return false - } - isEmit := false - if x.Tok == token.VAR { - isEmit = g.isEmitVar(x) - if !isEmit { - return false - } - } - - if first { - g.writeFileSourceHeader(s, filepaths[i], file) - first = false - } - if isEmit { - g.emitVar(s, x) - return false - } - g.writeGroupDecl(s, x) - return false - } - return true - - }) - + g.generateFile(s, file, filepaths[i]) } return s.String(), nil diff --git a/tygo/testdata/fixtures/directive.md b/tygo/testdata/fixtures/directive.md new file mode 100644 index 0000000..9fc3b25 --- /dev/null +++ b/tygo/testdata/fixtures/directive.md @@ -0,0 +1,57 @@ +This fixture is here to reproduce Github issue #26. + +```go +// Comment above a directive +// +//go:foo +//go:bar +const SomeValue = 3 //comment:test + +// Empty Comment +const AnotherValue = 4 // + +//go:something +const DirectiveOnly = 5 + +// RepoIndexerType specifies the repository indexer type +type RepoIndexerType int //revive:disable-line:exported + +const ( + // RepoIndexerTypeCode code indexer + RepoIndexerTypeCode RepoIndexerType = iota // 0 + // RepoIndexerTypeStats repository stats indexer + RepoIndexerTypeStats // 1 +) + +const A = "a" +const B = "a" +const C = "c" +``` + +```ts +/** + * Comment above a directive + */ +export const SomeValue = 3; +/** + * Empty Comment + */ +export const AnotherValue = 4; + +export const DirectiveOnly = 5; +/** + * RepoIndexerType specifies the repository indexer type + */ +export type RepoIndexerType = number /* int */; +/** + * RepoIndexerTypeCode code indexer + */ +export const RepoIndexerTypeCode: RepoIndexerType = 0; // 0 +/** + * RepoIndexerTypeStats repository stats indexer + */ +export const RepoIndexerTypeStats: RepoIndexerType = 1; // 1 +export const A = "a"; +export const B = "a"; +export const C = "c"; +``` \ No newline at end of file diff --git a/tygo/testdata/fixtures/emit.md b/tygo/testdata/fixtures/emit.md new file mode 100644 index 0000000..da4ad27 --- /dev/null +++ b/tygo/testdata/fixtures/emit.md @@ -0,0 +1,58 @@ +```go +// emit directive on a string literal emits that value. +// +//tygo:emit +var _ = `export type OtherStructAsTuple=[ + a:number, + b:number, + c:string, +] +` + +//tygo:emit This has no effect, only strings. +var _ = 12 + +// a non-string var is ignored. A var with no comment is ignored. + +var foo = " " + +// CustomMarshalled illustrates getting tygo to emit literal text +// This solves the problem of a struct field being marshalled into a tuple. +// +// emit directive on a struct emits the remainder of the directive line +// +//tygo:emit export type StructAsTuple=[a:number, b:number, c:string] +type CustomMarshalled struct { + Content []StructAsTuple `json:"content"` +} + +//tygo:emit export type Genre = "novel" | "crime" | "fantasy" +type Book struct { + Title string `json:"title"` + Genre string `json:"genre" tstype:"Genre"` +} +``` + +```ts +export type OtherStructAsTuple=[ + a:number, + b:number, + c:string, +] + +export type StructAsTuple=[a:number, b:number, c:string] +/** + * CustomMarshalled illustrates getting tygo to emit literal text + * This solves the problem of a struct field being marshalled into a tuple. + * emit directive on a struct emits the remainder of the directive line + */ +export interface CustomMarshalled { + content: StructAsTuple[]; +} +export type Genre = "novel" | "crime" | "fantasy" + +export interface Book { + title: string; + genre: Genre; +} +``` \ No newline at end of file diff --git a/tygo/testdata/fixtures/generic.md b/tygo/testdata/fixtures/generic.md new file mode 100644 index 0000000..a39c76d --- /dev/null +++ b/tygo/testdata/fixtures/generic.md @@ -0,0 +1,150 @@ +# Union types and empty interfaces and types +```yaml +fallback_type: "unknown" +``` + +```go +// Comment for UnionType +type UnionType interface { + // Comment for fields are possible + uint64 | string | *bool // comment after + + // Comment for a method + SomeMethod() string +} + +type Derived interface { + ~int | string // Line comment +} + +type Any interface { + string | any +} + +type Empty interface{} + +type Something any + +type EmptyStruct struct{} +``` + +```ts +/** + * Comment for UnionType + */ +export type UnionType = + /** + * Comment for fields are possible + */ + number /* uint64 */ | string | boolean | undefined // comment after +; +export type Derived = + number /* int */ | string // Line comment +; +export type Any = + string | unknown; +export type Empty = unknown; +export type Something = any; +export interface EmptyStruct { +} +``` + +# Values and pointers + +```yaml +fallback_type: "unknown" +``` + +```go + +type ValAndPtr[V any, PT *V, Unused ~uint64] struct { + Val V + // Comment for ptr field + Ptr PT // ptr line comment +} + +type ABCD[A, B string, C UnionType, D int64 | bool] struct { + A A `json:"a"` + B B `json:"b"` + C C `json:"c"` + D D `json:"d"` +} + +type Foo[A string | uint64, B *A] struct { + Bar A + Boo B +} + +type WithFooGenericTypeArg[A Foo[string, *string]] struct { + SomeField A `json:"some_field"` +} + +// Should not be output as it's a function +func (f Foo[int, Derived]) DoSomething() { + panic("something") +} +``` + +```ts +export interface ValAndPtr { + Val: V; + /** + * Comment for ptr field + */ + Ptr: PT; // ptr line comment +} +export interface ABCD { + a: A; + b: B; + c: C; + d: D; +} +export interface Foo { + Bar: A; + Boo: B; +} +export interface WithFooGenericTypeArg> { + some_field: A; +} +``` + +# Single + +```go +type Single[S string | uint] struct { + Field S +} + +type SingleSpecific = Single[string] +``` + +```ts +export interface Single { + Field: S; +} +export type SingleSpecific = Single; +``` + +# Any field + +Example for https://github.com/gzuidhof/tygo/issues/65. +```go +type AnyStructField[T any] struct { + Value T + SomeField string +} +``` +```ts +export interface AnyStructField { + Value: T; + SomeField: string; +} +``` + +```go +type JsonArray[T any] []T +``` + +```ts +export type JsonArray = T[]; +``` \ No newline at end of file diff --git a/tygo/testdata/fixtures/inheritance.md b/tygo/testdata/fixtures/inheritance.md new file mode 100644 index 0000000..17ac305 --- /dev/null +++ b/tygo/testdata/fixtures/inheritance.md @@ -0,0 +1,45 @@ +```go +type Base struct { + Name string `json:"name"` +} + +type Base2[T string | int] struct { + ID T `json:"id"` +} + +type Base3[T string, X int] struct { + Class T `json:"class"` + Level X `json:"level"` +} + +type Other[T int, X string] struct { + *Base `tstype:",extends,required"` + Base2[T] `tstype:",extends"` + *Base3[X, T] `tstype:",extends"` + OtherWithBase Base ` json:"otherWithBase"` + OtherWithBase2 Base2[X] ` json:"otherWithBase2"` + OtherValue string ` json:"otherValue"` + Author bookapp.AuthorWithInheritance[T] `tstype:"bookapp.AuthorWithInheritance" json:"author"` + bookapp.Book `tstype:",extends"` + TextBook *bookapp.TextBook[T] `tstype:",extends,required"` +} +``` + +```ts +export interface Base { + name: string; +} +export interface Base2 { + id: T; +} +export interface Base3 { + class: T; + level: X; +} +export interface Other extends Base, Base2, Partial>, bookapp.Book, bookapp.TextBook { + otherWithBase: Base; + otherWithBase2: Base2; + otherValue: string; + author: bookapp.AuthorWithInheritance; +} +``` \ No newline at end of file diff --git a/tygo/testdata/fixtures/simple.md b/tygo/testdata/fixtures/simple.md new file mode 100644 index 0000000..e35833c --- /dev/null +++ b/tygo/testdata/fixtures/simple.md @@ -0,0 +1,76 @@ +```go +type MyUint8 uint8 +type MyInt int +type MyString string +type MyAny any + +// Should be a number in TypeScript. +type MyRune rune +``` + +```ts +export type MyUint8 = number /* uint8 */; +export type MyInt = number /* int */; +export type MyString = string; +export type MyAny = any; +/** + * Should be a number in TypeScript. + */ +export type MyRune = number /* rune */; +``` + + +Struct with some comments +```go +// Comment for a struct +type MyStruct struct { + SomeField any `json:"some_field"` + // Comment for a field + OtherField bool // Comment after line + FieldWithImportedType some.Type +} +``` + +```ts +/** + * Comment for a struct + */ +export interface MyStruct { + some_field: any; + /** + * Comment for a field + */ + OtherField: boolean; // Comment after line + FieldWithImportedType: any /* some.Type */; +} +``` + +No preserve comments +```yaml +preserve_comments: "none" +``` + +```go +// Foo +type MyValue int // Bar +``` + +```ts +export type MyValue = number /* int */; +``` + +Empty file +```go +``` + +```ts +``` + +Unexported + +```go +const myValue = 3 +``` + +```ts +``` \ No newline at end of file