mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-02 19:36:41 +00:00
Add and apply .editorconfig from P2 (#1195)
* Consistenty use javax annotations. - Unfortunately jetbrains annotations seem to be exposed transitively via core somewhere, but with the correct IDE settings, annotations can be defaulted to javax - Cleaning up of import order in #1195 - Must be merged before #1195 * Add and apply .editorconfig from P2 - Does not rearrange entries * Address some comments * add back some javadoc comments * Address final comments Co-authored-by: NotMyFault <mc.cache@web.de>
This commit is contained in:
@ -44,4 +44,5 @@ public class SchematicsEventListener {
|
||||
LOGGER.warn("Failed to create schematics directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,4 +38,5 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface Chunk3d {
|
||||
|
||||
}
|
||||
|
@ -34,4 +34,5 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface ClipboardMask {
|
||||
|
||||
}
|
||||
|
@ -38,4 +38,5 @@ public @interface Direction {
|
||||
String AIM = "me";
|
||||
|
||||
boolean includeDiagonals() default false;
|
||||
|
||||
}
|
||||
|
@ -33,5 +33,7 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface MultiDirection {
|
||||
|
||||
boolean includeDiagonals() default false;
|
||||
|
||||
}
|
||||
|
@ -34,5 +34,7 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface Offset {
|
||||
|
||||
String FORWARD = "forward";
|
||||
|
||||
}
|
||||
|
@ -35,4 +35,5 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface OptionalArg {
|
||||
|
||||
}
|
||||
|
@ -33,8 +33,10 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface Radii {
|
||||
|
||||
/**
|
||||
* Number of radii values to inject at maximum. May inject less.
|
||||
*/
|
||||
int value();
|
||||
|
||||
}
|
||||
|
@ -33,4 +33,5 @@ import java.lang.annotation.Target;
|
||||
@Target({ElementType.PARAMETER, ElementType.METHOD})
|
||||
@InjectAnnotation
|
||||
public @interface Selection {
|
||||
|
||||
}
|
||||
|
@ -33,4 +33,5 @@ import java.lang.annotation.Target;
|
||||
@Target(ElementType.PARAMETER)
|
||||
@InjectAnnotation
|
||||
public @interface VertHeight {
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@ -55,7 +54,7 @@ public final class ChunkDeleter {
|
||||
private static final Logger LOGGER = LogManagerCompat.getLogger();
|
||||
|
||||
private static final Comparator<BlockVector2> chunkSorter = Comparator.comparing(
|
||||
pos -> (pos.getBlockX() & 31) + (pos.getBlockZ() & 31) * 32
|
||||
pos -> (pos.getBlockX() & 31) + (pos.getBlockZ() & 31) * 32
|
||||
);
|
||||
|
||||
private static final Gson chunkDeleterGson = new GsonBuilder()
|
||||
@ -69,7 +68,8 @@ public final class ChunkDeleter {
|
||||
}
|
||||
|
||||
public static void writeInfo(ChunkDeletionInfo info, Path chunkFile) throws IOException, JsonIOException {
|
||||
String json = chunkDeleterGson.toJson(info, new TypeToken<ChunkDeletionInfo>() {}.getType());
|
||||
String json = chunkDeleterGson.toJson(info, new TypeToken<ChunkDeletionInfo>() {
|
||||
}.getType());
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(chunkFile)) {
|
||||
writer.write(json);
|
||||
}
|
||||
@ -88,7 +88,8 @@ public final class ChunkDeleter {
|
||||
if (chunkDeleter.runDeleter()) {
|
||||
LOGGER.info("Successfully deleted {} matching chunks (out of {}, taking {} ms).",
|
||||
chunkDeleter.getDeletedChunkCount(), chunkDeleter.getDeletionsRequested(),
|
||||
System.currentTimeMillis() - start);
|
||||
System.currentTimeMillis() - start
|
||||
);
|
||||
if (deleteOnSuccess) {
|
||||
boolean deletedFile = false;
|
||||
try {
|
||||
@ -97,12 +98,12 @@ public final class ChunkDeleter {
|
||||
}
|
||||
if (!deletedFile) {
|
||||
LOGGER.warn("Chunk deletion file could not be cleaned up. This may have unintended consequences"
|
||||
+ " on next startup, or if /delchunks is used again.");
|
||||
+ " on next startup, or if /delchunks is used again.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGGER.error("Error occurred while deleting chunks. "
|
||||
+ "If world errors occur, stop the server and restore the *.bak backup files.");
|
||||
+ "If world errors occur, stop the server and restore the *.bak backup files.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,10 +160,11 @@ public final class ChunkDeleter {
|
||||
Path worldPath = Paths.get(chunkBatch.worldPath);
|
||||
if (chunkBatch.chunks != null) {
|
||||
return chunkBatch.chunks.stream()
|
||||
.collect(Collectors.groupingBy(RegionFilePos::new))
|
||||
.entrySet().stream().collect(Collectors.toMap(
|
||||
e -> worldPath.resolve("region").resolve(e.getKey().getFileName()),
|
||||
e -> e.getValue().stream().sorted(chunkSorter)));
|
||||
.collect(Collectors.groupingBy(RegionFilePos::new))
|
||||
.entrySet().stream().collect(Collectors.toMap(
|
||||
e -> worldPath.resolve("region").resolve(e.getKey().getFileName()),
|
||||
e -> e.getValue().stream().sorted(chunkSorter)
|
||||
));
|
||||
} else {
|
||||
final BlockVector2 minChunk = chunkBatch.minChunk;
|
||||
final BlockVector2 maxChunk = chunkBatch.maxChunk;
|
||||
@ -184,18 +186,20 @@ public final class ChunkDeleter {
|
||||
int minZ = Math.max(Math.min(startZ, endZ), minChunk.getBlockZ());
|
||||
int maxX = Math.min(Math.max(startX, endX), maxChunk.getBlockX());
|
||||
int maxZ = Math.min(Math.max(startZ, endZ), maxChunk.getBlockZ());
|
||||
Stream<BlockVector2> stream = Stream.iterate(BlockVector2.at(minX, minZ),
|
||||
bv2 -> {
|
||||
int nextX = bv2.getBlockX();
|
||||
int nextZ = bv2.getBlockZ();
|
||||
if (++nextX > maxX) {
|
||||
nextX = minX;
|
||||
if (++nextZ > maxZ) {
|
||||
return null;
|
||||
Stream<BlockVector2> stream = Stream.iterate(
|
||||
BlockVector2.at(minX, minZ),
|
||||
bv2 -> {
|
||||
int nextX = bv2.getBlockX();
|
||||
int nextZ = bv2.getBlockZ();
|
||||
if (++nextX > maxX) {
|
||||
nextX = minX;
|
||||
if (++nextZ > maxZ) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return BlockVector2.at(nextX, nextZ);
|
||||
}
|
||||
return BlockVector2.at(nextX, nextZ);
|
||||
});
|
||||
);
|
||||
groupedChunks.put(regionPath, stream);
|
||||
}
|
||||
}
|
||||
@ -251,10 +255,12 @@ public final class ChunkDeleter {
|
||||
backedUpRegions.add(backupFile);
|
||||
}
|
||||
|
||||
private boolean deleteChunks(Path regionFile, Stream<BlockVector2> chunks,
|
||||
BiPredicate<RegionAccess, BlockVector2> deletionPredicate) {
|
||||
private boolean deleteChunks(
|
||||
Path regionFile, Stream<BlockVector2> chunks,
|
||||
BiPredicate<RegionAccess, BlockVector2> deletionPredicate
|
||||
) {
|
||||
try (RegionAccess region = new RegionAccess(regionFile, shouldPreload)) {
|
||||
for (Iterator<BlockVector2> iterator = chunks.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<BlockVector2> iterator = chunks.iterator(); iterator.hasNext(); ) {
|
||||
BlockVector2 chunk = iterator.next();
|
||||
if (chunk == null) {
|
||||
break;
|
||||
@ -285,6 +291,7 @@ public final class ChunkDeleter {
|
||||
}
|
||||
|
||||
private static class BlockVector2Adapter extends TypeAdapter<BlockVector2> {
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter out, BlockVector2 value) throws IOException {
|
||||
out.beginArray();
|
||||
@ -301,9 +308,11 @@ public final class ChunkDeleter {
|
||||
in.endArray();
|
||||
return BlockVector2.at(x, z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class RegionFilePos {
|
||||
|
||||
private final int x;
|
||||
private final int z;
|
||||
|
||||
@ -358,5 +367,7 @@ public final class ChunkDeleter {
|
||||
public String toString() {
|
||||
return "(" + x + ", " + z + ")";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ public class ChunkDeletionInfo {
|
||||
public List<ChunkBatch> batches;
|
||||
|
||||
public static class ChunkBatch {
|
||||
|
||||
public String worldPath;
|
||||
public boolean backup;
|
||||
public List<DeletionPredicate> deletionPredicates;
|
||||
@ -46,11 +47,15 @@ public class ChunkDeletionInfo {
|
||||
final BlockVector2 dist = maxChunk.subtract(minChunk).add(1, 1);
|
||||
return dist.getBlockX() * dist.getBlockZ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DeletionPredicate {
|
||||
|
||||
public String property;
|
||||
public String comparison;
|
||||
public String value;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -98,4 +98,5 @@ class RegionAccess implements AutoCloseable {
|
||||
public void close() throws IOException {
|
||||
raf.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ public final class BlockStateIdAccess {
|
||||
|
||||
/**
|
||||
* An invalid internal ID, for verification purposes.
|
||||
*
|
||||
* @return an internal ID which is never valid
|
||||
*/
|
||||
public static int invalidId() {
|
||||
|
@ -37,4 +37,5 @@ public class ActorAuthorizer implements Authorizer {
|
||||
return sender.hasPermission(permission);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -106,8 +106,8 @@ public class CommandArgParser {
|
||||
if (part.getSubstring().endsWith("\"")) {
|
||||
state = State.NORMAL;
|
||||
currentArg.add(Substring.wrap(
|
||||
part.getSubstring().substring(0, part.getSubstring().length() - 1),
|
||||
part.getStart(), part.getEnd() - 1
|
||||
part.getSubstring().substring(0, part.getSubstring().length() - 1),
|
||||
part.getStart(), part.getEnd() - 1
|
||||
));
|
||||
finishArg();
|
||||
} else {
|
||||
@ -121,9 +121,9 @@ public class CommandArgParser {
|
||||
int start = currentArg.get(0).getStart();
|
||||
int end = Iterables.getLast(currentArg).getEnd();
|
||||
args.add(Substring.wrap(currentArg.stream()
|
||||
.map(Substring::getSubstring)
|
||||
.collect(Collectors.joining(" ")),
|
||||
start, end
|
||||
.map(Substring::getSubstring)
|
||||
.collect(Collectors.joining(" ")),
|
||||
start, end
|
||||
));
|
||||
currentArg.clear();
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public class CommandLoggingHandler implements CommandCallListener, AutoCloseable
|
||||
* Create a new instance.
|
||||
*
|
||||
* @param worldEdit an instance of WorldEdit
|
||||
* @param logger the logger to send messages to
|
||||
* @param logger the logger to send messages to
|
||||
*/
|
||||
public CommandLoggingHandler(WorldEdit worldEdit, Logger logger) {
|
||||
checkNotNull(worldEdit);
|
||||
@ -98,10 +98,10 @@ public class CommandLoggingHandler implements CommandCallListener, AutoCloseable
|
||||
builder.append(": ").append(parameters.getMetadata().getCalledName());
|
||||
|
||||
builder.append(": ")
|
||||
.append(Stream.concat(
|
||||
Stream.of(parameters.getMetadata().getCalledName()),
|
||||
parameters.getMetadata().getArguments().stream()
|
||||
).collect(Collectors.joining(" ")));
|
||||
.append(Stream.concat(
|
||||
Stream.of(parameters.getMetadata().getCalledName()),
|
||||
parameters.getMetadata().getArguments().stream()
|
||||
).collect(Collectors.joining(" ")));
|
||||
|
||||
if (logMode != null && actor instanceof Player) {
|
||||
Player player = (Player) actor;
|
||||
@ -132,7 +132,7 @@ public class CommandLoggingHandler implements CommandCallListener, AutoCloseable
|
||||
case REGION:
|
||||
try {
|
||||
builder.append(" - Region: ")
|
||||
.append(session.getSelection(world));
|
||||
.append(session.getSelection(world));
|
||||
} catch (IncompleteRegionException e) {
|
||||
break;
|
||||
}
|
||||
|
@ -39,13 +39,14 @@ public class CommandRegistrationHandler {
|
||||
|
||||
public <CI> void register(CommandManager manager, CommandRegistration<CI> registration, CI instance) {
|
||||
registration.containerInstance(instance)
|
||||
.commandManager(manager)
|
||||
.listeners(callListeners);
|
||||
.commandManager(manager)
|
||||
.listeners(callListeners);
|
||||
if (registration instanceof CommandPermissionsConditionGenerator.Registration) {
|
||||
((CommandPermissionsConditionGenerator.Registration) registration).commandPermissionsConditionGenerator(
|
||||
PERM_GEN
|
||||
PERM_GEN
|
||||
);
|
||||
}
|
||||
registration.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ public class CommandUtil {
|
||||
|
||||
private static Component makeDeprecatedFooter(String reason, Component replacement) {
|
||||
return TextComponent.builder()
|
||||
.append(DEPRECATION_MARKER)
|
||||
.append(" " + reason + ".")
|
||||
.append(TextComponent.newline())
|
||||
.build();
|
||||
.append(DEPRECATION_MARKER)
|
||||
.append(" " + reason + ".")
|
||||
.append(TextComponent.newline())
|
||||
.build();
|
||||
}
|
||||
|
||||
public interface NewCommandGenerator {
|
||||
@ -86,55 +86,57 @@ public class CommandUtil {
|
||||
|
||||
public static Component createNewCommandReplacementText(String suggestedCommand) {
|
||||
return TranslatableComponent.builder("worldedit.command.deprecation-message")
|
||||
.append(TextComponent.of(suggestedCommand)
|
||||
.clickEvent(ClickEvent.suggestCommand(suggestedCommand)))
|
||||
.build();
|
||||
.append(TextComponent.of(suggestedCommand)
|
||||
.clickEvent(ClickEvent.suggestCommand(suggestedCommand)))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Command deprecate(Command command, String reason,
|
||||
ReplacementMessageGenerator replacementMessageGenerator) {
|
||||
public static Command deprecate(
|
||||
Command command, String reason,
|
||||
ReplacementMessageGenerator replacementMessageGenerator
|
||||
) {
|
||||
Component deprecatedWarning = makeDeprecatedFooter(
|
||||
reason,
|
||||
replacementMessageGenerator.getReplacement(
|
||||
command,
|
||||
NoInputCommandParameters.builder().build()
|
||||
)
|
||||
reason,
|
||||
replacementMessageGenerator.getReplacement(
|
||||
command,
|
||||
NoInputCommandParameters.builder().build()
|
||||
)
|
||||
);
|
||||
return command.toBuilder()
|
||||
.action(parameters ->
|
||||
deprecatedCommandWarning(parameters, command, reason, replacementMessageGenerator))
|
||||
.footer(command.getFooter()
|
||||
.map(existingFooter -> existingFooter
|
||||
.append(TextComponent.newline())
|
||||
.append(deprecatedWarning))
|
||||
.orElse(deprecatedWarning))
|
||||
.build();
|
||||
.action(parameters ->
|
||||
deprecatedCommandWarning(parameters, command, reason, replacementMessageGenerator))
|
||||
.footer(command.getFooter()
|
||||
.map(existingFooter -> existingFooter
|
||||
.append(TextComponent.newline())
|
||||
.append(deprecatedWarning))
|
||||
.orElse(deprecatedWarning))
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Optional<Component> footerWithoutDeprecation(Command command) {
|
||||
return command.getFooter()
|
||||
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
|
||||
.map(footer -> Optional.of(
|
||||
replaceDeprecation(footer)
|
||||
))
|
||||
.orElseGet(command::getFooter);
|
||||
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
|
||||
.map(footer -> Optional.of(
|
||||
replaceDeprecation(footer)
|
||||
))
|
||||
.orElseGet(command::getFooter);
|
||||
}
|
||||
|
||||
public static Optional<Component> deprecationWarning(Command command) {
|
||||
return command.getFooter()
|
||||
.map(CommandUtil::extractDeprecation)
|
||||
.orElseGet(command::getFooter);
|
||||
.map(CommandUtil::extractDeprecation)
|
||||
.orElseGet(command::getFooter);
|
||||
}
|
||||
|
||||
public static boolean isDeprecated(Command command) {
|
||||
return command.getFooter()
|
||||
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
|
||||
.isPresent();
|
||||
.filter(footer -> anyComponent(footer, Predicate.isEqual(DEPRECATION_MARKER)))
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
private static boolean anyComponent(Component component, Predicate<Component> test) {
|
||||
return test.test(component) || component.children().stream()
|
||||
.anyMatch(x -> anyComponent(x, test));
|
||||
.anyMatch(x -> anyComponent(x, test));
|
||||
}
|
||||
|
||||
private static Component replaceDeprecation(Component component) {
|
||||
@ -142,9 +144,9 @@ public class CommandUtil {
|
||||
return TextComponent.empty();
|
||||
}
|
||||
return component.children(
|
||||
component.children().stream()
|
||||
.map(CommandUtil::replaceDeprecation)
|
||||
.collect(toList())
|
||||
component.children().stream()
|
||||
.map(CommandUtil::replaceDeprecation)
|
||||
.collect(toList())
|
||||
);
|
||||
}
|
||||
|
||||
@ -153,45 +155,45 @@ public class CommandUtil {
|
||||
return Optional.of(component);
|
||||
}
|
||||
return component.children().stream()
|
||||
.map(CommandUtil::extractDeprecation)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findAny();
|
||||
.map(CommandUtil::extractDeprecation)
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findAny();
|
||||
}
|
||||
|
||||
private static int deprecatedCommandWarning(
|
||||
CommandParameters parameters,
|
||||
Command command,
|
||||
String reason,
|
||||
ReplacementMessageGenerator generator
|
||||
CommandParameters parameters,
|
||||
Command command,
|
||||
String reason,
|
||||
ReplacementMessageGenerator generator
|
||||
) throws Exception {
|
||||
parameters.injectedValue(Key.of(Actor.class))
|
||||
.ifPresent(actor ->
|
||||
sendDeprecationMessage(parameters, command, reason, generator, actor)
|
||||
);
|
||||
.ifPresent(actor ->
|
||||
sendDeprecationMessage(parameters, command, reason, generator, actor)
|
||||
);
|
||||
return command.getAction().run(parameters);
|
||||
}
|
||||
|
||||
private static void sendDeprecationMessage(
|
||||
CommandParameters parameters,
|
||||
Command command,
|
||||
String reason,
|
||||
ReplacementMessageGenerator generator,
|
||||
Actor actor
|
||||
CommandParameters parameters,
|
||||
Command command,
|
||||
String reason,
|
||||
ReplacementMessageGenerator generator,
|
||||
Actor actor
|
||||
) {
|
||||
Component replacement = generator.getReplacement(command, parameters);
|
||||
actor.print(
|
||||
TextComponent.builder(reason + ". ", TextColor.GOLD)
|
||||
.append(replacement)
|
||||
.build()
|
||||
TextComponent.builder(reason + ". ", TextColor.GOLD)
|
||||
.append(replacement)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
public static Map<String, Command> getSubCommands(Command currentCommand) {
|
||||
return currentCommand.getParts().stream()
|
||||
.filter(p -> p instanceof SubCommandPart)
|
||||
.flatMap(p -> ((SubCommandPart) p).getCommands().stream())
|
||||
.collect(Collectors.toMap(Command::getName, Function.identity()));
|
||||
.filter(p -> p instanceof SubCommandPart)
|
||||
.flatMap(p -> ((SubCommandPart) p).getCommands().stream())
|
||||
.collect(Collectors.toMap(Command::getName, Function.identity()));
|
||||
}
|
||||
|
||||
private static String clean(String input) {
|
||||
@ -199,7 +201,7 @@ public class CommandUtil {
|
||||
}
|
||||
|
||||
private static final Comparator<Command> BY_CLEAN_NAME =
|
||||
Comparator.comparing(c -> clean(c.getName()));
|
||||
Comparator.comparing(c -> clean(c.getName()));
|
||||
|
||||
public static Comparator<Command> byCleanName() {
|
||||
return BY_CLEAN_NAME;
|
||||
@ -210,15 +212,15 @@ public class CommandUtil {
|
||||
*/
|
||||
public static List<String> fixSuggestions(String arguments, List<Substring> suggestions) {
|
||||
Substring lastArg = Iterables.getLast(
|
||||
CommandArgParser.spaceSplit(arguments)
|
||||
CommandArgParser.spaceSplit(arguments)
|
||||
);
|
||||
return suggestions.stream()
|
||||
// Re-map suggestions to only operate on the last non-quoted word
|
||||
.map(suggestion -> onlyOnLastQuotedWord(lastArg, suggestion))
|
||||
.map(suggestion -> suggestLast(lastArg, suggestion))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(toList());
|
||||
// Re-map suggestions to only operate on the last non-quoted word
|
||||
.map(suggestion -> onlyOnLastQuotedWord(lastArg, suggestion))
|
||||
.map(suggestion -> suggestLast(lastArg, suggestion))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
private static Substring onlyOnLastQuotedWord(Substring lastArg, Substring suggestion) {
|
||||
@ -254,7 +256,8 @@ public class CommandUtil {
|
||||
return Optional.empty();
|
||||
}
|
||||
checkState(end <= builder.length(),
|
||||
"Suggestion ends too late, last=%s, suggestion=", last, suggestion);
|
||||
"Suggestion ends too late, last=%s, suggestion=", last, suggestion
|
||||
);
|
||||
builder.replace(start, end, suggestion.getSubstring());
|
||||
return Optional.of(builder.toString());
|
||||
}
|
||||
@ -264,7 +267,7 @@ public class CommandUtil {
|
||||
* with the given message.
|
||||
*
|
||||
* @param condition the condition to check
|
||||
* @param message the message for failure
|
||||
* @param message the message for failure
|
||||
*/
|
||||
public static void checkCommandArgument(boolean condition, String message) {
|
||||
checkCommandArgument(condition, TextComponent.of(message));
|
||||
@ -275,7 +278,7 @@ public class CommandUtil {
|
||||
* with the given message.
|
||||
*
|
||||
* @param condition the condition to check
|
||||
* @param message the message for failure
|
||||
* @param message the message for failure
|
||||
*/
|
||||
public static void checkCommandArgument(boolean condition, Component message) {
|
||||
if (!condition) {
|
||||
@ -285,10 +288,11 @@ public class CommandUtil {
|
||||
|
||||
public static <T> T requireIV(Key<T> type, String name, InjectedValueAccess injectedValueAccess) {
|
||||
return injectedValueAccess.injectedValue(type).orElseThrow(() ->
|
||||
new IllegalStateException("No injected value for " + name + " (type " + type + ")")
|
||||
new IllegalStateException("No injected value for " + name + " (type " + type + ")")
|
||||
);
|
||||
}
|
||||
|
||||
private CommandUtil() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ public abstract class ExceptionConverterHelper implements ExceptionConverter {
|
||||
}
|
||||
|
||||
private static class ExceptionHandler implements Comparable<ExceptionHandler> {
|
||||
|
||||
final Class<? extends Throwable> cls;
|
||||
final Method method;
|
||||
|
||||
@ -108,6 +109,7 @@ public abstract class ExceptionConverterHelper implements ExceptionConverter {
|
||||
return cls.getCanonicalName().compareTo(o.cls.getCanonicalName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -76,7 +76,10 @@ public class WorldEditExceptionConverter extends ExceptionConverterHelper {
|
||||
final Matcher matcher = numberFormat.matcher(e.getMessage());
|
||||
|
||||
if (matcher.matches()) {
|
||||
throw newCommandException(Caption.of("worldedit.error.invalid-number.matches", TextComponent.of(matcher.group(1))), e);
|
||||
throw newCommandException(
|
||||
Caption.of("worldedit.error.invalid-number.matches", TextComponent.of(matcher.group(1))),
|
||||
e
|
||||
);
|
||||
} else {
|
||||
throw newCommandException(Caption.of("worldedit.error.invalid-number"), e);
|
||||
}
|
||||
|
@ -24,4 +24,5 @@ public interface CUIEvent {
|
||||
String getTypeId();
|
||||
|
||||
String[] getParameters();
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ public interface CUIRegion {
|
||||
* Sends CUI events describing the region for
|
||||
* versions of CUI equal to or greater than the
|
||||
* value supplied by getProtocolVersion().
|
||||
*
|
||||
*/
|
||||
void describeCUI(LocalSession session, Actor player);
|
||||
|
||||
@ -36,7 +35,6 @@ public interface CUIRegion {
|
||||
* Sends CUI events describing the region for
|
||||
* versions of CUI smaller than the value
|
||||
* supplied by getProtocolVersion().
|
||||
*
|
||||
*/
|
||||
void describeLegacyCUI(LocalSession session, Actor player);
|
||||
|
||||
@ -63,4 +61,5 @@ public interface CUIRegion {
|
||||
* @return the legacy type ID
|
||||
*/
|
||||
String getLegacyTypeID();
|
||||
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class SelectionCylinderEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] {
|
||||
return new String[]{
|
||||
String.valueOf(pos.getBlockX()),
|
||||
String.valueOf(pos.getBlockY()),
|
||||
String.valueOf(pos.getBlockZ()),
|
||||
@ -49,4 +49,5 @@ public class SelectionCylinderEvent implements CUIEvent {
|
||||
String.valueOf(radius.getZ())
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class SelectionEllipsoidPointEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] {
|
||||
return new String[]{
|
||||
String.valueOf(id),
|
||||
String.valueOf(pos.getBlockX()),
|
||||
String.valueOf(pos.getBlockY()),
|
||||
|
@ -36,7 +36,7 @@ public class SelectionMinMaxEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] {
|
||||
return new String[]{
|
||||
String.valueOf(min),
|
||||
String.valueOf(max),
|
||||
};
|
||||
|
@ -66,7 +66,7 @@ public class SelectionPoint2DEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] {
|
||||
return new String[]{
|
||||
String.valueOf(id),
|
||||
String.valueOf(blockX),
|
||||
String.valueOf(blockZ),
|
||||
|
@ -47,7 +47,7 @@ public class SelectionPointEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] {
|
||||
return new String[]{
|
||||
String.valueOf(id),
|
||||
String.valueOf(pos.getBlockX()),
|
||||
String.valueOf(pos.getBlockY()),
|
||||
|
@ -34,7 +34,7 @@ public class SelectionShapeEvent implements CUIEvent {
|
||||
|
||||
@Override
|
||||
public String[] getParameters() {
|
||||
return new String[] { shapeName };
|
||||
return new String[]{shapeName};
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class ServerCUIHandler {
|
||||
* Creates a structure block that shows the region.
|
||||
*
|
||||
* <p>
|
||||
* Null symbolises removal of the CUI.
|
||||
* Null symbolises removal of the CUI.
|
||||
* </p>
|
||||
*
|
||||
* @param player The player to create the structure block for.
|
||||
@ -170,4 +170,5 @@ public class ServerCUIHandler {
|
||||
return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(structureTag.build());
|
||||
//FAWE end
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,4 +58,5 @@ public class ExecutionData {
|
||||
throw new ExpressionTimeoutException("Calculations exceeded time limit.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -91,8 +91,10 @@ public class Expression implements Cloneable {
|
||||
|
||||
for (String variableName : variableNames) {
|
||||
slots.initVariable(variableName)
|
||||
.orElseThrow(() -> new ExpressionException(-1,
|
||||
"Tried to overwrite identifier '" + variableName + "'"));
|
||||
.orElseThrow(() -> new ExpressionException(
|
||||
-1,
|
||||
"Tried to overwrite identifier '" + variableName + "'"
|
||||
));
|
||||
}
|
||||
this.providedSlots = ImmutableList.copyOf(variableNames);
|
||||
|
||||
@ -124,8 +126,10 @@ public class Expression implements Cloneable {
|
||||
|
||||
for (String variableName : variableNames) {
|
||||
slots.initVariable(variableName)
|
||||
.orElseThrow(() -> new ExpressionException(-1,
|
||||
"Tried to overwrite identifier '" + variableName + "'"));
|
||||
.orElseThrow(() -> new ExpressionException(
|
||||
-1,
|
||||
"Tried to overwrite identifier '" + variableName + "'"
|
||||
));
|
||||
}
|
||||
this.providedSlots = ImmutableList.copyOf(variableNames);
|
||||
|
||||
@ -155,8 +159,10 @@ public class Expression implements Cloneable {
|
||||
for (int i = 0; i < values.length; ++i) {
|
||||
String slotName = providedSlots.get(i);
|
||||
LocalSlot.Variable slot = slots.getVariable(slotName)
|
||||
.orElseThrow(() -> new EvaluationException(-1,
|
||||
"Tried to assign to non-variable " + slotName + "."));
|
||||
.orElseThrow(() -> new EvaluationException(
|
||||
-1,
|
||||
"Tried to assign to non-variable " + slotName + "."
|
||||
));
|
||||
|
||||
slot.setValue(values[i]);
|
||||
}
|
||||
|
@ -50,8 +50,8 @@ public class ExpressionHelper {
|
||||
|
||||
public static EvaluationException evalException(Token token, String message) {
|
||||
return new EvaluationException(
|
||||
getErrorPosition(token),
|
||||
message
|
||||
getErrorPosition(token),
|
||||
message
|
||||
);
|
||||
}
|
||||
|
||||
@ -59,8 +59,10 @@ public class ExpressionHelper {
|
||||
check(iterations <= 256, ctx, "Loop exceeded 256 iterations");
|
||||
}
|
||||
|
||||
public static MethodHandle resolveFunction(Functions functions,
|
||||
ExpressionParser.FunctionCallContext ctx) {
|
||||
public static MethodHandle resolveFunction(
|
||||
Functions functions,
|
||||
ExpressionParser.FunctionCallContext ctx
|
||||
) {
|
||||
String fnName = ctx.name.getText();
|
||||
Set<MethodHandle> matchingFns = functions.getMap().get(fnName);
|
||||
check(!matchingFns.isEmpty(), ctx, "Unknown function '" + fnName + "'");
|
||||
@ -93,12 +95,12 @@ public class ExpressionHelper {
|
||||
}
|
||||
// We matched no function, fail with appropriate message.
|
||||
String possibleCounts = matchingFns.stream()
|
||||
.map(mh -> mh.isVarargsCollector()
|
||||
? (mh.type().parameterCount() - 1) + "+"
|
||||
: String.valueOf(mh.type().parameterCount()))
|
||||
.collect(Collectors.joining("/"));
|
||||
.map(mh -> mh.isVarargsCollector()
|
||||
? (mh.type().parameterCount() - 1) + "+"
|
||||
: String.valueOf(mh.type().parameterCount()))
|
||||
.collect(Collectors.joining("/"));
|
||||
throw evalException(ctx, "Incorrect number of arguments for function '" + fnName + "', "
|
||||
+ "expected " + possibleCounts + ", " + "got " + ctx.args.size());
|
||||
+ "expected " + possibleCounts + ", " + "got " + ctx.args.size());
|
||||
}
|
||||
|
||||
// Special argument handle names
|
||||
@ -111,15 +113,18 @@ public class ExpressionHelper {
|
||||
* If this argument needs a handle, returns the name of the handle needed. Otherwise, returns
|
||||
* {@code null}. If {@code arg} isn't a valid handle reference, throws.
|
||||
*/
|
||||
public static String getArgumentHandleName(String fnName, MethodType type, int i,
|
||||
ParserRuleContext arg) {
|
||||
public static String getArgumentHandleName(
|
||||
String fnName, MethodType type, int i,
|
||||
ParserRuleContext arg
|
||||
) {
|
||||
// Pass variable handle in for modification?
|
||||
Class<?> pType = type.parameterType(i);
|
||||
Optional<String> id = tryResolveId(arg);
|
||||
if (pType == LocalSlot.Variable.class) {
|
||||
// MUST be an id
|
||||
check(id.isPresent(), arg,
|
||||
"Function '" + fnName + "' requires a variable in parameter " + i);
|
||||
"Function '" + fnName + "' requires a variable in parameter " + i
|
||||
);
|
||||
return id.get();
|
||||
} else if (pType == LocalSlot.class) {
|
||||
return id.orElse(WRAPPED_CONSTANT);
|
||||
@ -129,7 +134,7 @@ public class ExpressionHelper {
|
||||
|
||||
private static Optional<String> tryResolveId(ParserRuleContext arg) {
|
||||
Optional<ExpressionParser.WrappedExprContext> wrappedExprContext =
|
||||
tryAs(arg, ExpressionParser.WrappedExprContext.class);
|
||||
tryAs(arg, ExpressionParser.WrappedExprContext.class);
|
||||
if (wrappedExprContext.isPresent()) {
|
||||
return tryResolveId(wrappedExprContext.get().expression());
|
||||
}
|
||||
@ -140,8 +145,8 @@ public class ExpressionHelper {
|
||||
}
|
||||
|
||||
private static <T extends ParserRuleContext> Optional<T> tryAs(
|
||||
ParserRuleContext ctx,
|
||||
Class<T> rule
|
||||
ParserRuleContext ctx,
|
||||
Class<T> rule
|
||||
) {
|
||||
if (rule.isInstance(ctx)) {
|
||||
return Optional.of(rule.cast(ctx));
|
||||
|
@ -23,7 +23,9 @@ package com.sk89q.worldedit.internal.expression;
|
||||
* Thrown when an evaluation exceeds the timeout time.
|
||||
*/
|
||||
public class ExpressionTimeoutException extends EvaluationException {
|
||||
|
||||
public ExpressionTimeoutException(String message) {
|
||||
super(-1, message);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,8 +34,10 @@ class ExpressionValidator extends ExpressionBaseListener {
|
||||
private final Set<String> variableNames = new HashSet<>();
|
||||
private final Functions functions;
|
||||
|
||||
ExpressionValidator(Collection<String> variableNames,
|
||||
Functions functions) {
|
||||
ExpressionValidator(
|
||||
Collection<String> variableNames,
|
||||
Functions functions
|
||||
) {
|
||||
this.variableNames.addAll(variableNames);
|
||||
this.functions = functions;
|
||||
}
|
||||
@ -58,11 +60,13 @@ class ExpressionValidator extends ExpressionBaseListener {
|
||||
public void enterIdExpr(ExpressionParser.IdExprContext ctx) {
|
||||
String text = ctx.source.getText();
|
||||
check(variableNames.contains(text), ctx,
|
||||
"Variable '" + text + "' is not bound");
|
||||
"Variable '" + text + "' is not bound"
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFunctionCall(ExpressionParser.FunctionCallContext ctx) {
|
||||
resolveFunction(functions, ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,7 +56,8 @@ public final class Functions {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try {
|
||||
DOUBLE_VALUE = lookup.findVirtual(Number.class, "doubleValue",
|
||||
methodType(double.class));
|
||||
methodType(double.class)
|
||||
);
|
||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -68,8 +69,10 @@ public final class Functions {
|
||||
handle = handle.asType(handle.type().wrap());
|
||||
if (handle.type().returnType() != Double.class) {
|
||||
// Ensure that the handle returns a Double, even if originally a Number
|
||||
checkState(Number.class.isAssignableFrom(handle.type().returnType()),
|
||||
"Function does not return a number");
|
||||
checkState(
|
||||
Number.class.isAssignableFrom(handle.type().returnType()),
|
||||
"Function does not return a number"
|
||||
);
|
||||
handle = handle.asType(handle.type().changeReturnType(Number.class));
|
||||
handle = filterReturnValue(handle, DOUBLE_VALUE);
|
||||
}
|
||||
@ -83,94 +86,124 @@ public final class Functions {
|
||||
}
|
||||
|
||||
private static void addMathHandles(
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
) throws NoSuchMethodException, IllegalAccessException {
|
||||
// double <name>(double) functions
|
||||
for (String name : ImmutableList.of(
|
||||
"sin", "cos", "tan", "asin", "acos", "atan",
|
||||
"sinh", "cosh", "tanh", "sqrt", "cbrt", "abs",
|
||||
"ceil", "floor", "rint", "exp", "log", "log10"
|
||||
"sin", "cos", "tan", "asin", "acos", "atan",
|
||||
"sinh", "cosh", "tanh", "sqrt", "cbrt", "abs",
|
||||
"ceil", "floor", "rint", "exp", "log", "log10"
|
||||
)) {
|
||||
map.put(name, lookup.findStatic(Math.class, name,
|
||||
methodType(double.class, double.class)));
|
||||
methodType(double.class, double.class)
|
||||
));
|
||||
}
|
||||
// Alias ln -> log
|
||||
map.put("ln", lookup.findStatic(Math.class, "log",
|
||||
methodType(double.class, double.class)));
|
||||
methodType(double.class, double.class)
|
||||
));
|
||||
map.put("round", lookup.findStatic(Math.class, "round",
|
||||
methodType(long.class, double.class)));
|
||||
methodType(long.class, double.class)
|
||||
));
|
||||
|
||||
map.put("atan2", lookup.findStatic(Math.class, "atan2",
|
||||
methodType(double.class, double.class, double.class)));
|
||||
methodType(double.class, double.class, double.class)
|
||||
));
|
||||
|
||||
// Special cases: we accept varargs for these
|
||||
map.put("min", lookup.findStatic(Doubles.class, "min",
|
||||
methodType(double.class, double[].class))
|
||||
.asVarargsCollector(double[].class));
|
||||
methodType(double.class, double[].class)
|
||||
)
|
||||
.asVarargsCollector(double[].class));
|
||||
map.put("max", lookup.findStatic(Doubles.class, "max",
|
||||
methodType(double.class, double[].class))
|
||||
.asVarargsCollector(double[].class));
|
||||
methodType(double.class, double[].class)
|
||||
)
|
||||
.asVarargsCollector(double[].class));
|
||||
}
|
||||
|
||||
private static void addStaticFunctionHandles(
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
) throws NoSuchMethodException, IllegalAccessException {
|
||||
map.put("rotate", lookup.findStatic(Functions.class, "rotate",
|
||||
methodType(double.class, Variable.class, Variable.class, double.class)));
|
||||
methodType(double.class, Variable.class, Variable.class, double.class)
|
||||
));
|
||||
map.put("swap", lookup.findStatic(Functions.class, "swap",
|
||||
methodType(double.class, Variable.class, Variable.class)));
|
||||
methodType(double.class, Variable.class, Variable.class)
|
||||
));
|
||||
map.put("gmegabuf", lookup.findStatic(Functions.class, "gmegabuf",
|
||||
methodType(double.class, double.class)));
|
||||
methodType(double.class, double.class)
|
||||
));
|
||||
map.put("gmegabuf", lookup.findStatic(Functions.class, "gmegabuf",
|
||||
methodType(double.class, double.class, double.class)));
|
||||
methodType(double.class, double.class, double.class)
|
||||
));
|
||||
map.put("gclosest", lookup.findStatic(Functions.class, "gclosest",
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class)));
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class
|
||||
)
|
||||
));
|
||||
map.put("random", lookup.findStatic(Functions.class, "random",
|
||||
methodType(double.class)));
|
||||
methodType(double.class)
|
||||
));
|
||||
map.put("randint", lookup.findStatic(Functions.class, "randint",
|
||||
methodType(double.class, double.class)));
|
||||
methodType(double.class, double.class)
|
||||
));
|
||||
map.put("perlin", lookup.findStatic(Functions.class, "perlin",
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class, double.class)));
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class, double.class
|
||||
)
|
||||
));
|
||||
map.put("voronoi", lookup.findStatic(Functions.class, "voronoi",
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class)));
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class
|
||||
)
|
||||
));
|
||||
map.put("ridgedmulti", lookup.findStatic(Functions.class, "ridgedmulti",
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class)));
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
private void addInstanceFunctionHandles(
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
SetMultimap<String, MethodHandle> map,
|
||||
MethodHandles.Lookup lookup
|
||||
) throws NoSuchMethodException, IllegalAccessException {
|
||||
map.put("megabuf", lookup.findSpecial(Functions.class, "megabuf",
|
||||
methodType(double.class, double.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
map.put("megabuf", lookup.findSpecial(Functions.class, "megabuf",
|
||||
methodType(double.class, double.class, double.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class, double.class), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
map.put("closest", lookup.findSpecial(Functions.class, "closest",
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class, double.class, double.class, double.class,
|
||||
double.class, double.class
|
||||
), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
|
||||
// rely on expression field
|
||||
map.put("query", lookup.findSpecial(Functions.class, "query",
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class
|
||||
), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
map.put("queryAbs", lookup.findSpecial(Functions.class, "queryAbs",
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class
|
||||
), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
map.put("queryRel", lookup.findSpecial(Functions.class, "queryRel",
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class), Functions.class)
|
||||
.bindTo(this));
|
||||
methodType(double.class, double.class, double.class, double.class, LocalSlot.class,
|
||||
LocalSlot.class
|
||||
), Functions.class
|
||||
)
|
||||
.bindTo(this));
|
||||
}
|
||||
|
||||
private static double rotate(Variable x, Variable y, double angle) {
|
||||
@ -212,7 +245,7 @@ public final class Functions {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
this.map = ImmutableSetMultimap.copyOf(
|
||||
Multimaps.transformValues(map, Functions::clean)
|
||||
Multimaps.transformValues(map, Functions::clean)
|
||||
);
|
||||
}
|
||||
|
||||
@ -258,17 +291,25 @@ public final class Functions {
|
||||
|
||||
private double closest(double x, double y, double z, double index, double count, double stride) {
|
||||
return findClosest(
|
||||
megaBuffer, x, y, z, (int) index, (int) count, (int) stride
|
||||
megaBuffer, x, y, z, (int) index, (int) count, (int) stride
|
||||
);
|
||||
}
|
||||
|
||||
private static double gclosest(double x, double y, double z, double index, double count, double stride) {
|
||||
return findClosest(
|
||||
globalMegaBuffer, x, y, z, (int) index, (int) count, (int) stride
|
||||
globalMegaBuffer, x, y, z, (int) index, (int) count, (int) stride
|
||||
);
|
||||
}
|
||||
|
||||
private static double findClosest(Int2ObjectMap<double[]> megabuf, double x, double y, double z, int index, int count, int stride) {
|
||||
private static double findClosest(
|
||||
Int2ObjectMap<double[]> megabuf,
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
int index,
|
||||
int count,
|
||||
int stride
|
||||
) {
|
||||
int closestIndex = -1;
|
||||
double minDistanceSquared = Double.MAX_VALUE;
|
||||
|
||||
@ -300,8 +341,10 @@ public final class Functions {
|
||||
|
||||
private static final ThreadLocal<PerlinNoise> localPerlin = ThreadLocal.withInitial(PerlinNoise::new);
|
||||
|
||||
private static double perlin(double seed, double x, double y, double z,
|
||||
double frequency, double octaves, double persistence) {
|
||||
private static double perlin(
|
||||
double seed, double x, double y, double z,
|
||||
double frequency, double octaves, double persistence
|
||||
) {
|
||||
PerlinNoise perlin = localPerlin.get();
|
||||
try {
|
||||
perlin.setSeed((int) seed);
|
||||
@ -329,8 +372,10 @@ public final class Functions {
|
||||
|
||||
private static final ThreadLocal<RidgedMultiFractalNoise> localRidgedMulti = ThreadLocal.withInitial(RidgedMultiFractalNoise::new);
|
||||
|
||||
private static double ridgedmulti(double seed, double x, double y, double z,
|
||||
double frequency, double octaves) {
|
||||
private static double ridgedmulti(
|
||||
double seed, double x, double y, double z,
|
||||
double frequency, double octaves
|
||||
) {
|
||||
RidgedMultiFractalNoise ridgedMulti = localRidgedMulti.get();
|
||||
try {
|
||||
ridgedMulti.setSeed((int) seed);
|
||||
@ -346,7 +391,7 @@ public final class Functions {
|
||||
// Compare to input values and determine return value
|
||||
// -1 is a wildcard, always true
|
||||
double ret = ((type.getValue() == -1 || typeId == type.getValue())
|
||||
&& (data.getValue() == -1 || dataValue == data.getValue())) ? 1.0 : 0.0;
|
||||
&& (data.getValue() == -1 || dataValue == data.getValue())) ? 1.0 : 0.0;
|
||||
|
||||
if (type instanceof Variable) {
|
||||
((Variable) type).setValue(typeId);
|
||||
|
@ -24,8 +24,17 @@ import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
|
||||
class LexerErrorListener extends BaseErrorListener {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
public void syntaxError(
|
||||
Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e
|
||||
) {
|
||||
throw new LexerException(charPositionInLine, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ package com.sk89q.worldedit.internal.expression;
|
||||
public interface LocalSlot {
|
||||
|
||||
final class Constant implements LocalSlot {
|
||||
|
||||
private final double value;
|
||||
|
||||
public Constant(double value) {
|
||||
@ -40,9 +41,11 @@ public interface LocalSlot {
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final class Variable implements LocalSlot {
|
||||
|
||||
private double value;
|
||||
|
||||
public Variable(double value) {
|
||||
@ -62,6 +65,7 @@ public interface LocalSlot {
|
||||
public String toString() {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
double getValue();
|
||||
|
@ -24,8 +24,17 @@ import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.Recognizer;
|
||||
|
||||
class ParserErrorListener extends BaseErrorListener {
|
||||
|
||||
@Override
|
||||
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) {
|
||||
public void syntaxError(
|
||||
Recognizer<?, ?> recognizer,
|
||||
Object offendingSymbol,
|
||||
int line,
|
||||
int charPositionInLine,
|
||||
String msg,
|
||||
RecognitionException e
|
||||
) {
|
||||
throw new ParserException(charPositionInLine, msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ public class SlotTable {
|
||||
|
||||
public Optional<LocalSlot.Variable> getVariable(String name) {
|
||||
return getSlot(name)
|
||||
.filter(LocalSlot.Variable.class::isInstance)
|
||||
.map(LocalSlot.Variable.class::cast);
|
||||
.filter(LocalSlot.Variable.class::isInstance)
|
||||
.map(LocalSlot.Variable.class::cast);
|
||||
}
|
||||
|
||||
public OptionalDouble getSlotValue(String name) {
|
||||
|
@ -32,7 +32,8 @@ class BreakException extends RuntimeException {
|
||||
|
||||
private BreakException(boolean doContinue) {
|
||||
super(doContinue ? "'continue' encountered outside a loop" : "'break' encountered outside a loop",
|
||||
null, true, false);
|
||||
null, true, false
|
||||
);
|
||||
|
||||
this.doContinue = doContinue;
|
||||
}
|
||||
|
@ -94,9 +94,9 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
|
||||
private Token extractToken(ParserRuleContext ctx) {
|
||||
List<TerminalNode> children = ctx.children.stream()
|
||||
.filter(TerminalNode.class::isInstance)
|
||||
.map(TerminalNode.class::cast)
|
||||
.collect(Collectors.toList());
|
||||
.filter(TerminalNode.class::isInstance)
|
||||
.map(TerminalNode.class::cast)
|
||||
.collect(Collectors.toList());
|
||||
ExpressionHelper.check(children.size() == 1, ctx, "Expected exactly one token, got " + children.size());
|
||||
return children.get(0).getSymbol();
|
||||
}
|
||||
@ -111,19 +111,20 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
|
||||
private void checkHandle(MethodHandle mh, ParserRuleContext ctx) {
|
||||
ExpressionHelper.check(mh.type().equals(ExpressionHandles.COMPILED_EXPRESSION_SIG), ctx,
|
||||
"Incorrect type returned from handler for " + ctx.getClass());
|
||||
"Incorrect type returned from handler for " + ctx.getClass()
|
||||
);
|
||||
}
|
||||
|
||||
private MethodHandle evaluateForNamedValue(ParserRuleContext ctx, String name) {
|
||||
MethodHandle guard = MethodHandles.guardWithTest(
|
||||
// if result is null
|
||||
IS_NULL.asType(methodType(boolean.class, Double.class)),
|
||||
// throw appropriate exception, dropping `result` argument
|
||||
MethodHandles.dropArguments(
|
||||
ExpressionHandles.throwEvalException(ctx, "Invalid expression for " + name), 0, Double.class
|
||||
),
|
||||
// else return the argument we were passed
|
||||
MethodHandles.identity(Double.class)
|
||||
// if result is null
|
||||
IS_NULL.asType(methodType(boolean.class, Double.class)),
|
||||
// throw appropriate exception, dropping `result` argument
|
||||
MethodHandles.dropArguments(
|
||||
ExpressionHandles.throwEvalException(ctx, "Invalid expression for " + name), 0, Double.class
|
||||
),
|
||||
// else return the argument we were passed
|
||||
MethodHandles.identity(Double.class)
|
||||
);
|
||||
// now pass `result` into `guard`
|
||||
MethodHandle result = evaluate(ctx).handle;
|
||||
@ -138,18 +139,20 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
MethodHandle value = evaluateForNamedValue(boolExpression, "a boolean");
|
||||
// Pass `value` into converter, returns (ExecutionData)boolean;
|
||||
return MethodHandles.collectArguments(
|
||||
DOUBLE_TO_BOOL, 0, value
|
||||
DOUBLE_TO_BOOL, 0, value
|
||||
);
|
||||
}
|
||||
|
||||
private MethodHandle evaluateConditional(ParserRuleContext condition,
|
||||
ParserRuleContext trueBranch,
|
||||
ParserRuleContext falseBranch) {
|
||||
private MethodHandle evaluateConditional(
|
||||
ParserRuleContext condition,
|
||||
ParserRuleContext trueBranch,
|
||||
ParserRuleContext falseBranch
|
||||
) {
|
||||
// easiest one of the bunch
|
||||
return MethodHandles.guardWithTest(
|
||||
evaluateBoolean(condition),
|
||||
trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle,
|
||||
falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle
|
||||
evaluateBoolean(condition),
|
||||
trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle,
|
||||
falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle
|
||||
);
|
||||
}
|
||||
|
||||
@ -166,45 +169,45 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
@Override
|
||||
public MethodHandle visitWhileStatement(ExpressionParser.WhileStatementContext ctx) {
|
||||
return ExpressionHandles.whileLoop(
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body)
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle visitDoStatement(ExpressionParser.DoStatementContext ctx) {
|
||||
return ExpressionHandles.doWhileLoop(
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body)
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle visitForStatement(ExpressionParser.ForStatementContext ctx) {
|
||||
return ExpressionHandles.forLoop(
|
||||
evaluate(ctx.init).handle,
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body),
|
||||
evaluate(ctx.update).handle
|
||||
evaluate(ctx.init).handle,
|
||||
evaluateBoolean(ctx.condition),
|
||||
evaluate(ctx.body),
|
||||
evaluate(ctx.update).handle
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle visitSimpleForStatement(ExpressionParser.SimpleForStatementContext ctx) {
|
||||
return ExpressionHandles.simpleForLoop(
|
||||
evaluateForValue(ctx.first),
|
||||
evaluateForValue(ctx.last),
|
||||
ctx.counter,
|
||||
evaluate(ctx.body)
|
||||
evaluateForValue(ctx.first),
|
||||
evaluateForValue(ctx.last),
|
||||
ctx.counter,
|
||||
evaluate(ctx.body)
|
||||
);
|
||||
}
|
||||
|
||||
private static final MethodHandle BREAK_STATEMENT =
|
||||
ExpressionHandles.dropData(MethodHandles.throwException(Double.class, BreakException.class)
|
||||
.bindTo(BreakException.BREAK));
|
||||
ExpressionHandles.dropData(MethodHandles.throwException(Double.class, BreakException.class)
|
||||
.bindTo(BreakException.BREAK));
|
||||
private static final MethodHandle CONTINUE_STATEMENT =
|
||||
ExpressionHandles.dropData(MethodHandles.throwException(Double.class, BreakException.class)
|
||||
.bindTo(BreakException.CONTINUE));
|
||||
ExpressionHandles.dropData(MethodHandles.throwException(Double.class, BreakException.class)
|
||||
.bindTo(BreakException.CONTINUE));
|
||||
|
||||
@Override
|
||||
public MethodHandle visitBreakStatement(ExpressionParser.BreakStatementContext ctx) {
|
||||
@ -219,20 +222,20 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
// MH = (Double)Double
|
||||
// takes the double to return, conveniently has Double return type
|
||||
private static final MethodHandle RETURN_STATEMENT_BASE = MethodHandles.filterReturnValue(
|
||||
// take the (Double)ReturnException constructor
|
||||
ExpressionHandles.NEW_RETURN_EXCEPTION,
|
||||
// and map the return type to Double by throwing it
|
||||
MethodHandles.throwException(Double.class, ReturnException.class)
|
||||
// take the (Double)ReturnException constructor
|
||||
ExpressionHandles.NEW_RETURN_EXCEPTION,
|
||||
// and map the return type to Double by throwing it
|
||||
MethodHandles.throwException(Double.class, ReturnException.class)
|
||||
);
|
||||
|
||||
@Override
|
||||
public MethodHandle visitReturnStatement(ExpressionParser.ReturnStatementContext ctx) {
|
||||
return MethodHandles.filterArguments(
|
||||
// take the (Double)Double return statement
|
||||
RETURN_STATEMENT_BASE,
|
||||
0,
|
||||
// map the Double back to ExecutionData via the returnValue
|
||||
evaluate(ctx.value).handle
|
||||
// take the (Double)Double return statement
|
||||
RETURN_STATEMENT_BASE,
|
||||
0,
|
||||
// map the Double back to ExecutionData via the returnValue
|
||||
evaluate(ctx.value).handle
|
||||
);
|
||||
}
|
||||
|
||||
@ -305,7 +308,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
return value;
|
||||
case MINUS:
|
||||
return ExpressionHandles.call(data ->
|
||||
-(double) ExpressionHandles.standardInvoke(value, data)
|
||||
-(double) ExpressionHandles.standardInvoke(value, data)
|
||||
);
|
||||
}
|
||||
throw ExpressionHelper.evalException(ctx, "Invalid text for plus/minus expr: " + ctx.op.getText());
|
||||
@ -315,7 +318,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
public MethodHandle visitNotExpr(ExpressionParser.NotExprContext ctx) {
|
||||
MethodHandle expr = evaluateBoolean(ctx.expr);
|
||||
return ExpressionHandles.call(data ->
|
||||
ExpressionHandles.boolToDouble(!(boolean) ExpressionHandles.standardInvoke(expr, data))
|
||||
ExpressionHandles.boolToDouble(!(boolean) ExpressionHandles.standardInvoke(expr, data))
|
||||
);
|
||||
}
|
||||
|
||||
@ -327,7 +330,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
// - Convert to long from double value
|
||||
// - Convert from Object to Double to double.
|
||||
return ExpressionHandles.call(data ->
|
||||
(double) ~(long) (double) ExpressionHandles.standardInvoke(expr, data)
|
||||
(double) ~(long) (double) ExpressionHandles.standardInvoke(expr, data)
|
||||
);
|
||||
}
|
||||
|
||||
@ -336,11 +339,11 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
MethodHandle left = evaluateBoolean(ctx.left);
|
||||
MethodHandle right = evaluateForValue(ctx.right);
|
||||
return MethodHandles.guardWithTest(
|
||||
left,
|
||||
right,
|
||||
ExpressionHandles.dropData(
|
||||
MethodHandles.constant(Double.class, ExpressionHandles.boolToDouble(false))
|
||||
)
|
||||
left,
|
||||
right,
|
||||
ExpressionHandles.dropData(
|
||||
MethodHandles.constant(Double.class, ExpressionHandles.boolToDouble(false))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -351,41 +354,45 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
// Inject left as primary condition, on failure take right with data parameter
|
||||
// logic = (Double,ExecutionData)Double
|
||||
MethodHandle logic = MethodHandles.guardWithTest(
|
||||
// data arg dropped implicitly -- (Double)boolean;
|
||||
DOUBLE_TO_BOOL,
|
||||
// drop data arg -- (Double,ExecutionData)Double;
|
||||
MethodHandles.dropArguments(
|
||||
MethodHandles.identity(Double.class), 1, ExecutionData.class
|
||||
),
|
||||
// drop left arg, call right -- (Double,ExecutionData)Double;
|
||||
MethodHandles.dropArguments(
|
||||
right, 0, Double.class
|
||||
)
|
||||
// data arg dropped implicitly -- (Double)boolean;
|
||||
DOUBLE_TO_BOOL,
|
||||
// drop data arg -- (Double,ExecutionData)Double;
|
||||
MethodHandles.dropArguments(
|
||||
MethodHandles.identity(Double.class), 1, ExecutionData.class
|
||||
),
|
||||
// drop left arg, call right -- (Double,ExecutionData)Double;
|
||||
MethodHandles.dropArguments(
|
||||
right, 0, Double.class
|
||||
)
|
||||
);
|
||||
// mixed = (ExecutionData,ExecutionData)Double
|
||||
MethodHandle mixed = MethodHandles.collectArguments(
|
||||
logic, 0, left
|
||||
logic, 0, left
|
||||
);
|
||||
// Deduplicate ExecutionData
|
||||
return ExpressionHandles.dedupData(mixed);
|
||||
}
|
||||
|
||||
private MethodHandle evaluateBinary(ParserRuleContext left,
|
||||
ParserRuleContext right,
|
||||
DoubleBinaryOperator op) {
|
||||
private MethodHandle evaluateBinary(
|
||||
ParserRuleContext left,
|
||||
ParserRuleContext right,
|
||||
DoubleBinaryOperator op
|
||||
) {
|
||||
MethodHandle mhLeft = evaluateForValue(left);
|
||||
MethodHandle mhRight = evaluateForValue(right);
|
||||
// Map two data args to two double args, then evaluate op
|
||||
MethodHandle doubleData = MethodHandles.filterArguments(
|
||||
CALL_BINARY_OP.bindTo(op), 0,
|
||||
unboxDoubles(mhLeft), unboxDoubles(mhRight)
|
||||
CALL_BINARY_OP.bindTo(op), 0,
|
||||
unboxDoubles(mhLeft), unboxDoubles(mhRight)
|
||||
);
|
||||
return ExpressionHandles.dedupData(doubleData);
|
||||
}
|
||||
|
||||
private MethodHandle evaluateBinary(ParserRuleContext left,
|
||||
ParserRuleContext right,
|
||||
Supplier<DoubleBinaryOperator> op) {
|
||||
private MethodHandle evaluateBinary(
|
||||
ParserRuleContext left,
|
||||
ParserRuleContext right,
|
||||
Supplier<DoubleBinaryOperator> op
|
||||
) {
|
||||
return evaluateBinary(left, right, op.get());
|
||||
}
|
||||
|
||||
@ -494,11 +501,13 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
MethodHandle value = evaluateForValue(ctx.expr);
|
||||
if (ctx.op.getType() == EXCLAMATION_MARK) {
|
||||
return ExpressionHandles.call(data ->
|
||||
factorial((double) ExpressionHandles.standardInvoke(value, data))
|
||||
factorial((double) ExpressionHandles.standardInvoke(value, data))
|
||||
);
|
||||
}
|
||||
throw ExpressionHelper.evalException(ctx,
|
||||
"Invalid text for post-unary expr: " + ctx.op.getText());
|
||||
throw ExpressionHelper.evalException(
|
||||
ctx,
|
||||
"Invalid text for post-unary expr: " + ctx.op.getText()
|
||||
);
|
||||
}
|
||||
|
||||
private static final double[] factorials = new double[171];
|
||||
@ -560,7 +569,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
break;
|
||||
default:
|
||||
throw ExpressionHelper.evalException(ctx, "Invalid text for assign expr: "
|
||||
+ ctx.assignmentOperator().getText());
|
||||
+ ctx.assignmentOperator().getText());
|
||||
}
|
||||
}
|
||||
variable.setValue(value);
|
||||
@ -589,7 +598,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
// Collapse every data into one argument
|
||||
int[] permutation = new int[arguments.length];
|
||||
return MethodHandles.permuteArguments(
|
||||
manyData, ExpressionHandles.COMPILED_EXPRESSION_SIG, permutation
|
||||
manyData, ExpressionHandles.COMPILED_EXPRESSION_SIG, permutation
|
||||
);
|
||||
}
|
||||
|
||||
@ -605,7 +614,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
MethodHandle filter = evaluateForValue(arg);
|
||||
filter = filter.asType(filter.type().unwrap());
|
||||
return MethodHandles.collectArguments(
|
||||
NEW_LS_CONSTANT, 0, filter
|
||||
NEW_LS_CONSTANT, 0, filter
|
||||
);
|
||||
}
|
||||
// small hack
|
||||
@ -617,7 +626,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
@Override
|
||||
public MethodHandle visitConstantExpression(ExpressionParser.ConstantExpressionContext ctx) {
|
||||
return ExpressionHandles.dropData(
|
||||
MethodHandles.constant(Double.class, Double.parseDouble(ctx.getText()))
|
||||
MethodHandles.constant(Double.class, Double.parseDouble(ctx.getText()))
|
||||
);
|
||||
}
|
||||
|
||||
@ -631,7 +640,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
* Method handle (ExecutionData)Double, returns null.
|
||||
*/
|
||||
private static final MethodHandle DEFAULT_RESULT =
|
||||
ExpressionHandles.dropData(MethodHandles.constant(Double.class, null));
|
||||
ExpressionHandles.dropData(MethodHandles.constant(Double.class, null));
|
||||
|
||||
@Override
|
||||
protected MethodHandle defaultResult() {
|
||||
@ -678,15 +687,16 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
|
||||
// Add a dummy Double parameter to the end
|
||||
// MH:dummyDouble = (ExecutionData, Double)Double
|
||||
MethodHandle dummyDouble = MethodHandles.dropArguments(
|
||||
result, 1, Double.class
|
||||
result, 1, Double.class
|
||||
);
|
||||
// Have oldResult turn it from data->Double
|
||||
// MH:doubledData = (ExecutionData, ExecutionData)Double
|
||||
MethodHandle doubledData = MethodHandles.collectArguments(
|
||||
dummyDouble, 1, oldResult
|
||||
dummyDouble, 1, oldResult
|
||||
);
|
||||
// Deduplicate the `data` parameter
|
||||
// MH:@return = (ExecutionData)Double
|
||||
return ExpressionHandles.dedupData(doubledData);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
class ExecNode {
|
||||
|
||||
final ParserRuleContext ctx;
|
||||
final MethodHandle handle;
|
||||
|
||||
@ -31,4 +32,5 @@ class ExecNode {
|
||||
this.ctx = ctx;
|
||||
this.handle = handle;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ public class ExpressionCompiler {
|
||||
|
||||
private static final String CE_EXECUTE = "execute";
|
||||
private static final MethodType HANDLE_TO_CE =
|
||||
methodType(CompiledExpression.class, MethodHandle.class);
|
||||
methodType(CompiledExpression.class, MethodHandle.class);
|
||||
|
||||
private static final MethodHandle HANDLE_TO_CE_CONVERTER;
|
||||
|
||||
@ -46,35 +46,38 @@ public class ExpressionCompiler {
|
||||
MethodHandle handleInvoker = MethodHandles.invoker(ExpressionHandles.COMPILED_EXPRESSION_SIG);
|
||||
try {
|
||||
HANDLE_TO_CE_CONVERTER = LambdaMetafactory.metafactory(
|
||||
MethodHandles.lookup(),
|
||||
// Implementing CompiledExpression.execute
|
||||
CE_EXECUTE,
|
||||
// Take a handle, to be converted to CompiledExpression
|
||||
HANDLE_TO_CE,
|
||||
// Raw signature for SAM type
|
||||
ExpressionHandles.COMPILED_EXPRESSION_SIG,
|
||||
// Handle to call the captured handle.
|
||||
handleInvoker,
|
||||
// Actual signature at invoke time
|
||||
ExpressionHandles.COMPILED_EXPRESSION_SIG
|
||||
MethodHandles.lookup(),
|
||||
// Implementing CompiledExpression.execute
|
||||
CE_EXECUTE,
|
||||
// Take a handle, to be converted to CompiledExpression
|
||||
HANDLE_TO_CE,
|
||||
// Raw signature for SAM type
|
||||
ExpressionHandles.COMPILED_EXPRESSION_SIG,
|
||||
// Handle to call the captured handle.
|
||||
handleInvoker,
|
||||
// Actual signature at invoke time
|
||||
ExpressionHandles.COMPILED_EXPRESSION_SIG
|
||||
).dynamicInvoker().asType(HANDLE_TO_CE);
|
||||
} catch (LambdaConversionException e) {
|
||||
throw new IllegalStateException("Failed to load ExpressionCompiler MetaFactory", e);
|
||||
}
|
||||
}
|
||||
|
||||
public CompiledExpression compileExpression(ExpressionParser.AllStatementsContext root,
|
||||
Functions functions) {
|
||||
public CompiledExpression compileExpression(
|
||||
ExpressionParser.AllStatementsContext root,
|
||||
Functions functions
|
||||
) {
|
||||
MethodHandle invokable = root.accept(new CompilingVisitor(functions));
|
||||
// catch ReturnExpression and substitute its result
|
||||
invokable = MethodHandles.catchException(
|
||||
invokable,
|
||||
ReturnException.class,
|
||||
ExpressionHandles.RETURN_EXCEPTION_GET_RESULT
|
||||
invokable,
|
||||
ReturnException.class,
|
||||
ExpressionHandles.RETURN_EXCEPTION_GET_RESULT
|
||||
);
|
||||
MethodHandle finalInvokable = invokable;
|
||||
return (CompiledExpression) ExpressionHandles.safeInvoke(
|
||||
HANDLE_TO_CE_CONVERTER, h -> h.invoke(finalInvokable)
|
||||
HANDLE_TO_CE_CONVERTER, h -> h.invoke(finalInvokable)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import it.unimi.dsi.fastutil.doubles.Double2ObjectMaps;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
@ -37,7 +38,6 @@ import java.util.Objects;
|
||||
import java.util.function.DoubleBinaryOperator;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.sk89q.worldedit.internal.expression.ExpressionHelper.check;
|
||||
import static com.sk89q.worldedit.internal.expression.ExpressionHelper.checkIterations;
|
||||
@ -80,38 +80,56 @@ class ExpressionHandles {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
try {
|
||||
EVAL_EXCEPTION_CONSTR = lookup.findConstructor(
|
||||
EvaluationException.class, methodType(void.class, int.class, String.class));
|
||||
EvaluationException.class, methodType(void.class, int.class, String.class));
|
||||
CALL_EXPRESSION = lookup.findVirtual(
|
||||
CompiledExpression.class, "execute",
|
||||
methodType(Double.class, ExecutionData.class));
|
||||
CompiledExpression.class, "execute",
|
||||
methodType(Double.class, ExecutionData.class)
|
||||
);
|
||||
GET_VARIABLE = lookup.findStatic(ExpressionHandles.class, "getVariable",
|
||||
methodType(LocalSlot.Variable.class, ExecutionData.class, Token.class));
|
||||
WHILE_FOR_LOOP_IMPL = lookup.findStatic(ExpressionHandles.class,
|
||||
"whileForLoopImpl",
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class,
|
||||
MethodHandle.class, ExecNode.class, MethodHandle.class));
|
||||
methodType(LocalSlot.Variable.class, ExecutionData.class, Token.class)
|
||||
);
|
||||
WHILE_FOR_LOOP_IMPL = lookup.findStatic(
|
||||
ExpressionHandles.class,
|
||||
"whileForLoopImpl",
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class,
|
||||
MethodHandle.class, ExecNode.class, MethodHandle.class
|
||||
)
|
||||
);
|
||||
DO_WHILE_LOOP_IMPL = lookup.findStatic(ExpressionHandles.class, "doWhileLoopImpl",
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class, ExecNode.class));
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class, ExecNode.class)
|
||||
);
|
||||
SIMPLE_FOR_LOOP_IMPL = lookup.findStatic(ExpressionHandles.class, "simpleForLoopImpl",
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class,
|
||||
MethodHandle.class, Token.class, ExecNode.class));
|
||||
methodType(Double.class, ExecutionData.class, MethodHandle.class,
|
||||
MethodHandle.class, Token.class, ExecNode.class
|
||||
)
|
||||
);
|
||||
SWITCH_IMPL = lookup.findStatic(ExpressionHandles.class, "switchImpl",
|
||||
methodType(Double.class, ExecutionData.class, Double2ObjectMap.class,
|
||||
MethodHandle.class, ExecNode.class));
|
||||
methodType(Double.class, ExecutionData.class, Double2ObjectMap.class,
|
||||
MethodHandle.class, ExecNode.class
|
||||
)
|
||||
);
|
||||
|
||||
IS_NULL = lookup.findStatic(Objects.class, "isNull",
|
||||
methodType(boolean.class, Object.class));
|
||||
methodType(boolean.class, Object.class)
|
||||
);
|
||||
DOUBLE_TO_BOOL = boxDoubles(lookup.findStatic(ExpressionHandles.class, "doubleToBool",
|
||||
methodType(boolean.class, double.class)));
|
||||
methodType(boolean.class, double.class)
|
||||
));
|
||||
CALL_BINARY_OP = lookup.findVirtual(DoubleBinaryOperator.class, "applyAsDouble",
|
||||
methodType(double.class, double.class, double.class))
|
||||
.asType(methodType(Double.class, DoubleBinaryOperator.class, double.class, double.class));
|
||||
NEW_LS_CONSTANT = lookup.findConstructor(LocalSlot.Constant.class,
|
||||
methodType(void.class, double.class));
|
||||
NEW_RETURN_EXCEPTION = lookup.findConstructor(ReturnException.class,
|
||||
methodType(void.class, Double.class));
|
||||
methodType(double.class, double.class, double.class)
|
||||
)
|
||||
.asType(methodType(Double.class, DoubleBinaryOperator.class, double.class, double.class));
|
||||
NEW_LS_CONSTANT = lookup.findConstructor(
|
||||
LocalSlot.Constant.class,
|
||||
methodType(void.class, double.class)
|
||||
);
|
||||
NEW_RETURN_EXCEPTION = lookup.findConstructor(
|
||||
ReturnException.class,
|
||||
methodType(void.class, Double.class)
|
||||
);
|
||||
RETURN_EXCEPTION_GET_RESULT = lookup.findVirtual(ReturnException.class,
|
||||
"getResult", methodType(Double.class));
|
||||
"getResult", methodType(Double.class)
|
||||
);
|
||||
} catch (NoSuchMethodException | IllegalAccessException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -120,9 +138,9 @@ class ExpressionHandles {
|
||||
static MethodHandle boxDoubles(MethodHandle handle) {
|
||||
MethodType type = handle.type();
|
||||
type = methodType(
|
||||
boxIfPrimitiveDouble(type.returnType()),
|
||||
type.parameterList().stream().map(ExpressionHandles::boxIfPrimitiveDouble)
|
||||
.collect(Collectors.toList())
|
||||
boxIfPrimitiveDouble(type.returnType()),
|
||||
type.parameterList().stream().map(ExpressionHandles::boxIfPrimitiveDouble)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
return handle.asType(type);
|
||||
}
|
||||
@ -134,9 +152,9 @@ class ExpressionHandles {
|
||||
static MethodHandle unboxDoubles(MethodHandle handle) {
|
||||
MethodType type = handle.type();
|
||||
type = methodType(
|
||||
unboxIfDouble(type.returnType()),
|
||||
type.parameterList().stream().map(ExpressionHandles::unboxIfDouble)
|
||||
.collect(Collectors.toList())
|
||||
unboxIfDouble(type.returnType()),
|
||||
type.parameterList().stream().map(ExpressionHandles::unboxIfDouble)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
return handle.asType(type);
|
||||
}
|
||||
@ -147,7 +165,9 @@ class ExpressionHandles {
|
||||
|
||||
@FunctionalInterface
|
||||
interface Invokable {
|
||||
|
||||
Object invoke(MethodHandle handle) throws Throwable;
|
||||
|
||||
}
|
||||
|
||||
static Object safeInvoke(MethodHandle handle, Invokable invokable) {
|
||||
@ -173,22 +193,22 @@ class ExpressionHandles {
|
||||
|
||||
static MethodHandle dedupData(MethodHandle doubleData) {
|
||||
return permuteArguments(
|
||||
doubleData, COMPILED_EXPRESSION_SIG,
|
||||
0, 0
|
||||
doubleData, COMPILED_EXPRESSION_SIG,
|
||||
0, 0
|
||||
);
|
||||
}
|
||||
|
||||
static LocalSlot.Variable initVariable(ExecutionData data, Token nameToken) {
|
||||
String name = nameToken.getText();
|
||||
return data.getSlots().initVariable(name)
|
||||
.orElseThrow(() -> ExpressionHelper.evalException(
|
||||
nameToken, "Cannot overwrite non-variable '" + name + "'"
|
||||
));
|
||||
.orElseThrow(() -> ExpressionHelper.evalException(
|
||||
nameToken, "Cannot overwrite non-variable '" + name + "'"
|
||||
));
|
||||
}
|
||||
|
||||
private static Supplier<EvaluationException> varNotInitException(Token nameToken) {
|
||||
return () -> ExpressionHelper.evalException(
|
||||
nameToken, "'" + nameToken.getText() + "' is not initialized yet"
|
||||
nameToken, "'" + nameToken.getText() + "' is not initialized yet"
|
||||
);
|
||||
}
|
||||
|
||||
@ -199,10 +219,10 @@ class ExpressionHandles {
|
||||
static LocalSlot.Variable getVariable(ExecutionData data, Token nameToken) {
|
||||
String name = nameToken.getText();
|
||||
LocalSlot slot = data.getSlots().getSlot(name)
|
||||
.orElseThrow(varNotInitException(nameToken));
|
||||
.orElseThrow(varNotInitException(nameToken));
|
||||
if (!(slot instanceof LocalSlot.Variable)) {
|
||||
throw ExpressionHelper.evalException(
|
||||
nameToken, "'" + name + "' is not a variable"
|
||||
nameToken, "'" + name + "' is not a variable"
|
||||
);
|
||||
}
|
||||
return (LocalSlot.Variable) slot;
|
||||
@ -211,7 +231,7 @@ class ExpressionHandles {
|
||||
static double getSlotValue(ExecutionData data, Token nameToken) {
|
||||
String name = nameToken.getText();
|
||||
return data.getSlots().getSlotValue(name)
|
||||
.orElseThrow(varNotInitException(nameToken));
|
||||
.orElseThrow(varNotInitException(nameToken));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -220,7 +240,8 @@ class ExpressionHandles {
|
||||
*/
|
||||
private static MethodHandle evalException(ParserRuleContext ctx, String message) {
|
||||
return insertArguments(EVAL_EXCEPTION_CONSTR, 0,
|
||||
getErrorPosition(ctx.start), message);
|
||||
getErrorPosition(ctx.start), message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,9 +251,9 @@ class ExpressionHandles {
|
||||
static MethodHandle throwEvalException(ParserRuleContext ctx, String message) {
|
||||
// replace arg0 of `throw` with `evalException`
|
||||
return collectArguments(
|
||||
throwException(Double.class, EvaluationException.class),
|
||||
0,
|
||||
evalException(ctx, message)
|
||||
throwException(Double.class, EvaluationException.class),
|
||||
0,
|
||||
evalException(ctx, message)
|
||||
);
|
||||
}
|
||||
|
||||
@ -253,22 +274,28 @@ class ExpressionHandles {
|
||||
|
||||
static MethodHandle whileLoop(MethodHandle condition, ExecNode body) {
|
||||
return insertArguments(WHILE_FOR_LOOP_IMPL, 1,
|
||||
null, condition, body, null);
|
||||
null, condition, body, null
|
||||
);
|
||||
}
|
||||
|
||||
static MethodHandle forLoop(MethodHandle init,
|
||||
MethodHandle condition,
|
||||
ExecNode body,
|
||||
MethodHandle update) {
|
||||
static MethodHandle forLoop(
|
||||
MethodHandle init,
|
||||
MethodHandle condition,
|
||||
ExecNode body,
|
||||
MethodHandle update
|
||||
) {
|
||||
return insertArguments(WHILE_FOR_LOOP_IMPL, 1,
|
||||
init, condition, body, update);
|
||||
init, condition, body, update
|
||||
);
|
||||
}
|
||||
|
||||
private static Double whileForLoopImpl(ExecutionData data,
|
||||
@Nullable MethodHandle init,
|
||||
MethodHandle condition,
|
||||
ExecNode body,
|
||||
@Nullable MethodHandle update) {
|
||||
private static Double whileForLoopImpl(
|
||||
ExecutionData data,
|
||||
@Nullable MethodHandle init,
|
||||
MethodHandle condition,
|
||||
ExecNode body,
|
||||
@Nullable MethodHandle update
|
||||
) {
|
||||
Double result = null;
|
||||
int iterations = 0;
|
||||
if (init != null) {
|
||||
@ -296,9 +323,11 @@ class ExpressionHandles {
|
||||
return insertArguments(DO_WHILE_LOOP_IMPL, 1, condition, body);
|
||||
}
|
||||
|
||||
private static Double doWhileLoopImpl(ExecutionData data,
|
||||
MethodHandle condition,
|
||||
ExecNode body) {
|
||||
private static Double doWhileLoopImpl(
|
||||
ExecutionData data,
|
||||
MethodHandle condition,
|
||||
ExecNode body
|
||||
) {
|
||||
Double result = null;
|
||||
int iterations = 0;
|
||||
do {
|
||||
@ -316,19 +345,24 @@ class ExpressionHandles {
|
||||
return result;
|
||||
}
|
||||
|
||||
static MethodHandle simpleForLoop(MethodHandle first,
|
||||
MethodHandle last,
|
||||
Token counter,
|
||||
ExecNode body) {
|
||||
static MethodHandle simpleForLoop(
|
||||
MethodHandle first,
|
||||
MethodHandle last,
|
||||
Token counter,
|
||||
ExecNode body
|
||||
) {
|
||||
return insertArguments(SIMPLE_FOR_LOOP_IMPL, 1,
|
||||
first, last, counter, body);
|
||||
first, last, counter, body
|
||||
);
|
||||
}
|
||||
|
||||
private static Double simpleForLoopImpl(ExecutionData data,
|
||||
MethodHandle getFirst,
|
||||
MethodHandle getLast,
|
||||
Token counterToken,
|
||||
ExecNode body) {
|
||||
private static Double simpleForLoopImpl(
|
||||
ExecutionData data,
|
||||
MethodHandle getFirst,
|
||||
MethodHandle getLast,
|
||||
Token counterToken,
|
||||
ExecNode body
|
||||
) {
|
||||
Double result = null;
|
||||
int iterations = 0;
|
||||
double first = (double) standardInvoke(getFirst, data);
|
||||
@ -350,16 +384,20 @@ class ExpressionHandles {
|
||||
return result;
|
||||
}
|
||||
|
||||
static MethodHandle switchStatement(Double2ObjectMap<ExecNode> cases,
|
||||
MethodHandle getValue,
|
||||
@Nullable ExecNode defaultCase) {
|
||||
static MethodHandle switchStatement(
|
||||
Double2ObjectMap<ExecNode> cases,
|
||||
MethodHandle getValue,
|
||||
@Nullable ExecNode defaultCase
|
||||
) {
|
||||
return insertArguments(SWITCH_IMPL, 1, cases, getValue, defaultCase);
|
||||
}
|
||||
|
||||
private static Double switchImpl(ExecutionData data,
|
||||
Double2ObjectMap<ExecNode> cases,
|
||||
MethodHandle getValue,
|
||||
@Nullable ExecNode defaultCase) {
|
||||
private static Double switchImpl(
|
||||
ExecutionData data,
|
||||
Double2ObjectMap<ExecNode> cases,
|
||||
MethodHandle getValue,
|
||||
@Nullable ExecNode defaultCase
|
||||
) {
|
||||
double value = (double) standardInvoke(getValue, data);
|
||||
boolean matched = false;
|
||||
Double evaluated = null;
|
||||
|
@ -38,4 +38,5 @@ public class ReturnException extends RuntimeException {
|
||||
public Double getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -103,10 +103,14 @@ public final class MCDirections {
|
||||
|
||||
public static int fromLegacyHanging(byte i) {
|
||||
switch (i) {
|
||||
case 0: return 2;
|
||||
case 1: return 1;
|
||||
case 2: return 0;
|
||||
default: return 3;
|
||||
case 0:
|
||||
return 2;
|
||||
case 1:
|
||||
return 1;
|
||||
case 2:
|
||||
return 0;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public abstract class AbstractFactory<E> {
|
||||
/**
|
||||
* Create a new factory.
|
||||
*
|
||||
* @param worldEdit the WorldEdit instance
|
||||
* @param worldEdit the WorldEdit instance
|
||||
* @param defaultParser the parser to fall back to
|
||||
*/
|
||||
protected AbstractFactory(WorldEdit worldEdit, InputParser<E> defaultParser) {
|
||||
@ -86,7 +86,7 @@ public abstract class AbstractFactory<E> {
|
||||
|
||||
public List<String> getSuggestions(String input) {
|
||||
return parsers.stream().flatMap(
|
||||
p -> p.getSuggestions(input)
|
||||
p -> p.getSuggestions(input)
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -100,4 +100,5 @@ public abstract class AbstractFactory<E> {
|
||||
|
||||
parsers.add(parsers.size() - 1, inputParser);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -49,4 +49,5 @@ public abstract class InputParser<E> {
|
||||
public Stream<String> getSuggestions(String input) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -78,4 +78,5 @@ public abstract class SimpleInputParser<E> extends InputParser<E> {
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ public class BiomeMath {
|
||||
/**
|
||||
* Compute the index into the MC biome array, for extended-height worlds.
|
||||
*
|
||||
* @param x the block x coordinate
|
||||
* @param y the block y coordinate
|
||||
* @param z the block z coordinate
|
||||
* @param x the block x coordinate
|
||||
* @param y the block y coordinate
|
||||
* @param z the block z coordinate
|
||||
* @param minY minimum y of the world
|
||||
* @param maxY maximum y of the world
|
||||
* @return the index into the standard MC biome array
|
||||
@ -67,4 +67,5 @@ public class BiomeMath {
|
||||
| n << HORIZONTAL_SECTION_COUNT
|
||||
| l;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -48,16 +48,16 @@ public class DeprecationUtil {
|
||||
// find the matching caller method
|
||||
Method callingMethod = getCallingMethod(caller);
|
||||
NonAbstractForCompatibility annotation =
|
||||
callingMethod.getAnnotation(NonAbstractForCompatibility.class);
|
||||
callingMethod.getAnnotation(NonAbstractForCompatibility.class);
|
||||
// get the deprecated method
|
||||
Method deprecatedMethod;
|
||||
try {
|
||||
deprecatedMethod = implementingClass.getMethod(
|
||||
annotation.delegateName(), annotation.delegateParams()
|
||||
annotation.delegateName(), annotation.delegateParams()
|
||||
);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new AssertionError(
|
||||
"Missing method referenced by " + NonAbstractForCompatibility.class, e
|
||||
"Missing method referenced by " + NonAbstractForCompatibility.class, e
|
||||
);
|
||||
}
|
||||
// Check if the deprecated method was overridden. If the declaring class is the caller's
|
||||
@ -67,7 +67,7 @@ public class DeprecationUtil {
|
||||
// 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));
|
||||
+ " must override " + methodToString(callingMethod));
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,22 +80,22 @@ public class DeprecationUtil {
|
||||
}
|
||||
for (Method declaredMethod : declaredMethods) {
|
||||
if (declaredMethod.isAnnotationPresent(NonAbstractForCompatibility.class)
|
||||
&& declaredMethod.getName().equals(callerInfo.getMethodName())) {
|
||||
&& declaredMethod.getName().equals(callerInfo.getMethodName())) {
|
||||
return declaredMethod;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Failed to find caller method "
|
||||
+ callerInfo.getMethodName() + " annotated with " + NonAbstractForCompatibility.class);
|
||||
+ callerInfo.getMethodName() + " annotated with " + NonAbstractForCompatibility.class);
|
||||
}
|
||||
|
||||
private static String methodToString(Method method) {
|
||||
StringBuilder builder = new StringBuilder(method.getDeclaringClass().getCanonicalName())
|
||||
.append('.')
|
||||
.append(method.getName())
|
||||
.append('(');
|
||||
.append('.')
|
||||
.append(method.getName())
|
||||
.append('(');
|
||||
Joiner.on(", ").appendTo(builder, Stream.of(method.getParameterTypes())
|
||||
.map(Class::getSimpleName)
|
||||
.iterator());
|
||||
.map(Class::getSimpleName)
|
||||
.iterator());
|
||||
builder.append(')');
|
||||
return builder.toString();
|
||||
}
|
||||
@ -106,12 +106,12 @@ public class DeprecationUtil {
|
||||
@SuppressWarnings("deprecation")
|
||||
BlockType wallSign = BlockTypes.WALL_SIGN;
|
||||
return blockType == sign || blockType == wallSign
|
||||
|| BlockCategories.SIGNS.contains(blockType);
|
||||
|| BlockCategories.SIGNS.contains(blockType);
|
||||
}
|
||||
|
||||
public static String getHeadOwnerKey() {
|
||||
int dataVersion = WorldEdit.getInstance().getPlatformManager()
|
||||
.queryCapability(Capability.GAME_HOOKS).getDataVersion();
|
||||
.queryCapability(Capability.GAME_HOOKS).getDataVersion();
|
||||
return dataVersion >= Constants.DATA_VERSION_MC_1_16 ? "SkullOwner" : "Owner";
|
||||
}
|
||||
|
||||
|
@ -21,15 +21,15 @@ package com.sk89q.worldedit.internal.util;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditManifest;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.text.html.HTMLDocument;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import java.awt.Desktop;
|
||||
import java.io.IOException;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class InfoEntryPoint {
|
||||
|
||||
@ -68,6 +68,7 @@ public class InfoEntryPoint {
|
||||
}
|
||||
|
||||
private static class NavigableEditorPane extends JTextPane {
|
||||
|
||||
public NavigableEditorPane(String htmlBody) {
|
||||
super(new HTMLDocument());
|
||||
setEditorKit(new HTMLEditorKit());
|
||||
@ -86,5 +87,7 @@ public class InfoEntryPoint {
|
||||
setEditable(false);
|
||||
setBorder(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -41,4 +41,5 @@ public class LogManagerCompat {
|
||||
|
||||
private LogManagerCompat() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ public class RegionOptimizedVectorSorter {
|
||||
long x = elem.getX();
|
||||
long z = elem.getZ();
|
||||
return (((x << (REGION_X_SHIFT - 9)) & REGION_X_MASK) ^ FLIP_REGION_X_SIGN)
|
||||
| (((z << (REGION_Z_SHIFT - 9)) & REGION_Z_MASK) ^ FLIP_REGION_Z_SIGN)
|
||||
| ((x << (CHUNK_X_SHIFT - 4)) & CHUNK_X_MASK)
|
||||
| ((z << (CHUNK_Z_SHIFT - 4)) & CHUNK_Z_MASK)
|
||||
| (Y_MAX - elem.getY());
|
||||
| (((z << (REGION_Z_SHIFT - 9)) & REGION_Z_MASK) ^ FLIP_REGION_Z_SIGN)
|
||||
| ((x << (CHUNK_X_SHIFT - 4)) & CHUNK_X_MASK)
|
||||
| ((z << (CHUNK_Z_SHIFT - 4)) & CHUNK_Z_MASK)
|
||||
| (Y_MAX - elem.getY());
|
||||
}
|
||||
|
||||
private static final int NUMBER_OF_BITS = 64;
|
||||
@ -91,11 +91,11 @@ public class RegionOptimizedVectorSorter {
|
||||
}
|
||||
|
||||
private static final ExecutorService SORT_SVC = Executors.newFixedThreadPool(
|
||||
Runtime.getRuntime().availableProcessors(),
|
||||
new ThreadFactoryBuilder()
|
||||
.setDaemon(true)
|
||||
.setNameFormat("worldedit-sort-svc-%d")
|
||||
.build()
|
||||
Runtime.getRuntime().availableProcessors(),
|
||||
new ThreadFactoryBuilder()
|
||||
.setDaemon(true)
|
||||
.setNameFormat("worldedit-sort-svc-%d")
|
||||
.build()
|
||||
);
|
||||
|
||||
public static void sort(List<BlockVector3> vectors) {
|
||||
@ -110,7 +110,7 @@ public class RegionOptimizedVectorSorter {
|
||||
* </p>
|
||||
*
|
||||
* @param parallel {@code true} to sort in parallel
|
||||
* @param vectors the vectors to sort
|
||||
* @param vectors the vectors to sort
|
||||
*/
|
||||
public static void sort(boolean parallel, List<BlockVector3> vectors) {
|
||||
// Currently we don't do an in-place radix sort, but we could in the future.
|
||||
@ -122,8 +122,8 @@ public class RegionOptimizedVectorSorter {
|
||||
BlockVector3[] source = vectors.toArray(new BlockVector3[0]);
|
||||
BlockVector3[] sorted = new BlockVector3[size];
|
||||
source = !parallel
|
||||
? serialSort(source, size, sorted)
|
||||
: parallelSort(source, size, sorted);
|
||||
? serialSort(source, size, sorted)
|
||||
: parallelSort(source, size, sorted);
|
||||
ListIterator<BlockVector3> it = vectors.listIterator();
|
||||
for (BlockVector3 blockVector3 : source) {
|
||||
it.next();
|
||||
@ -213,4 +213,5 @@ public class RegionOptimizedVectorSorter {
|
||||
|
||||
private RegionOptimizedVectorSorter() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -85,8 +85,8 @@ public final class Substring {
|
||||
}
|
||||
Substring substring1 = (Substring) o;
|
||||
return start == substring1.start
|
||||
&& end == substring1.end
|
||||
&& substring.equals(substring1.substring);
|
||||
&& end == substring1.end
|
||||
&& substring.equals(substring1.substring);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,9 +97,10 @@ public final class Substring {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Substring{"
|
||||
+ "substring='" + substring + "'"
|
||||
+ ",start=" + start
|
||||
+ ",end=" + end
|
||||
+ "}";
|
||||
+ "substring='" + substring + "'"
|
||||
+ ",start=" + start
|
||||
+ ",end=" + end
|
||||
+ "}";
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,13 +38,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* Natively access and perform operations on the world.
|
||||
*
|
||||
* @param <NC> the native chunk type
|
||||
* @param <NC> the native chunk type
|
||||
* @param <NBS> the native block state type
|
||||
* @param <NP> the native position type
|
||||
* @param <NP> the native position type
|
||||
*/
|
||||
public interface WorldNativeAccess<NC, NBS, NP> {
|
||||
|
||||
default <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
|
||||
default <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws
|
||||
WorldEditException {
|
||||
checkNotNull(position);
|
||||
checkNotNull(block);
|
||||
setCurrentSideEffectSet(sideEffects);
|
||||
@ -73,10 +74,10 @@ public interface WorldNativeAccess<NC, NBS, NP> {
|
||||
CompoundBinaryTag tag = baseBlock.getNbt();
|
||||
if (tag != null) {
|
||||
tag = tag.put(ImmutableMap.of(
|
||||
"id", StringBinaryTag.of(baseBlock.getNbtId()),
|
||||
"x", IntBinaryTag.of(position.getX()),
|
||||
"y", IntBinaryTag.of(position.getY()),
|
||||
"z", IntBinaryTag.of(position.getZ())
|
||||
"id", StringBinaryTag.of(baseBlock.getNbtId()),
|
||||
"x", IntBinaryTag.of(position.getX()),
|
||||
"y", IntBinaryTag.of(position.getY()),
|
||||
"z", IntBinaryTag.of(position.getZ())
|
||||
));
|
||||
|
||||
// update if TE changed as well
|
||||
|
Reference in New Issue
Block a user