diff options
author | Martin Odersky <odersky@gmail.com> | 2011-07-21 10:13:43 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-07-21 10:13:43 +0000 |
commit | dde17e953fb9ecc7f28fd0b7fe712c36382afaac (patch) | |
tree | 666da29faead5dd971db037475d8fae06aecf308 /src | |
parent | 48d2c7814465ec6ce4139e49269947c6d38f023b (diff) | |
download | scala-dde17e953fb9ecc7f28fd0b7fe712c36382afaac.tar.gz scala-dde17e953fb9ecc7f28fd0b7fe712c36382afaac.tar.bz2 scala-dde17e953fb9ecc7f28fd0b7fe712c36382afaac.zip |
Fleshed out Scala -> Java mapping; dealing with...
Fleshed out Scala -> Java mapping; dealing with arrays. No review.
Diffstat (limited to 'src')
4 files changed, 62 insertions, 11 deletions
diff --git a/src/compiler/scala/reflect/internal/transform/Transforms.scala b/src/compiler/scala/reflect/internal/transform/Transforms.scala index 8ed40dc55c..c2f3dc6092 100644 --- a/src/compiler/scala/reflect/internal/transform/Transforms.scala +++ b/src/compiler/scala/reflect/internal/transform/Transforms.scala @@ -8,7 +8,7 @@ trait Transforms { self: SymbolTable => object uncurry extends { val global: Transforms.this.type = self } with UnCurry object erasure extends { val global: Transforms.this.type = self } with Erasure - def javaType(sym: Symbol) = + def transformedType(sym: Symbol) = erasure.transformInfo(sym, uncurry.transformInfo(sym, refChecks.transformInfo(sym, sym.info))) diff --git a/src/compiler/scala/reflect/runtime/ConversionUtil.scala b/src/compiler/scala/reflect/runtime/ConversionUtil.scala index 4cebcb8ed6..47e57a2173 100644 --- a/src/compiler/scala/reflect/runtime/ConversionUtil.scala +++ b/src/compiler/scala/reflect/runtime/ConversionUtil.scala @@ -63,7 +63,7 @@ trait ConversionUtil extends internal.transform.Transforms { self: Universe => * all Scala-specific transformations in InfoTransformers. (to be done) */ protected def erasesTo(meth: Symbol, jmeth: jMethod): Boolean = { - val mtpe = javaType(meth) + val mtpe = transformedType(meth) (mtpe.paramTypes map typeToJavaClass) == jmeth.getParameterTypes.toList && typeToJavaClass(mtpe.resultType) == jmeth.getReturnType } @@ -73,7 +73,7 @@ trait ConversionUtil extends internal.transform.Transforms { self: Universe => * all Scala-specific transformations in InfoTransformers. (to be done) */ protected def erasesTo(meth: Symbol, jconstr: jConstructor[_]): Boolean = { - val mtpe = javaType(meth) + val mtpe = transformedType(meth) (mtpe.paramTypes map typeToJavaClass) == jconstr.getParameterTypes.toList } }
\ No newline at end of file diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala index 833b42529d..7d4eb8309f 100644 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ b/src/compiler/scala/reflect/runtime/JavaToScala.scala @@ -288,8 +288,11 @@ trait JavaToScala extends ConversionUtil { self: Universe => case java.lang.Double.TYPE => DoubleClass.tpe case java.lang.Boolean.TYPE => BooleanClass.tpe case jclazz: jClass[_] => - val clazz = classToScala(jclazz) - rawToExistential(typeRef(clazz.owner.thisType, clazz, List())) + if (jclazz.isArray) arrayType(typeToScala(jclazz.getComponentType)) + else { + val clazz = classToScala(jclazz) + rawToExistential(typeRef(clazz.owner.thisType, clazz, List())) + } case japplied: ParameterizedType => val (pre, sym) = typeToScala(japplied.getRawType) match { case ExistentialType(tparams, TypeRef(pre, sym, _)) => (pre, sym) diff --git a/src/compiler/scala/reflect/runtime/ScalaToJava.scala b/src/compiler/scala/reflect/runtime/ScalaToJava.scala index 7682566bf4..e9b5b96bc8 100644 --- a/src/compiler/scala/reflect/runtime/ScalaToJava.scala +++ b/src/compiler/scala/reflect/runtime/ScalaToJava.scala @@ -4,10 +4,12 @@ package runtime import java.lang.{Class => jClass, Package => jPackage} import java.lang.reflect.{ Method => jMethod, Constructor => jConstructor, Modifier => jModifier, Field => jField, - Member => jMember, Type => jType, GenericDeclaration} + Member => jMember, Type => jType, Array => jArray, GenericDeclaration} trait ScalaToJava extends ConversionUtil { self: Universe => + import definitions._ + /** Optionally, the Java package corresponding to a given Scala package, or None if no such Java package exists. * @param pkg The Scala package */ @@ -35,12 +37,58 @@ trait ScalaToJava extends ConversionUtil { self: Universe => noClass } - def fieldToJava(fld: Symbol): jField = null // to be done - def methodToJava(meth: Symbol): jMethod = null // to be done - def constrToJava(constr: Symbol): jConstructor[_] = null // to be done + private def expandedName(sym: Symbol): String = + if (sym.isPrivate) nme.expandedName(sym.name, sym.owner).toString + else sym.name.toString + + def fieldToJava(fld: Symbol): jField = fieldCache.toJava(fld) { + val jclazz = classToJava(fld.owner) + try jclazz getDeclaredField fld.name.toString + catch { + case ex: NoSuchFieldException => jclazz getDeclaredField expandedName(fld) + } + } + + def methodToJava(meth: Symbol): jMethod = methodCache.toJava(meth) { + val jclazz = classToJava(meth.owner) + val paramClasses = transformedType(meth).paramTypes map typeToJavaClass + try jclazz getDeclaredMethod (meth.name.toString, paramClasses: _*) + catch { + case ex: NoSuchMethodException => + jclazz getDeclaredMethod (expandedName(meth), paramClasses: _*) + } + } - /** The Java class corresponds to given Scala type (to be done) + def constrToJava(constr: Symbol): jConstructor[_] = constructorCache.toJava(constr) { + val jclazz = classToJava(constr.owner) + val paramClasses = transformedType(constr).paramTypes map typeToJavaClass + jclazz getConstructor (paramClasses: _*) + } + + private def jArrayClass(elemClazz: jClass[_]): jClass[_] = { + jArray.newInstance(elemClazz, 0).getClass + } + + /** The Java class that corresponds to given Scala type. + * Pre: Scala type is already transformed to Java level. */ - def typeToJavaClass(tpe: Type): jClass[_] = null + def typeToJavaClass(tpe: Type): jClass[_] = tpe match { + case ExistentialType(_, rtpe) => typeToJavaClass(rtpe) + case TypeRef(_, ArrayClass, List(elemtpe)) => jArrayClass(typeToJavaClass(elemtpe)) + case TypeRef(_, sym, _) => typeSymToJavaClass(sym) + case _ => throw new NoClassDefFoundError("no Java class corresponding to "+tpe+" found") + } + private def typeSymToJavaClass(sym: Symbol): jClass[_] = sym match { + case UnitClass => java.lang.Void.TYPE + case ByteClass => java.lang.Byte.TYPE + case CharClass => java.lang.Character.TYPE + case ShortClass => java.lang.Short.TYPE + case IntClass => java.lang.Integer.TYPE + case LongClass => java.lang.Long.TYPE + case FloatClass => java.lang.Float.TYPE + case DoubleClass => java.lang.Double.TYPE + case BooleanClass => java.lang.Boolean.TYPE + case _ => jClass.forName(sym.fullName) + } }
\ No newline at end of file |