parent
a08f73c995
commit
4b8d0eb685
20 changed files with 398 additions and 73 deletions
@ -0,0 +1,7 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
function generated_code_comments(?stdClass $object): mixed |
||||||
|
{ |
||||||
|
$object?->dynamicMethod(); |
||||||
|
return $object; |
||||||
|
} |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace GeneratedCodeUseSpacing; |
||||||
|
|
||||||
|
use Example\First; |
||||||
|
use Example\Second; |
||||||
|
use Example\Third; |
||||||
|
use Example\Fourth; |
||||||
|
|
||||||
|
function createAnonymousObject(): object |
||||||
|
{ |
||||||
|
return new class { |
||||||
|
}; |
||||||
|
} |
||||||
@ -0,0 +1,149 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use TypePhp\CompilerTest; |
||||||
|
|
||||||
|
final class EmptyTranslationUnitTest extends \BaseTest |
||||||
|
{ |
||||||
|
private string $projectDir; |
||||||
|
private CompilerTest $compiler; |
||||||
|
|
||||||
|
protected function setUp(): void |
||||||
|
{ |
||||||
|
parent::setUp(); |
||||||
|
$this->projectDir = sys_get_temp_dir() . '/typephp_empty_translation_' . bin2hex(random_bytes(6)); |
||||||
|
mkdir($this->projectDir, 0777, true); |
||||||
|
|
||||||
|
global $translator; |
||||||
|
$this->compiler = CompilerTest::create($this->projectDir); |
||||||
|
$translator = $this->compiler; |
||||||
|
} |
||||||
|
|
||||||
|
protected function tearDown(): void |
||||||
|
{ |
||||||
|
$this->removeDirectory($this->projectDir); |
||||||
|
parent::tearDown(); |
||||||
|
} |
||||||
|
|
||||||
|
public function testTraitOnlySourceIsNotAddedToCompilation(): void |
||||||
|
{ |
||||||
|
$trait = $this->writeSource('CompileTimeOnlyTrait.php', <<<'PHP' |
||||||
|
<?php |
||||||
|
|
||||||
|
trait CompileTimeOnlyTrait |
||||||
|
{ |
||||||
|
public function answer(): int |
||||||
|
{ |
||||||
|
return 42; |
||||||
|
} |
||||||
|
} |
||||||
|
PHP); |
||||||
|
$program = $this->writeSource('program.php', <<<'PHP' |
||||||
|
<?php |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
} |
||||||
|
PHP); |
||||||
|
|
||||||
|
$files = [$trait, $program]; |
||||||
|
$this->compiler->addFiles($files); |
||||||
|
foreach ($files as $file) { |
||||||
|
$this->compiler->prepareFile($file); |
||||||
|
} |
||||||
|
|
||||||
|
$traitCpp = $this->compiler->getCppFile($trait); |
||||||
|
$traitObject = $this->compiler->getObjectFile($traitCpp); |
||||||
|
if (!is_dir(dirname($traitCpp))) { |
||||||
|
mkdir(dirname($traitCpp), 0777, true); |
||||||
|
} |
||||||
|
file_put_contents($traitCpp, 'stale translation unit'); |
||||||
|
file_put_contents($traitObject, 'stale object'); |
||||||
|
file_put_contents($traitObject . '.typephp-cache', 'stale metadata'); |
||||||
|
|
||||||
|
$sources = $this->compiler->convert($files); |
||||||
|
|
||||||
|
self::assertNotContains($traitCpp, $sources); |
||||||
|
self::assertContains($this->compiler->getCppFile($program), $sources); |
||||||
|
self::assertFileDoesNotExist($traitCpp); |
||||||
|
self::assertFileDoesNotExist($traitObject); |
||||||
|
self::assertFileDoesNotExist($traitObject . '.typephp-cache'); |
||||||
|
self::assertFileExists($this->compiler->getArgInfoHeaderFile($trait)); |
||||||
|
} |
||||||
|
|
||||||
|
public function testFileContainingTraitAndFunctionStillEmitsTranslationUnit(): void |
||||||
|
{ |
||||||
|
$source = $this->writeSource('mixed.php', <<<'PHP' |
||||||
|
<?php |
||||||
|
|
||||||
|
trait MixedDeclarationTrait |
||||||
|
{ |
||||||
|
public function value(): int |
||||||
|
{ |
||||||
|
return 1; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function mixedDeclarationFunction(): int |
||||||
|
{ |
||||||
|
return 7; |
||||||
|
} |
||||||
|
PHP); |
||||||
|
|
||||||
|
$this->compiler->addFiles([$source]); |
||||||
|
$this->compiler->prepareFile($source); |
||||||
|
$cppFile = $this->compiler->convertFile($source); |
||||||
|
|
||||||
|
self::assertNotNull($cppFile); |
||||||
|
self::assertFileExists($cppFile); |
||||||
|
self::assertStringContainsString('return php::toInt(7L);', file_get_contents($cppFile)); |
||||||
|
} |
||||||
|
|
||||||
|
public function testCompileTimeOnlyLibraryStillEmitsExtensionSource(): void |
||||||
|
{ |
||||||
|
$source = $this->writeSource('LibraryTrait.php', <<<'PHP' |
||||||
|
<?php |
||||||
|
|
||||||
|
trait LibraryTrait |
||||||
|
{ |
||||||
|
public function value(): int |
||||||
|
{ |
||||||
|
return 1; |
||||||
|
} |
||||||
|
} |
||||||
|
PHP); |
||||||
|
|
||||||
|
$this->compiler->setBuildMode('lib'); |
||||||
|
$this->compiler->setOutputPath($this->projectDir . '/app'); |
||||||
|
$this->compiler->addFiles([$source]); |
||||||
|
$this->compiler->prepareFile($source); |
||||||
|
$sources = $this->compiler->convert([$source]); |
||||||
|
|
||||||
|
self::assertCount(1, $sources); |
||||||
|
self::assertStringContainsString('extension-app.cc', $sources[0]); |
||||||
|
self::assertFileExists($sources[0]); |
||||||
|
self::assertFileDoesNotExist($this->compiler->getCppFile($source)); |
||||||
|
} |
||||||
|
|
||||||
|
private function writeSource(string $name, string $source): string |
||||||
|
{ |
||||||
|
$file = $this->projectDir . '/' . $name; |
||||||
|
file_put_contents($file, $source); |
||||||
|
return $file; |
||||||
|
} |
||||||
|
|
||||||
|
private function removeDirectory(string $directory): void |
||||||
|
{ |
||||||
|
if (!is_dir($directory)) { |
||||||
|
return; |
||||||
|
} |
||||||
|
foreach (array_diff(scandir($directory), ['.', '..']) as $entry) { |
||||||
|
$path = $directory . '/' . $entry; |
||||||
|
if (is_dir($path)) { |
||||||
|
$this->removeDirectory($path); |
||||||
|
} else { |
||||||
|
unlink($path); |
||||||
|
} |
||||||
|
} |
||||||
|
rmdir($directory); |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,66 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
use TypePhp\CompilerTest; |
||||||
|
|
||||||
|
final class GeneratedCodeCommentTest extends BaseTest |
||||||
|
{ |
||||||
|
private function compileProbe(bool $debug): string |
||||||
|
{ |
||||||
|
global $translator; |
||||||
|
|
||||||
|
$compiler = CompilerTest::create(ROOT_PATH); |
||||||
|
$translator = $compiler; |
||||||
|
if ($debug) { |
||||||
|
$property = new ReflectionProperty($compiler, 'debug'); |
||||||
|
$property->setValue($compiler, true); |
||||||
|
} |
||||||
|
|
||||||
|
$source = ROOT_PATH . '/phpunit/code/generated-code-comments.php'; |
||||||
|
$compiler->addFiles([$source]); |
||||||
|
$compiler->prepareFile($source); |
||||||
|
$generated = $compiler->convertFile($source); |
||||||
|
$code = file_get_contents($generated); |
||||||
|
self::assertIsString($code); |
||||||
|
return $code; |
||||||
|
} |
||||||
|
|
||||||
|
private function compileFile(string $file): string |
||||||
|
{ |
||||||
|
global $translator; |
||||||
|
|
||||||
|
$compiler = CompilerTest::create(ROOT_PATH); |
||||||
|
$translator = $compiler; |
||||||
|
$source = ROOT_PATH . '/phpunit/code/' . $file; |
||||||
|
$compiler->addFiles([$source]); |
||||||
|
$compiler->prepareFile($source); |
||||||
|
$generated = $compiler->convertFile($source); |
||||||
|
self::assertNotNull($generated); |
||||||
|
$code = file_get_contents($generated); |
||||||
|
self::assertIsString($code); |
||||||
|
return $code; |
||||||
|
} |
||||||
|
|
||||||
|
public function testReleaseCodeOmitsCompilerExplanatoryComments(): void |
||||||
|
{ |
||||||
|
$code = $this->compileProbe(false); |
||||||
|
|
||||||
|
self::assertStringNotContainsString('// Stmt_', $code); |
||||||
|
self::assertStringNotContainsString('// Nullsafe Operator:', $code); |
||||||
|
self::assertStringNotContainsString('// Method Call:', $code); |
||||||
|
} |
||||||
|
|
||||||
|
public function testDebugCodeKeepsCompilerExplanatoryComments(): void |
||||||
|
{ |
||||||
|
$code = $this->compileProbe(true); |
||||||
|
|
||||||
|
self::assertStringContainsString('// Stmt_', $code); |
||||||
|
self::assertStringContainsString('// Nullsafe Operator:', $code); |
||||||
|
} |
||||||
|
|
||||||
|
public function testCompileTimeUseDeclarationsDoNotEmitBlankLines(): void |
||||||
|
{ |
||||||
|
$code = $this->compileFile('generated-code-use-spacing.php'); |
||||||
|
|
||||||
|
self::assertDoesNotMatchRegularExpression('/0,};(?:[ \t]*\R){3,}/', $code); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue