Back to Kilocode

Plan: Replace Internal SVGLoader Usage

.kilo/plans/1779987162764-misty-rocket.md

7.3.185.1 KB
Original Source

Plan: Replace Internal SVGLoader Usage

Context

The JetBrains plugin currently imports com.intellij.util.SVGLoader in packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/SvgIconColorizer.kt and calls SVGLoader.load(ByteArrayInputStream(patch()), scale.toFloat()) from SvgIcon.image(Graphics).

Inspection reports this as an internal API usage because SVGLoader and its load(InputStream, float) method are marked @ApiStatus.Internal.

I checked the local IntelliJ source reference via $INTELLIJ_REPO=/Users/kirillk/products/intellij-community:

  • platform/util/ui/src/com/intellij/util/SVGLoader.kt
  • platform/util/ui/src/com/intellij/ui/svg/svg.kt
  • platform/util/ui/src/com/intellij/ui/svg/jsvg.kt
  • libraries/jsvg/intellij.libraries.jsvg.iml

Important findings:

  • IntelliJ SVGLoader.load(stream, scale) delegates to internal loadSvg(...) in com.intellij.ui.svg.
  • The actual renderer uses com.github.weisj:jsvg:2.1.0 and renders into a BufferedImage with antialiasing, bicubic interpolation, and pure stroke control.
  • Copying SVGLoader.kt directly would keep references to other internal IntelliJ APIs (IconLoader, ScaleContext, ImageUtil, SvgAttributePatcher, createJSvgDocument, renderSvgWithSize, cache classes, etc.) and would be broader than needed.

Implementation Plan

  1. Add Kilo-owned SVG rendering code under the frontend UI package, for example:

    • packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/ui/SvgLoader.kt
    • Package: ai.kilocode.client.ui
    • Suggested internal object name: SvgLoader
  2. Keep the copied implementation minimal and purpose-specific:

    • Accept InputStream and scale: Float.
    • Parse the SVG with com.github.weisj.jsvg.parser.SVGLoader().load(stream) or the equivalent public jsvg API available in version 2.1.0.
    • Determine image dimensions from the root SVG width and height already parsed by existing SvgIconColorizer.size(...), or by passing dimensions into the loader if the public jsvg API does not expose reliable intrinsic size.
    • Render into BufferedImage(width * scale, height * scale, BufferedImage.TYPE_INT_ARGB) using Graphics2D rendering hints matching IntelliJ’s jsvg.kt:
      • KEY_ANTIALIASING = VALUE_ANTIALIAS_ON
      • KEY_INTERPOLATION = VALUE_INTERPOLATION_BICUBIC
      • KEY_STROKE_CONTROL = VALUE_STROKE_PURE
    • Return Image/BufferedImage.
  3. If jsvg does not expose intrinsic size cleanly from public API, adjust the API to avoid duplicating SVG parsing:

    • Add width and height parameters to the Kilo loader.
    • In SvgIcon.image(Graphics), call the loader with the already-computed size.first and size.second.
    • This is the likely smallest stable solution because current icons already require explicit width and height for SvgIconColorizer.size(...).
  4. Add the jsvg dependency explicitly to the plugin frontend module instead of relying on the IntelliJ-bundled library:

    • In packages/kilo-jetbrains/gradle/libs.versions.toml, add jsvg = "2.1.0" and jsvg = { module = "com.github.weisj:jsvg", version.ref = "jsvg" }.
    • In packages/kilo-jetbrains/frontend/build.gradle.kts, add implementation(libs.jsvg).
    • This follows the package instruction to bundle third-party libraries with the plugin rather than relying on IDE-bundled versions.
  5. Update SvgIconColorizer.kt:

    • Remove import com.intellij.util.SVGLoader.
    • Replace SVGLoader.load(ByteArrayInputStream(patch()), scale.toFloat()) with the Kilo-owned loader call.
    • Keep the existing color patching, cache key, scale calculation, and size parsing intact.
  6. Add a focused frontend unit test:

    • New test file: frontend/src/test/kotlin/ai/kilocode/client/ui/SvgIconColorizerTest.kt or SvgLoaderTest.kt.
    • Exercise the actual loader/colorizer with a small SVG resource or inline SVG bytes.
    • Assert that rendering returns a non-empty image at scale 1f and 2f, and that scaled dimensions are correct.
    • If testing the colorizer, paint the icon into a BufferedImage and verify at least one expected patched pixel color appears.
  7. Run verification from packages/kilo-jetbrains/:

    • ./gradlew typecheck
    • A targeted frontend test if Gradle supports one cleanly, otherwise ./gradlew test.
    • The requested DevKit internal API inspection is IDE-based; note in final response that the code no longer references com.intellij.util.SVGLoader, and typecheck/tests were run.

Notes And Risks

  • The user said “copy SaveLoaer”; I interpret this as “copy SVGLoader”. The implementation should copy the relevant rendering behavior, not IntelliJ’s full internal SVGLoader object, because the full source depends on multiple other internal APIs and cache infrastructure.
  • This change is in packages/kilo-jetbrains/, a Kilo-owned package, so kilocode_change markers are not needed.
  • jsvg package names and constructors should be confirmed during implementation against the downloaded dependency/API available to Gradle. If the API differs from IntelliJ source usage, inspect the source jar or compile error and adapt the minimal wrapper accordingly.