Fix addServiceListener not injected for union service type in listener attach#44594
Conversation
…r attach When a listener's attach() accepts a union service type (e.g. salesforce:Service = CdcService|PlatformEventsService), the compiler skips injecting the addServiceListener call because BUnionType does not carry Flags.SERVICE on its own flags, even though every member of the union is a service type. Introduce isServiceType() that recurses into union member types and unwraps BTypeReferenceType before checking the SERVICE flag, so addServiceListener is correctly injected for any listener whose attach() parameter is a union of service types. Fixes: https://github.com/ballerina-platform/ballerina-lang/issues/XXXXX
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughReplaces a direct Flags.SERVICE check in JvmObjectGen with a recursive isServiceType(BType) helper that handles union members and type references; adds necessary imports and updates isListenerAttach to delegate to the new helper. ChangesService Type Detection Refactoring
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/values/JvmObjectGen.java`:
- Around line 189-192: The isListenerAttach helper assumes
func.parameters.getFirst() exists and later injection code reads args[1]
unconditionally; add explicit arity guards: in
isListenerAttach(BIRNode.BIRFunction func) return false unless func.parameters
has at least one parameter (check size()/isEmpty()) before calling getFirst(),
and in the code path that injects/reads args[1] ensure the function parameter
count or runtime args.length is >=2 before dereferencing args[1] (or bail/skip
injection when arity is too small) so both compile-time and runtime accesses are
safe for non-attach arities.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 74b0eccd-94c0-4720-842d-3155b70df681
📒 Files selected for processing (1)
compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/values/JvmObjectGen.java
isListenerAttach called getFirst() without checking whether the parameters list was non-empty, and the injection site unconditionally read args[1] at runtime. A single size() >= 2 guard prevents both: getFirst() is safe (non-empty list), and the generated AALOAD at index 1 is only emitted when the function has at least two parameters so the runtime args array is guaranteed to contain args[1].
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #44594 +/- ##
============================================
- Coverage 75.03% 75.02% -0.01%
- Complexity 58707 58708 +1
============================================
Files 3601 3601
Lines 227161 227169 +8
Branches 29581 29585 +4
============================================
- Hits 170443 170439 -4
- Misses 47215 47223 +8
- Partials 9503 9507 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Problem
When a Ballerina listener's
attach()method accepts a union service type (e.g.salesforce:Service = CdcService|PlatformEventsService), the compiler skips injecting theaddServiceListenercall into the listener's generatedcalldispatch method. This causes those services to never appear in the runtime repository, so tools that rely onenv.getRepository().getArtifacts()(such as WSO2 ICP) report empty listeners/services for any non-HTTP event-driven integration.Root cause:
isListenerAttach()checkedFlags.SERVICEdirectly on the parameter type.BUnionTypenever carriesFlags.SERVICEon its own flags, even when every member of the union is a service type.Fix
Introduce
isServiceType(BType)that:trueif the type directly carriesFlags.SERVICEBUnionType(true only when every member is a service type)BTypeReferenceType(guards against nullreferredType) before recursingisListenerAttach()is updated to delegate toisServiceType().Related
Backport of #44592 (merged into
2201.13.x).Summary
This pull request fixes a compiler code-generation bug that caused addServiceListener to be omitted for listener attach() methods when the attach parameter was a union of service types (e.g., CdcService|PlatformEventsService). As a result, services for such listeners were not registered in the runtime repository and were not discoverable by tools inspecting env.getRepository().getArtifacts().
Changes
File:
JvmObjectGen.javaImpact
Ensures addServiceListener is injected for listeners whose attach parameter is a union of service types, so those services are correctly registered in the runtime repository and visible to repository inspection tools. Also improves codegen safety by avoiding out-of-bounds argument access during call dispatch generation.