1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-04-07 19:26:42 +00:00

Merge branch 'mc-1.21.x' into mc-1.21.y

This commit is contained in:
Jonathan Coates 2025-03-25 08:45:03 +00:00
commit a939ad8b97
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
36 changed files with 612 additions and 615 deletions

View File

@ -27,7 +27,7 @@ indent_size = 2
[*.yml]
indent_size = 2
[{*.kt,*.kts}]
[*.{kt,kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_continuation_indent_size = 4
ij_kotlin_spaces_around_equality_operators = true
@ -39,3 +39,14 @@ ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_method_parameters_wrap = off
ij_kotlin_call_parameters_wrap = off
ij_kotlin_extends_list_wrap = off
ktlint_code_style = intellij_idea
ktlint_standard_class-naming = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_function-naming = disabled
ktlint_standard_no-wildcard-imports = disabled
# FIXME: These two are disable right now as they're over-eager in putting things
# on the same line. We should set max_line_length and handle this properly.
ktlint_standard_function-signature = disabled
ktlint_standard_function-expression-body = disabled

View File

@ -6,7 +6,6 @@
import cc.tweaked.gradle.CCTweakedExtension
import cc.tweaked.gradle.CCTweakedPlugin
import cc.tweaked.gradle.IdeaRunConfigurations
import cc.tweaked.gradle.MinecraftConfigurations
plugins {

View File

@ -29,7 +29,7 @@ base.archivesName.convention("cc-tweaked-$mcVersion-${project.name}")
java {
toolchain {
languageVersion= CCTweakedPlugin.JAVA_VERSION
languageVersion = CCTweakedPlugin.JAVA_VERSION
}
withSourcesJar()
@ -93,6 +93,7 @@ sourceSets.all {
check("InvalidBlockTag", CheckSeverity.OFF) // Broken by @cc.xyz
check("InlineMeSuggester", CheckSeverity.OFF) // Minecraft uses @Deprecated liberally
// Too many false positives right now. Maybe we need an indirection for it later on.
check("AssignmentExpression", CheckSeverity.OFF) // I'm a bad person.
check("ReferenceEquality", CheckSeverity.OFF)
check("EnumOrdinal", CheckSeverity.OFF) // For now. We could replace most of these with EnumMap.
check("OperatorPrecedence", CheckSeverity.OFF) // For now.
@ -121,7 +122,6 @@ tasks.compileTestJava {
}
}
tasks.withType(JavaCompile::class.java).configureEach {
options.encoding = "UTF-8"
}
@ -170,7 +170,7 @@ tasks.test {
tasks.withType(JacocoReport::class.java).configureEach {
reports.xml.required = true
reports.html.required =true
reports.html.required = true
}
project.plugins.withType(CCTweakedPlugin::class.java) {
@ -194,30 +194,23 @@ spotless {
fun FormatExtension.defaults() {
endWithNewline()
trimTrailingWhitespace()
indentWithSpaces(4)
leadingTabsToSpaces(4)
}
java {
defaults()
importOrder("", "javax|java", "\\#")
removeUnusedImports()
}
val ktlintConfig = mapOf(
"ktlint_standard_no-wildcard-imports" to "disabled",
"ktlint_standard_class-naming" to "disabled",
"ktlint_standard_function-naming" to "disabled",
"ij_kotlin_allow_trailing_comma" to "true",
"ij_kotlin_allow_trailing_comma_on_call_site" to "true",
)
kotlinGradle {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
ktlint()
}
kotlin {
defaults()
ktlint().editorConfigOverride(ktlintConfig)
ktlint()
}
}

View File

@ -5,10 +5,8 @@
package cc.tweaked.gradle
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.AbstractExecTask
import org.gradle.api.tasks.OutputDirectory
import java.io.File
abstract class ExecToDir : AbstractExecTask<ExecToDir>(ExecToDir::class.java) {
@get:OutputDirectory

View File

@ -25,7 +25,6 @@ import javax.xml.xpath.XPathFactory
* Would be good to PR some (or all) of these changes upstream at some point.
*
* @see net.fabricmc.loom.configuration.ide.idea.IdeaSyncTask
* @see net.minecraftforge.gradle.common.util.runs.IntellijRunGenerator
*/
internal class IdeaRunConfigurations(project: Project) {
private val rootProject = project.rootProject
@ -35,22 +34,6 @@ internal class IdeaRunConfigurations(project: Project) {
private val writer = TransformerFactory.newInstance().newTransformer()
private val ideaDir = rootProject.file(".idea/")
private val buildDir: Lazy<String?> = lazy {
val ideaMisc = ideaDir.resolve("misc.xml")
try {
val doc = Files.newBufferedReader(ideaMisc.toPath()).use {
documentBuilder.parse(InputSource(it))
}
val node =
xpath.evaluate("//component[@name=\"ProjectRootManager\"]/output", doc, XPathConstants.NODE) as Node
val attr = node.attributes.getNamedItem("url") as Attr
attr.value.removePrefix("file://")
} catch (e: Exception) {
LOGGER.error("Failed to find root directory", e)
null
}
}
fun patch() = synchronized(LOCK) {
val runConfigDir = ideaDir.resolve("runConfigurations")
@ -58,10 +41,9 @@ internal class IdeaRunConfigurations(project: Project) {
Files.list(runConfigDir.toPath()).use {
for (configuration in it) {
val filename = configuration.fileName.toString();
val filename = configuration.fileName.toString()
when {
filename.endsWith("_fabric.xml") -> patchFabric(configuration)
filename.startsWith("forge_") && filename.endsWith(".xml") -> patchForge(configuration)
else -> {}
}
}
@ -72,65 +54,6 @@ internal class IdeaRunConfigurations(project: Project) {
setXml("//configuration", "folderName") { "Fabric" }
}
private fun patchForge(path: Path) = withXml(path) {
val configId = path.fileName.toString().removePrefix("forge_").removeSuffix(".xml")
val sourceSet = forgeConfigs[configId]
if (sourceSet == null) {
LOGGER.error("[{}] Cannot map run configuration to a known source set", path)
return@withXml
}
setXml("//configuration", "folderName") { "Forge" }
setXml("//configuration/module", "name") { "${rootProject.name}.forge.$sourceSet" }
if (buildDir.value == null) return@withXml
setXml("//configuration/envs/env[@name=\"MOD_CLASSES\"]", "value") { classpath ->
val classes = classpath!!.split(':')
val newClasses = mutableListOf<String>()
fun appendUnique(x: String) {
if (!newClasses.contains(x)) newClasses.add(x)
}
for (entry in classes) {
if (!entry.contains("/out/")) {
appendUnique(entry)
continue
}
val match = CLASSPATH_ENTRY.matchEntire(entry)
if (match != null) {
val modId = match.groups["modId"]!!.value
val proj = match.groups["proj"]!!.value
var component = match.groups["component"]!!.value
if (component == "production") component = "main"
appendUnique(forgeModEntry(modId, proj, component))
} else {
LOGGER.warn("[{}] Unknown classpath entry {}", path, entry)
appendUnique(entry)
}
}
// Ensure common code is on the classpath
for (proj in listOf("common", "common-api")) {
for (component in listOf("main", "client")) {
appendUnique(forgeModEntry("computercraft", proj, component))
}
}
if (newClasses.any { it.startsWith("cctest%%") }) {
appendUnique(forgeModEntry("cctest", "core", "testFixtures"))
appendUnique(forgeModEntry("cctest", "common", "testFixtures"))
appendUnique(forgeModEntry("cctest", "common", "testMod"))
}
newClasses.joinToString(":")
}
}
private fun forgeModEntry(mod: String, project: String, component: String) =
"$mod%%${buildDir.value}/production/${rootProject.name}.$project.$component"
private fun LocatedDocument.setXml(xpath: String, attribute: String, value: (String?) -> String) {
val node = this@IdeaRunConfigurations.xpath.evaluate(xpath, document, XPathConstants.NODE) as Node?
if (node == null) {
@ -159,16 +82,5 @@ internal class IdeaRunConfigurations(project: Project) {
companion object {
private val LOGGER = Logging.getLogger(IdeaRunConfigurations::class.java)
private val LOCK = Any()
private val CLASSPATH_ENTRY =
Regex("(?<modId>[a-z]+)%%\\\$PROJECT_DIR\\\$/projects/(?<proj>[a-z-]+)/out/(?<component>\\w+)/(?<type>[a-z]+)\$")
private val forgeConfigs = mapOf(
"runClient" to "client",
"runData" to "main",
"runGameTestServer" to "testMod",
"runServer" to "main",
"runTestClient" to "testMod",
)
}
}

View File

@ -10,7 +10,7 @@
fabric-api = "0.118.0+1.21.4"
fabric-loader = "0.16.10"
neoForge = "21.4.101-beta"
neoForgeSpi = "8.0.1"
neoMergeTool = "2.0.0"
mixin = "0.8.5"
parchment = "2024.12.07"
parchmentMc = "1.21.4"
@ -59,20 +59,20 @@ jmh = "1.37"
# Build tools
cctJavadoc = "1.8.4"
checkstyle = "10.21.2"
errorProne-core = "2.36.0"
checkstyle = "10.21.4"
errorProne-core = "2.37.0"
errorProne-plugin = "4.1.0"
fabric-loom = "1.10.3"
fabric-loom = "1.10.4"
githubRelease = "2.5.2"
gradleVersions = "0.50.0"
ideaExt = "1.1.7"
illuaminate = "0.1.0-74-gf1551d5"
illuaminate = "0.1.0-83-g1131f68"
lwjgl = "3.3.3"
minotaur = "2.8.7"
modDevGradle = "2.0.74"
nullAway = "0.12.3"
modDevGradle = "2.0.78"
nullAway = "0.12.4"
shadow = "8.3.1"
spotless = "6.23.3"
spotless = "7.0.2"
taskTree = "2.1.1"
teavm = "0.11.0-SQUID.1"
vanillaExtract = "0.2.1"
@ -87,7 +87,7 @@ checkerFramework = { module = "org.checkerframework:checker-qual", version.ref =
cobalt = { module = "cc.tweaked:cobalt", version.ref = "cobalt" }
commonsCli = { module = "commons-cli:commons-cli", version.ref = "commonsCli" }
fastutil = { module = "it.unimi.dsi:fastutil", version.ref = "fastutil" }
neoForgeSpi = { module = "net.neoforged:neoforgespi", version.ref = "neoForgeSpi" }
neoMergeTool = { module = "net.neoforged:mergetool", version.ref = "neoMergeTool" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
jetbrainsAnnotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" }
jspecify = { module = "org.jspecify:jspecify", version.ref = "jspecify" }

919
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
"tslib": "^2.0.3"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-node-resolve": "^16.0.0",
"@rollup/plugin-typescript": "^12.0.0",
"@rollup/plugin-url": "^8.0.1",
"@swc/core": "^1.3.92",

View File

@ -28,6 +28,20 @@ public class ComputerCraftTags {
public static final TagKey<Item> WIRED_MODEM = make("wired_modem");
public static final TagKey<Item> MONITOR = make("monitor");
/**
* Floppy disks. Both the read/write version, and treasure disks.
*
* @since 1.116.0
*/
public static final TagKey<Item> DISKS = make("disks");
/**
* All pocket computers.
*
* @since 1.116.0
*/
public static final TagKey<Item> POCKET_COMPUTERS = make("pocket_computers");
/**
* Items which can be {@linkplain Item#use(Level, Player, InteractionHand) used} when calling
* {@code turtle.place()}.

View File

@ -108,6 +108,8 @@ public final class LanguageProvider implements DataProvider {
add(ComputerCraftTags.Items.TURTLE, "Turtles");
add(ComputerCraftTags.Items.WIRED_MODEM, "Wired modems");
add(ComputerCraftTags.Items.MONITOR, "Monitors");
add(ComputerCraftTags.Items.DISKS, "Disks");
add(ComputerCraftTags.Items.POCKET_COMPUTERS, "Pocket Computers");
add(ComputerCraftTags.Items.DYEABLE, "Dyable items");
add(ComputerCraftTags.Items.TURTLE_CAN_PLACE, "Turtle-placeable items");

View File

@ -96,6 +96,8 @@ class TagProvider {
tags.copy(ComputerCraftTags.Blocks.TURTLE, ComputerCraftTags.Items.TURTLE);
tags.tag(ComputerCraftTags.Items.WIRED_MODEM).add(ModRegistry.Items.WIRED_MODEM.get(), ModRegistry.Items.WIRED_MODEM_FULL.get());
tags.copy(ComputerCraftTags.Blocks.MONITOR, ComputerCraftTags.Items.MONITOR);
tags.tag(ComputerCraftTags.Items.DISKS).add(ModRegistry.Items.DISK.get(), ModRegistry.Items.TREASURE_DISK.get());
tags.tag(ComputerCraftTags.Items.POCKET_COMPUTERS).add(ModRegistry.Items.POCKET_COMPUTER_NORMAL.get(), ModRegistry.Items.POCKET_COMPUTER_ADVANCED.get());
tags.tag(ComputerCraftTags.Items.DYEABLE)
.addTag(ComputerCraftTags.Items.TURTLE)

View File

@ -203,8 +203,10 @@
"item.computercraft.treasure_disk": "Floppy Disk",
"itemGroup.computercraft": "ComputerCraft",
"tag.item.computercraft.computer": "Computers",
"tag.item.computercraft.disks": "Disks",
"tag.item.computercraft.dyeable": "Dyable items",
"tag.item.computercraft.monitor": "Monitors",
"tag.item.computercraft.pocket_computers": "Pocket Computers",
"tag.item.computercraft.turtle": "Turtles",
"tag.item.computercraft.turtle_can_place": "Turtle-placeable items",
"tag.item.computercraft.wired_modem": "Wired modems",

View File

@ -0,0 +1 @@
{"values": ["computercraft:disk", "computercraft:treasure_disk"]}

View File

@ -0,0 +1 @@
{"values": ["computercraft:pocket_computer_normal", "computercraft:pocket_computer_advanced"]}

View File

@ -432,8 +432,8 @@ final class WiredNetworkImpl {
}
private static WiredNodeImpl checkNode(WiredNode node) {
if (node instanceof WiredNodeImpl) {
return (WiredNodeImpl) node;
if (node instanceof WiredNodeImpl n) {
return n;
} else {
throw new IllegalArgumentException("Unknown implementation of IWiredNode: " + node);
}

View File

@ -66,8 +66,8 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
public LiteralArgumentBuilder<CommandSourceStack> then(final ArgumentBuilder<CommandSourceStack, ?> argument) {
if (getRedirect() != null) throw new IllegalStateException("Cannot add children to a redirected node");
if (argument instanceof HelpingArgumentBuilder) {
children.add((HelpingArgumentBuilder) argument);
if (argument instanceof HelpingArgumentBuilder child) {
children.add(child);
} else if (argument instanceof LiteralArgumentBuilder) {
super.then(argument);
} else {

View File

@ -39,7 +39,7 @@ public class WirelessModemBlockEntity extends BlockEntity {
@Override
public boolean equals(@Nullable IPeripheral other) {
return this == other || (other instanceof Peripheral && entity == ((Peripheral) other).entity);
return this == other || (other instanceof Peripheral o && entity == o.entity);
}
@Override

View File

@ -40,7 +40,6 @@ import org.jspecify.annotations.Nullable;
* monitor.setCursorPos(1, 1)
* monitor.write("Hello, world!")
* }</pre>
*
* @cc.see monitor_resize Queued when a monitor is resized.
* @cc.see monitor_touch Queued when an advanced monitor is clicked.
*/
@ -95,7 +94,7 @@ public class MonitorPeripheral extends TermMethods implements IPeripheral {
@Override
public boolean equals(@Nullable IPeripheral other) {
return other instanceof MonitorPeripheral && monitor == ((MonitorPeripheral) other).monitor;
return other instanceof MonitorPeripheral o && monitor == o.monitor;
}
private ServerMonitor getMonitor() throws LuaException {

View File

@ -58,11 +58,10 @@ public final class MonitorWatcher {
if (monitor == null) continue;
var pos = tile.getBlockPos();
var world = tile.getLevel();
if (!(world instanceof ServerLevel)) continue;
if (!(tile.getLevel() instanceof ServerLevel level)) continue;
var chunk = world.getChunkAt(pos);
if (((ServerLevel) world).getChunkSource().chunkMap.getPlayers(chunk.getPos(), false).isEmpty()) {
var chunk = level.getChunkAt(pos);
if (level.getChunkSource().chunkMap.getPlayers(chunk.getPos(), false).isEmpty()) {
continue;
}

View File

@ -53,7 +53,7 @@ public class SpeakerBlockEntity extends BlockEntity {
@Override
public boolean equals(@Nullable IPeripheral other) {
return this == other || (other instanceof Peripheral && speaker == ((Peripheral) other).speaker);
return this == other || (other instanceof Peripheral o && speaker == o.speaker);
}
}
}

View File

@ -41,11 +41,12 @@ public final class PocketBrain implements IPocketAccess {
private int colour = -1;
private int lightColour = -1;
public PocketBrain(PocketHolder holder, @Nullable UpgradeData<IPocketUpgrade> upgrade, ServerComputer.Properties properties) {
public PocketBrain(PocketHolder holder, @Nullable UpgradeData<IPocketUpgrade> upgrade, int colour, ServerComputer.Properties properties) {
this.computer = new PocketServerComputer(this, holder, properties);
this.holder = holder;
this.position = holder.pos();
this.upgrade = upgrade;
this.colour = colour;
invalidatePeripheral();
}

View File

@ -35,6 +35,7 @@ import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.DyedItemColor;
import net.minecraft.world.level.Level;
import org.jspecify.annotations.Nullable;
@ -201,7 +202,7 @@ public class PocketComputerItem extends Item {
var computerID = NonNegativeId.getOrCreate(level.getServer(), stack, ModRegistry.DataComponents.COMPUTER_ID.get(), IDAssigner.COMPUTER);
var brain = new PocketBrain(
holder, getUpgradeWithData(stack),
holder, getUpgradeWithData(stack), DyedItemColor.getOrDefault(stack, -1),
ServerComputer.properties(computerID, getFamily())
.label(getLabel(stack))
.storageCapacity(StorageCapacity.getOrDefault(stack.get(ModRegistry.DataComponents.STORAGE_CAPACITY.get()), -1))
@ -240,10 +241,14 @@ public class PocketComputerItem extends Item {
// item. However, if we've just crafted the computer with an upgrade, we should sync the other way, and update
// the computer.
var server = level.getServer();
if (server != null) {
var computer = getServerComputer(server, stack);
if (computer != null) computer.getBrain().setUpgrade(getUpgradeWithData(stack));
}
if (server == null) return;
var computer = getServerComputer(server, stack);
if (computer == null) return;
var brain = computer.getBrain();
brain.setUpgrade(getUpgradeWithData(stack));
brain.setColour(DyedItemColor.getOrDefault(stack, -1));
}
public ComputerFamily getFamily() {

View File

@ -26,8 +26,7 @@ public class PocketSpeaker extends AbstractPocketUpgrade {
@Override
public void update(IPocketAccess access, @Nullable IPeripheral peripheral) {
if (!(peripheral instanceof PocketSpeakerPeripheral)) return;
((PocketSpeakerPeripheral) peripheral).update();
if (peripheral instanceof PocketSpeakerPeripheral speaker) speaker.update();
}
@Override

View File

@ -62,14 +62,13 @@ public class TurtleDropCommand implements TurtleCommand {
}
}
switch (transferred) {
case ContainerTransfer.NO_SPACE:
return TurtleCommandResult.failure("No space for items");
case ContainerTransfer.NO_ITEMS:
return TurtleCommandResult.failure("No items to drop");
default:
return switch (transferred) {
case ContainerTransfer.NO_SPACE -> TurtleCommandResult.failure("No space for items");
case ContainerTransfer.NO_ITEMS -> TurtleCommandResult.failure("No items to drop");
default -> {
turtle.playAnimation(TurtleAnimation.WAIT);
return TurtleCommandResult.success();
}
yield TurtleCommandResult.success();
}
};
}
}

View File

@ -50,15 +50,14 @@ public class TurtleSuckCommand implements TurtleCommand {
if (inventory != null) {
// Take from inventory of thing in front
var transferred = inventory.moveTo(TurtleUtil.getOffsetInventory(turtle), quantity);
switch (transferred) {
case ContainerTransfer.NO_SPACE:
return TurtleCommandResult.failure("No space for items");
case ContainerTransfer.NO_ITEMS:
return TurtleCommandResult.failure("No items to take");
default:
return switch (transferred) {
case ContainerTransfer.NO_SPACE -> TurtleCommandResult.failure("No space for items");
case ContainerTransfer.NO_ITEMS -> TurtleCommandResult.failure("No items to take");
default -> {
turtle.playAnimation(TurtleAnimation.WAIT);
return TurtleCommandResult.success();
}
yield TurtleCommandResult.success();
}
};
} else {
// Suck up loose items off the ground
var aabb = new AABB(

View File

@ -256,8 +256,8 @@ public class TurtleTool extends AbstractTurtleUpgrade {
EnchantmentHelper.doPostAttackEffects(player.serverLevel(), entity, source);
// Damage the original item stack.
if (!tool.isEmpty() && entity instanceof LivingEntity && didHurt) {
tool.postHurtEnemy((LivingEntity) entity, player);
if (!tool.isEmpty() && entity instanceof LivingEntity living && didHurt) {
tool.postHurtEnemy(living, player);
}
return true;

View File

@ -70,9 +70,9 @@ public final class DropConsumer {
public static boolean onEntitySpawn(Entity entity) {
// Capture any nearby item spawns
if (dropWorld == entity.level() && entity instanceof ItemEntity
if (dropWorld == entity.level() && entity instanceof ItemEntity item
&& assertNonNull(dropBounds).contains(entity.position())) {
handleDrops(((ItemEntity) entity).getItem());
handleDrops(item.getItem());
return true;
}

View File

@ -79,8 +79,8 @@ public class PrettyJsonWriter extends JsonWriter {
// Otherwise we either need to push to our list or finish a record pair.
var head = stack.getLast();
if (head instanceof DocList) {
((DocList) head).add(object);
if (head instanceof DocList headList) {
headList.add(object);
} else {
stack.removeLast();
((DocList) stack.getLast()).add(new Pair((String) head, object));

View File

@ -112,7 +112,7 @@ final class LuaDateTime {
private static int getField(Map<?, ?> table, String field, int def) throws LuaException {
var value = table.get(field);
if (value instanceof Number) return ((Number) value).intValue();
if (value instanceof Number n) return n.intValue();
if (def < 0) throw new LuaException("field \"" + field + "\" missing in date table");
return def;
}

View File

@ -110,14 +110,14 @@ public class OSAPI implements ILuaAPI {
return time;
}
private static int getDayForCalendar(Calendar c) {
var g = c instanceof GregorianCalendar ? (GregorianCalendar) c : new GregorianCalendar();
var year = c.get(Calendar.YEAR);
private static int getDayForCalendar(Calendar calendar) {
var g = calendar instanceof GregorianCalendar c ? c : new GregorianCalendar();
var year = calendar.get(Calendar.YEAR);
var day = 0;
for (var y = 1970; y < year; y++) {
day += g.isLeapYear(y) ? 366 : 365;
}
day += c.get(Calendar.DAY_OF_YEAR);
day += calendar.get(Calendar.DAY_OF_YEAR);
return day;
}
@ -133,7 +133,7 @@ public class OSAPI implements ILuaAPI {
* @param args The parameters of the event.
* @cc.tparam string name The name of the event to queue.
* @cc.param ... The parameters of the event. These can be any primitive type (boolean, number, string) as well as
* tables. Other types (like functions), as well as metatables, will not be preserved.
* tables. Other types (like functions), as well as metatables, will not be preserved.
* @cc.see os.pullEvent To pull the event queued
*/
@LuaFunction

View File

@ -265,8 +265,8 @@ public abstract class AbstractHandle {
checkOpen();
try {
var arg = arguments.get(0);
if (binary && arg instanceof Number) {
var number = ((Number) arg).intValue();
if (binary && arg instanceof Number n) {
var number = n.intValue();
writeSingle((byte) number);
} else {
channel.write(arguments.getBytesCoerced(0));

View File

@ -58,8 +58,8 @@ class TableImpl implements dan200.computercraft.api.lua.LuaTable<Object, Object>
private LuaValue getImpl(Object o) {
checkValid();
if (o instanceof String) return table.rawget((String) o);
if (o instanceof Integer) return table.rawget((Integer) o);
if (o instanceof String s) return table.rawget(s);
if (o instanceof Integer i) return table.rawget(i);
return Constants.NIL;
}

View File

@ -181,8 +181,8 @@ final class VarargArguments implements IArguments {
if (isClosed()) throw new IllegalStateException("Cannot use getTableUnsafe after IArguments has been closed.");
var value = varargs.arg(index + 1);
if (!(value instanceof LuaTable)) throw LuaValues.badArgument(index, "table", value.typeName());
return new TableImpl(this, (LuaTable) value);
if (!(value instanceof LuaTable table)) throw LuaValues.badArgument(index, "table", value.typeName());
return new TableImpl(this, table);
}
@Override
@ -191,8 +191,8 @@ final class VarargArguments implements IArguments {
var value = varargs.arg(index + 1);
if (value.isNil()) return Optional.empty();
if (!(value instanceof LuaTable)) throw LuaValues.badArgument(index, "table", value.typeName());
return Optional.of(new TableImpl(this, (LuaTable) value));
if (!(value instanceof LuaTable table)) throw LuaValues.badArgument(index, "table", value.typeName());
return Optional.of(new TableImpl(this, table));
}
@Override
@ -236,6 +236,7 @@ final class VarargArguments implements IArguments {
return metatable != null && metatable.rawget(NAME) instanceof LuaString s ? s.toString() : null;
}
@SuppressWarnings("ArrayRecordComponent")
private record ArraySlice<T>(T[] array, int offset) {
// FIXME: We should be able to remove the @Nullables if we update NullAway.

View File

@ -48,9 +48,10 @@ public class MethodTest {
@Test
public void testDynamicPeripheral() {
ComputerBootstrap.run(
"local dynamic = peripheral.wrap('top')\n" +
"assert(dynamic.foo() == 123, 'foo: ' .. tostring(dynamic.foo()))\n" +
"assert(dynamic.bar() == 321, 'bar: ' .. tostring(dynamic.bar()))",
"""
local dynamic = peripheral.wrap('top')
assert(dynamic.foo() == 123, 'foo: ' .. tostring(dynamic.foo()))
assert(dynamic.bar() == 321, 'bar: ' .. tostring(dynamic.bar()))""",
x -> x.getEnvironment().setPeripheral(ComputerSide.TOP, new Dynamic()),
50
);
@ -66,9 +67,10 @@ public class MethodTest {
@Test
public void testPeripheralThrow() {
ComputerBootstrap.run(
"local throw = peripheral.wrap('top')\n" +
"local _, err = pcall(function() throw.thisThread() end) assert(err == '/test.lua:2: !', (\"thisThread: %q\"):format(err))\n" +
"local _, err = pcall(function() throw.mainThread() end) assert(err == '/test.lua:3: !', (\"mainThread: %q\"):format(err))\n",
"""
local throw = peripheral.wrap('top')
local _, err = pcall(function() throw.thisThread() end) assert(err == '/test.lua:2: !', ("thisThread: %q"):format(err))
local _, err = pcall(function() throw.mainThread() end) assert(err == '/test.lua:3: !', ("mainThread: %q"):format(err))""",
x -> x.getEnvironment().setPeripheral(ComputerSide.TOP, new PeripheralThrow()),
50
);
@ -77,8 +79,9 @@ public class MethodTest {
@Test
public void testMany() {
ComputerBootstrap.run(
"assert(many.method_0)\n" +
"assert(many.method_39)",
"""
assert(many.method_0)
assert(many.method_39)""",
x -> x.addApi(new ManyMethods()), 50);
}
@ -94,8 +97,7 @@ public class MethodTest {
public void testModule() {
ComputerBootstrap.run(
"""
assert(require "test.module".func() == 123)
""",
assert(require "test.module".func() == 123)""",
x -> x.addApi(new IsModule()), 50);
}

View File

@ -24,7 +24,7 @@ dependencies {
testImplementation(libs.bundles.test)
testImplementation(libs.errorProne.testHelpers)
testImplementation(libs.neoForgeSpi)
testImplementation(variantOf(libs.neoMergeTool) { classifier("api") }) { isTransitive = false }
testCompileOnly(project(":core-api"))
testRuntimeOnly(libs.bundles.testRuntime)
}

View File

@ -168,6 +168,7 @@ public class TransformingClassLoader extends ClassLoader {
}
}
@SuppressWarnings("ArrayRecordComponent")
private record TransformedClass(String name, byte[] contents) {
}
}