Skip to content

Commit 5979c20

Browse files
committed
Fix #1741: sbt.ExtractAPI: extract annotations
This is necessary for correct incremental recompilation but is also used by sbt to find tests to run (for junit they should be annotated @org.junit.Test).
1 parent 3d0accd commit 5979c20

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package sbt
33

44
import ast.{Trees, tpd}
55
import core._, core.Decorators._
6-
import Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
6+
import Annotations._, Contexts._, Flags._, Phases._, Trees._, Types._, Symbols._
77
import Names._, NameOps._, StdNames._
88
import typer.Inliner
99

@@ -333,7 +333,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
333333
// TODO: Never dealias. We currently have to dealias because
334334
// sbt main class discovery relies on the signature of the main
335335
// method being fully dealiased. See https://github.com/sbt/zinc/issues/102
336-
val tp2 = if (!tp.isHK) tp.dealias else tp
336+
val tp2 = if (!tp.isHK) tp.dealiasKeepAnnots else tp
337337
tp2 match {
338338
case NoPrefix | NoType =>
339339
Constants.emptyType
@@ -411,9 +411,7 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
411411
case ConstantType(constant) =>
412412
new api.Constant(apiType(constant.tpe), constant.stringValue)
413413
case AnnotatedType(tpe, annot) =>
414-
// TODO: Annotation support
415-
ctx.debuglog(i"sbt-api: skipped annotation in $tp2")
416-
apiType(tpe)
414+
new api.Annotated(apiType(tpe), Array(apiAnnotation(annot)))
417415
case tp: ThisType =>
418416
apiThis(tp.cls)
419417
case tp: ParamType =>
@@ -498,7 +496,6 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
498496
sym.is(Implicit), sym.is(Lazy), sym.is(Macro), sym.is(SuperAccessor))
499497
}
500498

501-
// TODO: Support other annotations
502499
def apiAnnotations(s: Symbol): List[api.Annotation] = {
503500
val annots = new mutable.ListBuffer[api.Annotation]
504501

@@ -513,6 +510,27 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
513510
annots += marker(Inliner.bodyToInline(s).show(printTypesCtx).toString)
514511
}
515512

513+
// In the Scala2 ExtractAPI phase we only extract annotations that extend
514+
// StaticAnnotation, but in Dotty we currently pickle all annotations so we
515+
// extract everything (except inline body annotations which are handled
516+
// above).
517+
s.annotations.filter(_.symbol != defn.BodyAnnot) foreach { annot =>
518+
annots += apiAnnotation(annot)
519+
}
520+
516521
annots.toList
517522
}
523+
524+
def apiAnnotation(annot: Annotation): api.Annotation = {
525+
// FIXME: To faithfully extract an API we should extract the annotation tree,
526+
// sbt instead wants us to extract the annotation type and its arguments,
527+
// to do this properly we would need a way to hash trees and types in dotty itself,
528+
// instead we pretty-print the annotation tree.
529+
// However, we still need to extract the annotation type in the way sbt expect
530+
// because sbt uses this information to find tests to run (for example
531+
// junit tests are annotated @org.junit.Test).
532+
new api.Annotation(
533+
apiType(annot.tree.tpe), // Used by sbt to find tests to run
534+
Array(new api.AnnotationArgument("FULLTREE", annot.tree.show.toString)))
535+
}
518536
}

0 commit comments

Comments
 (0)