Skip to content

Commit 6ce9cc3

Browse files
committed
- Enhance collector code to provide affected units for inheritance resolving
- Skip resolving if no files got changed - Add import() method for AbstractUnitObject - Fix ParseError Handling
1 parent 7643cec commit 6ce9cc3

10 files changed

+140
-49
lines changed

src/Application.php

+6-6
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,9 @@ public function runCollector(CollectorConfig $config) {
127127
$project = $collector->run($scanner, $backend);
128128

129129
if ($collector->hasParseErrors()) {
130-
$this->logger->log('Parse errors during processing:');
131-
foreach($collector->getParseErrors() as $file) {
132-
$this->logger->log(' - ' . $file->getPathname());
130+
$this->logger->log('The following file(s) had errors during processing and were excluded:');
131+
foreach($collector->getParseErrors() as $file => $message) {
132+
$this->logger->log(' - ' . $file . ' (' . $message . ')');
133133
}
134134
}
135135

@@ -138,12 +138,12 @@ public function runCollector(CollectorConfig $config) {
138138
if ($vanished > 0) {
139139
$this->logger->log("Removed $vanished vanished file(s) from project");
140140
}
141-
141+
$changed = $project->save();
142142
if ($config->doResolveInheritance()) {
143-
$this->factory->getInstanceFor('InheritanceResolver')->resolve($project, $config->getInheritanceConfig());
143+
$this->factory->getInstanceFor('InheritanceResolver')->resolve($changed, $project, $config->getInheritanceConfig());
144144
}
145145

146-
$project->save();
146+
147147
$this->logger->log('Collector process completed');
148148
}
149149

src/collector/Collector.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
use TheSeer\DirectoryScanner\DirectoryScanner;
4040
use TheSeer\phpDox\ProgressLogger;
4141
use TheSeer\phpDox\Collector\Backend\BackendInterface;
42+
use TheSeer\phpDox\Collector\Backend\ParseErrorException;
4243
use TheSeer\phpDox\Project\Project;
4344

4445
/**
@@ -92,7 +93,9 @@ public function run(DirectoryScanner $scanner, BackendInterface $backend) {
9293
$this->logger->progress('cached');
9394
continue;
9495
}
95-
$this->processFile($file);
96+
if (!$this->processFile($file)) {
97+
$this->project->removeFile($file);
98+
}
9699
}
97100
$this->logger->completed();
98101
return $this->project;
@@ -134,9 +137,11 @@ private function processFile(\SplFileInfo $file) {
134137
}
135138
}
136139
$this->logger->progress('processed');
137-
} catch (ParseError $e) {
138-
$this->parseErrors[$file->getPathname()] = $e;
140+
return true;
141+
} catch (ParseErrorException $e) {
142+
$this->parseErrors[$file->getPathname()] = $e->getPrevious()->getMessage();
139143
$this->logger->progress('failed');
144+
return false;
140145
} catch (\Exception $e) {
141146
throw new CollectorException('Error while processing source file', CollectorException::ProcessingError, $e, $file);
142147
}

src/collector/InheritanceResolver.php

+4-5
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,13 @@ public function __construct(ProgressLogger $logger) {
5353
$this->logger = $logger;
5454
}
5555

56-
public function resolve(Project $project, \TheSeer\phpDox\InheritanceConfig $config) {
56+
public function resolve(Array $changed, Project $project, \TheSeer\phpDox\InheritanceConfig $config) {
57+
if (count($changed) == 0) {
58+
return;
59+
}
5760
$this->logger->reset();
5861
$this->logger->log("Resolving inheritance\n");
59-
60-
61-
6262
$this->logger->completed();
63-
6463
}
6564

6665
}

src/collector/backend/ParseErrorException.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@
3636
*/
3737
namespace TheSeer\phpDox\Collector\Backend {
3838

39-
4039
class ParseErrorException extends \Exception {
41-
const UnexpectedExpr = 1;
40+
const GeneralParseError = 1;
4241
}
4342

4443
}

src/collector/backend/ParseResult.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function getFileName() {
8181
* @return ClassObject
8282
*/
8383
public function addClass($name) {
84-
$obj = new ClassObject($this->file, $name);
84+
$obj = new ClassObject($name, $this->file);
8585
$this->classes[$name] = $obj;
8686
return $obj;
8787
}
@@ -91,7 +91,7 @@ public function addClass($name) {
9191
* @return InterfaceObject
9292
*/
9393
public function addInterface($name) {
94-
$obj = new InterfaceObject($this->file, $name);
94+
$obj = new InterfaceObject($name, $this->file);
9595
$this->interfaces[$name] = $obj;
9696
return $obj;
9797
}
@@ -101,7 +101,7 @@ public function addInterface($name) {
101101
* @return TraitObject
102102
*/
103103
public function addTrait($name) {
104-
$obj = new TraitObject($this->file, $name);
104+
$obj = new TraitObject($name, $this->file);
105105
$this->traits[$name] = $obj;
106106
return $obj;
107107
}

src/collector/backend/parser/PHPParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public function parse(\SplFileInfo $file) {
8181
$this->getTraverserInstance($result)->traverse($nodes);
8282
return $result;
8383
} catch (\Exception $e) {
84-
throw new ParseErrorException('Something went wrwong', 1, $e);
84+
throw new ParseErrorException('Something went wrwong', ParseErrorException::GeneralParseError, $e);
8585
}
8686
}
8787

src/project/AbstractUnitObject.php

+15-5
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,23 @@ abstract class AbstractUnitObject {
6767
protected $rootName = NULL;
6868

6969
/**
70-
* @param \SplFileInfo $file
7170
* @param string $name
71+
* @param \SplFileInfo $file
7272
*/
73-
public function __construct(\SplFileInfo $file, $name) {
73+
public function __construct($name = NULL, \SplFileInfo $file = NULL) {
7474
if ($this->rootName === NULL) {
7575
throw new UnitObjectException('No or invalid rootname set', UnitObjectException::InvalidRootname);
7676
}
7777
$this->dom = new fDOMDocument('1.0', 'UTF-8');
7878
$this->dom->registerNamespace('phpdox', self::XMLNS);
7979
$this->rootNode = $this->dom->createElementNS(self::XMLNS, $this->rootName);
8080
$this->dom->appendChild($this->rootNode);
81-
$this->setFileHeader($file);
82-
$this->setName($name);
81+
if ($name !== NULL) {
82+
$this->setName($name);
83+
}
84+
if ($file !== NULL) {
85+
$this->setFileHeader($file);
86+
}
8387
$this->setAbstract(FALSE);
8488
$this->setFinal(FALSE);
8589
}
@@ -96,7 +100,6 @@ private function setFileHeader(\SplFileInfo $file) {
96100
$fileNode->setAttribute('time', date('c',$file->getMTime()));
97101
$fileNode->setAttribute('unixtime', $file->getMTime());
98102
$fileNode->setAttribute('sha1', sha1_file($file->getRealPath()));
99-
100103
}
101104

102105
/**
@@ -118,6 +121,13 @@ public function export() {
118121
return $this->dom;
119122
}
120123

124+
/**
125+
* @param \TheSeer\fDOM\fDOMDocument $dom
126+
*/
127+
public function import(fDOMDocument $dom) {
128+
$this->dom = $dom;
129+
}
130+
121131
/**
122132
* @return string
123133
*/

src/project/IndexCollection.php

+30-17
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
/**
4242
*
4343
*/
44-
class IndexCollection implements DOMCollectionInterface {
44+
class IndexCollection {
4545

4646
/**
4747
* @var array
@@ -122,35 +122,48 @@ public function getAddedUnits() {
122122
* @param $path
123123
* @return \DOMNodeList
124124
*/
125-
public function getUnitsBySrcFile($path) {
125+
public function findUnitNodesBySrcFile($path) {
126126
return $this->getRootElement()->query(sprintf('//*[@src="%s"]',$path));
127127
}
128128

129+
/**
130+
* @param $namespace
131+
* @param $name
132+
*
133+
* @return fDOMElement
134+
* @throws IndexCollectionException
135+
*/
136+
public function findUnitNodeByName($namespace, $name) {
137+
return $this->getRootElement()->queryOne(
138+
sprintf('//phpdox:namespace[@name="%s"]/*[@name="%s"]', $namespace, $name));
139+
}
140+
129141
/**
130142
* @param AbstractUnitObject $unit
131143
*/
132-
protected function addUnit(AbstractUnitObject $unit, $type) {
144+
private function addUnit(AbstractUnitObject $unit, $type) {
133145
$root = $this->getRootElement();
134146
$this->addedUnits[$unit->getFullName()] = $unit;
135147

136-
$unitNode = $root->appendElementNS('http://xml.phpdox.de/src#', $type);
137-
$unitNode->setAttribute('name', $unit->getName());
138-
$unitNode->setAttribute('src', $unit->getSourceFilename());
139-
140-
$xpath = 'phpdox:namespace[@name="' . $unit->getNamespace() . '"]';
141-
$ctx = $root->queryOne($xpath);
142-
if (!$ctx) {
143-
$ctx = $root->appendElementNS('http://xml.phpdox.de/src#', 'namespace');
144-
$ctx->setAttribute('name', $unit->getNamespace());
145-
}
146-
$name = $unit->getName();
147-
if ($old = $ctx->queryOne("*[@name = '{$name}']")) {
148-
$ctx->replaceChild($unitNode, $old);
149-
} else {
148+
if (!$this->findUnitNodeByName($unit->getNamespace(), $unit->getName())) {
149+
$unitNode = $root->appendElementNS('http://xml.phpdox.de/src#', $type);
150+
$unitNode->setAttribute('name', $unit->getName());
151+
$unitNode->setAttribute('src', $unit->getSourceFilename());
152+
153+
$xpath = 'phpdox:namespace[@name="' . $unit->getNamespace() . '"]';
154+
$ctx = $root->queryOne($xpath);
155+
if (!$ctx) {
156+
$ctx = $root->appendElementNS('http://xml.phpdox.de/src#', 'namespace');
157+
$ctx->setAttribute('name', $unit->getNamespace());
158+
}
150159
$ctx->appendChild($unitNode);
151160
}
152161
}
153162

154163
}
155164

165+
class IndexCollectionException extends \Exception {
166+
167+
}
168+
156169
}

src/project/Project.php

+66-7
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@
3737
namespace TheSeer\phpDox\Project {
3838

3939
use TheSeer\fDOM\fDOMDocument;
40+
use TheSeer\fDOM\fDOMElement;
4041

4142
/**
4243
*
4344
*/
44-
class Project {
45+
class Project extends \TheSeer\phpDox\Application {
4546

4647
/**
4748
* @var string
@@ -99,6 +100,12 @@ public function addFile(\SplFileInfo $file) {
99100
return $isNew;
100101
}
101102

103+
104+
public function removeFile(\SplFileInfo $file) {
105+
$this->removeFileReferences($file->getPathname());
106+
$this->source->removeFile($file);
107+
}
108+
102109
/**
103110
* @param ClassObject $class
104111
*/
@@ -199,18 +206,24 @@ public function save() {
199206
}
200207
$indexDom = $this->index->export();
201208
$newUnits = $this->index->getAddedUnits();
209+
$reportUnits = $newUnits;
202210
foreach($newUnits as $unit) {
211+
$indexNode = $indexDom->queryOne(
212+
sprintf('//phpdox:namespace[@name="%s"]/*[@name="%s"]',
213+
$unit->getNamespace(),
214+
$unit->getName())
215+
);
203216
$name = str_replace('\\', '_', $unit->getFullName());
204217
$dom = $unit->export();
205218
$dom->formatOutput = TRUE;
206219
$dom->preserveWhiteSpace = FALSE;
207220
$fname = $map[$dom->documentElement->localName] . '/' . $name . '.xml';
221+
if ($indexNode->hasAttribute('xml')) {
222+
$reportUnits = array_merge($reportUnits, $this->findAffectedUnits($fname));
223+
} else {
224+
$indexNode->setAttribute('xml', $fname);
225+
}
208226
$dom->save($this->xmlDir . '/' . $fname);
209-
210-
$indexDom->queryOne(sprintf('//phpdox:namespace[@name="%s"]/*[@name="%s"]',
211-
$unit->getNamespace(),
212-
$unit->getName())
213-
)->setAttribute('xml', $fname);
214227
}
215228
$indexDom->formatOutput = TRUE;
216229
$indexDom->preserveWhiteSpace = FALSE;
@@ -220,6 +233,52 @@ public function save() {
220233
$sourceDom->formatOutput = TRUE;
221234
$sourceDom->preserveWhiteSpace = FALSE;
222235
$sourceDom->save($this->xmlDir . '/source.xml');
236+
237+
return $reportUnits;
238+
}
239+
240+
/**
241+
* @param $fname
242+
*
243+
* @return array
244+
*/
245+
private function findAffectedUnits($fname) {
246+
$affected = array();
247+
$dom = new fDOMDocument();
248+
$dom->load($this->xmlDir . '/' . $fname);
249+
$dom->registerNamespace('phpdox', 'http://xml.phpdox.de/src#');
250+
$extends = $dom->queryOne('//phpdox:extends');
251+
if ($extends instanceof fDOMElement) {
252+
$unitNode = $this->index->findUnitNodeByName(
253+
$extends->getAttribute('namespace'), $extends->getAttribute('class')
254+
);
255+
if ($unitNode) {
256+
$unitDom = new fDOMDocument();
257+
$unitDom->load($this->xmlDir . '/' . $unitNode->getAttribute('xml'));
258+
$unitDom->registerNamespace('phpdox', 'http://xml.phpdox.de/src#');
259+
if ($unitDom->documentElement->nodeName == 'class') {
260+
$unit = new ClassObject();
261+
} else {
262+
$unit = new TraitObject();
263+
}
264+
$unit->import($unitDom);
265+
$affected[$extends->getAttribute('full')] = $unit;
266+
}
267+
}
268+
$implements = $dom->query('//phpdox:implements');
269+
foreach($implements as $implement) {
270+
$unitNode = $this->index->findUnitNodeByName(
271+
$implement->getAttribute('namespace'), $implement->getAttribute('class')
272+
);
273+
if ($unitNode) {
274+
$unitDom = new fDOMDocument();
275+
$unitDom->load($this->xmlDir . '/' . $unitNode->getAttribute('xml'));
276+
$unit = new InterfaceObject();
277+
$unit->import($unitDom);
278+
$affected[$implement->getAttribute('full')] = $unit;
279+
}
280+
}
281+
return $affected;
223282
}
224283

225284
/**
@@ -248,7 +307,7 @@ private function initCollections() {
248307
* @param string $path
249308
*/
250309
private function removeFileReferences($path) {
251-
foreach($this->index->getUnitsBySrcFile($path) as $node) {
310+
foreach($this->index->findUnitNodesBySrcFile($path) as $node) {
252311
/** @var $node \DOMElement */
253312
$fname = $this->xmlDir . '/' . $node->getAttribute('xml');
254313
if (file_exists($fname)) {

src/project/SourceCollection.php

+6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ public function addFile(\SplFileInfo $file) {
7676
return $this->isChanged($relPath);
7777
}
7878

79+
public function removeFile(\SplFileInfo $file) {
80+
$relPath = realpath($file->getPathname());
81+
$relPath = substr($relPath, strlen(dirname($this->srcDir))+1);
82+
unset($this->collection[$relPath]);
83+
}
84+
7985
public function getChangedFiles() {
8086
$list = array();
8187
foreach(array_keys($this->collection) as $path) {

0 commit comments

Comments
 (0)