-
Notifications
You must be signed in to change notification settings - Fork 7
/
get_file_view.go
108 lines (87 loc) 路 2.71 KB
/
get_file_view.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
package server
import (
"errors"
"strings"
src "github.com/nevalang/neva/internal/compiler/sourcecode"
"github.com/tliron/glsp"
)
type GetFileViewRequest struct {
WorkspaceURI URI `json:"workspaceUri"`
Document struct {
URI URI `json:"uri"`
FileName string `json:"fileName"`
} `json:"document"`
}
type URI struct {
Path string `json:"path"`
FSPath string `json:"fsPath"`
}
type GetFileViewResponce struct {
File src.File `json:"file"`
Extra Extra `json:"extra"` // info that is not presented in the file but needed for rendering
}
type Extra struct {
NodesPorts map[string]map[string]src.Interface `json:"nodesPorts"` // components -> nodes -> interface
}
func (s *Server) GetFileView(glspCtx *glsp.Context, req GetFileViewRequest) (GetFileViewResponce, error) {
if s.index == nil {
return GetFileViewResponce{}, nil
}
relFilePath := strings.TrimPrefix(req.Document.FileName, req.WorkspaceURI.Path)
relFilePath = strings.TrimPrefix(relFilePath, "/")
relPathParts := strings.Split(relFilePath, "/") // relative path to file in slice
relPathLastPart := relPathParts[len(relPathParts)-1] // file name with extension
relPartsWithoutFile := relPathParts[:len(relPathParts)-1] // relative path to package
pkgName := strings.Join(relPartsWithoutFile, "/")
fileName := strings.TrimSuffix(relPathLastPart, ".neva")
scope := src.Scope{
Location: src.Location{
ModRef: s.index.EntryModRef,
PkgName: pkgName,
FileName: fileName,
},
Build: *s.index,
}
pkg, ok := s.index.Modules[s.index.EntryModRef].Packages[pkgName]
if !ok {
return GetFileViewResponce{}, errors.New("no such package: " + pkgName)
}
file, ok := pkg[fileName]
if !ok {
return GetFileViewResponce{}, errors.New("no such file: " + fileName + "." + pkgName)
}
extra, err := getExtraForFile(file, scope)
if err != nil {
return GetFileViewResponce{}, err
}
return GetFileViewResponce{
File: file,
Extra: Extra{
NodesPorts: extra,
},
}, nil
}
func getExtraForFile(file src.File, scope src.Scope) (map[string]map[string]src.Interface, error) {
extra := map[string]map[string]src.Interface{}
for entityName, entity := range file.Entities {
if entity.Kind != src.ComponentEntity {
continue
}
nodesIfaces := map[string]src.Interface{}
for nodeName, node := range entity.Component.Nodes {
nodeEntity, _, err := scope.Entity(node.EntityRef)
if err != nil {
return nil, err
}
var iface src.Interface
if nodeEntity.Kind == src.ComponentEntity {
iface = nodeEntity.Component.Interface
} else if nodeEntity.Kind == src.InterfaceEntity {
iface = nodeEntity.Interface
}
nodesIfaces[nodeName] = iface
}
extra[entityName] = nodesIfaces
}
return extra, nil
}