Skip to content

Commit

Permalink
Java parses leading annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
som-snytt committed Apr 2, 2024
1 parent cc55381 commit 9fca170
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 10 deletions.
26 changes: 16 additions & 10 deletions compiler/src/dotty/tools/dotc/parsing/JavaParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,11 @@ object JavaParsers {
}
}

def modifiers(inInterface: Boolean): Modifiers = {
def modifiers(inInterface: Boolean, annots0: List[Tree] = Nil): Modifiers = {
var flags: FlagSet = Flags.JavaDefined
// assumed true unless we see public/private/protected
var isPackageAccess = true
var annots = new ListBuffer[Tree]
var annots = ListBuffer.from[Tree](annots0)
def addAnnot(tpt: Tree) =
annots += atSpan(in.offset) {
in.nextToken()
Expand All @@ -453,7 +453,7 @@ object JavaParsers {

while (true)
in.token match {
case AT if (in.lookaheadToken != INTERFACE) =>
case AT if in.lookaheadToken != INTERFACE =>
in.nextToken()
annotation() match {
case Some(anno) => annots += anno
Expand Down Expand Up @@ -1080,24 +1080,30 @@ object JavaParsers {
/** CompilationUnit ::= [package QualId semi] TopStatSeq
*/
def compilationUnit(): Tree = {
val start = in.offset
val buf = ListBuffer.empty[Tree]
var start = in.offset
val leadingAnnots = if (in.token == AT) annotations() else Nil
val pkg: RefTree =
if (in.token == AT || in.token == PACKAGE) {
annotations()
if in.token == PACKAGE then
if !leadingAnnots.isEmpty then
//if (unit.source.file.name != "package-info.java")
// syntaxError(pos, "package annotations must be in file package-info.java")
start = in.offset
accept(PACKAGE)
val pkg = qualId()
accept(SEMI)
pkg
}
else
if !leadingAnnots.isEmpty then
buf ++= typeDecl(start, modifiers(inInterface = false, annots0 = leadingAnnots))
Ident(nme.EMPTY_PACKAGE)
thisPackageName = convertToTypeName(pkg) match {
case Some(t) => t.name.toTypeName
case _ => tpnme.EMPTY
}
val buf = new ListBuffer[Tree]
while (in.token == IMPORT)
buf ++= importDecl()
if (buf.isEmpty)
while in.token == IMPORT do
buf ++= importDecl()
while (in.token != EOF && in.token != RBRACE) {
while (in.token == SEMI) in.nextToken()
if (in.token != EOF) {
Expand Down
Empty file added tests/pos/i20026/Empty.java
Empty file.
4 changes: 4 additions & 0 deletions tests/pos/i20026/JFun.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@FunctionalInterface
public interface JFun {
String f(String s);
}
4 changes: 4 additions & 0 deletions tests/pos/i20026/JTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

@api.TestInstance(api.TestInstance.Lifecycle.PER_CLASS)
public class JTest {
}
6 changes: 6 additions & 0 deletions tests/pos/i20026/KTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

import api.*;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class KTest {
}
20 changes: 20 additions & 0 deletions tests/pos/i20026/TestInstance.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

package api;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface TestInstance {
enum Lifecycle {
PER_CLASS;
}
Lifecycle value();
}
6 changes: 6 additions & 0 deletions tests/pos/i20026/test.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

object Test extends App {
println {
new JTest
}
}

0 comments on commit 9fca170

Please sign in to comment.