Skip to content

Commit 008a36c

Browse files
Kordyjanprolativ
authored andcommitted
Add since annotation
1 parent 78aa483 commit 008a36c

File tree

5 files changed

+29
-1
lines changed

5 files changed

+29
-1
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,6 +948,7 @@ class Definitions {
948948
@tu lazy val FunctionalInterfaceAnnot: ClassSymbol = requiredClass("java.lang.FunctionalInterface")
949949
@tu lazy val TargetNameAnnot: ClassSymbol = requiredClass("scala.annotation.targetName")
950950
@tu lazy val VarargsAnnot: ClassSymbol = requiredClass("scala.annotation.varargs")
951+
@tu lazy val SinceAnnot: ClassSymbol = requiredClass("scala.annotation.since")
951952

952953
@tu lazy val JavaRepeatableAnnot: ClassSymbol = requiredClass("java.lang.annotation.Repeatable")
953954

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,7 @@ object RefChecks {
911911
private def checkUndesiredProperties(sym: Symbol, pos: SrcPos)(using Context): Unit =
912912
checkDeprecated(sym, pos)
913913
checkExperimental(sym, pos)
914+
checkSinceAnnot(sym, pos)
914915

915916
val xMigrationValue = ctx.settings.Xmigration.value
916917
if xMigrationValue != NoScalaVersion then
@@ -970,6 +971,21 @@ object RefChecks {
970971
for annot <- sym.annotations if annot.symbol.isExperimental do
971972
Feature.checkExperimentalDef(annot.symbol, annot.tree)
972973

974+
private def checkSinceAnnot(sym: Symbol, pos: SrcPos)(using Context): Unit =
975+
for
976+
annot <- sym.getAnnotation(defn.SinceAnnot)
977+
version <- annot.argumentConstantString(0)
978+
do
979+
val releaseVersion = ctx.settings.scalaRelease.value
980+
ScalaVersion.parse(version) match
981+
case Success(symVersion) if symVersion > ctx.settings.scalaRelease.value =>
982+
report.error(
983+
i"$sym was added in Scala $version, therefore it cannot be used in the code targeting Scala ${releaseVersion.unparse}",
984+
pos)
985+
case Failure(ex) =>
986+
report.warning(i"$sym has an unparsable version number: ${ex.getMessage}", pos)
987+
case _ =>
988+
973989
/** If @migration is present (indicating that the symbol has changed semantics between versions),
974990
* emit a warning.
975991
*/
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package scala.annotation
2+
3+
/** An annotation that is used to mark symbols added to the stdlib after 3.0 release */
4+
class since(scalaRelease: String) extends scala.annotation.StaticAnnotation

library/src/scala/quoted/Quotes.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package scala.quoted
22

3-
import scala.annotation.experimental
3+
import scala.annotation.{ experimental, since }
44
import scala.reflect.TypeTest
55

66
/** Current Quotes in scope
@@ -3695,6 +3695,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
36953695
def memberField(name: String): Symbol
36963696

36973697
/** Get named non-private fields declared or inherited */
3698+
@since("3.1")
36983699
def fieldMember(name: String): Symbol
36993700

37003701
/** Get all non-private fields declared or inherited */

tests/neg/since/since_t3.0.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted.*
2+
3+
def useQuotes(using Quotes) =
4+
import quotes.reflect.*
5+
def useFieldMember(s: Symbol) = s.fieldMember("abc") // error
6+
useFieldMember

0 commit comments

Comments
 (0)