Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-12-25 02:20:07 +01:00
Add new annotations from upstream
Dieser Commit ist enthalten in:
Ursprung
1e80c0429a
Commit
204de7eab5
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.internal.util;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class DeprecationUtil {
|
||||||
|
|
||||||
|
private DeprecationUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that one of the two functions is overridden. Caller method must be the new method,
|
||||||
|
* annotated with {@link NonAbstractForCompatibility}.
|
||||||
|
*
|
||||||
|
* @param implementingClass the result of calling {@link Object#getClass()}
|
||||||
|
*/
|
||||||
|
public static void checkDelegatingOverride(Class<?> implementingClass) {
|
||||||
|
// pull the information about the caller
|
||||||
|
StackTraceElement caller = Throwables.lazyStackTrace(new Throwable()).get(1);
|
||||||
|
// find the matching caller method
|
||||||
|
Method callingMethod = getCallingMethod(caller);
|
||||||
|
NonAbstractForCompatibility annotation =
|
||||||
|
callingMethod.getAnnotation(NonAbstractForCompatibility.class);
|
||||||
|
// get the deprecated method
|
||||||
|
Method deprecatedMethod;
|
||||||
|
try {
|
||||||
|
deprecatedMethod = implementingClass.getMethod(
|
||||||
|
annotation.delegateName(), annotation.delegateParams()
|
||||||
|
);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new AssertionError(
|
||||||
|
"Missing method referenced by " + NonAbstractForCompatibility.class, e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Check if the deprecated method was overridden. If the declaring class is the caller's
|
||||||
|
// class, then it wasn't. That means that the caller method (i.e. the new method) should be
|
||||||
|
// overridden by the implementing class.
|
||||||
|
// There's no need to check if the new method has been overridden, since the only other
|
||||||
|
// way this could be reached is if someone calls `super.xyz`, which they have no reason to.
|
||||||
|
if (deprecatedMethod.getDeclaringClass().getName().equals(caller.getClassName())) {
|
||||||
|
throw new IllegalStateException("Class " + implementingClass.getName()
|
||||||
|
+ " must override " + methodToString(callingMethod));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Method getCallingMethod(StackTraceElement callerInfo) {
|
||||||
|
Method[] declaredMethods;
|
||||||
|
try {
|
||||||
|
declaredMethods = Class.forName(callerInfo.getClassName()).getDeclaredMethods();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new AssertionError("Caller class missing?", e);
|
||||||
|
}
|
||||||
|
for (Method declaredMethod : declaredMethods) {
|
||||||
|
if (declaredMethod.isAnnotationPresent(NonAbstractForCompatibility.class) &&
|
||||||
|
declaredMethod.getName().equals(callerInfo.getMethodName())) {
|
||||||
|
return declaredMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Failed to find caller method " +
|
||||||
|
callerInfo.getMethodName() + " annotated with " + NonAbstractForCompatibility.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String methodToString(Method method) {
|
||||||
|
StringBuilder builder = new StringBuilder(method.getDeclaringClass().getCanonicalName())
|
||||||
|
.append('.')
|
||||||
|
.append(method.getName())
|
||||||
|
.append('(');
|
||||||
|
Joiner.on(", ").appendTo(builder, Stream.of(method.getParameterTypes())
|
||||||
|
.map(Class::getSimpleName)
|
||||||
|
.iterator());
|
||||||
|
builder.append(')');
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser 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 Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.internal.util;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The annotated method is only non-{@code abstract} for compatibility with old subclasses,
|
||||||
|
* and will be made {@code abstract} in the next major version of WorldEdit.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Any new subclasses <em>must</em> override the annotated method, failing to do so will result in
|
||||||
|
* an exception at runtime.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
@Documented
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface NonAbstractForCompatibility {
|
||||||
|
|
||||||
|
// Note that this annotation only functions properly if no other method in the same class
|
||||||
|
// shares the name of the annotated function AND is also annotated with this annotation.
|
||||||
|
// Otherwise, we cannot uniquely determine the calling method via reflection hacks.
|
||||||
|
// This could be changed, but it's not currently necessary.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the method delegated to by the annotated method.
|
||||||
|
*/
|
||||||
|
String delegateName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter types of the method delegated to by the annotated method.
|
||||||
|
*/
|
||||||
|
Class<?>[] delegateParams();
|
||||||
|
|
||||||
|
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren