@@ -3,6 +3,7 @@ package dotc
3
3
package transform
4
4
5
5
import core .*
6
+ import Annotations .Annotation
6
7
import Symbols .* , Types .* , Contexts .* , Flags .* , SymUtils .* , Decorators .* , reporting .*
7
8
import util .SrcPos
8
9
import config .{ScalaVersion , NoScalaVersion , Feature , ScalaRelease }
@@ -33,42 +34,63 @@ class CrossVersionChecks extends MiniPhase:
33
34
end checkUndesiredProperties
34
35
35
36
/** If @deprecated is present, and the point of reference is not enclosed
36
- * in either a deprecated member or a scala bridge method, issue a warning.
37
+ * in either a deprecated member or a scala bridge method, issue a warning.
37
38
*/
38
39
private def checkDeprecated (sym : Symbol , pos : SrcPos )(using Context ): Unit =
39
40
40
41
/** is the owner an enum or its companion and also the owner of sym */
41
- def isEnumOwner (owner : Symbol )( using Context ) =
42
+ def isEnumOwner (owner : Symbol ) =
42
43
// pre: sym is an enumcase
43
44
if owner.isEnumClass then owner.companionClass eq sym.owner
44
45
else if owner.is(ModuleClass ) && owner.companionClass.isEnumClass then owner eq sym.owner
45
46
else false
46
47
47
- def isDeprecatedOrEnum (owner : Symbol )( using Context ) =
48
+ def isDeprecatedOrEnum (owner : Symbol ) =
48
49
// pre: sym is an enumcase
49
50
owner.isDeprecated
50
51
|| isEnumOwner(owner)
51
52
52
- /** Skip warnings for synthetic members of case classes during declaration and
53
- * scan the chain of outer declaring scopes from the current context
54
- * a deprecation warning will be skipped if one the following holds
55
- * for a given declaring scope:
56
- * - the symbol associated with the scope is also deprecated.
57
- * - if and only if `sym` is an enum case, the scope is either
58
- * a module that declares `sym`, or the companion class of the
59
- * module that declares `sym`.
53
+ /** Skip warnings for synthetic members of case classes during declaration and
54
+ * scan the chain of outer declaring scopes from the current context
55
+ * a deprecation warning will be skipped if one the following holds
56
+ * for a given declaring scope:
57
+ * - the symbol associated with the scope is also deprecated.
58
+ * - if and only if `sym` is an enum case, the scope is either
59
+ * a module that declares `sym`, or the companion class of the
60
+ * module that declares `sym`.
60
61
*/
61
- def skipWarning (using Context ): Boolean =
62
- (ctx.owner.is(Synthetic ) && sym.is(CaseClass ))
63
- || ctx.owner.ownersIterator.exists(if sym.isEnumCase then isDeprecatedOrEnum else _.isDeprecated)
64
-
65
- // Also check for deprecation of the companion class for synthetic methods
66
- val toCheck = sym :: (if sym.isAllOf(SyntheticMethod ) then sym.owner.companionClass :: Nil else Nil )
67
- for sym <- toCheck; annot <- sym.getAnnotation(defn.DeprecatedAnnot ) do
62
+ def siteIsSyntheticCaseClassMember =
63
+ val owner = ctx.owner
64
+ def symIsCaseOrMember =
65
+ val klass = owner.enclosingClass
66
+ val kompanion = klass.companionClass
67
+ // deprecated sym is either enclosing case class or a sibling member
68
+ def checkSym (k : Symbol ) = sym == k || sym.owner == k
69
+ (klass.is(CaseClass ) || kompanion.is(CaseClass ))
70
+ &&
71
+ (checkSym(klass) || checkSym(kompanion))
72
+ owner.is(Synthetic ) && symIsCaseOrMember
73
+ def siteIsEnclosedByDeprecatedElement =
74
+ ctx.owner.ownersIterator.exists:
75
+ if sym.isEnumCase then isDeprecatedOrEnum else _.isDeprecated
76
+ def skipWarning : Boolean =
77
+ siteIsSyntheticCaseClassMember || siteIsEnclosedByDeprecatedElement
78
+
79
+ def maybeWarn (annotee : Symbol , annot : Annotation ) =
68
80
if ! skipWarning then
69
81
val msg = annot.argumentConstant(0 ).map(" : " + _.stringValue).getOrElse(" " )
70
82
val since = annot.argumentConstant(1 ).map(" since " + _.stringValue).getOrElse(" " )
71
- report.deprecationWarning(em " ${sym.showLocated} is deprecated ${since}${msg}" , pos)
83
+ report.deprecationWarning(em " ${annotee.showLocated} is deprecated ${since}${msg}" , pos)
84
+
85
+ // Also check for deprecation of the companion class for synthetic methods in the companion module
86
+ sym.getAnnotation(defn.DeprecatedAnnot ) match
87
+ case Some (annot) => maybeWarn(sym, annot)
88
+ case _ =>
89
+ if sym.isAllOf(SyntheticMethod ) then
90
+ val companion = sym.owner.companionClass
91
+ if companion.is(CaseClass ) then companion.getAnnotation(defn.DeprecatedAnnot ).foreach(maybeWarn(companion, _))
92
+
93
+ end checkDeprecated
72
94
73
95
private def checkExperimentalAnnots (sym : Symbol )(using Context ): Unit =
74
96
if sym.exists && ! sym.isInExperimentalScope then
0 commit comments