views:

175

answers:

1

Background

This question relates to the new Cirrus infrastructure for Aspect Oriented Programming in Delphi Prism.

I currently have an aspect which I am Auto-Injecting into a class and am attempting to modify the target code using aMethod.SetBody function. I have structured my code thus far using the Logging example code found on the Cirrus Introduction documentation wiki as a basis.

Question

How can I access the Result of the function being injected into, both with and without the original function body being executed?

I would like to be able to set the result of the function bypassing the call to OriginalBody in one code path and as the other code path to call the OriginalBody and use the subsequent Result of the OriginalBody in my Aspect code. I originally thought that this might be the intended purpose of the Aspects.RequireResult method but this appears to force execution of the OriginalBody in my case, causing code duplication.

+2  A: 

Do you mean something like this ?

Original method :-

method Something.SomeMethod(a:Integer;b:Integer;c:Integer): Integer;
begin
    result:=b+c;
end;

New method:-

begin
 if (a > 0) then 
 begin
   result := (b + c);
   exit
   end;
 begin
 result := 1000;
 exit
end

The method level aspect for that would look like this

  [AttributeUsage(AttributeTargets.Method)]
  Class1Attribute = public class(System.Attribute,
    IMethodImplementationDecorator)
  private
  protected
  public
    method HandleImplementation(Services: RemObjects.Oxygene.Cirrus.IServices; aMethod: RemObjects.Oxygene.Cirrus.IMethodDefinition);
  end;

implementation

method Class1Attribute.HandleImplementation(Services: RemObjects.Oxygene.Cirrus.IServices; aMethod: RemObjects.Oxygene.Cirrus.IMethodDefinition);
begin

  var newVersion:=new ResultValue();

  var newAssignment:=new AssignmentStatement(newVersion,new DataValue(1001));

  var p1:= new ParamValue(0);

  aMethod.SetBody(Services,method
    begin
      if (unquote<Integer>(p1)>0) then
      begin
        Aspects.OriginalBody;
      end
      else
      begin
        unquote(newAssignment);
      end;
    end);

end;
Mosh
If I try to use a string within the Datavalue (the target function returns a string) I get an internal error. Does this code need to be updated if I'm using a string?
jamiei
As long as SomeMethod returns a string and the parameter in new DataValue is also a string you should be ok.
Mosh
I get (CE7) Internal error (D03) in RemObjects.Oxygene.targets when I do replace with a string when unquoting the AssignmentStatement, what exactly does the DataValue() do?
jamiei
Its for the construction of result := 1000;DataValue represents the right hand side
Mosh
In that case, I may have found a compiler bug. Thanks for all your help Mosh!
jamiei