-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsourcecode.py
More file actions
147 lines (127 loc) · 3.45 KB
/
sourcecode.py
File metadata and controls
147 lines (127 loc) · 3.45 KB
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
import ast
import os
from parser import Parser
from typing import Self
from common import DepType
from protocol.dep import SourceDep
from protocol.file import SourceFile
from protocol.pkg import SourcePkg
from utils import (
caculate_hash_id, # type: ignore
format_path,
is_source,
)
class Dir:
"""Class representing a directory"""
id: str
path: str
files: int
pkg: bool
imps: set[Self]
def __init__(self, path: str):
self.id = caculate_hash_id(path)
self.path = path
self.files = 0
self.pkg = False
self.imps = set()
def dump(self) -> SourcePkg:
noramlized_path = format_path(self.path)
imports = []
for i in self.imps:
imports.append(i.id)
name = os.path.basename(noramlized_path)
return {
"id": self.id,
"name": "/" if name == "" else name,
"path": noramlized_path,
"imports": imports,
"deps": [],
}
class File:
"""Class representing a file"""
id: str
path: str
name: str
dir: Dir
source: bool
ast: str
error: str
parser: Parser | None
imps: set[Self]
def __init__(self, path: str, dir: Dir):
assert dir != None
self.id = caculate_hash_id(path)
self.path = path
self.name = os.path.basename(path)
self.dir = dir
self.source = is_source(path)
self.error = ""
self.parser = None
self.dir_ptr = None
self.imps = set()
def parse(self, lookup: any):
with open(self.path, "r") as file:
content = file.read()
self.ast = ast.parse(content)
self.parser = Parser(self, lookup)
self.parser.parse_source()
def connect(self):
for d in self.parser.deps.values():
if d.typ == DepType.FILE:
f = d.file_ptr
self.imps.add(f)
def liftup(self):
for f in self.imps:
if self.dir != f.dir:
self.dir.imps.add(f.dir)
def dump(self) -> SourceFile:
noramlized_path = format_path(self.dir.path)
imports = []
if self.source:
for i in self.imps:
imports.append(i.id)
# TODO: support normal deps in import parse
# deps = set()
# if self.source:
# for d in self.parser.deps.values():
# deps.add(d.id)
result = {
"id": self.id,
"name": self.name,
"path": noramlized_path,
"pkg": self.dir.id,
"imports": imports,
# "deps": [item for item in deps],
"deps": [],
}
return result
class Dep:
"""Class representing a dependency"""
id: str
name: str
typ: DepType
file_ptr: str
pkg_ptr: str
def __init__(self, ptr: File | Dir, typ: DepType):
self.id = caculate_hash_id(ptr.path)
self.name = ptr.path
self.typ = typ
if typ == DepType.PKG:
self.pkg_ptr = ptr
else:
self.file_ptr = ptr
def dump(self) -> SourceDep:
assert self.typ != DepType.PKG
type = "file"
if self.typ == DepType.MOD:
type = "mod"
else:
# trapped into panic
type = "pkg"
result = {
"id": self.id,
"name": self.name,
"type": type,
"ref": "",
}
return result