Skip to content

Commit

Permalink
Unclosed array expression should throw exception
Browse files Browse the repository at this point in the history
In the current implementation we do not take into account that people may try
the following notation:

    `@var array(string => string|null)`

At the moment this is interpreted as an Array Expression but fails because the
space causes the parser to see this as `array(string`, meaning an unclosed
array expression.

This change introduces a new RuntimeException that is thrown in this situation,
it is up to the consumer of this library to deal with this situation however it
deems best.
  • Loading branch information
mvriel committed Sep 25, 2018
1 parent 8049085 commit 9c0562f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
27 changes: 13 additions & 14 deletions src/TypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ final class TypeResolver
/** @var string Definition of the NAMESPACE operator in PHP */
const OPERATOR_NAMESPACE = '\\';

/** @var integer the iterator parser is inside a compound context */
/** @var int the iterator parser is inside a compound context */
const PARSER_IN_COMPOUND = 0;

/** @var integer the iterator parser is inside a nullable expression context */
/** @var int the iterator parser is inside a nullable expression context */
const PARSER_IN_NULLABLE = 1;

/** @var integer the iterator parser is inside an array expression context */
/** @var int the iterator parser is inside an array expression context */
const PARSER_IN_ARRAY_EXPRESSION = 2;

/** @var integer the iterator parser is inside a collection expression context */
/** @var int the iterator parser is inside a collection expression context */
const PARSER_IN_COLLECTION_EXPRESSION = 3;

/** @var string[] List of recognized keywords and unto which Value Object they map */
Expand Down Expand Up @@ -176,18 +176,21 @@ private function parseTypes(\ArrayIterator $tokens, Context $context, $parserCon

$resolvedType = new Array_($type);

// we generates arrays corresponding to the number of '[]'
// after the ')'
$numberOfArrays = (strlen($tokens->current()) - 1) / 2;
$token = $tokens->current();
// Someone did not properly close their array expression ..
if ($token === null) {
break;
}

// we generate arrays corresponding to the number of '[]' after the ')'
$numberOfArrays = (strlen($token) - 1) / 2;
for ($i = 0; $i < $numberOfArrays - 1; ++$i) {
$resolvedType = new Array_($resolvedType);
}

$types[] = $resolvedType;
$tokens->next();
} elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION
&& $token[0] === ')'
) {
} elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION && $token[0] === ')') {
break;
} elseif ($token === '<') {
if (count($types) === 0) {
Expand Down Expand Up @@ -241,10 +244,6 @@ private function parseTypes(\ArrayIterator $tokens, Context $context, $parserCon
'A type is missing in a collection expression'
);
}

throw new \RuntimeException(
'No types in a compound list'
);
} elseif (count($types) === 1) {
return $types[0];
}
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/TypeResolverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,29 @@ public function testResolvingArrayOfArrayExpressionTypes()
$this->assertInstanceOf(Object_::class, $secondType);
}

/**
* @covers ::__construct
* @covers ::resolve
* @covers ::<private>
*
* @uses \phpDocumentor\Reflection\Types\Context
* @uses \phpDocumentor\Reflection\Types\Compound
* @uses \phpDocumentor\Reflection\Types\Array_
* @uses \phpDocumentor\Reflection\Types\Object_
* @uses \phpDocumentor\Reflection\Fqsen
* @uses \phpDocumentor\Reflection\FqsenResolver
*/
public function testReturnEmptyCompoundOnAnUnclosedArrayExpressionType()
{
$fixture = new TypeResolver();

/** @var Compound $resolvedType */
$resolvedType = $fixture->resolve('(string|\stdClass', new Context(''));

$this->assertInstanceOf(Compound::class, $resolvedType);
$this->assertSame('', (string)$resolvedType);
}

/**
* @covers ::__construct
* @covers ::resolve
Expand Down

0 comments on commit 9c0562f

Please sign in to comment.