code-intelligence 2.0.2__py3-none-win_amd64.whl → 3.0.1__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- code_intelligence/__init__.py +10 -19
- code_intelligence/goober.py +209 -0
- code_intelligence/libcode_intelligence.h +119 -0
- code_intelligence/libcode_intelligence.so +0 -0
- {code_intelligence-2.0.2.dist-info → code_intelligence-3.0.1.dist-info}/METADATA +1 -1
- code_intelligence-3.0.1.dist-info/RECORD +8 -0
- code_intelligence/_code_intelligence.dll +0 -0
- code_intelligence-2.0.2.dist-info/RECORD +0 -6
- {code_intelligence-2.0.2.dist-info → code_intelligence-3.0.1.dist-info}/WHEEL +0 -0
code_intelligence/__init__.py
CHANGED
|
@@ -1,27 +1,18 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .goober import (
|
|
2
2
|
Language,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ImmediateSymbolDatabase,
|
|
8
|
-
LazySymbolDatabase,
|
|
9
|
-
AsyncSymbolDatabase,
|
|
10
|
-
AsyncResult,
|
|
3
|
+
Definition_Link,
|
|
4
|
+
scan_file,
|
|
5
|
+
find_symbols_in_text,
|
|
6
|
+
stop,
|
|
11
7
|
)
|
|
12
8
|
|
|
13
|
-
__version__ = "
|
|
9
|
+
__version__ = "3.0.1"
|
|
14
10
|
__version_info__ = tuple(int(i) for i in __version__.split('.'))
|
|
15
11
|
|
|
16
12
|
__all__ = [
|
|
17
13
|
"Language",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"ImmediateSymbolDatabase",
|
|
23
|
-
"LazySymbolDatabase",
|
|
24
|
-
"AsyncSymbolDatabase",
|
|
25
|
-
"AsyncResult",
|
|
26
|
-
"SymbolDatabase",
|
|
14
|
+
"Definition_Link",
|
|
15
|
+
"scan_file",
|
|
16
|
+
"find_symbols_in_text",
|
|
17
|
+
"stop",
|
|
27
18
|
]
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import ctypes as C
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
import threading
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from dataclasses import dataclass, fields
|
|
8
|
+
from enum import IntEnum, IntFlag
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Language(IntEnum):
|
|
12
|
+
UNKNOWN = 0
|
|
13
|
+
PYTHON = 1
|
|
14
|
+
JAVASCRIPT = 2
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
DIR = Path(__file__).parent
|
|
18
|
+
|
|
19
|
+
_lib = C.CDLL(str(DIR / "libcode_intelligence.so"))
|
|
20
|
+
|
|
21
|
+
SCAN_CALLBACK = C.CFUNCTYPE(None, C.c_void_p)
|
|
22
|
+
_lib.enqueue_scan_file.argtypes = [SCAN_CALLBACK, C.c_void_p, C.c_char_p, C.c_uint64]
|
|
23
|
+
_lib.enqueue_scan_file.restype = None
|
|
24
|
+
|
|
25
|
+
class Definition_Link_C(C.Structure):
|
|
26
|
+
_fields_ = [
|
|
27
|
+
("start_offset_in_text", C.c_uint32),
|
|
28
|
+
("end_offset_in_text" , C.c_uint32),
|
|
29
|
+
("source_file" , C.c_char_p),
|
|
30
|
+
("line_0_based" , C.c_uint32),
|
|
31
|
+
("column_0_based" , C.c_uint32),
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
FIND_CALLBACK = C.CFUNCTYPE(None, C.c_void_p, C.POINTER(Definition_Link_C), C.c_int, C.c_void_p)
|
|
35
|
+
_lib.enqueue_find_symbols_in_text.argtypes = [FIND_CALLBACK, C.c_void_p, C.c_char_p]
|
|
36
|
+
_lib.enqueue_find_symbols_in_text.restype = None
|
|
37
|
+
|
|
38
|
+
_lib.enqueue_stop.argtypes = []
|
|
39
|
+
_lib.enqueue_stop.restype = None
|
|
40
|
+
|
|
41
|
+
_lib.get_pending_tasks_count.argtypes = []
|
|
42
|
+
_lib.get_pending_tasks_count.restype = C.c_uint64
|
|
43
|
+
|
|
44
|
+
_lib.free_memory.argtypes = [C.c_void_p]
|
|
45
|
+
_lib.free_memory.restype = None
|
|
46
|
+
|
|
47
|
+
# --- CPYTHON C API ACCESS ---
|
|
48
|
+
C.pythonapi.Py_IncRef.argtypes = [C.py_object]
|
|
49
|
+
C.pythonapi.Py_IncRef.restype = None
|
|
50
|
+
C.pythonapi.Py_DecRef.argtypes = [C.py_object]
|
|
51
|
+
C.pythonapi.Py_DecRef.restype = None
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def positional_repr(cls):
|
|
55
|
+
def __repr__(self):
|
|
56
|
+
values = ', '.join(repr(getattr(self, f.name)) for f in fields(self))
|
|
57
|
+
return f"{cls.__name__}({values})"
|
|
58
|
+
cls.__repr__ = __repr__
|
|
59
|
+
return cls
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass
|
|
63
|
+
@positional_repr
|
|
64
|
+
class Definition_Link:
|
|
65
|
+
start_offset_in_text: int = 0
|
|
66
|
+
end_offset_in_text : int = 0
|
|
67
|
+
source_file : str = ""
|
|
68
|
+
line_0_based : int = 0
|
|
69
|
+
column_0_based : int = 0
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# IMPORTANT: KEEP THIS ALIVE FOR GO THREAD WORKER
|
|
73
|
+
C_NO_CALLBACK = SCAN_CALLBACK(0)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _wrap_data_ptr(callback, data):
|
|
77
|
+
full_data = (callback, data)
|
|
78
|
+
|
|
79
|
+
# MANUALLY INCREMENT THE REFERENCE COUNT
|
|
80
|
+
# We are now responsible for its lifetime
|
|
81
|
+
C.pythonapi.Py_IncRef(full_data)
|
|
82
|
+
|
|
83
|
+
return id(full_data)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _unwrap_data_ptr(data_ptr):
|
|
87
|
+
assert data_ptr != 0, "we got NULL"
|
|
88
|
+
|
|
89
|
+
full_data = C.cast(data_ptr, C.py_object).value
|
|
90
|
+
|
|
91
|
+
# MANUALLY DECREMENT THE REFERENCE COUNT.
|
|
92
|
+
# We are fulfilling our promise
|
|
93
|
+
C.pythonapi.Py_DecRef(full_data)
|
|
94
|
+
|
|
95
|
+
return full_data
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def scan_file(file, language: Language, callback=None, data=None) -> bool:
|
|
99
|
+
if callback is None:
|
|
100
|
+
c_callback, data_ptr = C_NO_CALLBACK, 0
|
|
101
|
+
else:
|
|
102
|
+
c_callback, data_ptr = C_AFTER_SCAN, _wrap_data_ptr(callback, data)
|
|
103
|
+
|
|
104
|
+
# print(f"[PY] sending next request {file}")
|
|
105
|
+
_lib.enqueue_scan_file(c_callback, data_ptr, os.fsencode(file), language)
|
|
106
|
+
|
|
107
|
+
# never drop the request (it would be a memory leak)
|
|
108
|
+
return True
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@SCAN_CALLBACK
|
|
112
|
+
def C_AFTER_SCAN(data_ptr):
|
|
113
|
+
callback, data = _unwrap_data_ptr(data_ptr)
|
|
114
|
+
if callback is not None:
|
|
115
|
+
callback(data)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def find_symbols_in_text(text: str, callback=None, data=None) -> bool:
|
|
119
|
+
if callback is None:
|
|
120
|
+
c_callback, data_ptr = C_NO_CALLBACK, 0
|
|
121
|
+
else:
|
|
122
|
+
c_callback, data_ptr = C_AFTER_FIND, _wrap_data_ptr(callback, data)
|
|
123
|
+
|
|
124
|
+
# print("[PY] sending find_symbols_in_text")
|
|
125
|
+
_lib.enqueue_find_symbols_in_text(c_callback, data_ptr, text.encode())
|
|
126
|
+
|
|
127
|
+
# never drop the request (it would be a memory leak)
|
|
128
|
+
return True
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@FIND_CALLBACK
|
|
132
|
+
def C_AFTER_FIND(data_ptr, links_ptr, count, strings_handle):
|
|
133
|
+
callback, data = _unwrap_data_ptr(data_ptr)
|
|
134
|
+
try:
|
|
135
|
+
if callback is not None:
|
|
136
|
+
results = [Definition_Link()] * count
|
|
137
|
+
for i in range(count):
|
|
138
|
+
link = links_ptr[i]
|
|
139
|
+
results[i] = Definition_Link(
|
|
140
|
+
start_offset_in_text=link.start_offset_in_text,
|
|
141
|
+
end_offset_in_text=link.end_offset_in_text,
|
|
142
|
+
source_file=link.source_file.decode('utf-8'),
|
|
143
|
+
line_0_based=link.line_0_based,
|
|
144
|
+
column_0_based=link.column_0_based,
|
|
145
|
+
)
|
|
146
|
+
callback(data, results)
|
|
147
|
+
finally:
|
|
148
|
+
if links_ptr: _lib.free_memory(links_ptr)
|
|
149
|
+
if strings_handle: _lib.free_memory(strings_handle)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def pending_tasks() -> int:
|
|
153
|
+
return _lib.get_pending_tasks_count()
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def stop():
|
|
157
|
+
_lib.enqueue_stop()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def wait_for_callbacks_in_seconds(timeout_s, step_s=0.15):
|
|
161
|
+
# print(f"[PY] Waiting for callbacks (~{timeout_s}s)...")
|
|
162
|
+
deadline = time.time() + timeout_s
|
|
163
|
+
while True:
|
|
164
|
+
if pending_tasks() == 0:
|
|
165
|
+
# print("[PY] All pending tasks have completed.")
|
|
166
|
+
return True
|
|
167
|
+
|
|
168
|
+
if time.time() >= deadline:
|
|
169
|
+
print("[PY] Timeout reached.")
|
|
170
|
+
return False
|
|
171
|
+
|
|
172
|
+
# print(f"[PY] pending_tasks={pending_tasks()}")
|
|
173
|
+
time.sleep(step_s)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
if __name__ == "__main__":
|
|
177
|
+
if len(sys.argv) <= 2:
|
|
178
|
+
print("usage: python goober.py text folder...")
|
|
179
|
+
exit(1)
|
|
180
|
+
|
|
181
|
+
def scan_callback(data):
|
|
182
|
+
print(f"[PY] {data}")
|
|
183
|
+
|
|
184
|
+
def find_callback(data, links):
|
|
185
|
+
text, label = data
|
|
186
|
+
print(f"[PY] Callback for '{label}': Found {len(links)} symbols in text \"{text}\"")
|
|
187
|
+
for res in links:
|
|
188
|
+
matched_symbol = text[res.start_offset_in_text:res.end_offset_in_text]
|
|
189
|
+
print(f" '{matched_symbol}' -> {res.source_file}:{res.line_0_based}:{res.column_0_based}")
|
|
190
|
+
|
|
191
|
+
for folder in sys.argv[2:]:
|
|
192
|
+
path = Path(folder)
|
|
193
|
+
if path.is_dir():
|
|
194
|
+
for file in path.rglob("*.py"):
|
|
195
|
+
scan_file(file, scan_callback, file)
|
|
196
|
+
else:
|
|
197
|
+
scan_file(path, scan_callback, path)
|
|
198
|
+
|
|
199
|
+
text = sys.argv[1]
|
|
200
|
+
find_symbols_in_text(text, find_callback, data=(text, "before"))
|
|
201
|
+
|
|
202
|
+
print("[PY] WAIT, WAIT, WAIT!")
|
|
203
|
+
wait_for_callbacks_in_seconds(20)
|
|
204
|
+
|
|
205
|
+
find_symbols_in_text(text, find_callback, data=(text, "after"))
|
|
206
|
+
|
|
207
|
+
wait_for_callbacks_in_seconds(1)
|
|
208
|
+
|
|
209
|
+
stop()
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
|
2
|
+
|
|
3
|
+
/* package code_intelligence/source */
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
#line 1 "cgo-builtin-export-prolog"
|
|
7
|
+
|
|
8
|
+
#include <stddef.h>
|
|
9
|
+
|
|
10
|
+
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
|
11
|
+
#define GO_CGO_EXPORT_PROLOGUE_H
|
|
12
|
+
|
|
13
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
|
14
|
+
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
|
15
|
+
extern size_t _GoStringLen(_GoString_ s);
|
|
16
|
+
extern const char *_GoStringPtr(_GoString_ s);
|
|
17
|
+
#endif
|
|
18
|
+
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
/* Start of preamble from import "C" comments. */
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
#line 3 "main.go"
|
|
25
|
+
|
|
26
|
+
#include <stdint.h>
|
|
27
|
+
#include <stdlib.h>
|
|
28
|
+
#include <stdlib.h>
|
|
29
|
+
|
|
30
|
+
typedef struct {
|
|
31
|
+
uint32_t start_offset_in_text;
|
|
32
|
+
uint32_t end_offset_in_text;
|
|
33
|
+
const char* source_file;
|
|
34
|
+
uint32_t line_0_based;
|
|
35
|
+
uint32_t column_0_based;
|
|
36
|
+
} Definition_Link_C;
|
|
37
|
+
|
|
38
|
+
typedef void (*scan_callback_t)(uintptr_t);
|
|
39
|
+
typedef void (*find_callback_t)(uintptr_t, const Definition_Link_C*, int, void*);
|
|
40
|
+
|
|
41
|
+
static inline void invoke_scan_callback(scan_callback_t callback, uintptr_t p) {
|
|
42
|
+
callback(p);
|
|
43
|
+
}
|
|
44
|
+
static inline void invoke_find_callback(find_callback_t callback, uintptr_t p, const Definition_Link_C* links, int count, void* string_handle) {
|
|
45
|
+
callback(p, links, count, string_handle);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#line 1 "cgo-generated-wrapper"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
/* End of preamble from import "C" comments. */
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
/* Start of boilerplate cgo prologue. */
|
|
56
|
+
#line 1 "cgo-gcc-export-header-prolog"
|
|
57
|
+
|
|
58
|
+
#ifndef GO_CGO_PROLOGUE_H
|
|
59
|
+
#define GO_CGO_PROLOGUE_H
|
|
60
|
+
|
|
61
|
+
typedef signed char GoInt8;
|
|
62
|
+
typedef unsigned char GoUint8;
|
|
63
|
+
typedef short GoInt16;
|
|
64
|
+
typedef unsigned short GoUint16;
|
|
65
|
+
typedef int GoInt32;
|
|
66
|
+
typedef unsigned int GoUint32;
|
|
67
|
+
typedef long long GoInt64;
|
|
68
|
+
typedef unsigned long long GoUint64;
|
|
69
|
+
typedef GoInt64 GoInt;
|
|
70
|
+
typedef GoUint64 GoUint;
|
|
71
|
+
typedef size_t GoUintptr;
|
|
72
|
+
typedef float GoFloat32;
|
|
73
|
+
typedef double GoFloat64;
|
|
74
|
+
#ifdef _MSC_VER
|
|
75
|
+
#if !defined(__cplusplus) || _MSVC_LANG <= 201402L
|
|
76
|
+
#include <complex.h>
|
|
77
|
+
typedef _Fcomplex GoComplex64;
|
|
78
|
+
typedef _Dcomplex GoComplex128;
|
|
79
|
+
#else
|
|
80
|
+
#include <complex>
|
|
81
|
+
typedef std::complex<float> GoComplex64;
|
|
82
|
+
typedef std::complex<double> GoComplex128;
|
|
83
|
+
#endif
|
|
84
|
+
#else
|
|
85
|
+
typedef float _Complex GoComplex64;
|
|
86
|
+
typedef double _Complex GoComplex128;
|
|
87
|
+
#endif
|
|
88
|
+
|
|
89
|
+
/*
|
|
90
|
+
static assertion to make sure the file is being used on architecture
|
|
91
|
+
at least with matching size of GoInt.
|
|
92
|
+
*/
|
|
93
|
+
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
|
94
|
+
|
|
95
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
|
96
|
+
typedef _GoString_ GoString;
|
|
97
|
+
#endif
|
|
98
|
+
typedef void *GoMap;
|
|
99
|
+
typedef void *GoChan;
|
|
100
|
+
typedef struct { void *t; void *v; } GoInterface;
|
|
101
|
+
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
|
102
|
+
|
|
103
|
+
#endif
|
|
104
|
+
|
|
105
|
+
/* End of boilerplate cgo prologue. */
|
|
106
|
+
|
|
107
|
+
#ifdef __cplusplus
|
|
108
|
+
extern "C" {
|
|
109
|
+
#endif
|
|
110
|
+
|
|
111
|
+
extern __declspec(dllexport) void enqueue_scan_file(scan_callback_t callback, uintptr_t data, char* c_path, GoUint64 language);
|
|
112
|
+
extern __declspec(dllexport) void enqueue_find_symbols_in_text(find_callback_t callback, uintptr_t data, char* c_text);
|
|
113
|
+
extern __declspec(dllexport) void enqueue_stop(void);
|
|
114
|
+
extern __declspec(dllexport) GoUint64 get_pending_tasks_count(void);
|
|
115
|
+
extern __declspec(dllexport) void free_memory(void* ptr);
|
|
116
|
+
|
|
117
|
+
#ifdef __cplusplus
|
|
118
|
+
}
|
|
119
|
+
#endif
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
code_intelligence-3.0.1.dist-info/METADATA,sha256=ScA4qConScZC4WNjwdRekYeFFaDLAVRcFk1Y1nTNogY,100
|
|
2
|
+
code_intelligence-3.0.1.dist-info/RECORD,,
|
|
3
|
+
code_intelligence-3.0.1.dist-info/WHEEL,sha256=aD7J6E7Slys9i0J65v6Ehfi0DHYa5rImRhUDp62Iwh0,98
|
|
4
|
+
code_intelligence/__init__.py,sha256=QPD-ZdurftMeM2nYpl6NVgnxjh-s-_E7q3n9eg3RgJo,327
|
|
5
|
+
code_intelligence/goober.py,sha256=tX_P4EByTn6JXeUbrN1Su-eQt4EfblQwidjk5Wt9cMo,6217
|
|
6
|
+
code_intelligence/libcode_intelligence.h,sha256=GN6gPx-vEG02Ltak29nGSX8rsxDlrjIkI-Tr_xBeet8,3059
|
|
7
|
+
code_intelligence/libcode_intelligence.so,sha256=sJB2jhC1GH0V3umiQhpaKwtf6pSPja3aS0n2rgoLnR8,2827264
|
|
8
|
+
code_intelligence/symdb.py,sha256=gRq3-xr2oYIzudgwDwMj3Zl5Pb0B8tDdnGKUB0WIV_o,32427
|
|
Binary file
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
code_intelligence-2.0.2.dist-info/METADATA,sha256=8VQm-3UWGdDOH4xdvXuTAA16F--cu8OQ9nYQOvJqzSo,100
|
|
2
|
-
code_intelligence-2.0.2.dist-info/RECORD,,
|
|
3
|
-
code_intelligence-2.0.2.dist-info/WHEEL,sha256=aD7J6E7Slys9i0J65v6Ehfi0DHYa5rImRhUDp62Iwh0,98
|
|
4
|
-
code_intelligence/__init__.py,sha256=JUcG5hLPvopKlYtD02xoEhoYzVImwWO-TJITknRZZGQ,527
|
|
5
|
-
code_intelligence/_code_intelligence.dll,sha256=wFdz8sbeS2o-TR6RSWFYktcPlXMQI85HSPKcsH7-4LA,6662144
|
|
6
|
-
code_intelligence/symdb.py,sha256=gRq3-xr2oYIzudgwDwMj3Zl5Pb0B8tDdnGKUB0WIV_o,32427
|
|
File without changes
|