refactor(compiler): standardize extension prefix handling and improve internal symbol detection

- Introduce EXTENSION_PREFIX constant in Constants class
- Add isTypePhpExtension method to Reflection class for proper extension identification
- Update getModuleName to use standardized extension prefix
- Modify internal class and interface detection to exclude TypePHP extension symbols
- Refactor internal functions loading to filter out TypePHP extension functions
- Remove deprecated ignoreExtensions property and related regex parsing logic
- Update version from 0.4.1 to 0.4.2
- Add test case to verify zend module always uses typephp prefix
pull/40/head
韩天峰 1 month ago
parent b51da46c5a
commit 9d29aa7a3f
  1. 9
      phpunit/src/CompilerBaseApiTest.php
  2. 2
      src/Metadata/Constants.php
  3. 15
      src/Resolver/Reflection.php
  4. 23
      src/Translator.php
  5. 2
      version.txt

@ -437,6 +437,15 @@ YAML, 'myproject.yml', 'examples/tetris-sdl');
$this->assertSame('demo.so', $this->invokeMethod('getTargetFileName'));
}
public function testGeneratedZendModuleAlwaysUsesTypePhpPrefix(): void
{
$this->compiler->setTargetName('demo');
$this->assertSame('typephp_demo', $this->compiler->getModuleName());
$this->compiler->setTargetName('123');
$this->assertSame('typephp_123', $this->compiler->getModuleName());
}
public function testParseProjectYamlResolvesRelativePathOptionsAgainstYamlDirectory(): void
{
$projectFile = $this->createProjectFile(<<<'YAML'

@ -12,6 +12,8 @@ use TypePhp\CompilerBase;
class Constants
{
public const string EXTENSION_PREFIX = 'typephp_';
public const array CPP_RESERVED_NAMES = [
'alignas',
'alignof',

@ -8,12 +8,20 @@
namespace TypePhp\Resolver;
use TypePhp\Metadata\Constants;
class Reflection
{
private static array $functions = [];
private static array $classes = [];
private static array $interfaces = [];
public static function isTypePhpExtension(mixed $extensionName): bool
{
return is_string($extensionName)
&& str_starts_with($extensionName, Constants::EXTENSION_PREFIX);
}
public static function isInternalClass(string $class): bool
{
static $internalClasses = null;
@ -25,7 +33,10 @@ class Reflection
foreach ($allClasses as $className) {
try {
$ref = new \ReflectionClass($className);
if ($ref->isInternal()) {
$extensionName = $ref->getExtensionName();
// Classes registered by the host AOT binary are implementation
// details, not built-ins of the target PHP environment.
if ($ref->isInternal() && !self::isTypePhpExtension($extensionName)) {
$internalClasses[strtolower($className)] = true;
}
} catch (\ReflectionException) {
@ -47,7 +58,7 @@ class Reflection
foreach ($allInterfaces as $interfaceName) {
try {
$ref = new \ReflectionClass($interfaceName);
if ($ref->isInternal()) {
if ($ref->isInternal() && !self::isTypePhpExtension($ref->getExtensionName())) {
$internalInterfaces[strtolower($interfaceName)] = true;
}
} catch (\ReflectionException) {

@ -58,9 +58,8 @@ class Translator extends Preprocessor
use ResourceCompilationTrait;
use ClassConstantValueTrait;
public const string VERSION = '0.4.1';
public const string VERSION = '0.4.2';
public const string APP_NAME = 'TypePHP Compiler (AOT)';
protected const string MODULE_NAME_PREFIX = 'app_';
protected string $targetName = 'app';
protected bool $hasExplicitOutput = false;
@ -71,7 +70,6 @@ class Translator extends Preprocessor
protected bool $verbose = false;
protected array $phpSrcFiles = [];
protected array $ignorePaths = [];
protected array $ignoreExtensions = [];
protected array $argInfoHeaderFiles = [];
protected array $registerSymbols = [];
@ -108,7 +106,14 @@ class Translator extends Preprocessor
// 只读取命令行参数,不立即应用(等待 YAML 解析后再应用)
// 这样可以确保优先级:命令行 > YAML > 默认值
$this->internalFunctions = array_flip(get_defined_functions()['internal']);
$this->internalFunctions = [];
foreach (get_defined_functions()['internal'] as $functionName) {
$function = Reflection::getFunction($functionName);
if ($function !== null && Reflection::isTypePhpExtension($function->getExtensionName())) {
continue;
}
$this->internalFunctions[$functionName] = true;
}
unset($this->internalFunctions[self::ENTRY_FUNCTION]);
$this->internalConstants = $this->loadInternalConstants();
if ($this->climate->arguments->defined('help')) {
@ -140,7 +145,9 @@ class Translator extends Preprocessor
$constants = [];
foreach ($groups as $groupName => $group) {
// 编译器进程中的用户常量属于被编译程序的运行时状态,不能在静态阶段展开。
if (strcasecmp((string) $groupName, 'user') === 0 || !is_array($group)) {
if (strcasecmp((string) $groupName, 'user') === 0
|| Reflection::isTypePhpExtension($groupName)
|| !is_array($group)) {
continue;
}
foreach ($group as $name => $value) {
@ -1086,7 +1093,7 @@ CODE;
public function getModuleName(): string
{
return self::MODULE_NAME_PREFIX . $this->targetName;
return Constants::EXTENSION_PREFIX . $this->targetName;
}
/**
@ -2211,10 +2218,6 @@ CODE;
$this->error('`ignore` must be array');
}
foreach ($ignore as $src) {
if (preg_match('/ext-([a-z0-9_]+)/i', $src, $matches)) {
$this->ignoreExtensions[] = $matches[1];
continue;
}
$realPath = $this->getAbsolutePath($src, $projectDir);
if (!$realPath) {
$this->error('Source file not exists: `' . $src . '`');

@ -1 +1 @@
1087
1088

Loading…
Cancel
Save