Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Agents
nette/php-generator
claude-code
cursor
php
code
nette
scaffolding

It is my fervent wish that this file guide every AI coding agent working with code in this repository.

Install
php artisan boost:add-skill nette/php-generator

Save this content to: AGENTS.md

# To My Agents!

It is my fervent wish that this file guide every AI coding agent working with code in this repository.

## Documentation

Any distilled, agent-facing documentation for this package - how it works
internally and the rationale behind key design decisions - lives in `docs/`.
Consult it before non-trivial changes; it is the source of truth from which the
public manual is distilled.

The object model is a self-explanatory builder, but three areas are trap-rich and
expensive to reconstruct: **type/nullability handling, the name/namespace model,
and the reflection<->source round-trip.** Read `docs/internals.md` before touching them.

`docs/upgrading.md` records, per released version, every change visible to
users of the package (renames, removals, deprecations, signatures, behavior,
configuration), each with its commit hash; internal changes are not in it. It
is the place to look up the history of a public symbol. Do not write to it; it
is extended at release time from the git history.

## Project Overview

Nette PHP Generator programmatically generates PHP code (classes, functions,
namespaces, whole files) with support for modern features (property hooks, enums,
attributes, asymmetric visibility), plus loading existing code back into the object
model.

- **PHP Version**: 8.3 - 8.6 (v5.0)
- **Package**: `nette/php-generator`

## Essential Commands

```bash
# Run all tests
vendor/bin/tester tests -s        # or: composer tester
vendor/bin/tester tests/Printer -s     # one topic folder or a single .phpt

# Static analysis
composer phpstan
```

## Conventions

- Every file starts with `declare(strict_types=1);`; **tabs**; braces on the next
  line for functions/methods; Nette Coding Standard.
- Tests are Nette Tester `.phpt` grouped by topic under `tests/` (`ClassLike/`,
  `Members/`, `Factory/`, `Extractor/`, `Printer/`, `PhpFile/`, `Dumper/`,
  `Helpers/`); many compare against a `.expect` file in the topic's `expected/`
  subfolder via the `sameFile()` helper (keeps test files clean and makes output
  changes visible in diffs).

## Working in this repo

- **The type is a `Nette\Utils\Type` object and nullability lives inside it** -
  `setNullable()` (which throws without a type), a `null` default and a `null`
  initial value are folded into the type by the setters (`applyNullable()`),
  one-way. `getType()` returns the object, the declaration string is `(string)`.
  Printing normalizes the spelling (`int|null` prints as `?int`). In `Factory`,
  call `setType()` only after `setInitialized()`, or a transient null folds in.
- **The type API is duplicated across five classes, not shared** - `Constant` has
  no nullable API, `EnumType::setType()` stores a plain string and skips
  validation (the backing type is checked only by `validate()` at print time).
  Account for these deliberate differences before "unifying" them.
- **`getName()` returns the SHORT name and `getFullName()` the FQN** - the opposite
  of `ReflectionClass::getName()`. `PhpNamespace` is the resolution engine
  (`resolveName`/`simplifyName`/`simplifyType`), with separate alias tables per
  symbol kind.
- **Names inside bodies, attribute args, and dumped values survive only as invisible
  `/*(n*/` comment tags** (`Helpers::tagName`, resolved by `simplifyTaggedNames` at
  print time); an untagged FQN prints verbatim and is never simplified.
- **Loading code has two paths:** `Factory` (reflection only, no I/O) and `Extractor`
  (nikic/php-parser, reached via `withBodies` or the `fromCode()` path, and **throws**
  if the parser is absent - fail-fast, never silent degradation).
- **`self`/`parent`/`static` are kept verbatim** (they're keywords). So
  `ClassManipulator::inheritMethod()`/`inheritProperty()`/`implement()` copy a member
  into a different class **without rewriting** those references - a relocation trap.
  Extracted bodies are likewise relative to their original namespace.
- User-facing how-to (builder API, body placeholders, Printer configuration,
  property hooks, asymmetric visibility, arrow functions) is manual material and
  lives in the public web docs, not here.

To My Agents!

It is my fervent wish that this file guide every AI coding agent working with code in this repository.

Documentation

Any distilled, agent-facing documentation for this package - how it works internally and the rationale behind key design decisions - lives in docs/. Consult it before non-trivial changes; it is the source of truth from which the public manual is distilled.

The object model is a self-explanatory builder, but three areas are trap-rich and expensive to reconstruct: type/nullability handling, the name/namespace model, and the reflection<->source round-trip. Read docs/internals.md before touching them.

docs/upgrading.md records, per released version, every change visible to users of the package (renames, removals, deprecations, signatures, behavior, configuration), each with its commit hash; internal changes are not in it. It is the place to look up the history of a public symbol. Do not write to it; it is extended at release time from the git history.

Project Overview

Nette PHP Generator programmatically generates PHP code (classes, functions, namespaces, whole files) with support for modern features (property hooks, enums, attributes, asymmetric visibility), plus loading existing code back into the object model.

  • PHP Version: 8.3 - 8.6 (v5.0)
  • Package: nette/php-generator

Essential Commands

# Run all tests
vendor/bin/tester tests -s        # or: composer tester
vendor/bin/tester tests/Printer -s     # one topic folder or a single .phpt

# Static analysis
composer phpstan

Conventions

  • Every file starts with declare(strict_types=1);; tabs; braces on the next line for functions/methods; Nette Coding Standard.
  • Tests are Nette Tester .phpt grouped by topic under tests/ (ClassLike/, Members/, Factory/, Extractor/, Printer/, PhpFile/, Dumper/, Helpers/); many compare against a .expect file in the topic's expected/ subfolder via the sameFile() helper (keeps test files clean and makes output changes visible in diffs).

Working in this repo

  • The type is a Nette\Utils\Type object and nullability lives inside it - setNullable() (which throws without a type), a null default and a null initial value are folded into the type by the setters (applyNullable()), one-way. getType() returns the object, the declaration string is (string). Printing normalizes the spelling (int|null prints as ?int). In Factory, call setType() only after setInitialized(), or a transient null folds in.
  • The type API is duplicated across five classes, not shared - Constant has no nullable API, EnumType::setType() stores a plain string and skips validation (the backing type is checked only by validate() at print time). Account for these deliberate differences before "unifying" them.
  • getName() returns the SHORT name and getFullName() the FQN - the opposite of ReflectionClass::getName(). PhpNamespace is the resolution engine (resolveName/simplifyName/simplifyType), with separate alias tables per symbol kind.
  • Names inside bodies, attribute args, and dumped values survive only as invisible /*(n*/ comment tags (Helpers::tagName, resolved by simplifyTaggedNames at print time); an untagged FQN prints verbatim and is never simplified.
  • Loading code has two paths: Factory (reflection only, no I/O) and Extractor (nikic/php-parser, reached via withBodies or the fromCode() path, and throws if the parser is absent - fail-fast, never silent degradation).
  • self/parent/static are kept verbatim (they're keywords). So ClassManipulator::inheritMethod()/inheritProperty()/implement() copy a member into a different class without rewriting those references - a relocation trap. Extracted bodies are likewise relative to their original namespace.
  • User-facing how-to (builder API, body placeholders, Printer configuration, property hooks, asymmetric visibility, arrow functions) is manual material and lives in the public web docs, not here.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console