From 1639251488d5767d372f8b4dbdf168b9f38b1917 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Wed, 10 Jul 2019 00:29:12 -0400 Subject: [PATCH 1/5] Add Parsing Simple Annotations in JavaParser --- .../tools/dotc/parsing/JavaParsers.scala | 49 ++++++++++++++----- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 219a4246812e..e445c0203d68 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -137,9 +137,9 @@ object JavaParsers { // ------------- general parsing --------------------------- /** skip parent or brace enclosed sequence of things */ - def skipAhead(): Unit = { - var nparens = 0 - var nbraces = 0 + def skipAhead(initnparens: Int, initnbraces: Int): Unit = { + var nparens = initnparens + var nbraces = initnbraces while ({ in.token match { case LPAREN => @@ -161,6 +161,8 @@ object JavaParsers { () } + def skipAhead(): Unit = skipAhead(0,0) + def skipTo(tokens: Int*): Unit = while (!(tokens contains in.token) && in.token != EOF) if (in.token == LBRACE) { skipAhead(); accept(RBRACE) } @@ -329,20 +331,42 @@ object JavaParsers { } def annotations(): List[Tree] = { - //var annots = new ListBuffer[Tree] + var annots = new ListBuffer[Tree] while (in.token == AT) { in.nextToken() - annotation() + annotation() match { + case Some(anno) => annots += anno + case _ => + } } - List() // don't pass on annotations for now + annots.toList } /** Annotation ::= TypeName [`(` AnnotationArgument {`,` AnnotationArgument} `)`] */ - def annotation(): Unit = { - qualId() - if (in.token == LPAREN) { skipAhead(); accept(RPAREN) } - else if (in.token == LBRACE) { skipAhead(); accept(RBRACE) } + def annotation(): Option[Tree] = { + val id = convertToTypeId(qualId()) + var skipAnno = false + + // only parse annotations without arguments + if (in.token == LPAREN) { + in.nextToken() + if (in.token != RPAREN) { + skipAnno = true + skipAhead(1, 0) + } + accept(RPAREN) + } else if (in.token == LBRACE) { + in.nextToken() + if (in.token != RBRACE) { + skipAnno = true + skipAhead(0, 1) + } + accept(RBRACE) + } + + if (skipAnno) None + else Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) } def modifiers(inInterface: Boolean): Modifiers = { @@ -360,7 +384,10 @@ object JavaParsers { in.token match { case AT if (in.lookaheadToken != INTERFACE) => in.nextToken() - annotation() + annotation() match { + case Some(anno) => annots :+= anno + case _ => + } case PUBLIC => isPackageAccess = false in.nextToken() From 27717fe5a2136c8a634eb3319457e7c8a8eb5797 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Thu, 17 Oct 2019 16:46:43 -0400 Subject: [PATCH 2/5] add tests for annotations in Java --- tests/pos/annotations-in-java/AnnoJava.java | 23 ++++++++++++++++++++ tests/pos/annotations-in-java/CallJava.scala | 4 ++++ 2 files changed, 27 insertions(+) create mode 100644 tests/pos/annotations-in-java/AnnoJava.java create mode 100644 tests/pos/annotations-in-java/CallJava.scala diff --git a/tests/pos/annotations-in-java/AnnoJava.java b/tests/pos/annotations-in-java/AnnoJava.java new file mode 100644 index 000000000000..18743c907f36 --- /dev/null +++ b/tests/pos/annotations-in-java/AnnoJava.java @@ -0,0 +1,23 @@ +class AnnoJavaParent { + public String n(int i) { + return "n: " + i; + } +} + +public class AnnoJava extends AnnoJavaParent { + + @MyAnno() + public static String m(int i) { + return "m: " + i; + } + + @Override + public String n(int i) { + return "n: " + i; + } +} + +@interface MyAnno { + int value() default 1; +} + diff --git a/tests/pos/annotations-in-java/CallJava.scala b/tests/pos/annotations-in-java/CallJava.scala new file mode 100644 index 000000000000..afaa8dbb89e1 --- /dev/null +++ b/tests/pos/annotations-in-java/CallJava.scala @@ -0,0 +1,4 @@ +class CallJava { + def mm(i: Int): String = AnnoJava.m(i) +} + From 4efc3ee059994d5cc56014240a0126142efb83a3 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 21 Oct 2019 13:13:16 -0400 Subject: [PATCH 3/5] remove baces case; change list to listbuffer --- .../tools/dotc/parsing/JavaParsers.scala | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index e445c0203d68..8828472f17cb 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -137,9 +137,9 @@ object JavaParsers { // ------------- general parsing --------------------------- /** skip parent or brace enclosed sequence of things */ - def skipAhead(initnparens: Int, initnbraces: Int): Unit = { - var nparens = initnparens - var nbraces = initnbraces + def skipAhead(): Unit = { + var nparens = 0 + var nbraces = 0 while ({ in.token match { case LPAREN => @@ -161,8 +161,6 @@ object JavaParsers { () } - def skipAhead(): Unit = skipAhead(0,0) - def skipTo(tokens: Int*): Unit = while (!(tokens contains in.token) && in.token != EOF) if (in.token == LBRACE) { skipAhead(); accept(RBRACE) } @@ -346,26 +344,19 @@ object JavaParsers { */ def annotation(): Option[Tree] = { val id = convertToTypeId(qualId()) - var skipAnno = false + var skipAnnot = false // only parse annotations without arguments if (in.token == LPAREN) { - in.nextToken() - if (in.token != RPAREN) { - skipAnno = true - skipAhead(1, 0) + if (in.lookaheadToken != RPAREN) { + skipAnnot = true + skipAhead() } + else in.nextToken() accept(RPAREN) - } else if (in.token == LBRACE) { - in.nextToken() - if (in.token != RBRACE) { - skipAnno = true - skipAhead(0, 1) - } - accept(RBRACE) } - if (skipAnno) None + if (skipAnnot) None else Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) } @@ -373,9 +364,9 @@ object JavaParsers { var flags: FlagSet = Flags.JavaDefined // assumed true unless we see public/private/protected var isPackageAccess = true - var annots: List[Tree] = Nil + var annots = new ListBuffer[Tree] def addAnnot(sym: ClassSymbol) = - annots :+= atSpan(in.offset) { + annots += atSpan(in.offset) { in.nextToken() New(TypeTree(sym.typeRef)) } @@ -385,7 +376,7 @@ object JavaParsers { case AT if (in.lookaheadToken != INTERFACE) => in.nextToken() annotation() match { - case Some(anno) => annots :+= anno + case Some(anno) => annots += anno case _ => } case PUBLIC => @@ -423,7 +414,7 @@ object JavaParsers { if (isPackageAccess && !inInterface) thisPackageName else tpnme.EMPTY - return Modifiers(flags, privateWithin) withAnnotations annots + return Modifiers(flags, privateWithin) withAnnotations annots.toList } assert(false, "should not be here") throw new RuntimeException From c6a10f30379471d9d70ef37c1fe825c5a7ce20fd Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 21 Oct 2019 13:32:28 -0400 Subject: [PATCH 4/5] change bool variable; add tests --- .../src/dotty/tools/dotc/parsing/JavaParsers.scala | 7 +++---- tests/pos/annotations-in-java/AnnoJava.java | 10 ++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 8828472f17cb..3cb7bea6d8dc 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -344,20 +344,19 @@ object JavaParsers { */ def annotation(): Option[Tree] = { val id = convertToTypeId(qualId()) - var skipAnnot = false + var annot: Option[Tree] = Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) // only parse annotations without arguments if (in.token == LPAREN) { if (in.lookaheadToken != RPAREN) { - skipAnnot = true + annot = None skipAhead() } else in.nextToken() accept(RPAREN) } - if (skipAnnot) None - else Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) + annot } def modifiers(inInterface: Boolean): Modifiers = { diff --git a/tests/pos/annotations-in-java/AnnoJava.java b/tests/pos/annotations-in-java/AnnoJava.java index 18743c907f36..41728fa708fb 100644 --- a/tests/pos/annotations-in-java/AnnoJava.java +++ b/tests/pos/annotations-in-java/AnnoJava.java @@ -6,6 +6,16 @@ public String n(int i) { public class AnnoJava extends AnnoJavaParent { + @MyAnno + int f() { + return 0; + } + + @MyAnno(1) + int g() { + return 1; + } + @MyAnno() public static String m(int i) { return "m: " + i; From c40d90131eeb070b8cfd2274b885bf19f906851e Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Mon, 21 Oct 2019 14:05:14 -0400 Subject: [PATCH 5/5] remove var --- .../tools/dotc/parsing/JavaParsers.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala index 3cb7bea6d8dc..eae00c93d0b5 100644 --- a/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala @@ -344,19 +344,19 @@ object JavaParsers { */ def annotation(): Option[Tree] = { val id = convertToTypeId(qualId()) - var annot: Option[Tree] = Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) - // only parse annotations without arguments - if (in.token == LPAREN) { - if (in.lookaheadToken != RPAREN) { - annot = None - skipAhead() - } - else in.nextToken() + if (in.token == LPAREN && in.lookaheadToken != RPAREN) { + skipAhead() accept(RPAREN) + None + } + else { + if (in.token == LPAREN) { + in.nextToken() + accept(RPAREN) + } + Some(ensureApplied(Select(New(id), nme.CONSTRUCTOR))) } - - annot } def modifiers(inInterface: Boolean): Modifiers = {