Skip to content

Commit

Permalink
Merge pull request #8525 from Nicelocal/immutable_readonly_3
Browse files Browse the repository at this point in the history
Immutable readonly atomics
  • Loading branch information
orklah committed Oct 19, 2022
2 parents 212281d + 3b3afd5 commit e52b712
Show file tree
Hide file tree
Showing 252 changed files with 6,483 additions and 3,833 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/bcc.yml
Expand Up @@ -13,7 +13,7 @@ jobs:
tools: composer:v2
coverage: none

- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0

Expand All @@ -24,7 +24,7 @@ jobs:
echo "::set-output name=vcs_cache::$(composer config cache-vcs-dir)"
- name: Cache composer cache
uses: actions/cache@v2
uses: actions/cache@v3
with:
path: |
${{ steps.composer-cache.outputs.files_cache }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -12,3 +12,4 @@
/tests/fixtures/symlinktest/*

.idea/
.vscode/
9 changes: 9 additions & 0 deletions UPGRADING.md
@@ -1,5 +1,14 @@
# Upgrading from Psalm 4 to Psalm 5
## Changed
- [BC] `Psalm\Type\Union`s are now partially immutable, mutator methods were removed and moved into `Psalm\Type\MutableUnion`.
To modify a union type, use the new `Psalm\Type\Union::getBuilder` method to turn a `Psalm\Type\Union` into a `Psalm\Type\MutableUnion`: once you're done, use `Psalm\Type\MutableUnion::freeze` to get a new `Psalm\Type\Union`.
Methods removed from `Psalm\Type\Union` and moved into `Psalm\Type\MutableUnion`:
- `replaceTypes`
- `addType`
- `removeType`
- `substitute`
- `replaceClassLike`

- [BC] TPositiveInt has been removed and replaced by TIntRange

- [BC] The parameter `$php_version` of `Psalm\Type\Atomic::create()` renamed
Expand Down
195 changes: 158 additions & 37 deletions psalm-baseline.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="dev-master@f7fc28bf5c23969ef1d9c8fd26f020ade0a2db9e">
<files psalm-version="dev-master@53e3889745852409b704e0035d93e0819d522912">
<file src="examples/TemplateChecker.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$comment_block-&gt;tags['variablesfrom'][0]</code>
Expand Down Expand Up @@ -68,7 +68,7 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/AssertionFinder.php">
<PossiblyUndefinedIntArrayOffset occurrences="34">
<PossiblyUndefinedIntArrayOffset occurrences="28">
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
<code>$assertion-&gt;rule[0]</code>
Expand All @@ -90,12 +90,6 @@
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[0]</code>
<code>$expr-&gt;getArgs()[1]</code>
<code>$expr-&gt;getArgs()[1]</code>
<code>$get_debug_type_expr-&gt;getArgs()[0]</code>
Expand All @@ -112,16 +106,18 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php">
<ComplexMethod occurrences="1">
<code>verifyType</code>
</ComplexMethod>
<PossiblyUndefinedIntArrayOffset occurrences="3">
<code>$non_existent_method_ids[0]</code>
<code>$parts[1]</code>
<code>explode('::', $cased_method_id)[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>$arg_function_params[$argument_offset][0]</code>
<code>$array_type-&gt;getGenericArrayType()-&gt;getChildNodes()[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArrayFunctionArgumentsAnalyzer.php">
Expand Down Expand Up @@ -253,10 +249,9 @@
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php">
<PossiblyUndefinedIntArrayOffset occurrences="3">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$l[4]</code>
<code>$r[4]</code>
<code>$var_line_parts[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/PhpVisitor/Reflector/ExpressionScanner.php">
Expand Down Expand Up @@ -289,6 +284,26 @@
<code>$cs[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Internal/Type/Comparator/CallableTypeComparator.php">
<LessSpecificReturnStatement occurrences="1">
<code>$callable</code>
</LessSpecificReturnStatement>
<MoreSpecificReturnType occurrences="1">
<code>TCallable|TClosure|null</code>
</MoreSpecificReturnType>
</file>
<file src="src/Psalm/Internal/Type/TemplateStandinTypeReplacer.php">
<ImpureMethodCall occurrences="5">
<code>get</code>
<code>get</code>
<code>get</code>
<code>getClassTemplateTypes</code>
<code>has</code>
</ImpureMethodCall>
<ImpurePropertyAssignment occurrences="1">
<code>$candidate_param_type-&gt;from_template_default</code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Internal/Type/TypeCombiner.php">
<PossiblyUndefinedIntArrayOffset occurrences="6">
<code>$combination-&gt;array_type_params[1]</code>
Expand All @@ -311,47 +326,153 @@
<code>array_keys($template_type_map[$template_param_name])[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Node/Stmt/VirtualClass.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualClass</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Node/Stmt/VirtualFunction.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualFunction</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Node/Stmt/VirtualInterface.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualInterface</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Node/Stmt/VirtualTrait.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualTrait</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Node/VirtualConst.php">
<PropertyNotSetInConstructor occurrences="1">
<code>VirtualConst</code>
</PropertyNotSetInConstructor>
</file>
<file src="src/Psalm/Type/Atomic.php">
<ImpureMethodCall occurrences="10">
<code>classExtendsOrImplements</code>
<code>classExtendsOrImplements</code>
<code>classExtendsOrImplements</code>
<code>classOrInterfaceExists</code>
<code>classOrInterfaceExists</code>
<code>classOrInterfaceExists</code>
<code>getMappedGenericTypeParams</code>
<code>interfaceExtends</code>
<code>interfaceExtends</code>
<code>interfaceExtends</code>
</ImpureMethodCall>
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>array_keys($template_type_map[$value])[0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Type/Atomic/CallableTrait.php">
<ImpureMethodCall occurrences="4">
<code>replace</code>
<code>replace</code>
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/GenericTrait.php">
<ImpureMethodCall occurrences="3">
<code>getMappedGenericTypeParams</code>
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<PossiblyUndefinedIntArrayOffset occurrences="1">
<code>$this-&gt;type_params[1]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Type/Atomic/HasIntersectionTrait.php">
<ImpureMethodCall occurrences="1">
<code>getMostSpecificTypeFromBounds</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TClassString.php">
<ImpureMethodCall occurrences="1">
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TClassStringMap.php">
<ImpureMethodCall occurrences="4">
<code>getString</code>
<code>getString</code>
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment occurrences="1">
<code>$cloned-&gt;value_param</code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TConditional.php">
<ImpureMethodCall occurrences="1">
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TKeyedArray.php">
<ImpureMethodCall occurrences="10">
<code>combine</code>
<code>combine</code>
<code>combineUnionTypes</code>
<code>combineUnionTypes</code>
<code>combineUnionTypes</code>
<code>combineUnionTypes</code>
<code>combineUnionTypes</code>
<code>combineUnionTypes</code>
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment occurrences="3">
<code>$key_type-&gt;possibly_undefined</code>
<code>$value_type-&gt;possibly_undefined</code>
<code>$value_type-&gt;possibly_undefined</code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TList.php">
<ImpureMethodCall occurrences="2">
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyAssignment occurrences="1">
<code>$cloned-&gt;type_param</code>
</ImpurePropertyAssignment>
</file>
<file src="src/Psalm/Type/Atomic/TObjectWithProperties.php">
<ImpureMethodCall occurrences="2">
<code>replace</code>
<code>replace</code>
</ImpureMethodCall>
<ImpurePropertyFetch occurrences="2">
<code>$type-&gt;possibly_undefined</code>
<code>$type-&gt;possibly_undefined</code>
</ImpurePropertyFetch>
</file>
<file src="src/Psalm/Type/Atomic/TTemplateKeyOf.php">
<ImpureMethodCall occurrences="1">
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TTemplatePropertiesOf.php">
<ImpureMethodCall occurrences="1">
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/Atomic/TTemplateValueOf.php">
<ImpureMethodCall occurrences="1">
<code>replace</code>
</ImpureMethodCall>
</file>
<file src="src/Psalm/Type/MutableUnion.php">
<PossiblyUnusedProperty occurrences="7">
<code>$allow_mutations</code>
<code>$by_ref</code>
<code>$failed_reconciliation</code>
<code>$from_template_default</code>
<code>$has_mutations</code>
<code>$initialized_class</code>
<code>$reference_free</code>
</PossiblyUnusedProperty>
</file>
<file src="src/Psalm/Type/Reconciler.php">
<PossiblyUndefinedIntArrayOffset occurrences="2">
<code>$type[0]</code>
<code>$type[0][0]</code>
</PossiblyUndefinedIntArrayOffset>
</file>
<file src="src/Psalm/Type/Union.php">
<PossiblyUnusedProperty occurrences="1">
<code>$ignore_isset</code>
</PossiblyUnusedProperty>
</file>
<file src="src/Psalm/Type/UnionTrait.php">
<PossiblyUnusedMethod occurrences="2">
<code>allFloatLiterals</code>
<code>allFloatLiterals</code>
</PossiblyUnusedMethod>
</file>
<file src="tests/Internal/Codebase/InternalCallMapHandlerTest.php">
<UnusedPsalmSuppress occurrences="1">
<code>UndefinedMethod</code>
</UnusedPsalmSuppress>
</file>
<file src="vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrowFunction.php">
<PossiblyUndefinedStringArrayOffset occurrences="1">
<code>$subNodes['expr']</code>
Expand Down
16 changes: 12 additions & 4 deletions src/Psalm/Context.php
Expand Up @@ -485,11 +485,14 @@ public function update(
if ((!$new_type || !$old_type->equals($new_type))
&& ($new_type || count($existing_type->getAtomicTypes()) > 1)
) {
$existing_type->substitute($old_type, $new_type);
$existing_type = $existing_type
->getBuilder()
->substitute($old_type, $new_type);

if ($new_type && $new_type->from_docblock) {
$existing_type->setFromDocblock();
$existing_type = $existing_type->setFromDocblock();
}
$existing_type = $existing_type->freeze();

$updated_vars[$var_id] = true;
}
Expand Down Expand Up @@ -770,18 +773,23 @@ public function removeDescendents(
$statements_analyzer
);

foreach ($this->vars_in_scope as $var_id => $type) {
foreach ($this->vars_in_scope as $var_id => &$type) {
if (preg_match('/' . preg_quote($remove_var_id, '/') . '[\]\[\-]/', $var_id)) {
$this->remove($var_id, false);
}

$builder = null;
foreach ($type->getAtomicTypes() as $atomic_type) {
if ($atomic_type instanceof DependentType
&& $atomic_type->getVarId() === $remove_var_id
) {
$type->addType($atomic_type->getReplacement());
$builder ??= $type->getBuilder();
$builder->addType($atomic_type->getReplacement());
}
}
if ($builder) {
$type = $builder->freeze();
}
}
}

Expand Down

0 comments on commit e52b712

Please sign in to comment.