Skip to content

Commit c25755d

Browse files
committed
feat: Initial implementation, focused on parsing type definitions
1 parent 756e65e commit c25755d

40 files changed

+3414
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

.github/dependabot.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/SchemaStore/schemastore/master/src/schemas/json/dependabot-2.0.json
2+
version: 2
3+
updates:
4+
- directory: /
5+
package-ecosystem: gomod
6+
schedule:
7+
interval: monthly
8+
commit-message:
9+
prefix: chore
10+
include: scope
11+
- directory: /
12+
package-ecosystem: github-actions
13+
schedule:
14+
interval: monthly
15+
commit-message:
16+
prefix: chore
17+
include: scope

.github/release-please-config.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3+
"packages": {
4+
".": {
5+
"release-type": "go",
6+
"bump-minor-pre-major": true,
7+
"include-v-in-tag": true
8+
}
9+
}
10+
}

.github/workflows/ci.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request: {}
8+
workflow_dispatch: {}
9+
10+
jobs:
11+
test:
12+
runs-on: ubuntu-latest
13+
strategy:
14+
matrix:
15+
go-version: ["1.20", "1.21", "1.22"]
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-go@v5
19+
with:
20+
go-version: ${{ matrix.go-version }}
21+
- run: go test -cover ./...
22+
23+
lint:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v4
27+
- uses: actions/setup-go@v5
28+
- uses: golangci/golangci-lint-action@v6
29+
with:
30+
version: v1.59.1
31+
32+
release-please:
33+
runs-on: ubuntu-latest
34+
needs: [test, lint]
35+
if: github.ref == 'refs/heads/main'
36+
steps:
37+
- uses: googleapis/release-please-action@v4
38+
id: release-please
39+
with:
40+
token: ${{ secrets.PAT }}
41+
config-file: .github/release-please-config.json
42+
manifest-file: .github/.release-please-manifest.json

.golangci.yaml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# See https://golangci-lint.run/usage/configuration/
2+
3+
linters:
4+
disable-all: true
5+
enable:
6+
# See https://golangci-lint.run/usage/linters/
7+
- asasalint # Check for pass []any as any in variadic func(...any).
8+
- bodyclose # Checks whether HTTP response body is closed successfully.
9+
- contextcheck # Check whether the function uses a non-inherited context.
10+
- durationcheck # Check for two durations multiplied together.
11+
- errcheck # Checks whether Rows.Err of rows is checked successfully.
12+
- errchkjson # Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted.
13+
- errorlint # Errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
14+
- forbidigo # Forbids identifiers.
15+
- gci # Gci controls Go package import order and makes it always deterministic.
16+
- gocritic # Provides diagnostics that check for bugs, performance and style issues. Extensible without recompilation through dynamic rules. Dynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion.
17+
- godot # Check if comments end in a period.
18+
- gosec # Inspects source code for security problems.
19+
- gosimple # Linter for Go source code that specializes in simplifying code.
20+
- govet # Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string.
21+
- inamedparam # Reports interfaces with unnamed method parameters.
22+
- ineffassign # Detects when assignments to existing variables are not used.
23+
- mirror # Reports wrong mirror patterns of bytes/strings usage.
24+
- misspell # Finds commonly misspelled English words.
25+
- musttag # Enforce field tags in (un)marshaled structs.
26+
- nilerr # Finds the code that returns nil even if it checks that the error is not nil.
27+
- nilnil # Checks that there is no simultaneous return of nil error and an invalid value.
28+
- noctx # Finds sending http request without context.Context.
29+
- nolintlint # Reports ill-formed or insufficient nolint directives.
30+
- nosprintfhostport # Checks for misuse of Sprintf to construct a host with port in a URL.
31+
- perfsprint # Checks that fmt.Sprintf can be replaced with a faster alternative.
32+
- protogetter # Reports direct reads from proto message fields when getters should be used.
33+
- reassign # Checks that package variables are not reassigned.
34+
- revive # Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint.
35+
- staticcheck # It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint.
36+
- tenv # # Tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17.
37+
- unconvert # Remove unnecessary type conversions.
38+
- unused # Checks Go code for unused constants, variables, functions and types.
39+
40+
linters-settings:
41+
# See https://golangci-lint.run/usage/linters/#linters-configuration
42+
forbidigo:
43+
forbid:
44+
- 'fmt\.Print.*' # Should be using a logger
45+
gci:
46+
sections:
47+
- standard
48+
- default
49+
- prefix(github.com/armsnyder)
50+
gocritic:
51+
enabled-tags:
52+
- performance
53+
- opinionated
54+
- experimental
55+
disabled-checks:
56+
- whyNoLint # False positives, use nolintlint instead
57+
govet:
58+
enable-all: true
59+
disable:
60+
- fieldalignment # Too struct
61+
nolintlint:
62+
require-specific: true
63+
revive:
64+
enable-all-rules: true
65+
rules:
66+
# See https://revive.run/r
67+
- name: add-constant # too strict
68+
disabled: true
69+
- name: argument-limit # too strict
70+
disabled: true
71+
- name: cognitive-complexity
72+
arguments:
73+
- 30
74+
- name: cyclomatic
75+
arguments:
76+
- 30
77+
- name: file-header # too strict
78+
disabled: true
79+
- name: function-length
80+
arguments:
81+
- 50 # statements
82+
- 0 # lines (0 to disable)
83+
- name: function-result-limit # too strict
84+
disabled: true
85+
- name: import-shadowing # too strict, results in uglier code
86+
disabled: true
87+
- name: line-length-limit # too strict
88+
disabled: true
89+
- name: max-public-structs # too strict
90+
disabled: true
91+
- name: modifies-parameter # too strict
92+
disabled: true
93+
- name: modifies-value-receiver # too strict
94+
disabled: true
95+
- name: nested-structs # too strict
96+
disabled: true
97+
- name: package-comments # too strict
98+
disabled: true
99+
- name: unhandled-error
100+
disabled: true # not as good as errcheck
101+
102+
issues:
103+
exclude-rules:
104+
- path: _test\.go$
105+
linters:
106+
- gosec # too strict
107+
- noctx # too strict
108+
- path: _test\.go$
109+
text: (cognitive-complexity|function-length|dot-imports|import-alias-naming) # too strict
110+
linters:
111+
- revive
112+
# Shadowing err is common.
113+
- text: 'shadow: declaration of "err"'
114+
linters:
115+
- govet
116+
- text: "^exported:.+stutters" # too strict and gets in the way of combining types like handlers
117+
linters:
118+
- revive
119+
- path: _test\.go$
120+
text: "unused-parameter" # too strict

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Adam Snyder
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# TypeScript AST
2+
3+
This library provides a way to parse TypeScript source code into an abstract
4+
syntax tree (AST) in Golang. The packages are laid out similar to the standard
5+
[go](https://pkg.go.dev/go) library.
6+
7+
[Package Documentation](https://pkg.go.dev/github.com/armsnyder/typescript-ast-go)
8+
9+
The main two packages are:
10+
11+
- [parser](https://pkg.go.dev/github.com/armsnyder/typescript-ast-go/parser):
12+
Parse TypeScript source code into an AST.
13+
- [ast](https://pkg.go.dev/github.com/armsnyder/typescript-ast-go/ast): The
14+
AST nodes and visitor for TypeScript source code.
15+
16+
This library was originally created in order to parse TypeScript type
17+
definitions specifically for the Language Server Protocol Specification. As a
18+
result, it is not feature complete and may not work for all TypeScript source
19+
code.

ast/ast.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Package ast defines the abstract syntax tree (AST) for the TypeScript
2+
// programming language and provides functionality for traversing the AST.
3+
package ast
4+
5+
// Node is a common interface that all nodes in the AST implement.
6+
type Node interface {
7+
node()
8+
}

ast/expression.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package ast
2+
3+
import "github.com/armsnyder/typescript-ast-go/token"
4+
5+
// Expr is a [Node] that represents an expression. An expression produces a
6+
// value.
7+
type Expr interface {
8+
Node
9+
expr()
10+
}
11+
12+
// NumericLiteral is a numeric literal expression.
13+
type NumericLiteral struct {
14+
Text string
15+
}
16+
17+
func (n *NumericLiteral) String() string {
18+
return n.Text
19+
}
20+
21+
func (*NumericLiteral) node() {}
22+
func (*NumericLiteral) expr() {}
23+
24+
// StringLiteral is a string literal expression.
25+
type StringLiteral struct {
26+
Text string
27+
}
28+
29+
func (n *StringLiteral) String() string {
30+
return n.Text
31+
}
32+
33+
func (*StringLiteral) node() {}
34+
func (*StringLiteral) expr() {}
35+
36+
// ArrayLiteralExpression is an array literal expression.
37+
type ArrayLiteralExpression struct {
38+
Elements []Expr
39+
}
40+
41+
func (*ArrayLiteralExpression) node() {}
42+
func (*ArrayLiteralExpression) expr() {}
43+
44+
// Identifier is an identifier literal expression.
45+
type Identifier struct {
46+
Text string
47+
}
48+
49+
func (n *Identifier) String() string {
50+
return n.Text
51+
}
52+
53+
func (*Identifier) node() {}
54+
func (*Identifier) expr() {}
55+
56+
// QualifiedName is a qualified name expression.
57+
type QualifiedName struct {
58+
Left *Identifier
59+
Right *Identifier
60+
}
61+
62+
func (*QualifiedName) node() {}
63+
func (*QualifiedName) expr() {}
64+
65+
// EnumMember is an enum member expression.
66+
type EnumMember struct {
67+
Name *Identifier
68+
Initializer Expr
69+
LeadingComment string
70+
}
71+
72+
func (n *EnumMember) String() string {
73+
return n.LeadingComment
74+
}
75+
76+
func (*EnumMember) node() {}
77+
func (*EnumMember) expr() {}
78+
79+
// TypeParameter is a type parameter expression.
80+
type TypeParameter struct {
81+
Name *Identifier
82+
}
83+
84+
func (*TypeParameter) node() {}
85+
func (*TypeParameter) expr() {}
86+
87+
// HeritageClause is a heritage clause expression.
88+
type HeritageClause struct {
89+
Types []*ExpressionWithTypeArguments
90+
}
91+
92+
func (*HeritageClause) node() {}
93+
func (*HeritageClause) expr() {}
94+
95+
// ExpressionWithTypeArguments is an expression with type arguments.
96+
type ExpressionWithTypeArguments struct {
97+
Expression *Identifier
98+
}
99+
100+
func (*ExpressionWithTypeArguments) node() {}
101+
func (*ExpressionWithTypeArguments) expr() {}
102+
103+
// Parameter is a parameter expression.
104+
type Parameter struct {
105+
Name *Identifier
106+
Type Type
107+
}
108+
109+
func (*Parameter) node() {}
110+
func (*Parameter) expr() {}
111+
112+
// VariableDeclarationList is an expression that declares a list of variables.
113+
type VariableDeclarationList struct {
114+
Declarations []*VariableDeclaration
115+
}
116+
117+
func (*VariableDeclarationList) node() {}
118+
func (*VariableDeclarationList) expr() {}
119+
120+
// VariableDeclaration is an expression that declares a variable.
121+
type VariableDeclaration struct {
122+
Name *Identifier
123+
Type Type
124+
Initializer Expr
125+
}
126+
127+
func (*VariableDeclaration) node() {}
128+
func (*VariableDeclaration) expr() {}
129+
130+
// PrefixUnaryExpression is an expression that applies a unary operator to an
131+
// operand.
132+
type PrefixUnaryExpression struct {
133+
Operator token.Kind
134+
Operand Expr
135+
}
136+
137+
func (*PrefixUnaryExpression) node() {}
138+
func (*PrefixUnaryExpression) expr() {}

0 commit comments

Comments
 (0)