summaryrefslogblamecommitdiff
path: root/src/compiler/scala/reflect/internal/Definitions.scala
blob: 654639adae1038fae9c5d554ed46c86bf0427f4e (plain) (tree)
1
2
3
4
5
6
7
8
9
                            
                                

                          
 
                     
                
 
                                              
              
                        
 
                                                           
                      
 
































                                                                                             
                                
                               







                                                                                                                                     
                                                                                       









































                                                                                                                
                                                            














                                                                              
                                                                        
                                     
                                                
 


                                               

                                                                           
                                    
                                                         
                                                 
                                                  
                                 
        
     
 





                                                                           
                                                                                 

                                                                                                         
 



                                                               
 
                                                              
                                                              
 



                                                             
 
                                     
                                                          
                                                      
                                                         
 
                


                                                                                                          
                                                                                                      
                                                                                                         
 
                   

                                                                                                                           

                                                                              
 
                                      
                                                                                      
                                                                        
                                                                             
                                                                          
                                                                                             


                                                                                       
 
                                    
                                                                                         






                                                                               
 
                          

                                                         





                                                                                                   
                                                             


                                                                              
                                                             
                                                               
                                                                 
                                                                 
                                                                         
                                                               
                                                                                 
                                                             
                                                              
                                                             


                                                                           
                                                                         
                                                                                    
                                                                                    



                                                                             

                                    
                                                                   
                                                                   
                                                                   
                                                         

                                                                               
                                                             


                                                                                      


                                                                                           
 
                                                                                
                                                                                                                              


                                                                     


                                                                         


                                                        
                                      

                                               


                                                            
                                           


                                                 




                                                                                                        
                                                                                                          



                                                                                                           





                                                                                             







                                                                             
 

                                                      
                                    


                                        
                                                                             
                                                                                                     


                          






                                                                                     

                                                                            
                                                            

                                                                           
 
                               
                                                    
                                                                         




                                                              

                                    

                                                                             
                                                                 
                                                                               





                                                                                







                                                                             

                                                      
                                                                                
                                                                                        
 






                                                                                                


                                                           
                                                          
 

                                                                             
                                                                                 
 














                                                                                           

                                                                                                      
                                                                                                       
 

                                                                          

                                                                                                  

                               

                                                                                             
                                      
                                     


                                                             




                                                                       


                                                                           
                                                                                                  
                                                 
 
                                                                        

                                                                         
                                                                                  



                                                      


                                                                                      
       
 



                                          
                                                         

                     
 
                                                                 

                                                                                  
                                                                                             
                                                                             
                                                                                

                                                                       
                                                                                          
                                                                                 

                                                                                        
                                                                                
 










                                                           
 




                                                                                            
 



                                                                       
 
                                                                      



                                                           
                                                                   
                   
     
 







                                                                        
                                                                


                                                               



               





                                                                           
 

                                                                                  
                                                                                        
 
                              
                                                      
                                                             
 


                   

                                                                   






                                                                              
                                                                                             
 
                                                                                    

                                                   




                                                          
                                                                                       


                                                

                       

     
                                 




                                    
                                    

                                    
                                    

                                                  



                                       
                                       
                                       

                                                 
                                                                         

                                                 
                                                                                       
 







                                                                 

                                       
 
                    
                                                                         
                                                                                 
                                                                             


                                                                 






                                                                   

                                                                          
                                                             
                                                             
 









































                                                                                                                  
 










                                                                                           

                                              
                                                                                                                  




                                                                                              



                                                       
                                                 
 
                                           
                                           
 
                                            
                                                        



                                                                
                                                   





                                                           
 
                                                        



                                                                                        
       
     

                                                     
 

                                                                  

                                                               
                      






                                                                                 
                                                                                               



         


                                                        
                                                                                          
 

                                                                                        
                                                             
                                   


           

                                                                                                        
                                                           
                                 





                                                                                  
                    
                 
                       
                                                                     

     

                                                                                

                                   


           
                                                                    
                                                         
                                  


          
                                                                                                                    





                                                              
                                                                                            


                                                                                     
                                                                                                           

                                        
                                                              

     
                                                                                     
                                                               
 
                                                                 
                                                                                           
 
                                                       

                                               
 
                                                                                

                                                                                         


                                                                                                          

                                                                                    
 
                                   
                                                             
                                                                                  
                                                                        
 
                                                                 
                                                                  
 


                                                                              




                                                          
                                                  



                                                          
 
                                            
                                       




                                                             
                                                                
                                                                                                

                                                                                         
                                           


                                                                                                
       
                           

                                                       

     



                                                                       
                                               
                                        
                                                 




                                                      
                                                          


                                                              
                                                 



                                                      










                                                                                          
                
                               
 
                                                                                                         
                                                
 

                                             
 
                                   

                                                                            
                                                                         

                                                                        










                                                                                    



                                                                                                     
                                       
                                                                                         
                                       
                                                                                                       
 

                                                                                  


                                                                                     
                                                                                     
                                             
                                       
                                                                                                                                       
 
                           
                                                             
 
                                                                                                 
                                       


                               





                       


                            
       






                                                                            
 
                          
            



                                                                           
                                                                    








                                                                                                           
                         


               
                                                                                    
                                                         
                                                                       

        
                                                                  
                                                        
                                                             


     
/* NSC -- new Scala compiler
 * Copyright 2005-2011 LAMP/EPFL
 * @author  Martin Odersky
 */

package scala.reflect
package internal

import scala.collection.{ mutable, immutable }
import Flags._
import PartialFunction._

trait Definitions extends reflect.api.StandardDefinitions {
  self: SymbolTable =>

  // the scala value classes
  trait ValueClassDefinitions {
    self: definitions.type =>

    private[Definitions] def valueCache(name: Name) = {
      if (name.isTypeName) ScalaPackageClass.info member name
      else ScalaPackageClass.info member name suchThat (_ hasFlag MODULE)
    }
    private[Definitions] def valueModuleMethod(className: Name, methodName: Name): Symbol = {
      valueCache(className.toTermName).moduleClass.tpe member methodName
    }

    import ClassfileConstants._

    private val nameToWeight = Map[Name, Int](
      tpnme.Byte   -> 2,
      tpnme.Char   -> 3,
      tpnme.Short  -> 4,
      tpnme.Int    -> 12,
      tpnme.Long   -> 24,
      tpnme.Float  -> 48,
      tpnme.Double -> 96
    )

    private val nameToTag = Map[Name, Char](
      tpnme.Byte    -> BYTE_TAG,
      tpnme.Char    -> CHAR_TAG,
      tpnme.Short   -> SHORT_TAG,
      tpnme.Int     -> INT_TAG,
      tpnme.Long    -> LONG_TAG,
      tpnme.Float   -> FLOAT_TAG,
      tpnme.Double  -> DOUBLE_TAG,
      tpnme.Boolean -> BOOL_TAG,
      tpnme.Unit    -> VOID_TAG,
      tpnme.Object  -> TVAR_TAG
    )

    private def classesMap[T](f: Name => T) = symbolsMap(ScalaValueClassesNoUnit, f)
    private def symbolsMap[T](syms: List[Symbol], f: Name => T): Map[Symbol, T] = syms zip (syms map (x => f(x.name))) toMap
    private def symbolsMapFilt[T](syms: List[Symbol], p: Name => Boolean, f: Name => T) = symbolsMap(syms filter (x => p(x.name)), f)

    private def boxedName(name: Name) = sn.Boxed(name.toTypeName)

    lazy val abbrvTag         = symbolsMap(ObjectClass :: ScalaValueClasses, nameToTag)
    lazy val numericWeight    = symbolsMapFilt(ScalaValueClasses, nameToWeight.keySet, nameToWeight)
    lazy val boxedModule      = classesMap(x => getModule(boxedName(x)))
    lazy val boxedClass       = classesMap(x => getClass(boxedName(x)))
    lazy val refClass         = classesMap(x => getClass("scala.runtime." + x + "Ref"))
    lazy val volatileRefClass = classesMap(x => getClass("scala.runtime.Volatile" + x + "Ref"))
    lazy val boxMethod        = classesMap(x => valueModuleMethod(x, nme.box))
    lazy val unboxMethod      = classesMap(x => valueModuleMethod(x, nme.unbox))

    private def newClass(owner: Symbol, name: TypeName, parents: List[Type]): Symbol = {
      val clazz = owner.newClass(NoPosition, name)
      clazz.setInfo(ClassInfoType(parents, new Scope, clazz))
      owner.info.decls.enter(clazz)
      clazz
    }

    def isNumericSubClass(sub: Symbol, sup: Symbol) = {
      val cmp = for (w1 <- numericWeight get sub ; w2 <- numericWeight get sup) yield w2 % w1
      cmp exists (_ == 0)
    }

    /** Is symbol a numeric value class? */
    def isNumericValueClass(sym: Symbol): Boolean =
      numericWeight contains sym

    private[Definitions] def fullNameStrings: List[String] = nme.ScalaValueNames map ("scala." + _)
    private[Definitions] lazy val fullValueName: Set[Name] = {
      val values = nme.ScalaValueNames flatMap (x => List(newTypeName("scala." + x), newTermName("scala." + x)))
      values.toSet + newTypeName("scala.AnyVal")
    }

    lazy val AnyValClass  = valueCache(tpnme.AnyVal)
    lazy val UnitClass    = valueCache(tpnme.Unit)
    lazy val ByteClass    = valueCache(tpnme.Byte)
    lazy val ShortClass   = valueCache(tpnme.Short)
    lazy val CharClass    = valueCache(tpnme.Char)
    lazy val IntClass     = valueCache(tpnme.Int)
    lazy val LongClass    = valueCache(tpnme.Long)
    lazy val FloatClass   = valueCache(tpnme.Float)
    lazy val DoubleClass  = valueCache(tpnme.Double)
    lazy val BooleanClass = valueCache(tpnme.Boolean)
      def Boolean_and = getMember(BooleanClass, nme.ZAND)
      def Boolean_or  = getMember(BooleanClass, nme.ZOR)
      def Boolean_not = getMember(BooleanClass, nme.UNARY_!)

    def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
    def ScalaValueClasses: List[Symbol] = List(
      UnitClass,
      BooleanClass,
      ByteClass,
      ShortClass,
      CharClass,
      IntClass,
      LongClass,
      FloatClass,
      DoubleClass
    )
  }

  object definitions extends AbsDefinitions with ValueClassDefinitions {
    private var isInitialized = false
    def isDefinitionsInitialized = isInitialized

    // symbols related to packages
    var emptypackagescope: Scope = null //debug

    // This is the package _root_.  The actual root cannot be referenced at
    // the source level, but _root_ is essentially a function () => <root>.
    lazy val RootPackage: Symbol = {
      val rp = NoSymbol.newValue(NoPosition, nme.ROOTPKG)
        .setFlag(FINAL | MODULE | PACKAGE | JAVA)
        .setInfo(NullaryMethodType(RootClass.tpe))
      RootClass.sourceModule = rp
      rp
    }

    // This is the actual root of everything, including the package _root_.
    lazy val RootClass: ModuleClassSymbol = (
      NoSymbol.newModuleClass(NoPosition, tpnme.ROOT)
        setFlag (FINAL | MODULE | PACKAGE | JAVA)
        setInfo rootLoader
    )
    // The empty package, which holds all top level types without given packages.
    lazy val EmptyPackage       = RootClass.newPackage(NoPosition, nme.EMPTY_PACKAGE_NAME).setFlag(FINAL)
    lazy val EmptyPackageClass  = EmptyPackage.moduleClass

    lazy val JavaLangPackage      = getModule(sn.JavaLang)
    lazy val JavaLangPackageClass = JavaLangPackage.moduleClass
    lazy val ScalaPackage         = getModule(nme.scala_)
    lazy val ScalaPackageClass    = ScalaPackage.moduleClass

    lazy val RuntimePackage       = getModule("scala.runtime")
    lazy val RuntimePackageClass  = RuntimePackage.moduleClass

    // convenient one-argument parameter lists
    lazy val anyparam     = List(AnyClass.typeConstructor)
    lazy val anyvalparam  = List(AnyValClass.typeConstructor)
    lazy val anyrefparam  = List(AnyRefClass.typeConstructor)

    // private parameter conveniences
    private def booltype    = BooleanClass.typeConstructor
    private def inttype     = IntClass.typeConstructor
    private def stringtype  = StringClass.typeConstructor

    // top types
    lazy val AnyClass             = newClass(ScalaPackageClass, tpnme.Any, Nil) setFlag (ABSTRACT)
    lazy val AnyRefClass          = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.typeConstructor)
    lazy val ObjectClass          = getClass(sn.Object)
    lazy val AnyCompanionClass    = getClass("scala.AnyCompanion") setFlag (SEALED | ABSTRACT | TRAIT)
    lazy val AnyValCompanionClass = getClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT)

    // bottom types
    lazy val NullClass            = newClass(ScalaPackageClass, tpnme.Null, anyrefparam) setFlag (ABSTRACT | TRAIT | FINAL)
    lazy val NothingClass         = newClass(ScalaPackageClass, tpnme.Nothing, anyparam) setFlag (ABSTRACT | TRAIT | FINAL)
    lazy val RuntimeNothingClass  = getClass(ClassfileConstants.SCALA_NOTHING)
    lazy val RuntimeNullClass     = getClass(ClassfileConstants.SCALA_NULL)

    // exceptions and other throwables
    lazy val ClassCastExceptionClass        = getClass("java.lang.ClassCastException")
    lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException)
    lazy val InvocationTargetExceptionClass = getClass(sn.InvTargetException)
    lazy val MatchErrorClass                = getClass("scala.MatchError")
    lazy val NonLocalReturnControlClass     = getClass("scala.runtime.NonLocalReturnControl")
    lazy val NullPointerExceptionClass      = getClass(sn.NPException)
    lazy val ThrowableClass                 = getClass(sn.Throwable)
    lazy val UninitializedErrorClass        = getClass("scala.UninitializedFieldError")

    // fundamental reference classes
    lazy val ScalaObjectClass           = getMember(ScalaPackageClass, tpnme.ScalaObject)
    lazy val PartialFunctionClass       = getClass("scala.PartialFunction")
    lazy val SymbolClass                = getClass("scala.Symbol")
    lazy val StringClass                = getClass(sn.String)
    lazy val StringModule               = StringClass.linkedClassOfClass
    lazy val ClassClass                 = getClass(sn.Class)
      def Class_getMethod               = getMember(ClassClass, nme.getMethod_)
    lazy val DynamicClass               = getClass("scala.Dynamic")

    // fundamental modules
    lazy val SysPackage = getPackageObject("scala.sys")
      def Sys_error    = getMember(SysPackage, nme.error)

    // Modules whose members are in the default namespace
    lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage)
    // Those modules and their module classes
    lazy val UnqualifiedOwners  = UnqualifiedModules.toSet ++ UnqualifiedModules.map(_.moduleClass)

    lazy val PredefModule: Symbol = getModule("scala.Predef")
    lazy val PredefModuleClass = PredefModule.moduleClass
      // Note: this is not the type alias AnyRef, it's a val defined in Predef
      // used by the @specialize annotation.
      def Predef_AnyRef = getMember(PredefModule, nme.AnyRef)
      def Predef_classOf = getMember(PredefModule, nme.classOf)
      def Predef_identity = getMember(PredefModule, nme.identity)
      def Predef_conforms = getMember(PredefModule, nme.conforms)
      def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray)
    lazy val ConsoleModule: Symbol = getModule("scala.Console")
    lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime")
    lazy val SymbolModule: Symbol = getModule("scala.Symbol")
    lazy val Symbol_apply = getMember(SymbolModule, nme.apply)
      def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq)
      def arrayApplyMethod = getMember(ScalaRunTimeModule, "array_apply")
      def arrayUpdateMethod = getMember(ScalaRunTimeModule, "array_update")
      def arrayLengthMethod = getMember(ScalaRunTimeModule, "array_length")
      def arrayCloneMethod = getMember(ScalaRunTimeModule, "array_clone")
      def ensureAccessibleMethod = getMember(ScalaRunTimeModule, "ensureAccessible")
      def scalaRuntimeSameElements = getMember(ScalaRunTimeModule, nme.sameElements)
    lazy val ReflectRuntimeMirror = getModule("scala.reflect.runtime.Mirror")
      def freeValueMethod = getMember(ReflectRuntimeMirror, "freeValue")
    lazy val ReflectPackage = getPackageObject("scala.reflect")
      def Reflect_mirror = getMember(ReflectPackage, "mirror")

    // classes with special meanings
    lazy val StringAddClass   = getClass("scala.runtime.StringAdd")
    lazy val ArrowAssocClass  = getClass("scala.Predef.ArrowAssoc")
    lazy val StringAdd_+      = getMember(StringAddClass, nme.PLUS)
    lazy val NotNullClass     = getClass("scala.NotNull")
    lazy val ScalaNumberClass           = getClass("scala.math.ScalaNumber")
    lazy val TraitSetterAnnotationClass = getClass("scala.runtime.TraitSetter")
    lazy val DelayedInitClass = getClass("scala.DelayedInit")
      def delayedInitMethod = getMember(DelayedInitClass, nme.delayedInit)
      // a dummy value that communicates that a delayedInit call is compiler-generated
      // from phase UnCurry to phase Constructors
      // !!! This is not used anywhere (it was checked in that way.)
      // def delayedInitArgVal = EmptyPackageClass.newValue(NoPosition, nme.delayedInitArg)
      //   .setInfo(UnitClass.tpe)

    lazy val TypeConstraintClass   = getClass("scala.annotation.TypeConstraint")
    lazy val SingletonClass        = newClass(ScalaPackageClass, tpnme.Singleton, anyparam) setFlag (ABSTRACT | TRAIT | FINAL)
    lazy val SerializableClass     = getClass("scala.Serializable")
    lazy val JavaSerializableClass = getClass(sn.JavaSerializable)
    lazy val ComparableClass       = getClass("java.lang.Comparable")
    lazy val JavaCloneableClass    = getClass("java.lang.Cloneable")
    lazy val RemoteInterfaceClass  = getClass("java.rmi.Remote")
    lazy val RemoteExceptionClass  = getClass("java.rmi.RemoteException")

    lazy val RepeatedParamClass = newCovariantPolyClass(
      ScalaPackageClass,
      tpnme.REPEATED_PARAM_CLASS_NAME,
      tparam => seqType(tparam.typeConstructor)
    )

    lazy val JavaRepeatedParamClass = newCovariantPolyClass(
      ScalaPackageClass,
      tpnme.JAVA_REPEATED_PARAM_CLASS_NAME,
      tparam => arrayType(tparam.typeConstructor)
    )

    def isByNameParamType(tp: Type)        = tp.typeSymbol == ByNameParamClass
    def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
    def isJavaRepeatedParamType(tp: Type)  = tp.typeSymbol == JavaRepeatedParamClass
    def isRepeatedParamType(tp: Type)      = isScalaRepeatedParamType(tp) || isJavaRepeatedParamType(tp)

    def isJavaVarArgs(params: List[Symbol])  = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
    def isScalaVarArgs(params: List[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
    def isVarArgsList(params: List[Symbol])  = params.nonEmpty && isRepeatedParamType(params.last.tpe)
    def isVarArgTypes(formals: List[Type])   = formals.nonEmpty && isRepeatedParamType(formals.last)

    def hasRepeatedParam(tp: Type): Boolean = tp match {
      case MethodType(formals, restpe) => isScalaVarArgs(formals) || hasRepeatedParam(restpe)
      case PolyType(_, restpe)         => hasRepeatedParam(restpe)
      case _                           => false
    }

    def isPrimitiveArray(tp: Type) = tp match {
      case TypeRef(_, ArrayClass, arg :: Nil) => isValueClass(arg.typeSymbol)
      case _                                  => false
    }
    def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
      case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem
      case _                                  => false
    }

    lazy val ByNameParamClass = newCovariantPolyClass(
      ScalaPackageClass,
      tpnme.BYNAME_PARAM_CLASS_NAME,
      tparam => AnyClass.typeConstructor
    )
    lazy val EqualsPatternClass = {
      val clazz = newClass(ScalaPackageClass, tpnme.EQUALS_PATTERN_NAME, Nil)
      clazz setInfo polyType(List(newTypeParam(clazz, 0)), ClassInfoType(anyparam, new Scope, clazz))
    }

    // collections classes
    lazy val ConsClass          = getClass("scala.collection.immutable.$colon$colon")
    lazy val IterableClass      = getClass("scala.collection.Iterable")
    lazy val IteratorClass      = getClass("scala.collection.Iterator")
    lazy val ListClass          = getClass("scala.collection.immutable.List")
    lazy val SeqClass           = getClass("scala.collection.Seq")
    lazy val StringBuilderClass = getClass("scala.collection.mutable.StringBuilder")
    lazy val TraversableClass   = getClass("scala.collection.Traversable")

    lazy val ListModule       = getModule("scala.collection.immutable.List")
      lazy val List_apply = getMember(ListModule, nme.apply)
    lazy val NilModule        = getModule("scala.collection.immutable.Nil")
    lazy val SeqModule        = getModule("scala.collection.Seq")

    // arrays and their members
    lazy val ArrayModule  = getModule("scala.Array")
      def ArrayModule_overloadedApply = getMember(ArrayModule, nme.apply)
    lazy val ArrayClass   = getClass("scala.Array")
      def Array_apply      = getMember(ArrayClass, nme.apply)
      def Array_update     = getMember(ArrayClass, nme.update)
      def Array_length     = getMember(ArrayClass, nme.length)
      lazy val Array_clone = getMember(ArrayClass, nme.clone_)

    // reflection / structural types
    lazy val SoftReferenceClass     = getClass("java.lang.ref.SoftReference")
    lazy val WeakReferenceClass     = getClass("java.lang.ref.WeakReference")
    lazy val MethodClass            = getClass(sn.MethodAsObject)
      def methodClass_setAccessible = getMember(MethodClass, nme.setAccessible)
    lazy val EmptyMethodCacheClass  = getClass("scala.runtime.EmptyMethodCache")
    lazy val MethodCacheClass       = getClass("scala.runtime.MethodCache")
      def methodCache_find  = getMember(MethodCacheClass, nme.find_)
      def methodCache_add   = getMember(MethodCacheClass, nme.add_)

    // scala.reflect
    lazy val PartialManifestClass  = getClass("scala.reflect.ClassManifest")
    lazy val PartialManifestModule = getModule("scala.reflect.ClassManifest")
    lazy val FullManifestClass     = getClass("scala.reflect.Manifest")
    lazy val FullManifestModule    = getModule("scala.reflect.Manifest")
    lazy val OptManifestClass      = getClass("scala.reflect.OptManifest")
    lazy val NoManifest            = getModule("scala.reflect.NoManifest")
    lazy val CodeClass             = getClass(sn.Code)
    lazy val CodeModule            = getModule(sn.Code)
      def Code_lift = getMember(CodeModule, nme.lift_)

    lazy val ScalaSignatureAnnotation = getClass("scala.reflect.ScalaSignature")
    lazy val ScalaLongSignatureAnnotation = getClass("scala.reflect.ScalaLongSignature")

    // invoke dynamic support
    lazy val LinkageModule = getModule("java.dyn.Linkage")
      lazy val Linkage_invalidateCallerClass = getMember(LinkageModule, "invalidateCallerClass")
    lazy val DynamicDispatchClass = getModule("scala.runtime.DynamicDispatch")
      lazy val DynamicDispatch_DontSetTarget = getMember(DynamicDispatchClass, "DontSetTarget")

    // Option classes
    lazy val OptionClass: Symbol = getClass("scala.Option")
    lazy val SomeClass: Symbol   = getClass("scala.Some")
    lazy val NoneModule: Symbol  = getModule("scala.None")
    lazy val SomeModule: Symbol  = getModule("scala.Some")

    // The given symbol represents either String.+ or StringAdd.+
    def isStringAddition(sym: Symbol) = sym == String_+ || sym == StringAdd_+
    def isArrowAssoc(sym: Symbol) = ArrowAssocClass.tpe.decls.toList contains sym

    // The given symbol is a method with the right signature to be a runnable java program.
    def isJavaMainMethod(sym: Symbol) = sym.tpe match {
      case MethodType(param :: Nil, restpe) if restpe.typeSymbol == UnitClass =>
        param.tpe match {
          case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == StringClass
          case _                                  => false
        }
      case _ => false
    }
    // The given class has a main method.
    def hasJavaMainMethod(sym: Symbol): Boolean =
      (sym.tpe member nme.main).alternatives exists isJavaMainMethod
    def hasJavaMainMethod(path: String): Boolean =
      hasJavaMainMethod(getModuleIfDefined(path))

    def isOptionType(tp: Type)  = cond(tp.normalize) { case TypeRef(_, OptionClass, List(_)) => true }
    def isSomeType(tp: Type)    = cond(tp.normalize) { case TypeRef(_,   SomeClass, List(_)) => true }
    def isNoneType(tp: Type)    = cond(tp.normalize) { case TypeRef(_,   NoneModule, List(_)) => true }

    def optionType(tp: Type)    = typeRef(NoPrefix, OptionClass, List(tp))
    def someType(tp: Type)      = typeRef(NoPrefix, SomeClass, List(tp))
    def symbolType              = typeRef(SymbolClass.typeConstructor.prefix, SymbolClass, List())
    def longType                = typeRef(LongClass.typeConstructor.prefix, LongClass, List())

    // Product, Tuple, Function
    private def mkArityArray(name: String, arity: Int, countFrom: Int = 1): Array[Symbol] = {
      val list = countFrom to arity map (i => getClass("scala." + name + i))
      if (countFrom == 0) list.toArray
      else (NoSymbol +: list).toArray
    }

    val MaxTupleArity, MaxProductArity, MaxFunctionArity = 22
    /** The maximal dimensions of a generic array creation.
     *  I.e. new Array[Array[Array[Array[Array[T]]]]] creates a 5 times
     *  nested array. More is not allowed.
     */
    val MaxArrayDims = 5
    lazy val TupleClass     = mkArityArray("Tuple", MaxTupleArity)
    lazy val ProductClass   = mkArityArray("Product", MaxProductArity)
    lazy val FunctionClass  = mkArityArray("Function", MaxFunctionArity, 0)
    lazy val AbstractFunctionClass = mkArityArray("runtime.AbstractFunction", MaxFunctionArity, 0)
    lazy val isProductNClass = ProductClass.toSet

      def tupleField(n: Int, j: Int) = getMember(TupleClass(n), "_" + j)
      def isTupleType(tp: Type): Boolean = isTupleType(tp, false)
      def isTupleTypeOrSubtype(tp: Type): Boolean = isTupleType(tp, true)
      private def isTupleType(tp: Type, subtypeOK: Boolean) = tp.normalize match {
        case TypeRef(_, sym, args) if args.nonEmpty =>
          val len = args.length
          len <= MaxTupleArity && {
            val tsym = TupleClass(len)
            (sym == tsym) || (subtypeOK && !tp.isHigherKinded && sym.isSubClass(tsym))
          }
        case _ => false
      }

      def tupleType(elems: List[Type]) = {
        val len = elems.length
        if (len <= MaxTupleArity) {
          val sym = TupleClass(len)
          typeRef(sym.typeConstructor.prefix, sym, elems)
        } else NoType
      }

    lazy val ProductRootClass: Symbol = getClass("scala.Product")
      def Product_productArity = getMember(ProductRootClass, nme.productArity)
      def Product_productElement = getMember(ProductRootClass, nme.productElement)
      // def Product_productElementName = getMember(ProductRootClass, nme.productElementName)
      def Product_iterator = getMember(ProductRootClass, nme.productIterator)
      def Product_productPrefix = getMember(ProductRootClass, nme.productPrefix)
      def Product_canEqual = getMember(ProductRootClass, nme.canEqual_)

      def productProj(z:Symbol, j: Int): Symbol = getMember(z, nme.productAccessorName(j))
      def productProj(n: Int,   j: Int): Symbol = productProj(ProductClass(n), j)

      /** returns true if this type is exactly ProductN[T1,...,Tn], not some subclass */
      def isExactProductType(tp: Type): Boolean = isProductNClass(tp.typeSymbol)

      def productType(elems: List[Type]) = {
        if (elems.isEmpty) UnitClass.tpe
        else {
          val len = elems.length
          if (len <= MaxProductArity) {
            val sym = ProductClass(len)
            typeRef(sym.typeConstructor.prefix, sym, elems)
          }
          else NoType
        }
      }

    /** if tpe <: ProductN[T1,...,TN], returns List(T1,...,TN) else Nil */
    def getProductArgs(tpe: Type): List[Type] = tpe.baseClasses find isProductNClass match {
      case Some(x)  => tpe.baseType(x).typeArgs
      case _        => Nil
    }

    def unapplyUnwrap(tpe:Type) = tpe.finalResultType.normalize match {
      case RefinedType(p :: _, _) => p.normalize
      case tp                     => tp
    }

    def functionApply(n: Int) = getMember(FunctionClass(n), nme.apply)
    def functionType(formals: List[Type], restpe: Type) = {
      val len = formals.length
      if (len <= MaxFunctionArity) {
        val sym = FunctionClass(len)
        typeRef(sym.typeConstructor.prefix, sym, formals :+ restpe)
      } else NoType
    }

    def abstractFunctionForFunctionType(tp: Type) = tp.normalize match {
      case tr @ TypeRef(_, _, args) if isFunctionType(tr) =>
        val sym = AbstractFunctionClass(args.length - 1)
        typeRef(sym.typeConstructor.prefix, sym, args)
      case _ =>
        NoType
    }

    def isFunctionType(tp: Type): Boolean = tp.normalize match {
      case TypeRef(_, sym, args) if args.nonEmpty =>
        val len = args.length
        len < MaxFunctionArity && sym == FunctionClass(len - 1)
      case _ =>
        false
    }

    def isSeqType(tp: Type) = elementType(SeqClass, tp.normalize) != NoType

    def elementType(container: Symbol, tp: Type): Type = tp match {
      case TypeRef(_, `container`, arg :: Nil)  => arg
      case _                                    => NoType
    }

    def seqType(arg: Type)    = appliedType(SeqClass.typeConstructor, List(arg))
    def arrayType(arg: Type)  = appliedType(ArrayClass.typeConstructor, List(arg))
    def byNameType(arg: Type) = appliedType(ByNameParamClass.typeConstructor, List(arg))

    def ClassType(arg: Type) =
      if (phase.erasedTypes || forMSIL) ClassClass.tpe
      else appliedType(ClassClass.typeConstructor, List(arg))

    //
    // .NET backend
    //

    lazy val ComparatorClass = getClass("scala.runtime.Comparator")
    // System.ValueType
    lazy val ValueTypeClass: Symbol = getClass(sn.ValueType)
    // System.MulticastDelegate
    lazy val DelegateClass: Symbol = getClass(sn.Delegate)
    var Delegate_scalaCallers: List[Symbol] = List()
    // Symbol -> (Symbol, Type): scalaCaller -> (scalaMethodSym, DelegateType)
    // var Delegate_scalaCallerInfos: HashMap[Symbol, (Symbol, Type)] = _
    lazy val Delegate_scalaCallerTargets: mutable.HashMap[Symbol, Symbol] = mutable.HashMap()

    def isCorrespondingDelegate(delegateType: Type, functionType: Type): Boolean = {
      isSubType(delegateType, DelegateClass.tpe) &&
      (delegateType.member(nme.apply).tpe match {
      	case MethodType(delegateParams, delegateReturn) =>
      	  isFunctionType(functionType) &&
      	  (functionType.normalize match {
      	    case TypeRef(_, _, args) =>
      	      (delegateParams.map(pt => {
                      if (pt.tpe == AnyClass.tpe) definitions.ObjectClass.tpe else pt})
      	       ::: List(delegateReturn)) == args
      	    case _ => false
      	  })
        case _ => false
      })
    }

    // members of class scala.Any
    var Any_==          : Symbol = _
    var Any_!=          : Symbol = _
    var Any_equals      : Symbol = _
    var Any_hashCode    : Symbol = _
    var Any_toString    : Symbol = _
    var Any_getClass    : Symbol = _
    var Any_isInstanceOf: Symbol = _
    var Any_asInstanceOf: Symbol = _
    var Any_##          : Symbol = _

    // members of class java.lang.{Object, String}
    var Object_eq          : Symbol = _
    var Object_ne          : Symbol = _
    var Object_==          : Symbol = _
    var Object_!=          : Symbol = _
    var Object_##          : Symbol = _
    var Object_synchronized: Symbol = _
    lazy val Object_isInstanceOf = newPolyMethod(
      ObjectClass, "$isInstanceOf",
      tparam => MethodType(List(), booltype)) setFlag (FINAL | SYNTHETIC)
    lazy val Object_asInstanceOf = newPolyMethod(
      ObjectClass, "$asInstanceOf",
      tparam => MethodType(List(), tparam.typeConstructor)) setFlag (FINAL | SYNTHETIC)

    def Object_getClass  = getMember(ObjectClass, nme.getClass_)
    def Object_clone     = getMember(ObjectClass, nme.clone_)
    def Object_finalize  = getMember(ObjectClass, nme.finalize_)
    def Object_notify    = getMember(ObjectClass, nme.notify_)
    def Object_notifyAll = getMember(ObjectClass, nme.notifyAll_)
    def Object_equals    = getMember(ObjectClass, nme.equals_)
    def Object_hashCode  = getMember(ObjectClass, nme.hashCode_)
    def Object_toString  = getMember(ObjectClass, nme.toString_)

    var String_+           : Symbol = _

    // boxed classes
    lazy val ObjectRefClass         = getClass("scala.runtime.ObjectRef")
    lazy val VolatileObjectRefClass = getClass("scala.runtime.VolatileObjectRef")
    lazy val BoxesRunTimeClass      = getModule("scala.runtime.BoxesRunTime")
    lazy val BoxedNumberClass       = getClass(sn.BoxedNumber)
    lazy val BoxedCharacterClass    = getClass(sn.BoxedCharacter)
    lazy val BoxedBooleanClass      = getClass(sn.BoxedBoolean)
    lazy val BoxedByteClass         = getClass("java.lang.Byte")
    lazy val BoxedShortClass        = getClass("java.lang.Short")
    lazy val BoxedIntClass          = getClass("java.lang.Integer")
    lazy val BoxedLongClass         = getClass("java.lang.Long")
    lazy val BoxedFloatClass        = getClass("java.lang.Float")
    lazy val BoxedDoubleClass       = getClass("java.lang.Double")

    lazy val BoxedUnitClass         = getClass("scala.runtime.BoxedUnit")
    lazy val BoxedUnitModule        = getModule("scala.runtime.BoxedUnit")
      def BoxedUnit_UNIT = getMember(BoxedUnitModule, "UNIT")
      def BoxedUnit_TYPE = getMember(BoxedUnitModule, "TYPE")

    // Annotation base classes
    lazy val AnnotationClass            = getClass("scala.annotation.Annotation")
    lazy val ClassfileAnnotationClass   = getClass("scala.annotation.ClassfileAnnotation")
    lazy val StaticAnnotationClass      = getClass("scala.annotation.StaticAnnotation")

    // Annotations
    lazy val BridgeClass                = getClass("scala.annotation.bridge")
    lazy val ElidableMethodClass        = getClass("scala.annotation.elidable")
    lazy val ImplicitNotFoundClass      = getClass("scala.annotation.implicitNotFound")
    lazy val MigrationAnnotationClass   = getClass("scala.annotation.migration")
    lazy val ScalaStrictFPAttr          = getClass("scala.annotation.strictfp")
    lazy val SerializableAttr           = getClass("scala.annotation.serializable") // @serializable is deprecated
    lazy val SwitchClass                = getClass("scala.annotation.switch")
    lazy val TailrecClass               = getClass("scala.annotation.tailrec")
    lazy val VarargsClass               = getClass("scala.annotation.varargs")
    lazy val uncheckedStableClass       = getClass("scala.annotation.unchecked.uncheckedStable")
    lazy val uncheckedVarianceClass     = getClass("scala.annotation.unchecked.uncheckedVariance")

    lazy val BeanPropertyAttr           = getClass(sn.BeanProperty)
    lazy val BooleanBeanPropertyAttr    = getClass(sn.BooleanBeanProperty)
    lazy val CloneableAttr              = getClass("scala.cloneable")
    lazy val DeprecatedAttr             = getClass("scala.deprecated")
    lazy val DeprecatedNameAttr         = getClass("scala.deprecatedName")
    lazy val NativeAttr                 = getClass("scala.native")
    lazy val RemoteAttr                 = getClass("scala.remote")
    lazy val ScalaInlineClass           = getClass("scala.inline")
    lazy val ScalaNoInlineClass         = getClass("scala.noinline")
    lazy val SerialVersionUIDAttr       = getClass("scala.SerialVersionUID")
    lazy val SpecializedClass           = getClass("scala.specialized")
    lazy val ThrowsClass                = getClass("scala.throws")
    lazy val TransientAttr              = getClass("scala.transient")
    lazy val UncheckedClass             = getClass("scala.unchecked")
    lazy val VolatileAttr               = getClass("scala.volatile")

    // Meta-annotations
    lazy val BeanGetterTargetClass      = getMetaAnnotation("beanGetter")
    lazy val BeanSetterTargetClass      = getMetaAnnotation("beanSetter")
    lazy val FieldTargetClass           = getMetaAnnotation("field")
    lazy val GetterTargetClass          = getMetaAnnotation("getter")
    lazy val ParamTargetClass           = getMetaAnnotation("param")
    lazy val SetterTargetClass          = getMetaAnnotation("setter")


    private def getMetaAnnotation(name: String) = getClass("scala.annotation.meta." + name)
    def isMetaAnnotation(sym: Symbol): Boolean = metaAnnotations(sym) || (
      // Trying to allow for deprecated locations
      sym.isAliasType && isMetaAnnotation(sym.info.typeSymbol)
    )

    lazy val metaAnnotations = Set(
      FieldTargetClass, ParamTargetClass,
      GetterTargetClass, SetterTargetClass,
      BeanGetterTargetClass, BeanSetterTargetClass
    )

    lazy val AnnotationDefaultAttr: Symbol = {
      val attr = newClass(RuntimePackageClass, tpnme.AnnotationDefaultATTR, List(AnnotationClass.typeConstructor))
      // This attribute needs a constructor so that modifiers in parsed Java code make sense
      attr.info.decls enter (attr newConstructor NoPosition setInfo MethodType(Nil, attr.tpe))
      attr
    }

    def getPackageObjectClass(fullname: Name): Symbol =
      getPackageObject(fullname).companionClass

    def getPackageObject(fullname: Name): Symbol =
      getModule(fullname).info member nme.PACKAGE

    def getModule(fullname: Name): Symbol =
      getModuleOrClass(fullname.toTermName)

    def getClass(fullname: Name): Symbol = {
      var result = getModuleOrClass(fullname.toTypeName)
      while (result.isAliasType) result = result.info.typeSymbol
      result
    }

    def getClassIfDefined(fullname: Name): Symbol =
      try getClass(fullname.toTypeName)
      catch { case _: MissingRequirementError => NoSymbol }

    def getModuleIfDefined(fullname: Name): Symbol =
      try getModule(fullname.toTermName)
      catch { case _: MissingRequirementError => NoSymbol }

    def getMember(owner: Symbol, name: Name): Symbol = {
      if (owner == NoSymbol) NoSymbol
      else owner.info.nonPrivateMember(name) match {
        case NoSymbol => throw new FatalError(owner + " does not have a member " + name)
        case result   => result
      }
    }
    def packageExists(packageName: String): Boolean =
      getModuleIfDefined(packageName).isPackage

    private def getModuleOrClass(path: Name, len: Int): Symbol = {
      val point = path lastPos('.', len - 1)
      val owner =
        if (point > 0) getModuleOrClass(path.toTermName, point)
        else RootClass
      val name = path subName (point + 1, len)
      val sym = owner.info member name
      val result = if (path.isTermName) sym.suchThat(_ hasFlag MODULE) else sym
      if (result != NoSymbol) result
      else {
        if (settings.debug.value) { log(sym.info); log(sym.info.members) }//debug
        missingHook(owner, name) orElse {
          MissingRequirementError.notFound((if (path.isTermName) "object " else "class ")+path)
        }
      }
    }

    /** If you're looking for a class, pass a type name.
     *  If a module, a term name.
     */
    private def getModuleOrClass(path: Name): Symbol = getModuleOrClass(path, path.length)

    private def newClass(owner: Symbol, name: TypeName, parents: List[Type]): Symbol = {
      val clazz = owner.newClass(NoPosition, name)
      clazz.setInfo(ClassInfoType(parents, new Scope, clazz))
      owner.info.decls.enter(clazz)
      clazz
    }

    private def newCovariantPolyClass(owner: Symbol, name: TypeName, parent: Symbol => Type): Symbol = {
      val clazz  = newClass(owner, name, List())
      val tparam = newTypeParam(clazz, 0) setFlag COVARIANT
      val p      = parent(tparam)
/*      p.typeSymbol.initialize
      println(p.typeSymbol + " flags: " + Flags.flagsToString(p.typeSymbol.flags))
      val parents = /*if (p.typeSymbol.isTrait)
        List(definitions.AnyRefClass.tpe, p)
                    else*/ List(p)
      println("creating " + name + " with parents " + parents) */
      clazz.setInfo(
        polyType(
          List(tparam),
          ClassInfoType(List(AnyRefClass.tpe, p), new Scope, clazz)))
    }

    private def newAlias(owner: Symbol, name: TypeName, alias: Type): Symbol = {
      val tpsym = owner.newAliasType(NoPosition, name)
      tpsym.setInfo(alias)
      owner.info.decls.enter(tpsym)
      tpsym
    }

    private def newMethod(owner: Symbol, name: TermName): Symbol = {
      val msym = owner.newMethod(NoPosition, name.encode)
      owner.info.decls.enter(msym)
      msym
    }

    private[Definitions] def newMethod(owner: Symbol, name: TermName, formals: List[Type], restpe: Type): Symbol = {
      val msym = newMethod(owner, name)
      val params = msym.newSyntheticValueParams(formals)
      msym.setInfo(MethodType(params, restpe))
    }

    /** tcon receives the type parameter symbol as argument */
    private def newPolyMethod(owner: Symbol, name: TermName, tcon: Symbol => Type): Symbol =
      newPolyMethodCon(owner, name, tparam => msym => tcon(tparam))

    /** tcon receives the type parameter symbol and the method symbol as arguments */
    private def newPolyMethodCon(owner: Symbol, name: TermName, tcon: Symbol => Symbol => Type): Symbol = {
      val msym = newMethod(owner, name)
      val tparam = newTypeParam(msym, 0)
      msym.setInfo(polyType(List(tparam), tcon(tparam)(msym)))
    }

    private def newParameterlessMethod(owner: Symbol, name: TermName, restpe: Type) =
      newMethod(owner, name).setInfo(NullaryMethodType(restpe))

    private def newTypeParam(owner: Symbol, index: Int): Symbol =
      owner.newTypeParameter(NoPosition, newTypeName("T" + index)) setInfo TypeBounds.empty

    lazy val boxedClassValues = boxedClass.values.toSet
    lazy val isUnbox = unboxMethod.values.toSet
    lazy val isBox = boxMethod.values.toSet

    /** Is symbol a phantom class for which no runtime representation exists? */
    lazy val isPhantomClass = Set[Symbol](AnyClass, AnyValClass, NullClass, NothingClass)

    /** Is the symbol that of a parent which is added during parsing? */
    lazy val isPossibleSyntheticParent = ProductClass.toSet[Symbol] + ProductRootClass + SerializableClass

    private lazy val scalaValueClassesSet = ScalaValueClasses.toSet
    private lazy val boxedValueClassesSet = boxedClass.values.toSet + BoxedUnitClass

    /** Is symbol a value class? */
    def isValueClass(sym: Symbol) = scalaValueClassesSet(sym)
    def isNonUnitValueClass(sym: Symbol) = (sym != UnitClass) && isValueClass(sym)
    def isScalaValueType(tp: Type) = scalaValueClassesSet(tp.typeSymbol)

    /** Is symbol a boxed value class, e.g. java.lang.Integer? */
    def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym)

    /** If symbol is a value class, return the value class, with the exception
     *  that BoxedUnit remains BoxedUnit.  If not a value class, NoSymbol.
     */
    def unboxedValueClass(sym: Symbol): Symbol =
      if (isValueClass(sym)) sym
      else if (sym == BoxedUnitClass) sym
      else boxedClass.map(_.swap).getOrElse(sym, NoSymbol)

    /** Is type's symbol a numeric value class? */
    def isNumericValueType(tp: Type): Boolean = tp match {
      case TypeRef(_, sym, _) => isNumericValueClass(sym)
      case _ => false
    }

    // todo: reconcile with javaSignature!!!
    def signature(tp: Type): String = {
      def erasure(tp: Type): Type = tp match {
        case st: SubType => erasure(st.supertype)
        case RefinedType(parents, _) => erasure(parents.head)
        case _ => tp
      }
      def flatNameString(sym: Symbol, separator: Char): String =
        if (sym == NoSymbol) ""   // be more resistant to error conditions, e.g. neg/t3222.scala
        else if (sym.owner.isPackageClass) sym.javaClassName
        else flatNameString(sym.owner, separator) + nme.NAME_JOIN_STRING + sym.simpleName
      def signature1(etp: Type): String = {
        if (etp.typeSymbol == ArrayClass) "[" + signature1(erasure(etp.normalize.typeArgs.head))
        else if (isValueClass(etp.typeSymbol)) abbrvTag(etp.typeSymbol).toString()
        else "L" + flatNameString(etp.typeSymbol, '/') + ";"
      }
      val etp = erasure(tp)
      if (etp.typeSymbol == ArrayClass) signature1(etp)
      else flatNameString(etp.typeSymbol, '.')
    }

    /** getModule2/getClass2 aren't needed at present but may be again,
     *  so for now they're mothballed.
     */
    // def getModule2(name1: Name, name2: Name) = {
    //   try getModuleOrClass(name1.toTermName)
    //   catch { case ex1: FatalError =>
    //     try getModuleOrClass(name2.toTermName)
    //     catch { case ex2: FatalError => throw ex1 }
    //   }
    // }
    // def getClass2(name1: Name, name2: Name) = {
    //   try {
    //     val result = getModuleOrClass(name1.toTypeName)
    //     if (result.isAliasType) getClass(name2) else result
    //   }
    //   catch { case ex1: FatalError =>
    //     try getModuleOrClass(name2.toTypeName)
    //     catch { case ex2: FatalError => throw ex1 }
    //   }
    // }

    /** Surgery on the value classes.  Without this, AnyVals defined in source
     *  files end up with an AnyRef parent.  It is likely there is a better way
     *  to evade that AnyRef.
     */
    private def setParents(sym: Symbol, parents: List[Type]): Symbol = sym.rawInfo match {
      case ClassInfoType(_, scope, clazz) =>
        sym setInfo ClassInfoType(parents, scope, clazz)
      case _ =>
        sym
    }

    def init() {
      if (isInitialized) return

      EmptyPackageClass setInfo ClassInfoType(Nil, newPackageScope(EmptyPackageClass), EmptyPackageClass)
      EmptyPackage setInfo EmptyPackageClass.tpe

      RootClass.info.decls enter EmptyPackage
      RootClass.info.decls enter RootPackage

      // members of class scala.Any
      Any_== = newMethod(AnyClass, nme.EQ, anyparam, booltype) setFlag FINAL
      Any_!= = newMethod(AnyClass, nme.NE, anyparam, booltype) setFlag FINAL
      Any_equals   = newMethod(AnyClass, nme.equals_, anyparam, booltype)
      Any_hashCode = newMethod(AnyClass, nme.hashCode_, Nil, inttype)
      Any_toString = newMethod(AnyClass, nme.toString_, Nil, stringtype)
      Any_##       = newMethod(AnyClass, nme.HASHHASH, Nil, inttype) setFlag FINAL

      // Any_getClass requires special handling.  The return type is determined on
      // a per-call-site basis as if the function being called were actually:
      //
      //    // Assuming `target.getClass()`
      //    def getClass[T](target: T): Class[_ <: T]
      //
      // Since getClass is not actually a polymorphic method, this requires compiler
      // participation.  At the "Any" level, the return type is Class[_] as it is in
      // java.lang.Object.  Java also special cases the return type.
      Any_getClass = (
        newMethod(AnyClass, nme.getClass_, Nil, getMember(ObjectClass, nme.getClass_).tpe.resultType)
          setFlag DEFERRED
      )
      Any_isInstanceOf = newPolyMethod(
        AnyClass, nme.isInstanceOf_, tparam => NullaryMethodType(booltype)) setFlag FINAL
      Any_asInstanceOf = newPolyMethod(
        AnyClass, nme.asInstanceOf_, tparam => NullaryMethodType(tparam.typeConstructor)) setFlag FINAL

      // members of class java.lang.{ Object, String }
      Object_## = newMethod(ObjectClass, nme.HASHHASH, Nil, inttype) setFlag FINAL
      Object_== = newMethod(ObjectClass, nme.EQ, anyrefparam, booltype) setFlag FINAL
      Object_!= = newMethod(ObjectClass, nme.NE, anyrefparam, booltype) setFlag FINAL
      Object_eq = newMethod(ObjectClass, nme.eq, anyrefparam, booltype) setFlag FINAL
      Object_ne = newMethod(ObjectClass, nme.ne, anyrefparam, booltype) setFlag FINAL
      Object_synchronized = newPolyMethodCon(
        ObjectClass, nme.synchronized_,
        tparam => msym => MethodType(msym.newSyntheticValueParams(List(tparam.typeConstructor)), tparam.typeConstructor)) setFlag FINAL

      String_+ = newMethod(
        StringClass, "+", anyparam, stringtype) setFlag FINAL

      val forced = List( // force initialization of every symbol that is entered as a side effect
        AnnotationDefaultAttr, // #2264
        RepeatedParamClass,
        JavaRepeatedParamClass,
        ByNameParamClass,
        AnyClass,
        AnyRefClass,
        AnyValClass,
        NullClass,
        NothingClass,
        SingletonClass,
        EqualsPatternClass,
        Object_isInstanceOf,
        Object_asInstanceOf
      )

      /** Removing the anyref parent they acquire from having a source file.
       */
      setParents(AnyValClass, anyparam)
      ScalaValueClasses foreach { sym =>
        setParents(sym, anyvalparam)
      }

      isInitialized = true
    } //init

    var nbScalaCallers: Int = 0
    def newScalaCaller(delegateType: Type): Symbol = {
      assert(forMSIL, "scalaCallers can only be created if target is .NET")
      // object: reference to object on which to call (scala-)method
      val paramTypes: List[Type] = List(ObjectClass.tpe)
      val name: String =  "$scalaCaller$$" + nbScalaCallers
      // tparam => resultType, which is the resultType of PolyType, i.e. the result type after applying the
      // type parameter =-> a MethodType in this case
      // TODO: set type bounds manually (-> MulticastDelegate), see newTypeParam
      val newCaller = newMethod(DelegateClass, name, paramTypes, delegateType) setFlag (FINAL | STATIC)
      // val newCaller = newPolyMethod(DelegateClass, name,
      // tparam => MethodType(paramTypes, tparam.typeConstructor)) setFlag (FINAL | STATIC)
      Delegate_scalaCallers = Delegate_scalaCallers ::: List(newCaller)
      nbScalaCallers += 1
      newCaller
    }

    // def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol, delType: Type) {
    // assert(Delegate_scalaCallers contains scalaCaller)
    // Delegate_scalaCallerInfos += (scalaCaller -> (methSym, delType))
    // }

    def addScalaCallerInfo(scalaCaller: Symbol, methSym: Symbol) {
      assert(Delegate_scalaCallers contains scalaCaller)
      Delegate_scalaCallerTargets += (scalaCaller -> methSym)
    }
  }
}