@@ -126,6 +126,13 @@ class LeetCodeExecutor implements Disposable {
126
126
cmd . push ( "-T" ) ; // use -T to force English version
127
127
}
128
128
129
+ console . log ( '🔍 DEBUG: showProblem called with:' , {
130
+ problemId : problemNode . id ,
131
+ problemName : problemNode . name ,
132
+ language : language ,
133
+ shouldAddHeaders : shouldAddHeaders
134
+ } ) ;
135
+
129
136
if ( ! await fse . pathExists ( filePath ) ) {
130
137
await fse . createFile ( filePath ) ;
131
138
let codeTemplate : string = await this . executeCommandWithProgressEx ( "Fetching problem data..." , this . nodeExecutable , cmd ) ;
@@ -138,8 +145,28 @@ class LeetCodeExecutor implements Disposable {
138
145
139
146
// Add debug template for C++ with enhanced parsing
140
147
if ( language === "cpp" || language === "c" ) {
141
- // Получаем markdown описание задачи для парсинга
142
- const markdownDescription = await this . getDescription ( problemNode . id , needTranslation ) ;
148
+ console . log ( '🧩 DEBUG: Попытка получить описание для парсинга тестовых данных...' ) ;
149
+ let markdownDescription = '' ;
150
+
151
+ try {
152
+ // Сначала пробуем стандартный CLI метод
153
+ markdownDescription = await this . getDescription ( problemNode . id , needTranslation ) ;
154
+ console . log ( '✅ DEBUG: Описание получено через CLI, длина:' , markdownDescription . length ) ;
155
+ } catch ( error ) {
156
+ console . log ( '⚠️ DEBUG: CLI метод не сработал, пробуем GraphQL...' , error . message ) ;
157
+
158
+ // Если CLI не работает и есть titleSlug, пробуем GraphQL
159
+ if ( problemNode . titleSlug ) {
160
+ try {
161
+ markdownDescription = await this . getDescriptionViaGraphQL ( problemNode . titleSlug , needTranslation ) ;
162
+ console . log ( '✅ DEBUG: Описание получено через GraphQL, длина:' , markdownDescription . length ) ;
163
+ } catch ( graphqlError ) {
164
+ console . log ( '❌ DEBUG: GraphQL тоже не сработал:' , graphqlError . message ) ;
165
+ }
166
+ }
167
+ }
168
+
169
+ // Добавляем debug шаблон (даже если описание пустое)
143
170
codeTemplate = this . addCppDebugTemplateWithDescription ( codeTemplate , markdownDescription ) ;
144
171
}
145
172
@@ -405,7 +432,8 @@ class LeetCodeExecutor implements Disposable {
405
432
locked : question . paidOnly || false ,
406
433
state : question . status || "Unknown" ,
407
434
date : challenge . date ,
408
- link : challenge . link
435
+ link : challenge . link ,
436
+ titleSlug : question . titleSlug // Добавляем titleSlug для GraphQL запросов
409
437
} ;
410
438
} ) ;
411
439
@@ -554,7 +582,7 @@ using namespace std;
554
582
555
583
private extractTestDataFromMarkdown ( markdownContent : string ) : string [ ] {
556
584
const testData : string [ ] = [ ] ;
557
- const seenValues = new Set < string > ( ) ; // Для отслеживания дубликатов
585
+ const seenVariables = new Set < string > ( ) ; // Отслеживаем только имена переменных
558
586
559
587
console . log ( '🔍 DEBUG: Начинаем парсинг markdown' ) ;
560
588
console . log ( '🔍 DEBUG: Ищем паттерны Input в тексте...' ) ;
@@ -581,7 +609,7 @@ using namespace std;
581
609
console . log ( `🔧 После декодирования HTML:` , inputLine ) ;
582
610
583
611
// Парсим переменные с учетом массивов, строк и чисел
584
- this . parseInputLine ( inputLine , testData , seenValues ) ;
612
+ this . parseInputLine ( inputLine , testData , seenVariables ) ;
585
613
}
586
614
}
587
615
@@ -612,7 +640,7 @@ using namespace std;
612
640
} ) ;
613
641
}
614
642
615
- private parseInputLine ( inputLine : string , testData : string [ ] , seenValues : Set < string > ) : void {
643
+ private parseInputLine ( inputLine : string , testData : string [ ] , seenVariables : Set < string > ) : void {
616
644
console . log ( '🔧 DEBUG: Парсим строку Input:' , inputLine ) ;
617
645
618
646
// Удаляем HTML теги и лишние символы в начале строки
@@ -637,6 +665,22 @@ using namespace std;
637
665
const varName = varMatch [ 1 ] ;
638
666
index += varMatch [ 0 ] . length ;
639
667
668
+ // Проверяем, встречали ли уже эту переменную
669
+ if ( seenVariables . has ( varName ) ) {
670
+ console . log ( `⚠️ Пропускаем дубликат переменной: ${ varName } ` ) ;
671
+ // Пропускаем значение до следующей переменной или конца строки
672
+ while ( index < cleanLine . length ) {
673
+ const char = cleanLine [ index ] ;
674
+ if ( char === ',' && cleanLine . substring ( index + 1 ) . match ( / \s * \w + \s * = / ) ) {
675
+ // Нашли запятую перед следующей переменной
676
+ index ++ ;
677
+ break ;
678
+ }
679
+ index ++ ;
680
+ }
681
+ continue ;
682
+ }
683
+
640
684
// Теперь извлекаем значение
641
685
let value = '' ;
642
686
let char = cleanLine [ index ] ;
@@ -678,15 +722,9 @@ using namespace std;
678
722
679
723
if ( value . trim ( ) ) {
680
724
const cleanValue = value . trim ( ) ;
681
- const key = `${ varName } :${ cleanValue } ` ; // Ключ для дедупликации
682
-
683
- if ( ! seenValues . has ( key ) ) {
684
- seenValues . add ( key ) ;
685
- testData . push ( cleanValue ) ;
686
- console . log ( '✅ Добавлено значение:' , `${ varName } = ${ cleanValue } ` ) ;
687
- } else {
688
- console . log ( '⚠️ Пропущен дубликат:' , `${ varName } = ${ cleanValue } ` ) ;
689
- }
725
+ seenVariables . add ( varName ) ; // Помечаем переменную как уже обработанную
726
+ testData . push ( cleanValue ) ;
727
+ console . log ( '✅ Добавлено значение:' , `${ varName } = ${ cleanValue } ` ) ;
690
728
}
691
729
692
730
// Пропускаем запятую и пробелы
@@ -970,6 +1008,103 @@ ${variableDeclarations}
970
1008
` ;
971
1009
}
972
1010
1011
+ /**
1012
+ * Получает описание задачи через GraphQL API LeetCode для Daily Challenges
1013
+ */
1014
+ public async getDescriptionViaGraphQL ( titleSlug : string , needTranslation : boolean = false ) : Promise < string > {
1015
+ try {
1016
+ const https = require ( 'https' ) ;
1017
+
1018
+ const query = `
1019
+ query questionContent($titleSlug: String!) {
1020
+ question(titleSlug: $titleSlug) {
1021
+ content
1022
+ title
1023
+ titleSlug
1024
+ difficulty
1025
+ likes
1026
+ dislikes
1027
+ sampleTestCase
1028
+ exampleTestcases
1029
+ categoryTitle
1030
+ topicTags {
1031
+ name
1032
+ }
1033
+ companyTagStats
1034
+ }
1035
+ }
1036
+ ` ;
1037
+
1038
+ const postData = JSON . stringify ( {
1039
+ query : query ,
1040
+ variables : { titleSlug : titleSlug }
1041
+ } ) ;
1042
+
1043
+ const hostname = needTranslation ? 'leetcode.cn' : 'leetcode.com' ;
1044
+ const options = {
1045
+ hostname : hostname ,
1046
+ port : 443 ,
1047
+ path : '/graphql' ,
1048
+ method : 'POST' ,
1049
+ headers : {
1050
+ 'Content-Type' : 'application/json' ,
1051
+ 'Content-Length' : Buffer . byteLength ( postData ) ,
1052
+ 'User-Agent' : 'vscode-leetcode-extension'
1053
+ }
1054
+ } ;
1055
+
1056
+ const response = await new Promise < string > ( ( resolve , reject ) => {
1057
+ const req = https . request ( options , ( res : any ) => {
1058
+ let data = '' ;
1059
+ res . on ( 'data' , ( chunk : any ) => {
1060
+ data += chunk ;
1061
+ } ) ;
1062
+ res . on ( 'end' , ( ) => {
1063
+ resolve ( data ) ;
1064
+ } ) ;
1065
+ } ) ;
1066
+
1067
+ req . on ( 'error' , ( error : any ) => {
1068
+ reject ( error ) ;
1069
+ } ) ;
1070
+
1071
+ req . write ( postData ) ;
1072
+ req . end ( ) ;
1073
+ } ) ;
1074
+
1075
+ const jsonData = JSON . parse ( response ) ;
1076
+ if ( jsonData . data && jsonData . data . question ) {
1077
+ const question = jsonData . data . question ;
1078
+
1079
+ // Формируем markdown описание в том же формате, что ожидает парсер
1080
+ // Включаем HTML контент с примерами Input/Output
1081
+ const markdown = `
1082
+ # ${ question . title }
1083
+
1084
+ ${ question . content }
1085
+
1086
+ **Difficulty:** ${ question . difficulty }
1087
+ **Likes:** ${ question . likes }
1088
+ **Dislikes:** ${ question . dislikes }
1089
+ **Category:** ${ question . categoryTitle }
1090
+ **Tags:** ${ ( question . topicTags || [ ] ) . map ( ( tag : any ) => tag . name ) . join ( ', ' ) }
1091
+
1092
+ ## Test Cases
1093
+ ${ question . exampleTestcases || question . sampleTestCase || '' }
1094
+ ` . trim ( ) ;
1095
+
1096
+ console . log ( '✅ DEBUG: Получено описание через GraphQL, содержит "Input":' , markdown . includes ( 'Input' ) ) ;
1097
+ return markdown ;
1098
+ }
1099
+
1100
+ throw new Error ( 'No question data found in GraphQL response' ) ;
1101
+
1102
+ } catch ( error ) {
1103
+ console . log ( '❌ DEBUG: Ошибка при получении описания через GraphQL:' , error ) ;
1104
+ throw error ;
1105
+ }
1106
+ }
1107
+
973
1108
}
974
1109
975
1110
export const leetCodeExecutor : LeetCodeExecutor = new LeetCodeExecutor ( ) ;
0 commit comments