python-delphi-lsp 3.6.0__cp310-abi3-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.
Files changed (56) hide show
  1. delphi_lsp/__init__.py +184 -0
  2. delphi_lsp/_version.py +1 -0
  3. delphi_lsp/agent_cache.py +1574 -0
  4. delphi_lsp/agent_cli.py +902 -0
  5. delphi_lsp/agent_context.py +3907 -0
  6. delphi_lsp/agent_cpg.py +349 -0
  7. delphi_lsp/agent_cpg_builder.py +666 -0
  8. delphi_lsp/agent_layers.py +1410 -0
  9. delphi_lsp/agent_metrics.py +526 -0
  10. delphi_lsp/agent_protocol.py +445 -0
  11. delphi_lsp/agent_relations.py +1881 -0
  12. delphi_lsp/agent_templates.py +614 -0
  13. delphi_lsp/agent_wiki.py +2853 -0
  14. delphi_lsp/agent_workspace.py +860 -0
  15. delphi_lsp/ast_serialize.py +126 -0
  16. delphi_lsp/binary.py +250 -0
  17. delphi_lsp/comment_builder.py +28 -0
  18. delphi_lsp/consts.py +345 -0
  19. delphi_lsp/delphi_lsp_native.pyd +0 -0
  20. delphi_lsp/delphiast_lexer.py +399 -0
  21. delphi_lsp/delphiast_parser.py +2189 -0
  22. delphi_lsp/delphiast_tokens.py +41 -0
  23. delphi_lsp/grammar.py +459 -0
  24. delphi_lsp/incremental.py +1139 -0
  25. delphi_lsp/lark_builder.py +2684 -0
  26. delphi_lsp/lark_tokens.py +236 -0
  27. delphi_lsp/lexical_scanner.py +30 -0
  28. delphi_lsp/lsp_server.py +6698 -0
  29. delphi_lsp/metrics.py +1452 -0
  30. delphi_lsp/native_bridge.py +300 -0
  31. delphi_lsp/navigation_cache.py +189 -0
  32. delphi_lsp/nodes.py +462 -0
  33. delphi_lsp/parallel_outline.py +662 -0
  34. delphi_lsp/parse_artifacts.py +969 -0
  35. delphi_lsp/parser.py +342 -0
  36. delphi_lsp/parser_backend.py +139 -0
  37. delphi_lsp/preprocessor.py +1122 -0
  38. delphi_lsp/progress.py +26 -0
  39. delphi_lsp/project_config.py +285 -0
  40. delphi_lsp/project_discovery.py +932 -0
  41. delphi_lsp/project_indexer.py +470 -0
  42. delphi_lsp/py.typed +1 -0
  43. delphi_lsp/response_cache.py +465 -0
  44. delphi_lsp/semantic.py +394 -0
  45. delphi_lsp/semantic_builder.py +2302 -0
  46. delphi_lsp/source_reader.py +17 -0
  47. delphi_lsp/wiki_external_sort.py +392 -0
  48. delphi_lsp/wiki_memory.py +548 -0
  49. delphi_lsp/workspace.py +83 -0
  50. delphi_lsp/writer.py +73 -0
  51. python_delphi_lsp-3.6.0.dist-info/METADATA +766 -0
  52. python_delphi_lsp-3.6.0.dist-info/RECORD +56 -0
  53. python_delphi_lsp-3.6.0.dist-info/WHEEL +4 -0
  54. python_delphi_lsp-3.6.0.dist-info/entry_points.txt +3 -0
  55. python_delphi_lsp-3.6.0.dist-info/licenses/LICENSE +373 -0
  56. python_delphi_lsp-3.6.0.dist-info/sboms/python-delphi-lsp.cyclonedx.json +770 -0
delphi_lsp/semantic.py ADDED
@@ -0,0 +1,394 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass, field
4
+ from enum import Enum
5
+
6
+
7
+ def normalize_name(name: str) -> str:
8
+ return '.'.join(
9
+ part.removeprefix('&')
10
+ for part in name.casefold().split('.')
11
+ )
12
+
13
+
14
+ @dataclass(frozen=True)
15
+ class SourceRange:
16
+ file_name: str
17
+ start_line: int
18
+ start_col: int
19
+ end_line: int
20
+ end_col: int
21
+
22
+ def contains(self, line: int, col: int) -> bool:
23
+ if line < self.start_line or line > self.end_line:
24
+ return False
25
+ if line == self.start_line and col < self.start_col:
26
+ return False
27
+ if line == self.end_line and col > self.end_col:
28
+ return False
29
+ return True
30
+
31
+
32
+ class Visibility(Enum):
33
+ UNKNOWN = 'unknown'
34
+ PRIVATE = 'private'
35
+ PROTECTED = 'protected'
36
+ PUBLIC = 'public'
37
+ PUBLISHED = 'published'
38
+ STRICT_PRIVATE = 'strict_private'
39
+ STRICT_PROTECTED = 'strict_protected'
40
+
41
+
42
+ class SymbolKind(Enum):
43
+ UNIT = 'unit'
44
+ MODULE = 'module'
45
+ NAMESPACE = 'namespace'
46
+ PACKAGE = 'package'
47
+ TYPE = 'type'
48
+ TYPE_PARAMETER = 'type_parameter'
49
+ CLASS = 'class'
50
+ RECORD = 'record'
51
+ INTERFACE = 'interface'
52
+ ENUM = 'enum'
53
+ ENUM_VALUE = 'enum_value'
54
+ FIELD = 'field'
55
+ PROPERTY = 'property'
56
+ METHOD = 'method'
57
+ FUNCTION = 'function'
58
+ PROCEDURE = 'procedure'
59
+ CONSTRUCTOR = 'constructor'
60
+ DESTRUCTOR = 'destructor'
61
+ VARIABLE = 'variable'
62
+ PARAMETER = 'parameter'
63
+ CONSTANT = 'constant'
64
+ LABEL = 'label'
65
+
66
+
67
+ class ScopeKind(Enum):
68
+ UNIT = 'unit'
69
+ TYPE = 'type'
70
+ ROUTINE = 'routine'
71
+ BLOCK = 'block'
72
+ WITH = 'with'
73
+
74
+
75
+ class Modifier(Enum):
76
+ ABSTRACT = 'abstract'
77
+ SEALED = 'sealed'
78
+ FINAL = 'final'
79
+ VIRTUAL = 'virtual'
80
+ OVERRIDE = 'override'
81
+ OVERLOAD = 'overload'
82
+ REINTRODUCE = 'reintroduce'
83
+ INLINE = 'inline'
84
+ STATIC = 'static'
85
+ CLASS = 'class'
86
+ EXTERNAL = 'external'
87
+ FORWARD = 'forward'
88
+ DEPRECATED = 'deprecated'
89
+ NORETURN = 'noreturn'
90
+
91
+
92
+ class ReferenceKind(Enum):
93
+ UNKNOWN = 'unknown'
94
+ VALUE = 'value'
95
+ TYPE = 'type'
96
+ TYPE_QUALIFIER = 'type_qualifier'
97
+ CONSTRUCTOR_CALL = 'constructor_call'
98
+ CALL = 'call'
99
+ PROPERTY = 'property'
100
+ UNIT = 'unit'
101
+ LABEL = 'label'
102
+
103
+
104
+ @dataclass(frozen=True)
105
+ class TypeRef:
106
+ def display_name(self) -> str:
107
+ return '<unknown>'
108
+
109
+
110
+ @dataclass(frozen=True)
111
+ class UnknownTypeRef(TypeRef):
112
+ reason: str = ''
113
+
114
+ def display_name(self) -> str:
115
+ return '<unknown>' if not self.reason else f'<unknown:{self.reason}>'
116
+
117
+
118
+ @dataclass(frozen=True)
119
+ class NamedTypeRef(TypeRef):
120
+ name: str
121
+ unit_name: str | None = None
122
+
123
+ def display_name(self) -> str:
124
+ if self.unit_name:
125
+ return f'{self.unit_name}.{self.name}'
126
+ return self.name
127
+
128
+
129
+ @dataclass(frozen=True)
130
+ class PointerTypeRef(TypeRef):
131
+ target: TypeRef
132
+
133
+ def display_name(self) -> str:
134
+ return f'^{self.target.display_name()}'
135
+
136
+
137
+ @dataclass(frozen=True)
138
+ class ClassOfTypeRef(TypeRef):
139
+ target: TypeRef
140
+
141
+ def display_name(self) -> str:
142
+ return f'class of {self.target.display_name()}'
143
+
144
+
145
+ @dataclass(frozen=True)
146
+ class ReferenceTypeRef(TypeRef):
147
+ target: TypeRef
148
+
149
+ def display_name(self) -> str:
150
+ return f'reference to {self.target.display_name()}'
151
+
152
+
153
+ @dataclass(frozen=True)
154
+ class FileTypeRef(TypeRef):
155
+ element_type: TypeRef | None = None
156
+
157
+ def display_name(self) -> str:
158
+ if self.element_type is None:
159
+ return 'file'
160
+ return f'file of {self.element_type.display_name()}'
161
+
162
+
163
+ @dataclass(frozen=True)
164
+ class GenericInstanceTypeRef(TypeRef):
165
+ base: NamedTypeRef
166
+ args: tuple[TypeRef, ...]
167
+
168
+ def display_name(self) -> str:
169
+ arg_list = ', '.join(arg.display_name() for arg in self.args)
170
+ return f'{self.base.display_name()}<{arg_list}>'
171
+
172
+
173
+ @dataclass(frozen=True)
174
+ class ArrayTypeRef(TypeRef):
175
+ element_type: TypeRef
176
+ dimensions: tuple[TypeRef, ...] = ()
177
+ is_dynamic: bool = False
178
+
179
+ def display_name(self) -> str:
180
+ if self.is_dynamic or not self.dimensions:
181
+ return f'array of {self.element_type.display_name()}'
182
+ dims = ', '.join(dim.display_name() for dim in self.dimensions)
183
+ return f'array[{dims}] of {self.element_type.display_name()}'
184
+
185
+
186
+ @dataclass(frozen=True)
187
+ class SetTypeRef(TypeRef):
188
+ element_type: TypeRef
189
+
190
+ def display_name(self) -> str:
191
+ return f'set of {self.element_type.display_name()}'
192
+
193
+
194
+ @dataclass(frozen=True)
195
+ class SubrangeTypeRef(TypeRef):
196
+ lower: str
197
+ upper: str
198
+
199
+ def display_name(self) -> str:
200
+ return f'{self.lower}..{self.upper}'
201
+
202
+
203
+ @dataclass(frozen=True)
204
+ class EnumTypeRef(TypeRef):
205
+ name: str
206
+ members: tuple[str, ...]
207
+
208
+ def display_name(self) -> str:
209
+ return self.name if self.name else 'enum'
210
+
211
+
212
+ @dataclass(frozen=True)
213
+ class RecordTypeRef(TypeRef):
214
+ name: str
215
+ scope: Scope | None = None
216
+ packed: bool = False
217
+
218
+ def display_name(self) -> str:
219
+ return self.name if self.name else 'record'
220
+
221
+
222
+ @dataclass(frozen=True)
223
+ class ClassTypeRef(TypeRef):
224
+ name: str
225
+ scope: Scope | None = None
226
+ bases: tuple[TypeRef, ...] = ()
227
+ is_abstract: bool = False
228
+
229
+ def display_name(self) -> str:
230
+ return self.name if self.name else 'class'
231
+
232
+
233
+ @dataclass(frozen=True)
234
+ class InterfaceTypeRef(TypeRef):
235
+ name: str
236
+ scope: Scope | None = None
237
+ bases: tuple[TypeRef, ...] = ()
238
+
239
+ def display_name(self) -> str:
240
+ return self.name if self.name else 'interface'
241
+
242
+
243
+ @dataclass(frozen=True)
244
+ class TypeParameterRef(TypeRef):
245
+ name: str
246
+
247
+ def display_name(self) -> str:
248
+ return self.name
249
+
250
+
251
+ @dataclass(frozen=True)
252
+ class ProcTypeRef(TypeRef):
253
+ name: str
254
+ params: tuple[TypeRef, ...] = ()
255
+ return_type: TypeRef | None = None
256
+
257
+ def display_name(self) -> str:
258
+ params = ', '.join(p.display_name() for p in self.params)
259
+ if self.return_type is None:
260
+ return f'procedure({params})'
261
+ return f'function({params}): {self.return_type.display_name()}'
262
+
263
+
264
+ @dataclass
265
+ class Symbol:
266
+ name: str
267
+ kind: SymbolKind
268
+ decl_range: SourceRange
269
+ name_range: SourceRange
270
+ scope: Scope
271
+ visibility: Visibility = Visibility.UNKNOWN
272
+ type_ref: TypeRef = field(default_factory=UnknownTypeRef)
273
+ modifiers: set[Modifier] = field(default_factory=set)
274
+ attributes: dict[str, str] = field(default_factory=dict)
275
+ doc: str = ''
276
+ overloads: list[Symbol] = field(default_factory=list)
277
+ member_scope: Scope | None = None
278
+ base_types: tuple[TypeRef, ...] = ()
279
+
280
+ def add_overload(self, symbol: Symbol) -> None:
281
+ self.overloads.append(symbol)
282
+
283
+
284
+ @dataclass
285
+ class SymbolReference:
286
+ name: str
287
+ kind: ReferenceKind
288
+ ref_range: SourceRange
289
+ scope: Scope
290
+ resolved: Symbol | None = None
291
+
292
+
293
+ @dataclass
294
+ class Scope:
295
+ kind: ScopeKind
296
+ name: str
297
+ parent: Scope | None = None
298
+ owner: Symbol | None = None
299
+ symbols: dict[str, list[Symbol]] = field(default_factory=dict)
300
+ imports: list[Scope] = field(default_factory=list)
301
+ with_scopes: list[Scope] = field(default_factory=list)
302
+
303
+ def define(self, symbol: Symbol) -> None:
304
+ key = normalize_name(symbol.name)
305
+ if key not in self.symbols:
306
+ self.symbols[key] = []
307
+ self.symbols[key].append(symbol)
308
+
309
+ def lookup_local(self, name: str) -> list[Symbol]:
310
+ return list(self.symbols.get(normalize_name(name), []))
311
+
312
+ def resolve(self, name: str) -> list[Symbol]:
313
+ results: list[Symbol] = []
314
+ results.extend(self.lookup_local(name))
315
+ if results:
316
+ return results
317
+ for scope in self.with_scopes:
318
+ scoped = scope.lookup_local(name)
319
+ if scoped:
320
+ return scoped
321
+ if self.parent is not None:
322
+ results.extend(self.parent.resolve(name))
323
+ if results:
324
+ return results
325
+ for scope in self.imports:
326
+ scoped = scope.lookup_local(name)
327
+ if scoped:
328
+ results.extend(scoped)
329
+ return results
330
+
331
+ def add_import(self, scope: Scope) -> None:
332
+ if scope not in self.imports:
333
+ self.imports.append(scope)
334
+
335
+ def add_with_scope(self, scope: Scope) -> None:
336
+ if scope not in self.with_scopes:
337
+ self.with_scopes.append(scope)
338
+
339
+
340
+ @dataclass
341
+ class SymbolIndex:
342
+ units: dict[str, Scope] = field(default_factory=dict)
343
+ name_index: dict[str, list[Symbol]] = field(default_factory=dict)
344
+
345
+ def register_unit(self, unit_name: str, unit_scope: Scope, *, index_symbols: bool = True) -> None:
346
+ self.units[normalize_name(unit_name)] = unit_scope
347
+ if index_symbols:
348
+ self._index_scope(unit_scope)
349
+
350
+ def lookup(self, name: str) -> list[Symbol]:
351
+ return list(self.name_index.get(normalize_name(name), []))
352
+
353
+ def lookup_unit(self, unit_name: str) -> Scope | None:
354
+ return self.units.get(normalize_name(unit_name))
355
+
356
+ def resolve_qualified(self, qualified_name: str) -> list[Symbol]:
357
+ parts = qualified_name.split('.')
358
+ if len(parts) < 2:
359
+ return self.lookup(qualified_name)
360
+ unit_name = '.'.join(parts[:-1])
361
+ symbol_name = parts[-1]
362
+ unit_scope = self.lookup_unit(unit_name)
363
+ if unit_scope is None:
364
+ return []
365
+ return unit_scope.lookup_local(symbol_name)
366
+
367
+ def _index_scope(self, scope: Scope, seen: set[int] | None = None) -> None:
368
+ if seen is None:
369
+ seen = set()
370
+ pending = [scope]
371
+ while pending:
372
+ current = pending.pop()
373
+ scope_id = id(current)
374
+ if scope_id in seen:
375
+ continue
376
+ seen.add(scope_id)
377
+ member_scopes: list[Scope] = []
378
+ for symbols in current.symbols.values():
379
+ for symbol in symbols:
380
+ key = normalize_name(symbol.name)
381
+ self.name_index.setdefault(key, []).append(symbol)
382
+ if (
383
+ symbol.member_scope is not None
384
+ and symbol.kind
385
+ in {
386
+ SymbolKind.CLASS,
387
+ SymbolKind.RECORD,
388
+ SymbolKind.INTERFACE,
389
+ SymbolKind.ENUM,
390
+ SymbolKind.TYPE,
391
+ }
392
+ ):
393
+ member_scopes.append(symbol.member_scope)
394
+ pending.extend(reversed(member_scopes))