Skip to content

Commit

Permalink
Add support for @deprecatedInheritance
Browse files Browse the repository at this point in the history
  • Loading branch information
hamzaremmal committed Nov 26, 2023
1 parent 55c2002 commit 698d90f
Show file tree
Hide file tree
Showing 13 changed files with 78 additions and 26 deletions.
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,7 @@ class Definitions {
@tu lazy val ProvisionalSuperClassAnnot: ClassSymbol = requiredClass("scala.annotation.internal.ProvisionalSuperClass")
@tu lazy val DeprecatedAnnot: ClassSymbol = requiredClass("scala.deprecated")
@tu lazy val DeprecatedOverridingAnnot: ClassSymbol = requiredClass("scala.deprecatedOverriding")
@tu lazy val DeprecatedInheritanceAnnot: ClassSymbol = requiredClass("scala.deprecatedInheritance")
@tu lazy val ImplicitAmbiguousAnnot: ClassSymbol = requiredClass("scala.annotation.implicitAmbiguous")
@tu lazy val ImplicitNotFoundAnnot: ClassSymbol = requiredClass("scala.annotation.implicitNotFound")
@tu lazy val InlineParamAnnot: ClassSymbol = requiredClass("scala.annotation.internal.InlineParam")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,10 @@ class InteractiveDriver(val settings: List[String]) extends Driver {

private val compiler: Compiler = new InteractiveCompiler

private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile] {
override def default(key: URI) = NoSource
}
private val myOpenedFiles = new mutable.LinkedHashMap[URI, SourceFile].withDefaultValue(NoSource)
def openedFiles: Map[URI, SourceFile] = myOpenedFiles

private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]] {
override def default(key: URI) = Nil
}
private val myOpenedTrees = new mutable.LinkedHashMap[URI, List[SourceTree]].withDefaultValue(Nil)
def openedTrees: Map[URI, List[SourceTree]] = myOpenedTrees

private val myCompilationUnits = new mutable.LinkedHashMap[URI, CompilationUnit]
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/reporting/Message.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ object Message:
def openLambda(tp: LambdaType): Unit =
openedLambdas += tp

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

var nonSensical = false

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import dotty.tools.dotc.reporting.CodeAction

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

private case class Patch(span: Span, replacement: String) {
def delta = replacement.length - (span.end - span.start)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ class SemanticSymbolBuilder:
private val locals = mutable.HashMap[Symbol, Int]()

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


def symbolName(sym: Symbol)(using Context): String =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ class CountOuterAccesses extends MiniPhase:
// LambdaLift can create outer paths. These need to be known in this phase.

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

private def markAccessed(tree: RefTree)(using Context): Tree =
val sym = tree.symbol
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,7 @@ object PatternMatcher {
}

private class RefCounter extends PlanTransform {
val count = new mutable.HashMap[Symbol, Int] {
override def default(key: Symbol) = 0
}
val count = new mutable.HashMap[Symbol, Int].withDefaultValue(0)
}

/** Reference counts for all labels */
Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1150,9 +1150,7 @@ trait Checking {

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

def checkDecl(decl: Symbol): Unit = {
Expand Down
12 changes: 12 additions & 0 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ object RefChecks {
}
end checkSelfAgainstParents

/** warn if `@deprecatedInheritance` is present */
def warnDeprecatedInheritance(cls: ClassSymbol, parentTrees: List[Tree])(using Context): Unit =
val psyms = cls.parentSyms
for (psym, pos) <- psyms.zip(parentTrees.map(_.srcPos))
annot <- psym.getAnnotation(defn.DeprecatedInheritanceAnnot)
do
val msg = annot.argumentConstantString(0).getOrElse("")
val since = annot.argumentConstantString(1).getOrElse("")
report.deprecationWarning(em"inheritance from $psym is deprecated (since: $since): $msg", pos)

/** Check that self type of this class conforms to self types of parents
* and required classes. Also check that only `enum` constructs extend
* `java.lang.Enum` and no user-written class extends ContextFunctionN.
Expand All @@ -123,6 +133,8 @@ object RefChecks {
val psyms = cls.asClass.parentSyms
checkSelfAgainstParents(cls.asClass, psyms)

warnDeprecatedInheritance(cls.asClass, parentTrees)

def isClassExtendingJavaEnum =
!cls.isOneOf(Enum | Trait) && psyms.contains(defn.JavaEnumClass)

Expand Down
4 changes: 1 addition & 3 deletions compiler/src/dotty/tools/dotc/util/Stats.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ import collection.mutable

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

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

inline def record(inline fn: String, inline n: Int = 1, inline skip: Boolean = timerOnly): Unit =
if (enabled && !skip) doRecord(fn, n)
Expand Down
4 changes: 1 addition & 3 deletions tests/init/pos/patternMatcher.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import scala.collection.mutable

class Translater:
val count = new mutable.HashMap[Int, Int] {
override def default(key: Int) = 0
}
val count = new mutable.HashMap[Int, Int].withDefaultValue(0)
count.get(10)
val n = 10
36 changes: 36 additions & 0 deletions tests/warn/i19002.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- Deprecation Warning: tests/warn/i19002.scala:5:20 -------------------------------------------------------------------
5 |class TBar1 extends TFoo // warn
| ^^^^
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:6:20 -------------------------------------------------------------------
6 |trait TBar2 extends TFoo // warn
| ^^^^
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:11:20 ------------------------------------------------------------------
11 |class CBar1 extends CFoo // warn
| ^^^^
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:12:20 ------------------------------------------------------------------
12 |trait CBar2 extends CFoo // warn
| ^^^^
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:17:20 ------------------------------------------------------------------
17 |class ABar1 extends AFoo // warn
| ^^^^
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:18:20 ------------------------------------------------------------------
18 |trait ABar2 extends AFoo // warn
| ^^^^
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:7:16 -------------------------------------------------------------------
7 |def TBar3 = new TFoo {} // warn
| ^^^^
| inheritance from trait TFoo is deprecated (since: FooLib 12.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:13:16 ------------------------------------------------------------------
13 |def CBar3 = new CFoo {} // warn
| ^^^^
| inheritance from class CFoo is deprecated (since: FooLib 11.0): this class will be made final
-- Deprecation Warning: tests/warn/i19002.scala:19:16 ------------------------------------------------------------------
19 |def ABar3 = new AFoo {} // warn
| ^^^^
| inheritance from class AFoo is deprecated (since: FooLib 10.0): this class will be made final
19 changes: 19 additions & 0 deletions tests/warn/i19002.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//> using options -deprecation

@deprecatedInheritance("this class will be made final", "FooLib 12.0")
trait TFoo
class TBar1 extends TFoo // warn
trait TBar2 extends TFoo // warn
def TBar3 = new TFoo {} // warn

@deprecatedInheritance("this class will be made final", "FooLib 11.0")
class CFoo
class CBar1 extends CFoo // warn
trait CBar2 extends CFoo // warn
def CBar3 = new CFoo {} // warn

@deprecatedInheritance("this class will be made final", "FooLib 10.0")
abstract class AFoo
class ABar1 extends AFoo // warn
trait ABar2 extends AFoo // warn
def ABar3 = new AFoo {} // warn

0 comments on commit 698d90f

Please sign in to comment.