1/*****************************************************************************
    2 * This file is part of the Prolog Development Tool (PDT)
    3 * 
    4 * Author: Tobias Rho
    5 * WWW: http://sewiki.iai.uni-bonn.de/research/pdt/start
    6 * Mail: pdt@lists.iai.uni-bonn.de
    7 * Copyright (C): 2013, CS Dept. III, University of Bonn
    8 * 
    9 * All rights reserved. This program is  made available under the terms
   10 * of the Eclipse Public License v1.0 which accompanies this distribution,
   11 * and is available at http://www.eclipse.org/legal/epl-v10.html
   12 * 
   13 ****************************************************************************/
   14
   15/*
   16 * Structure of the file:
   17 *
   18 * - conditions used by CTs
   19 * - actions    used by CTs
   20 * - dynamic predicates
   21 * - auxiliary predicates
   22 *
   23 * Author:      Tobias Rho
   24 * Date:        30.08.02
   25 * Last Change: 13.09.05
   26 */
   27
   28/* *** PUBLIC API **********************************************/
   29
   30/* *** CONDITIONS **********************************************
   31 *
   32 * Predicates used in the CT conditions generation.
   33 * These predicates are marked with CONDITION 
   34 * in the documentation.
   35 *
   36 */
   37cond(matchParams(_ParametersOrArgs, _PatternList)).
   38cond(extract_class_name(_FQN,_PackageName, _ClassName)).
   39
   40/* *** ACTIONS *************************************************
   41 *
   42 * Documentation copied from JTEngine/api/high_level_api.pl:
   43 *
   44 * Every predicate in the post action part of a
   45 * CT must be tagged with action/1.
   46 * Otherwise ct_apply/1 will throw an exception.
   47 * This design was choosen to be able to give actions
   48 * simple names which are be mapped to full names
   49 * when applied. Ambiguities with Prolog build-ins are avoided.
   50 */
   51
   52action( before(JP, Statements,ForwMethod,ForwBody)) :-              before(JP, Statements,ForwMethod,ForwBody), !.
   53action( after(JP, Statements,ForwMethod,ForwBody)) :-               after(JP, Statements,ForwMethod,ForwBody), !.
   54action( around(JoinPoint, _aroundStmts,_forwMethod,_forwBody)):-    around(JoinPoint,_aroundStmts,_forwMethod,_forwBody).
   55
   56action( add_unboxing_return(_return, _parent, _encl, _expr)):-      add_unboxing_return(_return, _parent, _encl, _expr).
   57%action( add_advice_param_ref(_pc,_adviceParam,_id,_parent,_encl)):- add_advice_param_ref(_pc,_adviceParam,_id,_parent,_encl).
   58%malte
   59action( add_proceed_call(_pc,_call,_parent, _enclMethod,_adviceArgs,_proceedArgs)):-add_proceed_call(_pc,_call, _parent, _enclMethod,_adviceArgs,_proceedArgs).
   60action(add_advice_instance_method_parameters(AdviceInstanceMethod, JP, AdviceParametersAndKinds,Parameters)) :-
   61add_advice_instance_method_parameters(AdviceInstanceMethod, JP, AdviceParametersAndKinds,Parameters).
   62
   63action(join_point_exceptions(JP,Exception)):-join_point_exceptions(JP,Exception).
   64action( concat_lists(A,B)):-    concat_lists(A,B).
   65action( addArgList(FnArgs, PcArgs, Idents, Parent, ForwMethod)):-   addArgList(FnArgs, PcArgs, Idents, Parent, ForwMethod).
   66action( addArg(FnArg,PcArgs,Ident,Parent,ForwMethod)):-             addArg(FnArg,PcArgs,Ident,Parent,ForwMethod).	    
   67action( addParamList(Params, Ids,Parent)) :-                        addParamList(Params, Ids,Parent).
   68action( addParamReferenceList(Refs, Params, Parent,Encl)) :-        addParamReferenceList(Refs, Params, Parent,Encl).
   69action( add_to_class_fq(Class,Member)):-             				add_to_class_fq(Class,Member).
   70action( copy_method_body(Method,BodyToCopy,Body)) :-                copy_method_body(Method,BodyToCopy,Body).
   71action( showError(Kind,ID,Msg)):-                                   showError(Kind,ID,Msg).
   72
   73
   74    
   75
   76
   77/*
   78 * addArgList(FnArgs, PcArgs, Ids, Parent, ForwMethod)
   79 * 
   80 * ACTION
   81 *
   82 * Recursive implementation of addArg/5, first parameter is a list
   83 * insead of on argument.
   84 * see addArg/5 documentation
   85 * for details.
   86 *
   87 */    
   88addArgList([], _, [], _,_).
   89addArgList([FnArg|FnArgs], PcArgs, [Ident|Idents], Parent, ForwMethod) :-
   90    addArg(FnArg,PcArgs,Ident,Parent,ForwMethod),
   91    addArgList(FnArgs, PcArgs, Idents, Parent, ForwMethod).
   92
   93/*
   94 * addArg(+FnArg,+JpArgs,+Ident,+Parent,+ForwMethod)
   95 * 
   96 * ACTION
   97 *
   98 * adds a reference (identT) to an advice parameter.
   99 * Parameters:
  100 *   FnArgs: The selected advice parameter
  101 *   JpArgs: The arguments at the join point (including target and this)
  102 *   Ident:  The new Id
  103 *   Parent: The parent of the Id
  104 *   ForwMethod: The enclosing forwarding method
  105 * 
  106 */    
  107 
  108addArg(FnArg,PcArgs,Ident,Parent,ForwMethod):-
  109    methodT(ForwMethod,_,_,[_This,_Target|ArgParams],_,_,_),
  110    lookupForwParameter(ForwMethod, FnArg,PcArgs,ArgParams,Param, Name),
  111    add(identT(Ident,Parent,ForwMethod,Name,Param)).
  112
  113/*
  114 * add_advice_instance_method_parameters(+AdviceInstanceMethod, +JP, +AdviceParametersAndKinds,ThisType, TargetType, Parameters)
  115 *
  116 * @param AdviceParametersAndKinds [(Param, Kind),...] : Kind = target, this, argument id at join point
  117 */
  118 add_advice_instance_method_parameters(AdviceInstanceMethod, JP, AdviceParametersAndKinds,
  119                                     [ThisParam,TargetParam|ArgParameters]) :-
  120    %get_join_point_arguments(JP, Args), 
  121    local_vars_of_jp(JP, ArgsTemp),
  122    lvar_ids(ArgsTemp,Args2),
  123
  124    getReceiverTypeOrEnclosingIfInAnonymousClass_fq(JP,Type),    
  125  	enclClass(JP, EnclClass),
  126  	(
  127  	anonymousClass(EnclClass) ->
  128  		(
  129  		classT(EnclClass,Parent,_,_),
  130	  	identT(_,Parent,_,_,EnclClassTmp),
  131  		fullQualifiedName(EnclClassTmp,ClassName)
  132  		);
  133  		enclClass_fq(JP,ClassName)
  134  	),  		
  135    get_or_add_parameter(AdviceInstanceMethod,this,AdviceParametersAndKinds, ClassName, ThisParam),
  136    get_or_add_parameter(AdviceInstanceMethod,target,AdviceParametersAndKinds, Type, TargetParam),    
  137    get_or_add_parameter_if_afterThrowingOrReturning_param_exists(	AdviceParametersAndKinds,AfterParam),    
  138    get_or_add_argument_parameters(AdviceInstanceMethod, Args, -1, AdviceParametersAndKinds, CurrentArgParameters),
  139    (
  140    	nonvar(AfterParam)->
  141    		concat_lists([AfterParam,CurrentArgParameters,Args2],ArgParameters) ;
  142    		concat_lists([CurrentArgParameters,Args2],ArgParameters)
  143    ).
  144    
  145
  146/*
  147 *
  148 */
  149get_or_add_argument_parameters(_, [],_, _, []).
  150
  151get_or_add_argument_parameters(AdviceInstanceMethod, [Arg|Args], Num, 
  152                               AdviceParametersAndKinds, [ArgParameter|ArgParameters]) :-
  153    plus(Num, 1, Next),
  154    Arg = lvar(Argument,_),
  155	get_or_add_argument_parameter(AdviceInstanceMethod, Argument, Next, AdviceParametersAndKinds, ArgParameter),
  156	get_or_add_argument_parameters(AdviceInstanceMethod, Args, Next, AdviceParametersAndKinds, ArgParameters).
  157
  158    get_or_add_argument_parameter(_, Argument, _,AdviceParametersAndKinds, ArgParameter):-
  159    memberchk((ArgParameter, Argument),AdviceParametersAndKinds),
  160    !.
  161    
  162
  163%exeption for execution pc
  164get_or_add_argument_parameter(AdviceInstanceMethod, Arg, _Num, _, ArgParameter):-    
  165  	aopT(JP,_,AdviceInstanceMethod),
  166   	methodT(JP,_,_,_,_,_,_),
  167    new_id(ArgParameter),       
  168    paramT(Arg,  _, _, ArgName)    ,
  169    getType(Arg,Type),
  170  	add(paramT(ArgParameter,  AdviceInstanceMethod, Type, ArgName)).
  171    	 
  172    	 
  173get_or_add_argument_parameter(AdviceInstanceMethod, Arg, Num, _, ArgParameter):-
  174    new_id(ArgParameter),
  175    getType(Arg,Type),
  176    get_arg_name(Arg,Num, ArgName),
  177    add(paramT(ArgParameter,  AdviceInstanceMethod, Type, ArgName)). 
  178 
  179
  180
  181get_arg_name(ArgID,Num,ArgName):-    
  182    paramT(ArgID,  _, _, ArgName);
  183    atom_concat('_arg', Num, ArgName).
  184
  185
  186/*
  187  * get_or_add_parameter_if_afterThrowingOrReturning_param_exists(+AdviceParametersAndKinds, -Param)
  188  *
  189  * if the current advice is an afterThrowing oder afterReturning advice, the extra formal will be added to
  190  * the advice method parameters on the thrid position
  191  *
  192  */  
  193  
  194get_or_add_parameter_if_afterThrowingOrReturning_param_exists(AdviceParametersAndKinds, Param) :-
  195    member((Param, extraArg), AdviceParametersAndKinds),
  196    !.
  197
  198get_or_add_parameter_if_afterThrowingOrReturning_param_exists( _, _).
  199
  200 
  201/*
  202 *get_or_add_parameter(_,+Kind,+AdviceParametersAndKinds,_,-Param) :-
  203 */  
  204get_or_add_parameter(_,Kind,AdviceParametersAndKinds,_,Param) :-
  205    member((Param, Kind), AdviceParametersAndKinds),
  206    !.
  207    
  208
  209get_or_add_parameter(AdviceInstanceMethod,'target', _, TargetType, Param) :-
  210	createTargetInstanceParam(TargetType, AdviceInstanceMethod, Param),
  211	!.
  212get_or_add_parameter(AdviceInstanceMethod,'this', _, TargetType, Param) :-
  213	createThisInstanceParam(TargetType, AdviceInstanceMethod, Param),
  214	!.
  215
  216/*
  217 * get_join_point_arguments(JP, Args)
  218 *
  219 */
  220 get_join_point_arguments(JP, Args) :-
  221  methodT(JP,_,_,Args,_,_,_),
  222  !.
  223  
  224get_join_point_arguments(JP, Args) :-
  225  methodCall(JP,_,_,_,_,Method,_),
  226  methodT(Method,_,_,Args,_,_,_),
  227  !.
  228get_join_point_arguments(JP, []) :-
  229  getFieldT(JP,_,_,_,_,_),
  230  !.
  231get_join_point_arguments(JP, [Arg]) :-
  232  setField(JP,_,_,_,_,Arg),
  233  !.
  234  
  235 get_join_point_arguments(_, []).  
  236/*
  237  * join_point_exceptions(+JP, -Exceptions)
  238  *
  239  */
  240
  241join_point_exceptions(JP,Exceptions):-
  242  methodT(JP,_,_,_,_,Exceptions,_).
  243  
  244join_point_exceptions(JP,Exceptions):-
  245	methodCall(JP,_,_,_,_,MID,_),
  246	methodT(MID,_,_,_,_,Exceptions,_).
  247 
  248join_point_exceptions(_,[]).
  249
  250
  251
  252
  253/*
  254 * matches_jp_exceptions(+ExceptionFQ,-ExceptionIDs)
  255 *
  256 * TESTED
  257 */
  258matches_exceptions(ExceptionFQ,ExceptionIDs):-    
  259    fullQualifiedNames(ExceptionIDs,ExceptionsFQ),
  260    memberchk(ExceptionFQ,ExceptionsFQ),
  261    !.
  262    
  263matches_exceptions(ExceptionFQ,[Head | Tail]):-    
  264    fullQualifiedName(Head,FQ),  
  265    (
  266    	subtype_name(FQ,ExceptionFQ); 
  267	    matches_exceptions(ExceptionFQ,Tail)
  268	).
  269
  270matches_exceptions(_,[]):- fail.    
  271    
  272
  273    
  274    
  275
  276/*
  277 * getTargetType(+JpID,-RecieverType)
  278 *
  279 *
  280 */
  281getReceiverType(JpID,RecieverType):-       
  282  applyT(JpID,_,_,_,_,_,Member),
  283  enclClass(Member,EnclClass),
  284  getType(EnclClass,RecieverType).
  285
  286getReceiverType(JpID,RecieverType):-           
  287  getFieldT(JpID,_,_,_,_,Member),
  288  enclClass(Member,EnclClass),
  289  getType(EnclClass,RecieverType).
  290      
  291getReceiverType(JpID,RecieverType):-             
  292  setField(JpID,_,_,_,Member,_),    	
  293  enclClass(Member,EnclClass),
  294  getType(EnclClass,RecieverType).
  295    
  296getReceiverType(JpID,RecieverType):-             
  297  methodT(JpID,_,_,_,_,_,_),
  298  enclClass(JpID,EnclClass),
  299  getType(EnclClass,RecieverType).
  300  
  301  
  302/*
  303 * add_unboxing_return(Return, _parent, EnclMethod, _expr)
  304 *
  305 * ACTION
  306 *
  307 * If EnclMethod has the return type void an empty returnT statment
  308 * with the id Return is created.
  309 * 
  310 * Otherwise the unboxingMethod ct is used to create a method 
  311 * in the enclosing class of EnclMethod which unboxes a 
  312 * the corresponding boxing type of PrimitiveType to
  313 * PrimitiveType, e.g. for the basic type int:
  314 *   public int intValue(Integer integer) { return ... }
  315 *
  316 * TESTED
  317 */
  318add_unboxing_return(Return, Parent, EnclMethod, Expr):-
  319    methodT(EnclMethod,_,_, _,type(basic,void,0),_,_),
  320    !,
  321    deleteTree(Expr), 
  322    add(returnT(Return,Parent,EnclMethod,null)).
  323
  324add_unboxing_return(_return, _parent, _encl, _expr):-
  325    enclClass(_encl,_enclClass),
  326    methodT(_encl,_,_, _,type(basic,_primitiveType,0),_,_),
  327    !,
  328    apply_ct(unboxingMethod(_enclClass,_primitiveType)),
  329    atom_concat(_primitiveType, 'Value', _primitiveTypeValue),
  330    methodT(_unboxingMethod, _enclClass,_primitiveTypeValue,[_],type(basic, _primitiveType, 0),[],_),
  331    new_ids([_apply,_select,_ident]),
  332    atom_concat(_primitiveType,'Value',_methodName),
  333    add(returnT(_return,_parent,_encl,_apply)),
  334      add(applyT(_apply,_return,_encl,_ident,_methodName, [_expr],_unboxingMethod)),
  335          add(identT(_ident,_apply,_encl,'this',_enclClass)),
  336    set_parent(_expr,_apply).
  337
  338add_unboxing_return(_return, _parent, _encl, _expr):-
  339    add(returnT(_return,_parent,_encl,_expr)).
  340  
  341%/*
  342% * add_advice_param_ref(JoinPoint,AdviceParam,Id,Parent,EnclMethod)
  343% *
  344% * ACTION
  345% * 
  346% * creates a reference (identT) to the advice 
  347% * parameter "AdviceParam" with the id "Id".
  348% */
  349%
  350%add_advice_param_ref(JP,_adviceParam,_id,_parent,_encl):-
  351%    getForwParam(_pc, _adviceParam, _param,_name),
  352%    add(identT(_id,_parent,_encl,_name,_param)).
  353    
  354    /*
  355 * showError(+Kind, +ID,+Msg)
  356 * 
  357 * ACTION
  358 */
  359showError(_,ID,Msg):-    
  360	var(ID),
  361	write('ID NOT BOUND: '),
  362	write(Msg),
  363	flush_output.
  364
  365showError(Kind, ID,Mesg):-
  366    not(sourceLocation(ID, _,_,_)),
  367    enclMethod(ID,Meth),
  368    method(Meth,Class,Name,_,_,_,_),
  369    fullQualifiedName(Class,Fqn),
  370    format('~w in method ~w.~w: ~w~nCannot find source location: Probably generated by aspect.~n~n',[Kind,Fqn,Name,Mesg]).
  371    
  372
  373showError(Kind,ID,Msg):-    
  374    enclMethod(ID,Meth),
  375    method(Meth,Class,Name,_,_,_,_),
  376    fullQualifiedName(Class,Fqn),
  377    format('~w in method ~w.~w  ',[Kind,Fqn,Name]),
  378    sourceLocation(ID, File,Start,_),
  379    format('(~w:~w)~n~n~w~n', [File,Start,Msg]),
  380    gen_tree(ID),
  381    flush_output,
  382
  383    /*
  384    * Added Dec 20, 2004 to store all errors/warnings
  385    * and move it to the Eclipse Problems View. (AL)
  386    */
  387    assert(isErrorWarningMessage(Kind, ID, Msg)).
  388    
  389    
  390/*
  391 * addParamList(+Params, +Ids,+Parent)
  392 *
  393 * ACTION
  394 */
  395
  396addParamList([],[],_).
  397addParamList([Param|Params], [Id|Ids],Parent) :-
  398    paramT(Param,_,Type,Name),
  399    add(paramT(Id,Parent,Type,Name)),
  400    addParamList(Params, Ids,Parent).    
  401    
  402/*
  403 * addParamReferenceList(+Refs, +Params, +Parent,+Encl)
  404 *
  405 * ACTION
  406 * Adds a list of parameter accesses.
  407 * Parent is the parent id and Encl the 
  408 * enclosing id of the created identT/5 facts.
  409 */
  410addParamReferenceList([], [], _Parent,_Encl).
  411
  412addParamReferenceList([Ref|Refs], [Param|Params], Parent,Encl) :-
  413    paramT(Param,_,_,Name),
  414    add(identT(Ref,Parent,Encl,Name,Param)),
  415	addParamReferenceList(Refs, Params, Parent,Encl).
  416    
  417    
  418    
  419    
  420    
  421/*
  422 * add_to_class_fq(+Class,+Member|+MemberList)
  423 * 
  424 * ACTION
  425 * Adds Member(s) to the class, if the Member is not already in the 
  426 * member list.
  427 * Fails if Class or Member is not bound and if Class is not a
  428 * of type classT.
  429 *
  430 * TESTED
  431 */
  432add_to_class_fq(_, []):- !.
  433add_to_class_fq(Class, [Member|Rest]) :-
  434    add_to_class_fq(Class,Member),
  435    add_to_class_fq(Class,Rest).
  436
  437add_to_class_fq(_class, _id) :-
  438    nonvar(_class),
  439    nonvar(_id),
  440    java_fq(classT(_class, _, _, _members)),
  441    member(_id, _members),
  442    !.
  443    
  444add_to_class_fq(_class, _id) :-
  445    nonvar(_class),
  446    nonvar(_id),
  447    java_fq(classT(_class, _p,_n,_members)),
  448    delete(java_fq(classT(_class, _p,_n,_members))),
  449    append(_members, [_id], _newMembers),
  450    add(java_fq(classT(_class, _p, _n, _newMembers))).
  451 
  452add_to_class_fq(_class, _id) :-
  453    sformat(Msg,'the class ~w could not be found in add_to_class',[_class]),
  454    t_i_based_error_handling(Msg).
  455    
  456
  457/************************** CT CONDITIONS (cond/1) *************************/
  458
  459/*
  460 * bindForwMethod(+JoinPoint,-ForwardingMethod,-Body)
  461 *
  462 * CONDITION
  463 *
  464 * binds forwarding method and body to
  465 * new ids.
  466 * In the case of a execution pointcut
  467 * on the body is bound.
  468 */
  469/*
  470bindForwMethod(_Method,_Method,_Body):-
  471% special case for the execution pointcut
  472    methodT(_Method,_,_,_,_,_,_),
  473    !,
  474    new_id(_Body).
  475
  476bindForwMethod(_,_forwMethod,_forwBody):-
  477    new_ids([_forwMethod,_forwBody]).
  478*/
  479/*
  480 * extract_class_name(+FQN,-Package, -ClassName)
  481 *
  482 * CONDITION
  483 * Atom operation. Binds ClassName to 
  484 * atom part right from most right '.'.
  485 *
  486 * e.g.: class_name('pckg1.pckg2.Class1','pckg1.pckg2','Class1').
  487 *
  488 * TESTED
  489 */
  490
  491extract_class_name(FQN, _PackageName, _ClassName) :-
  492	var(FQN),
  493	throw('INTERNAL ERROR: extract_class_name failed').
  494
  495extract_class_name(FQN, Package, ClassName) :-
  496    extract_class_name_(FQN, FQN, Package, ClassName).
  497	
  498extract_class_name_(FQN, ClassNameTmp, Package, ClassName) :-
  499    concat(_,'.',ClassNameTmp2,ClassNameTmp),
  500    !,
  501    extract_class_name_(FQN, ClassNameTmp2, Package, ClassName).
  502    
  503extract_class_name_(FQN, ClassName, Package,ClassName):-
  504    concat(Package, '.', ClassName, FQN),
  505    !.
  506extract_class_name_(_, ClassName, '',ClassName).   
  507   
  508/*** DYNAMIC PREDICATES ***************************************/
  509
  510:- multifile fieldAccess/2.  511:- multifile action/1.  512
  513/*
  514 * forwarding(Forwarding, LastForwarding,Jp)
  515 * 
  516 * except for the first fact:
  517 * forwarding(Forwarding,Jp,Jp)
  518 */
  519:- dynamic forwarding/3.  520:- dynamic forwarding/1.  521
  522/*
  523 * forwards(LastCall, LastForwarding, Kind, Jp)
  524 *
  525 * LastCall: the call at the real join point
  526 * LastForwarding: the method called by this call
  527 * Kind: getField | setField | execution | methodCall
  528 */
  529:- dynamic forwards/4.  530:- dynamic pointcut/1.  531:- dynamic visibility/3.  532:- dynamic laj_ct_list/1.  533:- multifile laj_ct_list/1.  534:- dynamic laj_binding_transfer/3.  535
  536/*** AUXILIARY PREDICATES ***************************************/
  537  
  538/*
  539 * replaceStatementWithForwarding(JoinPoint) 
  540 *
  541 * see replaceStatementWithForwarding(JoinPoint,ForwMethod,ForwBody).
  542 */
  543 
  544replaceStatementWithForwarding(JP) :-
  545    replaceStatementWithForwarding(JP,_,_).
  546
  547/*
  548 * replaceStatementWithForwarding(JoinPoint,ForwMethod,ForwBody) 
  549 *
  550 * Replaces a Joinpoint execution with the call of a forwarding method.
  551 * 
  552 * If ForwMethod and ForwBody are not bound they are bound to new ids.
  553 * Then, a new forwarding method is created
  554 * 
  555 */
  556
  557replaceStatementWithForwarding(JP,ForwMethod,ForwBody) :-
  558    bindIdIfNeeded(ForwMethod),
  559    bindIdIfNeeded(ForwBody),
  560    (
  561        (forwards(RealJP, _, _,JP),!);
  562        JP = RealJP
  563    ),
  564    enclClass(RealJP, EnclClass),
  565    !,
  566    createForwardingMethod(RealJP, EnclClass,ForwMethod,ForwBody),
  567    add_encl_meth_params(RealJP).
  568
  569/*
  570 * add_encl_meth_params(+Pc) 
  571 */
  572add_encl_meth_params(JP):-
  573    forwards(_,_,execution,JP),
  574    !.
  575    %throw('add_encl_meth_params not allowed for execution').
  576 
  577add_encl_meth_params(JP):-
  578    forwards(_call,LastForwMethod,Kind,JP),
  579    pc_param_num(JP,Kind,PN),
  580    add_encl_params_to_forw_if_need(JP,PN,LastForwMethod).
  581    
  582/*
  583 * add_encl_params_to_forw_if_need(+Pc,+PN,+ForwMethod)
  584 *
  585 * Add parameters of the enclosing method at the
  586 * real pointcut to the forwarding methods.
  587 * This predicate is TODO (X,X equiv. to. X)
  588 */
  589
  590add_encl_params_to_forw_if_need(_,_,ForwMethod):-
  591 	not(methodT(ForwMethod,_,_,_,_,_,_)),
  592 	!.
  593 	
  594 	add_encl_params_to_forw_if_need(_,PN,ForwMethod):-
  595    methodT(ForwMethod,_,_,Params,_,_,_),
  596    length(Params,PN),
  597    !.
  598 	
  599add_encl_params_to_forw_if_need(Pc,PN,ForwMethod):-
  600    methodT(ForwMethod,Class,Name,Params,Type,Exc,Body),
  601	getRealEncl(Pc,ForwMethod,RealEncl),
  602	methodT(RealEncl,_,_,EnclParams,_,_,_),
  603	copy_params(EnclParams,CopiedParams,ForwMethod),
  604	concat_lists([Params,CopiedParams],NewParams),
  605	replace(methodT(ForwMethod,Class,Name,Params,Type,Exc,Body),
  606    	    methodT(ForwMethod,Class,Name,NewParams,Type,Exc,Body)),
  607% replace forwarding call
  608    applyT(Apply,Parent,Encl,Expr,Name,Args,ForwMethod),
  609	
  610    methodT(RealEncl, _,_,RealParams,_,_,_),
  611    length(RealParams,Len),
  612  
  613    create_refs_to_encl_params(Encl,Len,Refs),
  614	concat_lists([Args,Refs],NewArgs),
  615	replace(applyT(Apply,Parent,Encl,Expr,Name,Args,ForwMethod),
  616    	    applyT(Apply,Parent,Encl,Expr,Name,NewArgs,ForwMethod)),
  617    forwarding(ForwMethod,LastForwMethod,Pc),
  618    add_encl_params_to_forw_if_need(Pc,PN,LastForwMethod).
  619
  620
  621/*
  622 * 	copy_params(+EnclParams,?CopiedParams,+ForwMethod)
  623 * 
  624 *  ?f CopiedParams is not bound, new ids will be created for 
  625 *  the new parameters.
  626 */
  627copy_params([],[],_NewEncl).
  628copy_params([Param|Params],[Copy|Copies],NewEncl):-
  629    (var(Copy)-> 
  630       new_id(Copy);true),
  631    paramT(Param,_,Type,Name),
  632    add(paramT(Copy,NewEncl,Type,Name)),
  633    copy_params(Params,Copies,NewEncl).
  634
  635/*
  636 * create_refs_to_encl_params(+Encl,+Len,-Refs)
  637 *
  638 * create idents which reference the Len-length tail 
  639 * of parameters of the method Encl.
  640 */
  641
  642create_refs_to_encl_params(Encl,Len,Refs) :-
  643    methodT(Encl, _,_,Params,_,_,_),
  644    tail(Params,Len,Tail),
  645	create_ref_idents(Tail,Refs).
  646
  647create_ref_idents([],[]).
  648create_ref_idents([Param|Params],[Ref|Refs]):-
  649	paramT(Param,Parent,_,_),
  650	createIdentRefParam(Param,Parent,Ref),
  651	create_ref_idents(Params,Refs).
  652   
  653/*
  654 * pc_param_num(+Pc,+Kind,?PN)
  655 */
  656pc_param_num(_Pc,getField,2).
  657pc_param_num(_Pc,setField,3).
  658pc_param_num(Pc,methodCall,PN) :-
  659    (applyT(Pc,_,_,_,_,Args,_);
  660     newClassT(Pc,_,_,_,Args,_,_,_)),
  661    getRealEncl(Pc,_,RealEncl),
  662    methodT(RealEncl,_,_,Params,_,_,_),
  663    length(Params,ParamsLen),
  664    length(Args,ArgsLen),
  665    plus(2,ArgsLen,Tmp),
  666    plus(Tmp,ParamsLen,PN).
  667
  668pc_param_num(Pc,execution,PN) :-
  669    methodT(Pc,_,_,Args,_,_,_),
  670    length(Args,ArgsLen),
  671    plus(2,ArgsLen,PN).
  672      
  673
  674/*
  675 * Encloses current body with a try finally block and inserts 
  676 * 
  677 * 
  678 Umschlie�e aktuellen Body mit einem try .. finally block und f�ge _insert in den finally Block ein,
  679 * wenn _insert ein Block ist wird insert als finally block eingef�gt.
  680c */
  681
  682addTryFinallyBlockStmts(_,_, []).
  683addTryFinallyBlockStmts(_forwMethod,_finallyBlock, _stmts) :-
  684    addTryFinallyBlock(_forwMethod,_finallyBlock),
  685    prependBlockStatments(_finallyBlock, _stmts).
  686
  687addTryFinallyBlock(_forwMethod,_finallyBlock):-
  688    new_ids([_try, _tryBlock]),
  689    methodT(_forwMethod,_,_,_,_,_,_block),
  690    blockT(_block, _parent, _encl, _stats), % die id des blocks wird dem try zugewiesen
  691    set_parent(_stats, _tryBlock),
  692    delete(blockT(_block, _parent, _encl, _stats)),
  693    add(blockT(_block, _parent,_encl,[_try])),
  694        add(tryT(_try, _block,_encl,_tryBlock, [],_finallyBlock)),
  695            add(blockT(_tryBlock, _try,_encl,_stats)),
  696            add(blockT(_finallyBlock, _try, _encl, [])).
  697
  698/*
  699aroundTryFinallyBlock(_block, _finallyBlock) :-
  700    blockT(_finallyBlock,_,_,_),
  701    !,
  702    new_ids([_try, _tryBlock]),
  703    blockT(_block, _parent, _encl, _stats), % die id des blocks wird dem try zugewiesen
  704    set_parent(_stats, _tryBlock),
  705    retractall(blockT(_block, _,_,_)),
  706    assert(blockT(_block, _parent,_encl,[_try])),
  707        assert(tryT(_try, _block,_encl,_block, [],_finallyBlock)),
  708            assert(blockT(_tryBlock, _try,_encl,_stats)),
  709            set_parent(_finallyBlock, _try),
  710            set_encl_method(_finallyBlock, _encl).
  711
  712aroundTryFinallyBlock(_block, _insert) :-
  713    new_ids([_try, _tryBlock, _finallyBlock]),
  714    blockT(_block, _parent, _encl, _stats), % die id des blocks wird dem try zugewiesen
  715    set_parent(_stats, _tryBlock),
  716    retractall(blockT(_block, _,_,_)),
  717    assert(blockT(_block, _parent,_encl,[_try])),
  718        assert(tryT(_try, _block,_encl,_tryBlock, [],_finallyBlock)),
  719            assert(blockT(_tryBlock, _try,_encl,_stats)),
  720            assert(blockT(_finallyBlock, _try, _encl, [])),
  721%    set_parent(_insert,_finallyBlock),
  722    prependBlockStatment(_finallyBlock, _insert).
  723*/
  724
  725
  726createAdviceMethod(JP,Statements,ForwMethod,ForwBody):-
  727   enclClass(JP,Class),
  728   add(methodT(ForwMethod,Class,'advice',_,_,_,ForwBody)),
  729   add(blockT(ForwBody,ForwMethod,ForwMethod,Statements)).
  730
  731
  732/*
  733 * createThisOrGetReceiver(OldParent, NewParent, Encl, OldReceiver, NewReceiver, DeclaringType) 
  734 */
  735
  736createThisOrGetReceiver(Parent, _newParent, _encl, null, Receiver,DeclaringType) :-
  737%    getFieldT(_ident, Parent, _encl, 'null', _name, _sym),
  738    enclClass(_encl,Anonym),
  739    classT(Anonym,NewClass,_,_),
  740    newClassT(NewClass,_,NewClassEncl,_,_,TypeExpr,_,_),
  741    getType(TypeExpr,type(class, Type,0)),
  742    not(subtype(Type,DeclaringType)),
  743    !,
  744    enclClass(NewClassEncl, Outer),
  745    
  746    (var(Receiver) -> new_id(Receiver);true),
  747    fullQualifiedName(Outer,FQN),
  748    new_id(SelectedTypeExpr),
  749    add(selectT(Receiver,Parent,EnclMethod,'this', SelectedTypeExpr, Outer)),  
  750    add(identT(SelectedTypeExpr, Receiver, EnclMethod, FQN,Outer)).
  751
  752
  753
  754createThisOrGetReceiver(_Parent, NewParent, Encl, null, Receiver,_DeclaringType) :-
  755    !,
  756    enclClass(Encl, EnclClass),
  757    new_id(Receiver),
  758    create_this_or_null_if_static(Receiver,NewParent, Encl, EnclClass).
  759
  760createThisOrGetReceiver(_Parent, NewParent, _encl, Receiver, Receiver,_DeclaringType) :-
  761%createThisOrGetReceiver(GetField, NewParent, Receiver,_DeclaringType) :-
  762    !,
  763    set_parent(Receiver, NewParent).
  764
  765/*
  766 * create_this_or_null_if_static(ID,Parent,EnclMethod,EnclClass)
  767 *
  768 * Will create a reference to this, if EnclMethod is not a static method.
  769 * Otherwise a null ident will be created.
  770 * Will create a new ID, if ID is not bound!
  771 */ 
  772create_this_or_null_if_static(ID, Parent, EnclMethod, _EnclClass):-
  773    modifierT(EnclMethod,'static'),
  774    !,
  775    (var(ID) -> new_id(ID);true),
  776    add(identT(ID, Parent, EnclMethod, 'null', 'null')).
  777
  778create_this_or_null_if_static(ID, Parent, EnclMethod, EnclClass):-
  779    (var(ID) -> new_id(ID);true),
  780    add(identT(ID, Parent, EnclMethod, 'this', EnclClass)).
  784createForwBody(_get, _forwMethod, _forwBody, _ForwName, [_thisParam,_recvParam],/* _Type*/type(basic, void, 0), _execReturn) :-
  785    getFieldT(_get, _parent, _enclMethod, _origReceiver,  _origName, _field),
  786    !,
  787    new_ids([_forwCall, _forwMethIdent]),
  788    fieldT(_field, DeclaringType, _Type, _origName, _),
  789    forwardingMethodName(_get, 'get$', _origName, _ForwName),
  790    enclClass(_enclMethod,_enclClass), %neu
  791    createForwMethParams(_enclClass,_forwMethod,DeclaringType, _origReceiver, [],[_thisParam,_recvParam]),
  792    createIdentRefParam(_recvParam,_callSelect, _forwReceiver),
  793%createThisOrGetReceiver(OldParent, NewParent, Encl, OldReceiver, NewReceiver, DeclaringType)     
  794    createThisOrGetReceiver(_parent, _forwCall, _enclMethod,_origReceiver,_receiver,DeclaringType),
  795    replaceId(_parent, _get, _forwCall),
  796    delete(getFieldT(_get, _parent, _enclMethod, _origReceiver,  _origName, _field)),
  797    create_this_or_null_if_static(_this,_forwCall, _enclMethod, _enclClass), %neu
  798    add(getFieldT(_get, _execReturn, _forwMethod, _forwReceiver, _origName, _field)),
  799    add(applyT(_forwCall, _parent,_enclMethod, 'null', _ForwName, [_this,_receiver],_forwMethod)),
  800    updateForwardsFact(_get,getField,_forwCall,_forwMethod).
  801
  802createForwBody(_set, _forwMethod, _forwBody, _ForwName, [_thisParam,_recvParam,_valueParam],  /*FieldType*/type(basic, void, 0), _execReturn) :-
  803    setField(_set, _parent, _enclMethod, _origReceiver, _field,_value),
  804    !,
  805    new_ids([_forwCall, _forwMethIdent, _selectField,_valueParam]),
  806    assignT(_set, _, _enclMethod, _lhs, _),
  807    fieldT(_field, DeclaringType, _FieldType, _origName, _),
  808    getType(_value,_Type),
  809    forwardingMethodName(_set,'set$', _origName, _ForwName),
  810    enclClass(_enclMethod,_enclClass), %neu
  811    createForwMethParams(_enclClass,_forwMethod,DeclaringType,_origReceiver, [],[_thisParam,_recvParam]),
  812    createIdentRefParam(_recvParam,_callSelect, _forwReceiver),
  813 %createThisOrGetReceiver(OldParent, NewParent, Encl, OldReceiver, NewReceiver, DeclaringType)     
  814    createThisOrGetReceiver(_parent, _forwCall, _enclMethod,_origReceiver,_receiver,DeclaringType),
  815    replaceId(_parent, _set, _forwCall),
  816    set_parent(_value, _forwCall),
  817    deleteTree(_lhs),
  818    add(paramT(_valueParam, _forwMethod, _Type, '_value')),
  819    createIdentRefParam(_valueParam,_set, _forwValue),
  820    create_this_or_null_if_static(_this,_forwCall, _enclMethod, _enclClass), %neu
  821    action(replace(assignT(_set, _execReturn, _forwMethod, _selectField, _forwValue))),
  822      add(getFieldT(_selectField, _set, _forwMethod, _forwReceiver, _origName, _field)),
  823    add(applyT(_forwCall, _parent,_enclMethod, 'null',_ForwName, [_this,_receiver,_value],_forwMethod)),
  824    updateForwardsFact(_set,setField,_forwCall,_forwMethod).
  825
  826createForwBody(_call, _forwMethod, _forwBody, _ForwName, [_thisParam|[_recvParam|_forwParams]], Type, _execReturn) :- %neu
  827    (
  828    	(applyT(_call,_parent,_enclMethod,_expr,_origName,_args, _method_constr),
  829    	 method(_method_constr,_,_,_,Type,_,_));
  830	    (newClassT(_call,_parent,_enclMethod,_method_constr,_args,_,_,_),
  831	    _expr = null,
  832	    constructor(_method_constr,ConstrClass,_,_,_),
  833	    Type = type(class,ConstrClass,0),
  834	     _origName = 'init')
  835	),
  836    !,
  837    debugme,
  838    getOrigArgs(_call,_args,_origArgs),
  839    new_ids([_forwCall, _forwMethIdent]),
  840%    applyT(_call, _parent, _enclMethod, _origReceiver, _),
  841    forwardingMethodName(_call, 'call$',_origName, _ForwName),
  842    enclClass(_enclMethod,_enclClass), %neu
  843    methodT(_method_constr,DeclaringType,_,_,_,_,_),
  844    createForwMethParams(_enclClass,_forwMethod,DeclaringType,_expr,_origArgs,[_thisParam|[_recvParam|_forwParams]]),
  845    replaceId(_parent, _call, _forwCall),
  846    getOrigParams(_call,[_thisParam|[_recvParam|_forwParams]],_origParams),
  847    replaceForwCall(_call, _parent, _method_constr, _origName, _execReturn, _forwMethod,_origParams,_recvParam),
  848    createForwArgs(_call,_enclMethod,_enclClass,_forwCall,_expr,_args,_forwArgs,DeclaringType),
  849    set_parent(_forwArgs,_forwCall),
  850    add(applyT(_forwCall, _parent,_enclMethod, 'null', _ForwName, _forwArgs,_forwMethod)),
  851    updateForwardsFact(_call,methodCall,_forwCall,_forwMethod).
  852
  853% execution
  854createForwMethodExecution(_method, _forwBody,_forwStmts) :- %neu
  855    methodT(_method, _class, _origName, _origParams, _type, _exceptions, _body),
  856    (interfaceT(_class)->
  857    	(fullQualifiedName(_class,FQN),sformat(Msg,'execution pointcut on interfaces not legal in LAJ: ~w',[FQN]),
  858    	 throw(Msg));true
  859    ),	
  860    new_ids([_forwCall, _forwMethIdent,_forwMethod]),
  861
  862%    applyT(_method, _parent, _method, _origReceiver, _),
  863    forwardingMethodName(_method, 'exec$',_origName, _forwName),
  864    enclClass(_method,_class), %neu
  865
  866% ersetzte alte Methode mit neuem Namen
  867    rec_set_encl_method(_body,_forwMethod),
  868    set_parent(_body,_forwMethod),
  869    
  870    cloneParams(_method, _origParams,_newParams),
  871    createThisInstanceParam(_class,_forwMethod,_thisVarDef),   
  872%    createTargetInstanceParam(_class, _forwMethod, 'null',_targetVarDef),
  873    createTargetInstanceParam(_class, _forwMethod, _targetVarDef),
  874    set_parent(_origParams,_forwMethod),
  875    rec_set_encl_method(_origParams,_forwMethod),
  876
  877    delete(methodT(_method, _class, _origName, _origParams, _type, _exceptions, _body)),
  878
  879    add(methodT(_method, _class, _origName, _newParams, _type, _exceptions, _forwBody)),
  880    add(methodT(_forwMethod, _class, _forwName, [_thisVarDef | [_targetVarDef |_origParams]], _type, _exceptions, _body)),
  881
  882    cloneModifier(_method,_forwMethod),
  883    add_to_class(_class, _forwMethod),
  884
  885    % add forwarding call
  886    ((_forwStmts == []) -> (
  887        new_ids([_execReturn,_thisIdent,_targetIdent]),
  888
  889        reccreateVarDefIdents(_forwCall, _newParams,_forwArgs),
  890        rec_set_encl_method(_forwArgs,_method),
  891        add(applyT(_forwCall, _execReturn,_method, 'null', _forwName, [_thisIdent| [_targetIdent | _forwArgs]], _forwMethod)),
  892        create_this_or_null_if_static(_thisIdent,   _forwCall, _method,  _class),
  893        create_this_or_null_if_static(_targetIdent, _forwCall, _method,  _class),
  894        createReturnOrExec(_forwBody, _forwMethod, _type, _forwCall, _execReturn),
  895        _bodyStmts = [_execReturn]
  896    );
  897        _bodyStmts = _forwStmts
  898    ),
  899    add(blockT(_forwBody, _method,_method, _bodyStmts)),%neu
  900    updateForwardsFact(_method,execution,_method,_forwMethod).
  901
  902
  903
  904createAroundBody(_call, _forwMethod, _forwBody, _ForwName,_forwParams, _Type) :-
  905    applyT(_call,_parent,_enclMethod,_expr,_origName,_args, _method),
  906    !,
  907    getOrigArgs(_call,_args,_origArgs),
  908    new_ids([_forwCall, _forwMethIdent]),
  909%    applyT(_call, _parent, _enclMethod, _origReceiver, _),
  910    method(_method, DeclaringType, _origName, _, _Type, _exc, _),
  911    forwardingMethodName(_call, 'call$',_origName, _ForwName),
  912    enclClass(_enclMethod,_enclClass),
  913    createForwMethParams(_enclClass,_forwMethod,DeclaringType,_expr,_origArgs,_forwParams),
  914    replaceId(_parent, _call, _forwCall),
  915    createForwArgs(_call,_enclMethod,_enclClass,_forwCall,_origReceiver,_args,_forwArgs,DeclaringType),
  916    set_parent(_forwArgs,_forwCall),
  917    add(applyT(_forwCall, _parent,_enclMethod, 'null', _ForwName, _forwArgs, _forwMethod)),
  918%    retractall(applyT(_call, _,_,_,__,_)), %new: remove old forwarding Appl
  919    updateForwardsFact(_call,methodCall,_forwCall,_forwMethod).%new: update
  920
  921
  922replaceForwCall(_call, _parent, _method, _origName, _execReturn,_forwMethod,_forwParams,_recvParam):-
  923    applyT(_call,_,_,_,_,_,_),
  924      createIdentRefParam(_recvParam,_callSelect, _forwReceiver),
  925      createVarDefIdents(_call, _forwParams, _argsInForw),
  926    action(replace(applyT(_call, _execReturn, _forwMethod, _forwReceiver,_origName, _argsInForw,_method))).
  927
  928replaceForwCall(_call, _parent, _method, _origName, _execReturn,_forwMethod,_forwParams,_recvParam):-
  929    newClassT(_call,_,_,Constructor,_,TypeExpr,Def,Enclosing),
  930    createVarDefIdents(_call, _forwParams, _argsInForw),
  931    action(replace(newClassT(_call, _execReturn, _forwMethod, Constructor,_argsInForw,TypeExpr,Def,Enclosing))).			    
  932
  933
  934createForwArgs(_call,_,_,_,_,_Args,_Args,_):-
  935    forwards(_call,_,_,_),
  936    !.
  937createForwArgs(_call,_enclMethod,_enclClass,_forwCall,_origReceiver,_Args,[_This|[Receiver|_Args]],DeclaringType):-
  938    create_this_or_null_if_static(_This,_forwCall, _enclMethod, _enclClass),
  939    ( 
  940      (_origReceiver = null,
  941   %createThisOrGetReceiver(OldParent, NewParent, Encl, OldReceiver, NewReceiver, DeclaringType)     
  942      createThisOrGetReceiver(_parent, _forwCall, _enclMethod,_origReceiver,Receiver,DeclaringType)
  943      
  944%       create_this_or_null_if_static(Receiver,_forwCall, _enclMethod, _enclClass)
  945      );
  946      _origReceiver = Receiver
  947    ).
  948    %createThisOrGetReceiver(_origReceiver, _forwCall,_Receiver).
  949
  950
  951getOrigParams(_call,_Params,_Params):-
  952    forwards(_call,_,_,_),
  953    !.
  954
  955getOrigParams(_,[_|[_|_ForwParams]],_ForwParams).
  956
  957
  958getOrigArgs(_call,_args,_OrigArgs) :-
  959    forwards(_call,_,_,_),
  960    !,
  961    _args = [_|[_|_OrigArgs]].
  962
  963getOrigArgs(_call,_Args,_Args).
  964/*
  965 * updateForwardsFact(+Call,+Kind,+ForwCall,+ForwMethod)
  966 */
  967updateForwardsFact(_call,_,_forwCall,_forwMethod):-
  968    forwards(_call,_lastForwMethod,_kind,_pc),
  969    !,
  970    delete(forwards(_call,_lastForwMethod,_kind,_pc)),
  971    add(forwards(_forwCall, _forwMethod, _kind, _pc)),
  972    add(forwarding(_forwMethod, _lastForwMethod,_pc)).
  973%    add(forwarding(_forwCall)).
  974
  975updateForwardsFact(_stmt,_kind, _forwCall,_forwMethod):-
  976    add(forwards(_forwCall, _forwMethod, _kind, _stmt)),
  977    add(forwarding(_forwMethod, _stmt,_stmt)).
  978%    add(forwarding(_forwCall)).
  979
  980/*
  981 * createForwardingMethod(Stat,Class,ForwMethod,ForwBody)
  982 *
  983 * Creates a forwarding method 
  984 *
  985 */
  986createForwardingMethod(_method, _class,_,_forwBody) :-
  987    methodT(_method,_class,_,_,_,_,_),
  988    !,
  989    createForwMethodExecution(_method, _forwBody,[]).
  990
  991createForwardingMethod(Stat,Class,ForwMethod,ForwBody) :-
  992    new_id(_execReturn),
  993    enclosing(Stat,EnclMethod),
  994    createForwBody(Stat, ForwMethod, ForwBody, ForwName, _params, Type, _execReturn),
  995    createReturnOrExec(ForwBody, ForwMethod, Type, Stat, _execReturn),
  996    add_to_class(Class, ForwMethod),
  997    add(methodT(ForwMethod, Class, ForwName, _params, Type, [], ForwBody)),
  998	share_static_modifier(EnclMethod,ForwMethod),
  999    add(modifierT(ForwMethod, 'private')),
 1000    add(blockT(ForwBody, ForwMethod, ForwMethod, [_execReturn])).
 1001
 1002
 1003
 1004createAroundMethod(Stat, Class,ForwStats,ForwMethod,ForwBody) :-
 1005%    new_ids([ForwMethod, ForwBody]),
 1006    enclosing(Stat,EnclMethod),
 1007    createAroundBody(Stat, ForwMethod, ForwBody, ForwName, _params, Type),
 1008%    createReturnOrExec(ForwBody, ForwMethod, Type, Stat, _execReturn),
 1009    add_to_class(Class, ForwMethod),
 1010    add(methodT(ForwMethod, Class, ForwName, _params, Type, [], ForwBody)),
 1011	share_static_modifier(EnclMethod,ForwMethod),
 1012    add(modifierT(ForwMethod, 'private')),
 1013    add(blockT(ForwBody, ForwMethod, ForwMethod, ForwStats)).
 1014
 1015
 1016share_static_modifier(EnclMethod,ForwMethod):-
 1017    modifierT(EnclMethod,'static'),
 1018    !,
 1019    add(modifierT(ForwMethod, 'static')).
 1020share_static_modifier(_EnclMethod,_ForwMethod):-
 1021    true.
 1022
 1023debugme(_id):-
 1024    format('~ndebug: ~w',[_id]),
 1025    flush_output.
 1026
 1027forwardingMethodName(_stat, _prefix, _origName, _ForwName) :-
 1028    new_id(_aNumber),
 1029    int2string(_aNumber, _aString),
 1030    stringAppend(_origName,'$',_aString,_forwName),
 1031    appendForwPrefix(_stat,_prefix, _forwName,_ForwName).
 1032
 1033appendForwPrefix(_stat,_, _forwName,_forwName):-
 1034    forwards(_stat,_,_,_),
 1035    !.
 1036
 1037appendForwPrefix(_stat,_prefix, _forwName,_ForwName) :-
 1038    stringAppend(_prefix, _forwName, _ForwName).
 1039%    stringAppend('forward$', _prefix, _forwName, _ForwName).
 1040
 1041    %    add(_Receiver, _apply, _encl, 'this', _enclClass).
 1042
 1043/*
 1044 * prependBlockStatments(+Block, +Statements)
 1045 *
 1046 * prepends the id list Statements to block Block.
 1047 */
 1048
 1049prependBlockStatments(_, []).
 1050
 1051prependBlockStatments(_block, _stmts) :-
 1052    blockT(_block, _parent, _encl, _oldStmts),
 1053    append(_stmts,_oldStmts,_newStmts),
 1054    delete(blockT(_block, _parent, _encl, _oldStmts)),
 1055    add(blockT(_block, _parent, _encl, _newStmts)).
 1056
 1057prependBlockStatment(_block, _pre) :-
 1058    blockT(_block, _parent, _encl, _stats),
 1059    prepend(_stats, _pre, _newStats),
 1060%    rec_set_encl_method(_pre, _encl),
 1061%    rec_set_parent(_pre, _block),
 1062    delete(blockT(_block, _parent, _encl, _stats)),
 1063    add(blockT(_block, _parent, _encl, _newStats)).
 1064
 1065
 1066appendBlockStatment(_block, _post) :-
 1067    blockT(_block, _parent, _encl, _stats),
 1068    append(_stats, [_post], _newStats),
 1069    rec_set_encl_method(_post, _encl),
 1070    rec_set_parent(_post, _block),
 1071    delete(blockT(_body, _p, _e, _stats)),
 1072    add(blockT(_body, _p, _e, _newStats)).
 1073
 1074
 1075/*
 1076 * matchParams(ParametersOrArgs, PatternList)
 1077 * 
 1078 * matches a parameter/expression list with a pattern list or
 1079 * with the types of another list of parameters/expressions.
 1080 *
 1081 * The PatternList elements of the following terms:
 1082 *
 1083 * id(FQN):     
 1084 *            FQN is a full qualified name of a object or basic type.
 1085 * list(PList):  
 1086 *            PList is a list of parameters.
 1087 *            If PList is not bound it will be bound to a list of parameters, 
 1088 *            otherwise the types of the parameters list are compared, see tests for examples.
 1089 *
 1090 * TESTED?
 1091 */
 1092matchParams([], []):-!.
 1093
 1094matchParams([], [id([Term])]) :-
 1095	var(Term).	
 1096
 1097
 1098matchParams([], [Term]) :-
 1099	var(Term).
 1100
 1101matchParams([VdHead | VdTail], [Term | PatTail]) :-
 1102    nonvar(Term),
 1103    Term = type(Type),
 1104    getType_fq(VdHead,Type),
 1105    matchParams(VdTail,  PatTail).
 1106
 1107
 1108
 1109matchParams([VdHead | VdTail], [Term | PatTail]) :-
 1110    nonvar(Term),
 1111    Term = params([Head|Tail]),
 1112    (
 1113      var(Head) ->
 1114        Head = VdHead;
 1115        (getType(Head,Type),getType(VdHead,Type))
 1116    ),
 1117    matchParams(VdTail, [params(Tail) | PatTail]).
 1118
 1119matchParams(VdHead, [Term | PatTail]) :-
 1120    nonvar(Term),
 1121    Term = params([]),
 1122    matchParams(VdHead, PatTail).
 1123
 1124
 1125
 1126
 1127matchParams([VdHead | VdTail], [List | PatTail]) :-
 1128    nonvar(List),
 1129    List = [_pattern , VdHead],
 1130    !,
 1131    matchParams([VdHead | VdTail], [_pattern | PatTail]).
 1132
 1133matchParams([VdHead | VdTail], [TypePattern | PatTail]) :-
 1134    nonvar(TypePattern),
 1135    TypePattern = typePattern(_pattern, _dim),
 1136    getType(VdHead, type(_kind, _id,_dim)),
 1137    getTypeName(type(_kind, _id,_dim), _name),
 1138    matchPatterns(_name, _pattern),
 1139    matchParams(VdTail, PatTail).
 1140
 1141matchParams([_VdHead | VdTail], [Term | PatTail]) :-
 1142	var(Term),
 1143    matchParams(VdTail,PatTail).
 1144    
 1145/*
 1146 * matchLMVPattern(ParametersOrArgs, PatternList)
 1147 * 
 1148 * matches a PEF-list with a pattern list or
 1149 * 
 1150 * The PatternList elements of the following terms:
 1151 *
 1152 * id(FQN):     
 1153 *            FQN is a full qualified name of a object or basic type.
 1154 * list(PList):  
 1155 *            PList is a list of parameters.
 1156 *            If PList is not bound it will be bound to a list of parameters, 
 1157 *            otherwise the types of the parameters list are compared, see tests for examples.
 1158 *
 1159 * TESTED
 1160 */
 1161
 1162
 1163
 1164matchLMVPattern([], []):-!.
 1165
 1166matchLMVPattern(_Head, [Term | _Tail]) :-
 1167    var(Term),
 1168    throw('Elements of the right list must be id/1 or list terms/1.').
 1169
 1170matchLMVPattern([VdHead | VdTail], [Term | PatTail]) :-
 1171    Term = id(VdHead),
 1172    matchLMVPattern(VdTail,  PatTail).
 1173
 1174matchLMVPattern([Head | VdTail], [Term | PatTail]) :-
 1175    Term = list([Head|Tail]),
 1176    matchLMVPattern(VdTail, [list(Tail) | PatTail]).
 1177
 1178matchLMVPattern(VdHead, [Term | PatTail]) :-
 1179    Term = list([]),
 1180    matchLMVPattern(VdHead, PatTail).
 1181
 1182	
 1183    
 1184matchParamTypeNameList([],[]).
 1185matchParamTypeNameList([Head | Tail],[FNHead|FNTail]):-
 1186    paramT(Head,_,Type,_),
 1187    getTypeName(Type,FNHead),
 1188	matchParamTypeNameList(Tail,FNTail).
 1189	
 1190matchPatterns(_, []).
 1191matchPatterns(_name, (_pat1;_pat2)) :-
 1192    !,(
 1193    matchPatterns(_name, _pat1);
 1194    matchPatterns(_name, _pat2)
 1195    ).
 1196
 1197matchPatterns(_name, (_pat1,_pat2)) :-
 1198    !,
 1199    matchPatterns(_name, _pat1),
 1200    matchPatterns(_name, _pat2).
 1201
 1202matchPatterns(_name, _pat) :-
 1203    pattern(_pat, _, _name).
 1204
 1205
 1206weave(before, _pc,_exec):-
 1207    before(_pc, _exec).
 1208
 1209weave(after, _pc,_exec):-
 1210    after(_pc, _exec).
 1211
 1212
 1213
 1214
 1215
 1216
 1217callToAdviceMethod(_pc, _adviceMeth, _adviceArgs,_exec,_forwMethod,_forwBody) :-
 1218    (replaceStatementWithForwarding(_pc,_forwMethod,_forwBody); true),
 1219    methodT(_adviceMeth,Aspect,_adviceMethName, _,_,_,_),
 1220    fieldT(_adviceInstanceVar,Aspect,_,'aspectInstance',_),
 1221    classT(Aspect,_,AdviceName,_),
 1222    new_ids([_exec, _apply, _selectAdviceMethod,_selectInstField, _ident]),
 1223    enclMethod(_pc,_enclMethod),
 1224    createIdentsReferencingAdviceParams(_pc, _enclMethod,_adviceArgs, _adviceCallArgs),
 1225    add(execT(_exec, 0,0, _apply)),
 1226    add(applyT(_apply, _exec,0, _selectInstField,_adviceMethName, _adviceCallArgs,_adviceMeth)),
 1227    add(getFieldT(_selectInstField, _apply, 0, _ident, 'aspectInstance',_adviceInstanceVar)),
 1228    add(identT(_ident, _selectInstField, 0, AdviceName, Aspect)).
 1229
 1230
 1231createIdentsReferencingAdviceParams(_,_,[],[]).
 1232
 1233createIdentsReferencingAdviceParams(_call,_enclMethod,[_adviceArg|_adviceArgs],[_Ident|_Idents]):-
 1234    new_id(_Ident),
 1235    getForwParam(_call, _adviceArg, _param,_name),
 1236    add(identT(_Ident, _call, _enclMethod, _name, _param)),
 1237    createIdentsReferencingAdviceParams(_call,_enclMethod,_adviceArgs,_Idents).
 1238    
 1239/*
 1240 * boxing_class(+BasicType, ?BoxingClass)
 1241 *
 1242 * Binds BoxingClass to the corresponding
 1243 * boxing class of the basic type BasicType.
 1244 */
 1245
 1246boxing_class(int, _class):-
 1247    packageT(_pckg, 'java.lang'),
 1248    classT(_class,_pckg,'Integer',_).
 1249    
 1250boxing_class(double, _class):-
 1251    packageT(_pckg, 'java.lang'),
 1252    classT(_class,_pckg,'Double',_).
 1253boxing_class(float, _class):-
 1254    packageT(_pckg, 'java.lang'),
 1255    classT(_class,_pckg,'Float',_).
 1256boxing_class(char, _class):-
 1257    packageT(_pckg, 'java.lang'),
 1258    classT(_class,_pckg,'Character',_).
 1259boxing_class(byte, _class):-
 1260    packageT(_pckg, 'java.lang'),
 1261    classT(_class,_pckg,'Byte',_).
 1262boxing_class(short, _class):-
 1263    packageT(_pckg, 'java.lang'),
 1264    classT(_class,_pckg,'Short',_).
 1265boxing_class(long, _class):-
 1266    packageT(_pckg, 'java.lang'),
 1267    classT(_class,_pckg,'Long',_).
 1268boxing_class(boolean, _class):-
 1269    packageT(_pckg, 'java.lang'),
 1270    classT(_class,_pckg,'Boolean',_).
 1271boxing_class(Kind, _class):-
 1272	sformat(Msg, 'ERROR: Could not find boxing class for ~w~n', [Kind]),
 1273	throw(Msg).
 1274
 1275
 1276add_proceed_call_idents(_,_,_,_,[],[],_,[]).
 1277add_proceed_call_idents(_pc,_call,_enclMethod, _adviceArgs, [_param|_params], [_forwParam|_forwParams], _proceedArgs,[_proceedArg|_Args]):-
 1278    getCompareElement(_pc,_param,_forwParam, _compare),
 1279    findProceedArg(_pc,_compare,_adviceArgs, _proceedArgs,_proceedArg),
 1280%    getForwParam(_pc, _adviceArg, _compare,_),
 1281    !,
 1282    add_proceed_call_idents(_pc,_call,_enclMethod, _adviceArgs, _params,_forwParams, _proceedArgs,_Args).
 1283
 1284add_proceed_call_idents(_pc,_call,_enclMethod, _adviceArgs, [_param|_params], [_forwParam|_forwParams], _proceedArgs,[_Arg|_Args]):-
 1285    new_id(_Arg),
 1286    !,
 1287    getCompareElement(_pc,_param,_forwParam, _ref),
 1288    getRefIdentName(_ref,_name),
 1289    add(identT(_Arg, _call, _enclMethod, _name, _ref)),
 1290    add_proceed_call_idents(_pc,_call,_enclMethod, _adviceArgs, _params,_forwParams, _proceedArgs,_Args).
 1291
 1292
 1293getRefIdentName(_ref,_name):-
 1294    localT(_ref, _, _, _, _name, _).
 1295getRefIdentName(_ref,_name):-
 1296    paramT(_ref, _, _, _name).
 1297getRefIdentName(_ref,'this'):-
 1298    classT(_ref, _, _, _).
 1299
 1300
 1301getCompareElement(_method,_param, _, _class):-
 1302     method(_method, _class, _, _, _, _, _),
 1303     forwards(_, _forwMethod, _, _method),
 1304     method(_forwMethod, _, _, _params, _, _, _),
 1305    (
 1306        _params = [_param|_];
 1307        _params = [_|[_param|_]]
 1308    ),
 1309    !.
 1310
 1311getCompareElement(_method,_, _forwParam,_forwParam):-
 1312    method(_method, _, _, _, _, _, _),
 1313    !.
 1314
 1315getCompareElement(_pc,_param,_, _param).
 1316
 1317
 1318findProceedArg(_pc,_compare,[_adviceArg|_adviceArgs], [_proceedArg|_proceedArgs],_proceedArg) :-
 1319    getForwParam(_pc, _adviceArg, _compare,_),
 1320    !.
 1321
 1322findProceedArg(_pc,_compare,[_|_adviceArgs], [_|_proceedArgs],_proceedArg) :-
 1323    findProceedArg(_pc,_compare,_adviceArgs, _proceedArgs,_proceedArg).
 1324
 1325
 1326createForwMethParams(_enclClass,_forwMethod,_DeclaringType,_origReceiver, _args,
 1327                     [_InstanceVarDef|[_ReceiverVarDef|_Params]]):-
 1328    validThisType(_enclClass,ValidEnclClass),
 1329    createThisInstanceParam(ValidEnclClass, _forwMethod, _InstanceVarDef),
 1330    (_origReceiver == null ->
 1331	  outerOrEnclClass(_enclClass,ValidTargetClass);
 1332	  getType(_origReceiver,type(class, ValidTargetClass,_))
 1333	),
 1334    createTargetInstanceParam(ValidTargetClass,_forwMethod, _ReceiverVarDef),
 1335%    createTargetInstanceParam(_enclClass, _forwMethod, _origReceiver, _ReceiverVarDef),
 1336    createForwParams(_forwMethod, _args, _Params).
 1337
 1338validThisType(EnclClass,Type):-
 1339    classT(EnclClass, Parent,_,_),
 1340    newClassT(Parent,_,_,_,_,TypeExpr,_,_),
 1341    getType(TypeExpr, type(class,Type,0)),
 1342%    extendsT(EnclClass,Super),
 1343%    enclClass(Parent,EnclOuterClass),
 1344    !.
 1345validThisType(EnclClass,EnclClass).
 1346
 1347/*
 1348 * outerOrEnclClass(+EnclClass,OuterClass)
 1349 *
 1350 * bind outer class if available, otherwise
 1351 * the second arg is bound to the first arg
 1352 */
 1353 
 1354outerOrEnclClass(EnclClass,OuterClass):-
 1355    classT(EnclClass,NewClass,_,_),
 1356    newClassT(NewClass,_,NewClassEncl,_,_,_,_,_),
 1357    enclClass(NewClassEncl,OuterClass),
 1358    !.
 1359outerOrEnclClass(EnclClass,EnclClass).
 1360
 1361
 1362
 1363createThisInstanceParam(_enclClass,_forwMethod,_InstanceVarDef):-
 1364    new_id(_InstanceVarDef),
 1365    add(java_fq(paramT(_InstanceVarDef, _forwMethod, _enclClass, '_this'))).
 1366
 1367
 1368createTargetInstanceParam(DeclaringType, _forwMethod, _ReceiverVarDef):-
 1369    new_id(_ReceiverVarDef),
 1370    add(java_fq(paramT(_ReceiverVarDef,  _forwMethod, DeclaringType, '_target'))),
 1371    !.
 1372
 1373/*
 1374createTargetInstanceParam(_enclClass, _forwMethod, 'null',_ReceiverVarDef):-
 1375    new_id(_ReceiverVarDef),
 1376    add(paramT(_ReceiverVarDef,  _forwMethod, type(class,_enclClass,0), '_target')),
 1377    !.
 1378createTargetInstanceParam(_enclClass, _forwMethod, _origReceiver,_ReceiverVarDef):-
 1379    new_id(_ReceiverVarDef),
 1380    getType(_origReceiver, _type),
 1381    add(paramT(_ReceiverVarDef,  _forwMethod, _type, '_target')).
 1382*/
 1383
 1384createForwParams(_forwMethod, _args, _Params) :-
 1385    createForwParams(_forwMethod, _args, _Params,0).
 1386
 1387createForwParams(_, [],[],_).
 1388createForwParams(_forwMethod, [_arg|_args], [_Param | _Params],_counter) :-
 1389    createForwParam(_forwMethod,_arg, _Param,_counter),
 1390    plus(_counter, 1, _next),
 1391    createForwParams(_forwMethod, _args, _Params,_next).
 1392
 1393createForwParam(_forwMethod, _arg, _Param,_counter) :-
 1394    getType(_arg,type(basic,null,0)),
 1395    !,
 1396    fullQualifiedName(JLO, 'java.lang.Object'),
 1397    new_id(_Param),
 1398    append_num('x', _counter, _name),
 1399    add(paramT(_Param, _forwMethod,type(class,JLO,0), _name)),
 1400    !.
 1401
 1402createForwParam(_forwMethod, _arg, _Param,_counter) :-
 1403    getType(_arg,_type),
 1404    new_id(_Param),
 1405    append_num('x', _counter, _name),
 1406    add(paramT(_Param, _forwMethod, _type, _name)),
 1407    !.
 1408
 1409% DEBUG commented
 1410
 1411getForwParam(_method, _adviceArg, _IdentRef,_IdentName):-
 1412    % Ausnahme fuer den execution pointcut
 1413    methodT(_method, _class, _, _params, _, _, _),
 1414    !,
 1415    forwards(_, _forwMethod, _, _method),
 1416    methodT(_forwMethod, _, _, [_|[_|_origParams]], _, _, _),
 1417    findParamExecution(_adviceArg,_class,_params,_origParams,_IdentName,_IdentRef).
 1418
 1419
 1420getForwParam(Pc, _adviceArg, _forwParam,_forwParamName):-
 1421    forwards(_forwCall, _forwMethod, _, Pc),
 1422    methodT(_forwMethod, _, _, [_thisParam|[_targetParam|_params]], _, _, _),
 1423    applyT(_forwCall, _,_, _, _,[_|[_|_args]],_),
 1424    getRealEncl(Pc,_,RealEncl),
 1425    methodT(RealEncl,_,_,EnclParams,_,_,_),
 1426    length(EnclParams,NumEnclParams),
 1427    remove_tail(_args,NumEnclParams,ArgListWithoutEnclParams),
 1428    concat_lists([ArgListWithoutEnclParams,EnclParams],SearchList),
 1429    findParam(_adviceArg,_thisParam,_targetParam,_params,SearchList,_forwParam),
 1430    paramT(_forwParam, _,_type, _forwParamName).
 1431
 1432findParamExecution('_this',_class, _,_,'this',_class):- !.
 1433findParamExecution('_target',_class,_,_,'this',_class):- !.
 1434findParamExecution(_param,_class,_params,_origParams, _forwParamName,_Param):-
 1435    _param \= '_this',
 1436    _param \= '_target',
 1437    findParam(_param,_,_,_params,_origParams,_Param),
 1438    paramT(_Param, _, _type, _forwParamName).
 1439
 1440
 1441findParam('_this',_ThisParam,_,_,_,_ThisParam):-
 1442    !.
 1443findParam('_target',_,_TargetParam,_,_,_TargetParam):-
 1444    !.
 1445findParam(_arg,_,_,[_Param|_params],[_arg1|_args],_Param):-
 1446    _arg \= '_this',
 1447    _arg \= '_target',
 1448    _arg == _arg1,
 1449    !.
 1450findParam(_arg,_thisParam,_targetParam,[_param|_params],[_a|_args],_ForwParam):-
 1451    !,
 1452    findParam(_arg,_thisParam,_targetParam,_params,_args,_ForwParam).
 1453
 1454/*
 1455  pc_visible(?Encl,?Class, ?Package)
 1456
 1457  Is true when a join point (pointcut) is visible
 1458  */
 1459
 1460pc_visible(_encl,_,_):-
 1461    enclClass(_encl,_enclClass),
 1462    modifierT(_enclClass,'aspect'),
 1463    !,
 1464    fail.
 1465
 1466pc_visible(_encl,_,_):-
 1467    not(visibility(_encl,_,_)),
 1468    !.
 1469
 1470pc_visible(_encl,_,_):-
 1471    visibility(_encl,'hidden',_),
 1472    !,
 1473    fail.
 1474
 1475pc_visible(_encl,_,_pckg):-
 1476    visibility(_encl,'package',_pckg),
 1477    !.
 1478    
 1479pc_visible(_encl,_currentAspectClass,_):-
 1480    visibility(_encl,'protected',_aspectClass),
 1481    !,
 1482    subtype(_currentAspectClass,_aspectClass).
 1483
 1484pc_visible(_encl,_aspectClass,_):-
 1485    visibility(_encl,'private',_aspectClass),
 1486    !.
 1487
 1488
 1489set_visibility(_pc, _type, _ref):-
 1490    forwards(_,_forwMethod,_,_pc),
 1491    !,
 1492    add(visibility(_forwMethod, _type, _ref)).
 1493
 1494set_visibility(_var, _type, _ref):-
 1495    add(visibility(_var, _type, _ref)).
 1496
 1497
 1498%    current_aspect(_aspectClass,_).
 1499
 1500%TODO: erzeuge Argument-Listen: TESTEN
 1501
 1502create_ref_idents(_pc, _apply, _encl, [], []).
 1503
 1504create_ref_idents(_pc, _apply, _encl, [_param_id|_rest], [_ident_id | _rest_ids]) :-
 1505    paramT(_param_id,_,_, _name),
 1506    !,
 1507    add(identT(_ident_id, _apply, _encl, _name, _param_id)),
 1508    create_ref_idents(_pc, _apply, _encl, _rest, _restids).
 1509
 1510% leere Parameter oder Argumentliste
 1511create_ref_idents(_pc, _apply, _encl, [[]|_rest], [[] | _rest_ids]) :-
 1512    !,
 1513    create_ref_idents(_pc, _apply, _encl, _rest, _restids).
 1514
 1515create_ref_idents(_pc, _apply, _encl, [_fn |_rest], [GetField | _rest_ids]) :-
 1516    not(tree(_fn,_,_)),
 1517    encl_class(_encl,_encl_class),
 1518    resolve_field(_fn,_encl_class,_field),
 1519    add(getFieldT(GetField, _apply, _encl, 'null',_fn, _field)),
 1520    create_ref_idents(_pc, _apply, _encl, _rest, _restids).
 1521
 1522create_ref_idents(_pc, _apply, _encl, [_arg_id|_rest], [GetField | _rest_ids]) :-
 1523    add_advice_param_ref(_pc, _arg_id,GetField,_apply, _encl),
 1524    create_ref_idents(_pc, _apply, _encl, _rest, _restids).
 1525
 1526create_ref_idents(_pc, _apply, _encl, [[_h |_t] | _rest], [ _param_ids | _rest_ids]) :-
 1527    !,
 1528    create_ref_idents(_pc, _apply, _encl, [_h|_t], _param_ids),
 1529    create_ref_idents(_pc, _apply, _encl, _rest, _restids).
 1530
 1531
 1532
 1533% leere Parameter oder Argumentliste
 1534extract_types(_encl_class, [], []).
 1535extract_types(_encl_class, [[]|_rest], [[] | _Rest]) :-
 1536    !,
 1537    create_ref_idents(_encl, _rest, _Rest).
 1538
 1539extract_types(_encl, [_fn|_rest], [_Type | _Rest]) :-
 1540    not(tree(_fn,_,_)),
 1541    !,
 1542    encl_class(_encl,_encl_class),
 1543    resolve_field(_fn,_encl_class,_field),
 1544    fieldT(_field,_,_Type, _,_),
 1545    create_ref_idents(_encl, _rest, _Rest).
 1546
 1547extract_types(_encl, [_arg|_rest], [_Type | _Rest]) :-
 1548    get_type(_arg,_Type),
 1549    create_ref_idents(_encl, _rest, _Rest).
 1550
 1551extract_types(_encl, [[_h |_t] | _rest], _Rest) :-
 1552
 1553    !,
 1554    create_ref_idents(_encl, [_h | _t], _rest_1),
 1555    create_ref_idents(_encl, _rest, _rest2),
 1556    append(_rest_1,_rest_2, _Rest).
 1557    
 1558
 1559constructor(_constructor,_class,_params):-
 1560    methodT(_constructor,_class,'<init>', _paramsConstructor,_,[],_),
 1561    matchParams(_params, _paramsConstructor).
 1562
 1563
 1564lookupForwParameter(Arg,_,[],[],_, _):-
 1565    format('forwarding parameter lookup failed: ~w~n',[Arg]).
 1566lookupForwParameter(_,FnArg,[FnArg|_],[Param|_],Param, Name):-
 1567    paramT(Param,_,_,Name).
 1568lookupForwParameter(ForwMethod,FnArg,[_|PcArgs],[_|ArgParams],Param, Name):-
 1569    lookupForwParameter(ForwMethod,FnArg,PcArgs,ArgParams,Param, Name).
 1570   
 1571    
 1572copy_method_body(Method,BodyToCopy,Body):-
 1573    cloneTree(BodyToCopy, Method, Method, Body).
 1574
 1575
 1576/*
 1577 * bindIdIfNeeded(ID) 
 1578 *
 1579 * Binds ID with new_id/1 if ID is a variable.
 1580 */
 1581bindIdIfNeeded(ID) :-
 1582    var(ID),
 1583    !,
 1584    new_id(ID).
 1585bindIdIfNeeded(_ID).
 1586
 1587/*
 1588 * apply_aj_cts.
 1589 * 
 1590 * debugging predicate
 1591 * applies all cts in the laj_ct_list 
 1592 * fact in the given order.
 1593 */
 1594apply_aj_cts :-
 1595    rollback,
 1596    apply_ct(change_aspect_class_member_visibility),
 1597    laj_ct_list(A),
 1598    apply_ctlist(A)
 1599    %apply_ct(resolve_no_call_invocations)
 1600    .
 1601    
 1602getReceiverTypeOrEnclosingIfInAnonymousClass_fq(ID,RecieverType_fq):-
 1603    java_fq(methodT(ID,RecieverType_fq,_,_,_,_,_)).
 1604
 1605
 1606%--ma statements 
 1607getReceiverTypeOrEnclosingIfInAnonymousClass_fq(ID,RecieverType_fq):-
 1608    statement(ID),
 1609    enclClass_fq(ID,RecieverType_fq).
 1610   
 1611    
 1612
 1613getReceiverTypeOrEnclosingIfInAnonymousClass_fq(ID,RecieverType_fq):-
 1614    getReceiver(ID, Rec),
 1615    (
 1616    Rec = 'null' ->
 1617       getNonAnonymousEnclosingClass_fq(ID,RecieverType_fq);
 1618       getType_fq(Rec,RecieverType_fq)
 1619    )    
 1620   	.
 1621   	
 1622% getReceiverTypeOrEnclosingIfInAnonymousClass_fq(ID,RecieverType_fq):-
 1623%    applyT(ID, _parent, _encl, _Receiver, 'super', _args,_method),
 1624%
 1625%    (
 1626%    Rec = 'null' ->
 1627%       getNonAnonymousEnclosingClass_fq(ID,RecieverType_fq);
 1628%       getType_fq(Rec,RecieverType_fq)
 1629%    )    
 1630%   	.
 1631      
 1632getNonAnonymousEnclosingClass_fq(Id,Class_fq):- 
 1633    enclClass(Id,Encl),
 1634	(
 1635		anonymousClass(Encl) ->
 1636		(
 1637			classT(Encl,Parent,_,_),
 1638			enclClass(Parent,ParentOfParent),
 1639			getNonAnonymousEnclosingClass_fq(ParentOfParent,Class_fq)
 1640		);
 1641		fullQualifiedName(Encl,Class_fq)
 1642	)
 1643	.
 1644	
 1645
 1646/*
 1647 * getReturnType(+ID, -TypeString)
 1648 *
 1649 * Returns the return type
 1650 *
 1651 */     
 1652    
 1653getReturnType(ID,Type):-
 1654    getType_fq(ID,Type).
 1655
 1656    %mappeltauer: why did i use this definition before?
 1657	% enclClass(ID,Class),
 1658	% fullQualifiedName(Class,Type).   
 1659      
 1660anonymousClass(ID):-
 1661	classT(ID,Parent,_,_),     
 1662  	newClassT(Parent,_,_,_,_,_,_,_).
 1663  	
 1664
 1665
 1666
 1667/*
 1668 * local_vars_of_jp_rek(+[IDs],-[LocalVars])
 1669 *
 1670 * collects all local variables of a joinpoint, which could
 1671 * be a whole block since LAJ2, in a list
 1672 * see LAJ-87
 1673 */          	
 1674local_vars_of_jp(Jp,Vars):-
 1675 methodT(Jp,_,_,Args,_,_,_),
 1676 local_defs_of_jp([Jp],Blacklist),
 1677 %local_vars_of_jp([Jp],LocalVars,Blacklist),
 1678 local_vars_of_jp(Args,Vars,[]).
 1679 %concat_lists([LocalVars,LocalVars2],Vars).
 1680
 1681local_vars_of_jp(Jp,LocalVars):-
 1682 local_defs_of_jp([Jp],Blacklist),
 1683 local_vars_of_jp([Jp],LocalVars,Blacklist).
 1684
 1685
 1686 
 1687local_vars_of_jp([],[],Blacklist):-!.
 1688local_vars_of_jp([ID|IDs],LocalVars,Blacklist) :-
 1689    local_var(ID,Ref),
 1690    not(memberchk(Ref,Blacklist)),
 1691        
 1692    tree_name(ID,Name),
 1693    local_vars_of_jp(IDs,List,Blacklist),
 1694    !,
 1695    concat_lists([lvar(Ref,Name)|List],LocalVarsTmp),
 1696    list_to_set_save(LocalVarsTmp,LocalVars)
 1697    .    
 1698
 1699local_vars_of_jp([ID|IDs],LocalVars,Blacklist) :-
 1700    local_var(ID,Ref),
 1701    memberchk(Ref,Blacklist),        
 1702    local_vars_of_jp(IDs,LocalVarsTmp,Blacklist),
 1703    !,
 1704    list_to_set_save(LocalVarsTmp,LocalVars)
 1705    .    
 1706    
 1707    
 1708    
 1709local_vars_of_jp([H|T],List,Blacklist) :-
 1710    not( local_var(H,_)),
 1711    sub_trees(H,Subtrees),
 1712    concat_lists([T|Subtrees],VarList),
 1713    local_vars_of_jp(VarList,List,Blacklist)
 1714    .
 1715
 1716local_defs_of_jp([],[]).
 1717local_defs_of_jp([Id|Ids],List) :-
 1718    localT(Id,_,_,_,_,_),
 1719    local_defs_of_jp(Ids, NewList),    
 1720    !,
 1721    concat_lists([Id,NewList],List)
 1722   
 1723    .
 1724
 1725local_defs_of_jp([H|T],List) :-
 1726    sub_trees(H,Subtrees),
 1727    concat_lists([T,Subtrees],VarList),
 1728    local_defs_of_jp(VarList,List)
 1729    .
 1730
 1731lvar_ids([],[]).
 1732lvar_ids([Lvar|Lvars],Ids) :-
 1733    Lvar = lvar(Id,_),
 1734    lvar_ids(Lvars,OtherIds),    
 1735    concat_lists([Id,OtherIds],Ids)   
 1736    .
 1737
 1738%----------
 1739% The following predecates sould be better placed into JTransformer or st.java
 1740% since they are very general queries
 1741
 1742    
 1743local_var(ID,Ref):-
 1744    identT(ID,_,_,_,Ref),
 1745    localT(Ref,_,_,_,_,_).
 1746  
 1747
 1748local_var(ID,Ref):-
 1749    identT(ID,_,_,_,Ref),
 1750    paramT(Ref,_,_,_).
 1751 
 1752
 1753local_var(Ref,Ref):-    
 1754    paramT(Ref,_,_,_).
 1755 
 1756
 1757   		
 1758/*
 1759 * tree_names(+[IDS],-[Names])
 1760 *
 1761 * returns the corresponding string values of the tree elements
 1762 */
 1763 
 1764tree_names([],[]).
 1765    
 1766tree_names([Arg|Args],Names):-
 1767    tree_name(Arg,Name),
 1768    tree_names(Args,NewNames),
 1769    concat_lists([Name,NewNames],Names).   
 1770
 1771/*
 1772 * tree_name(+ID,-Name)
 1773 *
 1774 * returns the corresponding string value of a tree element
 1775 */
 1776  
 1777tree_name(Arg,Name):-
 1778    paramT(Arg,_,_,Name).
 1779      	
 1780tree_name(ID,Name):-
 1781    identT(ID,_,_,_,Ref),
 1782    localT(Ref,_,_,_,Name,_).  
 1783
 1784tree_name(ID,Name):-
 1785    localT(ID,_,_,_,Name,_).  
 1786
 1787tree_name(ID,Name):-
 1788    identT(ID,_,_,_,Ref),
 1789    paramT(Ref,_,_,Name).  	
 1790  
 1791tree_name(ID,_):-    
 1792    treeSignature(ID,Signature),
 1793    stringAppend('cannot assign a string to id: ',Signature,Message),
 1794    throw(Message).
 1795 
 1796
 1797
 1798block_stmt(Id):-  blockT(Id,_,_,_). 
 1799block_stmt(Id):-  forLoopT(Id,_,_,_,_,_,_).
 1800block_stmt(Id):-  doLoopT(Id,_,_,_,_).
 1801block_stmt(Id):-  whileLoopT(Id,_,_,_,_).
 1802block_stmt(Id):-  ifT(Id,_,_,_,_,_).
 1803block_stmt(Id):-  switchT(Id,_,_,_,_).
 1804block_stmt(Id):-  tryT(Id,_,_,_,_,_).
 1805block_stmt(Id):-  catchT(Id,_,_,_,_).
 1806 
 1807 
 1808 
 1809
 1810 
 1811 
 1812 
 1813 
 1814 
 1815 
 1816 
 1817 
 1818    
 1819/*
 1820 * advice(ID, Name, [Arg,...])
 1821 */
 1822 
 1823/*
 1824 * created_by_advice(AdviceId, ForwId)
 1825 */ 
 1826
 1827 /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++not used anymore*/
 1828 
 1829/*
 1830 * add_proceed_call(+JoinPoint,+Id,+Parent,+EnclMethod,+AdviceArgs,+ProceedArgs)
 1831 *
 1832 * ACTION
 1833 *
 1834 * inserts a proceed call with the id "Id" to the last forwarding method
 1835 * created for "JoinPoint".
 1836 *
 1837 */
 1838/*add_proceed_call(_method,_call, _parent, _enclMethod,_adviceArgs,_proceedArgs):-
 1839    method(_method, _, _, _forwParams, _, _, _),
 1840    !,
 1841    forwards(_method,_methodToCall,_,_),
 1842    method(_methodToCall, _, Name, [_this|[_target|_params]], _, _, _),
 1843    add_proceed_call_idents(_method,_call,_enclMethod,_adviceArgs,  [_this|[_target|_params]],  [_this|[_target|_forwParams]],_proceedArgs,_args),
 1844    add(applyT(_call, _parent,_enclMethod, _expr, Name,_args,_methodToCall)),
 1845    add(forwarding(_call)).
 1846
 1847add_proceed_call(_pc,_call, _parent, _enclMethod,_adviceArgs,_proceedArgs):-
 1848    forwarding(_enclMethod,_methodToCall,_),
 1849    method(_enclMethod, _, _, _params, _, _, _),
 1850    method(_methodToCall, _, _name, _, _, _, _),
 1851    add_proceed_call_idents(_pc,_call,_enclMethod,_adviceArgs, _params, _params,_proceedArgs,_args),
 1852    add(applyT(_call, _parent,_enclMethod, 'null',_name, _args, _methodToCall)),
 1853    add(forwarding(_call)).
 1854    
 1855    
 1856    */
 1857 
 1858/*around(Method,AroundStmts,_,ForwBody) :-
 1859% special case: execution pointcut
 1860    methodT(Method,_,_,_,_,_,_),
 1861    createForwMethodExecution(Method, ForwBody, AroundStmts).
 1862
 1863around(_stat,_aroundStmts,_forwMethod,_forwBody) :-
 1864    (
 1865        (
 1866            not(forwards(_,_,_,_stat)),
 1867            replaceStatementWithForwarding(_stat)
 1868        );
 1869        true
 1870    ),
 1871    getRealStat(_stat,_realStat),
 1872    enclClass(_realStat, _enclClass),
 1873    createAroundMethod(_realStat, _enclClass, _aroundStmts,_forwMethod,_forwBody).
 1874  */ 
 1875  /*
 1876 * around(Joinpoint,Statements,ForwardingMethod,ForwardingBody)
 1877 *
 1878 * If this is the first advice for Joinpoint,
 1879 * the Joinpoint is moved to a forwarding method.
 1880 *
 1881 * The following is done in both cases:
 1882 * A new forwarding method is created and the list Statements
 1883 * is added to the body of the method.
 1884 *
 1885 * ForwardingMethod and ForwardingBody were bound 
 1886 * in ct the condition part by the predicate bindForwMethod/3.
 1887 */
 1888
 1889
 1890
 1891%around(JP,Statements,ForwMethod, ForwBody) :-
 1892%   createAdviceMethod(JP, Statements, ForwMethod, ForwBody),
 1893%  add(aopT(JP,'around', ForwMethod)).
 1894    
 1895   
 1896/*
 1897 *  before(Joinpoint, Statements, ForwardingMethod, ForwardingBody)
 1898 *
 1899 * ACTION
 1900 *
 1901 * If this is the first advice for Joinpoint,
 1902 * the Joinpoint is moved to a forwarding method.
 1903 *
 1904 * The following is done in both cases:
 1905 * A new forwarding method to the last created forwarding 
 1906 * method (lets call it "forw_last") is created.
 1907 * Before the call to forw_last the 
 1908 * the list "Statements" is inserted into the method body.
 1909 *
 1910 * ForwardingMethod and ForwardingBody were bound 
 1911 * in the ct condition part by the predicate bindForwMethod/3.
 1912 */
 1913    
 1914/*before(JP, Statements,ForwMethod,ForwBody) :-
 1915    (replaceStatementWithForwarding(JP,ForwMethod,ForwBody);true),
 1916    prependBlockStatments(ForwBody, Statements).
 1917*/
 1918%before(JP, Statements,ForwMethod,ForwBody) :-    
 1919%  createAdviceMethod(JP, Statements,ForwMethod,ForwBody),
 1920%  add(aopT(JP,'before',ForwMethod)).
 1921
 1922
 1923
 1924
 1925/*
 1926 *  after(Joinpoint, Statements, ForwardingMethod, ForwardingBody)
 1927 *
 1928 * ACTION
 1929 *
 1930 * Documentation see before/4, except the statements
 1931 * are inserted after the call to forw_last.
 1932 * Precisely: A try finally block is inserted around
 1933 * the forw_last call and the "Statements" are inserted into the
 1934 * finally block.
 1935 */
 1936/*
 1937after(_stat, _insertList,_forwMethod,_finallyBlock) :-
 1938    new_id(_forwBody),
 1939    (replaceStatementWithForwarding(_stat,_forwMethod,_forwBody);true),
 1940    addTryFinallyBlockStmts(_forwMethod, _finallyBlock, _insertList).
 1941*/    
 1942    
 1943%after(JP,Statements,ForwMethod,ForwBody) :-
 1944%  createAdviceMethod(JP, Statements,ForwMethod,ForwBody),
 1945%  add(aopT(JP,'after',ForwMethod)).