diff options
author | Martin Odersky <odersky@gmail.com> | 2014-02-11 14:42:45 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-02-11 14:42:56 +0100 |
commit | 459d78dccc40c94dd7da8b5b29762a494595778b (patch) | |
tree | 2d678de090302dab70d7079730f8ed4cc258b667 /src/dotty | |
parent | e895249de8f59e5a5c4175b428193fa4c5ea90af (diff) | |
download | dotty-459d78dccc40c94dd7da8b5b29762a494595778b.tar.gz dotty-459d78dccc40c94dd7da8b5b29762a494595778b.tar.bz2 dotty-459d78dccc40c94dd7da8b5b29762a494595778b.zip |
New scheme for attachments.
Added general way to put attachments on some base type (which needs to inherit from Attachment.Container).
Used it to turn typedTree map into an attachment.
Also, moved DotClass to dotc.util.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/dotc/Driver.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/CompilerCommand.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Names.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Periods.scala | 1 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Phases.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Symbols.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Transformers.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TyperState.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/parsing/Parsers.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 25 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/Attachment.scala | 65 | ||||
-rw-r--r-- | src/dotty/tools/dotc/util/DotClass.scala (renamed from src/dotty/tools/dotc/core/DotClass.scala) | 2 |
17 files changed, 114 insertions, 27 deletions
diff --git a/src/dotty/tools/dotc/Driver.scala b/src/dotty/tools/dotc/Driver.scala index fd2b776f8..892e4cf7d 100644 --- a/src/dotty/tools/dotc/Driver.scala +++ b/src/dotty/tools/dotc/Driver.scala @@ -2,7 +2,7 @@ package dotty.tools.dotc import config.CompilerCommand import core.Contexts.{Context, ContextBase} -import core.DotClass +import util.DotClass import reporting._ abstract class Driver extends DotClass { diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index 13f7d6f18..96a91654d 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -11,7 +11,7 @@ import collection.immutable.IndexedSeq import collection.mutable.ListBuffer import parsing.Tokens.Token import printing.Printer -import util.Stats +import util.{Stats, Attachment, DotClass} import annotation.unchecked.uncheckedVariance object Trees { @@ -29,7 +29,7 @@ object Trees { /** A base class for things that have positions (currently: modifiers and trees) */ - abstract class Positioned extends DotClass with Product { + abstract class Positioned extends Attachment.Container with Product { private[this] var curPos: Position = _ diff --git a/src/dotty/tools/dotc/config/CompilerCommand.scala b/src/dotty/tools/dotc/config/CompilerCommand.scala index f4c6ea014..ec8b17b0d 100644 --- a/src/dotty/tools/dotc/config/CompilerCommand.scala +++ b/src/dotty/tools/dotc/config/CompilerCommand.scala @@ -5,7 +5,7 @@ package config import java.io.File import Settings._ import core.Contexts._ -import core.DotClass +import util.DotClass import Properties._ object CompilerCommand extends DotClass { diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index 19d80db18..5ca53b04e 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -90,7 +90,7 @@ object Denotations { * * Then the denotation of `y` is `SingleDenotation(NoSymbol, A | B)`. */ - abstract class Denotation extends DotClass with printing.Showable { + abstract class Denotation extends util.DotClass with printing.Showable { /** The referencing symbol, exists only for non-overloaded denotations */ def symbol: Symbol diff --git a/src/dotty/tools/dotc/core/Names.scala b/src/dotty/tools/dotc/core/Names.scala index 30f82e05e..09fa6cf19 100644 --- a/src/dotty/tools/dotc/core/Names.scala +++ b/src/dotty/tools/dotc/core/Names.scala @@ -12,6 +12,7 @@ import collection.generic.CanBuildFrom import collection.mutable.{ Builder, StringBuilder } import collection.immutable.WrappedString import collection.generic.CanBuildFrom +import util.DotClass //import annotation.volatile object Names { diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala index 2a38acd15..04eef6aaf 100644 --- a/src/dotty/tools/dotc/core/Periods.scala +++ b/src/dotty/tools/dotc/core/Periods.scala @@ -1,6 +1,7 @@ package dotty.tools.dotc.core import Contexts._ +import dotty.tools.dotc.util.DotClass /** Periods are the central "clock" of the compiler. * A period consists of a run id and a phase id. diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala index 72ebc7129..14cab9821 100644 --- a/src/dotty/tools/dotc/core/Phases.scala +++ b/src/dotty/tools/dotc/core/Phases.scala @@ -1,7 +1,9 @@ package dotty.tools.dotc package core -import Periods._, Contexts._ +import Periods._ +import Contexts._ +import util.DotClass trait Phases { self: Context => import Phases._ diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala index a574c5ec2..4aa1ef94d 100644 --- a/src/dotty/tools/dotc/core/Symbols.scala +++ b/src/dotty/tools/dotc/core/Symbols.scala @@ -4,20 +4,27 @@ package core import Periods._ import Transformers._ -import Names._, Scopes._ +import Names._ +import Scopes._ import Flags._ import java.lang.AssertionError import Decorators._ import Symbols._ import Contexts._ -import SymDenotations._, printing.Texts._ +import SymDenotations._ +import printing.Texts._ import printing.Printer -import Types._, Annotations._, util.Positions._, StdNames._, NameOps._ +import Types._ +import Annotations._ +import util.Positions._ +import StdNames._ +import NameOps._ import ast.tpd.{TreeMapper, SharedTree} import Denotations.{ Denotation, SingleDenotation, MultiDenotation } import collection.mutable import io.AbstractFile import language.implicitConversions +import util.DotClass /** Creation methods for symbols */ trait Symbols { this: Context => diff --git a/src/dotty/tools/dotc/core/Transformers.scala b/src/dotty/tools/dotc/core/Transformers.scala index ba26c8be8..90df3a274 100644 --- a/src/dotty/tools/dotc/core/Transformers.scala +++ b/src/dotty/tools/dotc/core/Transformers.scala @@ -1,8 +1,13 @@ package dotty.tools.dotc package core -import Periods._, SymDenotations._, Contexts._, Types._, Denotations._ +import Periods._ +import SymDenotations._ +import Contexts._ +import Types._ +import Denotations._ import java.lang.AssertionError +import dotty.tools.dotc.util.DotClass trait Transformers diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala index 72d8472b6..1d2d4bac9 100644 --- a/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/src/dotty/tools/dotc/core/TypeComparer.scala @@ -8,8 +8,7 @@ import Decorators._ import StdNames.{nme, tpnme} import collection.mutable import printing.Disambiguation.disambiguated -import util.SimpleMap -import util.Stats +import util.{SimpleMap, Stats, DotClass} import config.Config import config.Printers._ diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala index 13fbdbe15..e0c7481c8 100644 --- a/src/dotty/tools/dotc/core/TyperState.scala +++ b/src/dotty/tools/dotc/core/TyperState.scala @@ -5,7 +5,7 @@ package core import Types._ import Flags._ import Contexts._ -import util.SimpleMap +import util.{SimpleMap, DotClass} import reporting._ import printing.{Showable, Printer} import printing.Texts._ diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 49b57d32f..377b20991 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -16,7 +16,7 @@ import Denotations._ import Periods._ import util.Positions.Position import util.Stats._ -import util.SimpleMap +import util.{DotClass, SimpleMap} import ast.tpd._, printing.Texts._ import ast.untpd import transform.Erasure diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala index cf0ab9f62..ceb4ebe42 100644 --- a/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/src/dotty/tools/dotc/parsing/Parsers.scala @@ -12,7 +12,8 @@ import core._ import Flags._ import Contexts._ import Names._ -import ast.Trees._, ast.TreeInfo +import ast.Trees._ +import ast.TreeInfo import Decorators._ import StdNames._ import util.Positions._ @@ -22,6 +23,7 @@ import NameOps._ import util.Chars._ import ScriptParsers._ import annotation.switch +import util.DotClass object Parsers { diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 776d59542..da90a0ab3 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 Inferencing._ import util.Positions._ -import util.SourcePosition +import util.{Attachment, SourcePosition, DotClass} import collection.mutable import annotation.tailrec import ErrorReporting._ @@ -96,10 +96,15 @@ 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] + /** A partial map from unexpanded member and pattern defs and to their expansions. * Populated during enterSyms, emptied during typer. */ - lazy val expandedTree = new mutable.AnyRefMap[DefTree, Tree] /*{ + lazy val expandedTree = new mutable.AnyRefMap[DefTree, Tree] + /*{ override def default(tree: DefTree) = tree // can't have defaults on AnyRefMaps :-( }*/ @@ -113,7 +118,7 @@ class Namer { typer: Typer => /** A map from expanded trees to their typed versions. * Populated when trees are typechecked during completion (using method typedAhead). */ - lazy val typedTree = new mutable.AnyRefMap[Tree, tpd.Tree] + // lazy val typedTree = new mutable.AnyRefMap[Tree, tpd.Tree] /** A map from method symbols to nested typers. * Populated when methods are completed. Emptied when they are typechecked. @@ -133,9 +138,9 @@ class Namer { typer: Typer => /** The symbol of the given expanded tree. */ def symbolOfTree(tree: Tree)(implicit ctx: Context): Symbol = { val xtree = expanded(tree) - typedTree get xtree match { - case Some(ttree) => ttree.denot.symbol - case _ => symOfTree(xtree) + xtree.getAttachment(TypedAhead) match { + case Some(ttree) => ttree.symbol + case none => symOfTree(xtree) } } @@ -249,12 +254,14 @@ class Namer { typer: Typer => val expanded = desugar.defTree(mdef) typr.println(i"Expansion: $mdef expands to $expanded") if (expanded ne mdef) expandedTree(mdef) = expanded + // if (expanded ne mdef) mdef.pushAttachment(ExpandedTree(expanded)) case _ => } /** The expanded version of this tree, or tree itself if not expanded */ def expanded(tree: Tree)(implicit ctx: Context): Tree = tree match { case ddef: DefTree => expandedTree.getOrElse(ddef, ddef) + //ddef.getAttachment(ExpandedTreeKey).orElse(ddef).asInstanceOf[Tree] case _ => tree } @@ -445,15 +452,13 @@ class Namer { typer: Typer => /** Typecheck tree during completion, and remember result in typedtree map */ private def typedAheadImpl(tree: Tree, pt: Type)(implicit ctx: Context): tpd.Tree = { val xtree = expanded(tree) - typedTree.get(xtree) match { + xtree.getAttachment(TypedAhead) match { case Some(ttree) => ttree case none => val ttree = typer.typed(tree, pt) - typedTree(xtree) = ttree + xtree.pushAttachment(TypedAhead, ttree) ttree } - // was: typedTree.getOrElseUpdate(expanded(tree), typer.typed(tree, pt)) - // but this fails for AnyRefMap with an ArrayIndexOutOfBounds exception in getOrElseUpdate } def typedAheadType(tree: Tree, pt: Type = WildcardType)(implicit ctx: Context): tpd.Tree = diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 697441ca1..e68109c9b 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -964,7 +964,7 @@ class Typer extends Namer with Applications with Implicits { def typedUnadapted(initTree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = { val xtree = expanded(initTree) - typedTree remove xtree match { + xtree.removeAttachment(TypedAhead) match { case Some(ttree) => ttree case none => val sym = symOfTree.getOrElse(xtree, NoSymbol) diff --git a/src/dotty/tools/dotc/util/Attachment.scala b/src/dotty/tools/dotc/util/Attachment.scala new file mode 100644 index 000000000..dc9602df3 --- /dev/null +++ b/src/dotty/tools/dotc/util/Attachment.scala @@ -0,0 +1,65 @@ +package dotty.tools.dotc.util + +/** A class inheriting from Attachment.Container supports + * adding, removing and lookup of attachments. Attachments are typed key/value pairs. + */ +object Attachment { + + class Key[+V] + + val NullKey = new Key[Null] + + abstract class AttachmentLink[+V] extends DotClass { + private[Attachment] def key: Key[V] + private[Attachment] def value: V + private[Attachment] var next: Link[_] + + def getAttachment[V](key: Key[V]): Option[V] = + if (this.key eq key) Some(this.value.asInstanceOf[V]) + else if (next == null) None + else next.getAttachment(key) + + def pushAttachment[V](key: Key[V], value: V): Unit = { + assert(!getAttachment(key).isDefined) + next = new Link(key, value, next) + } + + def putAttachment[V](key: Key[V], value: V): Option[V] = { + if (next == null) { + next = new Link(key, value, null) + None + } + else if (next.key eq key) { + val nx = next + next = new Link(key, value, nx.next) + Some(nx.value.asInstanceOf[V]) + } + else next.putAttachment(key, value) + } + + def removeAttachment[V](key: Key[V]): Option[V] = { + if (next == null) + None + else if (next.key eq key) { + val nx = next + next = nx.next + Some(nx.value.asInstanceOf[V]) + } + else next.removeAttachment(key) + } + + def allAttachments: List[Any] = + if (next == null) Nil else next.allAttachments + } + + private[Attachment] class Link[+V](val key: Key[V], val value: V, var next: Link[_]) + extends AttachmentLink[V] { + override def allAttachments: List[Any] = value :: super.allAttachments + } + + class Container extends AttachmentLink[Null] { + private[Attachment] def key = NullKey + private[Attachment] def value: Null = unsupported("value") + private[Attachment] var next: Link[_] = null + } +}
\ No newline at end of file diff --git a/src/dotty/tools/dotc/core/DotClass.scala b/src/dotty/tools/dotc/util/DotClass.scala index f74a4ba81..7839fc37d 100644 --- a/src/dotty/tools/dotc/core/DotClass.scala +++ b/src/dotty/tools/dotc/util/DotClass.scala @@ -1,4 +1,4 @@ -package dotty.tools.dotc.core +package dotty.tools.dotc.util /** Adds standard functionality to a class. * For now: Just the `unsupported` method. |