-
Notifications
You must be signed in to change notification settings - Fork 0
/
fs.go
106 lines (91 loc) · 2.67 KB
/
fs.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
package protocol
import (
"context"
"io/ioutil"
"log"
"github.com/john-nguyen09/phpintel/internal/jsonrpc2"
"github.com/john-nguyen09/phpintel/util"
"github.com/karrick/godirwalk"
)
// FS is an interface for reading files
type FS interface {
ConvertToURI(uri string) string
ReadFile(ctx context.Context, uri string) ([]byte, error)
ListFiles(ctx context.Context, base string) ([]TextDocumentIdentifier, error)
}
// URIFS is a LSP file reader which relies on xcontentProvider and xfilesProvider
// client capabilities
type URIFS struct {
conn *jsonrpc2.Conn
}
var _ FS = (*URIFS)(nil)
// NewLSPFS creates an URIFS instance from the connection
func NewLSPFS(conn *jsonrpc2.Conn) *URIFS {
return &URIFS{
conn: conn,
}
}
// ConvertToURI does nothing and return the path because it's already URI
func (f *URIFS) ConvertToURI(path string) string {
return path
}
// ReadFile uses textDocument/xcontent request to read content of the uri
func (f *URIFS) ReadFile(ctx context.Context, uri string) ([]byte, error) {
var textDocument TextDocumentItem
err := f.conn.Call(ctx, "textDocument/xcontent", &ContentParams{
TextDocument: TextDocumentIdentifier{
URI: uri,
},
}, &textDocument)
if err != nil {
return nil, err
}
return []byte(textDocument.Text), nil
}
// ListFiles uses workspace/xfiles request to list files under a base
func (f *URIFS) ListFiles(ctx context.Context, base string) (docs []TextDocumentIdentifier, err error) {
err = f.conn.Call(ctx, "workspace/xfiles", FilesParams{Base: base}, &docs)
return
}
// FileFS uses file path
type FileFS struct{}
// NewFileFS creates a FileFS instance
func NewFileFS() *FileFS {
return &FileFS{}
}
var _ FS = (*FileFS)(nil)
// ConvertToURI converts path to URI
func (f *FileFS) ConvertToURI(path string) string {
return util.PathToURI(path)
}
// ReadFile reads the file from uri, given that the uri is the file path
// rather than actually the URI
func (f *FileFS) ReadFile(ctx context.Context, uri string) ([]byte, error) {
path, err := util.URIToPath(uri)
if err != nil {
return nil, err
}
return ioutil.ReadFile(path)
}
// ListFiles lists files from the base
func (f *FileFS) ListFiles(ctx context.Context, base string) ([]TextDocumentIdentifier, error) {
var results []TextDocumentIdentifier
err := godirwalk.Walk(base, &godirwalk.Options{
Callback: func(path string, de *godirwalk.Dirent) error {
if !de.IsDir() {
results = append(results, TextDocumentIdentifier{
URI: path,
})
}
return nil
},
ErrorCallback: func(path string, err error) godirwalk.ErrorAction {
return godirwalk.SkipNode
},
Unsorted: true,
})
if err != nil {
log.Printf("FileFS.ListFiles error: %v", err)
}
return results, nil
}