Skip to content

Commit 408e6d2

Browse files
authored
Fix parsing Java annotation values (#11809)
1 parent 4fb0a61 commit 408e6d2

File tree

6 files changed

+72
-30
lines changed

6 files changed

+72
-30
lines changed

compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala

Lines changed: 17 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -359,19 +359,6 @@ object JavaParsers {
359359
* but instead we skip entire annotation silently.
360360
*/
361361
def annotation(): Option[Tree] = {
362-
object LiteralT:
363-
def unapply(token: Token) = Option(token match {
364-
case TRUE => true
365-
case FALSE => false
366-
case CHARLIT => in.name(0)
367-
case INTLIT => in.intVal(false).toInt
368-
case LONGLIT => in.intVal(false)
369-
case FLOATLIT => in.floatVal(false).toFloat
370-
case DOUBLELIT => in.floatVal(false)
371-
case STRINGLIT => in.name.toString
372-
case _ => null
373-
}).map(Constant(_))
374-
375362
def classOrId(): Tree =
376363
val id = qualId()
377364
if in.lookaheadToken == CLASS then
@@ -398,17 +385,17 @@ object JavaParsers {
398385
}
399386

400387
def argValue(): Option[Tree] =
401-
val tree = in.token match {
402-
case LiteralT(c) =>
403-
val tree = atSpan(in.offset)(Literal(c))
404-
in.nextToken()
405-
Some(tree)
406-
case AT =>
407-
in.nextToken()
408-
annotation()
409-
case IDENTIFIER => Some(classOrId())
410-
case LBRACE => array()
411-
case _ => None
388+
val tree = tryConstant match {
389+
case Some(c) =>
390+
Some(atSpan(in.offset)(Literal(c)))
391+
case _ => in.token match {
392+
case AT =>
393+
in.nextToken()
394+
annotation()
395+
case IDENTIFIER => Some(classOrId())
396+
case LBRACE => array()
397+
case _ => None
398+
}
412399
}
413400
if in.token == COMMA || in.token == RBRACE || in.token == RPAREN then
414401
tree
@@ -716,11 +703,7 @@ object JavaParsers {
716703

717704
in.nextToken() // EQUALS
718705
if (mods.is(Flags.JavaStatic) && mods.is(Flags.Final)) {
719-
val neg = in.token match {
720-
case MINUS | BANG => in.nextToken(); true
721-
case _ => false
722-
}
723-
tryLiteral(neg).map(forConst).getOrElse(tpt1)
706+
tryConstant.map(forConst).getOrElse(tpt1)
724707
}
725708
else tpt1
726709
}
@@ -976,7 +959,11 @@ object JavaParsers {
976959
case _ => in.nextToken(); syntaxError("illegal start of type declaration", skipIt = true); List(errorTypeTree)
977960
}
978961

979-
def tryLiteral(negate: Boolean = false): Option[Constant] = {
962+
def tryConstant: Option[Constant] = {
963+
val negate = in.token match {
964+
case MINUS | BANG => in.nextToken(); true
965+
case _ => false
966+
}
980967
val l = in.token match {
981968
case TRUE => !negate
982969
case FALSE => negate
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
J:
2+
new java.lang.SuppressWarnings(value = "a")
3+
new java.lang.SuppressWarnings(value = "b")
4+
new java.lang.SuppressWarnings(value = _root_.scala.Array.apply[java.lang.String]("c", "d")(scala.reflect.ClassTag.apply[java.lang.String](classOf[java.lang.String])))
5+
JOtherTypes:
6+
new Annot(value = 1, _, _)
7+
new Annot(value = -2, _, _)
8+
new Annot(_, m = false, _)
9+
new Annot(_, m = true, _)
10+
new Annot(_, _, n = 1.1)
11+
new Annot(_, _, n = -2.1)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import scala.quoted.*
2+
3+
inline def showAnnots(inline c: String): Unit = ${ showAnnotsImpl('c) }
4+
5+
def showAnnotsImpl(c: Expr[String])(using Quotes): Expr[Unit] =
6+
import quotes.reflect.*
7+
val al = Expr(Symbol.requiredClass(c.valueOrError).declaredMethods.flatMap(_.annotations.map(_.show)))
8+
'{
9+
println($c + ":")
10+
$al.foreach(println)
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public @interface Annot {
2+
int value() default 0;
3+
boolean m() default false;
4+
double n() default 0;
5+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
public class J {
2+
@SuppressWarnings(value = "a")
3+
public void f1() {}
4+
@SuppressWarnings("b")
5+
public void f2() {}
6+
@SuppressWarnings({"c", "d"})
7+
public void f3() {}
8+
}
9+
10+
class JOtherTypes {
11+
@Annot(1)
12+
public void f1() {}
13+
@Annot(-2)
14+
public void f2() {}
15+
@Annot(m = false)
16+
public void f3() {}
17+
@Annot(m = true)
18+
public void f4() {}
19+
@Annot(n = 1.1)
20+
public void f5() {}
21+
@Annot(n = -2.1)
22+
public void f6() {}
23+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Display annotation arguments in Java
2+
3+
@main def Test =
4+
showAnnots("J")
5+
showAnnots("JOtherTypes")

0 commit comments

Comments
 (0)