Skip to content

Commit 3a1e403

Browse files
author
Sara Alemanno
committed
Fix errors on tests and test/fix code
1 parent 835a701 commit 3a1e403

File tree

2 files changed

+44
-46
lines changed

2 files changed

+44
-46
lines changed

library/src-3.x/dotty/internal/StringContextMacro.scala

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ object StringContextMacro {
203203
case p :: parts1 => p :: parts1.map((part : String) => {
204204
if (!part.startsWith("%")) {
205205
val index = part.indexOf('%')
206-
if (index != -1) {
206+
if (!reporter.hasReported() && index != -1) {
207207
reporter.partError("conversions must follow a splice; use %% for literal %, %n for newline", parts.indexOf(part), index)
208208
"%s" + part
209209
} else "%s" + part
@@ -311,7 +311,7 @@ object StringContextMacro {
311311

312312
//relative indexing
313313
val hasRelative = conversion < l && part.charAt(conversion) == '<'
314-
val relativeIndex = conversion + 1
314+
val relativeIndex = conversion
315315
if (hasRelative)
316316
conversion += 1
317317

@@ -333,13 +333,13 @@ object StringContextMacro {
333333
conversion += 1
334334
}
335335
if (oldConversion == conversion) {
336-
reporter.partError("Missing conversion operator in '" + part.substring(pos, oldConversion - 1) + "'; use %% for literal %, %n for newline", partIndex, 0)
336+
reporter.partError("Missing conversion operator in '" + part.substring(pos, oldConversion - 1) + "'; use %% for literal %, %n for newline", partIndex, pos)
337337
hasPrecision = false
338338
}
339339
}
340340

341341
//conversion
342-
if(conversion >= l || (!part.charAt(conversion).isLetter && part.charAt(conversion) != '%'))
342+
if((conversion >= l || (!part.charAt(conversion).isLetter && part.charAt(conversion) != '%')) && !reporter.hasReported())
343343
reporter.partError("Missing conversion operator in '" + part.substring(pos, conversion) + "'; use %% for literal %, %n for newline", partIndex, pos)
344344

345345
val hasWidth = (hasWidth1 && !hasArgumentIndex) || hasWidth2
@@ -358,7 +358,7 @@ object StringContextMacro {
358358
*/
359359
def checkSubtype(actualType : Type, expectedType : String, argIndex : Int, possibilities : Type*) = {
360360
if (possibilities.find(actualType <:< _).isEmpty)
361-
reporter.argError("type mismatch;\n found : " + actualType.widen.show.stripPrefix("scala.Predef.") + "\n required: " + expectedType, argIndex)
361+
reporter.argError("type mismatch;\n found : " + actualType.widen.show.stripPrefix("scala.Predef.").stripPrefix("scala.") + "\n required: " + expectedType, argIndex)
362362
}
363363

364364
/** Checks whether a given argument index, relative or not, is in the correct bounds
@@ -379,7 +379,7 @@ object StringContextMacro {
379379
if (argumentIndex > maxArgumentIndex || argumentIndex <= 0)
380380
reporter.partError("Argument index out of range", partIndex, offset)
381381

382-
if (expectedArgumentIndex != argumentIndex)
382+
if (expectedArgumentIndex != argumentIndex && !reporter.hasReported())
383383
reporter.partWarning("Index is not this arg", partIndex, offset)
384384
}
385385

@@ -545,10 +545,10 @@ object StringContextMacro {
545545
*/
546546
def checkSpecials(partIndex : Int, conversionChar : Char, hasPrecision : Boolean, precision : Int, hasWidth : Boolean, width : Int) = conversionChar match {
547547
case 'n' => {
548-
checkNotAllowedParameter(hasPrecision, partIndex, precision + 1, "precision")
548+
checkNotAllowedParameter(hasPrecision, partIndex, precision, "precision")
549549
checkNotAllowedParameter(hasWidth, partIndex, width, "width")
550550
}
551-
case '%' => checkNotAllowedParameter(hasPrecision, partIndex, precision + 1, "precision")
551+
case '%' => checkNotAllowedParameter(hasPrecision, partIndex, precision, "precision")
552552
case _ => // OK
553553
}
554554

@@ -597,13 +597,14 @@ object StringContextMacro {
597597
* @param conversionChar the character used for the conversion
598598
* @param argument an option containing the type and index of the argument, None if there is no argument
599599
* @param flags the flags used for the formatting
600+
* @param formattingStart the index in the part where the formatting substring starts, i.e. where the '%' is
600601
* @return reports an error/warning if the formatting parameters are not allowed/wrong depending on the type, nothing otherwise
601602
*/
602-
def checkArgTypeWithConversion(partIndex : Int, conversionChar : Char, argument : Option[(Type, Int)], flags : List[(Char, Int)]) = {
603+
def checkArgTypeWithConversion(partIndex : Int, conversionChar : Char, argument : Option[(Type, Int)], flags : List[(Char, Int)], formattingStart : Int) = {
603604
if (argument.nonEmpty)
604605
checkTypeWithArgs(argument.get, conversionChar, partIndex, flags)
605606
else
606-
checkTypeWithoutArgs(conversionChar, partIndex, flags)
607+
checkTypeWithoutArgs(conversionChar, partIndex, flags, formattingStart)
607608
}
608609

609610
/** Checks whether the argument type checks with the formatting parameters
@@ -628,9 +629,9 @@ object StringContextMacro {
628629
case 'd' | 'o' | 'x' | 'X' => {
629630
checkSubtype(argType, "Int", argIndex, integral : _*)
630631
if (conversionChar != 'd') {
631-
val notAllowedFlagOnCondition = List(('+', !(argType <:< typeOf[java.math.BigInteger]), "Only use '+' for BigInt conversions to o, x, X"),
632-
(' ', !(argType <:< typeOf[java.math.BigInteger]), "Only use ' ' for BigInt conversions to o, x, X"),
633-
('(', !(argType <:< typeOf[java.math.BigInteger]), "Only use '(' for BigInt conversions to o, x, X"),
632+
val notAllowedFlagOnCondition = List(('+', !(argType <:< typeOf[java.math.BigInteger]), "only use '+' for BigInt conversions to o, x, X"),
633+
(' ', !(argType <:< typeOf[java.math.BigInteger]), "only use ' ' for BigInt conversions to o, x, X"),
634+
('(', !(argType <:< typeOf[java.math.BigInteger]), "only use '(' for BigInt conversions to o, x, X"),
634635
(',', true, "',' only allowed for d conversion of integral types"))
635636
checkFlags(partIndex, flags, notAllowedFlagOnCondition : _*)
636637
}
@@ -641,7 +642,7 @@ object StringContextMacro {
641642
case 'h' | 'H' | 'S' | 's' =>
642643
if (!(argType <:< typeOf[java.util.Formattable]))
643644
for {flag <- flags ; if (flag._1 == '#')}
644-
reporter.argError("type mismatch;\n found :" + argType.widen.show.stripPrefix("scala.Predef.") + "\n required: java.util.Formattable", argIndex)
645+
reporter.argError("type mismatch;\n found : " + argType.widen.show.stripPrefix("scala.Predef.").stripPrefix("scala.") + "\n required: java.util.Formattable", argIndex)
645646
case 'n' | '%' =>
646647
case illegal =>
647648
}
@@ -652,23 +653,21 @@ object StringContextMacro {
652653
* @param conversionChar the conversion parameter inside the formatting String
653654
* @param partIndex index of the part inside the String Context
654655
* @param flags the list of flags, and their index, used inside the formatting String
656+
* @param formattingStart the index in the part where the formatting substring starts, i.e. where the '%' is
655657
* @return reports an error if the formatting parameter refer to the type of the parameter but no parameter is given
656658
* nothing otherwise
657659
*/
658-
def checkTypeWithoutArgs(conversionChar : Char, partIndex : Int, flags : List[(Char, Int)]) = {
660+
def checkTypeWithoutArgs(conversionChar : Char, partIndex : Int, flags : List[(Char, Int)], formattingStart : Int) = {
659661
conversionChar match {
660662
case 'o' | 'x' | 'X' => {
661-
val notAllowedFlagOnCondition = List(('+', true, "Only use '+' for BigInt conversions to o, x, X"),
662-
(' ', true, "Only use ' ' for BigInt conversions to o, x, X"),
663-
('(', true, "Only use '(' for BigInt conversions to o, x, X"),
663+
val notAllowedFlagOnCondition = List(('+', true, "only use '+' for BigInt conversions to o, x, X"),
664+
(' ', true, "only use ' ' for BigInt conversions to o, x, X"),
665+
('(', true, "only use '(' for BigInt conversions to o, x, X"),
664666
(',', true, "',' only allowed for d conversion of integral types"))
665667
checkFlags(partIndex, flags, notAllowedFlagOnCondition : _*)
666668
}
667669
case _ => //OK
668670
}
669-
670-
if (!reporter.hasReported() && conversionChar != '%' && conversionChar != 'n')
671-
reporter.partError("conversions must follow a splice; use %% for literal %, %n for newline", partIndex, 0)
672671
}
673672

674673
/** Checks that a given part of the String Context respects every formatting constraint per parameter
@@ -699,14 +698,14 @@ object StringContextMacro {
699698
case None => {
700699
val (hasArgumentIndex, argumentIndex, flags, hasWidth, width, hasPrecision, precision, hasRelative, relativeIndex, conversion) = getFormatSpecifiers(part, 0, 0, true, formattingStart)
701700
if (hasArgumentIndex && !(part.charAt(argumentIndex).asDigit == 1 && (part.charAt(conversion) == 'n' || part.charAt(conversion) == '%')))
702-
reporter.partError("Argument index out of range", 0, argumentIndex + 1)
701+
reporter.partError("Argument index out of range", 0, argumentIndex)
703702
if (hasRelative)
704703
reporter.partError("No last arg", 0, relativeIndex)
705704
if (!reporter.hasReported()){
706705
val conversionWithType = checkFormatSpecifiers(0, hasArgumentIndex, argumentIndex, None, maxArgumentIndex, hasRelative, hasWidth, width, hasPrecision, precision, flags, conversion, None, part)
707706
nextStart = conversion + 1
708707
if (!reporter.hasReported() && part.charAt(conversion) != '%' && part.charAt(conversion) != 'n')
709-
reporter.partError("conversions must follow a splice; use %% for literal %, %n for newline", 0, 0)
708+
reporter.partError("conversions must follow a splice; use %% for literal %, %n for newline", 0, part.indexOf('%'))
710709
conversionWithType :: checkPart(part, nextStart, argument, maxArgumentIndex)
711710
} else checkPart(part, conversion + 1, argument, maxArgumentIndex)
712711
}
@@ -730,16 +729,15 @@ object StringContextMacro {
730729
val argTypeWithConversion = checkPart(parts.head, 0, None, None)
731730
if (!reporter.hasReported())
732731
for ((argument, conversionChar, flags) <- argTypeWithConversion)
733-
checkArgTypeWithConversion(0, conversionChar, argument, flags)
734-
}
735-
else {
732+
checkArgTypeWithConversion(0, conversionChar, argument, flags, parts.head.indexOf('%'))
733+
} else {
736734
val partWithArgs = parts.tail.zip(args)
737735
for (i <- (0 until args.size)){
738736
val (part, arg) = partWithArgs(i)
739737
val argTypeWithConversion = checkPart(part, 0, Some((i, arg)), Some(args.size))
740738
if (!reporter.hasReported())
741739
for ((argument, conversionChar, flags) <- argTypeWithConversion)
742-
checkArgTypeWithConversion(0, conversionChar, argument, flags)
740+
checkArgTypeWithConversion(i + 1, conversionChar, argument, flags, parts(i).indexOf('%'))
743741
}
744742
}
745743
}

tests/run-macros/f-interpolator-neg/Tests_2.scala

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ object Test {
4040
assertEquals(foo"$f%o", List((true, 1, 0, 0, "type mismatch;\n found : Double\n required: Int")))
4141
assertEquals(foo"$s%e", List((true, 1, 0, 0, "type mismatch;\n found : String\n required: Double")))
4242
assertEquals(foo"$b%f", List((true, 1, 0, 0, "type mismatch;\n found : Boolean\n required: Double")))
43-
assertEquals(foo"$s%i", List((true, 0, 0, 1, "illegal conversion character 'i'")))
43+
assertEquals(foo"$s%i", List((true, 0, 1, 1, "illegal conversion character 'i'")))
4444
}
4545

4646
def flagMismatches(s : String, c : Char, d : Int, f : Double, t : java.util.Date) = {
@@ -60,31 +60,31 @@ object Test {
6060
import TestFooErrors._
6161
assertEquals(foo"$c%.2c", List((true, 0, 1, 1, "precision not allowed")))
6262
assertEquals(foo"$d%.2d", List((true, 0, 1, 1, "precision not allowed")))
63-
assertEquals(foo"%.2%", List((true, 0, 1, 1, "precision not allowed")))
64-
assertEquals(foo"%.2n", List((true, 0, 1, 1, "precision not allowed")))
63+
assertEquals(foo"%.2%", List((true, 0, 0, 1, "precision not allowed")))
64+
assertEquals(foo"%.2n", List((true, 0, 0, 1, "precision not allowed")))
6565
assertEquals(foo"$f%.2a", List((true, 0, 1, 1, "precision not allowed")))
6666
assertEquals(foo"$t%.2tT", List((true, 0, 1, 1, "precision not allowed")))
6767
}
6868

6969
def badIndexes() = {
7070
import TestFooErrors._
71-
assertEquals(foo"%<s", List((true, 0, 1, 1, "No last arg")))
72-
assertEquals(foo"%<c", List((true, 0, 1, 1, "No last arg")))
73-
assertEquals(foo"%<tT", List((true, 0, 1, 1, "No last arg")))
74-
assertEquals(foo"${8}%d ${9}%d %3$$d", List((true, 0, 3, 1, "Argument index out of range")))
75-
assertEquals(foo"${8}%d ${9}%d%0$$d", List((true, 0, 3, 1, "Argument index out of range")))
71+
assertEquals(foo"%<s", List((true, 0, 0, 1, "No last arg")))
72+
assertEquals(foo"%<c", List((true, 0, 0, 1, "No last arg")))
73+
assertEquals(foo"%<tT", List((true, 0, 0, 1, "No last arg")))
74+
assertEquals(foo"${8}%d ${9}%d %3$$d", List((true, 0, 2, 4, "Argument index out of range")))
75+
assertEquals(foo"${8}%d ${9}%d%0$$d", List((true, 0, 2, 3, "Argument index out of range")))
7676
}
7777

7878
def warnings(s : String) = {
7979
import TestFooErrors._
8080
assertEquals(foo"${8}%d ${9}%1$$d", List((false, 0, 2, 1, "Index is not this arg")))
81-
assertEquals(foo"$s%s $s%s %1$$<s", List((false, 0, 3, 1, "Argument index ignored if '<' flag is present")))
81+
assertEquals(foo"$s%s $s%s %1$$<s", List((false, 0, 2, 4, "Argument index ignored if '<' flag is present")))
8282
assertEquals(foo"$s%s $s%1$$s", List((false, 0, 2, 1, "Index is not this arg")))
8383
}
8484

8585
def badArgTypes(s : String) = {
8686
import TestFooErrors._
87-
assertEquals(foo"$s%#s", List((true, 1, 1, 0, "type mismatch;\nfound : String\nrequired: java.util.Formattable")))
87+
assertEquals(foo"$s%#s", List((true, 1, 0, 0, "type mismatch;\n found : String\n required: java.util.Formattable")))
8888
}
8989

9090
def misunderstoodConversions(t : java.util.Date, s : String) = {
@@ -99,17 +99,17 @@ object Test {
9999
assertEquals(foo"${d}random-leading-junk%d", List((true, 0, 1, 19, "conversions must follow a splice; use %% for literal %, %n for newline")))
100100
assertEquals(StringContext().foo(), List((true, 2, -1, 0, "there are no parts")))
101101
assertEquals(foo"%1$$n", Nil)
102-
assertEquals(foo"%1$$d", List((true, 0, 1, 1, "Argument index out of range")))
103-
assertEquals(foo"blablablabla %% %.2d", List((true, 0, 1, 17, "precision not allowed")))
104-
assertEquals(foo"blablablabla %.2b %%", List((true, 0, 1, 13, "conversions must follow a splice; use %% for literal %, %n for newline")))
102+
assertEquals(foo"%1$$d", List((true, 0, 0, 1, "Argument index out of range")))
103+
assertEquals(foo"blablablabla %% %.2d", List((true, 0, 0, 17, "precision not allowed")))
104+
assertEquals(foo"blablablabla %.2b %%", List((true, 0, 0, 13, "conversions must follow a splice; use %% for literal %, %n for newline")))
105105

106-
assertEquals(foo"ana${3}%.2foo%2${true}%bb", List((true, 0, 3, 1, "Missing conversion operator in '%2'; use %% for literal %, %n for newline")))
106+
assertEquals(foo"ana${3}%.2foo%2${true}%bb", List((true, 0, 1, 6, "Missing conversion operator in '%2'; use %% for literal %, %n for newline")))
107107
assertEquals(foo"ac{2c{2{c.ca ", Nil)
108-
assertEquals(foo"b%c.%2ii%iin", List((true, 0, 1, 1, "conversions must follow a splice; use %% for literal %, %n for newline"),
109-
(true, 0, 1, 5, "illegal conversion character 'i'"), (true, 0, 1, 8, "illegal conversion character 'i'")))
110-
assertEquals(foo"b}22%2.c<{%{" , List((true, 0, 1, 4, "Missing conversion operator in '%2'; use %% for literal %, %n for newline"),
111-
(true, 0, 1, 10, "Missing conversion operator in '%'; use %% for literal %, %n for newline")))
112-
assertEquals(foo"%%bci.2${'i'}%..2c2", List((true, 0, 2, 1, "Missing conversion operator in '%'; use %% for literal %, %n for newline")))
108+
assertEquals(foo"b%c.%2ii%iin", List((true, 0, 0, 1, "conversions must follow a splice; use %% for literal %, %n for newline"),
109+
(true, 0, 0, 6, "illegal conversion character 'i'"), (true, 0, 0, 9, "illegal conversion character 'i'")))
110+
assertEquals(foo"b}22%2.c<{%{" , List((true, 0, 0, 4, "Missing conversion operator in '%2'; use %% for literal %, %n for newline"),
111+
(true, 0, 0, 10, "Missing conversion operator in '%'; use %% for literal %, %n for newline")))
112+
assertEquals(foo"%%bci.2${'i'}%..2c2", List((true, 0, 1, 0, "Missing conversion operator in '%'; use %% for literal %, %n for newline")))
113113
}
114114

115115
def assertEquals(actual: Any, expected: Any): Unit = {

0 commit comments

Comments
 (0)