Skip to content

Commit

Permalink
support java annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
bishabosha committed Feb 2, 2024
1 parent ef13061 commit 0ce1156
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ class TreeUnpickler[Tasty <: TastyUniverse](
if (nextByte === SPLITCLAUSE) {
assert(isJava, s"unexpected SPLITCLAUSE at $start")
}
setInfoWithParents(tparams, ctx.processParents(cls, parents))
setInfoWithParents(tparams, ctx.processParents(cls, parents, isJava))
}

traverseTemplate()
Expand Down
13 changes: 12 additions & 1 deletion src/compiler/scala/tools/nsc/tasty/bridge/ContextOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ trait ContextOps { self: TastyUniverse =>
unsupportedMessage(s"annotation on $sym: @$annot")
}
}
if (annot.symbol === defn.AnnotationDefaultClass) { // Scala 3 has a different annotation for default values
import scala.reflect.internal.ModifierFlags
assert(sym.owner.hasAllFlags(ModifierFlags.JAVA | ModifierFlags.JAVA_ANNOTATION))
sym.addAnnotation(u.definitions.AnnotationDefaultAttr) // Scala 2 expects this to be present
}
}
if (problematic.nonEmpty) {
sym.removeAnnotation(u.definitions.CompileTimeOnlyAttr)
Expand Down Expand Up @@ -510,7 +515,7 @@ trait ContextOps { self: TastyUniverse =>
}

/** sets up value class machinery */
final def processParents(cls: Symbol, parentTypes: List[Type]): parentTypes.type = {
final def processParents(cls: Symbol, parentTypes: List[Type], isJava: Boolean): parentTypes.type = {
if (parentTypes.head.typeSymbolDirect === u.definitions.AnyValClass) {
// TODO [tasty]: please reconsider if there is some shared optimised logic that can be triggered instead.
withPhaseNoLater("extmethods") { ctx0 =>
Expand All @@ -525,6 +530,12 @@ trait ContextOps { self: TastyUniverse =>
}
}
}
else if (isJava && parentTypes.exists(_.typeSymbolDirect === defn.JavaAnnotationClass)) {
import scala.reflect.internal.ModifierFlags
//sys.error(s"Java annotations are not supported in TASTy $cls: $parentTypes, ${parentTypes.map(_.typeSymbolDirect)}, ${parentTypes.map(_.typeSymbol)}")
cls.setFlag(ModifierFlags.JAVA_ANNOTATION)
cls.info.decls.enter(cls.newClassConstructor(u.NoPosition))
}
parentTypes
}

Expand Down
2 changes: 2 additions & 0 deletions src/compiler/scala/tools/nsc/tasty/bridge/TypeOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ trait TypeOps { self: TastyUniverse =>
final val TargetNameAnnotationClass: Symbol = u.definitions.TargetNameAnnotationClass
final val StaticMethodAnnotationClass: Symbol = u.definitions.StaticMethodAnnotationClass
final val ExperimentalAnnotationClass: Symbol = u.definitions.ExperimentalAnnotationClass
final val AnnotationDefaultClass: Symbol = u.definitions.AnnotationDefaultClass
final val JavaAnnotationClass: Symbol = u.definitions.JavaAnnotationClass

object PolyFunctionType {

Expand Down
2 changes: 2 additions & 0 deletions src/reflect/scala/reflect/internal/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val StaticMethodAnnotationClass = getClassIfDefined("scala.annotation.static")
lazy val PolyFunctionClass = getClassIfDefined("scala.PolyFunction")
lazy val ExperimentalAnnotationClass = getClassIfDefined("scala.annotation.experimental")
lazy val AnnotationDefaultClass = getClassIfDefined("scala.annotation.internal.AnnotationDefault")
lazy val JavaAnnotationClass = requiredClass[java.lang.annotation.Annotation]

lazy val BeanPropertyAttr = requiredClass[scala.beans.BeanProperty]
lazy val BooleanBeanPropertyAttr = requiredClass[scala.beans.BooleanBeanProperty]
Expand Down
16 changes: 16 additions & 0 deletions test/tasty/run-pipelined/src-2/tastytest/TestSomeAnnotation.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tastytest

import lib.SomeAnnotation

object TestSomeAnnotation extends scala.App {

@SomeAnnotation(value = "hello")
def method = 23

@SomeAnnotation(value = "hello", year = 1996)
def method2 = 23

@SomeAnnotation(value = "hello", year = 1996, classes = Array(classOf[Long]))
def method3 = 23

}
19 changes: 19 additions & 0 deletions test/tasty/run-pipelined/src-3/lib/SomeAnnotation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package lib;

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;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE, ElementType.FIELD, ElementType.LOCAL_VARIABLE })
@Inherited
public @interface SomeAnnotation {
String value();
int year() default 2024;
Class<?>[] classes() default {int.class, String.class};
}

0 comments on commit 0ce1156

Please sign in to comment.