@@ -2,6 +2,7 @@ package fourslash
2
2
3
3
import (
4
4
"encoding/json"
5
+ "fmt"
5
6
"strings"
6
7
"testing"
7
8
"unicode/utf8"
@@ -56,11 +57,15 @@ func ParseTestData(t *testing.T, contents string, fileName string) TestData {
56
57
markerPositions := make (map [string ]* Marker )
57
58
var markers []* Marker
58
59
var ranges []* RangeMarker
59
- filesWithMarker , symlinks , _ , globalOptions := testrunner .ParseTestFilesAndSymlinks (
60
+
61
+ filesWithMarker , symlinks , _ , globalOptions , e := testrunner .ParseTestFilesAndSymlinks (
60
62
contents ,
61
63
fileName ,
62
64
parseFileContent ,
63
65
)
66
+ if e != nil {
67
+ t .Fatalf ("Error parsing fourslash data: %s" , e .Error ())
68
+ }
64
69
65
70
hasTSConfig := false
66
71
for _ , file := range filesWithMarker {
@@ -138,7 +143,7 @@ const (
138
143
stateInObjectMarker
139
144
)
140
145
141
- func parseFileContent (fileName string , content string , fileOptions map [string ]string ) * testFileWithMarkers {
146
+ func parseFileContent (fileName string , content string , fileOptions map [string ]string ) ( * testFileWithMarkers , error ) {
142
147
fileName = tspath .GetNormalizedAbsolutePath (fileName , "/" )
143
148
144
149
// The file content (minus metacharacters) so far
@@ -159,7 +164,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
159
164
column := 1
160
165
161
166
// The current marker (or maybe multi-line comment?) we're parsing, possibly
162
- var openMarker locationInformation
167
+ var openMarker * locationInformation
163
168
164
169
// The latest position of the start of an unflushed plain text area
165
170
lastNormalCharPosition := 0
@@ -197,7 +202,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
197
202
} else if previousCharacter == '|' && currentCharacter == ']' {
198
203
// found a range end
199
204
if len (openRanges ) == 0 {
200
- reportError (fileName , line , column , "Found range end with no matching start." )
205
+ return nil , reportError (fileName , line , column , "Found range end with no matching start." )
201
206
}
202
207
rangeStart := openRanges [len (openRanges )- 1 ]
203
208
openRanges = openRanges [:len (openRanges )- 1 ]
@@ -219,7 +224,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
219
224
} else if previousCharacter == '/' && currentCharacter == '*' {
220
225
// found a possible marker start
221
226
state = stateInSlashStarMarker
222
- openMarker = locationInformation {
227
+ openMarker = & locationInformation {
223
228
position : (i - 1 ) - difference ,
224
229
sourcePosition : i - 1 ,
225
230
sourceLine : line ,
@@ -228,7 +233,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
228
233
} else if previousCharacter == '{' && currentCharacter == '|' {
229
234
// found an object marker start
230
235
state = stateInObjectMarker
231
- openMarker = locationInformation {
236
+ openMarker = & locationInformation {
232
237
position : (i - 1 ) - difference ,
233
238
sourcePosition : i - 1 ,
234
239
sourceLine : line ,
@@ -240,7 +245,10 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
240
245
// Object markers are only ever terminated by |} and have no content restrictions
241
246
if previousCharacter == '|' && currentCharacter == '}' {
242
247
objectMarkerData := strings .TrimSpace (content [openMarker .sourcePosition + 2 : i - 1 ])
243
- marker := getObjectMarker (fileName , openMarker , objectMarkerData )
248
+ marker , e := getObjectMarker (fileName , openMarker , objectMarkerData )
249
+ if e != nil {
250
+ return nil , e
251
+ }
244
252
245
253
if len (openRanges ) > 0 {
246
254
openRanges [len (openRanges )- 1 ].marker = marker
@@ -252,7 +260,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
252
260
difference += i + 1 - openMarker .sourcePosition
253
261
254
262
// Reset the state
255
- openMarker = locationInformation {}
263
+ openMarker = nil
256
264
state = stateNone
257
265
}
258
266
case stateInSlashStarMarker :
@@ -276,7 +284,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
276
284
difference += i + 1 - openMarker .sourcePosition
277
285
278
286
// Reset the state
279
- openMarker = locationInformation {}
287
+ openMarker = nil
280
288
state = stateNone
281
289
} else if ! (stringutil .IsDigit (currentCharacter ) ||
282
290
stringutil .IsASCIILetter (currentCharacter ) ||
@@ -289,7 +297,7 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
289
297
// Bail out the text we've gathered so far back into the output
290
298
flush (i )
291
299
lastNormalCharPosition = i
292
- openMarker = locationInformation {}
300
+ openMarker = nil
293
301
state = stateNone
294
302
}
295
303
}
@@ -309,6 +317,15 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
309
317
// Add the remaining text
310
318
flush (- 1 )
311
319
320
+ if len (openRanges ) > 0 {
321
+ openRange := openRanges [0 ]
322
+ return nil , reportError (fileName , openRange .sourceLine , openRange .sourceColumn , "Unterminated range." )
323
+ }
324
+
325
+ if openMarker != nil {
326
+ return nil , reportError (fileName , openMarker .sourceLine , openMarker .sourceColumn , "Unterminated marker." )
327
+ }
328
+
312
329
outputString := output .String ()
313
330
// Set LS positions for markers
314
331
lineMap := ls .ComputeLineStarts (outputString )
@@ -338,22 +355,20 @@ func parseFileContent(fileName string, content string, fileOptions map[string]st
338
355
file : testFileInfo ,
339
356
markers : markers ,
340
357
ranges : rangeMarkers ,
341
- }
358
+ }, nil
342
359
}
343
360
344
- func getObjectMarker (fileName string , location locationInformation , text string ) * Marker {
361
+ func getObjectMarker (fileName string , location * locationInformation , text string ) ( * Marker , error ) {
345
362
// Attempt to parse the marker value as JSON
346
363
var v interface {}
347
364
e := json .Unmarshal ([]byte ("{ " + text + " }" ), & v )
348
365
349
366
if e != nil {
350
- reportError (fileName , location .sourceLine , location .sourceColumn , "Unable to parse marker text " + text )
351
- return nil
367
+ return nil , reportError (fileName , location .sourceLine , location .sourceColumn , "Unable to parse marker text " + text )
352
368
}
353
369
markerValue , ok := v .(map [string ]interface {})
354
370
if ! ok || len (markerValue ) == 0 {
355
- reportError (fileName , location .sourceLine , location .sourceColumn , "Object markers can not be empty" )
356
- return nil
371
+ return nil , reportError (fileName , location .sourceLine , location .sourceColumn , "Object markers can not be empty" )
357
372
}
358
373
359
374
marker := & Marker {
@@ -369,10 +384,17 @@ func getObjectMarker(fileName string, location locationInformation, text string)
369
384
}
370
385
}
371
386
372
- return marker
387
+ return marker , nil
388
+ }
389
+
390
+ func reportError (fileName string , line int , col int , message string ) error {
391
+ return & fourslashError {fmt .Sprintf ("%v (%v,%v): %v" , fileName , line , col , message )}
392
+ }
393
+
394
+ type fourslashError struct {
395
+ err string
373
396
}
374
397
375
- func reportError (fileName string , line int , col int , message string ) {
376
- // !!! not implemented
377
- // errorMessage := fileName + "(" + string(line) + "," + string(col) + "): " + message;
398
+ func (e * fourslashError ) Error () string {
399
+ return e .err
378
400
}
0 commit comments