/** * Bytecode Class * * @author Martin Bravenboer <martin@cs.uu.nl> */ module dryad/model/bytecode-class imports dryad/lib-ext/oo/classes dryad/model/class dryad/model/bytecode-constructor dryad/model/bytecode-field dryad/model/bytecode-method dryad/bytecode/Bridge dryad/bytecode/Signature dryad/bytecode/util strategies /** * Construct a new bytecode class object * * @type _ -> BytecodeClass Object * @param String */ new-bytecode-class(|simple-name) = <classes_get-class> JavaBytecodeClass() ; classes_new-instance ; classes_set-instance-field(|"simple-name", simple-name) strategies set-package(|pkg) = instanceof-JavaBytecodeClass; classes_set-instance-field(|"package", pkg) get-package = instanceof-JavaBytecodeClass; classes_get-instance-field(|"package") strategies /** * Returns the super class of this class as a type. * Fails if this class has no superclass (i.e. this class is java.lang.Object) * * @type Class Object -> Source Type */ get-superclass-as-type = if-signature( ?ClassSignature(_, SuperClass(<id>), _) , get-reference-ast ; ?ClassFile(_, _, _, _, SuperClass(Some(<id>)), _, _, _, _) ; <bytecode-type-to-source-type> ObjectType(<id>) ) /** * Returns the interfaces implemented by this class as types. * * @type Class Object -> List(Source Type) */ get-superinterfaces-as-type = if-signature( ?ClassSignature(_, _, SuperInterfaces(<id>)) , get-reference-ast ; ?ClassFile(_, _, _, _, _, Interfaces(<id>), _, _, _) ; map(<bytecode-type-to-source-type> ObjectType(<id>)) ) strategies /** * @type BytecodeClass Object -> List(TypeParam) */ get-formal-type-parameters = instanceof-JavaBytecodeClass; if get-signature => sig then !sig => ClassSignature(TypeParams(<id>), _, _) else ![] end /** * Returns the generic signature of this class. * * @type BytecodeClass Object - ClassSignature */ get-signature = instanceof-JavaBytecodeClass; ?this; ( classes_get-instance-field(|GenericSignature()) <+ get-attributes ; if fetch(?ClassSignature(_, _, _); ?sig) then !Some(sig) else !None() end ; ?result ; <classes_set-instance-field(|GenericSignature(), result)> this ; reclassify-class-signature ; classes_get-instance-field(|GenericSignature()) ) ; ?Some(<id>) strategies /** * Returns the attributes of this bytecode class. * * Note: attributes are a bytecode-level construct and are not * directly related to Java source annotations. This strategy returns * the *bytecode* attributes. * * @type BytecodeClass Object -> List(Attribute) */ get-attributes = instanceof-JavaBytecodeClass; get-reference-ast ; ?ClassFile(_, _, _, _, _, _, _, _, Attributes(<id>)) strategies /** * Succeeds if this class is an interface. * * @type BytecodeClass Object -> BytecodeClass Object */ is-interface = instanceof-JavaBytecodeClass; where( get-access-flags ; fetch(?Interface()) ) /** * @type BytecodeClass Object -> List(AccessFlags) */ get-access-flags = instanceof-JavaBytecodeClass; get-reference-ast ; ?ClassFile(_, _, AccessFlags(<id>), _, _, _, _, _, _) /** * @todo Is default access necessary for bytecode classes? * @todo Do interfaces have default access set to public in bytecode? * @type BytecodeClass Object -> Access Modifier */ get-access = instanceof-JavaBytecodeClass; get-access-flags ; ( fetch-elem(?Public() + ?Private() + ?Protected()) <+ !DefaultAccess()) /** * Fields */ strategies /** * Initializes the field table of a bytecode class. * * @type BytecodeClass Object -> List(BytecodeField Object) */ init-get-declared-field-list = instanceof-JavaBytecodeClass; get-reference-ast ; ?ClassFile(_, _, _, _, _, _, Fields(<id>), _, _) ; filter(instanceof-JavaField) /** * Methods */ strategies /** * Initializes the declared method table of a bytecode class. * * @type BytecodeClass Object -> List(BytecodeMethod Object) */ init-get-declared-method-list = instanceof-JavaBytecodeClass; get-reference-ast ; ?ClassFile(_, _, _, _, _, _, _, Methods(<id>), _) ; filter(instanceof-JavaMethod) /** * Constructors */ strategies /** * Initializes the declared constructors list of a bytecode class. * * @type BytecodeClass Object -> List(BytecodeConstructor Object) */ init-get-declared-constructor-list = instanceof-JavaBytecodeClass; get-reference-ast ; ?ClassFile(_, _, _, _, _, _, _, Methods(<id>), _) ; filter(instanceof-JavaConstructor) /** * Member Classes */ strategies init-declared-member-type-table = instanceof-JavaBytecodeClass; ?this; where( new-hashtable => classtbl ) ; classes_set-instance-field(|"declared-member-type-table", classtbl) /** * AST * * @todo Implement get-ast. */ strategies set-ast(|ast) = instanceof-JavaBytecodeClass; ?this; where( <classtree-to-reference-ast(|this)> ast => ref-ast ) ; set-reference-ast(|ref-ast) /** * Reference AST of this bytecode class. */ strategies /** * Returns the Reference AST of this source class. * * @type BytecodeClass Object -> ReferenceAST(ClassTree) */ get-reference-ast = instanceof-JavaBytecodeClass; classes_get-instance-field(read-reference-ast-from-location |"reference-ast") /** * @param ReferenceAST(ClassTree) * @type BytecodeClass Object -> BytecodeClass Object */ set-reference-ast(|ref-ast) = instanceof-JavaBytecodeClass; classes_set-instance-field(|"reference-ast", ref-ast) read-reference-ast-from-location = instanceof-JavaBytecodeClass; ?this; ( get-location ; report-reading-class ; read-class-file ; classtree-to-reference-ast(|this) <+ get-simple-name ; debug(!"error: could not read class ") ; fail ) classtree-to-reference-ast(|this) = ?tree ; apply-to-methods-of-classtree( new-bytecode-method(|<id>) ; set-declaring-class(|this) ) ; apply-to-constructors-of-classtree( new-bytecode-constructor(|<id>) ; set-declaring-class(|this) ) ; apply-to-fields-of-classtree( new-bytecode-field(|<id>) ; set-declaring-class(|this) ) apply-to-constructors-of-classtree(s) = ClassFile(id, id, id, id, id, id, id , Methods(map(if is-instance-init-method then s end)) , id ) apply-to-methods-of-classtree(s) = ClassFile(id, id, id, id, id, id, id , Methods(map(if not(is-class-init-method + is-instance-init-method) then s end)) , id ) apply-to-fields-of-classtree(s) = ClassFile(id, id, id, id, id, id, Fields(map(s)), id, id) /** * Location */ strategies set-location(|loc) = instanceof-JavaBytecodeClass; classes_set-instance-field(|"location", loc) get-location = instanceof-JavaBytecodeClass; classes_get-instance-field(|"location") strategies report-reading-class = if-verbose2( where( ?Jar(jarpath, filepath) ; log(|Debug(), ["Reading class ", filepath, " from jar ", jarpath]) ) ) /** * Stratego class support for bytecode classes */ signature constructors /** * Identifier for BytecodeClass Objects. */ JavaBytecodeClass : ClassName strategies /** * Succeeds if this is a BytecodeClass Object. */ instanceof-JavaBytecodeClass = classes_instanceof(|JavaBytecodeClass()) /** * A BytecodeClass Object is a Class Object. */ instanceof-JavaClass = classes_instanceof(|JavaBytecodeClass())