1
0
mirror of https://github.com/danog/psalm.git synced 2024-12-02 17:52:45 +01:00
psalm/docs/contributing/what_makes_psalm_complicated.md
2020-11-29 23:51:09 -05:00

83 lines
2.7 KiB
Markdown

# Things that make developing Psalm complicated
This is a somewhat informal list that might aid others.
## Type inference
Type inference is one of the big things Psalm does. It tries to figure out what different PHP elements (function calls, if/for/foreach statements etc.) mean for the data in your code.
Within type inference there are a number of tricky areas:
#### Loops
Loops are hard to reason about - break and continue are a pain. This analysis mainly takes place in `LoopAnalyzer`
#### Combining types
There are lots of edge-cases when combining types together, given the many types Psalm supports. Type combining occurs in `TypeCombiner`.
#### Logical assertions
What effect do different PHP elements have on user-asserted logic in if conditionals, ternarys etc. This logic is spread between a number of different classes.
#### Generics & Templated code
Figuring out how templated code should work (`@template` tags) and how much it should work like it does in other languages (Hack, TypeScript etc.) is tricky. Psalm also supports things like nested templates (`@template T1 of T2`) which makes things trickier
## Detecting dead code
Detecting unused variables requires some fun [data-flow analysis](https://psalm.dev/articles/better-unused-variable-detection).
Detecting unused classes and methods between different runs requires maintaining references to those classes in cache (see below).
## Supporting the community
- **Supporting formal PHPDoc annotations**
- **Supporting informal PHPDoc annotations**
e.g. `ArrayIterator|string[]` to denote an `ArrayIterator` over strings
- **non-Composer projects**
e.g. WordPress
## Making Psalm fast
#### Parser-based reflection
Requires scanning everything necessary for analysis
#### Forking processes** (non-windows)
Mostly handled by code borrowed from Phan, but can introduce subtle issues, also requires to think about how to make work happen in processes
#### Caching thing
see below
## Cache invalidation
#### Invalidating analysis results
Requires tracking what methods/properties are used in what other files, and invalidating those results when linked methods change
#### Partial parsing
Reparsing bits of files that have changed, which is hard
## Language Server Support
#### Handling temporary file changes
When files change Psalm figures out what's changed within them to avoid re-analysing things unnecessarily
#### Dealing with malformed PHP code
When people write code, it's not always pretty as they write it. A language server needs to deal with that bad code somehow
## Fixing code with Psalter
#### Adding/replacing code
Figuring out what changed, making edits that could have been made by a human
#### Minimal diffs
hard to change more than you need