aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/transform/SymUtils.scala
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/src/dotty/tools/dotc/transform/SymUtils.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/transform/SymUtils.scala117
1 files changed, 117 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/SymUtils.scala b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
new file mode 100644
index 000000000..05305575e
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/transform/SymUtils.scala
@@ -0,0 +1,117 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import Types._
+import Contexts._
+import Symbols._
+import SymDenotations._
+import Decorators._
+import Names._
+import StdNames._
+import NameOps._
+import Flags._
+import Annotations._
+import language.implicitConversions
+
+object SymUtils {
+ implicit def decorateSymbol(sym: Symbol): SymUtils = new SymUtils(sym)
+ implicit def decorateSymDenot(d: SymDenotation): SymUtils = new SymUtils(d.symbol)
+}
+
+/** A decorator that provides methods on symbols
+ * that are needed in the transformer pipeline.
+ */
+class SymUtils(val self: Symbol) extends AnyVal {
+ import SymUtils._
+
+ /** All traits implemented by a class or trait except for those inherited through the superclass. */
+ def directlyInheritedTraits(implicit ctx: Context) = {
+ val superCls = self.asClass.superClass
+ val baseClasses = self.asClass.baseClasses
+ if (baseClasses.isEmpty) Nil
+ else baseClasses.tail.takeWhile(_ ne superCls).reverse
+ }
+
+ /** All traits implemented by a class, except for those inherited through the superclass.
+ * The empty list if `self` is a trait.
+ */
+ def mixins(implicit ctx: Context) = {
+ if (self is Trait) Nil
+ else directlyInheritedTraits
+ }
+
+ def isTypeTestOrCast(implicit ctx: Context): Boolean =
+ self == defn.Any_asInstanceOf || self == defn.Any_isInstanceOf
+
+ def isVolatile(implicit ctx: Context) = self.hasAnnotation(defn.VolatileAnnot)
+
+ def isAnyOverride(implicit ctx: Context) = self.is(Override) || self.is(AbsOverride)
+ // careful: AbsOverride is a term only flag. combining with Override would catch only terms.
+
+ /** If this is a constructor, its owner: otherwise this. */
+ final def skipConstructor(implicit ctx: Context): Symbol =
+ if (self.isConstructor) self.owner else self
+
+ /** The closest properly enclosing method or class of this symbol. */
+ final def enclosure(implicit ctx: Context) = {
+ self.owner.enclosingMethodOrClass
+ }
+
+ /** The closest enclosing method or class of this symbol */
+ final def enclosingMethodOrClass(implicit ctx: Context): Symbol =
+ if (self.is(Method, butNot = Label) || self.isClass) self
+ else if (self.exists) self.owner.enclosingMethodOrClass
+ else NoSymbol
+
+ /** Apply symbol/symbol substitution to this symbol */
+ def subst(from: List[Symbol], to: List[Symbol]): Symbol = {
+ def loop(from: List[Symbol], to: List[Symbol]): Symbol =
+ if (from.isEmpty) self
+ else if (self eq from.head) to.head
+ else loop(from.tail, to.tail)
+ loop(from, to)
+ }
+
+ def accessorNamed(name: TermName)(implicit ctx: Context): Symbol =
+ self.owner.info.decl(name).suchThat(_ is Accessor).symbol
+
+ def termParamAccessors(implicit ctx: Context): List[Symbol] =
+ self.info.decls.filter(_ is TermParamAccessor).toList
+
+ def caseAccessors(implicit ctx:Context) =
+ self.info.decls.filter(_ is CaseAccessor).toList
+
+ def getter(implicit ctx: Context): Symbol =
+ if (self.isGetter) self else accessorNamed(self.asTerm.name.getterName)
+
+ def setter(implicit ctx: Context): Symbol =
+ if (self.isSetter) self
+ else accessorNamed(self.asTerm.name.setterName)
+
+ def field(implicit ctx: Context): Symbol =
+ self.owner.info.decl(self.asTerm.name.fieldName).suchThat(!_.is(Method)).symbol
+
+ def isField(implicit ctx: Context): Boolean =
+ self.isTerm && !self.is(Method)
+
+ def implClass(implicit ctx: Context): Symbol =
+ self.owner.info.decl(self.name.implClassName).symbol
+
+ def annotationsCarrying(meta: ClassSymbol)(implicit ctx: Context): List[Annotation] =
+ self.annotations.filter(_.symbol.hasAnnotation(meta))
+
+ def withAnnotationsCarrying(from: Symbol, meta: ClassSymbol)(implicit ctx: Context): self.type = {
+ self.addAnnotations(from.annotationsCarrying(meta))
+ self
+ }
+
+ def registerCompanionMethod(name: Name, target: Symbol)(implicit ctx: Context) = {
+ if (!self.unforcedDecls.lookup(name).exists) {
+ val companionMethod = ctx.synthesizeCompanionMethod(name, target, self)
+ if (companionMethod.exists) {
+ companionMethod.entered
+ }
+ }
+ }
+}