Skip to content

Commit

Permalink
includes part of PHP_Reflect code to decouple CompatInfo from Reflect…
Browse files Browse the repository at this point in the history
… runner
  • Loading branch information
llaville committed Aug 5, 2020
1 parent e89de39 commit 248f689
Show file tree
Hide file tree
Showing 12 changed files with 1,574 additions and 854 deletions.
269 changes: 2 additions & 267 deletions src/Bartlett/CompatInfo/Analyser/AbstractAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Bartlett\CompatInfo\Analyser;

use Bartlett\CompatInfo\DataCollector\VersionUpdater;
use Bartlett\Reflect;
use Bartlett\Reflect\Analyser\AnalyserInterface;
use Bartlett\Reflect\Event\BuildEvent;
Expand All @@ -37,15 +38,7 @@ abstract class AbstractAnalyser implements AnalyserInterface, NodeVisitor
protected $subject;
protected $contextStack;

protected static $php4 = [
'ext.name' => 'user',
'ext.min' => '',
'ext.max' => '',
'ext.all' => '',
'php.min' => '4.0.0',
'php.max' => '',
'php.all' => '',
];
use VersionUpdater;

/**
* {@inheritDoc}
Expand Down Expand Up @@ -191,262 +184,4 @@ public function afterTraverse(array $nodes)
)
);
}

/**
* Update the base version if current ref version is greater
*
* @param string $current Current version
* @param string &$base Base version
*
* @return void
*/
public static function updateVersion(string $current, string &$base): void
{
if (version_compare($current, $base, 'gt')) {
$base = $current;
}
}

/**
* Update an element versions of the project
*
* @param string $element
* @param string $name
* @param array $versions
*
* @return void
*/
public function updateElementVersion(string $element, string $name, array $versions): void
{
$versions = array_merge(self::$php4, $versions);

if (!isset($this->metrics[$element][$name])) {
$versions['matches'] = $versions['matches'] ?? 0;
$this->metrics[$element][$name] = $versions;
}

if (isset($this->metrics[$element][$name]['arg.max'])
&& isset($versions['arg.max'])
&& $this->metrics[$element][$name]['arg.max'] < $versions['arg.max']
) {
$this->metrics[$element][$name]['arg.max'] = $versions['arg.max'];
}

self::updateVersion(
$versions['php.min'],
$this->metrics[$element][$name]['php.all']
);

self::updateVersion(
$versions['php.min'],
$this->metrics[$element][$name]['php.min']
);
self::updateVersion(
$versions['php.max'],
$this->metrics[$element][$name]['php.max']
);
self::updateVersion(
$versions['php.all'],
$this->metrics[$element][$name]['php.all']
);

if (isset($versions['declared'])) {
$this->metrics[$element][$name]['declared'] = true;
}
if (isset($versions['matches'])) {
$this->metrics[$element][$name]['matches'] = $versions['matches'];
}

if ('user' == $versions['ext.name']) {
$this->metrics[$element][$name]['ext.min'] = '';
$this->metrics[$element][$name]['ext.max'] = '';
return;
}

self::updateVersion(
$versions['ext.min'],
$this->metrics[$element][$name]['ext.min']
);
self::updateVersion(
$versions['ext.max'],
$this->metrics[$element][$name]['ext.max']
);
}

/**
* Updates parent container context
*
* @param array $versions (optional) Version informations
*
* @return void
*/
public function updateContextVersion(array $versions = null): void
{
if (count ($this->contextStack) > 1) {
list($celement, $cname) = array_pop($this->contextStack);
} else {
list($celement, $cname) = end($this->contextStack);
}

if (!isset($versions)) {
// retrieves current context information
$versions = $this->metrics[$celement][$cname];
}
$versions = array_replace(self::$php4, $versions);

list($pelement, $pname) = end($this->contextStack);

self::updateVersion(
$versions['php.all'],
$this->metrics[$pelement][$pname]['php.all']
);

self::updateVersion(
$versions['php.max'],
$this->metrics[$pelement][$pname]['php.max']
);

self::updateVersion(
$versions['php.min'],
$this->metrics[$pelement][$pname]['php.all']
);

if (isset($this->metrics[$celement][$cname]['optional'])) {
// conditional code
return;
}

self::updateVersion(
$versions['php.min'],
$this->metrics[$pelement][$pname]['php.min']
);
}

/**
* Update the global versions of the project
*
* @param string $min The PHP min version to check
* @param string $max The PHP max version to check
* @param string $all The PHP min version to check for all components
*
* @return void
*/
public function updateGlobalVersion(string $min, string $max, string $all): void
{
if (empty($this->metrics['versions'])) {
$this->metrics['versions'] = [
'php.min' => '4.0.0',
'php.max' => '',
'php.all' => '',
];
}

self::updateVersion(
$min,
$this->metrics['versions']['php.min']
);
self::updateVersion(
$max,
$this->metrics['versions']['php.max']
);
self::updateVersion(
$all,
$this->metrics['versions']['php.all']
);
}

/**
* Visits a namespace node.
*
* @param Node\Stmt\Namespace_ $namespace Represents a namespace in the data source
*
* @return void
*/
protected function visitNamespace(Node\Stmt\Namespace_ $namespace): void
{
$this->namespaces[] = $namespace->name;
}

/**
* Visits a class node.
*
* @param Node\Stmt\Class_ $class Represents a class in the namespace
*
* @return void
*/
protected function visitClass(Node\Stmt\Class_ $class): void
{
$this->testClass = false;

$parent = $class->extends;

if (empty($parent)) {
// No ancestry
// Treat the class as a test case class if the name
// of the parent class ends with "TestCase".

if (substr((string) $class->name, -8) == 'TestCase') {
$this->testClass = true;
}
} else {
// Ancestry
// Treat the class as a test case class if the name
// of the parent class equals to "PHPUnit_Framework_TestCase".

if (in_array((string) $parent, ['PHPUnit_Framework_TestCase', 'PHPUnit\\Framework\\TestCase'])) {
$this->testClass = true;
}
}
}

/**
* Checks if a property is implicitly public (PHP 4 syntax)
*
* @param array $tokens
* @param Node\Stmt\Property $prop
*
* @return boolean
*/
protected function isImplicitlyPublicProperty(array $tokens, Node\Stmt\Property $prop): bool
{
$i = $prop->getAttribute('startTokenPos');
return (isset($tokens[$i]) && $tokens[$i][0] == T_VAR);
}

/**
* Checks if a method is implicitly public (PHP 4 syntax)
*
* @param array $tokens
* @param Node\Stmt\ClassMethod $method
*
* @return boolean
*/
protected function isImplicitlyPublicFunction(array $tokens, Node\Stmt\ClassMethod $method): bool
{
$i = $method->getAttribute('startTokenPos');
for ($c = count($tokens); $i < $c; ++$i) {
$t = $tokens[$i];
if ($t[0] == T_PUBLIC || $t[0] == T_PROTECTED || $t[0] == T_PRIVATE) {
return false;
}
if ($t[0] == T_FUNCTION) {
break;
}
}
return true;
}

/**
* Checks if array syntax is normal or short (PHP 5.4+ feature)
*
* @param array $tokens
* @param Node\Expr\Array_ $array
*
* @return boolean
*/
protected function isShortArraySyntax(array $tokens, Node\Expr\Array_ $array): bool
{
$i = $array->getAttribute('startTokenPos');
return is_string($tokens[$i]);
}
}
Loading

0 comments on commit 248f689

Please sign in to comment.