From d63a6ba8540fb8ea7d01350ea68ff1ef0b53c5d4 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 1 Sep 2016 15:59:52 +0200 Subject: Make Context#moreProperties strongly typed To do this, factor out Key from Attachment into a new type, Property.Key. --- src/dotty/tools/dotc/ast/Desugar.scala | 4 ++-- src/dotty/tools/dotc/ast/Trees.scala | 6 +++--- src/dotty/tools/dotc/ast/untpd.scala | 10 +++++----- src/dotty/tools/dotc/core/Contexts.scala | 15 ++++++++++----- src/dotty/tools/dotc/transform/ExplicitOuter.scala | 4 ++-- src/dotty/tools/dotc/typer/Inliner.scala | 4 ++-- src/dotty/tools/dotc/typer/Namer.scala | 8 ++++---- src/dotty/tools/dotc/util/Attachment.scala | 4 +--- src/dotty/tools/dotc/util/Property.scala | 10 ++++++++++ 9 files changed, 39 insertions(+), 26 deletions(-) create mode 100644 src/dotty/tools/dotc/util/Property.scala (limited to 'src/dotty') diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala index edd6da5c9..4e27da2ca 100644 --- a/src/dotty/tools/dotc/ast/Desugar.scala +++ b/src/dotty/tools/dotc/ast/Desugar.scala @@ -8,7 +8,7 @@ import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._ import Decorators._ import language.higherKinds import collection.mutable.ListBuffer -import util.Attachment +import util.Property object desugar { import untpd._ @@ -16,7 +16,7 @@ object desugar { /** Tags a .withFilter call generated by desugaring a for expression. * Such calls can alternatively be rewritten to use filter. */ - val MaybeFilter = new Attachment.Key[Unit] + val MaybeFilter = new Property.Key[Unit] /** Info of a variable in a pattern: The named tree and its type */ private type VarInfo = (NameTree, Tree) diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index bb6fbd5ba..3b5de9308 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -12,7 +12,7 @@ import collection.immutable.IndexedSeq import collection.mutable.ListBuffer import parsing.Tokens.Token import printing.Printer -import util.{Stats, Attachment, DotClass} +import util.{Stats, Attachment, Property, DotClass} import annotation.unchecked.uncheckedVariance import language.implicitConversions import parsing.Scanners.Comment @@ -30,8 +30,8 @@ object Trees { /** The total number of created tree nodes, maintained if Stats.enabled */ @sharable var ntrees = 0 - /** Attachment key for trees with documentation strings attached */ - val DocComment = new Attachment.Key[Comment] + /** Property key for trees with documentation strings attached */ + val DocComment = new Property.Key[Comment] @sharable private var nextId = 0 // for debugging diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala index 61c3a79a4..32e27e9c7 100644 --- a/src/dotty/tools/dotc/ast/untpd.scala +++ b/src/dotty/tools/dotc/ast/untpd.scala @@ -6,7 +6,7 @@ import core._ import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._ import Denotations._, SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._ import Decorators._ -import util.Attachment +import util.Property import language.higherKinds import collection.mutable.ListBuffer @@ -161,17 +161,17 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo { def derivedType(originalSym: Symbol)(implicit ctx: Context): Type } - /** Attachment key containing TypeTrees whose type is computed + /** Property key containing TypeTrees whose type is computed * from the symbol in this type. These type trees have marker trees * TypeRefOfSym or InfoOfSym as their originals. */ - val References = new Attachment.Key[List[Tree]] + val References = new Property.Key[List[Tree]] - /** Attachment key for TypeTrees marked with TypeRefOfSym or InfoOfSym + /** Property key for TypeTrees marked with TypeRefOfSym or InfoOfSym * which contains the symbol of the original tree from which this * TypeTree is derived. */ - val OriginalSymbol = new Attachment.Key[Symbol] + val OriginalSymbol = new Property.Key[Symbol] // ------ Creation methods for untyped only ----------------- diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala index d8beb4b5c..6f9d19c40 100644 --- a/src/dotty/tools/dotc/core/Contexts.scala +++ b/src/dotty/tools/dotc/core/Contexts.scala @@ -30,6 +30,7 @@ import config.{Settings, ScalaSettings, Platform, JavaPlatform, SJSPlatform} import language.implicitConversions import DenotTransformers.DenotTransformer import parsing.Scanners.Comment +import util.Property.Key import xsbti.AnalysisCallback object Contexts { @@ -177,9 +178,12 @@ object Contexts { def freshName(prefix: Name): String = freshName(prefix.toString) /** A map in which more contextual properties can be stored */ - private var _moreProperties: Map[String, Any] = _ - protected def moreProperties_=(moreProperties: Map[String, Any]) = _moreProperties = moreProperties - def moreProperties: Map[String, Any] = _moreProperties + private var _moreProperties: Map[Key[Any], Any] = _ + protected def moreProperties_=(moreProperties: Map[Key[Any], Any]) = _moreProperties = moreProperties + def moreProperties: Map[Key[Any], Any] = _moreProperties + + def property[T](key: Key[T]): Option[T] = + moreProperties.get(key).asInstanceOf[Option[T]] private var _typeComparer: TypeComparer = _ protected def typeComparer_=(typeComparer: TypeComparer) = _typeComparer = typeComparer @@ -459,9 +463,10 @@ object Contexts { def setTypeComparerFn(tcfn: Context => TypeComparer): this.type = { this.typeComparer = tcfn(this); this } def setSearchHistory(searchHistory: SearchHistory): this.type = { this.searchHistory = searchHistory; this } def setFreshNames(freshNames: FreshNameCreator): this.type = { this.freshNames = freshNames; this } - def setMoreProperties(moreProperties: Map[String, Any]): this.type = { this.moreProperties = moreProperties; this } + def setMoreProperties(moreProperties: Map[Key[Any], Any]): this.type = { this.moreProperties = moreProperties; this } - def setProperty(prop: (String, Any)): this.type = setMoreProperties(moreProperties + prop) + def setProperty[T](key: Key[T], value: T): this.type = + setMoreProperties(moreProperties.updated(key, value)) def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid)) def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end)) diff --git a/src/dotty/tools/dotc/transform/ExplicitOuter.scala b/src/dotty/tools/dotc/transform/ExplicitOuter.scala index 6a52b128c..60ef1b306 100644 --- a/src/dotty/tools/dotc/transform/ExplicitOuter.scala +++ b/src/dotty/tools/dotc/transform/ExplicitOuter.scala @@ -15,7 +15,7 @@ import ast.Trees._ import SymUtils._ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Phases.Phase -import util.Attachment +import util.Property import collection.mutable /** This phase adds outer accessors to classes and traits that need them. @@ -36,7 +36,7 @@ class ExplicitOuter extends MiniPhaseTransform with InfoTransformer { thisTransf import ExplicitOuter._ import ast.tpd._ - val Outer = new Attachment.Key[Tree] + val Outer = new Property.Key[Tree] override def phaseName: String = "explicitOuter" diff --git a/src/dotty/tools/dotc/typer/Inliner.scala b/src/dotty/tools/dotc/typer/Inliner.scala index 852689a75..4eb8588a6 100644 --- a/src/dotty/tools/dotc/typer/Inliner.scala +++ b/src/dotty/tools/dotc/typer/Inliner.scala @@ -18,7 +18,7 @@ import Annotations.Annotation import transform.ExplicitOuter import config.Printers.inlining import ErrorReporting.errorTree -import util.Attachment +import util.Property import collection.mutable object Inliner { @@ -28,7 +28,7 @@ object Inliner { lazy val body = tree } - private val InlinedBody = new Attachment.Key[InlinedBody] + private val InlinedBody = new Property.Key[InlinedBody] // to be used as attachment def attachBody(inlineAnnot: Annotation, tree: => Tree)(implicit ctx: Context): Unit = inlineAnnot.tree.putAttachment(InlinedBody, new InlinedBody(tree)) diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 06e798bdb..4dff02018 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -9,7 +9,7 @@ import Contexts._, Symbols._, Types._, SymDenotations._, Names._, NameOps._, Fla import ast.desugar, ast.desugar._ import ProtoTypes._ import util.Positions._ -import util.{Attachment, SourcePosition, DotClass} +import util.{Property, SourcePosition, DotClass} import collection.mutable import annotation.tailrec import ErrorReporting._ @@ -160,9 +160,9 @@ class Namer { typer: Typer => import untpd._ - val TypedAhead = new Attachment.Key[tpd.Tree] - val ExpandedTree = new Attachment.Key[Tree] - val SymOfTree = new Attachment.Key[Symbol] + val TypedAhead = new Property.Key[tpd.Tree] + val ExpandedTree = new Property.Key[Tree] + val SymOfTree = new Property.Key[Symbol] /** A partial map from unexpanded member and pattern defs and to their expansions. * Populated during enterSyms, emptied during typer. diff --git a/src/dotty/tools/dotc/util/Attachment.scala b/src/dotty/tools/dotc/util/Attachment.scala index 8088b4cd0..20facfd97 100644 --- a/src/dotty/tools/dotc/util/Attachment.scala +++ b/src/dotty/tools/dotc/util/Attachment.scala @@ -4,9 +4,7 @@ package dotty.tools.dotc.util * adding, removing and lookup of attachments. Attachments are typed key/value pairs. */ object Attachment { - - /** The class of keys for attachments yielding values of type V */ - class Key[+V] + import Property.Key /** An implementation trait for attachments. * Clients should inherit from Container instead. diff --git a/src/dotty/tools/dotc/util/Property.scala b/src/dotty/tools/dotc/util/Property.scala new file mode 100644 index 000000000..608fc88e6 --- /dev/null +++ b/src/dotty/tools/dotc/util/Property.scala @@ -0,0 +1,10 @@ +package dotty.tools.dotc.util + +/** Defines a key type with which to tag properties, such as attachments + * or context properties + */ +object Property { + + /** The class of keys for properties of type V */ + class Key[+V] +} \ No newline at end of file -- cgit v1.2.3