Fix more upstream incompatibilities (#2767)

* Move more public types to records

(cherry picked from commit 35e58895f5379e78b856e8997a593701c6d9db21)

* chore: pull in PlacementType

* fix: mask reference in NegatedMask

* Use records in expression impl

(cherry picked from commit 453537c5b4783412aa1b4e982d7b72c637d0db8e)

* fix: variable record getter access

* chore: add since to Deprecated annotation

* chore: revert weird merge in ClientProxy

* chore: cleanup remaining deprecations

* chore: code-style

---------

Co-authored-by: Octavia Togami <octavia.togami@gmail.com>
This commit is contained in:
Pierre Maurice Schwang 2024-06-08 10:07:05 +02:00 committed by GitHub
parent c095c492e0
commit ee5d1caa2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 435 additions and 321 deletions

View File

@ -3082,8 +3082,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
) <= 0) { ) <= 0) {
return null; return null;
} }
int newType = (int) typeVariable.getValue(); int newType = (int) typeVariable.value();
int newData = (int) dataVariable.getValue(); int newData = (int) dataVariable.value();
if (newType != typeVar || newData != dataVar) { if (newType != typeVar || newData != dataVar) {
BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(newType, newData); BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(newType, newData);
return state == null ? defaultMaterial : state.toBaseBlock(); return state == null ? defaultMaterial : state.toBaseBlock();
@ -3181,9 +3181,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
// transform // transform
expression.evaluate(new double[]{scaled.x(), scaled.y(), scaled.z()}, timeout); expression.evaluate(new double[]{scaled.x(), scaled.y(), scaled.z()}, timeout);
int xv = (int) Math.floor(x.getValue() * unit.x() + zero2.x()); int xv = (int) Math.floor(x.value() * unit.x() + zero2.x());
int yv = (int) Math.floor(y.getValue() * unit.y() + zero2.y()); int yv = (int) Math.floor(y.value() * unit.y() + zero2.y());
int zv = (int) Math.floor(z.getValue() * unit.z() + zero2.z()); int zv = (int) Math.floor(z.value() * unit.z() + zero2.z());
BlockState get; BlockState get;
if (yv >= minY && yv <= maxY) { if (yv >= minY && yv <= maxY) {

View File

@ -23,27 +23,10 @@ import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
/** /**
* Items of metadata about shared clipboards. * Items of metadata about shared clipboards.
*
* @param format the format of the clipboard
* @param name the name of the clipboard
* @param author the author of the clipboard
*/ */
public class ClipboardShareMetadata { public record ClipboardShareMetadata(ClipboardFormat format, String name, String author) {
private final ClipboardFormat format;
private final String name;
private final String author;
public ClipboardShareMetadata(ClipboardFormat format, String name, String author) {
this.format = format;
this.name = name;
this.author = author;
}
public ClipboardFormat format() {
return this.format;
}
public String name() {
return this.name;
}
public String author() {
return this.author;
}
} }

View File

@ -167,24 +167,14 @@ public class Deform implements Contextual<Operation> {
); );
} }
private static final class DeformOperation implements Operation { private record DeformOperation(
Extent destination,
private final Extent destination; Region region,
private final Region region; Vector3 zero,
private final Vector3 zero; Vector3 unit,
private final Vector3 unit; String expression, //FAWE: Expression -> String
private final String expression; int timeout
private final int timeout; ) implements Operation {
private DeformOperation(Extent destination, Region region, Vector3 zero, Vector3 unit, String expression, int timeout) {
this.destination = destination;
this.region = region;
this.zero = zero;
this.unit = unit;
this.expression = expression;
this.timeout = timeout;
}
@Override @Override
public Operation resume(RunContext run) throws WorldEditException { public Operation resume(RunContext run) throws WorldEditException {
try { try {

View File

@ -87,7 +87,7 @@ public interface Mask {
} else if (this instanceof Masks.AlwaysFalse) { } else if (this instanceof Masks.AlwaysFalse) {
return Masks.ALWAYS_TRUE; return Masks.ALWAYS_TRUE;
} else if (this instanceof Masks.NegatedMask) { } else if (this instanceof Masks.NegatedMask) {
return ((Masks.NegatedMask) this).mask; return ((Masks.NegatedMask) this).mask();
} }
return new InverseMask(this); return new InverseMask(this);
} }

View File

@ -211,15 +211,7 @@ public final class Masks {
} }
//FAWE start - protected > private protected record NegatedMask(Mask mask) implements Mask {
protected static class NegatedMask implements Mask {
//FAWE end
protected final Mask mask;
private NegatedMask(Mask mask) {
this.mask = mask;
}
@Override @Override
public boolean test(BlockVector3 vector) { public boolean test(BlockVector3 vector) {
@ -245,13 +237,7 @@ public final class Masks {
} }
private static class NegatedMask2D implements Mask2D { private record NegatedMask2D(Mask2D mask) implements Mask2D {
private final Mask2D mask;
private NegatedMask2D(Mask2D mask) {
this.mask = mask;
}
@Override @Override
public boolean test(BlockVector2 vector) { public boolean test(BlockVector2 vector) {

View File

@ -33,34 +33,30 @@ import static com.google.common.base.Preconditions.checkNotNull;
* <p>This biome change does not have an {@link Extent} assigned to it because * <p>This biome change does not have an {@link Extent} assigned to it because
* one will be taken from the passed {@link UndoContext}. If the context * one will be taken from the passed {@link UndoContext}. If the context
* does not have an extent (it is null), cryptic errors may occur.</p> * does not have an extent (it is null), cryptic errors may occur.</p>
*/
public class BiomeChange3D implements Change {
private final BlockVector3 position;
private final BiomeType previous;
private final BiomeType current;
/**
* Create a new biome change.
* *
* @param position the position * @param position the position
* @param previous the previous biome * @param previous the previous biome
* @param current the current biome * @param current the current biome
*/ */
public BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType current) { public record BiomeChange3D(BlockVector3 position, BiomeType previous, BiomeType current) implements Change {
/**
* Create a new biome change.
*
*/
public BiomeChange3D {
checkNotNull(position); checkNotNull(position);
checkNotNull(previous); checkNotNull(previous);
checkNotNull(current); checkNotNull(current);
this.position = position;
this.previous = previous;
this.current = current;
} }
/** /**
* Get the position. * Get the position.
* *
* @return the position * @return the position
* @deprecated Use {@link #position()}.
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BlockVector3 getPosition() { public BlockVector3 getPosition() {
return position; return position;
} }
@ -69,7 +65,9 @@ public class BiomeChange3D implements Change {
* Get the previous biome. * Get the previous biome.
* *
* @return the previous biome * @return the previous biome
* @deprecated Use {@link #previous()}.
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BiomeType getPrevious() { public BiomeType getPrevious() {
return previous; return previous;
} }
@ -78,7 +76,9 @@ public class BiomeChange3D implements Change {
* Get the current biome. * Get the current biome.
* *
* @return the current biome * @return the current biome
* @deprecated Use {@link #current()}.
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BiomeType getCurrent() { public BiomeType getCurrent() {
return current; return current;
} }

View File

@ -34,12 +34,21 @@ import static com.google.common.base.Preconditions.checkNotNull;
* <p>This block change does not have an {@link Extent} assigned to it because * <p>This block change does not have an {@link Extent} assigned to it because
* one will be taken from the passed {@link UndoContext}. If the context * one will be taken from the passed {@link UndoContext}. If the context
* does not have an extent (it is null), cryptic errors may occur.</p> * does not have an extent (it is null), cryptic errors may occur.</p>
*
* @param position the position
* @param previous the previous block
* @param current the current block
*/ */
public class BlockChange implements Change { public record BlockChange(BlockVector3 position, BaseBlock previous, BaseBlock current) implements Change {
private final BlockVector3 position; /**
private final BaseBlock previous; * Create a new block change.
private final BaseBlock current; */
public BlockChange {
checkNotNull(position);
checkNotNull(previous);
checkNotNull(current);
}
/** /**
* Create a new block change. * Create a new block change.
@ -53,19 +62,16 @@ public class BlockChange implements Change {
BP previous, BP previous,
BC current BC current
) { ) {
checkNotNull(position); this(position, previous.toBaseBlock(), current.toBaseBlock());
checkNotNull(previous);
checkNotNull(current);
this.position = position;
this.previous = previous.toBaseBlock();
this.current = current.toBaseBlock();
} }
/** /**
* Get the position. * Get the position.
* *
* @return the position * @return the position
* @deprecated use {@link #position()}
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BlockVector3 getPosition() { public BlockVector3 getPosition() {
return position; return position;
} }
@ -74,7 +80,9 @@ public class BlockChange implements Change {
* Get the previous block. * Get the previous block.
* *
* @return the previous block * @return the previous block
* @deprecated use {@link #previous()}
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BaseBlock getPrevious() { public BaseBlock getPrevious() {
return previous; return previous;
} }
@ -83,7 +91,9 @@ public class BlockChange implements Change {
* Get the current block. * Get the current block.
* *
* @return the current block * @return the current block
* @deprecated use {@link #current()}
*/ */
@Deprecated(forRemoval = true, since = "TODO")
public BaseBlock getCurrent() { public BaseBlock getCurrent() {
return current; return current;
} }

View File

@ -87,16 +87,10 @@ public abstract class ExceptionConverterHelper implements ExceptionConverter {
} }
} }
private static class ExceptionHandler implements Comparable<ExceptionHandler> { private record ExceptionHandler(
Class<? extends Throwable> cls,
final Class<? extends Throwable> cls; Method method
final Method method; ) implements Comparable<ExceptionHandler> {
private ExceptionHandler(Class<? extends Throwable> cls, Method method) {
this.cls = cls;
this.method = method;
}
@Override @Override
public int compareTo(ExceptionHandler o) { public int compareTo(ExceptionHandler o) {
if (cls.equals(o.cls)) { if (cls.equals(o.cls)) {

View File

@ -57,13 +57,6 @@ public class InteractionDebouncer {
return Optional.empty(); return Optional.empty();
} }
private static class Interaction { private record Interaction(long tick, boolean result) {
public final long tick;
public final boolean result;
public Interaction(long tick, boolean result) {
this.tick = tick;
this.result = result;
}
} }
} }

View File

@ -23,36 +23,23 @@ import java.time.Instant;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
public class ExecutionData { public record ExecutionData(SlotTable slots, Functions functions, Instant deadline) {
/** /**
* Special execution context for evaluating constant values. As long as no variables are used, * Special execution context for evaluating constant values. As long as no variables are used, it can be considered
* it can be considered constant. * constant.
*/ */
public static final ExecutionData CONSTANT_EVALUATOR = new ExecutionData(null, null, Instant.MAX); public static final ExecutionData CONSTANT_EVALUATOR = new ExecutionData(null, null, Instant.MAX);
private final SlotTable slots; @Override
private final Functions functions; public SlotTable slots() {
private final Instant deadline;
public ExecutionData(SlotTable slots, Functions functions, Instant deadline) {
this.slots = slots;
this.functions = functions;
this.deadline = deadline;
}
public SlotTable getSlots() {
return requireNonNull(slots, "Cannot use variables in a constant"); return requireNonNull(slots, "Cannot use variables in a constant");
} }
public Functions getFunctions() { @Override
public Functions functions() {
return requireNonNull(functions, "Cannot use functions in a constant"); return requireNonNull(functions, "Cannot use functions in a constant");
} }
public Instant getDeadline() {
return deadline;
}
public void checkDeadline() { public void checkDeadline() {
if (Instant.now().isAfter(deadline)) { if (Instant.now().isAfter(deadline)) {
throw new ExpressionTimeoutException("Calculations exceeded time limit."); throw new ExpressionTimeoutException("Calculations exceeded time limit.");

View File

@ -40,6 +40,12 @@ public class ExpressionHelper {
} }
} }
public static void check(boolean condition, int positionInLine, String message) {
if (!condition) {
throw evalException(positionInLine, message);
}
}
public static int getErrorPosition(Token token) { public static int getErrorPosition(Token token) {
return token.getCharPositionInLine(); return token.getCharPositionInLine();
} }
@ -49,14 +55,18 @@ public class ExpressionHelper {
} }
public static EvaluationException evalException(Token token, String message) { public static EvaluationException evalException(Token token, String message) {
return evalException(getErrorPosition(token), message);
}
public static EvaluationException evalException(int positionInLine, String message) {
return new EvaluationException( return new EvaluationException(
getErrorPosition(token), positionInLine,
message message
); );
} }
public static void checkIterations(int iterations, ParserRuleContext ctx) { public static void checkIterations(int iterations, int positionInLine) {
check(iterations <= 256, ctx, "Loop exceeded 256 iterations"); check(iterations <= 256, positionInLine, "Loop exceeded 256 iterations");
} }
public static MethodHandle resolveFunction( public static MethodHandle resolveFunction(

View File

@ -211,8 +211,8 @@ public final class Functions {
final double cosF = Math.cos(angle); final double cosF = Math.cos(angle);
final double sinF = Math.sin(angle); final double sinF = Math.sin(angle);
final double xOld = x.getValue(); final double xOld = x.value();
final double yOld = y.getValue(); final double yOld = y.value();
x.setValue(xOld * cosF - yOld * sinF); x.setValue(xOld * cosF - yOld * sinF);
y.setValue(xOld * sinF + yOld * cosF); y.setValue(xOld * sinF + yOld * cosF);
@ -221,9 +221,9 @@ public final class Functions {
} }
private static double swap(Variable x, Variable y) { private static double swap(Variable x, Variable y) {
final double tmp = x.getValue(); final double tmp = x.value();
x.setValue(y.getValue()); x.setValue(y.value());
y.setValue(tmp); y.setValue(tmp);
return 0.0; return 0.0;
@ -391,8 +391,8 @@ public final class Functions {
private static double queryInternal(LocalSlot type, LocalSlot data, double typeId, double dataValue) { private static double queryInternal(LocalSlot type, LocalSlot data, double typeId, double dataValue) {
// Compare to input values and determine return value // Compare to input values and determine return value
// -1 is a wildcard, always true // -1 is a wildcard, always true
double ret = ((type.getValue() == -1 || typeId == type.getValue()) double ret = ((type.value() == -1 || typeId == type.value())
&& (data.getValue() == -1 || dataValue == data.getValue())) ? 1.0 : 0.0; && (data.value() == -1 || dataValue == data.value())) ? 1.0 : 0.0;
if (type instanceof Variable) { if (type instanceof Variable) {
((Variable) type).setValue(typeId); ((Variable) type).setValue(typeId);

View File

@ -24,19 +24,7 @@ package com.sk89q.worldedit.internal.expression;
*/ */
public interface LocalSlot { public interface LocalSlot {
final class Constant implements LocalSlot { record Constant(double value) implements LocalSlot {
private final double value;
public Constant(double value) {
this.value = value;
}
@Override
public double getValue() {
return value;
}
@Override @Override
public String toString() { public String toString() {
return String.valueOf(value); return String.valueOf(value);
@ -57,7 +45,7 @@ public interface LocalSlot {
} }
@Override @Override
public double getValue() { public double value() {
return value; return value;
} }
@ -65,9 +53,8 @@ public interface LocalSlot {
public String toString() { public String toString() {
return String.valueOf(value); return String.valueOf(value);
} }
} }
double getValue(); double value();
} }

View File

@ -58,7 +58,7 @@ public class SlotTable {
public OptionalDouble getSlotValue(String name) { public OptionalDouble getSlotValue(String name) {
LocalSlot slot = slots.get(name); LocalSlot slot = slots.get(name);
return slot == null ? OptionalDouble.empty() : OptionalDouble.of(slot.getValue()); return slot == null ? OptionalDouble.empty() : OptionalDouble.of(slot.value());
} }
} }

View File

@ -106,7 +106,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
if (ctx.parent instanceof ParserRuleContext) { if (ctx.parent instanceof ParserRuleContext) {
checkHandle(mh, (ParserRuleContext) ctx.parent); checkHandle(mh, (ParserRuleContext) ctx.parent);
} }
return new ExecNode(ctx, mh); return new ExecNode(ctx.start.getCharPositionInLine(), mh);
} }
private void checkHandle(MethodHandle mh, ParserRuleContext ctx) { private void checkHandle(MethodHandle mh, ParserRuleContext ctx) {
@ -127,7 +127,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
MethodHandles.identity(Double.class) MethodHandles.identity(Double.class)
); );
// now pass `result` into `guard` // now pass `result` into `guard`
MethodHandle result = evaluate(ctx).handle; MethodHandle result = evaluate(ctx).handle();
return MethodHandles.collectArguments(guard, 0, result); return MethodHandles.collectArguments(guard, 0, result);
} }
@ -151,8 +151,8 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
// easiest one of the bunch // easiest one of the bunch
return MethodHandles.guardWithTest( return MethodHandles.guardWithTest(
evaluateBoolean(condition), evaluateBoolean(condition),
trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle, trueBranch == null ? NULL_DOUBLE : evaluate(trueBranch).handle(),
falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle falseBranch == null ? NULL_DOUBLE : evaluate(falseBranch).handle()
); );
} }
@ -185,10 +185,10 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
@Override @Override
public MethodHandle visitForStatement(ExpressionParser.ForStatementContext ctx) { public MethodHandle visitForStatement(ExpressionParser.ForStatementContext ctx) {
return ExpressionHandles.forLoop( return ExpressionHandles.forLoop(
evaluate(ctx.init).handle, evaluate(ctx.init).handle(),
evaluateBoolean(ctx.condition), evaluateBoolean(ctx.condition),
evaluate(ctx.body), evaluate(ctx.body),
evaluate(ctx.update).handle evaluate(ctx.update).handle()
); );
} }
@ -235,7 +235,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
RETURN_STATEMENT_BASE, RETURN_STATEMENT_BASE,
0, 0,
// map the Double back to ExecutionData via the returnValue // map the Double back to ExecutionData via the returnValue
evaluate(ctx.value).handle evaluate(ctx.value).handle()
); );
} }
@ -262,7 +262,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
@Override @Override
public MethodHandle visitExpressionStatement(ExpressionParser.ExpressionStatementContext ctx) { public MethodHandle visitExpressionStatement(ExpressionParser.ExpressionStatementContext ctx) {
return evaluate(ctx.expression()).handle; return evaluate(ctx.expression()).handle();
} }
@Override @Override
@ -271,7 +271,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
int opType = ctx.op.getType(); int opType = ctx.op.getType();
return ExpressionHandles.call(data -> { return ExpressionHandles.call(data -> {
LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target); LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target);
double value = variable.getValue(); double value = variable.value();
double result = value; double result = value;
if (opType == INCREMENT) { if (opType == INCREMENT) {
value++; value++;
@ -289,7 +289,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
int opType = ctx.op.getType(); int opType = ctx.op.getType();
return ExpressionHandles.call(data -> { return ExpressionHandles.call(data -> {
LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target); LocalSlot.Variable variable = ExpressionHandles.getVariable(data, target);
double value = variable.getValue(); double value = variable.value();
if (opType == INCREMENT) { if (opType == INCREMENT) {
value++; value++;
} else { } else {
@ -547,7 +547,7 @@ class CompilingVisitor extends ExpressionBaseVisitor<MethodHandle> {
value = arg; value = arg;
} else { } else {
variable = ExpressionHandles.getVariable(data, target); variable = ExpressionHandles.getVariable(data, target);
value = variable.getValue(); value = variable.value();
switch (type) { switch (type) {
case POWER_ASSIGN: case POWER_ASSIGN:
value = Math.pow(value, arg); value = Math.pow(value, arg);

View File

@ -19,18 +19,7 @@
package com.sk89q.worldedit.internal.expression.invoke; package com.sk89q.worldedit.internal.expression.invoke;
import org.antlr.v4.runtime.ParserRuleContext;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
class ExecNode { record ExecNode(int positionInLine, MethodHandle handle) {
final ParserRuleContext ctx;
final MethodHandle handle;
ExecNode(ParserRuleContext ctx, MethodHandle handle) {
this.ctx = ctx;
this.handle = handle;
}
} }

View File

@ -200,7 +200,7 @@ class ExpressionHandles {
static LocalSlot.Variable initVariable(ExecutionData data, Token nameToken) { static LocalSlot.Variable initVariable(ExecutionData data, Token nameToken) {
String name = nameToken.getText(); String name = nameToken.getText();
return data.getSlots().initVariable(name) return data.slots().initVariable(name)
.orElseThrow(() -> ExpressionHelper.evalException( .orElseThrow(() -> ExpressionHelper.evalException(
nameToken, "Cannot overwrite non-variable '" + name + "'" nameToken, "Cannot overwrite non-variable '" + name + "'"
)); ));
@ -218,7 +218,7 @@ class ExpressionHandles {
static LocalSlot.Variable getVariable(ExecutionData data, Token nameToken) { static LocalSlot.Variable getVariable(ExecutionData data, Token nameToken) {
String name = nameToken.getText(); String name = nameToken.getText();
LocalSlot slot = data.getSlots().getSlot(name) LocalSlot slot = data.slots().getSlot(name)
.orElseThrow(varNotInitException(nameToken)); .orElseThrow(varNotInitException(nameToken));
if (!(slot instanceof LocalSlot.Variable)) { if (!(slot instanceof LocalSlot.Variable)) {
throw ExpressionHelper.evalException( throw ExpressionHelper.evalException(
@ -230,7 +230,7 @@ class ExpressionHandles {
static double getSlotValue(ExecutionData data, Token nameToken) { static double getSlotValue(ExecutionData data, Token nameToken) {
String name = nameToken.getText(); String name = nameToken.getText();
return data.getSlots().getSlotValue(name) return data.slots().getSlotValue(name)
.orElseThrow(varNotInitException(nameToken)); .orElseThrow(varNotInitException(nameToken));
} }
@ -302,11 +302,11 @@ class ExpressionHandles {
standardInvoke(init, data); standardInvoke(init, data);
} }
while ((boolean) standardInvoke(condition, data)) { while ((boolean) standardInvoke(condition, data)) {
checkIterations(iterations, body.ctx); checkIterations(iterations, body.positionInLine());
data.checkDeadline(); data.checkDeadline();
iterations++; iterations++;
try { try {
result = (Double) standardInvoke(body.handle, data); result = (Double) standardInvoke(body.handle(), data);
} catch (BreakException ex) { } catch (BreakException ex) {
if (!ex.doContinue) { if (!ex.doContinue) {
break; break;
@ -331,11 +331,11 @@ class ExpressionHandles {
Double result = null; Double result = null;
int iterations = 0; int iterations = 0;
do { do {
checkIterations(iterations, body.ctx); checkIterations(iterations, body.positionInLine());
data.checkDeadline(); data.checkDeadline();
iterations++; iterations++;
try { try {
result = (Double) standardInvoke(body.handle, data); result = (Double) standardInvoke(body.handle(), data);
} catch (BreakException ex) { } catch (BreakException ex) {
if (!ex.doContinue) { if (!ex.doContinue) {
break; break;
@ -369,12 +369,12 @@ class ExpressionHandles {
double last = (double) standardInvoke(getLast, data); double last = (double) standardInvoke(getLast, data);
LocalSlot.Variable variable = initVariable(data, counterToken); LocalSlot.Variable variable = initVariable(data, counterToken);
for (double i = first; i <= last; i++) { for (double i = first; i <= last; i++) {
checkIterations(iterations, body.ctx); checkIterations(iterations, body.positionInLine());
data.checkDeadline(); data.checkDeadline();
iterations++; iterations++;
variable.setValue(i); variable.setValue(i);
try { try {
result = (Double) standardInvoke(body.handle, data); result = (Double) standardInvoke(body.handle(), data);
} catch (BreakException ex) { } catch (BreakException ex) {
if (!ex.doContinue) { if (!ex.doContinue) {
break; break;
@ -406,10 +406,10 @@ class ExpressionHandles {
if (falling || entry.getDoubleKey() == value) { if (falling || entry.getDoubleKey() == value) {
matched = true; matched = true;
try { try {
evaluated = (Double) standardInvoke(entry.getValue().handle, data); evaluated = (Double) standardInvoke(entry.getValue().handle(), data);
falling = true; falling = true;
} catch (BreakException brk) { } catch (BreakException brk) {
check(!brk.doContinue, entry.getValue().ctx, "Cannot continue in a switch"); check(!brk.doContinue, entry.getValue().positionInLine(), "Cannot continue in a switch");
falling = false; falling = false;
break; break;
} }
@ -418,9 +418,9 @@ class ExpressionHandles {
// This if is like the one in the loop, default's "case" is `!matched` & present // This if is like the one in the loop, default's "case" is `!matched` & present
if ((falling || !matched) && defaultCase != null) { if ((falling || !matched) && defaultCase != null) {
try { try {
evaluated = (Double) standardInvoke(defaultCase.handle, data); evaluated = (Double) standardInvoke(defaultCase.handle(), data);
} catch (BreakException brk) { } catch (BreakException brk) {
check(!brk.doContinue, defaultCase.ctx, "Cannot continue in a switch"); check(!brk.doContinue, defaultCase.positionInLine(), "Cannot continue in a switch");
} }
} }
return evaluated; return evaluated;

View File

@ -19,6 +19,9 @@
package com.sk89q.worldedit.registry; package com.sk89q.worldedit.registry;
import com.sk89q.worldedit.internal.util.DeprecationUtil;
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
/** /**
* Represents an objects that can be added to a registry and referenced by an id which is unique within its registry. * Represents an objects that can be added to a registry and referenced by an id which is unique within its registry.
*/ */
@ -28,7 +31,24 @@ public interface Keyed {
* The id of this object in the registry. Must be unique, and lowercase. Certain registries (e.g Namespaced ones) may have additional restrictions. * The id of this object in the registry. Must be unique, and lowercase. Certain registries (e.g Namespaced ones) may have additional restrictions.
* *
* @return an id * @return an id
* @deprecated Use {@link #id()} instead.
*/ */
String getId(); @Deprecated(forRemoval = true, since = "TODO")
default String getId() {
return id();
}
/**
* The id of this object in the registry. Must be unique and lowercase. Certain registries (e.g namespaced ones)
* may have additional restrictions.
*
* @return an id
* @since TODO
*/
@NonAbstractForCompatibility(delegateName = "getId", delegateParams = {})
default String id() {
DeprecationUtil.checkDelegatingOverride(getClass());
return getId();
}
} }

View File

@ -0,0 +1,52 @@
/*
* 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 General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.session;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.RegionSelector;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
//FAWE: not in use (yet)
public record Placement(PlacementType placementType, BlockVector3 offset) {
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return placementType.getPlacementPosition(selector, actor).add(offset);
}
public boolean canBeUsedBy(Actor actor) {
return placementType.canBeUsedBy(actor);
}
public Component getInfo() {
if (offset.equals(BlockVector3.ZERO)) {
return TranslatableComponent.of(placementType.getTranslationKey());
} else {
return TranslatableComponent.of(
placementType.getTranslationKeyWithOffset(),
TextComponent.of(offset.getX()),
TextComponent.of(offset.getY()),
TextComponent.of(offset.getZ())
);
}
}
}

View File

@ -0,0 +1,119 @@
/*
* 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 General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.session;
import com.sk89q.worldedit.IncompleteRegionException;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.RegionSelector;
import static com.google.common.base.Preconditions.checkNotNull;
//FAWE: not in use (yet)
public enum PlacementType {
WORLD("worldedit.toggleplace.world", "worldedit.toggleplace.world-offset") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return BlockVector3.ZERO;
}
},
PLAYER("worldedit.toggleplace.player", "worldedit.toggleplace.player-offset") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
if (!canBeUsedBy(actor)) {
throw new IncompleteRegionException();
}
return ((Locatable) actor).getBlockLocation().toVector().toBlockPoint();
}
@Override
public boolean canBeUsedBy(Actor actor) {
checkNotNull(actor);
return actor instanceof Locatable;
}
},
HERE(null, null) {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead.");
}
@Override
public boolean canBeUsedBy(Actor actor) {
return PLAYER.canBeUsedBy(actor);
}
@Override
public String getTranslationKey() {
throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead.");
}
@Override
public String getTranslationKeyWithOffset() {
throw new IllegalStateException("PlacementType.HERE cannot be used. Use PLAYER or WORLD instead.");
}
},
POS1("worldedit.toggleplace.pos1", "worldedit.toggleplace.pos1-offset") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return selector.getPrimaryPosition();
}
},
MIN("worldedit.toggleplace.min", "worldedit.toggleplace.min-offset") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return selector.getRegion().getMinimumPoint();
}
},
MAX("worldedit.toggleplace.max", "worldedit.toggleplace.max-offset") {
@Override
public BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException {
return selector.getRegion().getMaximumPoint();
}
};
private final String translationKey;
private final String translationKeyWithOffset;
PlacementType(String translationKey, String translationKeyWithOffset) {
this.translationKey = translationKey;
this.translationKeyWithOffset = translationKeyWithOffset;
}
public abstract BlockVector3 getPlacementPosition(RegionSelector selector, Actor actor) throws IncompleteRegionException;
public boolean canBeUsedBy(Actor actor) {
return true;
}
public String getTranslationKey() {
return translationKey;
}
public String getTranslationKeyWithOffset() {
return translationKeyWithOffset;
}
}

View File

@ -22,46 +22,38 @@ package com.sk89q.worldedit.util;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Represents a block located at some position. * Represents a block located at some position.
*/ */
public final class LocatedBlock { public record LocatedBlock(BlockVector3 location, BaseBlock block) {
private final BlockVector3 location; public LocatedBlock {
private final BaseBlock block; checkNotNull(location);
checkNotNull(block);
public LocatedBlock(BlockVector3 location, BaseBlock block) {
this.location = checkNotNull(location);
this.block = checkNotNull(block);
} }
/**
* Gets the location.
*
* @return The location
* @deprecated This class is now a record. Use {@link #location()} instead.
*/
@Deprecated(forRemoval = true, since = "TODO")
public BlockVector3 getLocation() { public BlockVector3 getLocation() {
return location; return this.location;
} }
/**
* Gets the block.
*
* @return The block
* @deprecated This class is now a record. Use {@link #block()} instead.
*/
@Deprecated(forRemoval = true, since = "TODO")
public BaseBlock getBlock() { public BaseBlock getBlock() {
return block; return this.block;
}
@Override
public int hashCode() {
return Objects.hash(location, block);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (this.getClass() != obj.getClass()) {
return false;
}
LocatedBlock lb = (LocatedBlock) obj;
return Objects.equals(location, lb.location) && Objects.equals(block, lb.block);
} }
} }

View File

@ -168,16 +168,7 @@ public class DataReport implements Report {
} }
} }
private static class Line { private record Line(String key, String value) {
private final String key;
private final String value;
public Line(String key, String value) {
this.key = key;
this.value = value;
}
} }
} }

View File

@ -28,21 +28,32 @@ import com.sk89q.worldedit.registry.NamespacedRegistry;
/** /**
* All the types of biomes in the game. * All the types of biomes in the game.
*/ */
//FAWE start - RegistryItem //FAWE start - RegistryItem + not a record (legacyId + internalId need mutability)
public class BiomeType implements RegistryItem, Keyed, BiomePattern { public class BiomeType implements RegistryItem, Keyed, BiomePattern {
//FAWE end //FAWE end
public static final NamespacedRegistry<BiomeType> REGISTRY = new NamespacedRegistry<>("biome type", true); public static final NamespacedRegistry<BiomeType> REGISTRY = new NamespacedRegistry<>("biome type", true);
//FAWE start
private final String id; private final String id;
private int legacyId = -1; private int legacyId = -1;
private int internalId; private int internalId;
//FAWE start
public BiomeType(String id) { public BiomeType(String id) {
this.id = id; this.id = id;
} }
/**
* Gets the ID of this biome.
*
* @return The id
* @since TODO
*/
@Override
public String id() {
return this.id;
}
public int getLegacyId() { public int getLegacyId() {
return legacyId; return legacyId;
} }
@ -60,13 +71,14 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern {
public int getInternalId() { public int getInternalId() {
return internalId; return internalId;
} }
//FAWE end
/** /**
* Gets the ID of this biome. * Gets the ID of this biome.
* *
* @return The id * @return The id
* @deprecated use {@link #id()}
*/ */
@Deprecated(forRemoval = true, since = "TODO")
@Override @Override
public String getId() { public String getId() {
return this.id; return this.id;
@ -74,20 +86,19 @@ public class BiomeType implements RegistryItem, Keyed, BiomePattern {
@Override @Override
public String toString() { public String toString() {
return getId(); return id();
} }
@Override @Override
public int hashCode() { public int hashCode() {
//FAWE start - internalId > hashCode return this.internalId; // stop changing this (ok)
return this.internalId; // stop changing this
//FAWE end
} }
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj instanceof BiomeType && this.id.equals(((BiomeType) obj).id); return obj instanceof BiomeType && this.id.equals(((BiomeType) obj).id);
} }
//FAWE end
@Override @Override
public BiomeType applyBiome(BlockVector3 position) { public BiomeType applyBiome(BlockVector3 position) {

View File

@ -23,13 +23,15 @@ import com.fastasyncworldedit.core.registry.RegistryItem;
import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.NamespacedRegistry; import com.sk89q.worldedit.registry.NamespacedRegistry;
//FAWE start - implements RegistryItem //FAWE start - implements RegistryItem, not a record (internalId needs mutability)
public class EntityType implements RegistryItem, Keyed { public class EntityType implements RegistryItem, Keyed {
//FAWE end //FAWE end
public static final NamespacedRegistry<EntityType> REGISTRY = new NamespacedRegistry<>("entity type", true); public static final NamespacedRegistry<EntityType> REGISTRY = new NamespacedRegistry<>("entity type", true);
//FAWE start
private final String id; private final String id;
private int internalId;
public EntityType(String id) { public EntityType(String id) {
// If it has no namespace, assume minecraft. // If it has no namespace, assume minecraft.
@ -39,14 +41,28 @@ public class EntityType implements RegistryItem, Keyed {
this.id = id; this.id = id;
} }
/**
* Gets the id of this entity type.
*
* @return the id
* @since TODO
*/
public String id() {
return this.id;
}
/**
* Gets the id of this entity type.
*
* @return the id
* @deprecated use {@link #id()}
*/
@Deprecated(forRemoval = true, since = "TODO")
@Override @Override
public String getId() { public String getId() {
return this.id; return this.id;
} }
//FAWE start
private int internalId;
@Override @Override
public void setInternalId(int internalId) { public void setInternalId(int internalId) {
this.internalId = internalId; this.internalId = internalId;
@ -64,14 +80,15 @@ public class EntityType implements RegistryItem, Keyed {
* @return The name, or ID * @return The name, or ID
*/ */
public String getName() { public String getName() {
return getId(); return id();
} }
@Override @Override
public String toString() { public String toString() {
return getId(); return id();
} }
//FAWE start
@Override @Override
public int hashCode() { public int hashCode() {
return this.id.hashCode(); return this.id.hashCode();
@ -81,5 +98,6 @@ public class EntityType implements RegistryItem, Keyed {
public boolean equals(Object obj) { public boolean equals(Object obj) {
return obj instanceof EntityType && this.id.equals(((EntityType) obj).id); return obj instanceof EntityType && this.id.equals(((EntityType) obj).id);
} }
//FAWE end
} }

View File

@ -24,15 +24,15 @@ import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.NamespacedRegistry; import com.sk89q.worldedit.registry.NamespacedRegistry;
/** /**
* Minecraft now has a 'fluid' system. This is a * Minecraft now has a 'fluid' system. This is a stub class to represent what it may be in the future.
* stub class to represent what it may be in the future.
*/ */
//FAWE start - implements RegistryItem //FAWE start - implements RegistryItem, not a record (internalId needs mutability)
public class FluidType implements RegistryItem, Keyed { public class FluidType implements RegistryItem, Keyed {
//FAWE end //FAWE end
public static final NamespacedRegistry<FluidType> REGISTRY = new NamespacedRegistry<>("fluid type"); public static final NamespacedRegistry<FluidType> REGISTRY = new NamespacedRegistry<>("fluid type");
//FAWE start
private final String id; private final String id;
public FluidType(String id) { public FluidType(String id) {
@ -43,7 +43,19 @@ public class FluidType implements RegistryItem, Keyed {
* Gets the ID of this block. * Gets the ID of this block.
* *
* @return The id * @return The id
* @since TODO
*/ */
public String id() {
return this.id;
}
/**
* Gets the ID of this block.
*
* @return The id
* @deprecated use {@link #id()}
*/
@Deprecated(forRemoval = true, since = "TODO")
@Override @Override
public String getId() { public String getId() {
return this.id; return this.id;
@ -67,7 +79,7 @@ public class FluidType implements RegistryItem, Keyed {
@Override @Override
public String toString() { public String toString() {
return getId(); return id();
} }
@Override @Override

View File

@ -22,43 +22,21 @@ package com.sk89q.worldedit.world.gamemode;
import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.Registry; import com.sk89q.worldedit.registry.Registry;
public class GameMode implements Keyed { public record GameMode(String id) implements Keyed {
public static final Registry<GameMode> REGISTRY = new Registry<>("game mode"); public static final Registry<GameMode> REGISTRY = new Registry<>("game mode");
private final String id;
public GameMode(String id) {
this.id = id;
}
@Override
public String getId() {
return this.id;
}
/** /**
* Gets the name of this game mode, or the ID if the name cannot be found. * Gets the name of this game mode, or the ID if the name cannot be found.
* *
* @return The name, or ID * @return The name, or ID
*/ */
public String getName() { public String getName() {
return getId(); return id();
} }
@Override @Override
public String toString() { public String toString() {
return getId(); return id();
} }
@Override
public int hashCode() {
return this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
return obj instanceof GameMode && this.id.equals(((GameMode) obj).id);
}
} }

View File

@ -19,20 +19,53 @@
package com.sk89q.worldedit.world.registry; package com.sk89q.worldedit.world.registry;
import com.sk89q.worldedit.internal.util.DeprecationUtil;
import com.sk89q.worldedit.internal.util.NonAbstractForCompatibility;
public interface ItemMaterial { public interface ItemMaterial {
/**
* Gets the the maximum quantity of this item that can be in a single stack.
*
* @return the maximum quantity
* @deprecated Use {@link #maxStackSize()} instead.
*/
@Deprecated(forRemoval = true, since = "TODO")
default int getMaxStackSize() {
return maxStackSize();
}
/** /**
* Gets the the maximum quantity of this item that can be in a single stack. * Gets the the maximum quantity of this item that can be in a single stack.
* *
* @return the maximum quantity * @return the maximum quantity
* @since TODO
*/ */
int getMaxStackSize(); @NonAbstractForCompatibility(delegateName = "getMaxStackSize", delegateParams = {})
default int maxStackSize() {
DeprecationUtil.checkDelegatingOverride(getClass());
return getMaxStackSize();
}
/** /**
* Gets the the maximum damage this item can take before being broken. * Gets the the maximum damage this item can take before being broken.
* *
* @return the maximum damage, or 0 if not applicable * @return the maximum damage, or 0 if not applicable
* @deprecated Use {@link #maxDamage()} instead.
*/ */
int getMaxDamage(); @Deprecated(forRemoval = true, since = "TODO")
default int getMaxDamage() {
return maxDamage();
}
/**
* Gets the the maximum damage this item can take before being broken.
*
* @return the maximum damage, or 0 if not applicable
* @since TODO
*/
@NonAbstractForCompatibility(delegateName = "getMaxDamage", delegateParams = {})
default int maxDamage() {
DeprecationUtil.checkDelegatingOverride(getClass());
return getMaxDamage();
}
} }

View File

@ -34,13 +34,13 @@ public class PassthroughItemMaterial implements ItemMaterial {
} }
@Override @Override
public int getMaxStackSize() { public int maxStackSize() {
return itemMaterial.getMaxStackSize(); return itemMaterial.maxStackSize();
} }
@Override @Override
public int getMaxDamage() { public int maxDamage() {
return itemMaterial.getMaxDamage(); return itemMaterial.maxDamage();
} }
} }

View File

@ -19,24 +19,6 @@
package com.sk89q.worldedit.world.registry; package com.sk89q.worldedit.world.registry;
public class SimpleItemMaterial implements ItemMaterial { public record SimpleItemMaterial(int maxStackSize, int maxDamage) implements ItemMaterial {
private final int maxStackSize;
private final int maxDamage;
public SimpleItemMaterial(int maxStackSize, int maxDamage) {
this.maxStackSize = maxStackSize;
this.maxDamage = maxDamage;
}
@Override
public int getMaxStackSize() {
return maxStackSize;
}
@Override
public int getMaxDamage() {
return maxDamage;
}
} }

View File

@ -22,43 +22,20 @@ package com.sk89q.worldedit.world.weather;
import com.sk89q.worldedit.registry.Keyed; import com.sk89q.worldedit.registry.Keyed;
import com.sk89q.worldedit.registry.Registry; import com.sk89q.worldedit.registry.Registry;
public class WeatherType implements Keyed { public record WeatherType(String id) implements Keyed {
public static final Registry<WeatherType> REGISTRY = new Registry<>("weather type"); public static final Registry<WeatherType> REGISTRY = new Registry<>("weather type");
private final String id;
public WeatherType(String id) {
this.id = id;
}
@Override
public String getId() {
return this.id;
}
/** /**
* Gets the name of this weather, or the ID if the name cannot be found. * Gets the name of this weather, or the ID if the name cannot be found.
* *
* @return The name, or ID * @return The name, or ID
*/ */
public String getName() { public String getName() {
return getId(); return id();
} }
@Override @Override
public String toString() { public String toString() {
return getId(); return id();
} }
@Override
public int hashCode() {
return this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
return obj instanceof WeatherType && this.id.equals(((WeatherType) obj).id);
}
} }