Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions docs/architecture/0002-execution-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ interface SymbolSource
// --- Added JIT, when the step that needs them lands (NOT built in Step 2) ---
// Step 3b (functions/constants gain project reach; a second searchable kind exists):
// lookupFunction(FunctionName): ?FunctionInfo
// lookupConstant(ConstantName): ?ConstantInfo
// lookupConstant(GlobalConstantName): ?ConstantInfo
// searchClassLikes generalizes to search(string $prefix, NameKind $kind)
// Future (workspace scope, #264):
// locate(QualifiedName, NameKind): ?SymbolDefinition // kind-neutral def-site, only if a feature needs it
Expand Down Expand Up @@ -641,12 +641,27 @@ To stop the two typing models fighting before they are built:

- `QualifiedName` is the base FQN value type — a namespace path plus a short name,
**kind-neutral**.
- `ClassLikeName`, `FunctionName`, `ConstantName`, `NamespaceName` extend / wrap it
and **carry their kind intrinsically** (each exposes `kind(): NameKind`). These are
- `ClassLikeName`, `FunctionName`, `GlobalConstantName`, `NamespaceName` extend / wrap
it and **carry their kind intrinsically** (each exposes `kind(): NameKind`). These are
the primary currency; the per-kind `lookup*` methods take the matching one, so the
kind is implicit and `NameKind` is not passed. `ClassLikeName` is today's
`ClassName` (which per CLAUDE.md also serves as the class `Type`); whether it is
reused as-is, renamed, or wrapped is an open decision (§7). The other three are new.
- **`GlobalConstantName`, because `ConstantName` is the class constant member name**
beside `MethodName` and `PropertyName`. A bare member name is not an FQN, and one type
holding both would report `NameKind::Constant` for a member name. Unlike
`ClassLikeName` versus `ClassName` in §7, these are two concepts, not two names.
- **One `ConstantInfo` serves both**, with `?ClassName` for `declaringClass`; its absence
is what makes a constant global, and `format()` branches on that alone. `visibility`
and `isFinal` carry true values — a redeclared `const` is fatal, a repeated `define()`
a no-op. The nullable is a conscious exception to the no-nullable rule: the
alternatives are a second metadata type differing in one field, or a sentinel
`ClassName` the type system cannot catch as a lie.
- A global constant is **not** a `ResolvedMember` — that interface means *reached through
a class*, which is a path it does not have. Whether it instead gets a fifth wrapper or
`ConstantInfo` carries `ResolvedSymbol` itself is #416's, and turns on SC.13:
`ResolvedSymbol` is in `Resolution` and returns an `Index\Location`, so a `Domain`
object carrying it adds edges the layer contract denies.
- `locate(QualifiedName, NameKind)` is the kind-agnostic entry, used when the caller
has an FQN whose kind is known only from syntactic position and has not minted a
typed subtype. `NameKind` is **not** redundant here precisely because the input is
Expand All @@ -656,7 +671,7 @@ To stop the two typing models fighting before they are built:
is about identifiers, not search fragments. `kind` (once the parameter exists in
Step 3b) selects which namespace to search.
- **JIT:** Step 2 uses only `ClassLikeName` (today's `ClassName`) and `NamespaceName`.
`QualifiedName`, `NameKind`, `FunctionName`, and `ConstantName` land with the methods
`QualifiedName`, `NameKind`, `FunctionName`, and `GlobalConstantName` land with the methods
that first use them (Step 3b, and `locate` in the workspace scope) — an unused type
is not carried ahead of its method. This whole model is the *target*; it is
introduced piecewise.
Expand Down Expand Up @@ -814,7 +829,7 @@ once Step P is green.
**Resolved — see Section 8.**
- Whether `ClassLikeName` is the existing `ClassName` reused as-is, renamed, or a
wrapper — it must coexist with `ClassName`'s dual role as the class `Type` (§5.3).
- Whether `FunctionName` / `ConstantName` / `NamespaceName` land in Step 2 as prep
- Whether `FunctionName` / `GlobalConstantName` / `NamespaceName` land in Step 2 as prep
or in Step 3 with their lookups (lean: Step 3, to avoid an unused-type commit;
`NamespaceName` is needed by `childrenOf` in Step 2, so it lands then).
- Whether completion detail after the `search` migration comes from a follow-up
Expand Down
10 changes: 5 additions & 5 deletions docs/architecture/build-manifest.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ Notes:
of it. `NameKind` already exists (it predates Wave 2, as the catalog's coarse kind);
Step 2 carries `ClassLikeName` / `NamespaceName`; `QualifiedName` lands in **S3.7b**,
whose `DeclarationScanner` is its first caller; `FunctionName` in **S3.8a** and
`ConstantName` in **S3.8b**, with their lookups.
- **`ConstantName` is already taken.** `Domain\ConstantName` wraps a *class* constant
name; §5.3's `ConstantName` is a *global* constant FQN. Decide the naming before
S3.8b rather than inside it — this is the same coexistence question §7 leaves open
for `ClassLikeName` versus `ClassName`.
`GlobalConstantName` in **S3.8b**, with their lookups.
- **The `ConstantName` collision is settled (0002 §5.3):** the global FQN type is
`GlobalConstantName`, `Domain\ConstantName` stays the class member name, and one
`ConstantInfo` serves both kinds. The *resolved* shape stays open — it is #416's and
turns on SC.13, so take SC.13 first.
- **Steps 3 and 4 both edit `SymbolResolver` (§6).** S4.2 (positional extraction) is
gated on S3.8 (the 3b lookup migration) so the two never run concurrently; manifest
order keeps Step 3 ahead of Step 4 regardless. S4.1 (`TypeClassifier` + the §4.5/§4.6
Expand Down