Fabric API

Fabric API

106M Downloads

[RFC] Experimental APIs

sfPlayer1 opened this issue Β· 39 comments

commented

In order to support API features that are likely to change (1.16 nether biome selection) or difficult to get right from the start, I am proposing to offer experimental APIs in Fabric API. Those APIs are marked via @Deprecated and can both extend existing modules or form new ones.

The @Deprecated annotation use is in line with how Java annotates its preview features, which serve a similar purpose. Additionally the associated Javadoc has to include @deprecated Experimental feature, may be removed or changed without further notice <optional explanation why it is experimental>.

Addition of and incompatible changes to experimental features will incur a minor version bump, the major version and module version (v0/v1/...) remain the same.

commented

Modules such as fabric-transfer-api-v1 now use a combination of a module lifecycle field, annotations, and Javadoc to indicate their experimental status:

"custom": {
"fabric-api:module-lifecycle": "experimental"
}
/**
* Access to {@link Storage Storage&lt;ItemVariant&gt;} instances.
*
* <p><b>Experimental feature</b>, we reserve the right to remove or change it without further notice.
* The transfer API is a complex addition, and we want to be able to correct possible design mistakes.
*/
@ApiStatus.Experimental
public final class ItemStorage {

commented

This is now encoded in the contribution guidelines, which should be a sufficient reference.

commented

I agree, I assume minor gets bumped when adding an experimental API?

commented

sounds good to me

commented

Maybe add a special experimental label for experimental PRs?

commented

We may add another annotation targetting classes, fields, and methods to accompany @Deprecated (for easy lookup, added to api base most likely, or use guava @Beta as well)

commented

yes

commented

Yes

commented

Quick vote:
πŸ‘ for guava @Beta annotation etc. in addition to @Deprecated on snapshot hooks
πŸ‘Ž for just @Deprecated on snapshot hooks

commented

Quick reasoning:
@Beta alone cannot warn users efficiently. @Deprecated alone cannot distinguish from apis scheduled for release-stage removal or in no-source distributions. Combined would be the most informative.

commented

Another quick note: We talked about jetbrain annotations has annotations like @ApiStatus.Experimental, which may serve notification purposes with ide integration.

commented

Jetbrains Annotations are useful for stuff like ScheduledForRemoval and Experimental, but do IDEs support them?

commented

Here are all of the annotation APIs I know of:

  • JetBrains Annotations - Maven
    • Supported by JetBrains IDEs by default
    • Includes several annotations for APIs (Experimental, Internal, ScheduledForRemoval, AvailableSince, NonExtendable, and OverrideOnly)
    • Includes several other annotations related to compile-time checks, safety, and method contracts
  • @API Guardian - Maven
    • Supported by JetBrains IDEs by default
    • Includes one annotation with an enum for levels of support (INTERNAL, DEPRECATED, EXPERIMENTAL, MAINTAINED, and STABLE)
  • Guava Annotations - Maven
    • Supported by JetBrains IDEs by default
    • Includes one annotation for APIs (Beta)
    • Includes three other annotations related to GWT and testing

I can't speak on Eclipse support as I haven't used it in like six years.

I personally prefer JetBrains Annotations because they allow showing detailed API info and additional optional info.

commented

Here are the cons of each:

  • JetBrains Annotations
    • Maybe not interpreted by other IDEs? An annotation processor is preferable.
  • API Guardian
    • Too few associated tools available from official site (e.g. no annotation processor)
  • Guava Annotations
    • No standalone distribution, shipped with guava
    • May conflict with the version of guava vanilla uses
commented

All in favor of Jetbrains annotations voteπŸ‘
All in favor of literally anything else vote πŸ‘Ž

commented

I prefer JetBrains, because JetBrains IDEs will give a warning, and everything else can be configured to do so easily (or does so by default). Whereas anything else, will not be supported by literally anything.

commented

We need to decide on one annotation standard for ALL projects. This includes yarn, loom, api and loader.

The choice we make imo should be able to support type annotations such as
Foo<@Nullable Bar> and Foo.@Nullable Bar

commented

I think you should talk about the different options and the pros and cons before starting a poll like that.

commented

#499 (comment)
#499 (comment)
also most the other comments in this issue are that

commented

This isn’t the right issue for the null checking annotations either. I’d create a new issue about it.

commented

I mean JetBrains annotations "just work", while other annotations will be more descriptive. @Deprecated doesn't make that much sense, but will show a warning, while @Experimental makes sense, but no warning in the IDE. I prefer having IDE warnings.

commented

Deprecated was chosen as it works in all IDEs not just idea. Java it’s self was using it (I believe the latest version does something else now) for its own experimental APIs so it seemed a great fit.

commented

We're taking a lot of the experimental API stuff over to FabLabs. It'll be drafted and worked on there before it's PR'd into Fabric API.

commented

Imo fablabs will be large experimental apis that are applicable to previous versions (generally applicable).

Snapshot-bound smaller essential apis like nether biomes or living entity attributes may go through fabric directly, I'd suggest, due to a high necessity.

commented

I wonder how feasable it would be to add an @Experimental annotation, should be able to add warnings to that. IDEA does so for Unsafe and similar things.

commented

Well we could obviously add an annotation in 2s. The issue is IDE support for these annotations so the user can see something.

commented

The user visibility imo can be done with an annotation processor that maybe produces a warning if an annotated class/method/field is used in the abstract syntax tree?

commented

I don't think IntelliJ at least shows warnings from the Annotation Processor in the editing view, I know this because I have gotten Mixin warning that wait to show up until compiling, and then only in the build screen.

commented

yeah, you need a plugin for AP warnings.

commented

@sfPlayer1 Now that we are on java 16, a notable new feature is that @Deprecated now has a forRemoval boolean field. Should we start using those in fabric api now?

commented

I think so, see https://openjdk.java.net/jeps/277 - "the API is experimental and is subject to incompatible changes"

commented

See #1459 where I add forRemoval for apis that are definitely getting removed in the future.

Meanwhile, for actual experimental apis, I suggest a new review mechanism:
We do not need as throughout review for new-generation apis. We would instead add them with @ApiStatus.Experimental and @Deprecated, and have the review for normalization of new api in another pr (we can object or change an api to be forRemoval=true there).

commented

Experimental API should probably use forRemoval=false

commented

Yeah, forRemoval=true is one of the possible outcomes for an experimental api in a pull request that determines the fate of the exp api; or it may just be nuked in a minecraft update in the worst case.

Imo this two step model would allow us to draft a temporary api with less delay in case there is a minecraft update that break existing apis, such as a biome update; the maintainers can just add an api with no-last-call period or minimal review (or even commited to the api directly), which will be an exp api; the community later can open a pr to remove those temp api or elevate them to be permanent.

The three states:

State Annotations Destiny
Experimental API @ApiStatus.Experimental @Deprecated
Note: forRemoval is false by default
to be reviewed in a later pr, may either go mature or go dying, triaged through extensive use over time and the review pr
Dying API @Deprecated(forRemoval = true) to be removed in a version update, exact schedule to be determined in another issue as we don't have one yet
Mature API None the regular API endpoints that we recommend people to use; may go dying as API evolves
commented

I'd state false explicitly, this is all about communication, otherwise the above scheme is fine. The "in a version update" would be a bump in the minor version only as per the OP.

commented

The "in a version update" would be a bump in the minor version only as per the OP.

Hmm, removing dying api that grew from mature apis in minor updates would be too breaking imo. So an updated table:

State Annotations Destiny
Experimental API @ApiStatus.Experimental @Deprecated(forRemoval = false) to be reviewed in a later pr, may either go mature or go dying, triaged through extensive use over time and the review pr
Dying Experimental API @ApiStatus.Experimental @Deprecated(forRemoval = true) to be removed in a minor version update
Mature API None the regular API endpoints that we recommend people to use; may go dying as API evolves
Dying Mature API @Deprecated(forRemoval = true) to be removed in a major version update
commented

Yes I meant that for experimental api, the new table is spot on!

commented

That table does not reflect the status quo I think: Dying Mature API should probably be @Deprecated alone, as we will somewhat try not to remove it.

commented

@liach Ok so Player meant that the table is correct for Dying Mature APIs, so that would be for an API that we know we will have to remove in a subsequent version. However most deprecated APIs are not dying, so they should be marked as @Deprecated alone imo.

forRemoval = false would suggest we will keep it, which is not necessarily the case.

forRemoval = true means we intend to remove the API, which is not necessarily the case, or at least we will try to postpone it as long as it's reasonable.