Skip to content

feat: Add Scala 3 cross-compilation support - #723

Merged
oyvindberg merged 6 commits into
masterfrom
pr/scala3-support
Sep 28, 2025
Merged

feat: Add Scala 3 cross-compilation support#723
oyvindberg merged 6 commits into
masterfrom
pr/scala3-support

Conversation

@oyvindberg

@oyvindberg oyvindberg commented Sep 28, 2025

Copy link
Copy Markdown
Collaborator

Summary

This PR adds Scala 3 cross-compilation support to the ScalablyTyped Converter, enabling the project to build and run with both Scala 2.12 and Scala 3.

Key Achievement: Deterministic Output Across Scala Versions

A major accomplishment of this PR is achieving 100% identical output when generating TypeScript bindings across Scala 2.12 and Scala 3. This ensures:

  • Consistent generated code regardless of which Scala version is used to run the converter
  • Reliable caching and artifact reuse across different Scala versions
  • Predictable behavior in CI/CD pipelines

Changes Made for Deterministic Output

1. Stable Hashing Implementation (StableHash)

  • Problem: Scala's default hashCode implementation for Product types (case classes) changed between Scala 2 and 3, causing different hash values for the same data
  • Solution: Implemented a custom StableHash utility that uses an inlined MurmurHash3 algorithm (same as Scala's default) with consistent seed values across all Scala versions
  • Impact: File names generated from hash values are now identical across Scala versions

2. Deterministic Method Renaming for Erasure Clashes (CombineOverloads)

  • Problem: When handling method overloads with erasure clashes, the order of method renaming was non-deterministic due to HashMap iteration order differences
  • Solution: Modified combineSameErasure to sort grouped methods by:
    1. Type parameter count (primary)
    2. Type parameter names concatenated (secondary)
    3. Return type qualified name (tertiary)
  • Impact: Methods with erasure clashes now receive consistent suffix names (e.g., _Props, _PropNames) regardless of Scala version

3. Library Version Hash Calculation

  • Problem: Library version strings include a hash of generated source files that was inconsistent
  • Solution: Applied StableHash to all AST nodes and data structures involved in version calculation
  • Impact: Library versions like 2.5.13-572b22 are now identical across Scala versions

Other Scala 3 Compatibility Changes

Build Configuration

  • Updated all modules to cross-compile with Scala 2.12 and Scala 3
  • Kept sbt-converter as Scala 2.12 only (SBT plugin limitation)
  • Updated CI to test all modules except sbt-converter for Scala 3

Code Compatibility

  • Resolved cross-version dependency issues

CI/CD Updates

  • Added Scala 3 to the CI matrix for all platforms (Ubuntu, macOS, Windows)
  • Modified test commands to exclude sbt-converter for Scala 3 builds
  • Reverted to standard macos-latest runners from large runners

Testing

All existing tests pass on both Scala 2.12 and Scala 3, with identical output verified for:

  • Vue.js type definitions
  • React integration tests
  • All snapshot tests in ImporterTest3

Breaking Changes

None. The converter maintains backward compatibility and produces identical output to previous versions.

Future Work

  • Consider porting sbt-converter to Scala 3 when SBT adds proper Scala 3 support for plugins
  • Further optimization of cross-compilation build times

oyvindberg and others added 2 commits September 28, 2025 16:05
- Breaking change: *use normal circe instead of the ST forked one*. This may cause downstream breakage because of sbts global class loader. You'll just have to nag other maintainers to upgrade their circe if this causes problems
- Replace gigahorse with Java's built-in HTTP client to avoid cross-version conflicts
- Fix symbol literals throughout codebase (replace 'symbol with "string")
- Fix collection conversions for Scala 2/3 compatibility
- Add parallel collections compatibility layer for tests
- Fix lambda parameter syntax for Scala 3 (add parentheses)
- Configure cross-compilation for Scala 2.12.20 and 3.3.4
- All projects except sbt-converter now support Scala 3

Co-Authored-By: Claude <[email protected]>
…scary - because it seems this name change was done years ago
Replace hashCode usage with StableHash that generates consistent hashes
across Scala 2 and Scala 3 compilations. This fixes the issue where
SharedBuilder file names would differ between Scala versions due to
unstable hashCode implementations in Scala 3.
Reverting from macos-latest-large back to macos-latest as requested.
This uses the standard 3 vCPU / 7 GB RAM runners instead of the large ones.
The sbt-converter plugin is SBT 1.x specific and only works with Scala 2.12.
Updated CI workflow to test all modules except sbt-converter when building with Scala 3.
@oyvindberg
oyvindberg merged commit 93fac4d into master Sep 28, 2025
7 checks passed
@oyvindberg
oyvindberg deleted the pr/scala3-support branch September 28, 2025 18:39
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.

1 participant