Skip to content

Commit 45c43af

Browse files
authored
fix: compatible unmarshal historical version of AST json (#23)
* feat: add flag `-repo-id` for specify repoid * opt:(uniast) add `json.Unmarshaler` to be compatible with old version * add recover back
1 parent e7ef3e5 commit 45c43af

File tree

5 files changed

+97
-37
lines changed

5 files changed

+97
-37
lines changed

lang/golang/parser/file.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ import (
2929
func (p *GoParser) parseFile(ctx *fileContext, f *ast.File) error {
3030
cont := true
3131
ast.Inspect(f, func(node ast.Node) bool {
32-
// defer func() {
33-
// if r := recover(); r != nil {
34-
// fmt.Fprintf(os.Stderr, "panic: %v in %s:%d\n", r, ctx.filePath, ctx.fset.Position(node.Pos()).Line)
35-
// cont = false
36-
// return
37-
// }
38-
// }()
32+
defer func() {
33+
if r := recover(); r != nil {
34+
fmt.Fprintf(os.Stderr, "panic: %v in %s:%d\n", r, ctx.filePath, ctx.fset.Position(node.Pos()).Line)
35+
cont = false
36+
return
37+
}
38+
}()
3939
if funcDecl, ok := node.(*ast.FuncDecl); ok {
4040
// parse funcs
4141
_, ct := p.parseFunc(ctx, funcDecl)

lang/golang/parser/utils.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,11 @@ func isPkgScope(scope *types.Scope) bool {
175175
func getTypeKind(n ast.Expr) TypeKind {
176176
switch n.(type) {
177177
case *ast.StructType:
178-
return "struct"
178+
return TypeKindStruct
179179
case *ast.InterfaceType:
180-
return "interface"
180+
return TypeKindInterface
181181
default:
182-
return "typedef"
182+
return TypeKindTypedef
183183
}
184184
}
185185

lang/parse.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ type ParseOptions struct {
4040
// Language of the repo
4141
Verbose bool
4242
collect.CollectOption
43+
// specify the repo id
44+
RepoID string
4345
}
4446

4547
func Parse(ctx context.Context, uri string, args ParseOptions) ([]byte, error) {
@@ -78,6 +80,11 @@ func Parse(ctx context.Context, uri string, args ParseOptions) ([]byte, error) {
7880
return nil, err
7981
}
8082
log.Info("all symbols collected, start writing to stdout...\n")
83+
84+
if args.RepoID != "" {
85+
repo.Name = args.RepoID
86+
}
87+
8188
out, err := json.Marshal(repo)
8289
if err != nil {
8390
log.Error("Failed to marshal repository: %v\n", err)

lang/uniast/ast.go

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@
1717
package uniast
1818

1919
import (
20+
"encoding/json"
2021
"fmt"
2122
"os"
2223
"path/filepath"
24+
"strconv"
2325
"strings"
2426
)
2527

@@ -103,6 +105,28 @@ type Import struct {
103105
Path string
104106
}
105107

108+
func (i *Import) UnmarshalJSON(data []byte) error {
109+
if len(data) >= 2 && data[0] == '"' && data[len(data)-1] == '"' {
110+
v, e := strconv.Unquote(string(data))
111+
if e != nil {
112+
return e
113+
}
114+
i.Path = v
115+
return nil
116+
} else {
117+
var ii importObj
118+
err := json.Unmarshal(data, &ii)
119+
if err != nil {
120+
return err
121+
}
122+
i.Alias = ii.Alias
123+
i.Path = ii.Path
124+
return nil
125+
}
126+
}
127+
128+
type importObj Import
129+
106130
func NewImport(alias *string, path string) Import {
107131
return Import{
108132
Alias: alias,
@@ -448,6 +472,31 @@ type FileLine struct {
448472

449473
type TypeKind string
450474

475+
const (
476+
TypeKindStruct TypeKind = "struct"
477+
TypeKindInterface TypeKind = "interface"
478+
TypeKindTypedef TypeKind = "typedef"
479+
TypeKindEnum TypeKind = "enum"
480+
)
481+
482+
func (t *TypeKind) UnmarshalJSON(data []byte) error {
483+
if len(data) >= 2 && data[0] == '"' && data[len(data)-1] == '"' {
484+
*t = TypeKind(data[1 : len(data)-1])
485+
return nil
486+
}
487+
488+
// 兼容历史go ast
489+
switch string(data) {
490+
case "0":
491+
*t = TypeKindStruct
492+
case "1":
493+
*t = TypeKindInterface
494+
default:
495+
*t = TypeKindTypedef
496+
}
497+
return nil
498+
}
499+
451500
// const (
452501
// TypeKindStruct = 0 // type struct
453502
// TypeKindInterface = 1 // type interface
@@ -459,7 +508,8 @@ type TypeKind string
459508
type Type struct {
460509
Exported bool // if the struct is exported
461510

462-
TypeKind // type Kind: Struct / Interface / Typedef
511+
TypeKind TypeKind // type Kind: Struct / Interface / Typedef
512+
463513
Identity // unique id in a repo
464514
FileLine
465515
Content string // struct declaration content

main.go

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,48 +51,56 @@ Action:
5151
Language:
5252
rust for rust codes
5353
go for golang codes
54-
URI:
55-
for action parse: the directory path of the repo
56-
for action write: the file path of the UniAST for writer
5754
`
5855

5956
func main() {
6057
flags := flag.NewFlagSet("abcoder", flag.ExitOnError)
58+
59+
flagHelp := flags.Bool("h", false, "Show help message.")
60+
61+
flagVerbose := flags.Bool("verbose", false, "Verbose mode.")
62+
63+
flagOutput := flags.String("o", "", "Output path.")
64+
65+
var opts lang.ParseOptions
66+
flags.BoolVar(&opts.LoadExternalSymbol, "load-external-symbol", false, "load external symbols into results")
67+
flags.BoolVar(&opts.NoNeedComment, "no-need-comment", false, "do not need comment (only works for Go now)")
68+
flags.BoolVar(&opts.NeedTest, "need-test", false, "need parse test files (only works for Go now)")
69+
flags.Var((*StringArray)(&opts.Excludes), "exclude", "exclude files or directories, support multiple values")
70+
flags.StringVar(&opts.RepoID, "repo-id", "", "specify the repo id")
71+
flagLsp := flags.String("lsp", "", "Specify the language server path.")
72+
73+
var wopts lang.WriteOptions
74+
flags.StringVar(&wopts.Compiler, "compiler", "", "destination compiler path.")
75+
6176
flags.Usage = func() {
62-
fmt.Fprintf(os.Stderr, Usage)
77+
fmt.Fprint(os.Stderr, Usage)
6378
fmt.Fprintf(os.Stderr, "Flags:\n")
6479
flags.PrintDefaults()
6580
}
6681

6782
if len(os.Args) < 4 {
68-
fmt.Fprintf(os.Stderr, Usage)
83+
// call flags.Usage()
84+
flags.Usage()
6985
os.Exit(1)
7086
}
71-
7287
action := strings.ToLower(os.Args[1])
7388
language := uniast.NewLanguage(os.Args[2])
7489
if language == uniast.Unknown {
7590
fmt.Fprintf(os.Stderr, "unsupported language: %s\n", os.Args[2])
7691
os.Exit(1)
7792
}
78-
7993
uri := os.Args[3]
8094

81-
flagVerbose := flags.Bool("verbose", false, "Verbose mode.")
82-
83-
flagOutput := flags.String("o", "", "Output path.")
95+
flags.Parse(os.Args[4:])
96+
if flagHelp != nil && *flagHelp {
97+
flags.Usage()
98+
os.Exit(0)
99+
}
84100

85101
switch action {
86102
case "parse":
87-
var opts lang.ParseOptions
88-
89-
flags.BoolVar(&opts.LoadExternalSymbol, "load-external-symbol", false, "load external symbols into results")
90-
flags.BoolVar(&opts.NoNeedComment, "no-need-comment", false, "do not need comment (only works for Go now)")
91-
flags.BoolVar(&opts.NeedTest, "need-test", false, "need parse test files (only works for Go now)")
92-
flags.Var((*StringArray)(&opts.Excludes), "exclude", "exclude files or directories, support multiple values")
93-
flagLsp := flags.String("lsp", "", "Specify the language server path.")
94103

95-
flags.Parse(os.Args[4:])
96104
if flagVerbose != nil && *flagVerbose {
97105
log.SetLogLevel(log.DebugLevel)
98106
opts.Verbose = true
@@ -123,21 +131,16 @@ func main() {
123131
os.Exit(1)
124132
}
125133

126-
var opts lang.WriteOptions
127-
flags.StringVar(&opts.Compiler, "compiler", "", "destination compiler path.")
128-
129-
flags.Parse(os.Args[4:])
130-
131134
if flagVerbose != nil && *flagVerbose {
132135
log.SetLogLevel(log.DebugLevel)
133136
}
134137
if flagOutput != nil && *flagOutput != "" {
135-
opts.OutputDir = *flagOutput
138+
wopts.OutputDir = *flagOutput
136139
} else {
137-
opts.OutputDir = filepath.Base(repo.Name)
140+
wopts.OutputDir = filepath.Base(repo.Name)
138141
}
139142

140-
if err := lang.Write(context.Background(), repo, opts); err != nil {
143+
if err := lang.Write(context.Background(), repo, wopts); err != nil {
141144
log.Error("Failed to write: %v\n", err)
142145
os.Exit(1)
143146
}

0 commit comments

Comments
 (0)