fix(parser): eliminate Kotlin coroutine bytecode causing ClassNotFoundException in Gradle plugin#281
Conversation
…azy iterator Okio's sequence builder and our custom listRecursively both compile to coroutine bytecode referencing SpillingKt (added in Kotlin 2.1.20). Gradle 8.x bundles an older Kotlin stdlib, causing ClassNotFoundException at runtime inside the Gradle plugin. - Replace with lazySequence utility backed by an explicit Iterator stack. - Also add deleteRecursivelyCompat for the same reason
Wire the coroutine-free deleteRecursivelyCompat into FileManager so the Gradle plugin no longer calls Okio's deleteRecursively (which uses sequence{} internally).
…t helpers entirely. Also adds an inline comment explaining the depth computation formula and fixes a truncated KDoc sentence in deleteRecursivelyCompat.
…sivelyCompat Add tests for non-existent directory, deep tree traversal, and empty directory deletion to improve coverage of filesystem extension functions.
…er traversal Replace .toList().asReversed() with in-place stack-based deletion so memory usage scales with tree depth, not total node count. Files are deleted immediately on visit; directories are deleted once empty.
Document that DepthFirstIterator is not thread-safe and that sharing a single iterator across threads will corrupt the internal stack.
…Iterator
Eliminates the last sequence{} builder in commonMain, which caused
ClassNotFoundException for SpillingKt when running inside Gradle 8.x.
The old name was too generic and suggested a general-purpose lazy sequence builder. The new name communicates that it performs a depth-first tree traversal specifically.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
✅ Files skipped from review due to trivial changes (1)
WalkthroughIntroduces a stack-based depth-first traversal utility, rewrites sequence builders to explicit iterators, simplifies Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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
🧹 Nitpick comments (1)
svg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemDeleteRecursivelyCompatTest.kt (1)
34-34: Consider usingassertFalsefor negated existence checks.
assertTrue(!fs.exists(path))works butassertFalse(fs.exists(path))is more idiomatic and produces clearer failure messages.♻️ Example change
- assertTrue(!fs.exists(root)) + assertFalse(fs.exists(root))Also applies to: 63-63, 74-74, 119-119
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@svg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemDeleteRecursivelyCompatTest.kt` at line 34, Replace negated assertTrue checks with assertFalse for clearer, idiomatic tests: change assertions like assertTrue(!fs.exists(root)) to assertFalse(fs.exists(root)), and do the same for the other occurrences using fs.exists (the instances referenced around the same test file: the assertions at the other locations that call assertTrue with a negated fs.exists). Ensure you only swap the assertion call (assertTrue(!...) -> assertFalse(...)) and keep the fs.exists(...) expression unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@svg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemDeleteRecursivelyCompatTest.kt`:
- Around line 122-126: The assertEquals call in
FileSystemDeleteRecursivelyCompatTest has its expected and actual arguments
reversed; change the parameters so expected = expectedDeletions and actual =
recorder.deletedPaths.size (i.e., swap them in the assertEquals invocation) to
ensure failure messages report the expected value correctly and reference the
correct symbols (recorder.deletedPaths.size and expectedDeletions) when updating
the test.
---
Nitpick comments:
In
`@svg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemDeleteRecursivelyCompatTest.kt`:
- Line 34: Replace negated assertTrue checks with assertFalse for clearer,
idiomatic tests: change assertions like assertTrue(!fs.exists(root)) to
assertFalse(fs.exists(root)), and do the same for the other occurrences using
fs.exists (the instances referenced around the same test file: the assertions at
the other locations that call assertTrue with a negated fs.exists). Ensure you
only swap the assertion call (assertTrue(!...) -> assertFalse(...)) and keep the
fs.exists(...) expression unchanged.
🪄 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: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 466cb1cf-b6a9-40a5-919c-d8509d2d4281
📒 Files selected for processing (8)
svg-to-compose/build.gradle.ktssvg-to-compose/src/commonMain/kotlin/dev/tonholo/s2c/extensions/FileSystem.extension.ktsvg-to-compose/src/commonMain/kotlin/dev/tonholo/s2c/extensions/LazySequence.ktsvg-to-compose/src/commonMain/kotlin/dev/tonholo/s2c/geom/ApplyTransforms.ktsvg-to-compose/src/commonMain/kotlin/dev/tonholo/s2c/io/FileManager.ktsvg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemDeleteRecursivelyCompatTest.ktsvg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/FileSystemListRecursivelyTest.ktsvg-to-compose/src/commonTest/kotlin/dev/tonholo/s2c/extensions/LazySequenceTest.kt
Summary
sequence {}builders incommonMainwith explicit stack-based iterators to preventClassNotFoundExceptionforkotlin.coroutines.jvm.internal.SpillingKtwhen running inside Gradle 8.x, which bundles an older Kotlin stdlib (pre-2.1.20)depthFirstSequenceutility for coroutine-free tree traversal, used bylistRecursivelyanddeleteRecursivelyCompatdeleteRecursivelyCompatfrom.toList().asReversed()to stack-based post-order traversal, reducing memory usage from O(n) to O(depth) for large directory treessequence {}inapplyTransformationwith an explicitIteratorto eliminate the lastSpillingKtreferenceresolveSymlinks/symlinkTargethelpers andfollowSymlinksparameterSummary by CodeRabbit