@@ -551,11 +551,11 @@ export class ExtractionOrchestrator {
551551 processed ++ ;
552552
553553 // Создание записи файла
554- const fileRecord : IFileRecord = {
555- path : filePath ,
556- contentHash : hashContent ( content ) ,
557- language,
558- size : stats . size ,
554+ const fileRecord : IFileRecord = {
555+ path : filePath ,
556+ contentHash : hashContent ( content ) ,
557+ language : language as Language ,
558+ size : stats . size ,
559559 modifiedAt : stats . mtimeMs ,
560560 indexedAt : Date . now ( ) ,
561561 nodeCount : result . nodes . length ,
@@ -641,6 +641,15 @@ await this.storeExtractionResult(fileRecord, result);
641641
642642 onProgress ?.( { phase : 'scanning' , current : 0 , total : 0 , file : '' , durationMs : 0 } ) ;
643643
644+ // Загрузка грамматик перед основным циклом извлечения
645+ if ( PARSER_WORKER_AVAILABLE ) {
646+ try {
647+ await loadGrammarsWorker ( [ 'typescript' , 'python' ] ) ;
648+ } catch {
649+ // Игнорируем ошибки загрузки грамматик
650+ }
651+ }
652+
644653 // Пытаемся использовать git для быстрого обнаружения изменений
645654 const gitChanges = getGitChangedFiles ( this . rootDir ) ;
646655
@@ -900,6 +909,9 @@ await this.storeExtractionResult(fileRecord, result);
900909 this . _detectedFrameworks = null ;
901910 const frameworkNames = this . ensureDetectedFrameworks ( filePaths ) ;
902911
912+ // Уровень 2: сборка списка файлов, которые не удалось распарсить
913+ const failedFiles : { filePath : string ; content : string ; language : string ; stats : fs . Stats } [ ] = [ ] ;
914+
903915 const total = filePaths . length ;
904916 let processed = 0 ;
905917
@@ -959,20 +971,33 @@ await this.storeExtractionResult(fileRecord, result);
959971 continue ;
960972 }
961973
962- // Извлечение AST через экстрактор
974+ // Извлечение AST через экстрактор с 2-уровневым повтором
963975 let result : IExtractionResult ;
964976 try {
965977 result = this . extractFile ( filePath , content , language , frameworkNames ) ;
966978 } catch ( parseErr ) {
967- processed ++ ;
968- filesErrored ++ ;
969- errors . push ( {
970- message : parseErr instanceof Error ? parseErr . message : String ( parseErr ) ,
971- filePath,
972- severity : 'error' ,
973- code : 'parse_error' ,
974- } ) ;
975- continue ;
979+ // Уровень 1: повтор с оригинальным содержимым
980+ try {
981+ result = this . extractFile ( filePath , content , language , frameworkNames ) ;
982+ } catch ( parseErr2 ) {
983+ // Уровень 2: удаление комментариев и повтор
984+ try {
985+ const stripped = this . stripComments ( content , language ) ;
986+ result = this . extractFile ( filePath , stripped , language , frameworkNames ) ;
987+ } catch ( parseErr3 ) {
988+ // Сохраняем для повторной обработки с фолбэком
989+ failedFiles . push ( { filePath, content, language, stats } ) ;
990+ processed ++ ;
991+ filesErrored ++ ;
992+ errors . push ( {
993+ message : parseErr3 instanceof Error ? parseErr3 . message : String ( parseErr3 ) ,
994+ filePath,
995+ severity : 'error' ,
996+ code : 'parse_error' ,
997+ } ) ;
998+ continue ;
999+ }
1000+ }
9761001 }
9771002
9781003 processed ++ ;
@@ -1015,6 +1040,49 @@ await this.storeExtractionResult(fileRecord, result);
10151040 }
10161041 }
10171042
1043+ // Уровень 2: повторная обработка файлов, которые не удалось распарсить, с фолбэком
1044+ for ( const { filePath, content, language, stats } of failedFiles ) {
1045+ // Фолбэк: пробовать каждый доступный экстрактор
1046+ let fallbackResult : IExtractionResult | null = null ;
1047+ for ( const [ lang , extractor ] of EXTRACTOR_MAP ) {
1048+ try {
1049+ fallbackResult = extractor . extract ( content , filePath , frameworkNames ) ;
1050+ if ( fallbackResult . nodes . length > 0 ) {
1051+ break ;
1052+ }
1053+ } catch {
1054+ // Пробуем следующий экстрактор
1055+ }
1056+ }
1057+
1058+ if ( fallbackResult && fallbackResult . nodes . length > 0 ) {
1059+ const fileRecord : IFileRecord = {
1060+ path : filePath ,
1061+ contentHash : hashContent ( content ) ,
1062+ language : language as Language ,
1063+ size : stats . size ,
1064+ modifiedAt : stats . mtimeMs ,
1065+ indexedAt : Date . now ( ) ,
1066+ nodeCount : fallbackResult . nodes . length ,
1067+ errors : fallbackResult . errors . length > 0 ? fallbackResult . errors : undefined ,
1068+ } ;
1069+
1070+ await this . storeExtractionResult ( fileRecord , fallbackResult ) ;
1071+
1072+ filesErrored -- ;
1073+ filesIndexed ++ ;
1074+ totalNodes += fallbackResult . nodes . length ;
1075+ totalEdges += fallbackResult . edges . length ;
1076+
1077+ if ( fallbackResult . errors . length > 0 ) {
1078+ for ( const err of fallbackResult . errors ) {
1079+ if ( ! err . filePath ) err . filePath = filePath ;
1080+ }
1081+ errors . push ( ...fallbackResult . errors ) ;
1082+ }
1083+ }
1084+ }
1085+
10181086 return {
10191087 indexed : filesIndexed ,
10201088 updated : 0 ,
@@ -1436,10 +1504,10 @@ await this.storeExtractionResult(fileRecord, result);
14361504 try {
14371505 const result = this . extractFile ( filePath , content , language , frameworkNames ) ;
14381506
1439- const fileRecord : IFileRecord = {
1440- path : filePath ,
1441- contentHash : hashContent ( content ) ,
1442- language,
1507+ const fileRecord : IFileRecord = {
1508+ path : filePath ,
1509+ contentHash : hashContent ( content ) ,
1510+ language : language as Language ,
14431511 size : stats . size ,
14441512 modifiedAt : stats . mtimeMs ,
14451513 indexedAt : Date . now ( ) ,
0 commit comments