typeparser.scala
来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 507 行 · 第 1/2 页
SCALA
507 行
for (cmpName <- ENUM_CMP_NAMES) { val enumCmpType: Type = JavaMethodType(List(clazz.tpe), definitions.BooleanClass.tpe); val enumCmp: Symbol = clazz.newMethod(NoPosition, cmpName); enumCmp.setFlag(flags).setInfo(enumCmpType) instanceDefs.enter(enumCmp); } for (bitLogName <- ENUM_BIT_LOG_NAMES) { val enumBitLogType = JavaMethodType(List(clazz.tpe), classInfo); val enumBitLog = clazz.newMethod(NoPosition, bitLogName); enumBitLog.setFlag(flags).setInfo(enumBitLogType); instanceDefs.enter(enumBitLog); } } } // parseClass private def createMethod(method: MethodBase) { val rettype = if (method.IsConstructor()) clazz.tpe else getCLSType(method.asInstanceOf[MethodInfo].ReturnType); if (rettype == null) return; val mtype = methodType(method, rettype); if (mtype == null) return; val flags = translateAttributes(method); val owner = if (method.IsStatic()) statics else clazz; val methodSym = owner.newMethod(NoPosition, getName(method)).setFlag(flags). setInfo(mtype); (if (method.IsStatic()) staticDefs else instanceDefs).enter(methodSym); if (method.IsConstructor()) clrTypes.constructors(methodSym) = method.asInstanceOf[ConstructorInfo] else clrTypes.methods(methodSym) = method.asInstanceOf[MethodInfo]; } private def createMethod(name: Name, flags: Long, args: Array[MSILType], retType: MSILType, method: MethodInfo, statik: Boolean): Symbol = { val mtype: Type = methodType(args, getCLSType(retType)); assert(mtype != null); createMethod(name, flags, mtype, method, statik) } private def createMethod(name: Name, flags: Long, mtype: Type, method: MethodInfo, statik: Boolean): Symbol = { val methodSym: Symbol = (if (statik) statics else clazz).newMethod(NoPosition, name); methodSym.setFlag(flags).setInfo(mtype); (if (statik) staticDefs else instanceDefs).enter(methodSym); if (method != null) clrTypes.methods(methodSym) = method; methodSym } private def createDelegateView(typ: MSILType) = { val invoke: MethodInfo = typ.GetMember("Invoke")(0).asInstanceOf[MethodInfo]; val invokeRetType: Type = getCLRType(invoke.ReturnType); val invokeParamTypes: List[Type] =invoke.GetParameters().map(_.ParameterType).map(getCLSType).toList; val funType: Type = definitions.functionType(invokeParamTypes, invokeRetType); val typClrType: Type = getCLRType(typ); val flags = Flags.JAVA | Flags.STATIC | Flags.IMPLICIT; // todo: static? think not needed // create the forward view: delegate => function val delegateParamTypes: List[Type] = List(typClrType); // not ImplicitMethodType, this is for methods with implicit parameters (not implicit methods) val forwardViewMethodType = JavaMethodType(delegateParamTypes, funType); val fmsym = createMethod(nme.view_, flags, forwardViewMethodType, null, true); // create the backward view: function => delegate val functionParamTypes: List[Type] = List(funType); val backwardViewMethodType = JavaMethodType(functionParamTypes, typClrType); val bmsym = createMethod(nme.view_, flags, backwardViewMethodType, null, true); } private def createDelegateChainers(typ: MSILType) = { val flags: Long = Flags.JAVA | Flags.FINAL val args: Array[MSILType] = Array(typ) var s = createMethod(encode("+="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_COMBINE, false); s = createMethod(encode("-="), flags, args, clrTypes.VOID, clrTypes.DELEGATE_REMOVE, false); s = createMethod(nme.PLUS, flags, args, typ, clrTypes.DELEGATE_COMBINE, false); s = createMethod(nme.MINUS, flags, args, typ, clrTypes.DELEGATE_REMOVE, false); } private def getName(method: MethodBase): Name = { if (method.IsConstructor()) return nme.CONSTRUCTOR; val name = method.Name; if (method.IsStatic()) return newTermName(name); val params = method.GetParameters(); name match { case "GetHashCode" if (params.length == 0) => nme.hashCode_; case "ToString" if (params.length == 0) => nme.toString_; case "Finalize" if (params.length == 0) => nme.finalize_; case "Equals" if (params.length == 1 && params(0).ParameterType == clrTypes.OBJECT) => nme.equals_; case "Invoke" if (clrTypes.isDelegateType(method.DeclaringType)) => nme.apply; case _ => newTermName(name); } } //########################################################################## private def methodType(method: MethodBase, rettype: MSILType): Type = { val rtype = getCLSType(rettype); if (rtype == null) null else methodType(method, rtype); } /** Return a method type for the given method. */ private def methodType(method: MethodBase, rettype: Type): Type = methodType(method.GetParameters().map(_.ParameterType), rettype); /** Return a method type for the provided argument types and return type. */ private def methodType(argtypes: Array[MSILType], rettype: Type): Type = { def paramType(typ: MSILType): Type = if (typ eq clrTypes.OBJECT) definitions.AnyClass.tpe else getCLSType(typ); val ptypes = argtypes.map(paramType).toList; if (ptypes.contains(null)) null else JavaMethodType(ptypes, rettype); } //########################################################################## private def getClassType(typ: MSILType): Type = { assert(typ != null); val res = definitions.getClass(typ.FullName.replace('+', '.')).tpe; //if (res.isError()) // global.reporter.error("unknown class reference " + type.FullName); res } private def getCLSType(typ: MSILType): Type = { if (/*type == clrTypes.BYTE ||*/ typ == clrTypes.USHORT || typ == clrTypes.UINT || typ == clrTypes.ULONG || typ.IsNotPublic() || typ.IsNestedPrivate() || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem() || typ.IsPointer() || (typ.IsArray() && getCLSType(typ.GetElementType()) == null)) null; //Symbol s = clrTypes.getSymbol(type); //scalac.symtab.Type t = s != null ? make.classType(s) : getCLRType(type); else getCLRType(typ) } private def getCLRType(typ: MSILType): Type = if (typ == clrTypes.OBJECT) definitions.ObjectClass.tpe; else if (typ == clrTypes.VALUE_TYPE) definitions.AnyValClass.tpe else if (typ == clrTypes.STRING) definitions.StringClass.tpe; else if (typ == clrTypes.VOID) definitions.UnitClass.tpe else if (typ == clrTypes.BOOLEAN) definitions.BooleanClass.tpe else if (typ == clrTypes.CHAR) definitions.CharClass.tpe else if (typ == clrTypes.BYTE || typ == clrTypes.UBYTE) definitions.ByteClass.tpe else if (typ == clrTypes.SHORT || typ == clrTypes.USHORT) definitions.ShortClass.tpe else if (typ == clrTypes.INT || typ == clrTypes.UINT) definitions.IntClass.tpe else if (typ == clrTypes.LONG || typ == clrTypes.ULONG) definitions.LongClass.tpe else if (typ == clrTypes.FLOAT) definitions.FloatClass.tpe else if (typ == clrTypes.DOUBLE) definitions.DoubleClass.tpe else if (typ.IsArray()) appliedType(definitions.ArrayClass.tpe, List(getCLRType(typ.GetElementType()))); else { val res = clrTypes.sym2type.get (typ) match { case Some(sym) => sym.tpe case None => getClassType(typ); } assert (res != null, typ) res } // the values are Java-Box-Classes (e.g. Integer, Boolean, Character) // java.lang.Number to get the value (if a number, not for boolean, character) // see ch.epfl.lamp.compiler.msil.util.PEStream.java def getConstant(constType: Type, value: Object): Constant = { val typeClass = constType.typeSymbol if (typeClass == definitions.BooleanClass) Constant(value.asInstanceOf[java.lang.Boolean].booleanValue) else if (typeClass == definitions.ByteClass) Constant(value.asInstanceOf[java.lang.Number].byteValue) else if (typeClass == definitions.ShortClass) Constant(value.asInstanceOf[java.lang.Number].shortValue) else if (typeClass == definitions.CharClass) Constant(value.asInstanceOf[java.lang.Character].charValue) else if (typeClass == definitions.IntClass) Constant(value.asInstanceOf[java.lang.Number].intValue) else if (typeClass == definitions.LongClass) Constant(value.asInstanceOf[java.lang.Number].longValue) else if (typeClass == definitions.FloatClass) Constant(value.asInstanceOf[java.lang.Number].floatValue) else if (typeClass == definitions.DoubleClass) Constant(value.asInstanceOf[java.lang.Number].doubleValue) else if (typeClass == definitions.StringClass) Constant(value.asInstanceOf[java.lang.String]) else abort("illegal value: " + value + ", class-symbol: " + typeClass) } private def translateAttributes(typ: MSILType): Long = { var flags: Long = Flags.JAVA; if (typ.IsNotPublic() || typ.IsNestedPrivate() || typ.IsNestedAssembly() || typ.IsNestedFamANDAssem()) flags = flags | Flags.PRIVATE; else if (typ.IsNestedFamily() || typ.IsNestedFamORAssem()) flags = flags | Flags.PROTECTED; if (typ.IsAbstract()) flags = flags | Flags.ABSTRACT; if (typ.IsSealed()) flags = flags | Flags.FINAL; if (typ.IsInterface()) flags = flags | Flags.INTERFACE | Flags.TRAIT | Flags.ABSTRACT; flags } private def translateAttributes(field: FieldInfo): Long = { var flags: Long = Flags.JAVA; if (field.IsPrivate() || field.IsAssembly() || field.IsFamilyAndAssembly()) flags = flags | Flags.PRIVATE; else if (field.IsFamily() || field.IsFamilyOrAssembly()) flags = flags | Flags.PROTECTED; if (field.IsInitOnly()) flags = flags | Flags.FINAL; else flags = flags | Flags.MUTABLE; if (field.IsStatic) flags = flags | Flags.STATIC flags } private def translateAttributes(method: MethodBase): Long = { var flags: Long = Flags.JAVA; if (method.IsPrivate() || method.IsAssembly() || method.IsFamilyAndAssembly()) flags = flags | Flags.PRIVATE; else if (method.IsFamily() || method.IsFamilyOrAssembly()) flags = flags | Flags.PROTECTED; if (method.IsAbstract()) flags = flags | Flags.DEFERRED; if (method.IsStatic) flags = flags | Flags.STATIC flags }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?