Skip to content

Commit

Permalink
introducing name resolver (resolves class names)
Browse files Browse the repository at this point in the history
  • Loading branch information
Halleck45 committed Sep 1, 2014
1 parent d917dee commit 64c3ed1
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 48 deletions.
2 changes: 1 addition & 1 deletion src/Hal/Component/OOP/Extractor/ClassExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function extract(&$n, TokenCollection $tokens)
$isAbstract = $prev && T_ABSTRACT === $prev->getType();

$classname = $this->searcher->getFollowingName($n, $tokens);
$class = new ReflectedClass($this->namespace, $classname);
$class = new ReflectedClass($this->namespace, trim($classname));
$class->setAbstract($isAbstract);
return $class;
}
Expand Down
22 changes: 14 additions & 8 deletions src/Hal/Component/OOP/Extractor/Extractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

namespace Hal\Component\OOP\Extractor;
use Hal\Component\OOP\Resolver\NameResolver;
use Hal\Component\Token\Tokenizer;


Expand Down Expand Up @@ -69,10 +70,11 @@ public function extract($filename)
$result = new Result;

$tokens = $this->tokenizer->tokenize($filename);
$nameResolver = new NameResolver();

// default current values
$class = $interface = $function = $method = null;
$mapOfAliases = array();
// $mapOfAliases = array();

$len = sizeof($tokens, COUNT_NORMAL);
for($n = 0; $n < $len; $n++) {
Expand All @@ -84,10 +86,7 @@ public function extract($filename)
case T_USE:
$alias = $this->extractors->alias->extract($n, $tokens);
if (null !== $alias->name && null !== $alias->alias) {
$mapOfAliases[$alias->alias] = $alias->name;
$class && $class->setAliases($mapOfAliases);
$method && $method->setAliases($mapOfAliases);
$interface && $interface->setAliases($mapOfAliases);
$nameResolver->pushAlias($alias);
}
break;

Expand All @@ -98,15 +97,21 @@ public function extract($filename)

case T_INTERFACE:
$class = $this->extractors->interface->extract($n, $tokens);
$class->setAliases($mapOfAliases);
$class->setNameResolver($nameResolver);
// push class AND in global AND in local class map
$this->result->pushClass($class);
$result->pushClass($class);
break;

case T_EXTENDS:
$i = $n;
$parent = $this->searcher->getFollowingName($i, $tokens);
$class->setParent(trim($parent));
break;

case T_CLASS:
$class = $this->extractors->class->extract($n, $tokens);
$class->setAliases($mapOfAliases);
$class->setNameResolver($nameResolver);
// push class AND in global AND in local class map
$this->result->pushClass($class);
$result->pushClass($class);
Expand All @@ -120,7 +125,8 @@ public function extract($filename)
continue;
}
$method = $this->extractors->method->extract($n, $tokens);
$method->setAliases($mapOfAliases);
// $method->setAliases($mapOfAliases);
$method->setNameResolver($nameResolver);
$class->pushMethod($method);
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/Hal/Component/OOP/Extractor/InterfaceExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public function __construct(Searcher $searcher)
public function extract(&$n, TokenCollection $tokens)
{
$classname = $this->searcher->getFollowingName($n, $tokens);
return new ReflectedInterface($this->namespace, $classname);
return new ReflectedInterface($this->namespace, trim($classname));
}

/**
Expand Down
57 changes: 41 additions & 16 deletions src/Hal/Component/OOP/Reflected/ReflectedClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

namespace Hal\Component\OOP\Reflected;
use Hal\Component\OOP\Resolver\NameResolver;


/**
Expand Down Expand Up @@ -35,11 +36,11 @@ class ReflectedClass {
private $methods;

/**
* Map of aliases
* Resolver for names
*
* @var array
* @var NameResolver
*/
private $aliases = array();
private $nameResolver;

/**
* Does the class is abstract ?
Expand All @@ -48,6 +49,13 @@ class ReflectedClass {
*/
private $isAbstract = false;

/**
* Parent's name
*
* @var string
*/
private $parent;

/**
* Constructor
*
Expand All @@ -59,6 +67,7 @@ public function __construct($namespace, $name)
$this->name = (string) $name;
$this->namespace = (string) $namespace;
$this->methods = array();
$this->nameResolver = new NameResolver();
}

/**
Expand Down Expand Up @@ -103,15 +112,6 @@ public function getMethods()
*/
public function pushMethod(ReflectedMethod $method) {
$this->methods[$method->getName()] = $method;

// foreach($method->getArguments() as $argument) {
//
// $name = $argument->getType();
// if(!in_array($argument->getType(), array(null, $this->getName(), 'array'))) {
// $this->pushDependency($name);
// }
// }

return $this;
}

Expand All @@ -124,15 +124,20 @@ public function getDependencies()
foreach($this->getMethods() as $method) {
$dependencies = array_merge($dependencies, $method->getDependencies());
}
return $dependencies;
foreach($dependencies as &$name) {
$name = $this->nameResolver->resolve($name, $this->getNamespace());
}
return array_unique($dependencies);
}

/**
* @param array $aliases
* @param NameResolver $resolver
* @return $this
*/
public function setAliases(array $aliases)
public function setNameResolver(NameResolver $resolver)
{
$this->aliases = $aliases;
$this->nameResolver = $resolver;
return $this;
}

/**
Expand Down Expand Up @@ -162,4 +167,24 @@ public function setAbstract($bool) {
public function isAbstract() {
return $this->isAbstract;
}

/**
* Set the parent name
*
* @param $parent
* @return $this
*/
public function setParent($parent) {
$this->parent = $parent;
return $this;
}

/**
* Get the parent name
*
* @return null|string
*/
public function getParent() {
return $this->nameResolver->resolve($this->parent, $this->getNamespace());
}
};
27 changes: 11 additions & 16 deletions src/Hal/Component/OOP/Reflected/ReflectedMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

namespace Hal\Component\OOP\Reflected;
use Hal\Component\OOP\Resolver\NameResolver;


/**
Expand Down Expand Up @@ -48,11 +49,11 @@ class ReflectedMethod {
private $dependencies = array();

/**
* Map of aliases
* Resolver for names
*
* @var array
* @var NameResolver
*/
private $aliases = array();
private $nameResolver;

/**
* @var array
Expand All @@ -70,6 +71,7 @@ class ReflectedMethod {
public function __construct($name)
{
$this->name = (string) $name;
$this->nameResolver = new NameResolver();
}

/**
Expand Down Expand Up @@ -218,25 +220,18 @@ public function getDependencies()
// on read : compare with aliases. We cannot make it in pushDependency() => aliases aren't yet known
$dependencies = array();
foreach($this->dependencies as $name) {
$real = isset($this->aliases[$name]) ? $this->aliases[$name] : $name;
array_push($dependencies, $real);
array_push($dependencies, $this->nameResolver->resolve($name));
}
return array_unique($dependencies);
}

/**
* @param array $aliases
*/
public function setAliases(array $aliases)
{
$this->aliases = $aliases;
}

/**
* @return array
* @param NameResolver $resolver
* @return $this
*/
public function getAliases()
public function setNameResolver(NameResolver $resolver)
{
return $this->aliases;
$this->nameResolver = $resolver;
return $this;
}
};
67 changes: 67 additions & 0 deletions src/Hal/Component/OOP/Resolver/NameResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

/*
* (c) Jean-François Lépine <https://twitter.com/Halleck45>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Hal\Component\OOP\Resolver;


/**
* Alias (and namepsace) resolver
*
* @author Jean-François Lépine <https://twitter.com/Halleck45>
*/
class NameResolver
{

/**
* @var array
*/
private $aliases = array();

/**
* Resolve name of class
*
* @param string $name
* @param string $currentNamespace
* @return string
*/
public function resolve($name, $currentNamespace = '\\')
{
// already namespaced
if ('\\' == $name[0]) {
return $name;
}

// use xxx as yyy
if (isset($this->aliases[$name])) {
return $this->aliases[$name];
}

// use xxx;
foreach ($this->aliases as $alias => $nothing) {
$parts = preg_split('![^\w]!', $alias);
$last = $parts[sizeof($parts, COUNT_NORMAL) - 1];
if ($last === $name) {
return $alias;
}
}

return $name;
}

/**
* Push alias
*
* @param StdClass $alias
* @return $this
*/
public function pushAlias(\StdClass $alias) {
$this->aliases[$alias->alias] = $alias->name;
return $this;
}
}
1 change: 0 additions & 1 deletion tests/Hal/Component/OOP/MethodExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ public function provideCodeForReturns() {

/**
* @dataProvider provideCodeForNew
* @group wip
*/
public function testConstructorAreFound($expected, $code) {
$searcher = new Searcher();
Expand Down
15 changes: 10 additions & 5 deletions tests/Hal/Component/OOP/OOPExtractorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

/**
* @group oop
* @group wip
*/
class OOPExtractorTest extends \PHPUnit_Framework_TestCase {

Expand Down Expand Up @@ -35,11 +36,10 @@ public function providesForClassnames() {
}

/**
* @group wip
* @dataProvider providesForDependenciesWithoutAlias
*/
public function testDependenciesAreGivenWithoutAlias() {
public function testDependenciesAreGivenWithoutAlias($file, $expected) {

$file = __DIR__.'/../../../resources/oop/f4.php';
$result = new \Hal\Component\OOP\Extractor\Result();
$extractor = new Extractor(new \Hal\Component\Token\Tokenizer());
$result = $extractor->extract($file);
Expand All @@ -50,12 +50,17 @@ public function testDependenciesAreGivenWithoutAlias() {
$class = $classes[0];
$dependencies = $class->getDependencies();

$expected = array('\Full\AliasedClass', 'Toto');

$this->assertEquals($expected, $dependencies, 'Dependencies are given without alias');
}

public function providesForDependenciesWithoutAlias() {
return array(
array(__DIR__.'/../../../resources/oop/f7.php', array('Symfony\Component\Config\Definition\Processor'))
, array(__DIR__.'/../../../resources/oop/f4.php', array('\Full\AliasedClass', 'Toto'))
);
}


public function testCallsAreFoundAsDependencies() {
$file = __DIR__.'/../../../resources/oop/f5.php';
$extractor = new Extractor(new \Hal\Component\Token\Tokenizer());
Expand Down
12 changes: 12 additions & 0 deletions tests/resources/oop/f7.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Hal\Component\Config;
use Symfony\Component\Config\Definition\Processor;
use \Symfony\Component\Config\Definition\NodeInterface;

class Bar {
public function foo(array $config) {
$processor = new Processor();
return $processor->process($this->tree, $config);
}
}

0 comments on commit 64c3ed1

Please sign in to comment.