Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge module.xp and autoload.php #319

Open
thekid opened this issue Jan 15, 2017 · 7 comments
Open

Merge module.xp and autoload.php #319

thekid opened this issue Jan 15, 2017 · 7 comments

Comments

@thekid
Copy link
Member

thekid commented Jan 15, 2017

Scope of Change

This RFC suggests merging the special file module.xp into autoload.php created for Composer loading purposes.

Rationale

  • Consistent autoloading whether Composer is used or not; less I/O for the case it is.
  • Syntax-checkable module initialization code
  • Removed confusion with .xp source code from XP Compiler (phase 2)
  • Near zero cost for runtime module reflection (once libraries include module definitions)

Functionality

Current situation

Typical autoload.php file:

<?php namespace xp;

\lang\ClassLoader::registerPath(__DIR__);

An example module.xp:

<?php namespace com\example;

module xp-forge/example {
  public function initialize() {
    echo "Loaded module ", $this->name(), "\n";
  }
}

Implementation

Code inside autoload.php

<?php namespace com\example;

use lang\ClassLoader;

ClassLoader::registerPath(__DIR__, false,'xp-forge/patterns', [
  'initialize' => function() {
    echo '(autoload.php) Loaded module ', $this->name(), "\n";
  }
]);

Loading

  • During composer loading, autoload.php is loaded via autoload -> files from composer.json
  • During XP bootstrapping, autoload.php would be discovered when registering a path. If a module definition is existant, no module.xp file would be checked for.

Phases

  1. XP9.0. No BC breaks exist. You can start using the new layout alongside the old one.
  2. XP10.0. The file module.xp is deprecated, code needs to be migrated to the new layout

See also Transition below.

Security considerations

n/a

Speed impact

Slightly slower for the non-Composer case, since autoload.php files weren't being loaded.

Dependencies

None.

Related documents

@thekid thekid added this to the 9.0.0-RELEASE milestone Jan 15, 2017
@thekid
Copy link
Member Author

thekid commented Jan 15, 2017

Transition

This describes the various filesystem layouts and where module definitions are loaded from.

TL;DR:

If you don't use modules, no need for any action. If you do:

  • If your library requires compatibility with XP < 9.0, use the BC module layout
  • Otherwise use the new module layout only providing autoload.php

Basic Layout

Contains src/main/php/autoload.php

XP8.1 XP8.1 + Composer XP9.0 (+Composer) XP10.0 (+Composer)
Files loaded (none) autoload autoload autoload
Module definition (none) (none) (none) (none)

Classic module layout

Contains src/main/php/autoload.php and src/main/php/module.xp

XP8.1 XP8.1 + Composer XP9.0 (+Composer) XP10.0 (+Composer)
Files loaded module autoload, module autoload, module autoload
Module definition module module module (none) ⚠️

New module layout

Contains src/main/php/autoload.php which defines $module.

XP8.1 XP8.1 + Composer XP9.0 (+Composer) XP10.0 (+Composer)
Files loaded (none) autoload autoload autoload
Module definition (none) (none) autoload autoload

BC module layout

Contains src/main/php/autoload.php which defines $module and src/main/php/module.xp for BC reasons. Note you need to maintain the module code twice in both files!

XP8.1 XP8.1 + Composer XP9.0 (+Composer) XP10.0 (+Composer)
Files loaded module autoload, module autoload autoload
Module definition module module autoload autoload

@thekid
Copy link
Member Author

thekid commented Jan 15, 2017

Example of transition to new functionality:

diff --git a/src/main/php/autoload.php b/src/main/php/autoload.php
index 832c1dd..89375e3 100755
--- a/src/main/php/autoload.php
+++ b/src/main/php/autoload.php
@@ -1,3 +1,18 @@
-<?php namespace xp;
+<?php namespace xp\compiler;

-\lang\ClassLoader::registerPath(__DIR__);
\ No newline at end of file
+use lang\ClassLoader;
+use lang\reflect\Package;
+
+define('MODIFIER_PACKAGE',  2048);
+define('MODIFIER_INLINE',   4096);
+define('MODIFIER_NATIVE',   8192);
+define('DETAIL_PROPERTY',      0);
+
+ClassLoader::registerPath(__DIR__, false, 'xp-framework/compiler', [
+
+  /** @return void */
+  'initialize' => function() {
+    Syntax::registerAll(Package::forName('xp.compiler.syntax')->getPackages());
+    ClassLoader::registerLoader(JitClassLoader::instanceFor(realpath('.')), true);
+  }
+]);

@thekid
Copy link
Member Author

thekid commented Jan 16, 2017

For phase 2, the xp -v output could be changed to show modules instead of class path entries:

$ git diff
diff --git a/src/main/php/xp/runtime/Version.class.php b/src/main/php/xp/runtime/Version.class.php
index c210000..7d950b1 100755
--- a/src/main/php/xp/runtime/Version.class.php
+++ b/src/main/php/xp/runtime/Version.class.php
@@ -1,6 +1,7 @@
 <?php namespace xp\runtime;

 use util\cmd\Console;
+use lang\reflect\Module;

 /**
  * Displays XP version and runtime information
@@ -43,15 +44,15 @@ class Version {
   public static function main(array $args) {
     if (empty($args)) {
       Console::writeLinef(
-        'XP %s { PHP %s & ZE %s } @ %s',
+        "\e[37;1mXP %s { PHP %s & ZE %s } @ %s\e[0m",
         \xp::version(),
         phpversion(),
         zend_version(),
         php_uname()
       );
-      Console::writeLine('Copyright (c) 2001-2016 the XP group');
-      foreach (\lang\ClassLoader::getLoaders() as $delegate) {
-        Console::writeLine($delegate->toString());
+      Console::writeLine('Copyright (c) 2001-2017 the XP group');
+      foreach (Module::$registered as $module) {
+        Console::writeLine($module->name(), "\e[32m: ", $module->classLoader()->toString(), "\e[0m");
       }
       return 1;
     } else {

@thekid
Copy link
Member Author

thekid commented Jan 16, 2017

💡 How about also moving autoload.php from src/main/php to the root directory?

<?php namespace com\example;

use lang\ClassLoader;

ClassLoader::registerPath('src/main/php', false,'xp-forge/patterns', [
  'initialize' => function() {
    echo '(autoload.php) Loaded module ', $this->name(), "\n";
  }
]);

@thekid
Copy link
Member Author

thekid commented Jun 3, 2017

Libraries cannot drop module.xp until they require xp-framework/core 9.0.0 as minimum. Maybe it would be good if 8.x and 7.x would add forward-compatible support for this (7.9.0, 8.3.0) - then library authors could do this:

- "xp-framework/core": "^9.0 | ^8.0 | ^7.0"
+ "xp-framework/core": "^9.0 | ^8.3 | ^7.9"

...and still support XP7 - it's the last version with PHP 5.6 support, necessary for running on Debian Jessie, which bundles this version of PHP by default.

@thekid
Copy link
Member Author

thekid commented Jun 17, 2017

How about also moving autoload.php from src/main/php to the root directory?

It wouldn't be picked up by direct references via class.pth, then:

# Include this library
../inject/src/main/php/

So first we should either start putting module references there, see xp-runners/main#5 or reference autoload.php directly

# Local path and file references
src/autoload.php

# Dependencies, composer-style
?vendor/autoload.php

# Directly referencing dependencies, e.g. during development
../xp/inject/src/autoload.php

The autoload.php files would then:

<?php namespace inject;

use lang\ClassLoader;

ClassLoader::registerPath('src/main/php', false, 'xp-forge/inject', [
  'initialize' => function() {
    echo '(autoload.php) Loaded module ', $this->name(), "\n";
  }
]);
ClassLoader::registerPath('src/test/php', false, 'xp-forge/inject@test');

@thekid
Copy link
Member Author

thekid commented Jun 17, 2017

...or maybe even a file src/module.php, with the following:

<?php namespace inject;

use lang\ClassLoader;

ClassLoader::registerModule(__DIR__, 'xp-forge/inject', ['main/php', 'test/php'], [
  'initialize' => function() {
    echo '(autoload.php) Loaded module ', $this->name(), "\n";
  }
]);

@thekid thekid modified the milestones: 9.0.0-RELEASE, 9.1.0-RELEASE Sep 24, 2017
@thekid thekid removed this from the 9.1.0-RELEASE milestone Apr 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant