Skip to content
This repository has been archived by the owner on Sep 24, 2020. It is now read-only.

Start to work on interface compilation #157

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
56 changes: 54 additions & 2 deletions src/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@

use PHPSA\Definition\ClassDefinition;
use PHPSA\Definition\FunctionDefinition;
use PHPSA\Definition\InterfaceDefinition;
use PHPSA\Definition\RuntimeClassDefinition;
use PHPSA\Definition\TraitDefinition;
use PHPSA\Definition\RuntimeInterfaceDefinition;
use ReflectionClass;

class Compiler
{
/**
* @var ClassDefinition[]
*/
protected $classes = array();
protected $classes = [];

/**
* @var TraitDefinition[]
Expand All @@ -26,7 +28,12 @@ class Compiler
/**
* @var FunctionDefinition[]
*/
protected $functions = array();
protected $functions = [];

/**
* @var InterfaceDefinition[]
*/
protected $interfaces = [];

/**
* @param ClassDefinition $class
Expand All @@ -52,13 +59,36 @@ public function addFunction(FunctionDefinition $function)
$this->functions[] = $function;
}

/**
* @param InterfaceDefinition $interface
*/
public function addInterface(InterfaceDefinition $interface)
{
$this->interfaces[implode('\\', [$interface->getNamespace(), $interface->getName()])] = $interface;
}

/**
* @param Context $context
*/
public function compile(Context $context)
{
$context->scopePointer = null;

foreach ($this->interfaces as $interface) {
foreach ($interface->getExtendsInterface() as $extendsInterface) {
if (isset($this->interfaces[$extendsInterface])) {
$interface->addExtendsInterfaceDefinition($this->interfaces[$extendsInterface]);
continue;
}

if (class_exists($extendsInterface, true)) {
$interface->addExtendsInterfaceDefinition(
new RuntimeInterfaceDefinition(new ReflectionClass($extendsInterface))
);
}
}
}

/**
* @todo Implement class map...
*/
Expand All @@ -79,6 +109,28 @@ public function compile(Context $context)
}
}
}

foreach ($class->getInterfaces() as $interface) {
if (!isset($this->interfaces[$interface])) {
continue;
}

$class->addInterfaceDefinition($this->interfaces[$interface]);
}
}

foreach ($this->interfaces as $interface) {
/**
* @todo Configuration
*
* Ignore Interfaces compiling from vendor
*/
$checkVendor = strpos($class->getFilepath(), './vendor');
if ($checkVendor !== false && $checkVendor < 3) {
continue;
}

$interface->compile($context);
}

foreach ($this->functions as $function) {
Expand Down
40 changes: 35 additions & 5 deletions src/Definition/ClassDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,14 @@ class ClassDefinition extends ParentDefinition
protected $extendsClassDefinition;

/**
* @var array
* @var string[]
*/
protected $interfaces = array();
protected $interfaces = [];

/**
* @var InterfaceDefinition[]
*/
protected $interfacesDefinitions = [];

/**
* @param string $name
Expand Down Expand Up @@ -105,7 +110,7 @@ public function addProperty(Node\Stmt\Property $property)
foreach ($property->props as $propertyDefinition) {
$this->properties[$propertyDefinition->name] = $propertyDefinition;
}

$this->propertyStatements[] = $property;
}

Expand Down Expand Up @@ -235,8 +240,17 @@ public function hasMethod($name, $inherit = false)
*/
public function hasConst($name, $inherit = false)
{
if ($inherit && $this->extendsClassDefinition && $this->extendsClassDefinition->hasConst($name, $inherit)) {
return true;
if ($inherit) {
if ($this->extendsClassDefinition && $this->extendsClassDefinition->hasConst($name, $inherit)) {
return true;
}

/** @var InterfaceDefinition $interface */
foreach ($this->interfacesDefinitions as $interface) {
if ($interface->hasConst($name, true)) {
return true;
}
}
}

return isset($this->constants[$name]);
Expand Down Expand Up @@ -350,6 +364,22 @@ public function addInterface($interface)
$this->interfaces[] = $interface;
}

/**
* @return string[]
*/
public function getInterfaces()
{
return $this->interfaces;
}

/**
* @param InterfaceDefinition $interfaceDefinition
*/
public function addInterfaceDefinition(InterfaceDefinition $interfaceDefinition)
{
$this->interfacesDefinitions[] = $interfaceDefinition;
}

/**
* @return null|string
*/
Expand Down
26 changes: 22 additions & 4 deletions src/Definition/FileParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,8 @@ protected function parseTopDefinitions($topStatement, AliasManager $aliasManager
$definition->setExtendsClass($statement->extends->toString());
}

if ($statement->implements) {
foreach ($statement->implements as $interface) {
$definition->addInterface($interface->toString());
}
foreach ($statement->implements as $interface) {
$definition->addInterface($interface->toString());
}

foreach ($statement->stmts as $stmt) {
Expand Down Expand Up @@ -167,6 +165,26 @@ protected function parseTopDefinitions($topStatement, AliasManager $aliasManager
$definition->setNamespace($aliasManager->getNamespace());

$this->compiler->addFunction($definition);
} elseif ($statement instanceof Node\Stmt\Interface_) {
$definition = new InterfaceDefinition($statement->name, $statement);
$definition->setFilepath($filepath);
$definition->setNamespace($aliasManager->getNamespace());

foreach ($statement->extends as $interface) {
$definition->addExtendsInterface($interface->toString());
}

foreach ($statement->stmts as $stmt) {
if ($stmt instanceof Node\Stmt\ClassMethod) {
$method = new ClassMethod($stmt->name, $stmt, $stmt->type | Node\Stmt\Class_::MODIFIER_ABSTRACT);

$definition->addMethod($method);
} elseif ($stmt instanceof Node\Stmt\ClassConst) {
$definition->addConst($stmt);
}
}

$this->compiler->addInterface($definition);
}
}
}
Expand Down