summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/clr/CLRTypes.scala
blob: cf1f7f1db39c433207d6cf1ba8d881f400217d46 (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
138
139
/* NSC -- new scala compiler
 * Copyright 2004-2011 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.{ListBuffer, Map, HashMap, Set, HashSet}
import scala.tools.nsc.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: Map[Symbol,Type] = new HashMap
  val constructors: Map[Symbol,ConstructorInfo] = new HashMap
  val methods: Map[Symbol,MethodInfo] = new HashMap
  val fields: Map[Symbol, FieldInfo] = new HashMap
  val sym2type: Map[Type,Symbol] = new HashMap
  val addressOfViews: HashSet[Symbol] = new HashSet[Symbol]
  val mdgptrcls4clssym: Map[ /*cls*/ Symbol, /*cls*/ Symbol] = new 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