Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactoring for class/interface/trait based storage complete

  • Loading branch information...
commit 37230229f95a4e110d12809cffc85bdf5d9bc5ea 1 parent f773254
@theseer theseer authored
View
27 src/Application.php
@@ -104,24 +104,27 @@ public function runCollector(CollectorConfig $config) {
$config->getIncludeMasks(),
$config->getExcludeMasks()
);
- $container = $this->factory->getInstanceFor('container', $xmlDir);
-
- $collector = $this->factory->getInstanceFor('Collector');
- $collector->setStartIndex(strlen(dirname(realpath($srcDir))));
+ $container = $this->factory->getInstanceFor('Container', $xmlDir, strlen(dirname(realpath($srcDir))));
+ $collector = $this->factory->getInstanceFor('Collector', $xmlDir, $config->isPublicOnlyMode());
$collector->run(
$scanner($srcDir),
- $container,
- $this->factory->getInstanceFor('Analyser', $config->isPublicOnlyMode()),
- $xmlDir,
- $srcDir
+ $container
);
+ $container->save();
+ $container->cleanup($srcDir);
- // enforce existence of all container files, even if the code didn't trigger their creation
- foreach(array('classes','interfaces','namespaces','traits') as $c) {
- $container->getDocument($c);
- }
+ $resolver = $this->factory->getInstanceFor('Resolver', $xmlDir);
+ $resolver->run($container);
$container->save();
+
+ if ($collector->hasParseErrors()) {
+ $this->logger->log('Parse errors during processing:');
+ foreach($collector->getParseErrors() as $file) {
+ $this->logger->log(' - ' . $file->getPathname());
+ }
+ }
+
$this->logger->log('Collector process completed');
}
View
5 src/autoload.php
@@ -7,7 +7,6 @@ function($class) {
static $classes = null;
if ($classes === null) {
$classes = array(
- 'theseer\\phpdox\\analyser' => '/collector/Analyser.php',
'theseer\\phpdox\\application' => '/Application.php',
'theseer\\phpdox\\applicationexception' => '/Application.php',
'theseer\\phpdox\\bootstrap' => '/bootstrap/Bootstrap.php',
@@ -19,6 +18,7 @@ function($class) {
'theseer\\phpdox\\cli' => '/CLI.php',
'theseer\\phpdox\\collector' => '/collector/Collector.php',
'theseer\\phpdox\\collectorconfig' => '/config/CollectorConfig.php',
+ 'theseer\\phpdox\\collectorexception' => '/collector/Collector.php',
'theseer\\phpdox\\configexception' => '/config/GlobalConfig.php',
'theseer\\phpdox\\configloader' => '/config/ConfigLoader.php',
'theseer\\phpdox\\configloaderexception' => '/config/ConfigLoader.php',
@@ -48,6 +48,7 @@ function($class) {
'theseer\\phpdox\\engine\\html' => '/generator/engine/html/Html.php',
'theseer\\phpdox\\engine\\html\\functions' => '/generator/engine/html/functions.php',
'theseer\\phpdox\\engine\\htmlconfig' => '/generator/engine/html/HtmlConfig.php',
+ 'theseer\\phpdox\\engine\\indexer' => '/generator/engine/indexer/Indexer.php',
'theseer\\phpdox\\engine\\todo' => '/generator/engine/todo/Todo.php',
'theseer\\phpdox\\enginebootstrapapi' => '/bootstrap/EngineBootstrapApi.php',
'theseer\\phpdox\\errorhandler' => '/shared/ErrorHandler.php',
@@ -63,10 +64,12 @@ function($class) {
'theseer\\phpdox\\generatorconfigexception' => '/config/GeneratorConfig.php',
'theseer\\phpdox\\generatorexception' => '/generator/Generator.php',
'theseer\\phpdox\\globalconfig' => '/config/GlobalConfig.php',
+ 'theseer\\phpdox\\hasfileinfoexception' => '/shared/HasFileInfoException.php',
'theseer\\phpdox\\parserbootstrapapi' => '/bootstrap/ParserBootstrapApi.php',
'theseer\\phpdox\\progresslogger' => '/logger/ProgressLogger.php',
'theseer\\phpdox\\progressloggerexception' => '/logger/ProgressLogger.php',
'theseer\\phpdox\\projectconfig' => '/config/ProjectConfig.php',
+ 'theseer\\phpdox\\resolver' => '/collector/Resolver.php',
'theseer\\phpdox\\service' => '/generator/Service.php',
'theseer\\phpdox\\shellprogresslogger' => '/logger/ShellProgressLogger.php'
);
View
135 src/collector/Analyser.php
@@ -1,135 +0,0 @@
-<?php
-/**
- * Copyright (c) 2010 Arne Blankerts <arne@blankerts.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * * Neither the name of Arne Blankerts nor the names of contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package phpDox
- * @author Arne Blankerts <arne@blankerts.de>
- * @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
- * @license BSD License
- */
-
-namespace TheSeer\phpDox {
-
- use \pdepend\reflection\ReflectionSession;
- use \TheSeer\fDOM\fDOMDocument;
-
- class Analyser {
-
- protected $publicOnly;
-
- protected $namespaces;
- protected $interfaces;
- protected $classes;
- protected $factory;
-
- protected $dom;
-
- public function __construct(Factory $factory, $publicOnly = false) {
- $this->factory = $factory;
- $this->publicOnly = $publicOnly;
- }
-
- public function getClasses() {
- return $this->classes;
- }
-
- public function getInterfaces() {
- return $this->interfaces;
- }
-
- public function getNamespaces() {
- return $this->namespaces;
- }
-
- public function processFile(\SPLFileInfo $file) {
- $this->namespaces = array();
- $this->interfaces = array();
- $this->classes = array();
-
- $info = new \finfo();
- $encoding = $info->file($file, FILEINFO_MIME_ENCODING);
-
- $this->initWorkDocument($file);
-
- $session = new ReflectionSession();
- $session->addClassFactory( new \pdepend\reflection\factories\NullReflectionClassFactory() );
- $query = $session->createFileQuery();
- foreach ( $query->find( $file->getPathname() ) as $class ) {
- $this->handleClass($class, $query->getAliasMap(), $encoding);
- }
- return $this->dom;
- }
-
- protected function initWorkDocument(\SPLFileInfo $file) {
- $this->dom = new fDOMDocument('1.0', 'UTF-8');
- $this->dom->preserveWhitespace = true;
- $this->dom->registerNamespace('dox', 'http://xml.phpdox.de/src#');
- $root = $this->dom->createElementNS('http://xml.phpdox.de/src#', 'file');
- $this->dom->appendChild($root);
-
- $head = $root->appendElementNS('http://xml.phpdox.de/src#', 'head');
- $head->setAttribute('path', $file->getPath());
- $head->setAttribute('file', $file->getFilename());
- $head->setAttribute('realpath', $file->getRealPath());
- $head->setAttribute('size', $file->getSize());
- $head->setAttribute('time', date('c', $file->getCTime()));
- $head->setAttribute('unixtime', $file->getCTime());
- $head->setAttribute('sha1', sha1_file($file->getPathname()));
- }
-
- protected function handleClass(\ReflectionClass $class, array $aliasMap, $encoding) {
- $context = $this->dom->documentElement;
- if ($class->inNamespace()) {
- $context = $this->handleNamespace($class);
- }
-
- $classBuilder = $this->factory->getInstanceFor('ClassBuilder', $context, $aliasMap, $this->publicOnly, $encoding);
- $classNode = $classBuilder->process($class);
- if ($class->isInterface()) {
- $this->interfaces[$class->getName()] = $classNode;
- } else {
- $this->classes[$class->getName()] = $classNode;
- }
- }
-
- protected function handleNamespace(\ReflectionClass $class) {
- $namespace = $class->getNamespaceName();
- if (!isset($this->namespaces[$namespace])) {
- $nsNode = $this->dom->createElementNS('http://xml.phpdox.de/src#', 'namespace');
- $nsNode->setAttribute('name', $namespace);
- $this->dom->documentElement->appendChild($nsNode);
- $this->namespaces[$namespace] = $nsNode;
- }
- return $this->namespaces[$namespace];
- }
-
- }
-
-}
View
15 src/collector/ClassBuilder.php
@@ -43,37 +43,36 @@
class ClassBuilder {
- protected $ctx;
protected $publicOnly;
protected $encoding;
protected $parser;
protected $aliasMap;
- public function __construct(Parser $parser, fDOMElement $ctx, array $aliasMap, $publicOnly = false, $encoding = 'ISO-8859-1') {
+ public function __construct(Parser $parser, array $aliasMap, $publicOnly = false, $encoding = 'ISO-8859-1') {
$this->parser = $parser;
- $this->ctx = $ctx;
$this->aliasMap = $aliasMap;
$this->publicOnly = $publicOnly;
$this->encoding = $encoding;
}
- public function process(\ReflectionClass $class) {
+ public function process(fDOMDocument $dom, \ReflectionClass $class) {
- $node = $this->ctx->appendElementNS('http://xml.phpdox.de/src#', $class->isInterface() ? 'interface' : 'class' );
+ $node = $dom->createElementNS('http://xml.phpdox.de/src#', $class->isInterface() ? 'interface' : 'class');
+ $dom->documentElement->appendChild($node);
$node->setAttribute('full', $class->getName());
$node->setAttribute('name', $class->getShortName());
+ $node->setAttribute('namespace', $class->inNamespace() ? $class->getNamespaceName() : '\\');
$node->setAttribute('final', $class->isFinal() ? 'true' : 'false');
if ($node->nodeName === 'class') {
$node->setAttribute('abstract', $class->isAbstract() ? 'true' : 'false');
}
-
$node->setAttribute('start', $class->getStartLine());
$node->setAttribute('end', $class->getEndLine());
if ($docComment = $class->getDocComment()) {
$node->appendChild(
- $this->processDocBlock($this->ctx->ownerDocument, $docComment)
+ $this->processDocBlock($dom, $docComment)
);
}
@@ -91,8 +90,6 @@ public function process(\ReflectionClass $class) {
$this->processMembers($node, $class->getProperties());
$this->processMethods($node, $class->getMethods());
- return $node;
-
}
protected function addReferenceNode(\ReflectionClass $class, fDOMElement $context, $nodeName) {
View
180 src/collector/Collector.php
@@ -38,7 +38,6 @@
use \TheSeer\DirectoryScanner\PHPFilterIterator;
use \TheSeer\fDOM\fDOMDocument;
- use \TheSeer\fDOM\fDOMException;
class Collector {
@@ -55,8 +54,17 @@ class Collector {
*/
protected $logger;
- public function __construct(ProgressLogger $logger) {
+ protected $factory;
+ protected $xmlDir;
+ protected $publicOnly;
+
+ protected $parseErrors = array();
+
+ public function __construct(ProgressLogger $logger, FactoryInterface $factory, $xmlDir, $publicOnly) {
$this->logger = $logger;
+ $this->xmlDir = $xmlDir;
+ $this->factory = $factory;
+ $this->publicOnly = $publicOnly;
}
/**
@@ -68,117 +76,103 @@ public function setStartIndex($index) {
$this->srcIndex = $index;
}
+
+ public function hasParseErrors() {
+ return count($this->parseErrors) > 0;
+ }
+
+ public function getParseErrors() {
+ return $this->parseErrors;
+ }
+
/**
* Main executer of the collector, looping over the iterator with found files
*
*/
- public function run(\Iterator $scanner, Container $container, Analyser $analyser, $xmlDir, $srcDir) {
- $worker = new PHPFilterIterator($scanner);
-
- if (!file_exists($xmlDir)) {
- mkdir($xmlDir, 0755, true);
- }
-
+ public function run(\Iterator $dirIterator, Container $container) {
+ $worker = new PHPFilterIterator($dirIterator);
foreach($worker as $file) {
- $target = $this->setupTarget($file, $xmlDir);
- if (file_exists($target) && filemtime($target)==$file->getMTime()) {
- $this->logger->progress('cached');
- continue;
- }
try {
- $xml = $analyser->processFile($file);
- $xml->formatOutput= true;
-
- // This is a workaround:
- // Try to reparse generated xml to catch invalid utf-8 byte ranges
- $tmp = new fDOMDocument();
- $tmp->loadXML($xml->saveXML());
-
- $xml->save($target);
- touch($target, $file->getMTime(), $file->getATime());
-
- $src = realpath($file->getPathName());
-
- $container->registerNamespaces($analyser->getNamespaces(), $src, $target);
- $container->registerInterfaces($analyser->getInterfaces(), $src, $target);
- $container->registerClasses($analyser->getClasses(), $src, $target);
-
- $this->cleanUp($container, $xmlDir, $srcDir);
-
- $this->logger->progress('processed');
-
- } catch (fDOMException $e) {
- $this->logger->progress('failed');
+ if ($container->needsUpdate($this->srcIndex, $file)) {
+ $this->processFile($file, $container);
+ $container->registerFile($this->srcIndex, $file);
+ $this->logger->progress('processed');
+ } else {
+ $this->logger->progress('cached');
+ }
} catch (\pdepend\reflection\exceptions\ParserException $e) {
- // TODO: Add failed file to error list?
+ $this->parseErrors[] = $file;
$this->logger->progress('failed');
} catch (\Exception $e) {
- $this->logger->progress('failed');
- throw $e;
+ throw new CollectorException(
+ "Exception processing '" . $file->getPathname() . '."',
+ CollectorException::ProcessingError,
+ $e,
+ $file
+ );
}
}
$this->logger->completed();
-
}
- protected function setupTarget($file, $xmlDir) {
- $path = substr(realpath($file->getPathName()), $this->srcIndex);
- $target = $xmlDir . $path . '.xml';
- $targetDir = dirname($target);
- if (!file_exists($targetDir)) {
- mkdir($targetDir, 0755, true);
+
+ protected function processFile(\SPLFileInfo $file, Container $container) {
+ $info = new \finfo();
+ $encoding = $info->file($file, FILEINFO_MIME_ENCODING);
+
+ $session = new \pdepend\reflection\ReflectionSession();
+ $session->addClassFactory( new \pdepend\reflection\factories\NullReflectionClassFactory() );
+ $query = $session->createFileQuery();
+ $matches = $query->find( $file->getPathname() );
+ $aliasMap = $query->getAliasMap();
+ $classBuilder = $this->factory->getInstanceFor('ClassBuilder', $aliasMap, $this->publicOnly, $encoding);
+
+ foreach ( $matches as $class ) {
+ $dom = $this->getWorkDocument($file);
+ $classBuilder->process($dom, $class);
+ $fname = $this->saveWorkDocument($dom, $class);
+ $container->registerUnit($dom, $fname);
}
- return $target;
}
- /**
- * Helper to cleanup
- *
- * @param Container $container Container xml holding wrapper
- * @param string $xmlDir XML work directory with previously collected xml data
- * @param string $srcDir Source directory to compare xml structures with
- */
- protected function cleanup($container, $xmlDir, $srcDir) {
- $worker = new \RecursiveIteratorIterator(
- new \RecursiveDirectoryIterator($xmlDir, \FilesystemIterator::SKIP_DOTS),
- \RecursiveIteratorIterator::CHILD_FIRST
- );
- $len = strlen($xmlDir);
- $srcPath = dirname($srcDir);
-
- $containers = array('namespaces','classes','interfaces');
-
- $whitelist = array(
- $xmlDir . '/namespaces.xml',
- $xmlDir . '/classes.xml',
- $xmlDir . '/interfaces.xml'
- );
-
- foreach($worker as $fname => $file) {
- $fname = $file->getPathname();
- if (in_array($fname, $whitelist)) {
- continue;
- }
- if ($file->isFile()) {
- $srcFile = $srcPath . substr($fname, $len, -4);
- if (!file_exists($srcFile)) {
- unlink($fname);
- $xml = substr($fname, $len+1);
- foreach($containers as $name) {
- foreach($container->getDocument($name)->query("//phpdox:*[@xml='{$xml}']") as $node) {
- $node->parentNode->removeChild($node);
- }
- }
- }
- } elseif ($file->isDir()) {
- $rmDir = $srcPath . substr($fname, $len);
- if (!file_exists($rmDir)) {
- rmdir($fname);
- }
- }
+ protected function getWorkDocument(\SPLFileInfo $file) {
+ $dom = new fDOMDocument('1.0', 'UTF-8');
+ $dom->preserveWhitespace = true;
+ $dom->registerNamespace('phpdox', 'http://xml.phpdox.de/src#');
+ $root = $dom->createElementNS('http://xml.phpdox.de/src#', 'file');
+ $dom->appendChild($root);
+
+ $head = $root->appendElementNS('http://xml.phpdox.de/src#', 'head');
+ $head->setAttribute('path', $file->getPath());
+ $head->setAttribute('file', $file->getFilename());
+ $head->setAttribute('realpath', $file->getRealPath());
+ $head->setAttribute('size', $file->getSize());
+ $head->setAttribute('time', date('c', $file->getCTime()));
+ $head->setAttribute('unixtime', $file->getCTime());
+ $head->setAttribute('sha1', sha1_file($file->getPathname()));
+
+ return $dom;
+ }
+
+ protected function saveWorkDocument(fDOMDocument $dom, $class) {
+ $path = $this->xmlDir;
+ $path .= $class->isInterface() ? '/interfaces' : '/classes';
+ if (!file_exists($path)) {
+ mkdir($path, 0755, true);
}
+ $name = str_replace('\\','_', $dom->queryOne('//phpdox:class|//phpdox:interface|//phpdox:trait')->getAttribute('full'));
+
+ $fname = $path . '/' . $name . '.xml';
+ $dom->formatOutput = true;
+ $dom->preserveWhiteSpace = true;
+ $dom->save($fname);
+ return $fname;
}
}
+ class CollectorException extends HasFileInfoException {
+ const ProcessingError = 1;
+ }
+
}
View
108 src/collector/Resolver.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Copyright (c) 2010-2012 Arne Blankerts <arne@blankerts.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Arne Blankerts nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package phpDox
+ * @author Arne Blankerts <arne@blankerts.de>
+ * @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
+ * @license BSD License
+ *
+ */
+namespace TheSeer\phpDox {
+
+ use TheSeer\fDOM\fDOMElement;
+ use TheSeer\fDOM\fDOMDocument;
+
+ class Resolver {
+
+ protected $xmlDir;
+ protected $classesDom;
+
+ public function __construct($xmlDir) {
+ $this->xmlDir = $xmlDir;
+ }
+
+ public function run(Container $container) {
+ $this->classesDom = $container->getDocument('classes');
+ $classes = $this->classesDom->query('//phpdox:class');
+ foreach($classes as $classNode) {
+ $dom = $this->initDocument($classNode);
+ $this->process($dom, $classNode);
+ $dom->save($this->xmlDir.'/classes/'. str_replace('\\','_', $classNode->getAttribute('full')) . '.xml');
+ }
+ }
+
+ protected function process(fDOMDocument $dom, \DOMNode $node) {
+ foreach($node->query('.//phpdox:extends') as $extends) {
+ $full = $extends->getAttribute('full');
+ $extNode = $this->classesDom->queryOne('//phpdox:class[@full="' . $full . '"]');
+ if (!$extNode) {
+ /*
+ if ($this->isPHPClass($full)) {
+ // ...
+ }
+ */
+ continue;
+ }
+ $extDom = $this->initDocument($extNode);
+ foreach($extDom->query('//phpdox:method[@visibility != "private" and @abstract="false"]|//phpdox:member[@visibility != "private"]|//phpdox:constant') as $import) {
+ if (!$dom->queryOne('//phpdox:'.$import->localName.'[@name="'.$import->getAttribute('name').'"]')) {
+ $imported = $dom->documentElement->appendChild(
+ $dom->importNode($import, true)
+ );
+ $imported->setAttribute('inherited', $full);
+ $imported->removeAttribute('start');
+ $imported->removeAttribute('end');
+ }
+ }
+ $this->process($dom, $extDom);
+ }
+ }
+
+ protected function initDocument(fDOMElement $node) {
+ $dom = new fDOMDocument();
+ $dom->registerNamespace('phpdox', 'http://xml.phpdox.de/src#');
+
+ $tmp = new fDOMDocument();
+ $tmp->load($this->xmlDir. '/' . $node->getAttribute('xml'));
+ $tmp->registerNamespace('phpdox', 'http://xml.phpdox.de/src#');
+
+ $dom->appendChild(
+ $dom->importNode(
+ $tmp->queryOne('//phpdox:*[@full="' . $node->getAttribute('full') . '"]'),
+ true
+ )
+ );
+
+ return $dom;
+ }
+
+ }
+}
View
169 src/shared/Container.php
@@ -37,7 +37,8 @@
*/
namespace TheSeer\phpDox {
- use \TheSeer\fDom\fDomDocument;
+ use \TheSeer\fDOM\fDOMDocument;
+ use \TheSeer\fDOM\fDOMElement;
class Container {
@@ -69,6 +70,7 @@ public function getWorkDir() {
*/
public function save() {
foreach($this->documents as $fname => $dom) {
+ $dom->formatOutput = true;
$dom->save($fname);
}
}
@@ -86,6 +88,7 @@ public function getDocument($name) {
return $this->documents[$fname];
}
$dom = new fDOMDocument('1.0', 'UTF-8');
+ $dom->preserveWhiteSpace = false;
if (file_exists($fname)) {
$dom->load($fname);
} else {
@@ -98,62 +101,144 @@ public function getDocument($name) {
return $dom;
}
- public function registerNamespaces(array $list, $src, $target) {
- foreach($list as $namespace) {
- $name = $namespace->getAttribute('name');
- $nsNode = $this->getDocument('namespaces')->query("//phpdox:namespace[@name='$name']")->item(0);
- if (!$nsNode) {
- $nsNode = $this->getDocument('namespaces')->documentElement->appendElementNS('http://xml.phpdox.de/src#', 'namespace');
- $nsNode->setAttribute('name', $name);
+ public function needsUpdate($srcIndex, \SplFileInfo $file) {
+ $dom = $this->getDocument('source');
+ $path = dirname(substr($file->getPathname(),$srcIndex));
+ $ctx = $dom->documentElement;
+ foreach(explode('/', $path) as $dir) {
+ $d = $ctx->queryOne('phpdox:dir[@name="'.$dir.'"]');
+ if (!$d) {
+ return true;
}
- $fNode = $this->getDocument('namespaces')->query("//phpdox:namespace[@name='$name']/phpdox:file[@src='$src']")->item(0);
- if (!$fNode) {
- $file = $nsNode->appendElementNS('http://xml.phpdox.de/src#', 'file');
- $file->setAttribute('xml', $target);
- $file->setAttribute('src', $src);
+ $ctx = $d;
+ }
+ $f = $ctx->queryOne('phpdox:file[@name="' . $file->getBasename() . '"]');
+ if (!$f) {
+ return true;
+ }
+ return $file->getCTime() != $f->getAttribute('unixtime');
+ }
+
+ public function registerFile($srcIndex, \SplFileInfo $file) {
+ $dom = $this->getDocument('source');
+ $path = dirname(substr($file->getPathname(),$srcIndex));
+ $ctx = $dom->documentElement;
+ foreach(explode('/', $path) as $dir) {
+ if ($dir=='') {
+ continue;
}
+ $d = $ctx->queryOne('phpdox:dir[@name="'.$dir.'"]');
+ if (!$d) {
+ $d = $ctx->appendElementNS('http://xml.phpdox.de/src#', 'dir');
+ $d->setAttribute('name', $dir);
+ }
+ $ctx = $d;
+ }
+ $f = $ctx->queryOne('phpdox:file[@name="' . $file->getBasename() . '"]');
+ if (!$f) {
+ $f = $ctx->appendElementNS('http://xml.phpdox.de/src#', 'file');
+ $f->setAttribute('name', $file->getBasename());
+ }
+ $update = $file->getCTime() != $f->getAttribute('unixtime');
+ if ($update) {
+ $f->setAttribute('size', $file->getSize());
+ $f->setAttribute('time', date('c', $file->getCTime()));
+ $f->setAttribute('unixtime', $file->getCTime());
+ $f->setAttribute('sha1', sha1_file($file->getPathname()));
+ }
+ return $update;
+ }
+
+ public function registerUnit(fDOMDocument $dom, $fname) {
+ $ctx = $dom->queryOne('//phpdox:class|//phpdox:interface|//phpdox:trait');
+ $node2name = array(
+ 'class' => 'classes',
+ 'interface' => 'interfaces',
+ 'trait' => 'traits',
+ );
+ $container = $this->getDocument($node2name[$ctx->localName]);
+ $head = $dom->queryOne('//phpdox:head');
+
+ $namespace = $ctx->getAttribute('namespace');
+ $target = $container->queryOne('//phpdox:namespace[@name="' . $namespace . '"]');
+ if (!$target) {
+ $target = $container->documentElement->appendElementNS('http://xml.phpdox.de/src#','namespace');
+ $target->setAttribute('name', $namespace);
+ }
+
+ $workNode = $target->queryOne('.//phpdox:' . $ctx->localName . '[@full="' . $ctx->getAttribute('full') . '"]');
+ if ($workNode) {
+ $workNode->parentNode->removeChild($workNode);
+ }
+
+ $workNode = $target->appendElementNS('http://xml.phpdox.de/src#', $ctx->localName);
+ foreach($ctx->attributes as $attr) {
+ $workNode->appendChild($container->importNode($attr, true));
+ }
+ $workNode->setAttribute('xml', substr($fname, strlen($this->xmlDir)+1));
+ $workNode->setAttribute('src', $head->getAttribute('path').'/'.$head->getAttribute('file'));
+ foreach($ctx->query('.//phpdox:implements|.//phpdox:extends') as $node) {
+ $workNode->appendChild($container->importNode($node, true));
}
+
+ $this->registerNamespaces($namespace, $workNode->getAttribute('src'), $workNode->getAttribute('xml'));
}
- public function registerClasses(array $list, $src, $target) {
- $this->registerInContainer($this->getDocument('classes'), 'class', $target, $src, $list);
+ public function cleanup($srcDir) {
+ $ctx = $this->getDocument('source')->queryOne('/phpdox:source/phpdox:dir[1]');
+ $base = dirname($srcDir);
+ $this->checkDir(strlen($base)+1, $base, $ctx);
}
- public function registerInterfaces(array $list, $src, $target) {
- $this->registerInContainer($this->getDocument('interfaces'), 'interface', $target, $src, $list);
+ protected function checkDir($offset, $srcDir, fDOMElement $dir) {
+ $path = $srcDir . '/' . $dir->getAttribute('name');
+ foreach($dir->query('phpdox:file') as $file) {
+ $fname = $path . '/' . $file->getAttribute('name');
+ if (!file_exists( $fname )) {
+ $this->removeFile(substr($fname, $offset));
+ $dir->removeChild($file);
+ }
+ }
+ foreach($dir->query('phpdox:dir') as $sub) {
+ $this->checkDir($offset, $path, $sub);
+ }
+ if (!$dir->hasChildNodes()) {
+ $dir->parentNode->removeChild($dir);
+ }
}
- public function registerTraits(array $list, $src, $target) {
- $this->registerInContainer($this->getDocument('traits'), 'trait', $target, $src, $list);
+ protected function registerNamespaces($namespace, $src, $xml) {
+ $nsDoc = $this->getDocument('namespaces');
+ $nsNode = $nsDoc->queryOne("//phpdox:namespace[@name='$namespace']");
+ if (!$nsNode) {
+ $nsNode = $nsDoc->documentElement->appendElementNS('http://xml.phpdox.de/src#', 'namespace');
+ $nsNode->setAttribute('name', $namespace);
+ }
+ $fNode = $nsNode->queryOne("./phpdox:file[@src='$src']");
+ if (!$fNode) {
+ $file = $nsNode->appendElementNS('http://xml.phpdox.de/src#', 'file');
+ $file->setAttribute('src', $src);
+ $file->setAttribute('xml', $xml);
+ }
}
- protected function registerInContainer(fDomDocument $container, $nodeName, $target, $src, $list) {
- foreach($container->query("//phpdox:*[@src='$src']") as $old) {
- $old->parentNode->removeChild($old);
- }
- foreach($list as $srcNode) {
- if ($srcNode->parentNode->localName == 'namespace') {
- $ns = $srcNode->parentNode->getAttribute('name');
- $ctx = $container->query("//phpdox:namespace[@name='$ns']")->item(0);
- if (!$ctx) {
- $ctx = $container->documentElement->appendElementNS('http://xml.phpdox.de/src#', 'namespace');
- $ctx->setAttribute('name', $srcNode->parentNode->getAttribute('name'));
+ protected function removeFile($fname) {
+ foreach(array('classes','interfaces','traits','namespaces') as $name) {
+ $dom = $this->getDocument($name);
+ $list = $dom->query('//*[@src="'.$fname.'"]');
+ foreach($list as $node) {
+ $xml = $this->xmlDir . '/' . $node->getAttribute('xml');
+ if (file_exists($xml)) {
+ unlink($xml);
+ }
+ $parent = $node->parentNode;
+ $parent->removeChild($node);
+ if ($parent->localName == 'namespace' && !$parent->hasChildNodes()) {
+ $parent->parentNode->removeChild($parent);
}
- } else {
- $ctx = $container->documentElement;
- }
- $workNode = $ctx->appendElementNS('http://xml.phpdox.de/src#', $nodeName);
- foreach($srcNode->attributes as $attr) {
- $workNode->appendChild($container->importNode($attr, true));
- }
- $workNode->setAttribute('xml', substr($target, strlen($this->xmlDir)+1));
- $workNode->setAttribute('src', $src);
- foreach($srcNode->query('.//dox:implements|.//dox:extends') as $node) {
- $workNode->appendChild($container->importNode($node, true));
}
}
}
-
}
}
View
4 src/shared/ErrorHandler.php
@@ -117,6 +117,10 @@ public function handleException(\Exception $exception) {
fwrite(STDERR, sprintf("Location: %s (Line %d)\n\n", $exception->getFile(), $exception->getLine()));
fwrite(STDERR, $exception->getMessage() . "\n\n");
+ if ($exception instanceof HasFileInfoException) {
+ fwrite(STDERR, "\nException occured while processing file: " . $exception->getFile());
+ }
+
$trace = $exception->getTrace();
array_shift($trace);
foreach($trace as $pos => $entry) {
View
16 src/shared/Factory.php
@@ -117,10 +117,6 @@ protected function getCLI() {
return new CLI($this);
}
- protected function getAnalyser($public) {
- return new Analyser($this, $public);
- }
-
protected function getBootstrapApi() {
return new BootstrapApi($this->getEngineFactory(), $this->getDocblockFactory(), $this->getLogger());
}
@@ -140,6 +136,10 @@ protected function getApplication() {
return new Application($this, $this->getLogger());
}
+ protected function getResolver($xmlDir) {
+ return new Resolver($xmlDir);
+ }
+
protected function getContainer($xmlDir) {
if (!isset($this->instances['container'])) {
$this->instances['container'] = array();
@@ -170,16 +170,16 @@ protected function getScanner($include, $exclude = null) {
return $scanner;
}
- protected function getCollector() {
- return new Collector($this->getLogger());
+ protected function getCollector($xmlDir, $public) {
+ return new Collector($this->getLogger(), $this, $xmlDir, $public);
}
protected function getGenerator() {
return new Generator($this->getInstanceFor('EventFactory'), $this->getLogger());
}
- protected function getClassBuilder(fDOMElement $ctx, array $aliasMap, $public, $encoding) {
- return new ClassBuilder($this->getDocblockParser(), $ctx, $aliasMap, $public, $encoding);
+ protected function getClassBuilder(array $aliasMap, $public, $encoding) {
+ return new ClassBuilder($this->getDocblockParser(), $aliasMap, $public, $encoding);
}
protected function getService(AbstractGenerator $generator) {
View
54 src/shared/HasFileInfoException.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright (c) 2010-2012 Arne Blankerts <arne@blankerts.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Arne Blankerts nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT * NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER ORCONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package phpDox
+ * @author Arne Blankerts <arne@blankerts.de>
+ * @copyright Arne Blankerts <arne@blankerts.de>, All rights reserved.
+ * @license BSD License
+ *
+ */
+namespace TheSeer\phpDox {
+
+ abstract class HasFileInfoException extends \Exception {
+
+ protected $file;
+
+ public function __construct($message, $code, \Exception $previous, \SPLFileInfo $file) {
+ parent::__construct($message, $code, $previous);
+ $this->file = $file;
+ }
+
+ public function getFileInfo() {
+ return $this->file;
+ }
+ }
+
+}
Please sign in to comment.
Something went wrong with that request. Please try again.