-
Notifications
You must be signed in to change notification settings - Fork 1
/
parse.go
149 lines (127 loc) · 3.49 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2018 Roberto Mier Escandon <rmescandon@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package io
import (
"bytes"
"fmt"
"go/ast"
"go/parser"
"go/printer"
"go/token"
"os"
"path/filepath"
)
// ByteArrayToAST composes syntax tree from a byte array content
func ByteArrayToAST(buf []byte) (*ast.File, error) {
return parser.ParseFile(token.NewFileSet(), "", buf, 0)
}
// StringToAST composes syntax tree from a string
func StringToAST(str string) (*ast.File, error) {
return parser.ParseFile(token.NewFileSet(), "", str, 0)
}
// ASTToString returns a syntax tree as a string
func ASTToString(ast *ast.File) (string, error) {
b, err := astToBuffer(ast)
return b.String(), err
}
// ASTToByteArray returns a syntax tree as a byte array
func ASTToByteArray(ast *ast.File) ([]byte, error) {
b, err := astToBuffer(ast)
return b.Bytes(), err
}
func astToBuffer(ast *ast.File) (bytes.Buffer, error) {
var buf bytes.Buffer
err := printer.Fprint(&buf, token.NewFileSet(), ast)
return buf, err
}
// TraceAST prints out AST file content
func TraceAST(f *ast.File) error {
return ast.Print(token.NewFileSet(), f)
}
// FileToString reads file content and stores it in a string
func FileToString(file string) (string, error) {
b, err := fileToBuffer(file)
if err != nil {
return "", err
}
return b.String(), nil
}
// FileToByteArray reads file content and stores it in a byte array
func FileToByteArray(file string) ([]byte, error) {
b, err := fileToBuffer(file)
if err != nil {
return nil, err
}
return b.Bytes(), nil
}
// StringToFile writes a strint to a file
func StringToFile(content, filepath string) error {
return writeToFile(content, filepath)
}
// ByteArrayToFile writes a buffer to a file
func ByteArrayToFile(content []byte, filepath string) error {
return writeToFile(content, filepath)
}
// ASTToFile writes a syntax tree to file
func ASTToFile(ast *ast.File, file string) error {
err := EnsureDir(filepath.Dir(file))
if err != nil {
return err
}
f, err := os.Create(file)
if err != nil {
return fmt.Errorf("Could not create %v: %v", file, err)
}
defer f.Close()
return printer.Fprint(f, token.NewFileSet(), ast)
}
// writeToFile writes a string content to a file
func writeToFile(content interface{}, file string) error {
err := EnsureDir(filepath.Dir(file))
if err != nil {
return err
}
f, err := os.Create(file)
if err != nil {
return fmt.Errorf("Could not create %v: %v", file, err)
}
defer f.Close()
switch content.(type) {
case []byte:
_, err = f.Write(content.([]byte))
case string:
_, err = f.WriteString(content.(string))
}
if err != nil {
return fmt.Errorf("Error writing to output %v: %v", file, err)
}
return nil
}
func fileToBuffer(file string) (*bytes.Buffer, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
buf := new(bytes.Buffer)
_, err = buf.ReadFrom(f)
if err != nil {
return nil, err
}
return buf, nil
}