@@ -367,19 +367,20 @@ object StringContextMacro {
367
367
* @param offset the index in the part where there might be an error
368
368
* @param relative true if relative indexing is used, false otherwise
369
369
* @param argumentIndex the argument index parameter in the formatting String
370
+ * @param expected true if we have an expectedArgumentIndex, false otherwise
370
371
* @param expectedArgumentIndex the expected argument index parameter
371
372
* @param maxArgumentIndex the maximum argument index parameter that can be used
372
373
* @return reports a warning if relative indexing is used but an argument is still given,
373
374
* an error is the argument index is not in the bounds [1, number of arguments]
374
375
*/
375
- def checkArgumentIndex (partIndex : Int , offset : Int , relative : Boolean , argumentIndex : Int , expectedArgumentIndex : Int , maxArgumentIndex : Int ) = {
376
+ def checkArgumentIndex (partIndex : Int , offset : Int , relative : Boolean , argumentIndex : Int , expected : Boolean , expectedArgumentIndex : Int , maxArgumentIndex : Int ) = {
376
377
if (relative)
377
378
reporter.partWarning(" Argument index ignored if '<' flag is present" , partIndex, offset)
378
379
379
380
if (argumentIndex > maxArgumentIndex || argumentIndex <= 0 )
380
381
reporter.partError(" Argument index out of range" , partIndex, offset)
381
382
382
- if (expectedArgumentIndex != argumentIndex && ! reporter.hasReported())
383
+ if (expected && expectedArgumentIndex != argumentIndex && ! reporter.hasReported())
383
384
reporter.partWarning(" Index is not this arg" , partIndex, offset)
384
385
}
385
386
@@ -560,6 +561,7 @@ object StringContextMacro {
560
561
* @param hasArgumentIndex
561
562
* @param actualArgumentIndex
562
563
* @param expectedArgumentIndex
564
+ * @param firstFormattingSubstring true if it is the first in the list, i.e. not an indexed argument
563
565
* @param maxArgumentIndex
564
566
* @param hasRelative
565
567
* @param hasWidth
@@ -571,12 +573,14 @@ object StringContextMacro {
571
573
* @return the argument index and its type if there is an argument, the flags and the conversion parameter
572
574
* reports an error/warning if the formatting parameters are not allowed/wrong, nothing otherwise
573
575
*/
574
- def checkFormatSpecifiers (partIndex : Int , hasArgumentIndex : Boolean , actualArgumentIndex : Int , expectedArgumentIndex : Option [Int ], maxArgumentIndex : Option [Int ],
576
+ def checkFormatSpecifiers (partIndex : Int , hasArgumentIndex : Boolean , actualArgumentIndex : Int , expectedArgumentIndex : Option [Int ], firstFormattingSubstring : Boolean , maxArgumentIndex : Option [Int ],
575
577
hasRelative : Boolean , hasWidth : Boolean , width : Int , hasPrecision : Boolean , precision : Int , flags : List [(Char , Int )], conversion : Int , argType : Option [Type ], part : String ) : (Option [(Type , Int )], Char , List [(Char , Int )])= {
576
578
val conversionChar = part.charAt(conversion)
577
579
578
- if (hasArgumentIndex && expectedArgumentIndex.nonEmpty && maxArgumentIndex.nonEmpty)
579
- checkArgumentIndex(partIndex, actualArgumentIndex, hasRelative, part.charAt(actualArgumentIndex).asDigit, expectedArgumentIndex.get, maxArgumentIndex.get)
580
+ if (hasArgumentIndex && expectedArgumentIndex.nonEmpty && maxArgumentIndex.nonEmpty && firstFormattingSubstring)
581
+ checkArgumentIndex(partIndex, actualArgumentIndex, hasRelative, part.charAt(actualArgumentIndex).asDigit, true , expectedArgumentIndex.get, maxArgumentIndex.get)
582
+ else if (hasArgumentIndex && maxArgumentIndex.nonEmpty && ! firstFormattingSubstring)
583
+ checkArgumentIndex(partIndex, actualArgumentIndex, hasRelative, part.charAt(actualArgumentIndex).asDigit, false , 0 , maxArgumentIndex.get)
580
584
581
585
conversionChar match {
582
586
case 'c' | 'C' => checkCharacterConversion(partIndex, flags, hasPrecision, precision)
@@ -690,7 +694,7 @@ object StringContextMacro {
690
694
case Some (argIndex, arg) => {
691
695
val (hasArgumentIndex, argumentIndex, flags, hasWidth, width, hasPrecision, precision, hasRelative, relativeIndex, conversion) = getFormatSpecifiers(part, argIndex, argIndex + 1 , false , formattingStart)
692
696
if (! reporter.hasReported()){
693
- val conversionWithType = checkFormatSpecifiers(argIndex + 1 , hasArgumentIndex, argumentIndex, Some (argIndex + 1 ), maxArgumentIndex, hasRelative, hasWidth, width, hasPrecision, precision, flags, conversion, Some (arg.unseal.tpe), part)
697
+ val conversionWithType = checkFormatSpecifiers(argIndex + 1 , hasArgumentIndex, argumentIndex, Some (argIndex + 1 ), start == 0 , maxArgumentIndex, hasRelative, hasWidth, width, hasPrecision, precision, flags, conversion, Some (arg.unseal.tpe), part)
694
698
nextStart = conversion + 1
695
699
conversionWithType :: checkPart(part, nextStart, argument, maxArgumentIndex)
696
700
} else checkPart(part, conversion + 1 , argument, maxArgumentIndex)
@@ -702,7 +706,7 @@ object StringContextMacro {
702
706
if (hasRelative)
703
707
reporter.partError(" No last arg" , 0 , relativeIndex)
704
708
if (! reporter.hasReported()){
705
- val conversionWithType = checkFormatSpecifiers(0 , hasArgumentIndex, argumentIndex, None , maxArgumentIndex, hasRelative, hasWidth, width, hasPrecision, precision, flags, conversion, None , part)
709
+ val conversionWithType = checkFormatSpecifiers(0 , hasArgumentIndex, argumentIndex, None , start == 0 , maxArgumentIndex, hasRelative, hasWidth, width, hasPrecision, precision, flags, conversion, None , part)
706
710
nextStart = conversion + 1
707
711
if (! reporter.hasReported() && part.charAt(conversion) != '%' && part.charAt(conversion) != 'n' && ! hasArgumentIndex && ! hasRelative)
708
712
reporter.partError(" conversions must follow a splice; use %% for literal %, %n for newline" , 0 , part.indexOf('%' ))
0 commit comments