Skip to content

Commit

Permalink
Fixes issue #208
Browse files Browse the repository at this point in the history
  • Loading branch information
theseer committed Mar 19, 2015
1 parent 4369b37 commit 6169f3b
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 78 deletions.
161 changes: 90 additions & 71 deletions src/collector/backend/parser/UnitCollectingVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,15 @@ private function processMethodParams(MethodObject $method, array $params) {
private function processClassConstant(NodeType\ClassConst $node) {
$constNode = $node->consts[0];
$const = $this->unit->addConstant($constNode->name);
$const->setValue($constNode->getAttribute('originalValue'));

$resolved = $this->resolveExpressionValue($constNode->value);

$const->setType($resolved['type']);
$const->setValue($resolved['value']);
if (isset($resolved['constant'])) {
$const->setConstantReference($resolved['constant']);
}

$docComment = $node->getDocComment();
if ($docComment !== NULL) {
$block = $this->docBlockParser->parse($docComment, $this->aliasMap);
Expand Down Expand Up @@ -330,87 +338,98 @@ private function setVariableType(AbstractVariableObject $variable, $type = NULL)
$variable->setType($type);
}

/**
* @param AbstractVariableObject $variable
* @param \PhpParser\Node\Expr $default
* @return string
*/
private function setVariableDefaultValue(AbstractVariableObject $variable, \PhpParser\Node\Expr $default = NULL) {
if ($default === NULL) {
return;
}
if ($default instanceof \PhpParser\Node\Scalar\String) {
$variable->setDefault($default->getAttribute('originalValue'));
if ($variable->getType() == '{unknown}') {
$variable->setType('string');
}
return;
}
if ($default instanceof \PhpParser\Node\Scalar\LNumber ||
$default instanceof \PhpParser\Node\Expr\UnaryMinus ||
$default instanceof \PhpParser\Node\Expr\UnaryPlus) {
$variable->setDefault($default->getAttribute('originalValue'));
if ($variable->getType() == '{unknown}') {
$variable->setType('integer');
}
return;
}
if ($default instanceof \PhpParser\Node\Scalar\DNumber) {
$variable->setDefault($default->getAttribute('originalValue'));
if ($variable->getType() == '{unknown}') {
$variable->setType('float');
}
return;
}
if ($default instanceof \PhpParser\Node\Expr\Array_) {
//var_dump($default);
//$parameter->setDefault(join('\\', $default->items));
if ($variable->getType() == '{unknown}') {
$variable->setType('array');
}
return;
private function resolveExpressionValue(\PhpParser\Node\Expr $expr) {
if ($expr instanceof \PhpParser\Node\Scalar\String) {
return array(
'type' => 'string',
'value' => $expr->getAttribute('originalValue')
);
}
if ($default instanceof \PhpParser\Node\Expr\ClassConstFetch) {
$variable->setDefault(join('\\', $default->class->parts) . '::' . $default->name);
return;

if ($expr instanceof \PhpParser\Node\Scalar\LNumber ||
$expr instanceof \PhpParser\Node\Expr\UnaryMinus ||
$expr instanceof \PhpParser\Node\Expr\UnaryPlus) {
return array(
'type' => 'integer',
'value' => $expr->getAttribute('originalValue')
);
}
if ($default instanceof \PhpParser\Node\Expr\ConstFetch) {
$variable->setDefault(join('\\', $default->name->parts));
return;

if ($expr instanceof \PhpParser\Node\Scalar\DNumber) {
return array(
'type' => 'float',
'value' => $expr->getAttribute('originalValue')
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Trait_) {
$variable->setName('__TRAIT__');
return;

if ($expr instanceof \PhpParser\Node\Expr\Array_) {
return array(
'type' => 'array',
'value' => '' // @todo add array2xml?
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Class_) {
$variable->setDefault('__CLASS__');
return;

if ($expr instanceof \PhpParser\Node\Expr\ClassConstFetch) {
return array(
'type' => '{unknown}',
'value' => '',
'constant' => join('\\', $expr->class->parts) . '::' . $expr->name
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Method) {
$variable->setName('__METHOD__');
return;

if ($expr instanceof \PhpParser\Node\Expr\ConstFetch) {
$reference = join('\\', $expr->name->parts);
if (in_array(strtolower($reference),array('true','false'))) {
return array(
'type' => 'boolean',
'value' => $reference
);
}
return array(
'type' => '{unknown}',
'value' => '',
'constant' => join('\\', $expr->name->parts)
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Dir) {
$variable->setName('__DIR__');
return;

if ($expr instanceof \PhpParser\Node\Scalar\MagicConst\Line) {
return array(
'type' => 'integer',
'value' => '',
'constant' => $expr->getName()
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\File) {
$variable->setName('__FILE__');
return;

if ($expr instanceof \PhpParser\Node\Scalar\MagicConst) {
return array(
'type' => 'string',
'value' => '',
'constant' => $expr->getName()
);
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Function_) {
$variable->setName('__FUNC__');

$type = get_class($expr);
$line = $expr->startLine;
$file = $this->result->getFileName();
throw new ParseErrorException("Unexpected expression type '$type' for value in line $line of file '$file'", ParseErrorException::UnexpectedExpr);

}

/**
* @param AbstractVariableObject $variable
* @param \PhpParser\Node\Expr $default
* @return string
*/
private function setVariableDefaultValue(AbstractVariableObject $variable, \PhpParser\Node\Expr $default = NULL) {
if ($default === NULL) {
return;
}
if ($default instanceof \PhpParser\Node\Scalar\MagicConst\Line) {
$variable->setName('__LINE__');
return;
$resolved = $this->resolveExpressionValue($default);
$variable->setType($resolved['type']);
$variable->setDefault($resolved['value']);
if (isset($resolved['constant'])) {
$variable->setConstant($resolved['constant']);
}

$type = get_class($default);
$line = $default->startLine;
$file = $this->result->getFileName();
throw new ParseErrorException("Unexpected expression type '$type' for default value in line $line of file '$file'", ParseErrorException::UnexpectedExpr);
}

}
Expand Down
4 changes: 4 additions & 0 deletions src/collector/project/AbstractVariableObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public function setDefault($value) {
$this->ctx->setAttribute('default', $value);
}

public function setConstant($const) {
$this->ctx->setAttribute('constant', $const);
}

/**
* @param $type
*/
Expand Down
9 changes: 9 additions & 0 deletions src/collector/project/ConstantObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class ConstantObject {

public function __construct(fDOMElement $ctx) {
$this->ctx = $ctx;
$this->setType('{unknown}');
}

public function export() {
Expand All @@ -59,6 +60,14 @@ public function setValue($value) {
$this->ctx->setAttribute('value', $value);
}

public function setType($type) {
$this->ctx->setAttribute('type', $type);
}

public function setConstantReference($const) {
$this->ctx->setAttribute('constant', $const);
}

public function setDocBlock(DocBlock $docblock) {
$docNode = $docblock->asDom($this->ctx->ownerDocument);
if ($this->ctx->hasChildNodes()) {
Expand Down
5 changes: 4 additions & 1 deletion templates/html/components.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,10 @@
<xsl:for-each select="//pdx:constant">
<tr>
<td id="{@name}"><xsl:value-of select="@name" /></td>
<td><xsl:value-of select="@value" /></td>
<td><xsl:choose>
<xsl:when test="@value = ''"><xsl:value-of select="@constant" /></xsl:when>
<xsl:otherwise><xsl:value-of select="@value" /></xsl:otherwise>
</xsl:choose></td>
</tr>
</xsl:for-each>
</tbody>
Expand Down
8 changes: 6 additions & 2 deletions templates/html/method.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@

<xsl:template name="parameter">
<xsl:param name="param" />

<xsl:if test="$param/@default">[</xsl:if>
<xsl:choose>
<xsl:when test="$param/@type = 'object'">
Expand All @@ -213,10 +214,13 @@
</xsl:choose>
<xsl:if test="$param/@byreference = 'true'">&amp;</xsl:if>
$<xsl:value-of select="$param/@name" />
<xsl:if test="$param/@default"> = <xsl:value-of select="$param/@default" /></xsl:if>
<xsl:if test="$param/@default"> = <xsl:choose>
<xsl:when test="$param/@default = ''"><xsl:value-of select="$param/@constant" /></xsl:when>
<xsl:otherwise><xsl:value-of select="$param/@default" /></xsl:otherwise>
</xsl:choose></xsl:if>
<xsl:if test="$param/following-sibling::pdx:parameter">,
<xsl:call-template name="parameter">
<xsl:with-param name="param" select="$param/following-sibling::pdx:parameter" />
<xsl:with-param name="param" select="($param/following-sibling::pdx:parameter)[1]" />
</xsl:call-template>
</xsl:if>
<xsl:if test="$param/@default">]</xsl:if>
Expand Down
17 changes: 13 additions & 4 deletions templates/html/synopsis.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@
<ul class="none">
<li>// constants</li>
<xsl:for-each select="$unit/pdx:constant">
<li>const <xsl:value-of select="@name" /> = <xsl:value-of select="@value" />;</li>
<li>const <xsl:value-of select="@name" /> = <xsl:choose>
<xsl:when test="@value = ''"><xsl:value-of select="@constant" /></xsl:when>
<xsl:otherwise><xsl:value-of select="@value" /></xsl:otherwise>
</xsl:choose>;</li>
</xsl:for-each>
</ul>
</xsl:if>
Expand All @@ -45,18 +48,24 @@
<ul class="none">
<li>// Inherited constants from <xsl:copy-of select="pdxf:link(., '', @name)" /></li>
<xsl:for-each select="pdx:constant">
<li>const <a href="#{@name}"><xsl:value-of select="@name" /></a> = <xsl:value-of select="@value" />;</li>
<li>const <a href="#{@name}"><xsl:value-of select="@name" /></a> = <xsl:choose>
<xsl:when test="@value = ''"><xsl:value-of select="@constant" /></xsl:when>
<xsl:otherwise><xsl:value-of select="@value" /></xsl:otherwise>
</xsl:choose>;</li>
</xsl:for-each>
</ul>
</xsl:for-each>


<xsl:if test="$unit/pdx:member">
<ul class="none">
<li>// members</li>
<xsl:for-each select="$unit/pdx:member">
<li>
<xsl:value-of select="@visibility" /><xsl:if test="@static = 'true'">&#160;static</xsl:if><xsl:call-template name="vartype" />&#160;<a href="#members">$<xsl:value-of select="@name" /></a>;
<xsl:value-of select="@visibility" /><xsl:if test="@static = 'true'">&#160;static</xsl:if><xsl:call-template name="vartype" />&#160;<a href="#members">$<xsl:value-of select="@name" /></a><xsl:if test="@default or @constant"> =
<xsl:choose>
<xsl:when test="@default = ''"> <xsl:value-of select="@constant" /></xsl:when>
<xsl:otherwise><xsl:value-of select="@default" /></xsl:otherwise>
</xsl:choose></xsl:if>;
</li>
</xsl:for-each>
</ul>
Expand Down
24 changes: 24 additions & 0 deletions tests/data/issue208/src/code.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

const X='def';
const Y='ghi';

class Issue {
const FooTrue = true;
const FooFalse = false;
const FooString = 'abc';
const FooInt = 123;
const FooX = \X;
const FooY = Y;
const FooMagic = __FILE__;

private $fooTrue = true;
private $fooFalse = false;
private $fooString = 'abc';
private $fooInt = 123;
private $fooX = \X;
private $fooY = Y;
private $fooMagic = __FILE__;

public function foo($a = TRUE, $b = FALSE, $c = \X, $d = Y, $e = __FILE__) {}
}
15 changes: 15 additions & 0 deletions tests/data/issue208/test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<phpdox xmlns="http://xml.phpdox.net/config" silent="false">

<project name="phpDox-issue208" source="${basedir}/src" workdir="${basedir}/xml">

<collector publiconly="false" backend="parser" />

<generator output="${basedir}/docs">
<build engine="html" enabled="true" output="html" />
<build engine="xml" enabled="true" output="xml" />
</generator>

</project>

</phpdox>

0 comments on commit 6169f3b

Please sign in to comment.