Skip to content

Commit

Permalink
Allow ignoring exceptions only in global scope
Browse files Browse the repository at this point in the history
  • Loading branch information
bugreportuser authored and muglug committed Apr 17, 2019
1 parent 4abdc15 commit 2e14758
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 6 deletions.
9 changes: 7 additions & 2 deletions config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@

<xs:complexType name="ExceptionsType">
<xs:sequence>
<xs:element name="class" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
<xs:element name="classAndDescendants" minOccurs="0" maxOccurs="unbounded" type="NameAttributeType" />
<xs:element name="class" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
<xs:element name="classAndDescendants" minOccurs="0" maxOccurs="unbounded" type="ExceptionType" />
</xs:sequence>
</xs:complexType>

Expand Down Expand Up @@ -448,4 +448,9 @@
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>

<xs:complexType name="ExceptionType">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="onlyGlobalScope" type="xs:string" />
</xs:complexType>
</xs:schema>
24 changes: 22 additions & 2 deletions src/Psalm/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,21 @@ class Config
*/
public $ignored_exceptions = [];

/**
* @var array<string, bool>
*/
public $ignored_exceptions_in_global_scope = [];

/**
* @var array<string, bool>
*/
public $ignored_exceptions_and_descendants = [];

/**
* @var array<string, bool>
*/
public $ignored_exceptions_and_descendants_in_global_scope = [];

/**
* @var array<string, bool>
*/
Expand Down Expand Up @@ -697,13 +707,23 @@ public static function loadFromXML($base_dir, $file_contents)
if (isset($config_xml->ignoreExceptions->class)) {
/** @var \SimpleXMLElement $exception_class */
foreach ($config_xml->ignoreExceptions->class as $exception_class) {
$config->ignored_exceptions[(string) $exception_class['name']] = true;
$exception_name = (string) $exception_class['name'];
$global_attribute_text = (string) $exception_class['onlyGlobalScope'];
if ($global_attribute_text !== 'true' && $global_attribute_text !== '1') {
$config->ignored_exceptions[$exception_name] = true;
}
$config->ignored_exceptions_in_global_scope[$exception_name] = true;
}
}
if (isset($config_xml->ignoreExceptions->classAndDescendants)) {
/** @var \SimpleXMLElement $exception_class */
foreach ($config_xml->ignoreExceptions->classAndDescendants as $exception_class) {
$config->ignored_exceptions_and_descendants[(string) $exception_class['name']] = true;
$exception_name = (string) $exception_class['name'];
$global_attribute_text = (string) $exception_class['onlyGlobalScope'];
if ($global_attribute_text !== 'true' && $global_attribute_text !== '1') {
$config->ignored_exceptions_and_descendants[$exception_name] = true;
}
$config->ignored_exceptions_and_descendants_in_global_scope[$exception_name] = true;
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/Psalm/Internal/Analyzer/StatementsAnalyzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -1700,11 +1700,16 @@ public function getUncaughtThrows(Context $context)

if ($context->collect_exceptions) {
if ($context->possibly_thrown_exceptions) {
$config = $this->codebase->config;
$ignored_exceptions = array_change_key_case(
$this->codebase->config->ignored_exceptions
$context->is_global ?
$config->ignored_exceptions_in_global_scope :
$config->ignored_exceptions
);
$ignored_exceptions_and_descendants = array_change_key_case(
$this->codebase->config->ignored_exceptions_and_descendants
$context->is_global ?
$config->ignored_exceptions_and_descendants_in_global_scope :
$config->ignored_exceptions_and_descendants
);

foreach ($context->possibly_thrown_exceptions as $possibly_thrown_exception => $codelocations) {
Expand Down
82 changes: 82 additions & 0 deletions tests/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1241,4 +1241,86 @@ function example4(): void {

$this->analyzeFile($file_path, new Context());
}

/**
* @return void
*/
public function testIgnoreExceptions()
{
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
TestConfig::loadFromXML(
dirname(__DIR__),
'<?xml version="1.0"?>
<psalm checkForThrowsDocblock="true" checkForThrowsInGlobalScope="true">
<ignoreExceptions>
<class name="Exc1" />
<class name="Exc2" onlyGlobalScope="true" />
<classAndDescendants name="Exc3" />
<classAndDescendants name="Exc4" onlyGlobalScope="true" />
</ignoreExceptions>
</psalm>'
)
);

$file_path = getcwd() . '/src/somefile.php';

$this->addFile(
$file_path,
'<?php
class Exc1 extends Exception {}
class Exc2 extends Exception {}
class Exc3 extends Exception {}
class Exc4 extends Exception {}
throw new Exc1();
throw new Exc2();
throw new Exc3();
throw new Exc4();
function example() : void {
throw new Exc1();
throw new Exc3();
}'
);

$this->analyzeFile($file_path, new Context());
}

/**
* @expectedException \Psalm\Exception\CodeException
* @expectedExceptionMessage MissingThrowsDocblock
*
* @return void
*/
public function testNotIgnoredException()
{
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
TestConfig::loadFromXML(
dirname(__DIR__),
'<?xml version="1.0"?>
<psalm checkForThrowsDocblock="true" checkForThrowsInGlobalScope="true">
<ignoreExceptions>
<class name="Exc1" />
<class name="Exc2" onlyGlobalScope="true" />
<classAndDescendants name="Exc3" />
<classAndDescendants name="Exc4" onlyGlobalScope="true" />
</ignoreExceptions>
</psalm>'
)
);

$file_path = getcwd() . '/src/somefile.php';

$this->addFile(
$file_path,
'<?php
class Exc2 extends Exception {}
function example() : void {
throw new Exc2();
}'
);

$this->analyzeFile($file_path, new Context());
}
}

0 comments on commit 2e14758

Please sign in to comment.