All Downloads are FREE. Search and download functionalities are using the official Maven repository.

miniboxing.plugin.metadata.MiniboxMetadataAddons.scala Maven / Gradle / Ivy

There is a newer version: 0.4-M8
Show newest version
//
//     _____   .__         .__ ___.                    .__ scala-miniboxing.org
//    /     \  |__|  ____  |__|\_ |__    ____  ___  ___|__|  ____     ____
//   /  \ /  \ |  | /    \ |  | | __ \  /  _ \ \  \/  /|  | /    \   / ___\
//  /    Y    \|  ||   |  \|  | | \_\ \(  <_> ) >    < |  ||   |  \ / /_/  >
//  \____|__  /|__||___|  /|__| |___  / \____/ /__/\_ \|__||___|  / \___  /
//          \/          \/          \/               \/         \/ /_____/
// Copyright (c) 2011-2015 Scala Team, École polytechnique fédérale de Lausanne
//
// Authors:
//    * Eugene Burmako
//
package miniboxing.plugin
package metadata

import scala.collection.immutable.ListMap
import language.implicitConversions
import scala.reflect.NameTransformer

trait MiniboxMetadataAddons {
  self: MiniboxInjectComponent =>

  import global._
  import definitions._
  import scala.collection.immutable

  implicit def richSym(sym: Symbol) = new RichSym(sym)
  implicit def richType(tpe: Type) = new RichType(tpe)
  implicit def richTree(tree: Tree) = new RichTree(tree)

  // Thanks to @xeno-by :)
  class RichSym(sym: Symbol) {
    def getMiniboxedTypeParameters: List[Symbol] =
      sym.typeParams.filter((s: Symbol) => s.isMiniboxAnnotated)
    def hasMiniboxedTypeParameters: Boolean = {
      val existsMbox = sym.typeParams.exists((s: Symbol) => s.isMiniboxAnnotated)
      val existsSpec = sym.typeParams.exists((s: Symbol) => s hasAnnotation SpecializedClass)

      // #117: you can't mix @specialized and @miniboxed!
      if (existsMbox && existsSpec)
        global.reporter.error(sym.pos, s"You can't mix @specialized and @miniboxed in the same ${sym.kindString}. Use only @miniboxing!")

      existsMbox && !existsSpec
    }
    def isMiniboxAnnotated: Boolean = {
      beforeMiniboxInject(sym.info) // make sure the annotation hijacker updated it
      sym hasAnnotation MinispecClass
    }
    def isGenericAnnotated: Boolean = {
      sym hasAnnotation GenericClass
    }
    def isField = sym.isValue && !sym.isMethod
    def isMbArrayMethod: Boolean = isSymbolMbArrayMethod(sym)
    def isArray: Boolean = sym == ArrayClass
    def isImplicitlyPredefMethod: Boolean = isPredefMemberNamed(sym, nme.implicitly)
    def isCastSymbol: Boolean = definitions.isCastSymbol(sym)
    def isIsInstanceOfAnyMethod: Boolean = sym == Any_isInstanceOf
    def isArrowAssocMethod: Boolean = 
      isPredefMemberNamed(sym, newTermName("ArrowAssoc")) || 
      isPredefMemberNamed(sym, newTermName("any2ArrowAssoc")) || 
      (sym.owner == getMemberClass(PredefModule, newTermName("ArrowAssoc")) && sym.name == newTermName(NameTransformer.encode("->")))

    private def tweakedKind = if (sym.isTrait) if (flagdata.classStemTraitFlag(sym)) "trait" else "class" else sym.kindString
    private def tweakedName = if (sym.hasMeaninglessName) sym.owner.decodedName + sym.idString else sym.nameString

    def tweakedToString: String = tweakedKind + " " + tweakedName
    def tweakedFullString: String = tweakedKind + " " + sym.fullNameString
  }

  class RichType(tpe: Type) {
    def getStorageRepr: Symbol = tpe.dealiasWiden.annotations.filter(_.tpe.typeSymbol == StorageClass) match {
      case Nil         => assert(false, "No storage type detected?!?"); ???
      case List(annot) => annot.tpe.typeArgs(0).typeSymbol
    }
    def isStorage: Boolean = tpe.dealiasWiden.annotations.exists(_.tpe.typeSymbol == StorageClass)
    def withStorage(store: Type): Type = tpe.withAnnotations(List(Annotation.apply(appliedType(StorageClass.tpe, List(store)), Nil, ListMap.empty)))
    def withoutStorage: Type = tpe.filterAnnotations(_.tpe.typeSymbol != StorageClass)
    def withoutStorageDeep: Type = (new TypeMap {
      def apply(tpe: Type): Type = mapOver(tpe)
      override def mapOver(tpe: Type): Type = tpe match {
        case ann: AnnotatedType if ann.annotations.exists(_.tpe.typeSymbol == StorageClass) =>
          tpe.filterAnnotations(_.tpe.typeSymbol != StorageClass)
        case _ =>
          super.mapOver(tpe)
      }}).apply(tpe)
  }

  class RichTree(tree: Tree) {
    def isStorage: Boolean = tree.tpe.isStorage
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy