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

com.cloudbees.groovy.cps.impl.ThrowBlock Maven / Gradle / Ivy

There is a newer version: 1.31
Show newest version
package com.cloudbees.groovy.cps.impl;

import com.cloudbees.groovy.cps.Block;
import com.cloudbees.groovy.cps.Continuable;
import com.cloudbees.groovy.cps.Continuation;
import com.cloudbees.groovy.cps.Env;
import com.cloudbees.groovy.cps.Next;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.cloudbees.groovy.cps.impl.SourceLocation.*;
import static java.util.Arrays.asList;

/**
* @author Kohsuke Kawaguchi
*/
public class ThrowBlock implements Block {
    private final SourceLocation loc;
    private final Block exp;
    /**
     * If true, {@link Exception#fillInStackTrace()} is used at the point of throwing
     * to overwrite the stack trace of the exception.
     */
    private final boolean fillStackTrace;

    public ThrowBlock(Block exp) {
        this(UNKNOWN, exp,false);
    }

    public ThrowBlock(SourceLocation loc, Block exp, boolean fillStackTrace) {
        this.loc = loc;
        this.exp = exp;
        this.fillStackTrace = fillStackTrace;
    }

    public Next eval(final Env e, Continuation _) {
        return new Next(exp,e,new Continuation() {
            public Next receive(Object t) {
                if (t==null) {
                    t = new NullPointerException();
                }
                if (!(t instanceof Throwable)) {
                    t = new ClassCastException(t.getClass()+" cannot be cast to Throwable");
                }
                Throwable throwable = Throwable.class.cast(t);

                if (fillStackTrace) {
                    /*
                        CPS TRACE
                          this section contains a synthesized fake stack trace that shows the logical stack trace of the CPS code
                        ORIGINAL TRACE
                          this section contains the actual stack trace where 'throwable' was created
                     */

                    List stack = new ArrayList();

                    stack.add((loc!=null ? loc : UNKNOWN).toStackTrace());
                    e.buildStackTraceElements(stack,Integer.MAX_VALUE);
                    stack.add(Continuable.SEPARATOR_STACK_ELEMENT);
                    stack.addAll(asList(throwable.getStackTrace()));

                    throwable.setStackTrace(stack.toArray(new StackTraceElement[stack.size()]));
                }

                Continuation v = e.getExceptionHandler(throwable.getClass());
                return v.receive(t);
            }
        });
    }

    private static final long serialVersionUID = 1L;
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy