/**
* Utils for Java Abstract Syntax Trees
*/
module dryad/util/jtree
imports
libjava-front
/**
* Compilation Units
*/
strategies
/**
* @type CompilationUnit -> PackageName
*
* Returns PackageName([]) for the root package.
*/
get-package-name-of-compilation-unit =
?CompilationUnit(Some(PackageDec(_, <id>)), _, _)
get-package-name-of-compilation-unit =
?CompilationUnit(None(), _, _)
; !PackageName([])
/**
* Returns the package of a compilation unit.
*
* The package is created if it does not exist.
*
* @type CompilationUnit -> Package Object
*/
get-package-of-compilation-unit =
get-package-name-of-compilation-unit
; lookup-or-add-package
strategies
/**
* Dirty hack.
*
* @type CompilationUnit -> List(CompilationUnit)
*/
unpack-compilation-unit =
?CompilationUnit(pkgdec, importdecs, decs)
; <map(!CompilationUnit(pkgdec, importdecs, [<id>]))> decs
/**
* Dirty hack.
*
* @type List(CompilationUnit) -> CompilationUnit
*/
pack-compilation-unit =
map(?CompilationUnit(pkgdec, importdecs, [<id>]))
; !CompilationUnit(pkgdec, importdecs, <id>)
/**
* Type Declarations
*/
strategies
/**
* Returns the name of a type declaration.
*
* @type TypeDec -> Strintg
*/
get-name-of-typedec =
?ClassDec(ClassDecHead(_, Id(<id>), _, _, _), _)
get-name-of-typedec =
?InterfaceDec(InterfaceDecHead(_, Id(<id>), _, _), _)
/**
* Returns the superclass of a type declaration.
*
* This strategy does not return java.lang.Object if no superclass
* is defined.
*
* @type TypeDec -> Type
*/
get-superclass-of-typedec =
?ClassDec(ClassDecHead(_, _, _, Some(SuperDec(<id>)), _), _)
/**
* Returns the superinterfaces of a type declaration.
*
* This strategy fails if no interfaces are implemented.
*
* @type TypeDec -> List(Type)
*/
get-superinterfaces-of-typedec =
?ClassDec(ClassDecHead(_, _, _, _, Some(ImplementsDec(<id>))), _)
get-superinterfaces-of-typedec =
?InterfaceDec(InterfaceDecHead(_, _, _, Some(ExtendsInterfaces(<id>))), _)
strategies
apply-to-constructor-decs-of-typedec(s) =
apply-to-body-decs-of-typedec(
if ?ConstrDec(_, _) then s else id end
)
get-constructor-decs-of-typedec =
?ClassDec(_, ClassBody(<id>))
; filter(?ConstrDec(_, _))
strategies
apply-to-method-decs-of-typedec(s) =
apply-to-body-decs-of-typedec(
if ?AbstractMethodDec(_, _, _, _, _, _) + ?MethodDec(_, _) then s else id end
)
strategies
get-field-decs-of-typedec =
?ClassDec(_, ClassBody(<id>))
; filter(?FieldDec(_, _, _))
get-field-decs-of-typedec =
?InterfaceDec(_, <id>)
; filter(?ConstantDec(_, _, _))
apply-to-field-decs-of-typedec(s) =
apply-to-body-decs-of-typedec(
if ?FieldDec(_, _, _) + ?ConstantDec(_, _, _) then s else id end
)
strategies
get-body-decs-of-typedec =
?ClassDec(_, ClassBody(<id>))
get-body-decs-of-typedec =
?InterfaceDec(_, <id>)
get-member-type-decs-of-typedec =
get-body-decs-of-typedec
; filter(?InterfaceDec(_, _) + ?ClassDec(_, _))
apply-to-member-type-decs-of-typedec(s) =
apply-to-body-decs-of-typedec(
if ?InterfaceDec(_, _) + ?ClassDec(_, _) then s else id end
)
apply-to-body-decs-of-typedec(s) =
ClassDec(id, ClassBody(map(s)))
apply-to-body-decs-of-typedec(s) =
InterfaceDec(id, map(s))
/**
* Formal parameters
*/
strategies
get-type-of-param =
?Param(_, <id>, x)
; type-add-dimensions-from-id(|x)
get-type-of-field(|x) =
where(vardecid := <get-vardecid-of-field(|x)>)
; (?FieldDec(_, <id>, _) + ?ConstantDec(_, <id>, _))
; type-add-dimensions-from-id(|vardecid)
get-vardec-of-field(|x) =
( ?FieldDec(_, _, <id>) + ?ConstantDec(_, _, <id>))
; fetch-elem(
?VarDec(Id(x))
<+ ?VarDec(Id(x), _)
<+ ?VarDec(ArrayVarDecId(Id(x), _))
<+ ?VarDec(ArrayVarDecId(Id(x), _), _)
)
get-vardecid-of-field(|x) =
get-vardec-of-field(|x)
; (?VarDec(<id>) <+ ?VarDec(<id>, _))
/**
* @type Type -> Type
*/
type-add-dimensions-from-id(|vardecid) =
where(!vardecid => Id(_))
type-add-dimensions-from-id(|vardecid) =
where(dims := <?ArrayVarDecId(_, <id>)> vardecid)
; let next(|dim) = !ArrayType(<id>)
in foldl(next | dims )
end
/**
* Initializers and constructors
*/
strategies
is-class-init-method =
?StaticInit(_)
/**
* Succeeds if this is an instance initialization method (constructor).
*
* @type Bytecode Method -> Bytecode Method
*/
is-instance-init-method =
?InstanceInit(_) + ?ConstrDec(_, _)
/**
* Literals
*
* @todo Maybe Long literals should have an explicit structure.
*/
strategies
/**
* Succeeds if this is an integer literal (Long or Int)
*
* @type Expr -> Expr
*/
is-integer-literal =
?Lit(Deci(_))
is-integer-literal =
?Lit(Hexa(_))
is-integer-literal =
?Lit(Octa(_))
/**
* Succeeds if this is a float or double literal.
*/
is-floating-point-literal =
?Lit(Float(_))
/**
* Succeeds if this is a long literal
*
* @type Expr -> Expr
*/
is-long-literal =
let project-literal =
?Lit(Deci(<id>))
+ ?Lit(Hexa(<id>))
+ ?Lit(Octa(<id>))
in where(
project-literal
; test-last-char('l' + 'L')
)
end
/**
* Succeeds if this is a float literal (ends with f or F)
*
* @type Expr -> Expr
*/
is-float-literal =
where(
?Lit(Float(<id>))
; test-last-char('f' + 'F')
)
/**
* s is applied to the last character of the string
*
* @type String -> String
*/
test-last-char(s) =
where(
explode-string
; last
; s
)