diff options
Diffstat (limited to 'src/compiler/scala/reflect/runtime/JavaToScala.scala')
-rw-r--r-- | src/compiler/scala/reflect/runtime/JavaToScala.scala | 697 |
1 files changed, 0 insertions, 697 deletions
diff --git a/src/compiler/scala/reflect/runtime/JavaToScala.scala b/src/compiler/scala/reflect/runtime/JavaToScala.scala deleted file mode 100644 index e11f6140c9..0000000000 --- a/src/compiler/scala/reflect/runtime/JavaToScala.scala +++ /dev/null @@ -1,697 +0,0 @@ -package scala.reflect -package runtime - -import java.lang.{ Class => jClass, Package => jPackage, ClassLoader => JClassLoader } -import java.io.IOException -import java.lang.reflect.{ - Method => jMethod, - Constructor => jConstructor, - Modifier => jModifier, - Field => jField, - Member => jMember, - Type => jType, - TypeVariable => jTypeVariable, - GenericDeclaration, - GenericArrayType, - ParameterizedType, - WildcardType, - AnnotatedElement -} -import internal.MissingRequirementError -import internal.pickling.ByteCodecs -import internal.ClassfileConstants._ -import internal.pickling.UnPickler -import collection.mutable.{ HashMap, ListBuffer } -import internal.Flags._ -import scala.tools.nsc.util.ScalaClassLoader -import scala.tools.nsc.util.ScalaClassLoader._ - -trait JavaToScala extends ConversionUtil { self: SymbolTable => - - import definitions._ - - private object unpickler extends UnPickler { - val global: JavaToScala.this.type = self - } - - /** Defines the classloader that will be used for all class resolution activities in this mirror. - * Is mutable, since sometimes we need to change it in flight (e.g. to make the default mirror work with REPL). - * - * If you want to have a mirror with non-standard class resolution, override this var - * (or, even simpler, use the `mkMirror` function from `scala.reflect` package) - * - * Be careful, though, since fancy stuff might happen. - * Here's one example: - * - * partest uses a URLClassLoader(urls, null) with custom classpath to run workers (in separate threads) - * however it doesn't set the context classloader for them, so they inherit the system classloader - * http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html - * - * Once upon a time, scala.reflect.mirror was loaded using getClass.getClassLoader, - * which also means that classOf[...] constructs such as: - * - * classOf[scala.reflect.ScalaSignature] - * - * in unpickleClass were also loaded by the URLClassLoader - * - * But mirror's classLoader used Thread.currentThread.getContextClassLoader, - * which introduced a subtle bug that made the following snippet incorrectly: - * - * jclazz.getAnnotation(classOf[scala.reflect.ScalaSignature]) - * - * Indeed, jclazz was loaded by context classloader, which defaulted to system classloader, - * while ScalaSignature class was loaded by getClass.getClassLoader, which was incompatible with system classloader. - * As a result, unpickler couldn't see the signature and that blew up the mirror. - */ - var classLoader: ClassLoader - - /** Paul: It seems the default class loader does not pick up root classes, whereas the system classloader does. - * Can you check with your newly acquired classloader fu whether this implementation makes sense? - */ - def javaClass(path: String): jClass[_] = - javaClass(path, classLoader) - def javaClass(path: String, classLoader: JClassLoader): jClass[_] = - Class.forName(path, true, classLoader) - - /** Does `path` correspond to a Java class with that fully qualified name? */ - def isJavaClass(path: String): Boolean = - try { - javaClass(path) - true - } catch { - case (_: ClassNotFoundException) | (_: NoClassDefFoundError) | (_: IncompatibleClassChangeError) => - false - } - - /** - * Generate types for top-level Scala root class and root companion object - * from the pickled information stored in a corresponding Java class - * @param clazz The top-level Scala class for which info is unpickled - * @param module The top-level Scala companion object for which info is unpickled - * @param jclazz The Java class which contains the unpickled information in a - * ScalaSignature or ScalaLongSignature annotation. - */ - def unpickleClass(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = { - def markAbsent(tpe: Type) = setAllInfos(clazz, module, tpe) - def handleError(ex: Exception) = { - markAbsent(ErrorType) - if (settings.debug.value) ex.printStackTrace() - val msg = ex.getMessage() - MissingRequirementError.signal( - (if (msg eq null) "reflection error while loading " + clazz.name - else "error while loading " + clazz.name) + ", " + msg) - } - // don't use classOf[scala.reflect.ScalaSignature] here, because it will use getClass.getClassLoader, not mirror's classLoader - // don't use asInstanceOf either because of the same reason (lol, I cannot believe I fell for it) - // don't use structural types to simplify reflective invocations because of the same reason - // todo. test for this - def loadAnnotation(name: String): java.lang.annotation.Annotation = { - def inferClasspath(cl: ClassLoader) = cl match { - case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" - case _ => "<unknown>" - } - def show(cl: ClassLoader) = cl match { - case cl if cl != null => - "%s of type %s with classpath %s".format(cl, cl.getClass, inferClasspath(cl)) - case null => - import scala.tools.util.PathResolver.Environment._ - "primordial classloader with boot classpath [%s]".format(javaBootClassPath) - } - - try { - val cls_ann = Class.forName(name, true, classLoader) - val anns = jclazz.getAnnotations - val ann = anns find (_.annotationType == cls_ann) orNull; - if (ann == null && anns.find(_.annotationType.getName == name).isDefined) { - val msg = "Mirror classloader mismatch: %s (loaded by %s)%nis unrelated to the mirror's classloader (%s)" - throw new Error(msg.format(jclazz, show(jclazz.getClassLoader), show(classLoader))) - } - ann - } catch { - case ex: ClassNotFoundException => - val msg = "Dysfunctional mirror classloader, cannot load %s: %s." - throw new Error(msg.format(name, show(classLoader)), ex) - } - } - def loadScalaSignature: Option[String] = { - val ssig = loadAnnotation("scala.reflect.ScalaSignature") - if (ssig != null) { - val bytesMethod = ssig.annotationType.getMethod("bytes") - val result = bytesMethod.invoke(ssig) - Some(result.asInstanceOf[String]) - } else { - None - } - } - def loadScalaLongSignature: Option[Array[String]] = { - val slsig = loadAnnotation("scala.reflect.ScalaLongSignature") - if (slsig != null) { - val bytesMethod = slsig.annotationType.getMethod("bytes") - val result = bytesMethod.invoke(slsig) - Some(result.asInstanceOf[Array[String]]) - } else { - None - } - } - try { - markAbsent(NoType) - val sigs = (loadScalaSignature, loadScalaLongSignature) - sigs match { - case (Some(ssig), _) => - info("unpickling Scala "+clazz + " and " + module+ ", owner = " + clazz.owner) - val bytes = ssig.getBytes - val len = ByteCodecs.decode(bytes) - unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName) - case (_, Some(slsig)) => - info("unpickling Scala "+clazz + " and " + module + " with long Scala signature") - val byteSegments = slsig map (_.getBytes) - val lens = byteSegments map ByteCodecs.decode - val bytes = Array.ofDim[Byte](lens.sum) - var len = 0 - for ((bs, l) <- byteSegments zip lens) { - bs.copyToArray(bytes, len, l) - len += l - } - unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName) - case (None, None) => - // class does not have a Scala signature; it's a Java class - info("translating reflection info for Java " + jclazz) //debug - initClassModule(clazz, module, new FromJavaClassCompleter(clazz, module, jclazz)) - } - } catch { - case ex: MissingRequirementError => - handleError(ex) - case ex: IOException => - handleError(ex) - } - } - - /** - * A fresh Scala type parameter that corresponds to a Java type variable. - * The association between Scala type parameter and Java type variable is entered in the cache. - * @param jtvar The Java type variable - */ - private def createTypeParameter(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol = { - val tparam = sOwner(jtvar).newTypeParameter(newTypeName(jtvar.getName)) - .setInfo(new TypeParamCompleter(jtvar)) - tparamCache enter (jtvar, tparam) - tparam - } - - /** - * A completer that fills in the type of a Scala type parameter from the bounds of a Java type variable. - * @param jtvar The Java type variable - */ - private class TypeParamCompleter(jtvar: jTypeVariable[_ <: GenericDeclaration]) extends LazyType { - override def load(sym: Symbol) = complete(sym) - override def complete(sym: Symbol) = { - sym setInfo TypeBounds.upper(glb(jtvar.getBounds.toList map typeToScala map objToAny)) - } - } - - /** - * Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`. - * Pre: `sym` is already initialized with a concrete type. - * Note: If `sym` is a method or constructor, its parameter annotations are copied as well. - */ - private def copyAnnotations(sym: Symbol, jann: AnnotatedElement) { - // to do: implement - } - - /** - * A completer that fills in the types of a Scala class and its companion object - * by copying corresponding type info from a Java class. This completer is used - * to reflect classes in Scala that do not have a Scala pickle info, be it - * because they are local classes or have been compiled from Java sources. - * @param clazz The Scala class for which info is copied - * @param module The Scala companion object for which info is copied - * @param jclazz The Java class - */ - private class FromJavaClassCompleter(clazz: Symbol, module: Symbol, jclazz: jClass[_]) extends LazyType { - override def load(sym: Symbol) = { - debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug - assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym) - val flags = toScalaClassFlags(jclazz.getModifiers) - clazz setFlag (flags | JAVA) - if (module != NoSymbol) { - module setFlag (flags & PRIVATE | JAVA) - module.moduleClass setFlag (flags & PRIVATE | JAVA) - } - - copyAnnotations(clazz, jclazz) - // to do: annotations to set also for module? - - clazz setInfo new LazyPolyType(jclazz.getTypeParameters.toList map createTypeParameter) - if (module != NoSymbol) { - module setInfo module.moduleClass.tpe - module.moduleClass setInfo new LazyPolyType(List()) - } - } - - override def complete(sym: Symbol): Unit = { - load(sym) - completeRest() - } - def completeRest(): Unit = self.synchronized { - val tparams = clazz.rawInfo.typeParams - - val parents = try { - parentsLevel += 1 - val jsuperclazz = jclazz.getGenericSuperclass - val superclazz = if (jsuperclazz == null) AnyClass.tpe else typeToScala(jsuperclazz) - superclazz :: (jclazz.getGenericInterfaces.toList map typeToScala) - } finally { - parentsLevel -= 1 - } - clazz setInfo GenPolyType(tparams, new ClassInfoType(parents, newScope, clazz)) - if (module != NoSymbol) { - module.moduleClass setInfo new ClassInfoType(List(), newScope, module.moduleClass) - } - - def enter(sym: Symbol, mods: Int) = - (if (jModifier.isStatic(mods)) module.moduleClass else clazz).info.decls enter sym - - for (jinner <- jclazz.getDeclaredClasses) { - enter(jclassAsScala(jinner, clazz), jinner.getModifiers) - } - - pendingLoadActions = { () => - - for (jfield <- jclazz.getDeclaredFields) - enter(jfieldAsScala(jfield), jfield.getModifiers) - - for (jmeth <- jclazz.getDeclaredMethods) - enter(jmethodAsScala(jmeth), jmeth.getModifiers) - - for (jconstr <- jclazz.getConstructors) - enter(jconstrAsScala(jconstr), jconstr.getModifiers) - - } :: pendingLoadActions - - if (parentsLevel == 0) { - while (!pendingLoadActions.isEmpty) { - val item = pendingLoadActions.head - pendingLoadActions = pendingLoadActions.tail - item() - } - } - } - class LazyPolyType(override val typeParams: List[Symbol]) extends LazyType { - override def complete(sym: Symbol) { - completeRest() - } - } - } - - /** used to avoid cyclies */ - var parentsLevel = 0 - var pendingLoadActions: List[() => Unit] = Nil - - /** - * If Java modifiers `mods` contain STATIC, return the module class - * of the companion module of `clazz`, otherwise the class `clazz` itself. - */ - private def followStatic(clazz: Symbol, mods: Int) = - if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz - - /** Methods which need to be wrapped because they either are getSimpleName - * or call getSimpleName: - * - * public String getSimpleName() - * public boolean isAnonymousClass() - * public boolean isLocalClass() - * public boolean isMemberClass() - * public String getCanonicalName() - * - * TODO - find all such calls and wrap them. - * TODO - create mechanism to avoid the recurrence of unwrapped calls. - */ - private def wrapClassCheck[T](alt: T)(body: => T): T = - try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt } - - private def wrapIsLocalClass(clazz: jClass[_]): Boolean = - wrapClassCheck(false)(clazz.isLocalClass) - - private def wrapGetSimpleName(clazz: jClass[_]): String = - wrapClassCheck("")(clazz.getSimpleName) - - /** - * The Scala owner of the Scala class corresponding to the Java class `jclazz` - */ - private def sOwner(jclazz: jClass[_]): Symbol = { - if (jclazz.isMemberClass) { - val jEnclosingClass = jclazz.getEnclosingClass - val sEnclosingClass = classToScala(jEnclosingClass) - followStatic(sEnclosingClass, jclazz.getModifiers) - } else if (wrapIsLocalClass(jclazz)) { - val jEnclosingMethod = jclazz.getEnclosingMethod - if (jEnclosingMethod != null) { - methodToScala(jEnclosingMethod) - } else { - val jEnclosingConstructor = jclazz.getEnclosingConstructor - constrToScala(jEnclosingConstructor) - } - } else if (jclazz.isPrimitive || jclazz.isArray) { - ScalaPackageClass - } else if (jclazz.getPackage != null) { - val jPackage = jclazz.getPackage - packageToScala(jPackage) - } else { - // @eb: a weird classloader might return a null package for something with a non-empty package name - // for example, http://groups.google.com/group/scala-internals/browse_thread/thread/7be09ff8f67a1e5c - // in that case we could invoke packageNameToScala(jPackageName) and, probably, be okay - // however, I think, it's better to blow up, since weirdness of the class loader might bite us elsewhere - val jPackageName = jclazz.getName.substring(0, Math.max(jclazz.getName.lastIndexOf("."), 0)) - assert(jPackageName == "") - EmptyPackageClass - } - } - - /** - * The Scala owner of the Scala symbol corresponding to the Java member `jmember` - */ - private def sOwner(jmember: jMember): Symbol = { - followStatic(classToScala(jmember.getDeclaringClass), jmember.getModifiers) - } - - /** - * The Scala owner of the Scala type parameter corresponding to the Java type variable `jtvar` - */ - private def sOwner(jtvar: jTypeVariable[_ <: GenericDeclaration]): Symbol = - genericDeclarationToScala(jtvar.getGenericDeclaration) - - /** - * Returns `true` if Scala name `name` equals Java name `jstr`, possibly after - * make-not-private expansion. - */ - private def approximateMatch(sym: Symbol, jstr: String): Boolean = - (sym.name.toString == jstr) || - sym.isPrivate && nme.expandedName(sym.name.toTermName, sym.owner).toString == jstr - - /** - * Find declarations or definition in class `clazz` that maps to a Java - * entity with name `jname`. Because of name-mangling, this is more difficult - * than a simple name-based lookup via `decl`. If `decl` fails, members - * that start with the given name are searched instead. - */ - private def lookup(clazz: Symbol, jname: String): Symbol = - clazz.info.decl(newTermName(jname)) orElse { - (clazz.info.decls.iterator filter (approximateMatch(_, jname))).toList match { - case List() => NoSymbol - case List(sym) => sym - case alts => clazz.newOverloaded(alts.head.tpe.prefix, alts) - } - } - - /** - * The Scala method corresponding to given Java method. - * @param jmeth The Java method - * @return A Scala method object that corresponds to `jmeth`. - */ - def methodToScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) { - val jOwner = jmeth.getDeclaringClass - var sOwner = classToScala(jOwner) - sOwner = followStatic(sOwner, jmeth.getModifiers) - lookup(sOwner, jmeth.getName) suchThat (erasesTo(_, jmeth)) orElse jmethodAsScala(jmeth) - } - - /** - * The Scala constructor corresponding to given Java constructor. - * @param jconstr The Java constructor - * @return A Scala method object that corresponds to `jconstr`. - */ - def constrToScala(jconstr: jConstructor[_]): Symbol = constructorCache.toScala(jconstr) { - val owner = followStatic(classToScala(jconstr.getDeclaringClass), jconstr.getModifiers) - lookup(owner, "<init>") suchThat (erasesTo(_, jconstr)) orElse jconstrAsScala(jconstr) - } - - /** - * The Scala package corresponding to given Java package - */ - def packageToScala(jpkg: jPackage): Symbol = packageCache.toScala(jpkg) { - makeScalaPackage(jpkg.getName) - } - - /** - * The Scala package with given fully qualified name. - */ - def packageNameToScala(fullname: String): Symbol = { - val jpkg = jPackage.getPackage(fullname) - if (jpkg != null) packageToScala(jpkg) else makeScalaPackage(fullname) - } - - /** - * The Scala package with given fully qualified name. Unlike `packageNameToScala`, - * this one bypasses the cache. - */ - def makeScalaPackage(fullname: String): Symbol = { - val split = fullname lastIndexOf '.' - val owner = if (split > 0) packageNameToScala(fullname take split) else RootClass - assert(owner.isModuleClass, owner+" when making "+fullname) - val name = newTermName(fullname drop (split + 1)) - var pkg = owner.info decl name - if (pkg == NoSymbol) { - pkg = owner.newPackage(name) - pkg.moduleClass setInfo new LazyPackageType - pkg setInfoAndEnter pkg.moduleClass.tpe - info("made Scala "+pkg) - } else if (!pkg.isPackage) - throw new ReflectError(pkg+" is not a package") - pkg.moduleClass - } - - private def scalaSimpleName(jclazz: jClass[_]): TypeName = { - val owner = sOwner(jclazz) - val enclosingClass = jclazz.getEnclosingClass - var prefix = if (enclosingClass != null) enclosingClass.getName else "" - val isObject = owner.isModuleClass && !owner.isPackageClass - if (isObject && !prefix.endsWith(nme.MODULE_SUFFIX_STRING)) prefix += nme.MODULE_SUFFIX_STRING - assert(jclazz.getName.startsWith(prefix)) - var name = jclazz.getName.substring(prefix.length) - name = name.substring(name.lastIndexOf(".") + 1) - newTypeName(name) - } - - /** - * The Scala class that corresponds to a given Java class. - * @param jclazz The Java class - * @return A Scala class symbol that reflects all elements of the Java class, - * in the form they appear in the Scala pickling info, or, if that is - * not available, wrapped from the Java reflection info. - */ - def classToScala(jclazz: jClass[_]): Symbol = classCache.toScala(jclazz) { - val jname = javaTypeName(jclazz) - - val sym = - if (jname == fulltpnme.RuntimeNothing) - NothingClass - else if (jname == fulltpnme.RuntimeNull) - NullClass - else - { - val owner = sOwner(jclazz) - val simpleName = scalaSimpleName(jclazz) - - def lookup = { - def coreLookup(name: Name): Symbol = { - val sym = owner.info.decl(name) - sym orElse { - if (name.startsWith(nme.NAME_JOIN_STRING)) - coreLookup(name.subName(1, name.length)) - else - NoSymbol - } - } - - if (nme.isModuleName(simpleName)) { - val moduleName = nme.stripModuleSuffix(simpleName).toTermName - val sym = coreLookup(moduleName) - if (sym == NoSymbol) sym else sym.moduleClass - } else { - coreLookup(simpleName) - } - } - - val sym = { - if (jclazz.isMemberClass && !nme.isImplClassName(jname)) { - lookup - } else if (wrapIsLocalClass(jclazz) || invalidClassName(jname)) { - // local classes and implementation classes not preserved by unpickling - treat as Java - jclassAsScala(jclazz) - } else if (jclazz.isArray) { - ArrayClass - } else javaTypeToValueClass(jclazz) orElse { - // jclazz is top-level - get signature - lookup - // val (clazz, module) = createClassModule( - // sOwner(jclazz), newTypeName(jclazz.getSimpleName), new TopClassCompleter(_, _)) - // classCache enter (jclazz, clazz) - // clazz - } - } - - if (!sym.isType) { - val classloader = jclazz.getClassLoader - println("classloader is: %s of type %s".format(classloader, classloader.getClass)) - def inferClasspath(cl: ClassLoader) = cl match { - case cl: java.net.URLClassLoader => "[" + (cl.getURLs mkString ",") + "]" - case _ => "<unknown>" - } - println("classpath is: %s".format(inferClasspath(classloader))) - def msgNoSym = "no symbol could be loaded from %s (scala equivalent is %s) by name %s".format(owner, jclazz, simpleName) - def msgIsNotType = "not a type: symbol %s loaded from %s (scala equivalent is %s) by name %s".format(sym, owner, jclazz, simpleName) - assert(false, if (sym == NoSymbol) msgNoSym else msgIsNotType) - } - - sym - } - - sym.asInstanceOf[ClassSymbol] - } - - /** - * The Scala type parameter that corresponds to a given Java type parameter. - * @param jparam The Java type parameter - * @return A Scala type parameter symbol that has the same owner and name as the Java type parameter - */ - def tparamToScala(jparam: jTypeVariable[_ <: GenericDeclaration]): Symbol = tparamCache.toScala(jparam) { - val owner = genericDeclarationToScala(jparam.getGenericDeclaration) - owner.info match { - case PolyType(tparams, _) => tparams.find(_.name.toString == jparam.getName).get - } - } - - /** - * The Scala symbol that corresponds to a given Java generic declaration (class, method, or constructor) - */ - def genericDeclarationToScala(jdecl: GenericDeclaration) = jdecl match { - case jclazz: jClass[_] => classToScala(jclazz) - case jmeth: jMethod => methodToScala(jmeth) - case jconstr: jConstructor[_] => constrToScala(jconstr) - } - - /** - * Given some Java type arguments, a corresponding list of Scala types, plus potentially - * some existentially bound type variables that represent wildcard arguments. - */ - private def targsToScala(owner: Symbol, args: List[jType]): (List[Type], List[Symbol]) = { - val tparams = new ListBuffer[Symbol] - def targToScala(arg: jType): Type = arg match { - case jwild: WildcardType => - val tparam = owner.newExistential(newTypeName("T$" + tparams.length)) - .setInfo(TypeBounds( - lub(jwild.getLowerBounds.toList map typeToScala), - glb(jwild.getUpperBounds.toList map typeToScala map objToAny))) - tparams += tparam - typeRef(NoPrefix, tparam, List()) - case _ => - typeToScala(arg) - } - (args map targToScala, tparams.toList) - } - - /** - * The Scala type that corresponds to given Java type - */ - def typeToScala(jtpe: jType): Type = jtpe match { - case jclazz: jClass[_] => - 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) - case TypeRef(pre, sym, _) => (pre, sym) - } - val args0 = japplied.getActualTypeArguments - val (args, bounds) = targsToScala(pre.typeSymbol, args0.toList) - ExistentialType(bounds, typeRef(pre, sym, args)) - case jarr: GenericArrayType => - arrayType(typeToScala(jarr.getGenericComponentType)) - case jtvar: jTypeVariable[_] => - val tparam = tparamToScala(jtvar) - typeRef(NoPrefix, tparam, List()) - } - - /** - * The Scala class that corresponds to given Java class without taking - * Scala pickling info into account. - * @param jclazz The Java class - * @return A Scala class symbol that wraps all reflection info of `jclazz` - */ - private def jclassAsScala(jclazz: jClass[_]): Symbol = jclassAsScala(jclazz, sOwner(jclazz)) - - private def jclassAsScala(jclazz: jClass[_], owner: Symbol): Symbol = { - val name = scalaSimpleName(jclazz) - val completer = (clazz: Symbol, module: Symbol) => new FromJavaClassCompleter(clazz, module, jclazz) - val (clazz, module) = createClassModule(owner, name, completer) - classCache enter (jclazz, clazz) - clazz - } - - /** - * The Scala field that corresponds to given Java field without taking - * Scala pickling info into account. - * @param jfield The Java field - * @return A Scala value symbol that wraps all reflection info of `jfield` - */ - private def jfieldAsScala(jfield: jField): Symbol = fieldCache.toScala(jfield) { - val field = ( - sOwner(jfield) - newValue(newTermName(jfield.getName), NoPosition, toScalaFieldFlags(jfield.getModifiers)) - setInfo typeToScala(jfield.getGenericType) - ) - fieldCache enter (jfield, field) - copyAnnotations(field, jfield) - field - } - - private def setMethType(meth: Symbol, tparams: List[Symbol], paramtpes: List[Type], restpe: Type) = { - meth setInfo GenPolyType(tparams, MethodType(meth.owner.newSyntheticValueParams(paramtpes map objToAny), restpe)) - } - - /** - * The Scala method that corresponds to given Java method without taking - * Scala pickling info into account. - * @param jmeth The Java method - * @return A Scala method symbol that wraps all reflection info of `jmethod` - */ - private def jmethodAsScala(jmeth: jMethod): Symbol = methodCache.toScala(jmeth) { - val clazz = sOwner(jmeth) - val meth = clazz.newMethod(newTermName(jmeth.getName), NoPosition, toScalaMethodFlags(jmeth.getModifiers)) - methodCache enter (jmeth, meth) - val tparams = jmeth.getTypeParameters.toList map createTypeParameter - val paramtpes = jmeth.getGenericParameterTypes.toList map typeToScala - val resulttpe = typeToScala(jmeth.getGenericReturnType) - setMethType(meth, tparams, paramtpes, resulttpe) - copyAnnotations(meth, jmeth) - if ((jmeth.getModifiers & JAVA_ACC_VARARGS) != 0) { - meth.setInfo(arrayToRepeated(meth.info)) - } - meth - } - - /** - * The Scala constructor that corresponds to given Java constructor without taking - * Scala pickling info into account. - * @param jconstr The Java constructor - * @return A Scala constructor symbol that wraps all reflection info of `jconstr` - */ - private def jconstrAsScala(jconstr: jConstructor[_]): Symbol = { - // [Martin] Note: I know there's a lot of duplication wrt jmethodAsScala, but don't think it's worth it to factor this out. - val clazz = sOwner(jconstr) - val constr = clazz.newConstructor(NoPosition, toScalaMethodFlags(jconstr.getModifiers)) - constructorCache enter (jconstr, constr) - val tparams = jconstr.getTypeParameters.toList map createTypeParameter - val paramtpes = jconstr.getGenericParameterTypes.toList map typeToScala - setMethType(constr, tparams, paramtpes, clazz.tpe) - constr setInfo GenPolyType(tparams, MethodType(clazz.newSyntheticValueParams(paramtpes), clazz.tpe)) - copyAnnotations(constr, jconstr) - constr - } -} - -class ReflectError(msg: String) extends java.lang.Error(msg) |