Skip to content

Commit ad66ab5

Browse files
committed
Add support for @deprecatedInheritance
1 parent 55c2002 commit ad66ab5

File tree

13 files changed

+78
-26
lines changed

13 files changed

+78
-26
lines changed

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

+1
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,7 @@ class Definitions {
10061006
@tu lazy val ProvisionalSuperClassAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ProvisionalSuperClass")
10071007
@tu lazy val DeprecatedAnnot: ClassSymbol = requiredClass("scala.deprecated")
10081008
@tu lazy val DeprecatedOverridingAnnot: ClassSymbol = requiredClass("scala.deprecatedOverriding")
1009+
@tu lazy val deprecatedInheritanceAnnot: ClassSymbol = requiredClass("scala.deprecatedInheritance")
10091010
@tu lazy val ImplicitAmbiguousAnnot: ClassSymbol = requiredClass("scala.annotation.implicitAmbiguous")
10101011
@tu lazy val ImplicitNotFoundAnnot: ClassSymbol = requiredClass("scala.annotation.implicitNotFound")
10111012
@tu lazy val InlineParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InlineParam")

compiler/src/dotty/tools/dotc/interactive/InteractiveDriver.scala

+2-6
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,10 @@ class InteractiveDriver(val settings: List[String]) extends Driver {
4747

4848
private val compiler: Compiler = new InteractiveCompiler
4949

50-
private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile] {
51-
override def default(key: URI) = NoSource
52-
}
50+
private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile].withDefaultValue(NoSource)
5351
def openedFiles: Map[URI, SourceFile] = myOpenedFiles
5452

55-
private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]] {
56-
override def default(key: URI) = Nil
57-
}
53+
private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]].withDefaultValue(Nil)
5854
def openedTrees: Map[URI, List[SourceTree]] = myOpenedTrees
5955

6056
private val myCompilationUnits = new mutable.LinkedHashMap[URI, CompilationUnit]

compiler/src/dotty/tools/dotc/reporting/Message.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ object Message:
5757
def openLambda(tp: LambdaType): Unit =
5858
openedLambdas += tp
5959

60-
val seen = new collection.mutable.HashMap[SeenKey, List[Recorded]]:
61-
override def default(key: SeenKey) = Nil
60+
val seen = new collection.mutable.HashMap[SeenKey, List[Recorded]].withDefaultValue(Nil)
6261

6362
var nonSensical = false
6463

compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import dotty.tools.dotc.reporting.CodeAction
1515

1616
/** Handles rewriting of Scala2 files to Dotty */
1717
object Rewrites {
18-
private class PatchedFiles extends mutable.HashMap[SourceFile, Patches]
18+
private type PatchedFiles = mutable.HashMap[SourceFile, Patches]
1919

2020
private case class Patch(span: Span, replacement: String) {
2121
def delta = replacement.length - (span.end - span.start)

compiler/src/dotty/tools/dotc/semanticdb/SemanticSymbolBuilder.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ class SemanticSymbolBuilder:
2020
private val locals = mutable.HashMap[Symbol, Int]()
2121

2222
/** The local symbol(s) starting at given offset */
23-
private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]():
24-
override def default(key: Int) = Set[Symbol]()
23+
private val symsAtOffset = new mutable.HashMap[Int, Set[Symbol]]().withDefault(_ => Set[Symbol]())
2524

2625

2726
def symbolName(sym: Symbol)(using Context): String =

compiler/src/dotty/tools/dotc/transform/CountOuterAccesses.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ class CountOuterAccesses extends MiniPhase:
4343
// LambdaLift can create outer paths. These need to be known in this phase.
4444

4545
/** The number of times an outer accessor that might be dropped is accessed */
46-
val outerAccessCount = new mutable.HashMap[Symbol, Int] {
47-
override def default(s: Symbol): Int = 0
48-
}
46+
val outerAccessCount = new mutable.HashMap[Symbol, Int].withDefaultValue(0)
4947

5048
private def markAccessed(tree: RefTree)(using Context): Tree =
5149
val sym = tree.symbol

compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,7 @@ object PatternMatcher {
504504
}
505505

506506
private class RefCounter extends PlanTransform {
507-
val count = new mutable.HashMap[Symbol, Int] {
508-
override def default(key: Symbol) = 0
509-
}
507+
val count = new mutable.HashMap[Symbol, Int].withDefaultValue(0)
510508
}
511509

512510
/** Reference counts for all labels */

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -1150,9 +1150,7 @@ trait Checking {
11501150

11511151
/** Check that class does not declare same symbol twice */
11521152
def checkNoDoubleDeclaration(cls: Symbol)(using Context): Unit = {
1153-
val seen = new mutable.HashMap[Name, List[Symbol]] {
1154-
override def default(key: Name) = Nil
1155-
}
1153+
val seen = new mutable.HashMap[Name, List[Symbol]].withDefaultValue(Nil)
11561154
typr.println(i"check no double declarations $cls")
11571155

11581156
def checkDecl(decl: Symbol): Unit = {

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

+12
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ object RefChecks {
114114
}
115115
end checkSelfAgainstParents
116116

117+
/** warn if `@deprecatedInheritance` is present */
118+
def warnDeprecatedInheritance(cls: ClassSymbol, parentTrees: List[Tree])(using Context): Unit =
119+
val psyms = cls.parentSyms
120+
for (psym, pos) <- psyms.zip(parentTrees.map(_.srcPos))
121+
annot <- psym.getAnnotation(defn.deprecatedInheritanceAnnot)
122+
do
123+
val msg = annot.argumentConstantString(0).getOrElse("")
124+
val since = annot.argumentConstantString(1).getOrElse("")
125+
report.deprecationWarning(em"inheritance from $psym is deprecated (since: $since): $msg", pos)
126+
117127
/** Check that self type of this class conforms to self types of parents
118128
* and required classes. Also check that only `enum` constructs extend
119129
* `java.lang.Enum` and no user-written class extends ContextFunctionN.
@@ -123,6 +133,8 @@ object RefChecks {
123133
val psyms = cls.asClass.parentSyms
124134
checkSelfAgainstParents(cls.asClass, psyms)
125135

136+
warnDeprecatedInheritance(cls.asClass, parentTrees)
137+
126138
def isClassExtendingJavaEnum =
127139
!cls.isOneOf(Enum | Trait) && psyms.contains(defn.JavaEnumClass)
128140

compiler/src/dotty/tools/dotc/util/Stats.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@ import collection.mutable
1919

2020
@volatile private var stack: List[String] = Nil
2121

22-
val hits: mutable.HashMap[String, Int] = new mutable.HashMap[String, Int] {
23-
override def default(key: String): Int = 0
24-
}
22+
val hits: mutable.Map[String, Int] = new mutable.HashMap[String, Int].withDefaultValue(0)
2523

2624
inline def record(inline fn: String, inline n: Int = 1, inline skip: Boolean = timerOnly): Unit =
2725
if (enabled && !skip) doRecord(fn, n)

tests/init/pos/patternMatcher.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import scala.collection.mutable
22

33
class Translater:
4-
val count = new mutable.HashMap[Int, Int] {
5-
override def default(key: Int) = 0
6-
}
4+
val count = new mutable.HashMap[Int, Int].withDefaultValue(0)
75
count.get(10)
86
val n = 10

tests/warn/i19002.check

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
-- Deprecation Warning: tests/warn/i19002.scala:5:20 -------------------------------------------------------------------
2+
5 |class TBar1 extends TFoo // warn
3+
| ^^^^
4+
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
5+
-- Deprecation Warning: tests/warn/i19002.scala:6:20 -------------------------------------------------------------------
6+
6 |trait TBar2 extends TFoo // warn
7+
| ^^^^
8+
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
9+
-- Deprecation Warning: tests/warn/i19002.scala:11:20 ------------------------------------------------------------------
10+
11 |class CBar1 extends CFoo // warn
11+
| ^^^^
12+
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
13+
-- Deprecation Warning: tests/warn/i19002.scala:12:20 ------------------------------------------------------------------
14+
12 |trait CBar2 extends CFoo // warn
15+
| ^^^^
16+
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
17+
-- Deprecation Warning: tests/warn/i19002.scala:17:20 ------------------------------------------------------------------
18+
17 |class ABar1 extends AFoo // warn
19+
| ^^^^
20+
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final
21+
-- Deprecation Warning: tests/warn/i19002.scala:18:20 ------------------------------------------------------------------
22+
18 |trait ABar2 extends AFoo // warn
23+
| ^^^^
24+
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final
25+
-- Deprecation Warning: tests/warn/i19002.scala:7:16 -------------------------------------------------------------------
26+
7 |def TBar3 = new TFoo {} // warn
27+
| ^^^^
28+
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
29+
-- Deprecation Warning: tests/warn/i19002.scala:13:16 ------------------------------------------------------------------
30+
13 |def CBar3 = new CFoo {} // warn
31+
| ^^^^
32+
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
33+
-- Deprecation Warning: tests/warn/i19002.scala:19:16 ------------------------------------------------------------------
34+
19 |def ABar3 = new AFoo {} // warn
35+
| ^^^^
36+
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final

tests/warn/i19002.scala

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//> using options -deprecation
2+
3+
@deprecatedInheritance("this class will be made final", "FooLib 12.0")
4+
trait TFoo
5+
class TBar1 extends TFoo // warn
6+
trait TBar2 extends TFoo // warn
7+
def TBar3 = new TFoo {} // warn
8+
9+
@deprecatedInheritance("this class will be made final", "FooLib 11.0")
10+
class CFoo
11+
class CBar1 extends CFoo // warn
12+
trait CBar2 extends CFoo // warn
13+
def CBar3 = new CFoo {} // warn
14+
15+
@deprecatedInheritance("this class will be made final", "FooLib 10.0")
16+
abstract class AFoo
17+
class ABar1 extends AFoo // warn
18+
trait ABar2 extends AFoo // warn
19+
def ABar3 = new AFoo {} // warn

0 commit comments

Comments
 (0)