Skip to content

Commit

Permalink
Sort namespaces php env independently
Browse files Browse the repository at this point in the history
  • Loading branch information
mamuz committed Jul 20, 2015
1 parent eb7110c commit 6c1b9aa
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 50 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Expand Up @@ -2,7 +2,11 @@
All notable changes to this project will be documented in this file.

## v0.1.3 - UNRELEASED
Nothing yet.
### Fixed
- Sort namespaces php env independently

### Added
- DependencyMap

## v0.1.2 - 2015-07-05
### Added
Expand Down
30 changes: 21 additions & 9 deletions src/Collector.php
Expand Up @@ -33,8 +33,8 @@ class Collector extends NodeVisitorAbstract
/** @var array */
private $classMap = array();

/** @var array */
private $dependencies = array();
/** @var DependencyMap */
private $dependencies;

/** @var Node\Stmt\ClassLike[] */
private $foundClasses = array();
Expand Down Expand Up @@ -102,19 +102,24 @@ class Collector extends NodeVisitorAbstract
'stream_is_local',
);

public function __construct()
{
$this->dependencies = new DependencyMap;
}

public function leaveNode(Node $node)
{
if ($node instanceof Node\Stmt\Class_) {
$this->collect(array($node->extends));
$this->collect($node->implements);
$this->collect(array($node->extends), 'extension');
$this->collect($node->implements, 'implementation');
$this->foundClasses[] = $node;
} elseif ($node instanceof Node\Stmt\Interface_) {
$this->collect($node->extends);
$this->collect($node->extends, 'implementation');
$this->foundClasses[] = $node;
} elseif ($node instanceof Node\Stmt\Trait_) {
$this->foundClasses[] = $node;
} elseif ($node instanceof Node\Stmt\TraitUse) {
$this->collect($node->traits);
$this->collect($node->traits, 'traitUse');
} elseif ($node instanceof Node\Stmt\Declare_) {
$this->hasFoundInvalidStmt = true;
} elseif ($node instanceof Node\Expr\Include_) {
Expand All @@ -131,14 +136,21 @@ public function leaveNode(Node $node)

/**
* @param Node\Name[]|null $names
* @param string $type
*/
private function collect($names)
private function collect($names, $type)
{
if ($names) {
foreach ($names as $name) {
if ($name) {
$name = $name->toString();
$this->dependencies[$name] = $name;
if (false === strpos($name, '_')
&& count(explode("\\", $name)) == 1
) {
continue;
}
$method = 'add' . ucfirst($type);
$this->dependencies->$method($name);
}
}
}
Expand All @@ -157,7 +169,7 @@ public function reset()
$this->classMap[$name] = $this->dependencies;
}

$this->dependencies = array();
$this->dependencies = new DependencyMap;
$this->foundClasses = array();
$this->hasFoundInvalidStmt = false;
}
Expand Down
94 changes: 94 additions & 0 deletions src/DependencyMap.php
@@ -0,0 +1,94 @@
<?php
/**
* The MIT License (MIT)
*
* Copyright (c) 2015 Marco Muths
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

namespace Squeeze;

class DependencyMap
{
/** @var array */
private $implementations = array();

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

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

/**
* @param string $fqcn
*/
public function addImplementation($fqcn)
{
$this->implementations[$fqcn] = $fqcn;
}

/**
* @param string $fqcn
*/
public function addTraitUse($fqcn)
{
$this->traitUses[$fqcn] = $fqcn;
}

/**
* @param string $fqcn
*/
public function addExtension($fqcn)
{
$this->extensions[$fqcn] = $fqcn;
}

/**
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}

/**
* @return array
*/
public function getImplementations()
{
return $this->implementations;
}

/**
* @return array
*/
public function getTraitUses()
{
return $this->traitUses;
}

/**
* @return array
*/
public function getAll()
{
return array_merge($this->implementations, $this->traitUses, $this->extensions);
}
}
62 changes: 22 additions & 40 deletions src/Filter.php
Expand Up @@ -32,7 +32,6 @@

class Filter
{

/** @var ParserAbstract */
private $parser;

Expand Down Expand Up @@ -77,40 +76,21 @@ public function extractClassMapFrom(\Iterator $files)
}

$classMap = $this->collector->getClassMap();
$classMap = $this->removeInternalClassesFrom($classMap);
$classMap = $this->removeUnloadableClassesFrom($classMap);
$classMap = $this->sort($classMap);

return $classMap;
}

/**
* @param array $classMap
* @return array
*/
private function removeInternalClassesFrom(array $classMap)
{
foreach ($classMap as $class => $dependencies) {
foreach ($dependencies as $index => $dependency) {
if (false === strpos($dependency, '_')
&& count(explode("\\", $dependency)) == 1
) {
unset($classMap[$class][$index]);
}
}
}

return $classMap;
}

/**
* @param array $classMap
* @return array
*/
private function removeUnloadableClassesFrom(array $classMap)
{
foreach ($classMap as $class => $dependencies) {
foreach ($dependencies as $dependency) {
/** @var DependencyMap $dependencies */
foreach ($dependencies->getAll() as $dependency) {
if (!isset($classMap[$dependency])) {
unset($classMap[$class]);
$classMap = $this->removeUnloadableClassesFrom($classMap);
Expand All @@ -128,31 +108,33 @@ private function removeUnloadableClassesFrom(array $classMap)
*/
private function sort(array $classMap)
{
$classes = array_keys($classMap);
$classesSorted = array();

set_error_handler(
function ($code, $message, $file, $line) {
echo "[$code] on line $line in $file\n$message\n";
foreach ($classMap as $class => $dependencyMap) {
/** @var DependencyMap $dependencyMap */
if (!in_array($class, $classesSorted)) {
$classesSorted[] = $class;
}
foreach ($dependencyMap->getAll() as $dependency) {
$classPosition = array_search($class, $classesSorted);
$dependencyPosition = array_search($dependency, $classesSorted);
if (false !== $dependencyPosition) {
if ($dependencyPosition < $classPosition) {
continue;
}
}
$before = array_slice($classesSorted, 0, $classPosition);
$after = array_slice($classesSorted, $classPosition, count($classesSorted));
$classesSorted = array_merge($before, array($dependency), $after);
}
);
foreach ($classes as $class) {
class_exists($class, true);
}
restore_error_handler();

$classIncludes = array_merge(
get_declared_interfaces(),
get_declared_traits(),
get_declared_classes()
);

$classMap = array();
foreach ($classIncludes as $class) {
if (in_array($class, $classes)) {
$classMap[$class] = $this->classloader->findFile($class);
}
foreach ($classesSorted as $class) {
$classMap[$class] = $this->classloader->findFile($class);
}

return $classMap;
}

}

0 comments on commit 6c1b9aa

Please sign in to comment.