<commit_before>package throwing.bridge;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.IntStream;

abstract class CheckedBridge<D, X extends Throwable> extends AbstractBridge<D, X> {
    private static final String PACKAGE = CheckedBridge.class.getPackage().getName();
    // it might be useful to have a way to turn this off
    public static volatile boolean FILTER_STACK = true;

    private final FunctionBridge<X> bridge;
    private final RethrowChain<BridgeException, X> chain;
    private final Function<BridgeException, X> launder;

    CheckedBridge(D delegate, FunctionBridge<X> bridge) {
        this(delegate, bridge, RethrowChain.start());
    }

    CheckedBridge(D delegate, FunctionBridge<X> bridge, RethrowChain<BridgeException, X> chain) {
        super(delegate, bridge.getExceptionClass());
        this.bridge = bridge;
        this.chain = chain.chain(t -> {
            Throwable cause = t.getCause();
            if (getExceptionClass().isInstance(cause)) {
                // filter out bridge lines from the exception. They can get
                // rather verbose.
                if (FILTER_STACK) {
                    filterStackTrace(cause);
                }

                return Optional.of(getExceptionClass().cast(cause));
            }

            return Optional.empty();
        });
        launder = this.chain.finish();
    }

    private void filterStackTrace(Throwable cause) {
        List<StackTraceElement> ste = Arrays.asList(cause.getStackTrace());

        IntSummaryStatistics stats = IntStream.range(0, ste.size()).filter(
                i -> ste.get(i).getClassName().startsWith(PACKAGE)).summaryStatistics();
        if (stats.getCount() > 0) {
            List<StackTraceElement> filtered = new ArrayList<>(ste.size() - (stats.getMax() - stats.getMin()));
            for (int x = 0; x < stats.getMin(); x++) {
                filtered.add(ste.get(x));
            }
            for (int x = stats.getMax() + 1; x < ste.size(); x++) {
                filtered.add(ste.get(x));
            }
            cause.setStackTrace(filtered.toArray(new StackTraceElement[filtered.size()]));
        }
    }

    public FunctionBridge<X> getBridge() {
        return bridge;
    }

    public RethrowChain<BridgeException, X> getChain() {
        return chain;
    }

    protected void filterBridgeException(Runnable runnable) throws X {
        filterBridgeException(() -> {
            runnable.run();
            return null;
        });
    }

    protected <R> R filterBridgeException(Supplier<R> supplier) throws X {
        try {
            return supplier.get();
        } catch (BridgeException e) {
            X x = launder.apply(e);
            // it's possible that we've mapped from Y -> X with a new X(Y) call.
            // this would result in a brand new stack trace free of filtering
            filterStackTrace(x);
            throw x;
        }
    }
}<commit_msg>Don't duplicate the stack filtering<commit_after>package throwing.bridge;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.IntStream;

abstract class CheckedBridge<D, X extends Throwable> extends AbstractBridge<D, X> {
    private static final String PACKAGE = CheckedBridge.class.getPackage().getName();
    // it might be useful to have a way to turn this off
    public static volatile boolean FILTER_STACK = true;
    
    private final FunctionBridge<X> bridge;
    private final RethrowChain<BridgeException, X> chain;
    private final Function<BridgeException, X> launder;
    
    CheckedBridge(D delegate, FunctionBridge<X> bridge) {
        this(delegate, bridge, RethrowChain.start());
    }
    
    CheckedBridge(D delegate, FunctionBridge<X> bridge, RethrowChain<BridgeException, X> chain) {
        super(delegate, bridge.getExceptionClass());
        this.bridge = bridge;
        this.chain = chain.chain(t -> {
            Throwable cause = t.getCause();
            if (getExceptionClass().isInstance(cause)) {
                return Optional.of(getExceptionClass().cast(cause));
            }
            
            return Optional.empty();
        });
        launder = this.chain.finish();
    }
    
    private void filterStackTrace(Throwable cause) {
        List<StackTraceElement> ste = Arrays.asList(cause.getStackTrace());
        
        IntSummaryStatistics stats = IntStream.range(0, ste.size())
                .filter(i -> ste.get(i).getClassName().startsWith(PACKAGE)).summaryStatistics();
        if (stats.getCount() > 0) {
            List<StackTraceElement> filtered = new ArrayList<>(ste.size() - (stats.getMax() - stats.getMin()));
            for (int x = 0; x < stats.getMin(); x++) {
                filtered.add(ste.get(x));
            }
            for (int x = stats.getMax() + 1; x < ste.size(); x++) {
                filtered.add(ste.get(x));
            }
            cause.setStackTrace(filtered.toArray(new StackTraceElement[filtered.size()]));
        }
    }
    
    public FunctionBridge<X> getBridge() {
        return bridge;
    }
    
    public RethrowChain<BridgeException, X> getChain() {
        return chain;
    }
    
    protected void filterBridgeException(Runnable runnable) throws X {
        filterBridgeException(() -> {
            runnable.run();
            return null;
        });
    }
    
    protected <R> R filterBridgeException(Supplier<R> supplier) throws X {
        try {
            return supplier.get();
        } catch (BridgeException e) {
            X x = launder.apply(e);
            // filter out bridge lines from the exception. They can get
            // rather verbose.
            if (FILTER_STACK) {
                filterStackTrace(x);
            }
            throw x;
        }
    }
}
{'fraction_non_alphanumeric': 0.11292694884785096, 'fraction_numerical': 0.0013074031704526884, 'mean_word_length': 2.2815013404825737, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '522488', 'n_tokens_mistral': 1721, 'n_tokens_neox': 1630, 'n_words': 412}