Skip to content

Commit

Permalink
A ton of new stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabrizio Branca committed Jun 20, 2015
1 parent 9c9eca8 commit 29fe6dd
Show file tree
Hide file tree
Showing 19 changed files with 815 additions and 94 deletions.
26 changes: 22 additions & 4 deletions n98-magerun.yaml
Expand Up @@ -2,7 +2,25 @@ autoloaders:
Mpmd: %module%/src

commands:
customCommands:
- Mpmd\Magento\CoreHacksCommand
- Mpmd\Magento\CodePoolOverridesCommand
- Mpmd\Magento\DependencyCheckCommand
customCommands:
- Mpmd\Magento\CoreHacksCommand
- Mpmd\Magento\CodePoolOverridesCommand
- Mpmd\Magento\DependencyCheckCommand
- Mpmd\Magento\DependencyCheckCommand\Verify
- Mpmd\Magento\DependencyCheckCommand\Classgraph
- Mpmd\Magento\DependencyCheckCommand\Modulegraph
Mpmd\Magento\DependencyCheckCommand:
parsers:
- Mpmd\DependencyChecker\Parser\Tokenizer
- Mpmd\DependencyChecker\Parser\Xpath
Mpmd\DependencyChecker\Parser\Tokenizer:
handlers:
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\WhitespaceString
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\Interfaces
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\TypeHints
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\StaticCalls
- Mpmd\DependencyChecker\Parser\Tokenizer\Handler\MagentoFactoryMethods
Mpmd\DependencyChecker\Parser\Xpath:
handlers:
- Mpmd\DependencyChecker\Parser\Xpath\Handler\SystemXml
- Mpmd\DependencyChecker\Parser\Xpath\Handler\LayoutXml
7 changes: 7 additions & 0 deletions phpunit.xml
@@ -0,0 +1,7 @@
<phpunit bootstrap="tests/bootstrap.php">
<testsuites>
<testsuite name="MPMD Tests">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
4 changes: 2 additions & 2 deletions src/Mpmd/DependencyChecker/AbstractHandler.php
Expand Up @@ -22,10 +22,10 @@ public function __construct(\Mpmd\DependencyChecker\Parser\AbstractParser $parse
{
$this->parser = $parser;
$this->collector = $collector;
$this->_contruct();
$this->_construct();
}

public function _contruct() {}
public function _construct() {}

abstract public function listenTo($type);

Expand Down
129 changes: 125 additions & 4 deletions src/Mpmd/DependencyChecker/Collector.php
Expand Up @@ -122,23 +122,144 @@ public function filter($filter) {
return array_unique($filteredClasses);
}

/**
* Get class-to-class relations
*
* @return array
*/
public function getClassRelations()
{
$relations = array();
foreach ($this->getSourceClasses() as $sourceClass => $data) {
$relations[$sourceClass] = array();
foreach ($data as $type => $classes) {
foreach ($classes as $targetClass) {
if ($targetClass != $sourceClass) {
if (!isset($relations[$sourceClass][$targetClass])) {
$relations[$sourceClass][$targetClass] = array();
}
$relations[$sourceClass][$targetClass][] = $type;
}
}
}
}
return $relations;
}

/**
* Get classes
*
* @return array
*/
public function getModuleRelations()
{
$relations = array();
$divUtil = new \Mpmd\Util\Div();
foreach ($this->getSourceClasses() as $sourceClass => $data) {
$sourceModule = $divUtil->getModuleFromClass($sourceClass, 2);
if (!is_array($relations[$sourceModule])) {
$relations[$sourceModule] = array();
}
foreach ($data as $type => $classes) {
foreach ($classes as $targetClass) {
$targetModule = $divUtil->getModuleFromClass($targetClass, 2);
if ($targetModule != $sourceModule) {
if (!is_array($relations[$sourceModule])) {
$relations[$sourceModule] = array();
}
if (!in_array($targetModule, $relations[$sourceModule])) {
$relations[$sourceModule][] = $targetModule;
}
}
}
}
}
return $relations;
}

/**
* Returns the class for a given file (if any)
*
* @param $file
* @return bool|string
*/
public function getClassForFile($file)
{
if (!isset($this->classes[$file])) {
throw new \InvalidArgumentException('File not found.');
}
if (!is_array($this->classes[$file]['class']) || count($this->classes[$file]['class']) == 0) {
return false;
}
if (count($this->classes[$file]['class']) > 1) {
// TODO: found more than one class in this file! ignoring this for now...
}
return reset($this->classes[$file]['class']);
}

/**
* Get classes
*
* @return array
*/
public function getModules()
{
return array_keys($this->getClassesByModule());
}

/**
* Get classes grouped by module
*
* @return array
*/
public function getClassesByModule()
{
$divUtil = new \Mpmd\Util\Div();

$modules = array();
$classesByModule = array();
foreach ($this->flatten() as $class) {
$module = $divUtil->getModuleFromClass($class, 2);
if (!in_array($module, $modules)) {
$modules[] = $module;
if (!in_array($module, $classesByModule)) {
$classesByModule[$module][] = $class;
}
}
return $classesByModule;
}

/**
* Get all classes found in the files (not in the depencencies)
*
* @return array
*/
public function getSourceClasses()
{
$sourceClasses = array();
foreach ($this->classes as $file => $data) {
$sourceClass = $this->getClassForFile($file);
if (!$sourceClass) {
continue;
}
$sourceClasses[$sourceClass] = $data;
}
return $sourceClasses;
}

/**
* Get all modules found in source classes
*
* @return array
*/
public function getSourceModules()
{
$divUtil = new \Mpmd\Util\Div();
$sourceModules = array();
foreach ($this->getSourceClasses() as $sourceClass => $data) {
$sourceModule = $divUtil->getModuleFromClass($class, 2);
if (!in_array($sourceModule, $sourceModules)) {
$sourceModules[] = $sourceModule;
}
}
return $modules;
return $sourceModules;
}

/**
Expand Down
19 changes: 1 addition & 18 deletions src/Mpmd/DependencyChecker/Parser/Tokenizer.php
Expand Up @@ -20,31 +20,14 @@ class Tokenizer extends AbstractParser
*/
protected $tokens;

/**
* Constructor
*
* @param \Mpmd\DependencyChecker\Collector $collector
*/
public function __construct(\Mpmd\DependencyChecker\Collector $collector)
{
// TODO: there are probably better ways of doing this

$this->addHandler(new Tokenizer\Handler\WhitespaceString($this, $collector));
$this->addHandler(new Tokenizer\Handler\Interfaces($this, $collector));
$this->addHandler(new Tokenizer\Handler\TypeHints($this, $collector));
$this->addHandler(new Tokenizer\Handler\StaticCalls($this, $collector));
$this->addHandler(new Tokenizer\Handler\MagentoFactoryMethods($this, $collector));
}

/**
* Run tokenizer
*
* @param string filename
* @throws \Exception
*/
public function parse($file)
public function parse($source)
{
$source = file_get_contents($file);
$this->tokens = token_get_all($source);

foreach ($this->tokens as $i => $token) {
Expand Down
Expand Up @@ -36,7 +36,11 @@ public function handle($i)
if ($string == strtolower($method)) {
$j = $this->parser->skip($i+1, array(T_WHITESPACE));
$this->parser->assertToken($j, '(');
$j = $this->parser->skip($j+1, array(T_WHITESPACE));
$j = $this->parser->skip($j+1, array(T_WHITESPACE, T_STRING_CAST));
if ($this->parser->is($j, T_VARIABLE)) {
// we can't find out what that variable points to, so we'll let this one go...
continue;
}
$this->parser->assertToken($j, T_CONSTANT_ENCAPSED_STRING);

$classPath = trim($this->parser->getValue($j), '"\'');
Expand Down
Expand Up @@ -15,7 +15,7 @@ public function handle($i)
$this->parser->assertToken($i-1, T_STRING);
$value = $this->parser->getValue($i-1);
if (!in_array($value, array('self', 'parent'))) {
$this->collector->addClass($value, 'static_calls');
$this->collector->addClass($value, 'static_call');
}
}

Expand Down
22 changes: 12 additions & 10 deletions src/Mpmd/DependencyChecker/Parser/Tokenizer/Handler/TypeHints.php
Expand Up @@ -12,20 +12,22 @@ class TypeHints extends AbstractHandler {

public function handle($i)
{
$this->parser->assertToken($i+1, T_WHITESPACE);
$this->parser->assertToken($i+2, T_STRING);

$j = $i+2;
$j = $this->parser->skip($j+1, array(T_WHITESPACE));
$j = $i+1;
$this->parser->assertToken($j, T_WHITESPACE);
$j = $this->parser->skip($j + 1, array(T_WHITESPACE, '&'));
$this->parser->assertToken($j, T_STRING); // function name
$j = $this->parser->skip($j + 1, array(T_WHITESPACE, '&'));

// parse arguments
$this->parser->assertToken($j, '(');
$j = $this->parser->skip($j+1, array(T_WHITESPACE));
$j++;
while (!$this->parser->is($j, ')')) {
if ($this->parser->is($j, T_STRING)) { // we found a type hint
$this->parser->assertToken($j+1, T_WHITESPACE);
$this->parser->assertToken($j+2, T_VARIABLE);
$this->collector->addClass($this->parser->getValue($j), 'type_hints');
$this->parser->assertToken($j + 1, T_WHITESPACE);
$this->parser->assertToken($j + 2, T_VARIABLE);
$this->collector->addClass($this->parser->getValue($j), 'type_hint');
}
$j = $this->parser->skipUntil($j+1, array(',', ')'));
$j = $this->parser->skipUntil($j + 1, array(',', ')'));
}
}

Expand Down
Expand Up @@ -28,7 +28,6 @@ public function handle($i)
// we can't handle code like this:
// $object = new $className();
// so, let's just skip that.

} else {
throw $e;
}
Expand Down
17 changes: 2 additions & 15 deletions src/Mpmd/DependencyChecker/Parser/Xpath.php
Expand Up @@ -15,22 +15,9 @@ class Xpath extends AbstractParser

protected $fileExtensions = array('xml');

/**
* Constructor
*
* @param \Mpmd\DependencyChecker\Collector $collector
*/
public function __construct(\Mpmd\DependencyChecker\Collector $collector)
public function parse($string)
{
// TODO: there are probably better ways of doing this

$this->addHandler(new Xpath\Handler\SystemXml($this, $collector));
$this->addHandler(new Xpath\Handler\LayoutXml($this, $collector));
}

public function parse($file)
{
$simpleXml = simplexml_load_file($file);
$simpleXml = simplexml_load_string($string);

foreach ($this->handlers as $handler) { /* @var $handler Xpath\Handler\AbstractHandler */
if ($handler->listenTo($simpleXml)) {
Expand Down

0 comments on commit 29fe6dd

Please sign in to comment.