Add support for parsing system classes.

This commit is contained in:
Stu Hood 2015-09-18 13:03:57 -07:00
parent d4f7977c42
commit 5a3b95cd6d
2 changed files with 21 additions and 7 deletions

View File

@ -160,7 +160,7 @@ object ClassToAPI {
} catch { } catch {
case e: Throwable => case e: Throwable =>
throw new IllegalStateException( throw new IllegalStateException(
s"Failed to parse class $c: this may mean your classfiles are corrupted. Please clean and try again.", s"Failed to parse $c: this may mean your classfiles are corrupted. Please clean and try again.",
e e
) )
} }

View File

@ -38,14 +38,22 @@ object IO {
/** /**
* Returns a URL for the directory or jar containing the the class file `cl`. * Returns a URL for the directory or jar containing the the class file `cl`.
* If the location cannot be determined, an error is generated. * If the location cannot be determined, an error is generated.
* Note that Java standard library classes typically do not have a location associated with them.
*/ */
def classLocation(cl: Class[_]): URL = def classLocation(cl: Class[_]): URL = {
{ val codeSource = cl.getProtectionDomain.getCodeSource
val codeSource = cl.getProtectionDomain.getCodeSource if (codeSource ne null) {
if (codeSource == null) sys.error("No class location for " + cl) codeSource.getLocation
else codeSource.getLocation } else {
Option(ClassLoader.getSystemClassLoader.getResource(classfilePathForClassname(cl.getName)))
.flatMap {
// TODO: assuming that System-class-loaded classes are located in jars, which
// will cause this method to truncate to the jar
urlAsFile
}.getOrElse {
sys.error("No class location for " + cl)
}.toURI.toURL
} }
}
/** /**
* Returns the directory or jar file containing the the class file `cl`. * Returns the directory or jar file containing the the class file `cl`.
@ -88,6 +96,12 @@ object IO {
case _ => None case _ => None
} }
/**
* @return The path for the given classname.
*
* TODO: crossplatform
*/
def classfilePathForClassname(clsname: String): String = s"${clsname.replace('.', '/')}.class"
private[this] def uriToFile(uriString: String): File = private[this] def uriToFile(uriString: String): File =
{ {
val uri = new URI(uriString) val uri = new URI(uriString)