summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
blob: 40189b9444dce7a490300a40e07f87c3283c813d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/* NSC -- new scala compiler
 * Copyright 2004-2013 LAMP/EPFL
 */


package scala.tools.nsc
package symtab
package clr

import java.io.File
import java.util.{Comparator, StringTokenizer}
import scala.util.Sorting
import ch.epfl.lamp.compiler.msil._
import scala.collection.{ mutable, immutable }
import scala.reflect.internal.util.{Position, NoPosition}

/**
 * Collects all types from all reference assemblies.
 */
abstract class CLRTypes {

  val global: Global
  import global.Symbol
  import global.definitions

  //##########################################################################

  var BYTE: Type = _
  var UBYTE: Type = _
  var SHORT: Type = _
  var USHORT: Type = _
  var CHAR: Type = _
  var INT: Type = _
  var UINT: Type = _
  var LONG: Type = _
  var ULONG: Type = _
  var FLOAT: Type = _
  var DOUBLE: Type = _
  var BOOLEAN: Type = _
  var VOID: Type = _
  var ENUM: Type = _
  var DELEGATE: Type = _

  var OBJECT: Type = _
  var STRING: Type = _
  var STRING_ARRAY: Type = _

  var VALUE_TYPE: Type = _

  var SCALA_SYMTAB_ATTR: Type = _
  var SYMTAB_CONSTR: ConstructorInfo = _
  var SYMTAB_DEFAULT_CONSTR: ConstructorInfo = _

  var DELEGATE_COMBINE: MethodInfo = _
  var DELEGATE_REMOVE: MethodInfo = _

  val types: mutable.Map[Symbol,Type] = new mutable.HashMap
  val constructors: mutable.Map[Symbol,ConstructorInfo] = new mutable.HashMap
  val methods: mutable.Map[Symbol,MethodInfo] = new mutable.HashMap
  val fields: mutable.Map[Symbol, FieldInfo] = new mutable.HashMap
  val sym2type: mutable.Map[Type,Symbol] = new mutable.HashMap
  val addressOfViews = new mutable.HashSet[Symbol]
  val mdgptrcls4clssym: mutable.Map[ /*cls*/ Symbol, /*cls*/ Symbol] = new mutable.HashMap

  def isAddressOf(msym : Symbol) = addressOfViews.contains(msym)

  def isNonEnumValuetype(cls: Symbol) = {
    val msilTOpt = types.get(cls)
    val res = msilTOpt.isDefined && {
      val msilT = msilTOpt.get
      msilT.IsValueType && !msilT.IsEnum
    }
    res
  }

  def isValueType(cls: Symbol): Boolean = {
    val opt = types.get(cls)
    opt.isDefined && opt.get.IsValueType
  }

  def init() = try { // initialize
    // the MsilClasspath (nsc/util/Classpath.scala) initializes the msil-library by calling
    // Assembly.LoadFrom("mscorlib.dll"), so this type should be found
    Type.initMSCORLIB(getTypeSafe("System.String").Assembly)

    BYTE     = getTypeSafe("System.SByte")
    UBYTE    = getTypeSafe("System.Byte")
    CHAR     = getTypeSafe("System.Char")
    SHORT    = getTypeSafe("System.Int16")
    USHORT   = getTypeSafe("System.UInt16")
    INT      = getTypeSafe("System.Int32")
    UINT     = getTypeSafe("System.UInt32")
    LONG     = getTypeSafe("System.Int64")
    ULONG    = getTypeSafe("System.UInt64")
    FLOAT    = getTypeSafe("System.Single")
    DOUBLE   = getTypeSafe("System.Double")
    BOOLEAN  = getTypeSafe("System.Boolean")
    VOID     = getTypeSafe("System.Void")
    ENUM     = getTypeSafe("System.Enum")
    DELEGATE = getTypeSafe("System.MulticastDelegate")

    OBJECT = getTypeSafe("System.Object")
    STRING = getTypeSafe("System.String")
    STRING_ARRAY = getTypeSafe("System.String[]")
    VALUE_TYPE = getTypeSafe("System.ValueType")

    SCALA_SYMTAB_ATTR = getTypeSafe("scala.runtime.SymtabAttribute")
    val bytearray: Array[Type] = Array(Type.GetType("System.Byte[]"))
    SYMTAB_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(bytearray)
    SYMTAB_DEFAULT_CONSTR = SCALA_SYMTAB_ATTR.GetConstructor(Type.EmptyTypes)

    val delegate: Type = getTypeSafe("System.Delegate")
    val dargs: Array[Type] = Array(delegate, delegate)
    DELEGATE_COMBINE = delegate.GetMethod("Combine", dargs)
    DELEGATE_REMOVE = delegate.GetMethod("Remove", dargs)
  }
  catch {
    case e: RuntimeException =>
      Console.println(e.getMessage)
      throw e
  }

  //##########################################################################
  // type mapping and lookup

  def getType(name: String): Type = Type.GetType(name)

  def getTypeSafe(name: String): Type = {
    val t = Type.GetType(name)
    assert(t != null, name)
    t
  }

  def mkArrayType(elemType: Type): Type = getType(elemType.FullName + "[]")

  def isDelegateType(t: Type): Boolean = { t.BaseType() == DELEGATE }
}  // CLRTypes