hhvmhacklang

hhvm issues \nFatal error: Uncaught Error: unknown class xhp_x__element in :\nStack trace:\n#0 /Users/user/code/xhp-js-example/example.php(12)


I'm trying to play with xhp and I'm finding that running the one xhp example I could find https://github.com/hhvm/xhp-js-example is issuing an error \nFatal error: Uncaught Error: Found top-level code in :\nStack trace:\n#0 {main} when following the README as is on HHVM 4.71. Removing require_once(__DIR__.'/vendor/autoload.php'); resolves the top-level code error but I'm now stuck with the error \nFatal error: Uncaught Error: unknown class xhp_x__element in :\nStack trace:\n#0 /Users/user/code/xhp-js-example/example.php(12): <unknown>()\n#1 {main}. I've tried to change the code in example.php to the one found here:

class :introduction extends :x:element {
  protected function render(): \XHPRoot {
    return <strong>Hello!</strong>;
  }
}

class :intro-plain-str extends :x:element {
  protected function render(): \XHPRoot {
    // Since this function returns an XHPRoot, if you want to return a primitive
    // like a string, wrap it around <x:frag>
    return <x:frag>Hello!</x:frag>;
  }
}
echo <introduction />;
echo PHP_EOL.PHP_EOL;
echo <intro-plain-str />;

since that didn't work, I also tried the simple example from here:

<?hh // strict
$user_name = 'Fred';
echo <tt>Hello <strong>{$user_name}</strong></tt>;

but altered to resolve the top-level error by wrapping it in a function and annotating it as follows:

<?hh // strict

<<__EntryPoint>>
function main(): void {
  $user_name = 'Fred';
  echo <tt>Hello <strong>{$user_name}</strong></tt>;
}

I'd get a very similar error \nFatal error: Uncaught Error: Class undefined: xhp_tt in /Users/user/code/xhp-js-example/example.php:6\nStack trace:\n#0 (): main()\n#1 {main}

Any help with getting these seemingly simple examples to work would be much appreciated since it's very painful and discouraging for trying this tech when the basic examples don't seem to run. this is using the macos package of hhvm on Catalina.

EDIT: I've also tried this without the use of xhp-js, which is included in the example repo and am getting the same error message.


Solution

  • There are a few roadblocks that the OP encountered to get XHP running with HHVM 4.62, as discussed in the comments.

    1. xhp-js and xhp-js-example are both outdated by a few years so they can't compile due to breaking changes to HHVM itself, as the OP saw.
    2. While the XHP syntax is built into Hack, all the standard implementations are provided by xhp-lib, so it is necessary to autoload that in order to use the standard library of tags and tag classes.
    3. New to HHVM 4.62 is mandatory FIXME whitelisting, which requires package writers to explicitly specify allowed HH_FIXME codes in the .hhconfig. These were added to XHP-lib in 4.0.0rc1, so this version is necessary when running on HHVM 4.62.

    Therefore, a minimal project with XHP on 4.62 looks like this:

    composer.json

    {
      "require": {
        "hhvm": "~4.62",
        "hhvm/hhvm-autoload": "^3.1.3",
        "facebook/xhp-lib": "~4.0.0rc1"
      }
    }
    

    hh_autoload.json

    { "roots": [ "src/" ] }
    

    src/example.hack

    require_once(__DIR__ . "/../vendor/hh_autoload.hh");
    <<__EntryPoint>>
    function main(): void {
      echo <div>{1 + 2}</div>;
    }