Skip to content

ADFA-6560: Restore plugin-api constructors that older plugins call - #2173

Merged
Daniel-ADFA merged 6 commits into
stagefrom
bugfix/ADFA-6560-plugin-tooltip-button-ctor
Oct 22, 2026
Merged

Daniel-ADFA merged 6 commits into
stagefrom
bugfix/ADFA-6560-plugin-tooltip-button-ctor

Conversation

@Daniel-ADFA

@Daniel-ADFA Daniel-ADFA commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

ADFA-6560

Makes it safe to add methods with a default body to plugin interfaces, and lets plugins built before May load again.

  • Compiles plugin-api interface bodies as Java default methods (jvmDefault = ENABLE). Since the ADFA-4058 languageVersion pin they were abstract methods plus DefaultImpls. So each method with a body added to an interface a plugin implements failed with AbstractMethodError in every plugin built before it, unless the host wrapped the call (as PluginUiActionManager does for getHiddenToolbarActionIds). Those plugins now inherit the body. DefaultImpls stays, so plugins built since May are unaffected.
  • Restores what pre-May plugins call: PluginTooltipButton(String, String, int) (Add plugin sidebar/toolbar tooltips and directPath URI option #1268), the pre-tooltipTag constructors of NavigationItem, TabItem, FileTabMenuItem and MenuItem (hidden from Kotlin source), and the IdeArchiveService.extract and IdeCommandService.executeCommand default-argument helpers. The April Keystore Generator build behind GlitchTip 8548737 works again. The builds on addons.appdevforall.org were never affected.

A plugin built against this plugin-api needs IDE 26.43 or later unless it overrides every interface method it implements (noted in PLUGIN_API_CHANGELOG.md). The two style: commits are Spotless reformats only.

…change

Editing the file pulls it under the Spotless ratchet, which reindents it
to tabs and adds trailing commas. Kept separate from the ADFA-6560 fix.
#1268 added directPath to PluginTooltipButton, which replaced the
(String, String, int) constructor. Plugins built before it, such as older
Keystore Generator installs, call that constructor from getTooltipEntries,
so their documentation install fails with NoSuchMethodError on every
launch (fatal on older releases).

Add the old constructor back as a hidden secondary constructor. It
restores both (String, String, int) and its default-order synthetic,
while staying invisible to Kotlin source, so current callers resolve to
the primary constructor as before.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Important

Review skipped

Review was skipped as selected files did not have any reviewable changes.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 6d3ad14e-ca16-49e4-8126-b0378c48c7ab
📥 Commits

Reviewing files that changed from the base of the PR and between 651d28d and a387836.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 2c49fa4c-ffd4-4204-89dd-7e9c3bbe084b
📥 Commits

Reviewing files that changed from the base of the PR and between 48ea2bb and 651d28d.

📒 Files selected for processing: 5
  • docs/PLUGIN_API_CHANGELOG.md
  • plugin-api/api/plugin-api.api
  • plugin-api/build.gradle.kts
  • plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/services/IdeServices.kt
  • plugin-api/src/test/kotlin/com/itsaky/androidide/plugins/extensions/InterfaceDefaultMethodsTest.kt

Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

📝 Summary
  • Restored hidden compatibility constructors for legacy plugins.
  • Enabled JVM default methods for plugin API interfaces.
  • Added constructor and interface compatibility tests.
  • Updated the plugin API changelog and compatibility documentation.
  • Risk: compatibility gaps may remain in service default-argument helpers.
  • Test execution results are unavailable.

The plugin API enables JVM default methods, adds synthetic default-argument bridges, preserves pre-tooltipTag constructors, and adds tests and documentation for binary compatibility and IDE version requirements.

Changes: Plugin API compatibility

Layer / File(s) Summary
JVM default methods and API entries
plugin-api/build.gradle.kts, plugin-api/api/plugin-api.api
Kotlin compilation enables JVM default methods. The API exposes default implementations and synthetic default-argument bridges for extension and IDE service interfaces.
Compatibility constructor implementation
plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/FileOpenExtension.kt, plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/UIExtension.kt
Hidden deprecated constructors preserve earlier parameter layouts. MenuItem applies default masks to selected parameters.
Compatibility validation and documentation
plugin-api/src/test/kotlin/com/itsaky/androidide/plugins/extensions/*, plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/extensions/*, plugin-api/src/main/kotlin/com/itsaky/androidide/plugins/services/IdeServices.kt, docs/PLUGIN_API_CHANGELOG.md
Tests validate constructor and interface-default compatibility. Documentation records IDE version requirements and restored JVM default behavior.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested reviewers: hal-eisen-adfa, jatezzz

Merge Risk: ⚪ Minimal · up to 651d2

No actionable compatibility issue was found; the change is ready for normal validation and merge.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 42.42% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 8 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly identifies the restoration of plugin-api constructors for older plugins. This is a central change in the pull request, although it does not mention the Java default-method compatibil…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description directly addresses the changeset. It explains Java default methods, restored plugin compatibility constructors, default-argument helpers, affected plugin versions, and for…
Full details: Title check

Explanation

The title clearly identifies the restoration of plugin-api constructors for older plugins. This is a central change in the pull request, although it does not mention the Java default-method compatibility work.

Full details: Description check

Explanation

The pull request description directly addresses the changeset. It explains Java default methods, restored plugin compatibility constructors, default-argument helpers, affected plugin versions, and formatting-only commits.

Full details: Docstring Coverage

Explanation

Docstring coverage is 42.42% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 33 functions across 8 files. (2 skipped: 2 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

A rabbit checks each default door,
Old constructors hop back once more.
JVM methods bloom in place,
Tests guard every bridge and case,
Version notes mark the floor.

Comment @coderabbitai help to get the list of available commands.

@Daniel-ADFA
Daniel-ADFA requested a review from a team October 20, 2026 21:41
…no functional change

Editing both files pulls them under the Spotless ratchet. Kept separate
from the ADFA-6560 fix.
NavigationItem, TabItem, FileTabMenuItem and MenuItem gained tooltipTag
(MenuItem also icon) after April, which replaced the constructors that
plugins built before then call. An old Keystore Generator build still
failed on NavigationItem's constructor in getSideMenuItems after the
PluginTooltipButton fix.

Add the old constructors back as hidden secondary constructors.
NavigationItem, TabItem and FileTabMenuItem take the old parameters with
the old defaults, which restores both the full constructor and its
default-argument synthetic. MenuItem's full constructor survived through
@jvmoverloads, so only its default-argument constructor is restored, with
the exact JVM signature and the April defaults applied from the mask.
@Daniel-ADFA Daniel-ADFA changed the title ADFA-6560: Restore PluginTooltipButton's pre-directPath constructors ADFA-6560: Restore plugin-api constructors that older plugins call Oct 20, 2026
Pinning languageVersion to 2.1 (ADFA-4058, later 2.0) dropped Kotlin's
newer jvm-default behaviour, so plugin-api compiled every interface body
as an abstract method plus a DefaultImpls static. Plugins built against
the earlier plugin-api call the interface default with invoke-super. The
April Keystore Generator, for one, hit AbstractMethodError on
UIExtension.getToolbarActions() in EditorActivity.onCreate. The plugin
crash guard caught it, but the editor stayed blank until the plugin was
disabled.

jvmDefault = ENABLE keeps the language pin and puts the bodies back on
the interfaces. It keeps DefaultImpls for plugins built since May, and
restores the IdeArchiveService.extract$default and
IdeCommandService.executeCommand$default helpers that pre-May callers
link against.

A plugin built against this plugin-api has no DefaultImpls stubs, so on
an IDE built between ADFA-4058 and 26.42 it needs to override every
interface method it uses. PLUGIN_API_CHANGELOG.md says so.

InterfaceDefaultMethodsTest fails without the change: getToolbarActions
is not a default method, and neither is any body behind a DefaultImpls
static. fragment-ktx joins the test runtime classpath because
EditorTabExtension takes a Fragment and reflection has to load it.
@Daniel-ADFA
Daniel-ADFA merged commit 88b6e4a into stage Oct 22, 2026
@Daniel-ADFA
Daniel-ADFA deleted the bugfix/ADFA-6560-plugin-tooltip-button-ctor branch October 22, 2026 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants