You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/CHANGELOG.md
+13-17Lines changed: 13 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,27 +36,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
36
36
37
37
### Changed
38
38
39
-
-**Lower memory use across every stored type.** The internal representation of a PHP type is now 24 bytes instead of 64, so every parameter, return, and property type (and every type nested inside them) takes less than half the space it used to. On large Laravel projects this cuts peak memory by roughly 15% and the live heap by roughly 19%, with no change to what PHPantom resolves.
40
-
-**Identical types are stored once.** A project repeats the same handful of types thousands of times over: every `string` parameter, every `?Carbon` property, every `Collection<User>` return. PHPantom now stores each distinct type a single time and refers to it by a pointer, so a type occurrence costs 8 bytes instead of 24 plus its own copy of the payload. On large Laravel projects this cuts peak memory by a further 10% and the live heap by 20%, and drops around a quarter of all live allocations. Comparing two types is now a pointer check rather than a walk over their structure, so analysis is slightly faster as well.
41
-
-**Lower memory use when resolving class hierarchies.** Resolving a class no longer copies every inherited or synthesized member into it. Members that a merge does not actually rewrite are shared with their source across the whole workspace, and the copies a merge does produce (template substitution, trait and interface merging, Eloquent Builder and scope forwarding) are deduplicated so that value-identical results share a single allocation instead of one per class. Method parameter lists are shared the same way. On large Laravel projects, where nearly every Eloquent model resolves through a generic base and forwards the same query-builder methods, this roughly halves the memory held by the resolved-class cache during whole-project analysis and speeds up the merge itself.
42
-
-**Property and constant sharing extends the same memory win.** Inherited and synthesized properties and constants are now shared and interned the same way methods already were, instead of being cloned onto every class that inherits them. This further reduces the resolved-class cache's memory footprint on large projects, on top of the method sharing above.
39
+
-**Lower memory use for stored types.** Every parameter, return, and property type now takes less than half the memory it used to, and identical types (every `string` parameter, every `?Carbon` property, every `Collection<User>` return) are stored once and shared instead of duplicated at each occurrence. Comparing two types is now a quick reference check rather than a walk over their structure, so analysis is slightly faster too. On large Laravel projects this meaningfully cuts both peak memory and live heap size, with no change to what PHPantom resolves.
40
+
-**Lower memory use when resolving class hierarchies.** Resolving a class no longer copies every inherited or synthesized method, property, and constant onto it. Members a merge doesn't actually change are shared with their source across the whole workspace, and members it does produce (template substitution, trait and interface merging, Eloquent forwarding) are deduplicated so identical results share one allocation. On large Laravel projects, where most Eloquent models resolve through a shared generic base, this roughly halves the memory held by the resolved-class cache and speeds up resolution itself.
43
41
-**Classes are pre-resolved for the whole workspace after startup.** Once the background index completes, every known class is resolved in dependency order even when workspace diagnostics are disabled, so the first completion, hover, or go-to-definition against any class reads a warm cache instead of resolving on demand. Edits still re-resolve only the affected classes.
44
42
-**Continuous progress reporting.** The indexing progress bar now advances file by file with live counts (e.g. "Scanning vendor packages (3201/8544 files)") instead of jumping between a few fixed milestones. This covers single-project, monorepo, and non-Composer workspaces. Go to Implementation, Find References, and Type Hierarchy show the same live progress while they scan, including when one of them triggers the first full workspace index.
45
43
-**Property hover now shows effective types as a `var` detail line.** Property hovers now mirror method hovers by displaying the resolved/effective property type above the PHP snippet as `**var**`, while the snippet itself shows only the native PHP property declaration. This keeps docblock-inferred, virtual, and schema-derived property types out of the generated signature block. Contributed by @calebdw.
46
44
-**Updated the bundled mago toolchain to 1.43.0.** The parser, docblock parser, formatter, and supporting crates are refreshed to the latest upstream release. Contributed by @enwi in https://github.com/PHPantom-dev/phpantom_lsp/pull/234.
47
-
- **PHPDoc comments and the types inside them are now parsed by one unified parser.** Docblock parsing moves to `mago-phpdoc-syntax`, replacing the two frozen crates PHPantom used before. Tags written with a `@psalm-` or `@phpstan-` prefix are now recognized as the same tag as their unprefixed form throughout, so a vendor-prefixed variant reliably takes precedence over the plain one, and spellings such as `@phpstan-extends`, `@phpstan-sealed` and `@template-extends` are understood in every place the plain spelling was. Variance annotations (`covariant`, `contravariant`) in generic arguments are parsed directly rather than stripped beforehand, which makes docblock go-to-definition and rename land on the right text in types that use them. A tag indented with more than one space after the `*` is no longer dropped, and a docblock you are still typing (a bare `@`, a half-written type, no closing `*/`) now yields the tags above the cursor instead of nothing, so `@param`, `@return` and `@throws` completion keeps working mid-edit.
48
-
-**PHPDoc tags are read from the parsed grammar instead of being scanned again as text.** Every tag the PHPDoc parser understands now hands PHPantom the pieces it already identified: the type, the variable it applies to, the description that follows, a `@method` signature's parameters and template parameters, a `@template` bound and default, an alias definition. PHPantom previously split those back out of the raw comment text with its own scanner, which disagreed with the real grammar in places. Types written across several lines are now handled the same everywhere, so a multi-line `@property`, `@mixin`, or `@template` bound resolves like its single-line form, and trailing prose no longer leaks into a `@phpstan-type` alias definition or a `@method` parameter type. Tags the grammar cannot parse still fall back to the old scan, so half-typed and non-standard annotations keep working.
49
-
-**Lower memory use in the cross-file reference index.** The index backing Find References and the reference-count inlay hints now keeps only the distinct files and counts each symbol actually needs, instead of one entry per matching location plus never-read position data. On large projects this removes millions of short-lived allocations and shrinks the index to a fraction of its previous size, with no change to Find References or inlay hint results.
50
-
-**Lower memory use for method lookups.** Each resolved class's method name index is now a sorted list searched with binary search instead of a hash map, using about a third of the memory for the same lookup speed. On large Laravel projects, where the resolved-class cache holds thousands of these indexes, this measurably shrinks total memory use.
51
-
-**Lower memory use for member access spans.** The subject text recorded for every `->`/`::` access (e.g. `$this` in `$this->save()`) no longer allocates a string when it is a plain slice of the source, which covers the vast majority of accesses in typical PHP code. It now reuses the file's own bytes instead, with an allocation only for the rarer cases (chained calls, `new` expressions) where the recorded text differs from the source.
52
-
-**`@method` and `@property` tags are parsed once per class.** The magic members a class declares in its docblock were re-parsed from the raw comment text every time the class, or any class that inherits or mixes it in, was resolved. They are now parsed when the file is read and reused from then on, which also means the parsed types are qualified against the declaring file's imports directly instead of by rewriting the comment text. Whole-project analysis of a large Laravel codebase runs a few percent faster and uses slightly less memory, with identical results.
53
-
-**Faster diagnostics on large projects.** Several diagnostic checks (by-reference parameter detection, the `Stringable`-to-`string` acceptance check, and `model-property<Model>` literal validation) now read a class's inheritance from the resolved-class cache instead of re-merging traits, parent classes, and generics from scratch on every call. On large Laravel projects this removed a measurable share of the diagnostic pass's CPU time, and as a side effect these checks now also see interface-declared members (e.g. a `__toString` declared only on an implemented interface).
54
-
-**Laravel string keys are collected once instead of once per CPU core.** Checking a `route()`, `config()`, `view()`, or `__()` key needs the project's full list of valid keys, and building each list walks the project directory. The diagnostic pass runs one worker per core, so all of them used to reach the empty list at the same moment and every one repeated the same walk, leaving most cores waiting on the disk rather than analysing. Each list is now built once and shared, which roughly doubles the number of cores the diagnostic pass keeps busy and cuts whole-project analysis time by around 15% on large Laravel projects.
55
-
-**Repeated class lookups are remembered instead of searched again.** Answering "which class does this name refer to?" is the single most frequent thing PHPantom does: analysing a large Laravel project asks it millions of times, over only a few thousand distinct classes. Every question used to hash the name and take a read lock on two shared indexes, so with one worker per CPU core the workers spent much of their time queueing behind each other instead of analysing. Each worker now remembers the answers it has already looked up and drops them the moment the class indexes change, so a repeated question costs a single pointer comparison. Whole-project analysis is 8-12% faster on large Laravel projects and uses up to a third less CPU, with identical results and no measurable change in memory use. Hover, completion, and go-to-definition resolve names through the same path and get the same saving.
56
-
-**Vendor package scanning no longer reads every file twice.** Startup used to scan each vendor file once to find its classes, functions, and constants, then read and scan it again just to classify which package it came from for completion ranking. Each file's package is now known before it is scanned, so both are done in a single parallel pass, roughly halving the I/O and CPU cost of the vendor scan.
57
-
-**Whole-workspace class pre-resolution now spreads across cores.** Resolving every known class in dependency order after indexing ran on a single core, leaving a single-threaded pause between the parallel index and the parallel diagnostic pass that grew with the number of classes in the project. That work is now shared across a pool of workers, which cuts the phase to roughly a quarter of its previous time on large Laravel projects and takes close to 20% off whole-project analysis on the largest of them. The editor's post-startup pre-resolution goes through the same path, so a large project becomes fully warm sooner. Results are unchanged.
58
-
-**Project startup is roughly three times faster.** Building the class index at startup was the least parallel part of a run: it read every project and vendor file through a memory map, and mapping a file takes a lock that the whole process shares, so the more cores read files at once the longer each of them waited. Files are now read normally (only genuinely large ones are still mapped), the per-package directory walks run in parallel instead of one package after another, and both the file scan and the scan of a bundled `.phar` tool hand work out in small batches so no core sits idle behind a batch of large files. On large Laravel projects the startup phase drops from around 0.6s to 0.2s, taking 15-37% off whole-project analysis time across every project measured and up to 19% off its CPU use. The editor goes through the same pipeline, so it becomes usable sooner. Results are unchanged.
59
-
-**The `analyze` and `fix` CLI subcommands no longer build the cross-file reference index.** That index only serves Find References, Rename, and reference-count inlay hints, none of which the CLI subcommands ever query, so every file they parsed was still paying to populate it. Skipping the build removes that wasted CPU and short-lived allocation from whole-project `analyze` and `fix` runs; the editor's LSP session is unaffected.
45
+
-**PHPDoc comments and the types inside them are now parsed by one unified parser.** Tags written with a `@psalm-` or `@phpstan-` prefix are now recognized as the same tag as their unprefixed form throughout, so a vendor-prefixed variant reliably takes precedence over the plain one, and spellings such as `@phpstan-extends`, `@phpstan-sealed` and `@template-extends` are understood everywhere the plain spelling was. Variance annotations (`covariant`, `contravariant`) in generic arguments are parsed directly rather than stripped beforehand, which makes docblock go-to-definition and rename land on the right text in types that use them. A tag indented with more than one space after the `*` is no longer dropped, and a docblock you are still typing (a bare `@`, a half-written type, no closing `*/`) now yields the tags above the cursor instead of nothing, so `@param`, `@return`, and `@throws` completion keeps working mid-edit.
46
+
-**PHPDoc tags are read directly from the parsed grammar instead of being scanned again as text.** Types written across several lines are now handled the same everywhere, so a multi-line `@property`, `@mixin`, or `@template` bound resolves like its single-line form, and trailing prose no longer leaks into a `@phpstan-type` alias definition or a `@method` parameter type. Tags the grammar cannot parse still fall back to the old scan, so half-typed and non-standard annotations keep working.
47
+
-**Lower memory use in the cross-file reference index, method lookups, and member access spans.** The index backing Find References and the reference-count inlay hints now keeps only the data each symbol actually needs, each resolved class's method lookup uses a more compact structure, and the text recorded for every `->`/`::` access reuses the source file's own bytes instead of allocating a copy in the common case. On large projects these together remove a large share of short-lived allocations, with no change to any feature's results.
48
+
-**`@method` and `@property` tags are parsed once per class instead of on every resolution.** The magic members a class declares in its docblock are now parsed when the file is read and reused from then on, instead of being re-parsed from the raw comment text every time the class (or anything that inherits or mixes it in) is resolved. Whole-project analysis of a large Laravel codebase runs a few percent faster and uses slightly less memory, with identical results.
49
+
-**Faster diagnostics on large projects.** Several diagnostic checks (by-reference parameter detection, the `Stringable`-to-`string` acceptance check, and `model-property<Model>` literal validation) now reuse a class's already-resolved inheritance instead of re-merging traits, parent classes, and generics on every call. As a side effect these checks now also see interface-declared members (e.g. a `__toString` declared only on an implemented interface).
50
+
-**Faster Laravel string-key diagnostics.** Checking a `route()`, `config()`, `view()`, or `__()` key needs the project's full list of valid keys. That list is now built once and shared instead of being rebuilt redundantly during the diagnostic pass, cutting whole-project analysis time by around 15% on large Laravel projects.
51
+
-**Faster class-name resolution.** Looking up which class a name refers to is the single most frequent thing PHPantom does, so repeated lookups are now cached and invalidated only when the class indexes actually change. Whole-project analysis is 8-12% faster on large Laravel projects with lower CPU use and no change in results; hover, completion, and go-to-definition resolve names through the same path and see the same improvement.
52
+
-**Vendor package scanning no longer reads every file twice.** Startup used to scan each vendor file once to find its classes, functions, and constants, then read and scan it again just to classify which package it came from for completion ranking. Both are now done in a single pass, roughly halving the I/O and CPU cost of the vendor scan.
53
+
-**Faster whole-workspace class pre-resolution.** Resolving every known class in dependency order after indexing now spreads across multiple workers instead of running on a single one, substantially cutting the pause between indexing and diagnostics on large Laravel projects. The editor's post-startup pre-resolution goes through the same path, so a large project becomes fully warm sooner.
54
+
-**Project startup is significantly faster.** Building the class index now reads files normally instead of memory-mapping them, and the work is parallelized more effectively across your CPU cores. This meaningfully cuts both startup time and CPU use on large Laravel projects, speeding up whole-project analysis and getting the editor ready sooner, with no change in results.
55
+
-**The `analyze` and `fix` CLI subcommands no longer build the cross-file reference index.** That index only serves Find References, Rename, and reference-count inlay hints, none of which the CLI subcommands query, so skipping it removes wasted work from whole-project `analyze` and `fix` runs. The editor's LSP session is unaffected.
0 commit comments