/**
* Access to Java bytecode by conversion to ATerms.
*
* @todo Use libstratego-sglr for parsing signatures
* @author Martin Bravenboer <martin@cs.uu.nl>
* @author Lennart Kats <l.c.l.kats@tudelft.nl>
*/
module dryad/bytecode/Bridge
imports
libstratego-jvm
dryad/bytecode/Signature
dryad/bytecode/ClassSignature
dryad/bytecode/MethodSignature
dryad/bytecode/FieldSignature
strategies
read-class-file =
?Jar(jarpath, filepath)
; where(get-jvm(|[<xtc-find> "class2aterm.jar"]) => jvm)
; <strjvm-callstatic(|jvm, "str/classtree/Class2ATerm", "disasm_from_jar")> [jarpath, filepath]
; parse-signatures
read-class-file =
(?ClassFile(path) + ?FILE(path))
; where(get-jvm(|[<xtc-find> "class2aterm.jar"]) => jvm)
; <strjvm-callstatic(|jvm, "str/classtree/Class2ATerm", "disasm")> [path, "off"]
; parse-signatures
read-class-file-disasm =
(?ClassFile(path) + ?FILE(path))
; where(get-jvm(|[<xtc-find> "class2aterm.jar"]) => jvm)
; <strjvm-callstatic(|jvm, "str/classtree/Class2ATerm", "disasm")> [path, "on"]
; parse-signatures
/**
* Serializes a Java class file to a file.
* The output file name and path is determined from the package and class name.
*
* @type ClassFile -> FILE
*/
write-class-file:
classfile @ ClassFile(_, _, _, ThisClass(name), _, _, _, _, _) -> FILE(output)
where
path := <add-extension> (<string-replace(|".", "/")> name, "class")
; FILE(output) := <write-class-file(|path)> classfile
/**
* Serializes a Java class file to a file.
*
* @type ClassFile -> FILE
*/
write-class-file(|path):
ClassFile(_, _, _, _, _, _, _, _, _) -> FILE(path)
where
write-to
; xtc-transform(!"baffle", !["-ws"]) => FILE(input)
; where(get-jvm(|[<xtc-find> "class2aterm.jar"]) => jvm)
; <strjvm-callstatic(|jvm, "str/classtree/ATerm2Class", "asm")> [input, path]
strategies
get-jvm(|classpath) =
GetJVM
<+ strjvm-create(|classpath) => jvm
; rules(GetJVM: _ -> jvm)
strategies
parse-signatures =
topdown(try(
?ClassSignature(<parse-class-signature>)
+ ?MethodSignature(<parse-method-signature>)
+ ?FieldSignature(<parse-field-signature>)
))
parse-class-signature =
parse-signature(|"ClassSignature.tbl")
parse-method-signature =
parse-signature(|"MethodSignature.tbl")
parse-field-signature =
parse-signature(|"FieldSignature.tbl")
parse-signature(|tbl) =
where(<get-signature-parse-table> tbl => opentbl)
; (parse-string(|opentbl) <+ report-parse-error; fail)
; desugar-signature
get-signature-parse-table =
?tbl
; ( ParseTable
<+ <xtc-find> tbl
; ReadFromFile
; open-parse-table => opentbl
; rules(ParseTable: tbl -> opentbl)
)
desugar-signature =
alltd(
( ?ClassSignature(_, _, _)
+ ?MethodSignature(_, _, _, _)
+ ?FieldSignature(_)
)
; topdown(repeat(DesugarSignature))
)
DesugarSignature :
MethodSignature(Some(t1), t2, t3, t4) -> MethodSignature(t1, t2, t3, t4)
DesugarSignature :
MethodSignature(None(), t2, t3, t4) -> MethodSignature(TypeParams([]), t2, t3, t4)
DesugarSignature :
ClassSignature(Some(t1), t2, t3) -> ClassSignature(t1, t2, t3)
DesugarSignature :
ClassSignature(None(), t2, t3) -> ClassSignature(TypeParams([]), t2, t3)
DesugarSignature :
TypeName(Id(x)) -> TypeName(PackageName([]), Id(x))
DesugarSignature :
TypeArg(None(), type) -> type
/**
* @todo Desugar None ClassBound
*/
DesugarSignature :
TypeParam(Id(x), ClassBound(Some(ftype)), is)
->
TypeParam(Id(x), Some(TypeBound([ftype | is])))
DesugarSignature :
Class(type) -> type
/**
* @todo Temporary hack to support ? extends E by rewriting to E.
*/
DesugarSignature :
TypeArg(Some(Plus), TypeVar(Id(x))) -> TypeArg(None(), TypeVar(Id(x)))