16
16
from codegen .sdk .codebase .diff_lite import ChangeType , DiffLite
17
17
from codegen .sdk .codebase .flagging .flags import Flags
18
18
from codegen .sdk .codebase .io .file_io import FileIO
19
+ from codegen .sdk .codebase .progress .stub_progress import StubProgress
19
20
from codegen .sdk .codebase .transaction_manager import TransactionManager
20
21
from codegen .sdk .codebase .validation import get_edges , post_reset_validation
21
22
from codegen .sdk .core .autocommit import AutoCommit , commiter
39
40
from codegen .git .repo_operator .repo_operator import RepoOperator
40
41
from codegen .sdk .codebase .io .io import IO
41
42
from codegen .sdk .codebase .node_classes .node_classes import NodeClasses
43
+ from codegen .sdk .codebase .progress .progress import Progress
42
44
from codegen .sdk .core .dataclasses .usage import Usage
43
45
from codegen .sdk .core .expressions import Expression
44
46
from codegen .sdk .core .external_module import ExternalModule
@@ -111,16 +113,19 @@ class CodebaseContext:
111
113
projects : list [ProjectConfig ]
112
114
unapplied_diffs : list [DiffLite ]
113
115
io : IO
116
+ progress : Progress
114
117
115
118
def __init__ (
116
119
self ,
117
120
projects : list [ProjectConfig ],
118
121
config : CodebaseConfig = DefaultConfig ,
119
122
io : IO | None = None ,
123
+ progress : Progress | None = None ,
120
124
) -> None :
121
125
"""Initializes codebase graph and TransactionManager"""
122
126
from codegen .sdk .core .parser import Parser
123
127
128
+ self .progress = progress or StubProgress ()
124
129
self ._graph = PyDiGraph ()
125
130
self .filepath_idx = {}
126
131
self ._ext_module_idx = {}
@@ -371,7 +376,6 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr
371
376
skip_uncache = incremental and ((len (files_to_sync [SyncType .DELETE ]) + len (files_to_sync [SyncType .REPARSE ])) == 0 )
372
377
if not skip_uncache :
373
378
uncache_all ()
374
-
375
379
# Step 0: Start the dependency manager and language engine if they exist
376
380
# Start the dependency manager. This may or may not run asynchronously, depending on the implementation
377
381
if self .dependency_manager is not None :
@@ -429,24 +433,29 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr
429
433
file = self .get_file (file_path )
430
434
file .remove_internal_edges ()
431
435
436
+ task = self .progress .begin ("Reparsing updated files" , count = len (files_to_sync [SyncType .REPARSE ]))
432
437
files_to_resolve = []
433
438
# Step 4: Reparse updated files
434
- for file_path in files_to_sync [SyncType .REPARSE ]:
439
+ for idx , file_path in enumerate (files_to_sync [SyncType .REPARSE ]):
440
+ task .update (f"Reparsing { self .to_relative (file_path )} " , count = idx )
435
441
file = self .get_file (file_path )
436
442
to_resolve .extend (file .unparse (reparse = True ))
437
443
to_resolve = list (filter (lambda node : self .has_node (node .node_id ) and node is not None , to_resolve ))
438
444
file .sync_with_file_content ()
439
445
files_to_resolve .append (file )
440
-
446
+ task . end ()
441
447
# Step 5: Add new files as nodes to graph (does not yet add edges)
442
- for filepath in files_to_sync [SyncType .ADD ]:
448
+ task = self .progress .begin ("Adding new files" , count = len (files_to_sync [SyncType .ADD ]))
449
+ for idx , filepath in enumerate (files_to_sync [SyncType .ADD ]):
450
+ task .update (f"Adding { self .to_relative (filepath )} " , count = idx )
443
451
content = self .io .read_text (filepath )
444
452
# TODO: this is wrong with context changes
445
453
if filepath .suffix in self .extensions :
446
454
file_cls = self .node_classes .file_cls
447
455
new_file = file_cls .from_content (filepath , content , self , sync = False , verify_syntax = False )
448
456
if new_file is not None :
449
457
files_to_resolve .append (new_file )
458
+ task .end ()
450
459
for file in files_to_resolve :
451
460
to_resolve .append (file )
452
461
to_resolve .extend (file .get_nodes ())
@@ -474,27 +483,35 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr
474
483
self ._computing = True
475
484
try :
476
485
logger .info (f"> Computing import resolution edges for { counter [NodeType .IMPORT ]} imports" )
486
+ task = self .progress .begin ("Resolving imports" , count = counter [NodeType .IMPORT ])
477
487
for node in to_resolve :
478
488
if node .node_type == NodeType .IMPORT :
489
+ task .update (f"Resolving imports in { node .filepath } " , count = idx )
479
490
node ._remove_internal_edges (EdgeType .IMPORT_SYMBOL_RESOLUTION )
480
491
node .add_symbol_resolution_edge ()
481
492
to_resolve .extend (node .symbol_usages )
493
+ task .end ()
482
494
if counter [NodeType .EXPORT ] > 0 :
483
495
logger .info (f"> Computing export dependencies for { counter [NodeType .EXPORT ]} exports" )
496
+ task = self .progress .begin ("Computing export dependencies" , count = counter [NodeType .EXPORT ])
484
497
for node in to_resolve :
485
498
if node .node_type == NodeType .EXPORT :
499
+ task .update (f"Computing export dependencies for { node .filepath } " , count = idx )
486
500
node ._remove_internal_edges (EdgeType .EXPORT )
487
501
node .compute_export_dependencies ()
488
502
to_resolve .extend (node .symbol_usages )
503
+ task .end ()
489
504
if counter [NodeType .SYMBOL ] > 0 :
490
505
from codegen .sdk .core .interfaces .inherits import Inherits
491
506
492
507
logger .info ("> Computing superclass dependencies" )
508
+ task = self .progress .begin ("Computing superclass dependencies" , count = counter [NodeType .SYMBOL ])
493
509
for symbol in to_resolve :
494
510
if isinstance (symbol , Inherits ):
511
+ task .update (f"Computing superclass dependencies for { symbol .filepath } " , count = idx )
495
512
symbol ._remove_internal_edges (EdgeType .SUBCLASS )
496
513
symbol .compute_superclass_dependencies ()
497
-
514
+ task . end ()
498
515
if not skip_uncache :
499
516
uncache_all ()
500
517
self ._compute_dependencies (to_resolve , incremental )
@@ -504,17 +521,20 @@ def _process_diff_files(self, files_to_sync: Mapping[SyncType, list[Path]], incr
504
521
def _compute_dependencies (self , to_update : list [Importable ], incremental : bool ):
505
522
seen = set ()
506
523
while to_update :
524
+ task = self .progress .begin ("Computing dependencies" , count = len (to_update ))
507
525
step = to_update .copy ()
508
526
to_update .clear ()
509
527
logger .info (f"> Incrementally computing dependencies for { len (step )} nodes" )
510
- for current in step :
528
+ for idx , current in enumerate (step ):
529
+ task .update (f"Computing dependencies for { current .filepath } " , count = idx )
511
530
if current not in seen :
512
531
seen .add (current )
513
532
to_update .extend (current .recompute (incremental ))
514
533
if not incremental :
515
534
for node in self ._graph .nodes ():
516
535
if node not in seen :
517
536
to_update .append (node )
537
+ task .end ()
518
538
seen .clear ()
519
539
520
540
def build_subgraph (self , nodes : list [NodeId ]) -> PyDiGraph [Importable , Edge ]:
0 commit comments