typeparser.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 507 行 · 第 1/2 页

SCALA
507
字号
/* NSC -- new scala compiler * Copyright 2004-2007 LAMP/EPFL */// $Id: TypeParser.scala 13629 2007-12-24 14:09:25Z mcdirmid $package scala.tools.nsc.symtab.clrimport java.io.IOExceptionimport ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute, _}import scala.collection.mutable.{HashMap, HashSet}import scala.tools.nsc.util.{Position, NoPosition}import classfile.UnPickler/** *  @author Nikolay Mihaylov */abstract class TypeParser {  val global: Global  import global.loaders.clrTypes  import clrTypes.global._  //##########################################################################  private var clazz: Symbol = _  private var instanceDefs: Scope = _   // was members  private var staticModule: Symbol = _  // was staticsClass  private var staticDefs: Scope = _     // was statics  protected def statics: Symbol = staticModule.moduleClass  protected var busy: Boolean = false       // lock to detect recursive reads  private object unpickler extends UnPickler {    val global: TypeParser.this.global.type = TypeParser.this.global  }  def parse(typ: MSILType, root: Symbol) {    def handleError(e: Exception) = {      if (settings.debug.value) e.printStackTrace()  //debug      throw new IOException("type '" + typ.FullName + "' is broken\n(" + e.getMessage() + ")")    }    assert(!busy)    busy = true    if (root.isModule) {      this.clazz = root.linkedClassOfModule      this.staticModule = root    } else {      this.clazz = root      this.staticModule = root.linkedModuleOfClass    }    try {      parseClass(typ)    } catch {      case e: FatalError => handleError(e)      case e: RuntimeException => handleError(e)    }    busy = false  }  private def parseClass(typ: MSILType) {    clrTypes.types(clazz) = typ    clrTypes.sym2type(typ) = clazz    if (typ.IsDefined(clrTypes.SCALA_SYMTAB_ATTR, false)) {      val attrs = typ.GetCustomAttributes(clrTypes.SCALA_SYMTAB_ATTR, false);      assert (attrs.length == 1, attrs.length);      val a = attrs(0).asInstanceOf[MSILAttribute];      assert (a.getConstructor() == clrTypes.SYMTAB_CONSTR);      val symtab = a.getConstructorArguments()(0).asInstanceOf[Array[Byte]]      unpickler.unpickle(symtab, 0, clazz.asInstanceOf[unpickler.global.Symbol],                                     staticModule.asInstanceOf[unpickler.global.Symbol], typ.FullName);      val mClass = clrTypes.getType(typ.FullName + "$");      if (mClass != null) {        clrTypes.types(statics) = mClass;        val moduleInstance = mClass.GetField("MODULE$");        assert (moduleInstance != null, mClass);        clrTypes.fields(statics) = moduleInstance;      }      return    }    val flags = translateAttributes(typ)    val ifaces: Array[MSILType] = typ.getInterfaces()    val superType = if (typ.BaseType() != null) getCLRType(typ.BaseType())                    else  if (typ.IsInterface()) definitions.ObjectClass.tpe                    else definitions.AnyClass.tpe; // this is System.Object    val parents = superType :: ifaces.map(getCLRType).toList    instanceDefs = newClassScope(clazz)    staticDefs = newClassScope(staticModule)    val classInfo = ClassInfoType(parents, instanceDefs, clazz)    val staticInfo = ClassInfoType(List(), staticDefs, statics)    clazz.setFlag(flags)    clazz.setInfo(classInfo)    statics.setFlag(Flags.JAVA)    statics.setInfo(staticInfo)    staticModule.setFlag(Flags.JAVA)    staticModule.setInfo(statics.tpe)    // import nested types    for (ntype <- typ.getNestedTypes() if !(ntype.IsNestedPrivate				            || ntype.IsNestedAssembly				            || ntype.IsNestedFamANDAssem)				          || ntype.IsInterface)      {	val loader = new global.loaders.MSILTypeLoader(ntype)	val nclazz = statics.newClass(NoPosition, ntype.Name.toTypeName)	val nmodule = statics.newModule(NoPosition, ntype.Name)	nclazz.setInfo(loader)	nmodule.setInfo(loader)	staticDefs.enter(nclazz)	staticDefs.enter(nmodule)	assert(nclazz.linkedModuleOfClass == nmodule, nmodule)	assert(nmodule.linkedClassOfModule == nclazz, nclazz)      }    val fields = typ.getFields()    for (field <- fields if !(field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly)) {      val flags = translateAttributes(field);      val name = newTermName(field.Name);      val fieldType =        if (field.IsLiteral && !field.FieldType.IsEnum)	  ConstantType(getConstant(getCLRType(field.FieldType), field.getValue))	else getCLRType(field.FieldType);      val owner = if (field.IsStatic()) statics else clazz;      val sym = owner.newValue(NoPosition, name).setFlag(flags).setInfo(fieldType);        // TODO: set private within!!! -> look at typechecker/Namers.scala        (if (field.IsStatic()) staticDefs else instanceDefs).enter(sym);      clrTypes.fields(sym) = field;    }    for (constr <- typ.getConstructors() if !constr.IsStatic() && !constr.IsPrivate() &&         !constr.IsAssembly() && !constr.IsFamilyAndAssembly())      createMethod(constr);    // initially also contains getters an setters of properties.    val methodsSet = new HashSet[MethodInfo]();    methodsSet ++= typ.getMethods();    for (prop <- typ.getProperties) {      val propType: Type = getCLSType(prop.PropertyType);      if (propType != null) {	val getter: MethodInfo = prop.GetGetMethod(true);	val setter: MethodInfo = prop.GetSetMethod(true);	var gparamsLength: Int = -1;	if (!(getter == null || getter.IsPrivate || getter.IsAssembly	      || getter.IsFamilyAndAssembly))	  {	    assert(prop.PropertyType == getter.ReturnType);	    val gparams: Array[ParameterInfo] = getter.GetParameters();	    gparamsLength = gparams.length;	    val name: Name = if (gparamsLength == 0) prop.Name else nme.apply;	    val flags = translateAttributes(getter);	    val mtype: Type = if (gparamsLength == 0) PolyType(List(), propType)                              else methodType(getter, getter.ReturnType);	    val owner: Symbol = if (getter.IsStatic) statics else clazz;	    val methodSym = owner.newMethod(NoPosition, name).setFlag(flags).setInfo(mtype);	    methodSym.setFlag(Flags.ACCESSOR);	    (if (getter.IsStatic) staticDefs else instanceDefs).enter(methodSym)	    clrTypes.methods(methodSym) = getter;	    methodsSet -= getter;	  }	if (!(setter == null || setter.IsPrivate || setter.IsAssembly	     || setter.IsFamilyAndAssembly))	  {	    val sparams: Array[ParameterInfo] = setter.GetParameters()	    if(getter != null)	      assert(getter.IsStatic == setter.IsStatic);	    assert(setter.ReturnType == clrTypes.VOID);	    if(getter != null)	      assert(sparams.length == gparamsLength + 1, "" + getter + "; " + setter);	    val name: Name = if (gparamsLength == 0) nme.getterToSetter(prop.Name)			     else nme.update;	    val flags = translateAttributes(setter);	    val mtype: Type = methodType(setter, definitions.UnitClass.tpe);	    val owner: Symbol = if (setter.IsStatic) statics else clazz;	    val methodSym = owner.newMethod(NoPosition, name).setFlag(flags).setInfo(mtype);	    methodSym.setFlag(Flags.ACCESSOR);	    (if (setter.IsStatic) staticDefs else instanceDefs).enter(methodSym);	    clrTypes.methods(methodSym) = setter;	    methodsSet -= setter;	  }      }    }/*    for (event <- typ.GetEvents) {      // adding += and -= methods to add delegates to an event.      // raising the event ist not possible from outside the class (this is so      // generally in .net world)      val adder: MethodInfo = event.GetAddMethod();      val remover: MethodInfo = event.GetRemoveMethod();      if (!(adder == null || adder.IsPrivate || adder.IsAssembly	    || adder.IsFamilyAndAssembly))	{	  assert(adder.ReturnType == clrTypes.VOID);	  assert(adder.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));	  val name = encode("+=");	  val flags = translateAttributes(adder);	  val mtype: Type = methodType(adder, adder.ReturnType);	  createMethod(name, flags, mtype, adder, adder.IsStatic)	  methodsSet -= adder;	}      if (!(remover == null || remover.IsPrivate || remover.IsAssembly	    || remover.IsFamilyAndAssembly))	{	  assert(remover.ReturnType == clrTypes.VOID);	  assert(remover.GetParameters().map(_.ParameterType).toList == List(event.EventHandlerType));	  val name = encode("-=");	  val flags = translateAttributes(remover);	  val mtype: Type = methodType(remover, remover.ReturnType);	  createMethod(name, flags, mtype, remover, remover.IsStatic)	  methodsSet -= remover;	}    } */    for (method <- methodsSet.elements)      if (!method.IsPrivate() && !method.IsAssembly() && !method.IsFamilyAndAssembly())        createMethod(method);    // Create methods and views for delegate support    if (clrTypes.isDelegateType(typ)) {      createDelegateView(typ)      createDelegateChainers(typ)    }    // create the box/unbox methods for value types    if (typ.IsValueType) {      val box = statics.newMethod(NoPosition, nme.box).        setInfo(MethodType(List(clazz.tpe), definitions.ObjectClass.tpe));      definitions.boxMethod(clazz) = box;      val unbox = statics.newMethod(NoPosition, nme.unbox).        setInfo(MethodType(List(definitions.ObjectClass.tpe), clazz.tpe));      definitions.unboxMethod(clazz) = unbox;      //Console.println(typ.FullName + " : " + parents);    }    // for enumerations introduce comparison and bitwise logical operations;    // the backend should recognize and replace them with comparison or    // bitwise logical operations on the primitive underlying type    if (typ.IsEnum) {      val ENUM_CMP_NAMES = List(nme.EQ, nme.NE, nme.LT, nme.LE, nme.GT, nme.GE);      val ENUM_BIT_LOG_NAMES = List(nme.OR, nme.AND, nme.XOR);      val flags = Flags.JAVA | Flags.FINAL

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?