Skip to content

v0.2.1

Choose a tag to compare

@math3usmartins math3usmartins released this 17 Jun 19:05
· 8 commits to main since this release
b39788e

What's Changed

Two high-impact defects are fixed:

  1. the CLI now runs correctly when xphp is installed as a Composer dependency
  2. specialized generics no longer break at autoload when they reference imported built-in classes or
    interfaces.

The rest of the release hardens test coverage and documentation for behavior that already shipped in 0.2.0.

No language or API changes; upgrading is drop-in.

Bug fixes

CLI runs when installed as a dependency

vendor/bin/xphp failed at startup for every project that installed xphp as a
(dev) dependency:

Fatal error: Failed opening required '.../vendor/xphp-lang/xphp/vendor/autoload.php'

The entrypoint hardcoded a path to its own vendor/autoload.php, which only
exists in a standalone checkout. It now locates Composer's autoloader across all
install layouts — the bin-proxy path, the consuming project's
vendor/autoload.php, and a standalone checkout (the path the bundled PHAR also
uses) — and prints a clear, non-fatal message if none can be found.

Impact: the documented workflow (vendor/bin/xphp compile …, build scripts, CI)
now works for downstream consumers, not just inside this repository.

Specialized generics keep imported class/interface references valid

When a generic was specialized, its declaration was lifted into a generated
namespace, but bare class/interface names that relied on the source file's use
imports were copied verbatim. They then resolved into the generated namespace and
threw at load time:

Fatal error: Interface "XPHP\Generated\…\Countable" not found

This affected any template that, via an imported (unqualified) name:

  • extends / implements a built-in interface (Countable, IteratorAggregate,
    Traversable, ArrayAccess, …),
  • instantiates an imported class (new ArrayIterator(…)),
  • catches an imported exception (catch (SomeException $e)),
  • or references one in a property, parameter, return, union/nullable, or
    constant type hint.

The compiler now fully-qualifies every such non-generic reference when it emits a
specialized class, so the generated code is import-independent and loads cleanly.
Failures were silent at compile time and only surfaced on first autoload.

Upgrade note: the previous workaround — writing global/built-in names
fully-qualified with a leading \ in .xphp sources — is no longer required.
Existing fully-qualified names keep working unchanged.

Testing & tooling

  • Added a dedicated PHP 8.5 test runtime (container + CI group) and coverage for
    the PHP 8.5 pipe operator (|>) passing through the transpiler untouched.
  • Added end-to-end regression coverage for catching exceptions by generic
    specialization.
  • Added regression coverage for the two fixes above: a CLI bootstrap test that
    drives the binary in standalone, installed-as-dependency, and missing-autoloader
    layouts; and a fixture exercising generics that extend/implement built-ins and
    use imported classes in new / catch / type-hint positions.

Documentation

  • Documented catching exceptions via generic specialization and PHP 8.5
    syntax pass-through.
  • Fixed a broken README example and an incorrect cache-path reference.
  • Expanded the caveats guide and tidied the roadmap.

Full Changelog: v0.2.0...v0.2.1