@@ -316,41 +316,40 @@ export function validateScrapScript(
316
316
text : string ,
317
317
maxNumberOfProblems : number ,
318
318
) : Diagnostic [ ] {
319
- const diagnostics : Diagnostic [ ] = [ ] ;
320
-
319
+ let tree : Tree ;
321
320
try {
322
- const tree = parse ( text ) ;
323
- const rootNode = tree . rootNode ;
324
-
325
- // Enhanced error detection
326
- if ( rootNode . hasError ) {
327
- const errorNodes = findErrorNodes ( rootNode ) ;
328
-
329
- for ( const errorNode of errorNodes ) {
330
- const range = nodeToRange ( errorNode ) ;
331
- const diagnostic = createDiagnosticForError ( errorNode , range ) ;
332
- diagnostics . push ( diagnostic ) ;
333
- }
334
- }
335
-
336
- // Additional validations
337
- validatePatternMatching ( rootNode , diagnostics ) ;
338
- validateTypeConsistency ( rootNode , diagnostics , text ) ;
339
- validateWhereClauseStructure ( rootNode , diagnostics ) ;
340
- validateRecordSyntax ( rootNode , diagnostics ) ;
341
- validateListSyntax ( rootNode , diagnostics ) ;
342
- validateFunctionSyntax ( rootNode , diagnostics ) ;
321
+ tree = parse ( text ) ;
343
322
} catch ( err ) {
344
323
console . error ( "Error parsing ScrapScript:" , err ) ;
345
- diagnostics . push ( {
324
+ return limitDiagnostics ( [ {
346
325
severity : DiagnosticSeverity . Error ,
347
326
range : Range . create ( 0 , 0 , 0 , 0 ) ,
348
327
message : `Failed to parse ScrapScript: ${ err } ` ,
349
328
source : "scrapscript" ,
350
- } ) ;
329
+ } ] , maxNumberOfProblems ) ;
351
330
}
352
331
353
- return diagnostics . slice ( 0 , maxNumberOfProblems ) ;
332
+ const rootNode : SyntaxNode = tree . rootNode ;
333
+
334
+ // Enhanced error detection
335
+ const errors : Diagnostic [ ] = rootNode . hasError ?
336
+ findErrorNodes ( rootNode ) . map ( errorNode => {
337
+ const range = nodeToRange ( errorNode ) ;
338
+ return createDiagnosticForError ( errorNode , range ) ;
339
+ } ) : [ ] ;
340
+
341
+ // Additional validations
342
+ const validations : Diagnostic [ ] = [
343
+ validatePatternMatching ( rootNode ) ,
344
+ validateTypeConsistency ( rootNode , text ) ,
345
+ validateWhereClauseStructure ( rootNode ) ,
346
+ validateRecordSyntax ( rootNode ) ,
347
+ validateListSyntax ( rootNode ) ,
348
+ validateFunctionSyntax ( rootNode )
349
+ ] . flat ( ) ;
350
+
351
+ const diagnostics : Diagnostic [ ] = errors . concat ( validations ) ;
352
+ return limitDiagnostics ( diagnostics , maxNumberOfProblems ) ;
354
353
}
355
354
356
355
function findErrorNodes ( node : SyntaxNode ) : SyntaxNode [ ] {
@@ -419,11 +418,9 @@ function createDiagnosticForError(
419
418
} ;
420
419
}
421
420
422
- function validatePatternMatching (
423
- node : SyntaxNode ,
424
- diagnostics : Diagnostic [ ] ,
425
- ) : void {
426
- walkTree ( node , ( currentNode ) => {
421
+ function validatePatternMatching ( node : SyntaxNode ) : Diagnostic [ ] {
422
+ return validateNodeBy ( node , ( currentNode ) => {
423
+ const diagnostics : Diagnostic [ ] = [ ] ;
427
424
if (
428
425
currentNode . type === "match_fun" ||
429
426
currentNode . type === "pattern_match"
@@ -459,15 +456,16 @@ function validatePatternMatching(
459
456
} ) ;
460
457
}
461
458
}
459
+ return diagnostics ;
462
460
} ) ;
463
461
}
464
462
465
463
function validateTypeConsistency (
466
464
node : SyntaxNode ,
467
- diagnostics : Diagnostic [ ] ,
468
465
text : string ,
469
- ) : void {
470
- walkTree ( node , ( currentNode ) => {
466
+ ) : Diagnostic [ ] {
467
+ return validateNodeBy ( node , ( currentNode ) => {
468
+ const diagnostics : Diagnostic [ ] = [ ] ;
471
469
if ( currentNode . type === "list" ) {
472
470
const elementTypes = new Set < string > ( ) ;
473
471
@@ -490,6 +488,7 @@ function validateTypeConsistency(
490
488
} ) ;
491
489
}
492
490
}
491
+ return diagnostics ;
493
492
} ) ;
494
493
}
495
494
@@ -517,11 +516,9 @@ function inferBasicType(node: SyntaxNode): string | null {
517
516
}
518
517
}
519
518
520
- function validateWhereClauseStructure (
521
- node : SyntaxNode ,
522
- diagnostics : Diagnostic [ ] ,
523
- ) : void {
524
- walkTree ( node , ( currentNode ) => {
519
+ function validateWhereClauseStructure ( node : SyntaxNode ) : Diagnostic [ ] {
520
+ return validateNodeBy ( node , ( currentNode ) => {
521
+ let diagnostics : Diagnostic [ ] = [ ] ;
525
522
if ( currentNode . type === "where" ) {
526
523
// Check for proper "; identifier = expression" structure
527
524
let hasProperStructure = false ;
@@ -548,14 +545,13 @@ function validateWhereClauseStructure(
548
545
} ) ;
549
546
}
550
547
}
548
+ return diagnostics ;
551
549
} ) ;
552
550
}
553
551
554
- function validateRecordSyntax (
555
- node : SyntaxNode ,
556
- diagnostics : Diagnostic [ ] ,
557
- ) : void {
558
- walkTree ( node , ( currentNode ) => {
552
+ function validateRecordSyntax ( node : SyntaxNode ) : Diagnostic [ ] {
553
+ return validateNodeBy ( node , ( currentNode ) => {
554
+ let diagnostics : Diagnostic [ ] = [ ] ;
559
555
if ( currentNode . type === "record" ) {
560
556
// Validate record field syntax
561
557
for ( let i = 0 ; i < currentNode . namedChildCount ; i ++ ) {
@@ -574,11 +570,13 @@ function validateRecordSyntax(
574
570
}
575
571
}
576
572
}
573
+ return diagnostics ;
577
574
} ) ;
578
575
}
579
576
580
- function validateListSyntax ( node : SyntaxNode , diagnostics : Diagnostic [ ] ) : void {
581
- walkTree ( node , ( currentNode ) => {
577
+ function validateListSyntax ( node : SyntaxNode ) : Diagnostic [ ] {
578
+ return validateNodeBy ( node , ( currentNode ) => {
579
+ let diagnostics : Diagnostic [ ] = [ ] ;
582
580
if ( currentNode . type === "list" ) {
583
581
// Check for trailing commas and proper separators
584
582
const text = currentNode . text ;
@@ -592,14 +590,13 @@ function validateListSyntax(node: SyntaxNode, diagnostics: Diagnostic[]): void {
592
590
} ) ;
593
591
}
594
592
}
593
+ return diagnostics ;
595
594
} ) ;
596
595
}
597
596
598
- function validateFunctionSyntax (
599
- node : SyntaxNode ,
600
- diagnostics : Diagnostic [ ] ,
601
- ) : void {
602
- walkTree ( node , ( currentNode ) => {
597
+ function validateFunctionSyntax ( node : SyntaxNode ) : Diagnostic [ ] {
598
+ return validateNodeBy ( node , ( currentNode ) => {
599
+ let diagnostics : Diagnostic [ ] = [ ] ;
603
600
if ( currentNode . type === "fun" ) {
604
601
// Check for proper arrow function syntax
605
602
const hasArrow = currentNode . text . includes ( "->" ) ;
@@ -613,6 +610,7 @@ function validateFunctionSyntax(
613
610
} ) ;
614
611
}
615
612
}
613
+ return diagnostics ;
616
614
} ) ;
617
615
}
618
616
0 commit comments