优化 Task.getCaller() (#4308)

This commit is contained in:
Glavo 2025-08-21 20:53:19 +08:00 committed by GitHub
parent 87a3a4ece3
commit e52cfb036e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 54 deletions

View File

@ -24,7 +24,6 @@ import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import org.jackhuang.hmcl.event.EventManager;
import org.jackhuang.hmcl.util.InvocationDispatcher;
import org.jackhuang.hmcl.util.ReflectionHelper;
import org.jackhuang.hmcl.util.function.ExceptionalConsumer;
import org.jackhuang.hmcl.util.function.ExceptionalFunction;
import org.jackhuang.hmcl.util.function.ExceptionalRunnable;
@ -35,10 +34,9 @@ import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;
@ -1009,8 +1007,19 @@ public abstract class Task<T> {
void execute(T result, Exception exception) throws Exception;
}
private static final String PACKAGE_PREFIX = Task.class.getPackageName() + ".";
private static final Predicate<StackWalker.StackFrame> PREDICATE = stackFrame -> !stackFrame.getClassName().startsWith(PACKAGE_PREFIX);
private static final Function<Stream<StackWalker.StackFrame>, Optional<StackWalker.StackFrame>> FUNCTION = stream -> stream.filter(PREDICATE).findFirst();
private static final Function<StackWalker.StackFrame, String> FRAME_MAPPING = frame -> {
String fileName = frame.getFileName();
if (fileName != null)
return frame.getClassName() + '.' + frame.getMethodName() + '(' + fileName + ':' + frame.getLineNumber() + ')';
else
return frame.getClassName() + '.' + frame.getMethodName();
};
private static String getCaller() {
return ReflectionHelper.getCaller(packageName -> !"org.jackhuang.hmcl.task".equals(packageName)).toString();
return StackWalker.getInstance().walk(FUNCTION).map(FRAME_MAPPING).orElse("Unknown");
}
private static final class SimpleTask<T> extends Task<T> {

View File

@ -1,49 +0,0 @@
/*
* Hello Minecraft! Launcher
* Copyright (C) 2020 huangyuhui <huanghongxun2008@126.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.jackhuang.hmcl.util;
import java.util.function.Predicate;
/**
*
* @author huangyuhui
*/
public final class ReflectionHelper {
private ReflectionHelper() {
}
/**
* Get caller, this method is caller sensitive.
*
* @param packageFilter returns false if we consider the given package is internal calls, not the caller
* @return the caller, method name, source file, line number
*/
public static StackTraceElement getCaller(Predicate<String> packageFilter) {
StackTraceElement[] elements = Thread.currentThread().getStackTrace();
// element[0] is Thread.currentThread().getStackTrace()
// element[1] is ReflectionHelper.getCaller(packageFilter)
// so element[2] is caller of this method.
StackTraceElement caller = elements[2];
for (int i = 3; i < elements.length; ++i) {
if (packageFilter.test(StringUtils.substringBeforeLast(elements[i].getClassName(), '.')) &&
!caller.getClassName().equals(elements[i].getClassName()))
return elements[i];
}
return caller;
}
}