Skip to content

Fix unused warnings for methods implementing external interfaces#402

Draft
kjonescertinia wants to merge 5 commits intomainfrom
fix/issue-401-interface-completeness
Draft

Fix unused warnings for methods implementing external interfaces#402
kjonescertinia wants to merge 5 commits intomainfrom
fix/issue-401-interface-completeness

Conversation

@kjonescertinia
Copy link
Contributor

Summary

This PR fixes issue #401 where public/global methods implementing interfaces from external namespaces were incorrectly flagged as unused.

Root cause: The UnusedPlugin didn't account for cases where interface information is incomplete due to external dependencies. Methods that appear unused locally may actually implement interface contracts from external packages.

Solution:

  • Add hasAllInterfaces flag to ApexClassDeclaration to track interface completeness
  • Recursively checks the entire type hierarchy (superclass and all interfaces)
  • Update UnusedPlugin.couldBeUnused() to suppress warnings for public/global methods when hasAllInterfaces is false
  • Improve documentation for isComplete flag in TypeDeclaration

Related fixes: This PR also includes fixes for issues #397 and #398:

Test plan

  • All 697 existing tests pass
  • Added 8 new tests covering various interface scenarios:
    • Public method implementing unknown external interface not flagged
    • Private method implementing unknown external interface still flagged
    • Global method implementing unknown external interface not flagged
    • Public method implementing known interface can be flagged
    • Inheritance chains with unknown interfaces
    • Multiple interface scenarios (all unknown, mixed known/unknown)
  • Code formatting verified with sbt scalafmtAll

Fixes #401

#397)

Fixed regression where loop variables used only in for-loop conditions
and increments were being incorrectly marked as unused. For example,
`for (Integer i = 0; i < 2; i++)` would incorrectly flag `i` as unused.

The issue was caused by `withUsageTracking(false)` preventing variable
references in for control from being tracked. Removed this wrapper to
allow proper usage tracking.

Added comprehensive test coverage for:
- Variables used only in condition
- Variables used only in update/increment
- Variables unused (should still be flagged)
- Variables used in body (read or modified)
- Multiple variable declarations in for loops

All 697 tests pass with no regressions.
When initializing a List/Set with a ghosted element type (external namespace
types without definitions), the variable usage tracking was being skipped. This
caused variables used within the list initializer to be incorrectly flagged as
unused.

The fix ensures that parts.foreach(_.verify(input, context)) is called even
when the element type lookup fails, maintaining proper variable usage tracking
while skipping type compatibility checks for unavailable types.
…d-fixes-397-398

# Conflicts:
#	jvm/src/test/scala/com/nawforce/apexlink/plugin/UnusedTest.scala
…faces (fixes #401)

Add hasAllInterfaces flag to track whether we have complete information about
all implemented interfaces. When false, public/global methods are not flagged
as unused since they may be implementing interfaces from external namespaces.

- Add hasAllInterfaces lazy val to ApexClassDeclaration
- Update UnusedPlugin to check hasAllInterfaces before flagging methods
- Add 8 comprehensive tests covering various interface scenarios
- Improve isComplete documentation in TypeDeclaration
@kjonescertinia
Copy link
Contributor Author

Merge dependency: This PR should be merged after #397 and #398 are merged, as the branch was created from a combined test branch that includes both of those fixes.

@kjonescertinia kjonescertinia marked this pull request as draft November 23, 2025 19:13
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.

False positive unused warnings for methods implementing external namespace interfaces

1 participant