Skip to content

Commit dd2175f

Browse files
committed
Update documentation and improve caching configuration details
1 parent 7cbd2c9 commit dd2175f

9 files changed

Lines changed: 57 additions & 36 deletions

File tree

docs/advanced/how-it-works.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,13 @@ TypePHP solves this using `TypePHPPrinter` and regex post-processing. Injected g
9393

9494
### Disk Caching
9595

96-
Once transformed, TypePHP saves the resulting code to disk in `sys_get_temp_dir() . '/typephp-cache/'`. On all subsequent requests:
96+
Once transformed, TypePHP saves the resulting code to disk in your configured `cache_dir` (which defaults to `sys_get_temp_dir() . '/typephp-cache/'`). On all subsequent requests:
9797
* AST parsing runs **0 times**.
9898
* PHP's **OPCache** compiles the cached file once into bytecode in RAM.
9999
* Stream file reads execute natively at C-level speed inside Zend Engine.
100100

101+
*(TypePHP's stream wrapper automatically detects and skips intercepting files inside your configured `cache_dir` to prevent infinite loops and double-transformation overhead).*
102+
101103
---
102104

103105
## Typed Arrays and Array Shapes
@@ -182,10 +184,6 @@ For function-level templates (`@template T`), TypePHP pushes a temporary call fr
182184

183185
---
184186

185-
Here is the updated, brief **Validation Error Messages and Trace Attribution** section for `docs/architecture/how-it-works.md`:
186-
187-
---
188-
189187
## Validation Error Messages and Trace Attribution
190188

191189
When a type contract fails, TypePHP constructs informative error messages through a 3-tier pipeline:

docs/getting-started/configuration.md

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,17 @@ return [
5454

5555
/*
5656
|--------------------------------------------------------------------------
57-
| Enable Caching
58-
|--------------------------------------------------------------------------
59-
| Pre-transforms and caches PHP files on disk for maximum speed.
57+
| Enable Caching & Cache Directory
58+
|--------------------------------------------------------------------------
59+
| Pre-transforms and caches PHP files on disk for OPcache optimization.
60+
|
61+
| 'cache_dir' determines where these files are stored. By default (null),
62+
| it uses your system's temp directory. You can change this to a path
63+
| inside your project (e.g., __DIR__ . '/storage/framework/typephp').
64+
| TypePHP automatically protects this directory from being double-transformed.
6065
*/
6166
'cache' => true,
67+
'cache_dir' => null,
6268

6369
/*
6470
|--------------------------------------------------------------------------
@@ -90,7 +96,7 @@ return [
9096
| Included Paths & Whitelisting
9197
|--------------------------------------------------------------------------
9298
| Globs or specific file paths that should be intercepted and type-checked.
93-
| Note: you can just specify "*" glob pattern to include all files including in the root folder.
99+
| Note: you can just specify "**" glob pattern to include all files including in the root folder.
94100
*/
95101
'include' => [
96102
'src/**',
@@ -129,34 +135,42 @@ Key options explained:
129135
| **`'magic_properties'`** | `true` | Enforces class-level `@property`, `@property-read`, and `@property-write` annotations on dynamic assignments (`__set`). |
130136
| **`'magic_methods'`** | `true` | Enforces class-level `@method` annotations on dynamic method calls (`__call` / `__callStatic`). |
131137
| **`'respect_ignore_tags'`** | `true` | Respects `@typephp-ignore` and `@typephp-ignore-file` tags. Set to `false` in CI/CD to force audit checks. |
132-
| **`'cache'`** | `true` | Pre-transforms and caches PHP files on disk (`typephp-cache/`) for OPcache optimization. |
138+
| **`'cache'`** | `true` | Pre-transforms and caches PHP files on disk. |
139+
| **`'cache_dir'`** | `null` | Custom path to store cached files. Defaults to system temporary directory (`sys_get_temp_dir() . '/typephp-cache/'`). |
133140

134141
---
135142

136143
## Inline Variable Categories Reference (`inline_vars`)
137144

138-
How each `inline_vars` toggle maps to PHPDoc type annotations:
145+
*(... rest of the file remains exactly the same ...)*
146+
```
139147
140-
| Config Option | Covered PHPDoc Types | Examples |
141-
| :--- | :--- | :--- |
142-
| **`'scalars'`** | Primitive & Refined Scalars | `int`, `string`, `bool`, `positive-int`, `non-empty-string`, `truthy` |
143-
| **`'objects'`** | Class Instances & Bare Class References | `User`, `stdClass`, `class-string`, `interface-string`, `enum-string` |
144-
| **`'generics'`** | Template & Bound Types | `Collection<User>`, `Producer<T>`, `class-string<T>` |
145-
| **`'arrays'`** | All Arrays, Shapes, & Lists | `array{id: int}`, `int[]`, `User[]`, `list<string>`, `array<string, int>` |
146-
| **`'callables'`** | Callables & Closures | `callable`, `Closure`, `callable(int): string`, `static-closure` |
147-
| **`'properties'`** | Class Property Writes | `$this->id = 1`, `UserProfile::$username = 'Alice'` |
148+
---
149+
150+
### 2. `docs/advanced/how-it-works.md`
151+
152+
*(Find the "Zero Line-Drift Formatting and Caching" section and update the "Disk Caching" part to this:)*
148153
149-
### Important Notes on `inline_vars` Behavior
154+
```markdown
155+
### Disk Caching
150156
151-
* **Inner Structural Types Are Always Validated:** Disabling `'scalars' => false` only turns off standalone scalar assignments (such as `/** @var positive-int $x */`). If `'arrays'` or `'generics'` is enabled, TypePHP **will still validate inner scalar constraints** inside array shapes (`array{id: positive-int}`), lists (`list<positive-int>`), or generic containers (`Collection<positive-int>`) to maintain structural type integrity.
152-
* **Active Generic Instance Prebinding:** Enabling `'generics' => true` allows inline `@var` annotations on object instantiations (such as `/** @var Collection<User> $users */ $users = new Collection();`) to **actively prebind generic template parameters (`T = User`)** directly to that object instance in `WeakMap` memory. Every subsequent method call on that instance (`$users->add()`, `$users->get()`) will enforce `T = User`!
157+
Once transformed, TypePHP saves the resulting code to disk in your configured `cache_dir` (which defaults to `sys_get_temp_dir() . '/typephp-cache/'`). On all subsequent requests:
158+
* AST parsing runs **0 times**.
159+
* PHP's **OPCache** compiles the cached file once into bytecode in RAM.
160+
* Stream file reads execute natively at C-level speed inside Zend Engine.
161+
162+
*(TypePHP's stream wrapper automatically detects and skips intercepting files inside your configured `cache_dir` to prevent infinite loops and double-transformation overhead).*
163+
```
153164

154165
---
155166

156-
## Pattern Specificity Rules
167+
### 3. `docs/troubleshooting.md`
168+
169+
*(Find the "How do I know if TypePHP is actively transforming a file?" question and update the answer:)*
157170

158-
If a file matches both an `include` rule and an `exclude` rule, TypePHP compares pattern lengths:
171+
```markdown
159172

160-
* **Specific Whitelist Wins:** `'vendor/my-org/package/**'` (length 25) takes precedence over `'vendor/**'` (length 8).
161-
* **Single File Override:** `'src/LegacyFile.php'` (length 22) takes precedence over `'src/**'` (length 6).
162-
* **Tie-Breaker:** If pattern lengths are equal, `exclude` takes precedence to ensure application safety.
173+
```
174+
175+
---
176+
All docs are updated! What's our next target? Should we start refactoring validators, expanding the Extension System, or write a quick web-framework mock test?

docs/troubleshooting.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ If TypePHP is not enforcing contracts on a specific file or method, check the fo
2222
You can verify that a file is being intercepted and transformed in two ways:
2323

2424
1. **Intentionally Trigger an Error:** Pass an invalid argument (such as a negative integer to a `positive-int` parameter). If a `TypePHP\Exception\TypeError` is thrown, TypePHP is active.
25-
2. **Inspect the Cache Directory:** Look inside your system temporary directory (`sys_get_temp_dir() . '/typephp-cache/'`). You will see transformed PHP files containing injected `RuntimeTypeChecker` calls.
25+
2. **Inspect the Cache Directory:** Look inside your configured `cache_dir` (if undefined, this defaults to your system temporary directory: `sys_get_temp_dir() . '/typephp-cache/'`). You will see transformed PHP files containing injected `RuntimeTypeChecker` calls.
26+
27+
---
28+
29+
### Why are files inside my custom `cache_dir` not being intercepted?
30+
31+
If you configured a custom `cache_dir` inside your project directory (e.g., `__DIR__ . '/storage/typephp'`) and set your include paths to `['**']`, you might wonder why the cache files aren't being transformed.
32+
33+
**This is a built-in safety mechanism.** TypePHP automatically detects your `cache_dir` and unconditionally excludes it from its internal `StreamWrapper` and `FileFilter`. This prevents catastrophic infinite loops and double-parsing overhead that would occur if TypePHP tried to intercept and transform its own cached files.
2634

2735
---
2836

src/Contract/FileFilter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ public static function isFileExcluded(string|false|null $fileName): bool
6868
// Equal specificity tie-breaker: Exclude wins!
6969
return $longestExcludeMatch >= $longestIncludeMatch;
7070
}
71-
71+
7272
/**
7373
* Converts a glob pattern into an absolute regex pattern.
7474
*/

src/Internal/StreamWrapper.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,9 @@ private static function isReadOnlyCall(): bool
504504
return \in_array($callerFunc, ['file_get_contents', 'file', 'readfile', 'highlight_file', 'show_source', 'token_get_all'], true);
505505
}
506506

507-
/**
508-
* Determines whether a target PHP file path should be intercepted using Pattern Specificity.
509-
*/
507+
/**
508+
* Determines whether a target PHP file path should be intercepted using Pattern Specificity.
509+
*/
510510
private static function isApplicationFile(string $path, string|false $resolvedPath): bool
511511
{
512512
if (! (bool) (Config::get()['enabled'] ?? true)) {

src/Internal/Visitor/PropertyHookInjector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,4 @@ public function enterNode(Node $node): int|null
124124

125125
return $newStmts;
126126
}
127-
}
127+
}

tests/Contract/FileFilterTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
$normalFilePath = str_replace('\\', '/', getcwd() . '/app/Models/User.php');
154154

155155
expect(FileFilter::isFileExcluded($cachedFilePath))->toBeTrue()
156-
->and(FileFilter::isFileExcluded($normalFilePath))->toBeFalse();
156+
->and(FileFilter::isFileExcluded($normalFilePath))->toBeFalse()
157+
;
157158

158159
Config::reset();
159160
});

tests/Visitor/PropertyHookInjectorTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,4 @@
7575
->and($body[0]->getAttribute('typephp_injected'))->toBeTrue()
7676
;
7777
});
78-
});
78+
});

typephp.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
| When enabled, transformed PHP files are cached on disk for speed.
5050
| Set to false to run AST transformations purely in RAM (php://memory).
5151
|
52-
| 'cache_dir' determines where these files are stored. By default (null),
52+
| 'cache_dir' determines where these files are stored. By default (null),
5353
| it uses your system's temp directory. You can change this to a path
5454
| inside your project, e.g., __DIR__ . '/storage/framework/typephp'.
5555
| TypePHP will automatically protect this directory from being re-transformed.

0 commit comments

Comments
 (0)