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

#2321 - Fix private callback visibility #2325

Draft
wants to merge 14 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions Library/AbstractCompilerFile.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

/**
* This file is part of the Zephir.
*
* (c) Phalcon Team <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir;

abstract class AbstractCompilerFile
{
/**
* @var string|null
*/
protected ?string $compiledFile = null;

/**
* @var bool
*/
protected bool $external = false;

/**
* Returns the path to the compiled file.
*
* @return string|null
*/
public function getCompiledFile(): ?string
{
return $this->compiledFile;
}

/**
* @return bool
*/
public function isExternal(): bool
{
return $this->external;
}

/**
* Sets if the class belongs to an external dependency or not.
*
* @param mixed $external
*/
public function setIsExternal($external): void
{
$this->external = (bool) $external;
}

/**
* Compiles the file.
*
* @param Compiler $compiler
* @param StringsManager $stringsManager
*/
abstract public function compile(Compiler $compiler, StringsManager $stringsManager): void;
}
13 changes: 8 additions & 5 deletions Library/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ public function generate(bool $fromGenerate = false): bool
$files = [];

$hash = '';
/** @var AbstractCompilerFile $compileFile */
foreach ($this->files as $compileFile) {
/**
* Only compile classes in the local extension, ignore external classes
Expand All @@ -771,6 +772,7 @@ public function generate(bool $fromGenerate = false): bool
/**
* Round 3.2. Compile anonymous classes
*/
/** @var AbstractCompilerFile $compileFile */
foreach ($this->anonymousFiles as $compileFile) {
$compileFile->compile($this, $this->stringManager);
$compiledFile = $compileFile->getCompiledFile();
Expand Down Expand Up @@ -1314,13 +1316,13 @@ public function processExtensionGlobals(string $namespace): array
* Process compound structures
*/
foreach ($structures as $structureName => $internalStructure) {
if (preg_match('/^[0-9a-zA-Z\_]$/', $structureName)) {
if (preg_match('/^[0-9a-zA-Z_]$/', $structureName)) {
throw new Exception("Struct name: '".$structureName."' contains invalid characters");
}

$structBuilder = new Struct('_zephir_struct_'.$structureName, $structureName);
foreach ($internalStructure as $field => $global) {
if (preg_match('/^[0-9a-zA-Z\_]$/', $field)) {
if (preg_match('/^[0-9a-zA-Z_]$/', $field)) {
throw new Exception("Struct field name: '".$field."' contains invalid characters");
}

Expand All @@ -1343,7 +1345,7 @@ public function processExtensionGlobals(string $namespace): array
* Process single variables
*/
foreach ($variables as $name => $global) {
if (preg_match('/^[0-9a-zA-Z\_]$/', $name)) {
if (preg_match('/^[0-9a-zA-Z_]$/', $name)) {
throw new Exception("Extension global variable name: '".$name."' contains invalid characters");
}

Expand Down Expand Up @@ -2165,11 +2167,12 @@ private function loadConstantsSources(array $constantsSources)
}

foreach (file($constantsSource) as $line) {
if (preg_match('/^\#define[ \t]+([A-Z0-9\_]+)[ \t]+([0-9]+)/', $line, $matches)) {
if (preg_match('/^#define[ \t]+([A-Z0-9_]+)[ \t]+([0-9]+)/', $line, $matches)) {
$this->constants[$matches[1]] = ['int', $matches[2]];
continue;
}
if (preg_match('/^\#define[ \t]+([A-Z0-9\_]+)[ \t]+(\'(.){1}\')/', $line, $matches)) {

if (preg_match('/^#define[ \t]+([A-Z0-9_]+)[ \t]+(\'(.)\')/', $line, $matches)) {
$this->constants[$matches[1]] = ['char', $matches[3]];
}
}
Expand Down
128 changes: 47 additions & 81 deletions Library/CompilerFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
use Zephir\Exception\ParseException;
use Zephir\FileSystem\FileSystemInterface;

use function count;
use function dirname;
use function is_array;

/**
* This class represents every file compiled in a project.
* Every file may contain a class or an interface.
*/
final class CompilerFile implements FileInterface
final class CompilerFile extends AbstractCompilerFile implements FileInterface
{
use LoggerAwareTrait;

Expand All @@ -48,11 +50,6 @@ final class CompilerFile implements FileInterface
*/
private ?string $filePath = null;

/**
* @var bool
*/
private bool $external = false;

/**
* Original internal representation (IR) of the file.
*
Expand All @@ -65,11 +62,6 @@ final class CompilerFile implements FileInterface
*/
private $originalNode;

/**
* @var string|null
*/
private ?string $compiledFile = null;

/**
* @var ClassDefinition|null
*/
Expand Down Expand Up @@ -135,40 +127,20 @@ public function setClassName(string $className)
}

/**
* {@inheritdoc}
*
* @return ClassDefinition
* @return ClassDefinition|null
*/
public function getClassDefinition()
public function getClassDefinition(): ?ClassDefinition
{
$this->classDefinition->setAliasManager($this->aliasManager);

return $this->classDefinition;
}

public function getFunctionDefinitions()
public function getFunctionDefinitions(): array
{
return $this->functionDefinitions;
}

/**
* Sets if the class belongs to an external dependency or not.
*
* @param bool $external
*/
public function setIsExternal($external): void
{
$this->external = (bool) $external;
}

/**
* @return bool
*/
public function isExternal(): bool
{
return $this->external;
}

/**
* Adds a function to the function definitions.
*
Expand Down Expand Up @@ -244,6 +216,7 @@ public function compileClass(CompilationContext $compilationContext): void
*
* @param CompilationContext $compilationContext
* @param FunctionDefinition $functionDefinition
* @throws Exception
*/
public function compileFunction(CompilationContext $compilationContext, FunctionDefinition $functionDefinition)
{
Expand All @@ -269,7 +242,7 @@ public function compileFunction(CompilationContext $compilationContext, Function
* @param CompilationContext $compilationContext
* @param array $topStatement
*/
public function compileComment(CompilationContext $compilationContext, $topStatement)
public function compileComment(CompilationContext $compilationContext, array $topStatement): void
{
$compilationContext->codePrinter->output('/'.$topStatement['value'].'/');
}
Expand All @@ -278,10 +251,10 @@ public function compileComment(CompilationContext $compilationContext, $topState
* Creates a definition for an interface.
*
* @param string $namespace
* @param array $topStatement
* @param array $docblock
* @param array $topStatement
* @param array|null $docblock
*/
public function preCompileInterface($namespace, $topStatement, $docblock)
public function preCompileInterface(string $namespace, array $topStatement, ?array $docblock = null)
{
$classDefinition = new ClassDefinition($namespace, $topStatement['name']);
$classDefinition->setIsExternal($this->external);
Expand Down Expand Up @@ -343,11 +316,11 @@ public function preCompileInterface($namespace, $topStatement, $docblock)
* Creates a definition for a class.
*
* @param CompilationContext $compilationContext
* @param string $namespace
* @param array $topStatement
* @param array $docblock
* @param string $namespace
* @param array $topStatement
* @param array|null $docblock
*/
public function preCompileClass(CompilationContext $compilationContext, $namespace, $topStatement, $docblock)
public function preCompileClass(CompilationContext $compilationContext, string $namespace, array $topStatement, ?array $docblock = null)
{
$classDefinition = new ClassDefinition($namespace, $topStatement['name']);
$classDefinition->setIsExternal($this->external);
Expand Down Expand Up @@ -637,16 +610,6 @@ public function preCompile(Compiler $compiler)
$this->ir = $ir;
}

/**
* Returns the path to the compiled file.
*
* @return string
*/
public function getCompiledFile(): string
{
return $this->compiledFile;
}

/**
* Check dependencies.
*
Expand Down Expand Up @@ -712,24 +675,28 @@ public function checkDependencies(Compiler $compiler)
foreach ($classDefinition->getImplementedInterfaces() as $interface) {
if ($compiler->isInterface($interface)) {
$interfaceDefinitions[$interface] = $compiler->getClassDefinition($interface);
} else {
if ($compiler->isBundledInterface($interface)) {
$interfaceDefinitions[$interface] = $compiler->getInternalClassDefinition($interface);
} else {
if ($extendedClass !== null) {
$classDefinition->setExtendsClassDefinition(new ClassDefinitionRuntime($extendedClass));
}

$this->logger->warning(
sprintf(
'Cannot locate class "%s" when extending interface "%s"',
$interface,
$classDefinition->getCompleteName()
),
['nonexistent-class', $this->originalNode]
);
}
continue;
}

if ($compiler->isBundledInterface($interface)) {
$interfaceDefinitions[$interface] = $compiler->getInternalClassDefinition($interface);

continue;
}

if ($extendedClass !== null) {
$classDefinition->setExtendsClassDefinition(new ClassDefinitionRuntime($extendedClass));
}

$this->logger->warning(
sprintf(
'Cannot locate class "%s" when extending interface "%s"',
$interface,
$classDefinition->getCompleteName()
),
['nonexistent-class', $this->originalNode]
);
}

if (count($interfaceDefinitions) > 0) {
Expand All @@ -740,12 +707,13 @@ public function checkDependencies(Compiler $compiler)
/**
* Compiles the file.
*
* @param Compiler $compiler
* @param Compiler $compiler
* @param StringsManager $stringsManager
*
* @throws CompilerException
* @throws Exception
* @throws ReflectionException
*/
public function compile(Compiler $compiler, StringsManager $stringsManager)
public function compile(Compiler $compiler, StringsManager $stringsManager): void
{
if (!$this->ir) {
throw new CompilerException('Unable to locate the intermediate representation of the compiled file');
Expand Down Expand Up @@ -843,22 +811,20 @@ public function compile(Compiler $compiler, StringsManager $stringsManager)

$classDefinition->setOriginalNode($this->originalNode);

$completeName = $classDefinition->getCompleteName();

$path = str_replace('\\', \DIRECTORY_SEPARATOR, strtolower($completeName));
$path = str_replace('\\', \DIRECTORY_SEPARATOR, strtolower($classDefinition->getCompleteName()));

$filePath = 'ext/'.$path.'.zep.c';
$filePathHeader = 'ext/'.$path.'.zep.h';

if (strpos($path, \DIRECTORY_SEPARATOR)) {
$dirname = \dirname($filePath);
$dirname = dirname($filePath);
if (!is_dir($dirname)) {
mkdir($dirname, 0755, true);
}
}

/**
* If the file does not exists we create it for the first time
* If the file does not exist we create it for the first time
*/
if (!file_exists($filePath)) {
file_put_contents($filePath, $codePrinter->getOutput());
Expand Down Expand Up @@ -896,7 +862,7 @@ public function applyClassHeaders(CompilationContext $compilationContext)
{
$classDefinition = $this->classDefinition;

$separators = str_repeat('../', \count(explode('\\', $classDefinition->getCompleteName())) - 1);
$separators = str_repeat('../', count(explode('\\', $classDefinition->getCompleteName())) - 1);

$code = ''.PHP_EOL;
$code .= '#ifdef HAVE_CONFIG_H'.PHP_EOL;
Expand Down Expand Up @@ -926,11 +892,11 @@ public function applyClassHeaders(CompilationContext $compilationContext)
}
}

if (\count($this->headerCBlocks) > 0) {
if (count($this->headerCBlocks) > 0) {
$code .= implode(PHP_EOL, $this->headerCBlocks).PHP_EOL;
}

/*
/**
* Prepend the required files to the header
*/
$compilationContext->codePrinter->preOutput($code);
Expand All @@ -954,7 +920,7 @@ public function getFilePath(): string
*
* @throws CompilerException
*/
protected function processShortcuts(array $property, ClassDefinition $classDefinition)
protected function processShortcuts(array $property, ClassDefinition $classDefinition): void
{
foreach ($property['shortcuts'] as $shortcut) {
if ('_' == substr($property['name'], 0, 1)) {
Expand Down Expand Up @@ -1026,7 +992,7 @@ protected function processShortcuts(array $property, ClassDefinition $classDefin
'type' => 'parameter',
'name' => $name,
'const' => 0,
'data-type' => 1 == \count($returnsType) ? $returnsType[0] : 'variable',
'data-type' => 1 == count($returnsType) ? $returnsType[0] : 'variable',
'mandatory' => 0,
],
]),
Expand Down
Loading