@@ -344,14 +344,7 @@ public static IReadOnlyList<GmlDiagnostic> CheckArgumentCountDiagnostics(string
344344 // Skip string/char literals (treat backticks as strings too)
345345 if ( c == '"' || c == '\' ' || c == '`' )
346346 {
347- char quote = c ;
348- i ++ ;
349- while ( i < len )
350- {
351- if ( code [ i ] == '\\ ' ) { i += 2 ; continue ; }
352- if ( code [ i ] == quote ) { i ++ ; break ; }
353- i ++ ;
354- }
347+ i = SkipStringLiteral ( code , i ) ;
355348 continue ;
356349 }
357350 // Identifiers
@@ -376,6 +369,24 @@ public static IReadOnlyList<GmlDiagnostic> CheckArgumentCountDiagnostics(string
376369 return diagnostics ?? ( IReadOnlyList < GmlDiagnostic > ) Array . Empty < GmlDiagnostic > ( ) ;
377370 }
378371
372+ // Skips a string literal starting at index i (which must be the quote character).
373+ // Handles backslash escape sequences; returns the index just past the closing
374+ // quote, or the end of the text if the string is unterminated.
375+ private static int SkipStringLiteral ( string code , int i )
376+ {
377+ char quote = code [ i ] ;
378+ i ++ ;
379+ int len = code . Length ;
380+ while ( i < len )
381+ {
382+ char ch = code [ i ] ;
383+ if ( ch == '\\ ' ) { i += 2 ; continue ; }
384+ if ( ch == quote ) return i + 1 ;
385+ i ++ ;
386+ }
387+ return i ;
388+ }
389+
379390 private static void CheckFunctionCall ( string code , string functionName , int wordStart ,
380391 ref int openParenIndex , ref List < GmlDiagnostic > diagnostics )
381392 {
@@ -386,6 +397,25 @@ private static void CheckFunctionCall(string code, string functionName, int word
386397 while ( scan < code . Length && depth > 0 )
387398 {
388399 char ch = code [ scan ] ;
400+ // Skip string literals so their contents never affect nesting
401+ if ( ch == '"' || ch == '\' ' || ch == '`' )
402+ {
403+ scan = SkipStringLiteral ( code , scan ) ;
404+ continue ;
405+ }
406+ // Skip comments
407+ if ( ch == '/' && scan + 1 < code . Length && code [ scan + 1 ] == '/' )
408+ {
409+ while ( scan < code . Length && code [ scan ] != '\n ' ) scan ++ ;
410+ continue ;
411+ }
412+ if ( ch == '/' && scan + 1 < code . Length && code [ scan + 1 ] == '*' )
413+ {
414+ scan += 2 ;
415+ while ( scan + 1 < code . Length && ! ( code [ scan ] == '*' && code [ scan + 1 ] == '/' ) ) scan ++ ;
416+ scan += 2 ;
417+ continue ;
418+ }
389419 if ( ch == '(' || ch == '[' || ch == '{' ) depth ++ ;
390420 else if ( ch == ')' )
391421 {
@@ -411,9 +441,31 @@ private static void CheckFunctionCall(string code, string functionName, int word
411441 int argCount = 0 ;
412442 bool hasContent = false ;
413443 int nesting = 0 ;
414- for ( int k = startIndex + 1 ; k < closeIndex ; k ++ )
444+ for ( int k = startIndex + 1 ; k < closeIndex ; )
415445 {
416446 char ch = code [ k ] ;
447+ // String literal: counts as argument content, but commas inside
448+ // it must not be treated as argument separators
449+ if ( ch == '"' || ch == '\' ' || ch == '`' )
450+ {
451+ hasContent = true ;
452+ k = Math . Min ( SkipStringLiteral ( code , k ) , closeIndex ) ;
453+ continue ;
454+ }
455+ // Skip line/block comments
456+ if ( ch == '/' && k + 1 < closeIndex && code [ k + 1 ] == '/' )
457+ {
458+ while ( k < closeIndex && code [ k ] != '\n ' ) k ++ ;
459+ continue ;
460+ }
461+ if ( ch == '/' && k + 1 < closeIndex && code [ k + 1 ] == '*' )
462+ {
463+ k += 2 ;
464+ while ( k + 1 < closeIndex && ! ( code [ k ] == '*' && code [ k + 1 ] == '/' ) ) k ++ ;
465+ k = Math . Min ( k + 2 , closeIndex ) ;
466+ continue ;
467+ }
468+ k ++ ;
417469 if ( char . IsWhiteSpace ( ch ) ) continue ;
418470 hasContent = true ;
419471 if ( ch == '(' || ch == '[' || ch == '{' ) nesting ++ ;
0 commit comments