From 8c54e68efd7961050af2ac33f53cbb5701c03f37 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Sat, 4 Sep 2021 17:39:29 +0300 Subject: [PATCH 1/2] Added documentation on callmap editing --- docs/contributing/editing_callmaps.md | 81 +++++++++++++++++++++++++++ docs/contributing/index.md | 4 ++ 2 files changed, 85 insertions(+) create mode 100644 docs/contributing/editing_callmaps.md diff --git a/docs/contributing/editing_callmaps.md b/docs/contributing/editing_callmaps.md new file mode 100644 index 00000000000..d33bb532051 --- /dev/null +++ b/docs/contributing/editing_callmaps.md @@ -0,0 +1,81 @@ +# Altering callmaps + +## Intro + +One of the first things most contributors start with is proposing changes to +callmaps. + +Callmap is a data file (formatted as a PHP file returning an array) that tells +Psalm what arguments function/method takes and what it returns. + +There are two full callmaps (`CallMap.php` and `CallMap_historical.php`) in +`dictionaries` folder, and a number of delta files that provide information on +how signatures changed in various PHP versions. `CallMap_historical` has +signatures as they were in PHP 7.0, `CallMap.php` contains current signatures +(for PHP 8.1 at the time of writing). + +## Full callmap format + +Full callmaps (`CallMap.php` and `CallMap_historical.php`) have function/method +names as keys and an array representing the corresponding signature as a value. + +First element of that value is a return type (it also doesn't have a key), and +subsequent elements represent function/method parameters. Parameter name for an +optional parameter is postfixed with `=`. + +## Delta file format + +Delta files (named `CallMap__delta.php`) +list the changed that happened in the corresponding PHP version. There are +three section with self-explanatory names: `aded` (for functions/methods that +were added in that PHP version), `removed` (for those that were removed) and +`changed`. + +Entry format for `removed` and `added` section matches that of a full callmap, +while `changed` entries list `old` and `new` signatures. + +## How Psalm uses delta files + +When the current PHP version is set to something other than the latest PHP +version supported by Psalm, it needs to process delta files to arrive at a +version of callmap matching the one that is used during analysis. Psalm uses +the following process to do that: + +1. Read `CallMap.php` (Note: it's the one having latest signatures). +2. If it matches configured PHP version, use it. +3. If the callmap for previous PHP version exists, read that. +4. Take previous callmap delta and apply it in reverse order. That is, entries + in `removed` section are added, those in `added` section are removed and + `changed.new` signatures in the current callamp are replaced with + `changed.old`. +5. Goto 2 + +## Consistent histories + +To make sure there are no mismatches in deltas and the callmap, CI validates +that all function/method entries have consistent histories. E.g. that the +signature in `changed.new` matches the one in `CallMap.php`, the `removed` +entries are actually absent from `CallMap.php` and so on. + +## Typical changes + +To put that into practical perspective, let's see how a couple of typical +callmap changes may look like. + +### Adding a new function + +Say, there's a function added in PHP 8.1, e.g. `array_is_list()`. Add it to the +`CallMap_81_delta.php` (as it was introduced in PHP 8.1), and `CallMap.php` (as +it exists in the latest PHP version). Here's [the PR that does it](https://github.com/vimeo/psalm/pull/6398/files). + +### Correcting the function signature + +Assume you found incorrect signature, the one that was always different to what +we currently have in Psalm. This will need a change to `CallMap_historical.php` +(as the signature was always that way) and `CallMap.php` (as the signature is +still valid). Here's [the PR that does it](https://github.com/vimeo/psalm/pull/6359/files). + +If function signature is correct for an older version but has changed since you +will need to edit the delta for PHP version where signature changed and +`CallMap.php` (as this new signature is still valid). Here's +[the PR that does it (makes `timestamp` nullable)](https://github.com/vimeo/psalm/pull/6244/files). diff --git a/docs/contributing/index.md b/docs/contributing/index.md index 6bf0d8037b7..66b0613eb51 100644 --- a/docs/contributing/index.md +++ b/docs/contributing/index.md @@ -26,6 +26,10 @@ There's a lot of interesting theory behind the things Psalm does, too. If you wa Lastly, working to improve static analysis tools will also make you a better PHP developer – it'll help you think more about how values flow through your program. +### Guides + +* [Editing callmaps](editing_callmaps.md) + ## Pull Requests Before you send a pull request, make sure you follow these guidelines: From 6e2131da43ddf634a863993af294815e7f1d5777 Mon Sep 17 00:00:00 2001 From: Bruce Weirdan Date: Sat, 4 Sep 2021 19:27:09 +0300 Subject: [PATCH 2/2] s/aded/added/ --- docs/contributing/editing_callmaps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributing/editing_callmaps.md b/docs/contributing/editing_callmaps.md index d33bb532051..e2699bf6f49 100644 --- a/docs/contributing/editing_callmaps.md +++ b/docs/contributing/editing_callmaps.md @@ -27,7 +27,7 @@ optional parameter is postfixed with `=`. Delta files (named `CallMap__delta.php`) list the changed that happened in the corresponding PHP version. There are -three section with self-explanatory names: `aded` (for functions/methods that +three section with self-explanatory names: `added` (for functions/methods that were added in that PHP version), `removed` (for those that were removed) and `changed`.