delphiaopdelphi-prismoxygene

Delphi Prism Cirrus accessing and setting the Result of a function


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.


Solution

  • 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;