Skip to content

Commit 644e14f

Browse files
committed
chore: add comments and update readme
1 parent d08c147 commit 644e14f

File tree

16 files changed

+98
-67
lines changed

16 files changed

+98
-67
lines changed

README.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![Go Reference](https://pkg.go.dev/badge/github.com/coder/guts.svg)](https://pkg.go.dev/github.com/coder/guts)
44

5-
`guts` is a tool to convert golang types to typescript for enabling a consistent type definition across the frontend and backend. It is intended to be called and customized as a library, rather than as a command line tool.
5+
`guts` is a tool to convert golang types to typescript for enabling a consistent type definition across the frontend and backend. It is intended to be called and customized as a library, rather than as a command line executable.
66

77
See the [simple example](./example/simple) for a basic usage of the library.
88
```go
@@ -32,17 +32,32 @@ interface SimpleType<T extends Comparable> {
3232

3333
`guts` is a library, not a command line utility. This is to allow configuration with code, and also helps with package resolution.
3434

35-
See the [simple example](./example/simple) for a basic usage of the library.
35+
See the [simple example](./example/simple) for a basic usage of the library. A larger example can be found in the [Coder repository](https://github.com/coder/coder/blob/a632a841d4f5666c2c1690801f88cd1a1fcffc00/scripts/apitypings/main.go).
3636

3737
```go
38+
// Step 1: Create a new Golang parser
39+
golang, _ := guts.NewGolangParser()
40+
// Step 2: Configure the parser
41+
_ = golang.IncludeGenerate("github.com/coder/guts/example/simple")
42+
// Step 3: Convert the Golang to the typescript AST
43+
ts, _ := golang.ToTypescript()
44+
// Step 4: Mutate the typescript AST
45+
ts.ApplyMutations(
46+
config.ExportTypes, // add 'export' to all top level declarations
47+
)
48+
// Step 5: Serialize the typescript AST to a string
49+
output, _ := ts.Serialize()
50+
fmt.Println(output)
51+
```
52+
3853

3954
# How it works
4055

4156
`guts` first parses a set of golang packages. The Go AST is traversed to find all the types defined in the packages.
4257

4358
These types are placed into a simple AST that directly maps to the typescript AST.
4459

45-
Using [goja](https://github.com/dop251/goja), these types are then converted to typescript using the typescript compiler API.
60+
Using [goja](https://github.com/dop251/goja), these types are then serialized to typescript using the typescript compiler API.
4661

4762

4863
# Generator Opinions
@@ -64,4 +79,4 @@ output, _ := ts.Serialize()
6479

6580
# Helpful notes
6681

67-
An incredible website to visualize the AST of typescript: https://ts-ast-viewer.com/
82+
An incredible website to visualize the AST of typescript: https://ts-ast-viewer.com/

TODO.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

bindings/ast.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package bindings
22

33
import (
44
"fmt"
5+
"go/token"
56
"go/types"
67

78
"github.com/dop251/goja"
@@ -11,12 +12,16 @@ type Node interface {
1112
isNode()
1213
}
1314

15+
// Identifier is a name given to a variable, function, class, etc.
16+
// Identifiers should be unique within a package. Package information is
17+
// included to help with disambiguation in the case of name collisions.
1418
type Identifier struct {
1519
Name string
1620
Package *types.Package
1721
Prefix string
1822
}
1923

24+
// GoName should be a unique name for the identifier across all Go packages.
2025
func (i Identifier) GoName() string {
2126
if i.PkgName() != "" {
2227
return fmt.Sprintf("%s.%s", i.PkgName(), i.Name)
@@ -36,12 +41,16 @@ func (i Identifier) String() string {
3641
}
3742

3843
// Ref returns the identifier reference to be used in the generated code.
44+
// This is the identifier to be used in typescript, since all generated code
45+
// lands in the same namespace.
3946
func (i Identifier) Ref() string {
4047
return i.Prefix + i.Name
4148
}
4249

50+
// Source is the golang file that an entity is sourced from.
4351
type Source struct {
44-
File string
52+
File string
53+
Position token.Position
4554
}
4655

4756
type HeritageType string
@@ -51,6 +60,8 @@ const (
5160
HeritageTypeImplements HeritageType = "implements"
5261
)
5362

63+
// HeritageClause
64+
// interface Foo extends Bar, Baz {}
5465
type HeritageClause struct {
5566
Token HeritageType
5667
Args []ExpressionType

bindings/declarations.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Interface struct {
2626
func (*Interface) isNode() {}
2727
func (*Interface) isDeclarationType() {}
2828

29+
// PropertySignature is a field in an interface
2930
type PropertySignature struct {
3031
// Name is the field name
3132
Name string
@@ -85,6 +86,9 @@ func Simplify(p []*TypeParameter) ([]*TypeParameter, error) {
8586
return params, nil
8687
}
8788

89+
// VariableStatement is a top level declaration of a variable
90+
// var foo: string = "bar"
91+
// const foo: string = "bar"
8892
type VariableStatement struct {
8993
Modifiers []Modifier
9094
Declarations *VariableDeclarationList

bindings/expressions.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package bindings
22

3-
import "golang.org/x/xerrors"
3+
import (
4+
"fmt"
5+
6+
"golang.org/x/xerrors"
7+
)
48

59
// ExpressionType
610
type ExpressionType interface {
@@ -134,7 +138,15 @@ type OperatorNodeType struct {
134138
Type ExpressionType
135139
}
136140

141+
// OperatorNode allows adding a keyword to a type
142+
// Keyword must be "KeyOfKeyword" | "UniqueKeyword" | "ReadonlyKeyword"
137143
func OperatorNode(keyword LiteralKeyword, node ExpressionType) *OperatorNodeType {
144+
switch keyword {
145+
case KeywordReadonly, KeywordUnique, KeywordKeyOf:
146+
default:
147+
// TODO: Would be better to raise some error here.
148+
panic(fmt.Sprint("unsupported operator keyword: ", keyword))
149+
}
138150
return &OperatorNodeType{
139151
Keyword: keyword,
140152
Type: node,

bindings/parse.go

Lines changed: 0 additions & 44 deletions
This file was deleted.

builtins.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,20 @@ package guts
22

33
import "github.com/coder/guts/bindings"
44

5+
// Some references are built into either Golang or Typescript.
56
var (
7+
// builtInComparable is a reference to the 'comparable' type in Golang.
68
builtInComparable = bindings.Identifier{Name: "Comparable"}
7-
builtInString = bindings.Identifier{Name: "string"}
8-
builtInNumber = bindings.Identifier{Name: "number"}
9-
builtInBoolean = bindings.Identifier{Name: "boolean"}
10-
builtInRecord = bindings.Identifier{Name: "Record"}
9+
// builtInRecord is a reference to the 'Record' type in Typescript.
10+
builtInRecord = bindings.Identifier{Name: "Record"}
1111
)
1212

13+
// RecordReference creates a reference to the 'Record' type in Typescript.
14+
// The Record type takes in 2 type parameters, key and value.
15+
func RecordReference(key, value bindings.ExpressionType) *bindings.ReferenceType {
16+
return bindings.Reference(builtInRecord, key, value)
17+
}
18+
1319
func (ts *Typescript) includeComparable() {
1420
// The zzz just pushes it to the end of the sorting.
1521
// Kinda strange, but it works.
@@ -18,9 +24,9 @@ func (ts *Typescript) includeComparable() {
1824
Name: builtInComparable,
1925
Modifiers: []bindings.Modifier{},
2026
Type: bindings.Union(
21-
bindings.Reference(builtInString),
22-
bindings.Reference(builtInNumber),
23-
bindings.Reference(builtInBoolean),
27+
ptr(bindings.KeywordString),
28+
ptr(bindings.KeywordNumber),
29+
ptr(bindings.KeywordBoolean),
2430
),
2531
Parameters: []*bindings.TypeParameter{},
2632
Source: bindings.Source{},

cmd/gots/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/coder/guts/config"
99
)
1010

11+
// TODO: Build out a decent cli for this, just for easy experimentation.
1112
func main() {
1213
//ctx := context.Background()
1314
gen, err := guts.NewGolangParser()

config/doc.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Package config provides standard configurations for the guts package.
2+
// These configurations are useful for common use cases.
3+
package config

convert.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,7 @@ func (ts *Typescript) typescriptType(ty types.Type) (parsedType, error) {
786786
return parsedType{}, xerrors.Errorf("simplify generics in map: %w", err)
787787
}
788788
parsed := parsedType{
789-
Value: bindings.Reference(builtInRecord, keyType.Value, valueType.Value),
789+
Value: RecordReference(keyType.Value, valueType.Value),
790790
TypeParameters: tp,
791791
RaisedComments: append(keyType.RaisedComments, valueType.RaisedComments...),
792792
}

0 commit comments

Comments
 (0)