All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.core.function.index.TracePointer Maven / Gradle / Ivy

package org.snapscript.core.function.index;

import static org.snapscript.core.function.index.Retention.NEVER;

import org.snapscript.core.attribute.AttributeResult;
import org.snapscript.core.attribute.AttributeResultBinder;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.function.ArgumentConverter;
import org.snapscript.core.function.Function;
import org.snapscript.core.function.Invocation;
import org.snapscript.core.function.Origin;
import org.snapscript.core.function.Signature;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.stack.ThreadStack;

public class TracePointer implements FunctionPointer {
   
   private final AttributeResultBinder binder;
   private final Invocation invocation;
   private final Function function;
   
   public TracePointer(Function function, ThreadStack stack) {
      this.binder = new AttributeResultBinder(function);
      this.invocation = new TraceInvocation(function, stack);
      this.function = function;
   }

   @Override
   public ReturnType getType(Scope scope) {
      AttributeResult result = binder.bind(scope);

      if(result == null) {
         throw new InternalStateException("No return type for '" + function + "'");
      }
      return new ReturnType(result, scope);
   }
   
   @Override
   public Function getFunction() {
      return function;
   }
   
   @Override
   public Invocation getInvocation() {
      return invocation;
   }

   @Override
   public Retention getRetention() {
      return NEVER;
   }
   
   @Override
   public String toString() {
      return String.valueOf(function);
   }
   
   private static class TraceInvocation implements Invocation {
   
      private final ThreadStack stack;
      private final Function function;
      
      public TraceInvocation(Function function, ThreadStack stack) {
         this.function = function;
         this.stack = stack;
      }
      
      @Override
      public Object invoke(Scope scope, Object object, Object... arguments) throws Exception{
         Signature signature = function.getSignature();
         ArgumentConverter converter = signature.getConverter();
         Invocation invocation = function.getInvocation();
         Origin origin = signature.getOrigin();
         
         try {
            Object[] list = arguments;
            
            if(!origin.isSystem()) {
               stack.before(function);
            }
            if(origin.isPlatform()) {
               list = converter.convert(arguments);
            } else {
               list = converter.assign(arguments);
            }
            return invocation.invoke(scope, object, list);
         } finally {
            if(!origin.isSystem()) {
               stack.after(function);
            }
         }
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy