Exception.java

/**
* Copyright 2010,2021 Nikolas S Boyd.
Permission is granted to copy this work provided this copyright statement is retained in all copies.

*/
package Hoot.Exceptions;

import Hoot.Runtime.Functions.*;
import Hoot.Runtime.Faces.*;
import Hoot.Runtime.Values.*;
import Hoot.Runtime.Blocks.*;
import Smalltalk.Core.*;
import Smalltalk.Blocks.*;
import Smalltalk.Magnitudes.*;
import Hoot.Behaviors.*;
import Hoot.Behaviors.Nil;
import Hoot.Behaviors.Object;
import Hoot.Behaviors.True;
import Hoot.Behaviors.False;
import Hoot.Behaviors.Boolean;
import Hoot.Magnitudes.*;
import Hoot.Magnitudes.Integer;
import Hoot.Magnitudes.Character;
import Hoot.Magnitudes.Float;
import Hoot.Magnitudes.Double;
import Hoot.Collections.*;
import Hoot.Collections.String;
import Hoot.Runtime.Behaviors.HootRegistry;
import Hoot.Runtime.Names.Primitive;
import Hoot.Runtime.Exceptions.*;
import Smalltalk.Core.Posit;
import Smalltalk.Core.Subject;
import Smalltalk.Exceptions.*;
import Smalltalk.Collections.ReadableString;

public class Exception extends Object implements ExceptionBuilder, SignaledException
{

  public static Metaclass type() { return (Metaclass)Metaclass.$class; }
  @Override public Metaclass $class() { return (Metaclass)Metaclass.$class; }
  public static class Metaclass extends Object.Metaclass implements ExceptionBuilder.Metatype, SignaledException.Metatype
  {
    static final Exception.Metaclass $class = new Exception.Metaclass();
    public Metaclass() {
      this(Exception.Metaclass.class);
    }

    public Metaclass(java.lang.Class aClass) {
      super(aClass);
    }

    @Override public java.lang.Class outerClass() { return Exception.class; }


    /**
     * @return 
     */
    public   ExceptionSet append(final ExceptionSelector.Metatype argument)
    {
      java.lang.String exitID = "ExceptionMetatype>>append";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (ExceptionSet)f0.exit(exitID, (ExceptionSet.type().with(this).append(argument)));
      });
    }

    /**
     * @return 
     */
    @Override public   Boolean handles(final SignaledException exception)
    {
      java.lang.String exitID = "ExceptionMetatype>>handles";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Boolean)f0.exit(exitID, exception.$class().isKindOf(this));
      });
    }

    /**
     * @return 
     */
    @Override public   Boolean isKindOf(final ExceptionDescription.Metatype superType)
    {
      java.lang.String exitID = "ExceptionMetatype>>isKindOf";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Boolean)f0.exit(exitID, Boolean.from(superType.getClass().isAssignableFrom(this.getClass())));
      });
    }

    /**
     * @return 
     */
    @Override public   void handleWith_during(final MonadicValuable handler, final Closure aBlock)
    {
      java.lang.String exitID = "ExceptionMetatype>>handleWith_during";
      Frame f0 = new Frame(exitID);
      ExceptionContext.during_handle(aBlock, ((Enclosure)handler).asHandlerOf(((HandledException.Metatype)this.type())));
    }

    /**
     * @return 
     */
    @Override public   Exception signal()
    {
      java.lang.String exitID = "ExceptionMetatype>>signal";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Exception)f0.exit(exitID, ((Exception)this.$new()).signal());
      });
    }

    /**
     * @return 
     */
    @Override public   Exception signal(final ReadableString message)
    {
      java.lang.String exitID = "ExceptionMetatype>>signal";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Exception)f0.exit(exitID, (fp) -> {
      Exception prime = (Exception)this.$new();
      prime.messageText(message); 

      return prime.signal();
      });
      });
    }

    /**
     * @return 
     */
    public   Exception $new()
    {
      java.lang.String exitID = "ExceptionMetatype>>$new";
      Frame f0 = new Frame(exitID);
      return f0.evaluate(() -> {
      return (Exception)f0.exit(exitID, Primitive.newInstance(this.outerClass()));
      });
    }
  }


  protected Enclosure theHandler;
  protected String messageText = String.from("");
  protected String tag = String.from("");
    protected Exception replacementException;
    public Exception replacementException() { return this.replacementException; }
    public Object getReplacementException() { return (Object)this.replacementException; }

    public Exception replacementException(Exception value) { this.replacementException = value; return this; }
    public void setReplacementException(Object value) { this.replacementException = (Exception)value; }

  ;
  protected NiladicValuable resignalBlock;

  /**
   * @return 
   */
  public   ExceptionSet append(final ExceptionSelector.Metatype argument)
  {
    java.lang.String exitID = "Exception>>append";
    Frame f0 = new Frame(exitID);
    return (ExceptionSet)(this.$class().append(argument));
  }

  /**
   * @return 
   */
  public   ExceptionContext environment()
  {
    java.lang.String exitID = "Exception>>environment";
    Frame f0 = new Frame(exitID);
    return (ExceptionContext)ExceptionContext.environment();
  }

  /**
   * @return 
   */
  protected   Enclosure registeredHandler()
  {
    java.lang.String exitID = "Exception>>registeredHandler";
    Frame f0 = new Frame(exitID);
    return (Enclosure)this.environment().findHandler(this);
  }

  /**
   * @return 
   */
  protected   Enclosure activeHandler()
  {
    java.lang.String exitID = "Exception>>activeHandler";
    Frame f0 = new Frame(exitID);
    return (Enclosure)ExceptionContext.findHandler(this.valueType());
  }

  /**
   * @return 
   */
  public   Enclosure currentHandler()
  {
    java.lang.String exitID = "Exception>>currentHandler";
    Frame f0 = new Frame(exitID);
    return (Enclosure)theHandler;
  }

  /**
   * @return 
   */
  public   Enclosure currentHandler(final Enclosure handler)
  {
    java.lang.String exitID = "Exception>>currentHandler";
    Frame f0 = new Frame(exitID);
     theHandler = handler;
    return (Enclosure)handler;
  }

  /**
   * @return 
   */
  public   Boolean isSignaled()
  {
    java.lang.String exitID = "Exception>>isSignaled";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(this.hasAny(this.currentHandler()));
  }

  /**
   * @return 
   */
  public   void exit(final Subject value)
  {
    java.lang.String exitID = "Exception>>exit";
    Frame f0 = new Frame(exitID);
    this.isResumable().ifTrue_ifFalse(Closure.with(f2 -> {
      this.resume(value);
    }, ""), Closure.with(f2 -> {
      this.$return(value);
    }, ""));
  }

  /**
   * @return 
   */
  @Override public   void resume()
  {
    java.lang.String exitID = "Exception>>resume";
    Frame f0 = new Frame(exitID);
    this.resume(Nil.literal());
  }

  /**
   * @return 
   */
  @Override public   void resume(final Subject value)
  {
    java.lang.String exitID = "Exception>>resume";
    Frame f0 = new Frame(exitID);
    this.isResumable().ifFalse(Closure.with(f2 -> {
      ControlError.type().signal(String.from("Attempt to resume from a non-resumable exception"));
    }, ""));
    this.activeHandler().resume(value);
  }

  /**
   * @return 
   */
  @Override public   void $return()
  {
    java.lang.String exitID = "Exception>>$return";
    Frame f0 = new Frame(exitID);
    this.$return(Nil.literal());
  }

  /**
   * @return 
   */
  @Override public   void $return(final Subject value)
  {
    java.lang.String exitID = "Exception>>$return";
    Frame f0 = new Frame(exitID);
    this.activeHandler().$return(value);
  }

  /**
   * @return 
   */
  public   String messageText()
  {
    java.lang.String exitID = "Exception>>messageText";
    Frame f0 = new Frame(exitID);
    return (String)messageText;
  }

  /**
   * @return 
   */
  public   String messageText(final ReadableString aMessage)
  {
    java.lang.String exitID = "Exception>>messageText";
    Frame f0 = new Frame(exitID);
     messageText = String.from(aMessage);
    return (String)messageText;
  }

  /**
   * @return 
   */
  public   String tag(final String aTag)
  {
    java.lang.String exitID = "Exception>>tag";
    Frame f0 = new Frame(exitID);
     tag = aTag;
    return (String)tag;
  }

  /**
   * @return 
   */
  public   String tag()
  {
    java.lang.String exitID = "Exception>>tag";
    Frame f0 = new Frame(exitID);
    return f0.evaluate(() -> {
    tag.notEmpty().ifTrue(Closure.with(f2 -> {
      return (String)f0.exit(exitID, tag);
    }, ""));
    messageText.notEmpty().ifTrue(Closure.with(f2 -> {
      return (String)f0.exit(exitID, messageText);
    }, ""));
    return (String)f0.exit(exitID, String.from(""));
    });
  }

  /**
   * @return 
   */
  protected   String defaultDescriptionString()
  {
    java.lang.String exitID = "Exception>>defaultDescriptionString";
    Frame f0 = new Frame(exitID);
    return (String)this.$class().name();
  }

  /**
   * @return 
   */
  @Override public   String description()
  {
    java.lang.String exitID = "Exception>>description";
    Frame f0 = new Frame(exitID);
    return (String)(Boolean.primitiveValue(this.messageText().notEmpty()) ? this.defaultDescriptionString() : this.messageText());
  }

  /**
   * @return 
   */
  protected   Subject activateHandler()
  {
    java.lang.String exitID = "Exception>>activateHandler";
    Frame f0 = new Frame(exitID);
    return (Subject)ExceptionContext.activateHandler(this);
  }

  /**
   * @return 
   */
  public   Exception defaultAction()
  {
    java.lang.String exitID = "Exception>>defaultAction";
    Frame f0 = new Frame(exitID);
    UnhandledException.type().raise(this);
    return (Exception)this;
  }

  /**
   * @return 
   */
  protected   Exception abandonAction()
  {
    java.lang.String exitID = "Exception>>abandonAction";
    Frame f0 = new Frame(exitID);
    UnhandledException.type().raise(new UnresumableException());
    return (Exception)this;
  }

  /**
   * @return 
   */
  public   Subject handle()
  {
    java.lang.String exitID = "Exception>>handle";
    Frame f0 = new Frame(exitID);
    Valued result = ExceptionContext.activateHandler(this);
    if (this.wasResignaled().primitiveBoolean()) {
      return this.replacementException().signal();
    };
    if (!(this.isResumable().primitiveBoolean())) {
      this.abandonAction();
    };
    return (Subject)result;
  }

  /**
   * @return 
   */
  public   Subject outer()
  {
    java.lang.String exitID = "Exception>>outer";
    Frame f0 = new Frame(exitID);
    this.activeHandler().passFrom(this);
    return (Subject)this;
  }

  /**
   * @return 
   */
  @Override public   void pass()
  {
    java.lang.String exitID = "Exception>>pass";
    Frame f0 = new Frame(exitID);
    this.currentHandler().passFrom(this);
  }

  /**
   * @return 
   */
  protected   Boolean wasResignaled()
  {
    java.lang.String exitID = "Exception>>wasResignaled";
    Frame f0 = new Frame(exitID);
    return (Boolean)this.hasAny(replacementException);
  }

  /**
   * @return 
   */
  public   void resignalAs(final ExceptionDescription anException)
  {
    java.lang.String exitID = "Exception>>resignalAs";
    Frame f0 = new Frame(exitID);
    this.replacementException(((Exception)anException));
  }

  /**
   * @return 
   */
  protected   NiladicValuable resignalContinuation()
  {
    java.lang.String exitID = "Exception>>resignalContinuation";
    Frame f0 = new Frame(exitID);
    return (NiladicValuable)resignalBlock;
  }

  /**
   * @return 
   */
  protected   Exception resignalContinuation(final NiladicValuable aBlock)
  {
    java.lang.String exitID = "Exception>>resignalContinuation";
    Frame f0 = new Frame(exitID);
     resignalBlock = aBlock;
    return (Exception)this;
  }

  /**
   * @return 
   */
  protected   Exception initializeResignal()
  {
    java.lang.String exitID = "Exception>>initializeResignal";
    Frame f0 = new Frame(exitID);
    return f0.evaluate(() -> {
    this.resignalContinuation(Closure.with(f2 -> {
      return (Exception)f0.exit(exitID, this.resignalContinuation());
    }, ""));
    return (Exception)this;
    });
  }

  /**
   * 
   */
  public    Exception()
  {
    java.lang.String exitID = "Exception>>Exception";
    Frame f0 = new Frame(exitID);
    this.initializeResignal();
  }

  /**
   * @return 
   */
  public   void retry()
  {
    java.lang.String exitID = "Exception>>retry";
    Frame f0 = new Frame(exitID);
    this.activeHandler().retry();
  }

  /**
   * @return 
   */
  public   void retryUsing(final NiladicValuable aBlock)
  {
    java.lang.String exitID = "Exception>>retryUsing";
    Frame f0 = new Frame(exitID);
    this.activeHandler().retry(aBlock);
  }

  /**
   * @return 
   */
  public   Exception signal()
  {
    java.lang.String exitID = "Exception>>signal";
    Frame f0 = new Frame(exitID);
    return f0.evaluate(() -> {
    this.isSignaled().ifTrue(Closure.with(f2 -> {
      return (Exception)f0.exit(exitID, ControlError.type().signal(String.from("Signaling an already signaled exception")));
    }, ""));
    this.handle();
    return (Exception)this;
    });
  }

  /**
   * @return 
   */
  public   Exception signal(final ReadableString message)
  {
    java.lang.String exitID = "Exception>>signal";
    Frame f0 = new Frame(exitID);
    {
    Exception prime = this;
    prime.messageText(message); 

    return prime.signal();
    }
  }

  /**
   * @return 
   */
  protected   Boolean hasNo(final Valued item)
  {
    java.lang.String exitID = "Exception>>hasNo";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(Utils.hasNo(item));
  }

  /**
   * @return 
   */
  protected   Boolean hasAny(final Valued item)
  {
    java.lang.String exitID = "Exception>>hasAny";
    Frame f0 = new Frame(exitID);
    return (Boolean)Boolean.from(Utils.hasAny(item));
  }

  /**
   * @return 
   */
  protected   Boolean hasHandler()
  {
    java.lang.String exitID = "Exception>>hasHandler";
    Frame f0 = new Frame(exitID);
    return (Boolean)this.hasAny(this.registeredHandler());
  }

  /**
   * @return 
   */
  protected   Boolean isActive()
  {
    java.lang.String exitID = "Exception>>isActive";
    Frame f0 = new Frame(exitID);
    return (Boolean)this.isSignaled();
  }

  /**
   * @return 
   */
  protected   Boolean hasActiveHandler()
  {
    java.lang.String exitID = "Exception>>hasActiveHandler";
    Frame f0 = new Frame(exitID);
    Enclosure handler = this.registeredHandler();
    return (Boolean)this.hasAny(handler);
  }

  /**
   * @return 
   */
  @Override public   Boolean isResumable()
  {
    java.lang.String exitID = "Exception>>isResumable";
    Frame f0 = new Frame(exitID);
    return (Boolean)False.literal();
  }

  /**
   * @return 
   */
  @Override public   Boolean isNested()
  {
    java.lang.String exitID = "Exception>>isNested";
    Frame f0 = new Frame(exitID);
    return (Boolean)this.hasAny(ExceptionContext.findPriorHandler(this.valueType()));
  }

  /**
   * @return 
   */
  @Override public   Boolean isKindOf(final ExceptionDescription.Metatype superType)
  {
    java.lang.String exitID = "Exception>>isKindOf";
    Frame f0 = new Frame(exitID);
    return (Boolean)this.$class().isKindOf(superType);
  }
}