-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdebug-position.js
More file actions
160 lines (132 loc) · 5.41 KB
/
Copy pathdebug-position.js
File metadata and controls
160 lines (132 loc) · 5.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Test to verify position calculation
const fs = require('fs');
// Custom JSON parser that tries to find the position of error
function parseJsonWithPosition(text) {
try {
const result = JSON.parse(text);
return { success: true, result };
} catch (error) {
if (error instanceof Error) {
// Try to extract position information from error message
const positionMatch = error.message.match(/position (\d+)/);
if (positionMatch) {
const position = parseInt(positionMatch[1], 10);
return { success: false, message: error.message, position };
}
// For newer Node.js versions that don't include position in error message,
// we'll try to find the problematic character with a more accurate approach
let position = 0;
// Try to find the actual position by parsing character by character
// This is a more accurate approach than the previous heuristic
for (let i = 0; i < text.length; i++) {
try {
// Try parsing progressively larger substrings
JSON.parse(text.substring(0, i + 1));
} catch (e) {
// If parsing fails, the error is likely at or near position i
position = i;
break;
}
}
// If we still haven't found a position, try to find the first non-whitespace character
// after the last successfully parsed character
if (position === 0) {
for (let i = 0; i < text.length; i++) {
const char = text[i];
if (!/\s/.test(char)) { // Not whitespace
position = i;
break;
}
}
}
return { success: false, message: error.message, position };
}
return { success: false, message: 'Unknown error occurred', position: 0 };
}
}
// Simulate VS Code position functions
function createPosition(line, character) {
return { line, character };
}
function positionAt(offset, text) {
let line = 0;
let character = 0;
for (let i = 0; i < offset && i < text.length; i++) {
if (text[i] === '\n') {
line++;
character = 0;
} else {
character++;
}
}
return createPosition(line, character);
}
function offsetAt(position, text) {
let offset = 0;
let currentLine = 0;
let currentChar = 0;
for (let i = 0; i < text.length; i++) {
if (currentLine === position.line && currentChar === position.character) {
return offset;
}
if (text[i] === '\n') {
currentLine++;
currentChar = 0;
} else {
currentChar++;
}
offset++;
}
return offset;
}
// Read the sample JSON file
const text = fs.readFileSync('./debug-invalid.json', 'utf8');
console.log('Sample JSON:');
console.log(text);
// Parse the JSON to find the error position
const parseResult = parseJsonWithPosition(text);
console.log('\nParse result:');
console.log('Success:', parseResult.success);
if (!parseResult.success) {
console.log('Error message:', parseResult.message);
console.log('Error position (character offset):', parseResult.position);
// Convert the position to line and character
const errorPosition = positionAt(parseResult.position, text);
console.log('Error position (line, character):', errorPosition);
// Check what character is at that position
const char = text[parseResult.position];
console.log('Character at error position:', char ? `"${char}"` : '(end of file)');
// Test with a selection (simulate selecting part of the document)
// Let's simulate selecting from the beginning to somewhere in the middle
const selectionStart = { line: 0, character: 0 }; // Start from beginning
const selectionEnd = { line: 5, character: 0 }; // End at beginning of line 5
const selectionStartOffset = offsetAt(selectionStart, text);
const selectionEndOffset = offsetAt(selectionEnd, text);
console.log('\nSimulating selection from start to line 5:');
console.log('Selection start offset:', selectionStartOffset);
console.log('Selection end offset:', selectionEndOffset);
// Extract selected text
const selectedText = text.substring(selectionStartOffset, selectionEndOffset);
console.log('Selected text:');
console.log(selectedText);
// Parse the selected text
const selectedParseResult = parseJsonWithPosition(selectedText);
console.log('\nParse result for selected text:');
console.log('Success:', selectedParseResult.success);
if (!selectedParseResult.success) {
console.log('Error position in selection:', selectedParseResult.position);
// Calculate the actual position in the document
const actualErrorPositionOffset = selectionStartOffset + selectedParseResult.position;
console.log('Actual error position offset in document:', actualErrorPositionOffset);
const actualErrorPosition = positionAt(actualErrorPositionOffset, text);
console.log('Actual error position (line, character):', actualErrorPosition);
// Compare with what our extension code would calculate
console.log('\nExtension code simulation:');
console.log('Selection isEmpty: false');
console.log('Document length:', text.length);
console.log('Compact result position:', selectedParseResult.position);
console.log('Selection start offset:', selectionStartOffset);
console.log('Calculated error offset:', selectionStartOffset + selectedParseResult.position);
console.log('Error position line/char:', actualErrorPosition.line, actualErrorPosition.character);
}
}