From 4620401adb703c7ec924ba526de1f9000687cd74 Mon Sep 17 00:00:00 2001 From: DerManoMann Date: Fri, 15 May 2026 12:52:23 +1200 Subject: [PATCH 1/2] Add domain glossary (CONTEXT.md) and align docs terminology Establishes a shared vocabulary for the project's core concepts (Annotation, Analysis, Context, Generator, Processor, etc.) with explicit resolutions for ambiguous terms like "generate", "merge", and "nested". Also removes outdated TokenAnalyser references from the under-the-hood doc. Co-Authored-By: Claude Opus 4.6 --- CONTEXT.md | 93 ++++++++++++++++++++++++++++++++++++ docs/guide/under-the-hood.md | 5 +- 2 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 CONTEXT.md diff --git a/CONTEXT.md b/CONTEXT.md new file mode 100644 index 000000000..6c727694e --- /dev/null +++ b/CONTEXT.md @@ -0,0 +1,93 @@ +# swagger-php + +A PHP library that generates OpenAPI specification documents from PHP source code +by scanning annotations (attributes and docblocks) and processing them into a +complete spec. + +## Language + +### Core Concepts + +**Annotation**: +An OpenAPI specification element declared as a PHP 8+ attribute or legacy docblock comment on a class, method, or property. +_Avoid_: Attribute (too narrow), decorator, metadata + +**Analysis**: +The aggregate result of scanning source code — contains all discovered annotations and structural definitions, before processing. +_Avoid_: Result, scan output + +**Context**: +Nested metadata describing where an annotation was found in the source hierarchy (file, namespace, class, method, property). +_Avoid_: Location, position + +**Generator**: +The orchestrator that coordinates scanning, processing, and output — it generates an OpenAPI spec from annotations, not code from a spec. +_Avoid_: Builder, compiler + +**Processor**: +A single transformation step in an ordered pipeline that converts raw Analysis into a valid, complete OpenAPI specification. +_Avoid_: Handler, middleware, transformer + +### Annotation Lifecycle + +**Unmerged**: +An annotation that has been discovered but not yet incorporated into the target OpenAPI root object. +_Avoid_: Pending, orphaned + +**Merge**: +Incorporating an annotation into its correct position within the OpenAPI object tree, guided by the nesting map. +_Avoid_: Combine, attach + +**Augment**: +Filling in missing annotation fields with values inferred from code (e.g. deriving a schema type from a PHP type hint). +_Avoid_: Enrich, hydrate + +**Expand**: +Resolving PHP inheritance (classes, interfaces, traits, enums) by copying parent annotations into child schemas. +_Avoid_: Inherit, flatten + +### Structural Concepts + +**Nesting**: +The declarative parent-child mapping (`$_nested`) that defines which annotation types can belong inside other annotation types — distinct from PHP class inheritance. +_Avoid_: Hierarchy (ambiguous with class hierarchy) + +**Component**: +A reusable named definition stored in `#/components/` and referenced via `$ref` elsewhere in the spec. +_Avoid_: Shared schema, template + +**Ref**: +A JSON Pointer (`$ref`) linking to another part of the spec, resolved by processors into `#/components/...` paths. +_Avoid_: Link (means something else in OpenAPI), pointer + +### Scanning + +**Analyser**: +Reflects on PHP source files to discover annotations and produce an Analysis. +_Avoid_: Scanner (too narrow — TokenScanner is a sub-component), parser + +**AnnotationFactory**: +Creates annotation objects from discovered PHP attributes or docblock comments during analysis. +_Avoid_: Builder, constructor + +## Relationships + +- A **Generator** uses an **Analyser** to produce an **Analysis** +- An **Analysis** contains **Annotations**, each carrying a **Context** +- **Processors** run sequentially on an **Analysis**, first **merging** unmerged annotations, then **expanding** inheritance, then **augmenting** missing fields +- **Nesting** defines where an **Annotation** can be merged within the OpenAPI tree +- A **Component** is an **Annotation** that has been merged into `#/components/` and is reachable by **Ref** + +## Example dialogue + +> **Dev:** "I added a `@OA\Schema` on a class but it's not appearing in the output." +> **Domain expert:** "Is it still **unmerged**? Check that the **nesting** map allows it to be **merged** into Components, and that a **processor** hasn't filtered it out." + +> **Dev:** "Why does the child class schema include the parent's properties?" +> **Domain expert:** "That's **expansion** — the ExpandClasses **processor** copies parent **annotations** into the child during the pipeline." + +## Flagged ambiguities + +- "generate" — resolved: reserve for the full end-to-end pipeline (`Generator::generate()`). Use **analyse** for the discovery phase and **serialize** for producing JSON/YAML output. +- "merge" — resolved: reserve for tree-placement (moving an annotation into its correct position in the OpenAPI object). Combining multiple annotations' fields into one (e.g. Properties into a Schema) is part of **augment**. +- "nested" — resolved: use **nesting map** when referring to the `$_nested` declaration. Use **enclosing** when talking about the physical source code structure (file, class, method) that Context tracks. \ No newline at end of file diff --git a/docs/guide/under-the-hood.md b/docs/guide/under-the-hood.md index 69a0c3e12..732b7cfc3 100644 --- a/docs/guide/under-the-hood.md +++ b/docs/guide/under-the-hood.md @@ -4,8 +4,7 @@ - The `Generator` iterates over the given sources (Symfony `Finder`, file/directory list, etc.) - The configured analyser (`AnalyserInterface`) reads the files and builds an `Analysis` object. - Default (as of v4) is the `ReflectionAnalyser`. Alternatively, there is the `TokenAnalyser` which was the default in v3. -- The legacy `TokenAnalyser` was removed in v5. + The default is the `ReflectionAnalyser`. - The `Analysis` object and its annotations are then processed by the configured processors. - If enabled, the analysis/annotations are validated. - The root `OpenApi` annotation then contains all annotations and is serialized into YAML/JSON. @@ -15,7 +14,7 @@ Each annotation is associated with a unique `Context` instance. This contains details, collected by the parser/analyser, about the PHP context where the annotation was found. -Typically, there will be a processor that uses the data to augment/enrich the annotation. +Typically, there will be a processor that uses the data to augment the annotation. **Examples of the data collected:** - class/interface/trait/enum names From 286e69c126d35cd847075cfaebf3e47d3f65205a Mon Sep 17 00:00:00 2001 From: DerManoMann Date: Fri, 15 May 2026 12:54:32 +1200 Subject: [PATCH 2/2] Ignore local .claude settings --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8165fa159..bce2eee4d 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ vendor/ .idea/ .phpstan/ /.phpunit.cache/test-results +/.claude/settings.local.json