Table of Contents
Расширители доступа (Access Wideners)
Расширители доступа предоставляют возможность ослабить ограничения доступа к классам, методам или полям. Расширители доступа похожи на широко известные Access Transformers.
Расширители доступа могут использоваться вместо аксессора миксинов, и в настоящее время есть 2 случая, когда функциональности, предоставляемой миксином, недостаточно:
- Необходимость доступа к закрытому классу (пакету), особенно для теневой цели или доступа к полю или методу в миксине.
- Возможность переопределять final-методы или подклассы final-классов.
- Если вы хотите создать подкласс класса, имеющий только (пакетные) приватные конструкторы, расширители - хороший выбор.
Чтобы изменения в расширителе доступа отображались в декомпилированном исходном коде, запустите задачу gradle genSources
, а затем перезагрузите проект gradle в вашей IDE.
Примечание: В отличие от аксессора миксинов, расширители доступа не работают для исходников модов.
Требования
- Fabric-loader 0.8.0 или выше
- Loom 0.2.7 или выше
Формат файла
Для определения изменений доступа, включенных в ваш мод, используется специальный формат файла. Чтобы облегчить работу IDE, вам следует использовать расширение файла .accesswidener
.
Файл должен начинаться со следующего заголовка. namespace
обычно всегда должно быть установлено слово named
, а не имя вашего проекта. Loom выполнит ремаппинг файла расширителя доступа в intermediary
вместе с вашим модом.
accessWidener v2 <namespace>
И снова, пространство имён должно быть named
в большинстве, если не во всех случаях
Файлы расширителя доступа могут содержать пустые строки и комментарии, начинающиеся с #
# Поддерживаются комментарии, подобные этому, а также в конце строки
Для разделения в файле расширителя доступа можно использовать любые пробельные символы, рекомендуется использовать табуляцию.
Имена классов разделяются символом /
, а не .
Для внутренних классов следует использовать $
вместо /
.
Классы
Доступ к классу может быть изменён путём указания доступа и имени класса в соответствии с пространством имён маппинга, определённым в заголовке.
<access> class <className>
- access может быть accessible или extendable
Методы
Доступ к методу может быть изменён путём указания доступа, имени класса, имени метода и дескриптора метода в соответствии с пространством имён маппинга, определённым в заголовке.
<access> method <className> <methodName> <methodDesc>
- access может быть accessible или extendable
- className - класс-владелец
- methodName - имя метода
- methodDesc - дескриптор метода
Поля
Доступ к полю может быть изменён путём указания доступа, имени класса, имени поля и дескриптора поля в соответствии с пространством имён маппинга, определённым в заголовке.
<access> field <className> <fieldName> <fieldDesc>
- access может быть accessible или mutable
- className - класс-владелец
- fieldName - имя поля
- fieldDesc - дескриптор поля
Изменение доступа
Extendable
Extendable следует использовать, когда вы хотите расширить класс или переопределить метод.
- Классы становятся public, а final удаляется
- Методы становятся protected, а final удаляется
Если сделать метод расширяемым, то и класс станет расширяемым.
Accessible
Accessible следует использовать, когда вы хотите получить доступ к классу, полю или методу из другого класса.
- Классы становятся public
- Методы становятся public и final, если они private
- Поля становятся public
Делая метод или поле доступным, вы также делаете доступным класс.
Mutable
Mutable следует использовать, когда вы хотите изменить final-поле.
- Final-поля удалены
Если вы хотите сделать приватное final-поле одновременно доступным и изменяемым, вам нужно использовать две директивы, по одной на каждое изменение.
Указание расположения файла
Расположение файла расширителя доступа должно быть указано в файле build.gradle и в файле fabric.mod.json. Он должен храниться в ресурсах, так как его необходимо включить в экспортируемый jar-файл. (Замените “modid” в примере на свой собственный идентификатор мода).
Loom 0.9 или выше:
loom { accessWidenerPath = file("src/main/resources/modid.accesswidener") }
Loom 0.8 или ниже:
loom { accessWidener = file("src/main/resources/modid.accesswidener") }
fabric.mod.json:
... "accessWidener" : "modid.accesswidener", ...
Проверка файла
По умолчанию несуществующие записи accesswidener игнорируются.
В последних версиях Loom вы можете выполнить команду gradlew validateAccessWidener
, чтобы проверить, что все классы, поля и методы, указанные в файле accesswidener, существуют.
Сообщения об ошибках могут быть немного загадочными. Например, если вы ошиблись в указании поля, ошибка не говорит, в чём проблема - в имени или в типе. Например, если в сообщении говорится, что не удаётся найти поле “fooI
”, это может означать, что поля с именем foo
не существует, или что оно существует, но не является int
(I
).
V2 изменения
В версии v2 были добавлены ключевые слова с префиксом transitive-*
:
transitive-accessible
transitive-extendable
transitive-mutable
Они отличаются от своих обычных, не префиксных вариантов тем, что применяются также к модам, зависящим от этого мода.