Skip to content

Commit

Permalink
Follow-up for non-warning nilary/nullary override with BeanProperty
Browse files Browse the repository at this point in the history
Follow-up for PR 10450 which stopped the nilary / nullary override
warning for synthesized BeanProperty getters.

The fix only worked by accident. The BeanProperty annotation class
is only meta-annotated to target the field, not the generated
bean getter.

However, `beanGetterSymbol.hasAnnotation(BeanPropertyAttr)` was still
true because the annotation is an `ExtraLazyAnnotationInfo`, which
overrides `symbol` to always return the initial symbol even after the
underlying `LazyAnnotationInfo` is mapped to `UnmappableAnnotation`
by annotation filtering (`Namer.annotSig.computeInfo`).

This PR changes `ExtraLazyAnnotationInfo.symbol` to call `super.symbol`
if the underlying `LazyAnnotationInfo` is forced.

To fix the check in RefChecks, `BeanProperty` and `BooleanBeanProperty`
are now meta-annotated with `@beanGetter` and `@beanSetter`.
  • Loading branch information
lrytz committed Aug 25, 2023
1 parent 49d5507 commit 9fb86b9
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 10 deletions.
4 changes: 3 additions & 1 deletion src/library/scala/beans/BeanProperty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

package scala.beans

import scala.annotation.meta.{beanGetter, beanSetter, field}

/** When attached to a field, this annotation adds a setter and a getter
* method following the Java Bean convention. For example:
* {{{
Expand All @@ -26,6 +28,6 @@ package scala.beans
* For fields of type `Boolean`, if you need a getter named `isStatus`,
* use the `scala.beans.BooleanBeanProperty` annotation instead.
*/
@scala.annotation.meta.field
@field @beanGetter @beanSetter
@deprecatedInheritance("Scheduled for being final in the future", "2.13.0")
class BeanProperty extends scala.annotation.StaticAnnotation
4 changes: 3 additions & 1 deletion src/library/scala/beans/BooleanBeanProperty.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

package scala.beans

import scala.annotation.meta.{beanGetter, beanSetter, field}

/** This annotation has the same functionality as
* `scala.beans.BeanProperty`, but the generated Bean getter will be
* named `isFieldName` instead of `getFieldName`.
*/
@scala.annotation.meta.field
@field @beanGetter @beanSetter
@deprecatedInheritance("Scheduled for being final in the future", "2.13.0")
class BooleanBeanProperty extends scala.annotation.StaticAnnotation
12 changes: 7 additions & 5 deletions src/reflect/scala/reflect/internal/AnnotationInfos.scala
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
* definitions) have to be lazy (#1782)
*/
class LazyAnnotationInfo(lazyInfo: => AnnotationInfo) extends AnnotationInfo {
private[this] var forced = false
private lazy val forcedInfo = try lazyInfo finally forced = true
private[this] var _forced = false
protected def forced = _forced
private lazy val forcedInfo = try lazyInfo finally _forced = true

def atp: Type = forcedInfo.atp
def args: List[Tree] = forcedInfo.args
Expand All @@ -167,16 +168,17 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
def setOriginal(t: Tree): this.type = { forcedInfo.setOriginal(t); this }

// We should always be able to print things without forcing them.
override def toString = if (forced) forcedInfo.toString else "@<?>"
override def toString = if (_forced) forcedInfo.toString else "@<?>"

override def pos: Position = if (forced) forcedInfo.pos else NoPosition
override def pos: Position = if (_forced) forcedInfo.pos else NoPosition

override def completeInfo(): Unit = forcedInfo
}

final class ExtraLazyAnnotationInfo(sym: => Symbol, lazyInfo: => AnnotationInfo) extends LazyAnnotationInfo(lazyInfo) {
private[this] lazy val typeSymbol = sym
override def symbol: Symbol = typeSymbol
// If `forced` to UnmappableAnnotation, ensure to return NoSymbol, otherwise `ann.matches(annCls)` can be incorrect
override def symbol: Symbol = if (forced) super.symbol else typeSymbol
}

/** Typed information about an annotation. It can be attached to either
Expand Down
6 changes: 3 additions & 3 deletions test/files/run/reify_ann5.check
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
class C extends AnyRef {
@new inline @beanGetter() @new BeanProperty() <paramaccessor> val x: Int = _;
@new BeanProperty() @new inline @beanGetter() @new BeanProperty() <paramaccessor> val x: Int = _;
def <init>(x: Int) = {
super.<init>();
()
Expand All @@ -10,13 +10,13 @@
}
{
class C extends AnyRef {
@scala.beans.BeanProperty <paramaccessor> private[this] val x: Int = _;
@scala.beans.BeanProperty @scala.beans.BeanProperty <paramaccessor> private[this] val x: Int = _;
<stable> <accessor> <paramaccessor> def x: Int = C.this.x;
def <init>(x: Int): C = {
C.super.<init>();
()
};
@inline @scala.annotation.meta.beanGetter @<notype> def getX(): Int = C.this.x
@scala.beans.BeanProperty @inline @scala.annotation.meta.beanGetter @scala.beans.BeanProperty def getX(): Int = C.this.x
};
()
}

0 comments on commit 9fb86b9

Please sign in to comment.