Skip to content

Commit

Permalink
Merge pull request #7433 from zoonru/maximum_shaped_array_size
Browse files Browse the repository at this point in the history
Add configuration for maximum size of shaped array
  • Loading branch information
orklah committed Mar 15, 2022
2 parents 32f10c3 + e7ec124 commit ebffd52
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 4 deletions.
1 change: 1 addition & 0 deletions config.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<xs:attribute name="cacheDirectory" type="xs:string" />
<xs:attribute name="errorBaseline" type="xs:string" />
<xs:attribute name="maxStringLength" type="xs:string" />
<xs:attribute name="maxShapedArraySize" type="xs:string" default="100" />
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="phpVersion" type="xs:string" />
<xs:attribute name="serializer" type="xs:string" />
Expand Down
22 changes: 22 additions & 0 deletions docs/running_psalm/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,28 @@ Allows you to hard-code a serializer for Psalm to use when caching data. By defa
```
Allows you to hard-code the number of threads Psalm will use (similar to `--threads` on the command line). This value will be used in place of detecting threads from the host machine, but will be overridden by using `--threads` or `--debug` (which sets threads to 1) on the command line

#### maxStringLength
```xml
<psalm
maxStringLength="1000"
>
```
This setting controls the maximum length of literal strings that will be transformed into a literal string type during Psalm analysis.
Strings longer than this value (by default 1000 bytes) will be transformed in a generic `non-empty-string` type, instead.

Please note that changing this setting might introduce unwanted side effects and those side effects won't be considered as bugs.

#### maxShapedArraySize
```xml
<psalm
maxShapedArraySize="100"
>
```
This setting controls the maximum size of shaped arrays that will be transformed into a shaped `array{key1: "value", key2: T}` type during Psalm analysis.
Arrays bigger than this value (100 by default) will be transformed in a generic `non-empty-array` type, instead.

Please note that changing this setting might introduce unwanted side effects and those side effects won't be considered as bugs.

## Project settings

#### &lt;projectFiles&gt;
Expand Down
10 changes: 10 additions & 0 deletions src/Psalm/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,11 @@ class Config
*/
public $max_avg_path_length = 70;

/**
* @var int
*/
public $max_shaped_array_size = 100;

/**
* @var string[]
*/
Expand Down Expand Up @@ -1080,6 +1085,11 @@ private static function fromXmlAndPaths(
$config->max_string_length = $attribute_text;
}

if (isset($config_xml['maxShapedArraySize'])) {
$attribute_text = (int)$config_xml['maxShapedArraySize'];
$config->max_shaped_array_size = $attribute_text;
}

if (isset($config_xml['inferPropertyTypesFromConstructor'])) {
$attribute_text = (string) $config_xml['inferPropertyTypesFromConstructor'];
$config->infer_property_types_from_constructor = $attribute_text === 'true' || $attribute_text === '1';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,12 @@ private static function analyzeArrayItem(
}
}

$config = $codebase->config;

if ($item_value_type = $statements_analyzer->node_data->getType($item->value)) {
if ($item_key_value !== null && count($array_creation_info->property_types) <= 100) {
if ($item_key_value !== null
&& count($array_creation_info->property_types) <= $config->max_shaped_array_size
) {
$array_creation_info->property_types[$item_key_value] = $item_value_type;
} else {
$array_creation_info->can_create_objectlike = false;
Expand All @@ -491,7 +495,9 @@ private static function analyzeArrayItem(
} else {
$array_creation_info->item_value_atomic_types[] = new TMixed();

if ($item_key_value !== null && count($array_creation_info->property_types) <= 100) {
if ($item_key_value !== null
&& count($array_creation_info->property_types) <= $config->max_shaped_array_size
) {
$array_creation_info->property_types[$item_key_value] = Type::getMixed();
} else {
$array_creation_info->can_create_objectlike = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -644,13 +644,17 @@ private static function handleArrayItem(
return false;
}

$config = $codebase->config;

$array_creation_info->all_list = $array_creation_info->all_list && $item_is_list_item;

if ($item->key instanceof PhpParser\Node\Scalar\String_
|| $item->key instanceof PhpParser\Node\Scalar\LNumber
|| !$item->key
) {
if ($item_key_value !== null && count($array_creation_info->property_types) <= 50) {
if ($item_key_value !== null
&& count($array_creation_info->property_types) <= $config->max_shaped_array_size
) {
$array_creation_info->property_types[$item_key_value] = $single_item_value_type;
} else {
$array_creation_info->can_create_objectlike = false;
Expand All @@ -664,7 +668,7 @@ private static function handleArrayItem(

if (count($dim_type->getAtomicTypes()) > 1
|| $dim_type->hasMixed()
|| count($array_creation_info->property_types) > 50
|| count($array_creation_info->property_types) > $config->max_shaped_array_size
) {
$array_creation_info->can_create_objectlike = false;
} else {
Expand Down

0 comments on commit ebffd52

Please sign in to comment.