Record Class ModAccessWidenerEntry

java.lang.Object
java.lang.Record
net.fabricmc.loom.configuration.accesswidener.ModAccessWidenerEntry
Record Components:
modId - mod 的 id(原 FabricModJson.getId())
modSchemaVersion - mod 元数据的 schema 版本(原 FabricModJson.getVersion(),只参与身份)
path - 规则文件在 mod 内的路径
environment - 规则适用的环境
transitiveOnly - 是否只取 transitive- 规则
data - 规则文件内容
All Implemented Interfaces:
AccessWidenerEntry

public record ModAccessWidenerEntry(String modId, int modSchemaVersion, String path, ModEnvironment environment, boolean transitiveOnly, byte[] data) extends Record implements AccessWidenerEntry
AccessWidenerEntry implementation for a FabricModJson.

为什么这里不持有 FabricModJson

本 record 的实例会随 AccessWidenerJarProcessor.Spec 进入 ProcessMinecraftJarTask 的任务状态(spec 是该任务的 @Internal 属性,但 @Internal 只免掉指纹,不免掉序列化)。任务状态整体必须能写进配置缓存,而 FabricModJson 持有的东西 恰恰都不是配置缓存能序列化的值:
  • 元数据本体是 Gson 的 JsonObject,其内部映射类型是 com.google.gson.internal.LinkedTreeMap;
  • 资源来源形状不定——jar 路径、源码集,甚至跨项目数据重建出来的 lambda 闭包。
实测(Gradle 9.5/9.6,org.gradle.configuration-cache=true 且 problems=fail): 带着依赖 mod 的 access widener 构建时,存储阶段直接以 value '{...}' is not assignable to 'com.google.gson.internal.LinkedTreeMap' 失败, 整个构建无法通过配置缓存。因此这里只保留链真正需要的纯值:元数据身份(id 与 schema 版本)、 规则文件路径、环境、以及「是否只取 transitive 规则」标志,外加**规则文件本身的字节**。

为什么规则文件字节可以在配置期读

依赖 mod 的元数据本来就是从同一份来源读出来的(jar 依赖读 jar 条目,项目依赖读 LoomProjectData 已复制的资源),所以「配置期读不到、只有执行期才读得到」的情形不存在; 本包的 LocalAccessWidenerEntry 也早就在建 spec 时读文件并在缺失时直接失败。 把字节在配置期取出来,链在执行期就不需要再碰任何一句「怎么读」的上下文。

为什么身份是显式写出来的

spec.hashCode() 是 loom 既有协议里的链身份(缓存值与产物路径都由它派生, 见 MinecraftJarProcessorManager.getCacheValue()),所以改造不能让它漂移。 改造前的身份是 Objects.hash(FabricModJson.hashCode() = Objects.hash(id, schemaVersion), path, environment, transitiveOnly), 下面的 hashCode() 逐位复现这一串。规则文件字节只是载荷、不进身份:把它算进去会让 「同一个 mod 的同一份规则文件、内容不同」被当成两条链,而既有协议只看 mod 身份。
  • Constructor Details

    • ModAccessWidenerEntry

      public ModAccessWidenerEntry(String modId, int modSchemaVersion, String path, ModEnvironment environment, boolean transitiveOnly, byte[] data)
      Creates an instance of a ModAccessWidenerEntry record class.
      Parameters:
      modId - the value for the modId record component
      modSchemaVersion - the value for the modSchemaVersion record component
      path - the value for the path record component
      environment - the value for the environment record component
      transitiveOnly - the value for the transitiveOnly record component
      data - the value for the data record component
  • Method Details

    • readAll

      public static List<ModAccessWidenerEntry> readAll(FabricModJson modJson, boolean transitiveOnly)
    • hashCode

      public int hashCode()
      身份与改造前逐位一致.

      改造前的身份来自 record 自动生成的实现,合并方式是从 0 开始的 31 折: result = 0; result = 31 * result + h(i),与 Objects.hash(...) 的从 1 开始 (result = 1; ...)差着最前面一个 ×31。这里必须按前者的写法显式复现: 用 Objects.hash(第一个组件, 第二个, ...) 铺开整条链会得到另一个数, 而 spec.hashCode() 是产物路径与缓存值的来源(见类注释),差一个数就意味着所有工作区 都要重新处理一遍 Minecraft jar。

      Specified by:
      hashCode in class Record
    • equals

      public boolean equals(Object o)
      与 hashCode() 同源的等值判定:只比身份,不比规则文件字节.

      刻意与 hashCode() 用同一组字段:record 自动生成的实现会把 data 按引用比较, 那既与身份不一致,又让两条内容相同的链永远不相等。

      Specified by:
      equals in class Record
    • toString

      public String toString()
      Returns a string representation of this record class. The representation contains the name of the class, followed by the name and value of each of the record components.
      Specified by:
      toString in class Record
      Returns:
      a string representation of this object
    • mappingId

      public @Nullable String mappingId()
      Specified by:
      mappingId in interface AccessWidenerEntry
      Returns:
      The mod id to be used in TransitiveAccessWidenerMappingsProcessor or null when this entry does not contain transitive entries.
    • getSortKey

      public String getSortKey()
      Specified by:
      getSortKey in interface AccessWidenerEntry
    • read

      public void read(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor, LazyCloseable<net.fabricmc.tinyremapper.TinyRemapper> remapper, MappingsNamespace productionNamespace) throws IOException
      Specified by:
      read in interface AccessWidenerEntry
      Throws:
      IOException
    • readOfficial

      public void readOfficial(net.fabricmc.classtweaker.api.visitor.ClassTweakerVisitor visitor) throws IOException
      Specified by:
      readOfficial in interface AccessWidenerEntry
      Throws:
      IOException
    • modId

      public String modId()
      Returns the value of the modId record component.
      Returns:
      the value of the modId record component
    • modSchemaVersion

      public int modSchemaVersion()
      Returns the value of the modSchemaVersion record component.
      Returns:
      the value of the modSchemaVersion record component
    • path

      public String path()
      Returns the value of the path record component.
      Returns:
      the value of the path record component
    • environment

      public ModEnvironment environment()
      Returns the value of the environment record component.
      Specified by:
      environment in interface AccessWidenerEntry
      Returns:
      the value of the environment record component
    • transitiveOnly

      public boolean transitiveOnly()
      Returns the value of the transitiveOnly record component.
      Returns:
      the value of the transitiveOnly record component
    • data

      public byte[] data()
      Returns the value of the data record component.
      Returns:
      the value of the data record component