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 + -
显示快捷键?