## Fix InnerGraphPlugin handling for class static properties with computed keys

**Backlog ticket**

The `InnerGraphPlugin` currently mis-handles top‑level‑symbol tracking when exported classes contain static members with computed (dynamic) property keys.

### Observed behaviour
- In production mode with `usedExports: "global"`, modules that export a class with static computed properties can **throw an uncaught runtime error** (e.g., `Cannot read properties of undefined`) during dependency walking, or produce **incorrect tree‑shaking** (exported values incorrectly dropped).
- The problem is limited to static members whose keys are non‑literal expressions (e.g., `static [expr] = value`). Methods and getters with computed keys are also affected but may manifest differently.
- The issue does not appear for instance members, nor for static members whose keys are plain identifiers/strings.

### Desired outcome
1. **Correct runtime behaviour** – modules that export classes with static computed property keys must compile without errors and work as expected in production builds.
2. **Correct dead‑code elimination** – static computed properties of used classes must be treated as part of the class’s top‑level usage; unused classes must still be safe to drop entirely without crashing the compilation.
3. **Consistent plugin contracts** – the arguments passed to the parser hooks `classBodyElement`, `classBodyValue`, and `classExtendsExpression` should be named accurately (`classDefinition` instead of `statement`) to reflect the node they actually carry and to avoid mistakes in plugins that consume them.

### Implementation constraints & edge cases
- When `InnerGraphPlugin` processes a `classBodyValue` for a **static** non‑method member with a computed key, it must correctly look up the top‑level symbol from the `classDefinition` node, and if the class is reachable, emit a `PureExpressionDependency` so that the key expression is retained with the right `usedByExports` tracking.
- For each class body element, if the enclosing class is tracked as a top‑level symbol the plugin must **reset the top‑level symbol to `undefined`** before evaluating the element’s key, preventing leakage from a previous element.
- The fix must not break simple (non‑computed) class properties, nor affect instance properties, nor change behaviour for classes that are not assigned to a top‑level exported symbol.
- No changes should be required to the public API or configuration – only internal tracking and the existing `InnerGraphPlugin` hooks need updating.

### Internal context
- `JavascriptParser` defines the hooks `classBodyElement` and `classBodyValue` with signatures that currently label the class-definition argument as `"statement"`. Renaming them to `"classDefinition"` makes the intent explicit and aligns with the node type actually passed.
- `InnerGraphPlugin` already uses `classWithTopLevelSymbol` to map class nodes onto `InnerGraph`-aware functions; the new logic needs to query this map using the `classDefinition` reference rather than the element/statement.

assign class property keys to the correct top level symbol


Emit errors for imports from CommonJS modules when the named export is statically known to be absent.

Currently, importing a non-existent named export from a CJS module that uses `__esModule` (or from a pure CJS module that only exposes a default) silently produces `undefined` at runtime. Instead, webpack should produce a linking error during compilation. In `HarmonyImportDependency.getLinkingErrors`, after resolving the module’s `exportsType`:

- For `"namespace"` and `"default-with-named"` modules, when `moduleGraph.isExportProvided(importedModule, ids)` returns `false` (meaning it’s definitely missing), emit a `HarmonyLinkingError` with the format
  `export '<name>' (imported as '<alias>') was not found in '<module>' (possible exports: <list>)`.
  The `<list>` should show the actual exports of the module obtained from the export info.
- Do **not** emit the missing-export error when importing `"default"` from a `"default-with-named"` module (the default export exists).
- The existing error for `"default-only"` (`"only default export is available"`) and the transitional warning for `"redirect-warn"` (`"only default export is available soon"`) must remain unchanged; they are separate cases and should not be triggered by the new check.

This should apply to:
- CJS modules that define `__esModule` and export only a `default` (here, named imports other than `default` are missing).
- Pure CJS modules whose static analysis reveals only a `default` export.
- Any module where an attempted named import (including `__esModule` itself) is known to be absent (e.g., the `mjs/non-enumerable` case).
- Tree-shaking scenarios where a mutation makes an export unavailable (e.g., `cjs-tree-shaking/mutate`).

emit errors for exports in commonjs modules for which we know that they don't exist


`MultiStats#toString()` produces ANSI color codes by default even when no color option is passed. This causes problems when the output is piped to a file or consumed by tools that don’t expect terminal escapes. The `Stats` class may default to `colors: true`, but for `MultiStats` summarising multiple compilations, uncolored output should be the default unless the caller explicitly sets `colors: true`. The behaviour should match the principle that `MultiStats` is often used for programmatic consumption or aggregated reports where color is unwanted. The fix should ensure that the default for `colors` is `false` in `MultiStats#toString`, while still allowing explicit override. The `toJson` method does not need to change; only the stringification step should adjust the default.

Refactored MultiStats.js to ES6, as well as MultiStats.test.js


When using `cache: { type: "filesystem" }` with `buildDependencies`, an error while resolving the initial set of build dependencies (for example, a path that cannot be resolved) can permanently corrupt the dependency tracking for that cache. After the error, legitimate build dependency files (like config files or loaders) are no longer watched for changes, so subsequent edits to those files do not invalidate the cache and stale output is served.

**Expected behavior**
If resolving `buildDependencies` fails during a build, the cache infrastructure should not "commit" any changes to the tracked build dependencies for that run. The previously known set of build dependencies (from a prior successful build, or an empty set) should remain intact, and any new dependencies that were discovered during the failed build should be discarded. The next successful build should then be able to correctly register and watch all dependencies.

**Observed behavior**
When a build encounters an error during the resolution phase of build dependencies, the newly discovered dependencies are added to the tracked set and the pending list is cleared *before* the resolution completes. As a result, if resolution fails, those dependencies remain in the persistent tracking state but are no longer treated as “new” for future resolution attempts. Subsequent builds never re-resolve them, so changes to those files are silently ignored, leading to stale cached output.

**Impact**
This is especially problematic in environments where `buildDependencies` include dynamically computed paths, paths that might temporarily not exist, or optional configuration files. A single intermittent error (e.g., network mount not yet available, race condition in CI, or a misconfigured dependency) can permanently break incremental cache invalidation until the cache is manually cleared.

The fix should ensure that the build-dependency registration (the addition to the tracked set and the clearing of the new-dependencies list) only happens *after* the dependency resolution succeeds. If resolution fails, the pending set should be discarded or requeued so that the next attempt can try again.

errors in initial cache no longer cause build dependencies to be ignored


Prevent concurrent compilations on the same `Compiler` instance.

Today, calling `compiler.run()` or `compiler.watch()` while a compilation is already in progress on that instance leads to a second, overlapping compilation. This causes non-deterministic output, race conditions, and confusing failures. We should reject such calls explicitly so that consumers can detect and handle the mistake, and the compiler itself remains in a consistent state.

### Acceptance criteria

1. **Active compilation guard**
   If `compiler.run(callback)` is called while any compilation is already running on that instance (initiated by a previous `run()` or `watch()`), `callback` must be invoked _synchronously_ with an `Error` describing that only one concurrent compilation is supported. No new compilation must start.

2. **Watch while busy**
   If `compiler.watch(watchOptions, handler)` is called while any compilation is already running on that instance, `handler` must be invoked _synchronously_ with the same kind of `Error`, and no watching must begin.

3. **Reusability after `run()`**
   Once a compilation started by `run()` completes (whether successfully, with errors, or with a fatal compilation error), a subsequent `run()` or `watch()` call must succeed normally and start a new compilation.

4. **Reusability after closing a watcher**
   Once a watcher is closed via `watching.close()`, the compiler must allow a new `run()` or `watch()` to be started immediately.

5. **No permanent lock‑out**
   The guard must be reset after every compilation finishes. A call sequence like `run()` → finishes → `run()` again must work repeatedly.

6. **Child compilers not affected**
   Compiler instances created via `compiler.createChildCompiler()` follow an internal lifecycle; they are not subject to this restriction.

7. **Callback contract**
   No callback provided to `run()` or handler provided to `watch()` may be invoked more than once, and whenever an error is delivered, no subsequent success notification may happen for that invocation.

The intent is that each `Compiler` instance supports at most one compilation at a time, and the API surface communicates that constraint clearly by returning a predictable error instead of silently corrupting state.

Prevent webpack from running twice at a time


In async module initialization (`AwaitDependenciesInitFragment`), when the target environment does not support destructuring (`output.environment.destructuring: false`), the generated code for multiple named imports from an async module currently awaits the internal `__webpack_async_dependencies__` promise once per import variable. This causes the async function to potentially yield execution multiple times for the same resolution, which can break expected execution order. Instead, the result of awaiting the dependency promise must be computed **once**, stored in a local variable, and then each import assignment should read from that variable. The fix should apply only to the non-destructuring branch (when `this.dependencies.size !== 1` or `!supportsDestructuring()`), leaving the destructuring path unchanged.

fix: resolve execution order issue from extra await in async modules


**Problem**
When using `optimization.runtimeChunk: "single"` together with `splitChunks` in a Node.js target, a shared module that should be extracted into a single common chunk ends up being instantiated more than once. This causes state set in one entry point to be invisible in another, breaking any dependency on shared singleton state (e.g. configuration, instrumentation, or in‑memory caches).

**Steps to reproduce**
1. Configure webpack with `target: "node"` and multiple entry points that live under different directory paths (e.g. `deep/path/a`, `b`, `somewhere/c`).
2. Enable `optimization.runtimeChunk: "single"` so the runtime is a separate, shared chunk.
3. Use `optimization.splitChunks` to extract a module that is imported by at least two entry points (`minChunks: 2`, an `initial` chunk cache group with `enforce: true` and a test matching the shared module).
4. Import the shared module from the two entry points, call a setter in one entry point, and read the value in the other.

**Observed behavior**
The value read by the second entry point remains the initial value (e.g. `0`) instead of reflecting the setter call. This indicates that separate copies of the shared module are loaded for each entry point rather than a single shared instance.

**Expected behavior**
The shared module should be placed into a chunk that is loaded exactly once and shared by all entry points that depend on it. Mutations made in one entry point should be visible in the others.

**Root cause analysis (suspected)**
The chunk graph method `getChunkEntryDependentChunksIterable` in `lib/ChunkGraph.js` appears to misidentify the set of chunks that are “dependent” on a given entry chunk. It currently includes the entrypoint chunk itself as a dependent of itself, and it derives the dependency set from the chunk’s own `entryModules` rather than from the entrypoint’s chunk group. This incorrect dependency information causes the chunk integration logic (used during split chunk optimization) to believe that the shared module’s chunk cannot be safely integrated with both entry points simultaneously. As a result, each entry point ends up with its own copy of the module.

**Impact**
- Breaks module singleton semantics when runtime chunk splitting is active.
- Forces users to either avoid `runtimeChunk: "single"` or work around the duplication by manually ensuring only one entry point touches shared state.
- Can lead to subtle production bugs that only surface with particular entry point directory nesting patterns.

**Suggested fix direction**
`getChunkEntryDependentChunksIterable` should:
- Only consider `Entrypoint` chunk groups when collecting dependent chunks.
- Use the entrypoint’s chunk (obtained via `getEntrypointChunk()`) and its `entryModules` to compute the dependency set, rather than the chunk’s own.
- Exclude the entrypoint chunk itself from the returned set, in addition to the current exclusion of the original chunk and runtime‑only chunks.


When connecting to a server that rejects the WebSocket upgrade, the ZIO-HTTP WebSocket client does not fail the ZIO effect. Instead, the attempt either hangs indefinitely or completes without error, leading to later failures that are hard to diagnose.

Steps to reproduce:
- Create a server route that responds with a non-101 status (e.g., `Handler.badRequest` or any plain HTTP handler).
- Attempt a WebSocket connection using `Handler.webSocket(_ => ZIO.unit).connect(url, ...)`.
- Observe that the resulting ZIO does not fail, and the connection never becomes usable.

Expected behavior:
If the server replies with any status other than `101 Switching Protocols` for the WebSocket upgrade request, the client connection should fail immediately with a clear error that indicates the upgrade was rejected, ideally including the status code received. The resulting ZIO effect must be a failure so that callers can gracefully handle rejected upgrades.

Impact:
This makes it impossible to reliably detect when a WebSocket endpoint is unavailable or misconfigured, and can cause silent timeouts or cryptic errors elsewhere. It violates the principle of surfacing protocol-level failures at the connection layer.

fix: fail WebSocket client connection when the server rejects the upgrade (#4178)


When using Datastar attribute helpers, several attributes render incorrectly:

- `dataOnIntersect` does not include modifier suffixes in the attribute name (e.g., `.once` should produce `data-on-intersect__once`, but currently the suffix is missing).
- `dataInit` and `dataOnLoad` render the expression object itself instead of its JavaScript value (the attribute value shows the `Js` wrapper rather than the string).
- `dataRef` case-conversion methods (`camel`, `kebab`, `snake`, `pascal`) update only the local case-modifier field but do not propagate the case change to the embedded `signalName`, so the ref does not actually reflect the selected case.
- Modifier types that support chaining via `&&` (including `IntersectModifier`, `OnIntervalModifier`, `InitModifier`, `LoadModifier`, `OnSignalPatchModifier`, `EventModifier`) may produce malformed attribute names when a `None` modifier is present in the chain.  In particular, the absence of any modifier should render no suffix, but under some modifiers the suffix `__none` appears, and chained `And` renderings can duplicate or include unwanted separator characters.

Ensure all Datastar attribute helpers product correct, spec-compliant HTML attributes; modifier chains excluding `None` should simply concatenate the same way as other modifiers, and when no modifier is selected the attribute name should have no suffix.

Fix rendering of data attributes and modifiers in Datastar (#3857)


```
Title: Multipart streaming form hangs when a non‑streaming field fails to decode

A user reports that when an endpoint that accepts multipart/form‑data
(one JSON metadata field + a streaming binary field) receives a request
where the JSON is malformed, the server hangs and never closes the
connection or produces a response.  The expected behaviour is that a
decode error (e.g. `HttpCodecError.MalformedBody`) propagates and the
server returns a 4xx response without leaking fibres or blocking
indefinitely.

The problem appears to be isolated to the interaction between
`StreamingForm` and the `Endpoint` decoder’s handling of streaming
inputs:

- `StreamingForm.fields` produces a stream of `FormField` values, and
  the reader fibre may block on an internal queue offer while pushing
  bytes into a field stream.  If the downstream decoding fails (e.g.
  invalid JSON), that reader fibre is not interrupted, causing a leak
  and a hang.

- The `ready` promise used by the endpoint decoder to signal that all
  non‑streaming fields have been decoded and the handler can start
  consuming the streaming field should complete with failure when a
  non‑streaming field cannot be decoded.  Currently it appears this
  promise can be left unfulfilled or completed only with success,
  preventing error propagation.

The fix must ensure:

1. When the consumer of the `fields` stream fails (or is interrupted),
   the reader fibre is reliably cancelled and its resources are cleaned
   up.  Special care is needed where the reader may be parked inside a
   blocking offer that does not natively respond to ZIO interruption;
   an explicit abort mechanism should unblock that offer.

2. The endpoint’s field decoding sets the `ready` promise to failure as
   soon as any field decode fails, so the overall request handling can
   observe the error immediately and avoid a deadlock.

3. No zombie fibres or queue entries are left behind after a failure;
   the tail of the streaming form must be properly drained or
   terminated with an appropriate signal.

Acceptance criteria (behavioural):

- A malformed JSON field in a multipart form that also contains a valid
  streaming field causes the endpoint to return a 400 (or
  appropriately‑mapped error) rather than hanging.

- The server remains responsive and does not leak fibres/threads after
  such a failure.

- Valid multipart forms with streaming fields continue to work as
  before.
```

Reproducer and fix for multipart/form-data bug (#2468)


As a user of ZIO HTTP, I'd like to use custom domain types (e.g., `UserId`, `PostId`) in path patterns, but currently `PathCodec` and `SegmentCodec` lack transformation methods. The existing `decode` can already fail, but `format`/`encode` always return a `Path` directly, with no way to represent encoding failures. This makes it impossible to safely round-trip custom types: if a custom type's value can't be encoded back to a valid path segment, there's no way to signal that.

Please add transformation methods (`transform`, `transformOrFail`, `transformOrFailLeft`, `transformOrFailRight`) to `PathCodec` and `SegmentCodec`, analogous to those on `HttpCodec`. Because encoding a transformed value can now fail, the return types of `format` and `encode` must become `Either[String, Path]` (and correspondingly in `RoutePattern`). The fallibility should propagate through the internal optimization and decoder pipelines, so that a failed encoding via `format` or `encode` produces a `Left` with a descriptive error string, and a failed decoding via `decode` returns the same `Left` error.

This would allow patterns like `/users/{userId}/posts/{postId}` where `userId` is an `Int` decoded to `UserId` (via `transform`) and `postId` is a string validated to be a numeric `PostId` (via `transformOrFailLeft`), with proper error handling in both directions.

transform functions for PathCodec (#2376)


When sending a response with a streaming body, the server exhibits two problems:

1. There is an unnecessary delay: the final chunk of a stream is held back and written separately from the chunk's content, after all preceding chunks have been flushed. This delay is visible to clients.

2. If the response carries a `Content-Length` header together with a stream body, some HTTP clients can close the connection before the server sends the trailing empty-last-content frame (`LastHttpContent`), causing connection errors and preventing reuse of the connection for subsequent requests.

The fix should ensure:
- Every chunk from a stream body (including the last) is written and flushed to the client as soon as it becomes available, with no extra accumulation step.
- A response whose body is a `StreamBody` must never include a `Content-Length` header; chunked transfer encoding must always be used for such responses.


**Problem:**
When the CORS middleware is configured with an `allowedOrigin` that only permits a specific origin, it only rejects **OPTIONS** preflight requests from disallowed origins. Normal requests (e.g., `GET`, `POST`, `PUT`) from a disallowed origin are **not** rejected – they go through to the handler, just without any CORS headers in the response. This violates the security model: a request from a disallowed origin should not reach the server logic at all.

**Expected behavior:**
If a request carries an `Origin` header that the current `CorsConfig.allowedOrigin` rejects (returns `None`), the middleware should immediately respond with a **403 Forbidden** status, regardless of the HTTP method. The handler behind the middleware must never be invoked.

**Acceptance criteria:**
1. **`POST`/`GET`/`PUT`/`DELETE` from disallowed origin** → response status is `403 Forbidden`. No CORS headers are added (the origin is not allowed, so the standard says no `Access-Control-Allow-Origin`).
2. **`OPTIONS` preflight from disallowed origin** → also rejected (this was likely already the case, but must still hold). No `Access-Control-Allow-Origin` header.
3. **Normal request from an **allowed** origin** → processed normally, and the correct `Access-Control-Allow-Origin` header is included in the response (based on the `CorsConfig`).
4. **`OPTIONS` preflight from allowed origin** → still returns `204 No Content` (or as documented) with the appropriate CORS headers.
5. The fix must respect the `allowedMethods` and `allowedOrigin` settings from `CorsConfig`; if an origin is allowed but the method is not in `allowedMethods`, the preflight behaviour should remain unchanged (that case is already handled).

**Constraints:**
- This is a change in the `cors` middleware implementation. No public API changes are needed; the fix is purely behavioural.
- The existing test suite for CORS (`CorsSpec`) must be extended to cover the new rejections for non-OPTIONS requests (note: in the patch, tests were added; we don't mention them explicitly, but the request would naturally imply tests should be added to verify the behaviour).

Fix CORS middleware to reject non-OPTIONS requests from disallowed or… (#3890)


```
NettyConnectionPool.get returns a ZIO that acquires a Netty channel. The channel is not being closed when the scope that acquired it ends, causing a resource leak.

- Attach a finalizer to the channel acquisition that closes the channel when the scope is released. Use `channel.close()` (not `disconnect()`), execute it via NettyFuture, only do so if the channel is still open, and silently ignore any errors from the close operation.
- Ensure that closing the connection pool itself (e.g., when its own scope ends) also triggers closing of channels that were previously obtained from it.
- Add a test that acquires a connection through the pool, scopes the pool, and then verifies the channel is closed after the pool’s scope ends.
```

Add finalizer for Netty channels created via `NettyConnectionPool` (#2663)


**Title**: `JsonSchema.fromZSchema` does not fully inline nested schemas with `SchemaStyle.Inline`

**Description**:
When generating a `JsonSchema` from a ZIO `Schema` using `JsonSchema.fromZSchema(schema, SchemaRef(SchemaSpec.OpenAPI, SchemaStyle.Inline))`, the resulting JSON schema still contains `$ref` entries for nested case class fields, contrary to the expectation that `Inline` produces a completely self-contained schema with no references.

**Steps to reproduce**:
1. Define two case classes with a nested field, e.g. `Inner(value: String)` and `Outer(inner: Inner)`.
2. Derive `Schema`s for both using `DeriveSchema.gen`.
3. Call `JsonSchema.fromZSchema(outerSchema, SchemaRef(SchemaSpec.OpenAPI, SchemaStyle.Inline))`.
4. Serialize the resulting `JsonSchema` to JSON.

Observed: the output contains `$ref` references (e.g. for the `Inner` type) instead of inlining the object schema for the `inner` field.

**Expected behavior**:
When `SchemaStyle.Inline` is used, the JSON schema output must not contain any `$ref` string; every composite type should be recursively inlined in place. For `Outer`, the `inner` property should directly contain an `object` schema with a `value` string field, rather than a `$ref` to a separate definition.

fix: Ensure JsonSchema.fromZSchema respects SchemaStyle.Inline for nested schemas (#3168) (#3955)


**Title:** Expose materialized body content without internal-class matching

**Description:**
The `Body` trait currently hides the raw in-memory bytes of a body. Users who need to access the body’s content without consuming it (e.g., for logging, tracing, or conditional middleware) are forced to pattern-match on internal concrete types (`ChunkBody`, `ArrayBody`, etc.) which are private and fragile. We need a public API that returns the body’s content if it is already fully in memory, and `None` otherwise.

- Add `def materializedContent: Option[Chunk[Byte]]` to `Body`.
- Add `def materializedAsString: Option[String]` to `Body` that decodes `materializedContent` using the charset from `contentType` (falling back to `Charsets.Http`).

**Behavioral contract:**
- **In-memory bodies** (empty, array, chunk, string, and the JVM Netty `AsciiStringBody`) must return `Some` with the appropriate bytes.
- **Non-materialized bodies** (stream, file, websocket, error, and the JVM Netty async body) must return `None`.
- `EmptyBody` → `materializedContent = Some(Chunk.empty)`, `materializedAsString = Some("")`.
- `StringBody` must also provide an optimized `materializedAsString` that returns the original string and a `materializedContent` that encodes it with the body’s charset.
- `materializedAsString` must respect any charset present in the body’s `contentType`. If no charset is specified, `Charsets.Http` is the default.
- The implementation must cover **all body variants** in both the platform-independent code and the JVM-specific Netty layer; there should be no silent `None` on a subtype that actually holds in-memory data.

**Non-goals:**
- Do not change how bodies are consumed or serialized; this is a read-only “peek” operation.
- Do not introduce any new external dependencies or change the public constructors of `Body`.

feat(http): expose Body materialized content without internal class matching (#4005)


```
Title: `Middleware.metrics` should use route pattern information for automatic metric labels

Currently, `HandlerAspect.metrics` requires users to manually supply a `pathLabelMapper` (a `PartialFunction[Request, String]`) to avoid high-cardinality path labels.
Without a custom mapper the label is the raw request path (e.g. `/users/123`), which is problematic for metrics backends like Prometheus.
Correct setup demands extra boilerplate and is error-prone.

We need a `metrics` method on the `Middleware` object that eliminates the `pathLabelMapper` parameter entirely.
Because a middleware sees the full set of `Routes`, it can inspect each route’s `RoutePattern` (which already knows the HTTP method and the path codec) and derive safe, low-cardinality labels automatically.

**Behavioral requirements**
- Applying `Middleware.metrics` to a `Routes`/`HttpApp` should produce per-route metric labels using the *route pattern*, not the raw request path.
- For a route defined with a specific method (e.g. `Method.GET`), the `method` label must reflect that exact method (e.g. `"GET"`).
- For routes that match any method (e.g. `Method.ANY`), the `method` label should be `"*"`.
- The `path` label must be the rendered form of the route’s path codec (e.g. `/users/{id}` for a parameterised segment).
  Catch-all trailing patterns (e.g. the `trailing` codec) should produce a placeholder like `"/..."` rather than the raw matching request path.
- All other metric semantics (counter, histogram, gauge for concurrent requests) should remain identical to the current `HandlerAspect.metrics`.
- The old `HandlerAspect.metrics` that expects a manual `pathLabelMapper` should be removed so that only the automatic, middleware-based variant remains.

**Why this matters**
A `Middleware.metrics` that uses `RoutePattern` will make Prometheus-friendly metrics work out of the box, without asking every user to hand-write a path mapper.
It also removes a known footgun (accidentally having high-cardinality path labels) and aligns metric instrumentation with the existing route structure of ZIO HTTP.
```

Convert metrics from HandlerAspect to Middleware #2320 (#2334)


## Report: `maxInitialLineLength` is hardcoded and not configurable

**Observed behavior**
- The server rejects or silently fails to process incoming HTTP requests whose request line (e.g., a very long URL with encoded query parameters) exceeds 4096 bytes.
- Similarly, the HTTP client cannot handle response status lines longer than 4096 bytes.
- There is no way to override these limits through ZIO Http’s public configuration (neither `Server.Config` nor `ZClient.Config`).

**Expected behavior**
- The maximum allowed initial line length for both server request decoding and client response decoding should be configurable via `Server.Config` and `ZClient.Config`, respectively.
- The default value should remain 4096 to preserve backward compatibility.
- The configured value should be propagated down to the underlying Netty codecs (the `HttpRequestDecoder` for the server and the `HttpClientCodec` for the client) in place of the current hardcoded literal `4096`.

**Why this matters**
- Users with longer URLs (e.g., those containing deeply nested path segments, large query strings, or encoded parameters) encounter mysterious failures that cannot be fixed without modifying library internals.
- Other header size limits (`maxHeaderSize`) are already configurable; this gap makes the configuration surface inconsistent and complicates operational tuning.

sourcing maxInitialLineLength through the config and propagating it to netty's configuration (#2561)


Add a per-client proxy setting to `ZClient`.

`ZClient` currently allows per-client SSL configuration via `ssl(ssl: ClientSSLConfig)` but has no equivalent for proxies. The only way to set a proxy is through the global `ZClient.Config`. This makes it impossible to use different proxies for different client instances.

Add a `proxy(proxy: Proxy)` method on `ZClient` that returns a new `ZClient` with the given proxy. A proxy set this way must be passed down to the underlying driver and used for all HTTP requests made through that client. When a per-client proxy is set, it must take precedence over any proxy configured in the global `Config`; when no per-client proxy is provided, the global proxy (if any) must still be used.

Ensure that the proxy is forwarded correctly through every `Driver` implementation, including the live driver, the test driver (`TestClient`), and any aspect wrappers (e.g., logging, metrics). The existing pattern used for `ssl` should serve as a guide.

issue_2212 update client proxy settings (#2336)


Add support for multi-valued query parameters in the `Endpoint` API.
Currently, query codecs (`query`, `queryInt`, etc.) extract at most one value per key; repeated keys are silently ignored.
We need a way to access all values for a key as a `Chunk[A]`.

Requirements:
- Introduce public combinators `queryAll(name)` and typed variants (`queryAllInt`, `queryAllBool`, `queryAllTo`) that return all values for a given key as `Chunk[A]`.
- The existing single-value codecs (`query`, `queryInt`, …) **must reject** requests where the key occurs with more than one value, yielding a `BadRequest` (400) instead of silently picking one.
- A required multi-value codec must produce a `BadRequest` if the key is entirely absent from the query string.
- If the key is present but has no value (e.g., `?key=`), the multi-value codec should produce an empty `Chunk`.
- Support `.optional` on multi-value codecs so that missing key yields `None`, while present-without-value yields `Some(Chunk.empty)`.
- Make sure the encoding round-trips correctly: an endpoint that produces multi-value query parameters should produce the key repeated once per value.
- The CLI endpoint support and OpenAPI generation must also accommodate the new multi-value query parameter form.

Intoroduce query parameters with multiple values to Endpoint API (#2631)


We need the ability to attach arbitrary `HttpCodec` values to an endpoint’s input and output, not just the schema‑based `in`/`out` methods. Add `inCodec` (for request‑side codecs) and `outCodec` (for response‑side codecs) on `Endpoint`. For the input, the new codec should combine with the existing input using `HttpCodec.++` (with a `Combiner`). For the output, it should fall back/alternate with the existing output using `HttpCodec.|` (with an `Alternator`).

To make it easier to build custom header codecs, add convenience methods on the `HeaderCodecs` trait for defining a header codec by name and a `TextCodec`, without needing an existing `HeaderType` class. Provide:
- `name(name, textCodec)` — direct header codec.
- Variants that accept parse/render functions: one that parses to `Either[String, A]`, one to `Option[A]`, and one that can throw (catching via `Try`).

Make the built‑in `TextCodec` values (`string`, `int`, `boolean`, `uuid`) implicit so that when using the new header helpers (or `queryAs`), the appropriate `TextCodec` is resolved automatically without an explicit argument.

Add methods to `Endpoint` to apply any kind of in/out codec (#2142)


Add a `generateHeadRoutes` option to `Server.Config` (default `false`) so that, when enabled, the server automatically serves HEAD requests using the corresponding GET handler for the same path. The HEAD response must include the same headers as the GET response (notably `Content-Length`) but with an empty body. Explicit HEAD routes must take precedence when they exist. Method.ANY routes must also respond to HEAD requests in the same way (no body, headers preserved). When the option is disabled, behavior must remain unchanged: HEAD requests to paths without an explicit HEAD route should return 404. Ensure the change works with path parameters and streaming response bodies.

Autogenerate HEAD routes for GET routes via server config (#3789) (#3811)


**Title:** Spurious request timeouts when client connection pool and idle timeout are combined

**Description:**
When the ZIO HTTP client is used with a connection pool and a client-level idle timeout (configured via `Client.Config.idleTimeout`), requests can fail with read timeout errors even though the server is responsive. The issue occurs when a connection that has been sitting idle in the pool is later reused for a new request — the idle timeout is not reset when the connection is borrowed, so it may expire during (or immediately before) the subsequent request, causing a premature channel closure and a client-side timeout error.

**Expected behavior:**
The idle timeout should be refreshed every time a connection is taken from the pool to serve a new request. This way, the timeout only applies to genuinely idle connections lingering in the pool, and never to connections that are actively being used. Concretely, if a client has an idle timeout of 500 ms and the server handler takes 150 ms per request, multiple consecutive requests reusing the same pooled connection should all succeed without any timeout-related failures.

**Constraints / hints:**
- The fix must preserve the existing pool semantics: connections that are truly broken or closed should still be invalidated and retired.
- The refresh logic must be applied before the pooled channel is returned to the caller, so that the idle timeout countdown always begins from the moment the connection is claimed.
- Any internal Netty channel pipeline timeout handler installed during connection creation must be replaced or reset to a fresh instance with the correct timeout duration at the point of pool checkout.

Fix connection pooled client timeouts (#2860)


**Title:** Proxy-style handlers that return a `Client` response fail to transmit the response body

**Description**
When a server handler uses `Client.request(...)` to forward a request to another service and returns the resulting `Response` directly, the response body never reaches the original client. The client sees either a truncated response or a connection error, even though the upstream service returned a valid response with a body.

**Expected behavior**
The server should transparently forward the upstream response body back to the original client. A handler that does

```scala
case req => Client.request(upstreamUrl, method = req.method, headers = req.headers, content = req.body)
```

should produce a response whose body contains the same bytes as the upstream response, regardless of whether the body is materialised eagerly or streamed asynchronously.

**Current behavior**
The upstream response body is received asynchronously (via an `AsyncBody`). When the server attempts to write this body to the Netty channel, the raw chunk data is passed directly to the channel without conversion to a Netty buffer, causing a write failure or producing no output.

**Constraint / invariants**
- The fix must work for any response returned from `Client.request`—including responses with non-empty streaming bodies.
- No unnecessary buffering of the entire response body in memory; the existing streaming behaviour must be preserved.
- The solution should not break the existing synchronous body-writing path for `AsciiStringBody` and `ByteBufBody`.
- The server must remain compatible with Netty’s pipeline: data arriving from the asynchronous source is presented as a `Chunk[Byte]` (specifically a `ByteArray` chunk backed by a standard array), and must be wrapped into a `ByteBuf` before being written to the channel.
- The last chunk of the body must still cause `LastHttpContent.EMPTY_LAST_CONTENT` to be flushed so that Netty can finalise the response cleanly.

**Acceptance criteria**
- A request to a server endpoint that internally calls `Client.request` to fetch data from another path returns the exact same body that the upstream path would return directly.
- Both endpoints return identical responses (status, headers, body) when the same logical resource is requested directly vs. through the proxy handler.
- No `IllegalStateException`, `ClassCastException`, or Netty `ClosedChannelException` is thrown when the proxy path is exercised.
- The existing body-writing strategies (e.g., writing a static string body) continue to work without regression.

Support returning body from another request (#2161)


```markdown
**Title:** Support C# 9 record declarations without braces in brace-layout analyzers

**Issue:**
StyleCop.Analyzers currently do not handle C# 9 record declarations that omit braces, such as `public record Customer(string Name);` or `public record Placeholder;`. The layout rules that check brace placement (e.g., SA1500, SA1502, SA1505, SA1508, SA1509) either produce false diagnostics or throw exceptions when analyzing these declarations, because they assume every record has both an opening and a closing brace token.

**Expected behavior:**
When a record declaration does not provide braces (i.e., its brace tokens are `None`), the brace-layout rules should **not** report any diagnostics for it, and they must not throw exceptions. The rules should silently ignore such declarations rather than treating them as syntactically malformed.

**Affected area:**
All rules in the `LayoutRules` namespace that retrieve `OpenBraceToken` / `CloseBraceToken` from record declarations and then perform line/position checks on those tokens. The concrete list includes at least SA1500, SA1502, SA1505, SA1508, SA1509, but the underlying issue may affect other rules that inspect brace tokens similarly.

**Acceptance criteria:**
- For a single-line record declaration without braces, no brace-related diagnostics are reported.
- No analyzer exceptions are thrown for such declarations.
- The behavior for record declarations *with* braces remains unchanged.
```


**Request: Allow `<inheritdoc />` on static members that implement static abstract/virtual interface members**

### Problem
Rule **SA1648** currently reports a diagnostic when `<inheritdoc />` is placed on a static member, because the rule assumes static members never implement interface members.
With the introduction of **static abstract and static virtual interface members** in C# 11, a static member of a class or struct can genuinely implement an interface member that carries documentation.
In this case `<inheritdoc />` is legitimate and should **not** produce a diagnostic.

At the same time, ordinary static members that do **not** implement any interface member (e.g., static methods of an interface that are not abstract or virtual, or static members of a class that do not implement anything) should **continue** to be flagged by SA1648.

### Acceptance Criteria
1. When a class/struct member is static and it **implements** (explicitly or implicitly) a static abstract or static virtual member from an interface, and that member is decorated with `<inheritdoc />`, SA1648 must **not** generate a diagnostic.
2. If the static member does **not** implement any interface member (including non-abstract/non-virtual static members of an interface when implemented on a class, or unrelated static members), SA1648 must **still** emit the diagnostic as it does today.
3. The rule must work correctly across all C# language versions:
   - On older versions where static abstract/virtual members are not available, nothing changes.
   - On C# 11+ the new behavior applies.
4. The behavior for non-static members must be completely unchanged.

### Additional context
- This is the same rule that already accepts `<inheritdoc />` on instance members that implement interface members.
- The implementation should recognise that a static member can implement an interface member (the current blanket exclusion of all static members from “implementing an interface member” is the root cause).
- The fix should not introduce false negatives for legitimate cases where `<inheritdoc />` is invalid (e.g., a static member that merely matches the signature of a non-abstract interface member without actually implementing it).

Update SA1648 to accept inheritdoc on members implemented from static abstract/virtual interface members. Also add tests for non-abstract/virtual interface members.


**Title:** SA1008: Split diagnostic descriptors, fix leading-newline trailing-space bug, and deduplicate property keys

The `SA1008OpeningParenthesisMustBeSpacedCorrectly` analyzer currently uses a single `DiagnosticDescriptor` with a parameterized message format (`"Opening parenthesis must{0} be {1} by a space."`). This makes the reported messages less readable and harder to suppress individually. We want to replace it with three distinct descriptors, each with a clear, fixed message:

- `DescriptorNotPreceded` – message: `"Opening parenthesis must not be preceded by a space."`
- `DescriptorPreceded` – message: `"Opening parenthesis must be preceded by a space."`
- `DescriptorNotFollowed` – message: `"Opening parenthesis must not be followed by a space."`

The original code also held `haveTrailingSpace` which was always `false` in practice; the trailing-space rule is simply: *never* allow a space immediately after an opening parenthesis. The logic should be simplified to unconditionally report the not-followed descriptor whenever a trailing space is present.

### Bug: trailing space not reported when parenthesis is at start of a line

In `HandleOpenParenToken`, the trivia scan uses an early `return` when it hits `EndOfLineTrivia`, which means the trailing-space check is skipped for any opening parenthesis that is the first token on a new line. This causes a false negative for cases like:

```
TestMethod2(
    ( int)test1);   // trailing space after '(' not flagged
```

The early exit should be changed so that only the leading-space check is affected by the new-line position, while the trailing-space check still runs.

### Code-fix provider

`SA1008CodeFixProvider` currently uses hard-coded string literals (`"location"`, `"action"`, `"preceding"`, `"following"`, `"insert"`, `"remove"`) to read diagnostic properties. This is fragile and duplicates knowledge that should live in the analyzer. The provider should instead reference named constants exposed by `SA1008OpeningParenthesisMustBeSpacedCorrectly` (e.g., `LocationKey`, `ActionKey`, `LocationPreceding`, `LocationFollowing`, `ActionInsert`, `ActionRemove`) so that the strings stay in sync.

### Additional notes

- The public descriptor properties should be `public static` so they can be referenced by the test helper and the code-fix provider.
- The test helper (`DiagnosticVerifier.Helper.cs`) will need an overload `CSharpDiagnostic(DiagnosticDescriptor descriptor)` that creates a `DiagnosticResult` matching a specific descriptor, so tests can assert the exact descriptor that is expected.


**Bug: SA1648 incorrectly requires removing `<inheritdoc/>` on parameterless constructors of classes that inherit from System.Object**

The SA1648 diagnostic is triggered when a constructor declares `<inheritdoc/>` on a class whose base type is `System.Object` (both implicit and explicit inheritance), even though the constructor has zero parameters and could inherit documentation from `System.Object`'s parameterless constructor. The diagnostic should only fire when there is no matching base constructor to inherit documentation from. For a parameterless constructor of any class that inherits (directly or indirectly) from `System.Object`, the base type's parameterless constructor provides a documentation source, so `<inheritdoc/>` is valid.

**Acceptance criteria:**
- A parameterless constructor with `<inheritdoc/>` on a class that does not explicitly declare any base class (implicitly inheriting from `System.Object`) must not produce SA1648.
- A parameterless constructor with `<inheritdoc/>` on a class that explicitly inherits from `System.Object` (`class Test : System.Object`) must not produce SA1648.
- A constructor with one or more parameters that inherits from `System.Object` and uses `<inheritdoc/>` should still trigger SA1648, because there is no matching base constructor to inherit from.
- Classes inheriting from a non-`System.Object` base type must continue to be validated as before: `<inheritdoc/>` is allowed only when a matching constructor signature exists in the base type, otherwise SA1648 is reported.
- No other rule behavior must change; only the exception for parameterless constructors inheriting from `System.Object` is added.


SA1008 does not correctly enforce leading space before the opening parenthesis of a tuple type when the tuple type is part of an array type, a nullable type, or a pointer type, or when the tuple type is preceded by a parameter modifier keyword (`out`, `ref`, `in`, `params`). The rule should require a space in these positions, but it currently fails to do so (or reports incorrectly) because it does not look through the wrapping type to the surrounding context and does not consider keyword modifiers.

Examples:
- `params (int, int)[] arg` / `out (int, int)[] arg` : should require a space before the `(`.
- `public (int, int)? Method()` : the opening parenthesis of the tuple type should be preceded by a space; this fails when the tuple is wrapped in `?` (nullable type).
- `(int, int)[] arg` (bare tuple array parameter) : should require a space before `(`.

Correct SA1008’s handling so that in these cases the opening parenthesis of a tuple type is treated as requiring a preceding space. The fix must correctly handle nesting through array/nullable/pointer wrappers when deciding whether the tuple type appears in a position that expects a leading space (return type, parameter with modifier keyword).

Fix SA1008 handling of tuple type opening parenthesis


Title: SA1515 false positive for comments after C# 7 pattern-matching case labels

### Description
Rule SA1515 (“Single-line comment must be preceded by a blank line”) incorrectly flags a single‑line comment that appears immediately after a pattern‑matching case label in a `switch` statement. The same comment directly after a traditional `case` or `default` label is correctly permitted.

### Steps to reproduce
1. Enable StyleCop.Analyzers in a C# project that targets C# 7 or later.
2. Write a `switch` statement with a case that uses pattern matching:
   ```csharp
   switch (new object())
   {
       case int x:
           // This comment should be allowed without a blank line before it
           break;
   }
   ```
3. Build the project.

### Observed behavior
SA1515 fires on the single‑line comment, requiring a blank line between the `case int x:` label and the comment.

### Expected behavior
No SA1515 diagnostic should be produced. The pattern‑matching case label is semantically equivalent to a regular case label at the start of a new scope. Comments that immediately follow it should be treated the same way as comments after `case <value>:` or `default:`, i.e. they should not require a preceding blank line.

### Impact
Developers using modern C# pattern‑matching must either add unnecessary blank lines (producing inconsistent switch‑statement formatting) or suppress the rule for those statements. This is especially disruptive in codebases that heavily adopt pattern matching and enforce SA1515.

Fix SA1515 handling of comment after pattern-matching case label


**Title:** SA1114 (ParameterListMustFollowDeclaration) should also enforce blank-line rules on constructor calls

**Background**
SA1114 currently reports a diagnostic when a parameter/argument list has a blank line between the opening parenthesis and the first element. This check already works for:

- method declarations
- constructor declarations
- method invocations (e.g. `DoSomething(` … `)`)

**Missing behavior**
The rule does **not** analyze object creation expressions (constructor calls) of the form `new Foo(…)`. Users can add an unexpected blank line after the opening parenthesis without a diagnostic, which is inconsistent with the handling of method invocations.

**Desired behavior**
SA1114 should also examine the argument list of an object creation expression. The same blank-line logic must apply:

- Report SA1114 when the argument list starts with a blank line (i.e. the first argument does not appear immediately after the opening parenthesis, either on the same line or on the very next line with no intervening empty line).
- Do **not** report a diagnostic when:
  - the arguments are on the same line as the opening parenthesis
  - the first argument is on the line directly following the opening parenthesis (no blank line in between)
  - the argument list is empty (even if blank lines appear inside an empty `()`) — this mirrors the existing tolerance for empty lists in method invocations.

The diagnostic locations, severity, and message text should remain unchanged and follow the same convention as for method invocations.

**Constraints**
- The change must not alter the existing behavior for method declarations, constructor declarations, or method invocations.
- For object creation expressions, the same syntactic structures (`ArgumentListSyntax`) and positional logic should be used; no new concepts or exceptions should be introduced.

**Acceptance criteria**
A `new Foo(\n\narg)` pattern triggers SA1114.
`new Foo(\narg)` and `new Foo(arg)` do not trigger SA1114.
Empty `new Foo(\n)` or `new Foo(\n\n)` do not trigger SA1114 (consistent with method invocation handling).


Title: Fix SA1624 handling for expression-bodied properties

The `PropertySummaryDocumentationAnalyzer` must correctly handle documentation summaries on expression-bodied properties (e.g., `int Property => default;`). An expression-bodied property has only an implicit get accessor, so the same documentation rules that apply to a property with a single explicit `get;` accessor should apply here.

**Observed problem:**
When a summary on an expression-bodied property starts with `"Gets or sets"` (or the bool variant `"Gets or sets a value indicating whether"`), the analyzer does not report the correct diagnostic. Instead of SA1624 (property summary text should reflect the actual accessors) with an offer to remove the extra `"or sets"` part, it either reports SA1623 (property summary must start with get/set text) or fails to provide a code fix. This is inconsistent with the behaviour for a property declared with only a `{ get; }` accessor.

**Expected behaviour:**
- A summary that starts with `"Gets"` (or the bool form `"Gets a value indicating whether"`) should be accepted as valid for an expression-bodied property – no diagnostic.
- A summary that starts with `"Gets or sets"` should produce **diagnostic SA1624**. The diagnostic must supply the `ExpectedTextKey` and `TextToRemoveKey` properties so that the existing `PropertySummaryDocumentationCodeFixProvider` can offer a fix: replacing the summary text with the single‑accessor form (i.e., stripping `" or sets"`).
- The behaviour should be identical to how explicit get‑only properties are handled.

**Acceptance:**
- Unit tests confirm that expression-bodied properties with summary starting with `"Gets"` produce no diagnostic.
- Unit tests confirm that expression-bodied properties with summary starting with `"Gets or sets"` produce SA1624, and that the code fix correctly changes the summary to the single‑accessor text.

Fix documentation check for Expression Body Properties


SA1206 does not currently recognize the `ref` keyword in C# 7.2 `ref struct` declarations.

`ref` should be treated as a standard modifier (classified alongside other non-accessibility, non‑static modifiers such as `partial`, `readonly`, `fixed`, etc.). The rule must enforce the usual modifier ordering: accessibility modifiers (e.g., `private`, `public`) must appear before `ref`.

**Acceptance criteria**
- `private ref struct` → no SA1206 violation.
- `ref private struct` → SA1206 is reported, with the diagnostic indicating that `ref` must come after `private`.

The change should only affect the ordering logic; it must not introduce false positives for any existing valid modifier combinations, and it must not break the behaviour of SA1206 for other modifiers.


**Bug: SA1119 code fix removes parentheses from preprocessor directive without preserving required whitespace**

When the SA1119 "Remove unnecessary parentheses" code fix runs on a parenthesized preprocessor expression like `#if (DEBUG)`, the resulting code becomes `#ifDEBUG`—the `#if` token and the symbol merge without any space, producing invalid C#. The fix should instead yield `#if DEBUG` with a separating space, because the original `#if` keyword does not end with trailing whitespace.

More generally, the fix should ensure that when it removes parentheses and the unwrapped expression has no leading trivia, the space between the previous token and the expression is maintained. If the previous token already has trailing whitespace in its trivia, no extra space is needed; otherwise, a space must be inserted to keep tokens separated.

The fix must continue to work correctly for ordinary non-directive cases (e.g., `int x = (5);` → `int x = 5;`) and for directive cases where whitespace already exists, without adding duplicate spacing.

Made things work properly for the normal situation as well


SA1623 (property summary documentation) does not handle C# 7 ref-returning properties correctly.
When a property has a return type like `ref int`, the analyzer should still determine the underlying type (`int`) to decide whether the summary should start with "Gets" or "Sets".
Currently, the ref modifier causes the property type to appear as `ref int`, which can lead to false diagnostics or failures.

Fix: Before querying the semantic model for the property type, strip the `ref` wrapper from the `TypeSyntax` so that the check works the same as for non-ref properties.
The fix must remain compatible with earlier C# versions (use the `Lightup` helpers for `RefTypeSyntax` access).
No other property analysis behavior should change.

Update documentation analyzer to handle ref returns


**Title:** SA1130 code fix crashes on event delegates when the event symbol cannot be resolved

**Description:**

When an SA1130 diagnostic is raised for an anonymous method subscribed to an event (via `+=` or `-=`), and the event itself cannot be resolved by the compiler (for example, because the event name is misspelled or undefined), applying the SA1130 code fix causes an exception. The code fix should instead handle this case gracefully: it should **not** offer a code fix at all when the event symbol cannot be resolved, because the transformation relies on extracting parameter names from the event delegate type.

This problem only occurs when the anonymous method expression’s parent is an `AddAssignmentExpression` or `SubtractAssignmentExpression` whose left-hand side is an unresolved symbol. In all other cases the code fix works correctly.

**Expected behavior:**

- The SA1130 code fix provider must not crash when the event symbol is missing.
- When an event symbol cannot be resolved, the code fix should **not** be registered, so no lightbulb action is shown.
- If a fix-all operation encounters such a diagnostic, the unresolved node should be left unchanged rather than causing an exception.

**Steps to reproduce (conceptual):**

Write a small C# project where an event subscription uses an anonymous method but the event itself is not declared anywhere (or contains a typo), e.g.:

```csharp
TestEvent -= delegate { Console.WriteLine("hello"); };
```

The analyzer will still flag the anonymous method for SA1130. Attempting to apply the corresponding code fix currently crashes.

Fix that the SA1130 code fix crashes on an invalid event symbol


SA1112 (Closing parenthesis must be on line of opening parenthesis) currently ignores local functions. It should detect when a local function declaration has no parameters and the closing parenthesis is placed on a different line than the opening parenthesis, and offer a code fix to move it to the same line. This behavior should mirror how the rule already handles regular methods and constructors. Local functions that **do** have parameters should not be flagged (consistent with existing treatment of parameterized method declarations).

Implement support for local functions in SA1112


The SA1129 code fix incorrectly suggests replacing `new CancellationToken()` with `CancellationToken.None` when the expression appears as a default parameter value. This produces invalid code because `CancellationToken.None` is not a compile-time constant and cannot be used as a default argument. The fixer should propose `default(CancellationToken)` in that context instead. The analyzer itself already correctly reports the violation; only the code fix needs to be adjusted to handle the default-parameter case.

Fixed SA1129 code fix for CancellationToken as default parameter


```
SA1501 should treat single-line blocks inside lambdas/anonymous methods
based on whether the *whole containing expression* is single-line

Currently SA1501 unconditionally allows single-line blocks when the
block's parent is an anonymous method or lambda expression (simple or
parenthesized).  The StyleCop convention is narrower: a single-line block
is allowed only when the entire lambda/anonymous-method expression fits
on a single line.  When the expression spans multiple lines (e.g. the
arrow is on one line and `{ ... }` on the next), the block must be
expanded, just like any other multiline statement.

The code fix for SA1501 also needs adjustment for these cases:
- Indentation of the expanded block body should be relative to the
  *statement* parent, not the immediate parent expression.
- For lambda/anonymous-method blocks, the block open brace should be
  indented one additional level beyond that statement parent.
- When deciding whether to add a newline after the closing brace, the
  code fix must not add one if the next token is `)`, `,`, or `;`.

Reproduction example that should produce a diagnostic (currently does
not):
  Func<int> test = () =>
      { return 5; };

Expected after applying the code fix:
  Func<int> test = () =>
      {
          return 5;
      };

Single-line expressions should still be allowed without diagnostics:
  Func<int> test = () => { return 5; };
  EventHandler d = delegate(object s, EventArgs e) { };

This should also handle parenthesized lambda expressions.
```


Fix SA1117 rule to properly enforce "all parameters on same line or each on separate lines". Currently the analyzer only recognizes the separate-lines case when the second parameter is exactly one line below the first; otherwise it bails out to SA1115, which does not enforce any line placement. This means parameters that span more than one line distance (e.g., first param on line 5, second on line 8) can escape the rule entirely.

The expected behavior:
- If the first parameter is on the same line as the opening token/separator, then *all* parameters must be on that same line.
- Otherwise (first parameter on a different line), every parameter must be on its own separate line, regardless of the line gap.

Apply this fix consistently to parameter lists, argument lists, attribute argument lists, and array creation sizes. Also ensure that array rank specifiers in jagged/multidimensional creations like `new int[10][,,,]` do not trigger false diagnostics—those commas should not be mistaken for separate size expressions.


Bug: SA1217 does not respect `systemUsingDirectivesFirst` for static using directives

When `systemUsingDirectivesFirst` is enabled under `orderingRules` in `stylecop.json`, regular `using` directives for `System.*` namespaces are ordered before other usings — both in diagnostics reported by SA1210/SA1211 and in the code fix sorting. However, the same setting is ignored for static using directives (`using static`).

**Observed behavior**
Given the following code with `systemUsingDirectivesFirst: true`:
```csharp
using static MyNamespace.TestClass;
using static System.Math;
```
SA1217 does not report a diagnostic ordering issue, and the corresponding code fix does not move `System.Math` before the non‑System static using.

**Expected behavior**
When `systemUsingDirectivesFirst` is enabled, static usings for `System.*` should be placed before other static usings, just as regular System usings are placed before other namespace usings. The ordering within the system‑static group and within the non‑system static group should each remain alphabetical.

**Additional constraints**
- Static using directives that resolve to a type or member whose full name begins with `System` must be recognized as *system static imports* and should be separated accordingly.
- The analyzer (SA1217) must emit a diagnostic when a non‑system static using appears before a system static using under this setting, and the code fix must reorder them correctly.
- The implementation must correctly identify static usings for `System.*` despite the fact that they resolve to types (or members) rather than namespaces. The current `IsSeparatedSystemUsing` in the sorter only checks for `INamespaceSymbol` and also explicitly skips static usings, so it cannot classify static system usings. A classification that works for both regular and static usings is needed.
- The sorting order in the code fix provider (`UsingCodeFixProvider`) must place system static imports immediately after regular System usings (if any) and before other static imports, respecting the existing grouping conventions.
- The change should not affect behavior when `systemUsingDirectivesFirst` is false or not configured; static usings should remain a single alphabetically ordered group as before.

This inconsistency forces teams that use `systemUsingDirectivesFirst` to manually reorder static usings, undermining the automated enforcement.

Added system first support for static usings


We need to support file headers written as multiline (`/* ... */`) comments, not only `//` comments. Currently, SA1633 reports a missing file header and SA1636 reports a copyright text mismatch for files that use a valid multiline comment header. Additionally, the copyright text comparison is overly strict: it compares the full copyright text as a single string, so leading `*` prefixes, indentation, and line-end variations in multiline comments cause false SA1636 violations even when the actual copyright text matches the configured `copyrightText` setting. The comparison should be line-based and ignore leading and trailing whitespace on each line, so that typical multiline-comment formatting and whitespace in file headers do not cause false positives. This must work for both XML headers (`<copyright>` inside the comment) and plain text headers (when `xmlHeader` is false).


**Title:** SA1117: "Parameters must be on the same line" incorrectly uses end-line for comparison

**Severity:** Bug (false positives / false negatives)
**Rule:** SA1117 (ParametersMustBeOnSameLineOrSeparateLines)

**Summary**
When the first two parameters in a parameter list appear on the same line, the rule currently compares the start line of one parameter with the *end* line of the next parameter to determine whether subsequent parameters are also “on the same line”. This leads to incorrect diagnostics whenever a parameter is a multiline expression (e.g., a concatenation, a lambda body, an array initializer).

**Expected behavior**
The rule should only compare the *starting* positions of adjacent parameters. If the first N parameters all start on the same line, then every additional parameter that also starts on that same line should not produce a violation (conversely, a parameter starting on a different line should trigger the rule). The end line of any parameter is irrelevant.

**Steps to reproduce**
1. Write a method invocation/declaration where two or more arguments appear on the same opening line, one of those arguments spans multiple lines (so its start line differs from its end line), and a *later* argument also starts on the same opening line.
2. Observe that SA1117 reports a warning claiming the later argument is not on the same line (or incorrectly allows a configuration that should be flagged).

**Affected areas**
All constructs checked by SA1117: method declarations, indexers, delegates, constructor initializers, attribute arguments, array creation expressions, and invocations.

**Request**
Update the line-condition logic in the rule implementation so that when the initial parameters are on the same line, the comparison for subsequent parameters is strictly `param1.GetLine() == param2.GetLine()` (start vs. start). No other changes to the rule’s logic are needed.

Only compare starting positions for "on same line"


**SA1200 code fix mishandles a comment separated from the first using directive by a blank line**

When the `SA1200` (UsingDirectivesMustBePlacedCorrectly) code fix moves using directives to a different location (for example, inside a namespace), any comment that precedes the first using directive is normally carried along with the using block. However, if that comment is separated from the first using directive by one or more blank lines, the fix fails to preserve the comment correctly: it is either left behind or attached to the preceding file header instead of being moved together with the using directives.

**Expected behavior**
A comment that is separated from the first using directive by a blank line should be treated as belonging to the set of using directives, not as part of the leading file header or any preceding declaration. After the fix moves the using directives into their target scope:

- The separated comment should appear before the first using directive in the sorted result, maintaining the blank line separation that existed before the first using.
- The comment (and any blank lines) should be indented to match the new surrounding scope, without introducing trailing whitespace on blank lines.
- If the trivia before the first using already contained other elements (such as preprocessor directives or `#if false` blocks), those should continue to be handled with their existing indentation rules and not be damaged.

**Current (incorrect) behavior**
The comment is not associated with the using block; it may be incorrectly merged with the file header or even dropped from the output, depending on the exact trivia arrangement.

**Impact**
Developers who rely on separated comments to document groups of using directives see these comments lost or misplaced after applying the SA1200 fix, leading to manual rework.

Fix handling of both a header and a separated comment


**Title:** SA1208 code fix does not work with file-scoped namespaces (C# 10)

**Background**
SA1208 (“System using directives must come before other using directives”) is an ordering rule. The analyzer already detects violations inside file-scoped namespaces (e.g. `namespace Foo;`), but when the user invokes the code fix (lightbulb / “fix all”) it either fails or reorders the using directives incorrectly.

**Desired behavior**
The code fix for SA1208 should correctly reorder using directives that appear inside a file-scoped namespace, matching the behavior that already exists for traditional block‑scoped namespaces.

**Notes / constraints**
- File-scoped namespace nodes are syntactically different from block‑scoped `NamespaceDeclarationSyntax`, so code that only picks up the latter will miss or mishandle file‑scoped cases. The fix must treat both forms uniformly when iterating members, counting namespaces, processing using directives, and inserting/removing nodes.
- The fix must work under the existing `UsingDirectivesPlacement` settings (`InsideNamespace` / `OutsideNamespace`). For file‑scoped namespaces, using directives are semantically inside the namespace, so the “placed inside” behavior should apply.
- The fix should not regress existing behavior for block‑scoped namespaces, nor break when multiple (nested) namespaces are present (even though file‑scoped namespaces cannot be nested).
- The fix should leverage the same compatibility abstraction already used elsewhere in the codebase for handling newer syntax nodes (e.g. the `Lightup` helpers) rather than duplicating logic.

Implement code fix support for SA1208 with file-scoped namespaces


```
SA1015 (ClosingGenericBracketsMustBeSpacedCorrectly) reports spacing violations for trailing spaces after `>` that appear inside dictionary initializer items, collection initializers, and C# 12 collection expressions. For example, the following patterns are incorrectly flagged:

- `{ M<int> }` as the last element in a collection initializer (e.g., `new List<Action> { M<int> }`)
- `{ 1, M<int> }` as a dictionary initializer item
- `[ M<int> ]` in a collection expression (C# 12)

In each of these, the space after `>` sits immediately before a closing delimiter (`}` or `]`). This situation is analogous to already-handled cases where a trailing space before `)` or another `>` is allowed. The rule should not report SA1015 for trailing spaces after `>` when the next token is a closing brace that ends an initializer block or a closing bracket that ends a collection expression.
```

Update SA1015 to not care about trailing spaces in a number of cases: typically last in dictionary initializer items, collection initializers and collection expressions. #3856


The SA1006 analyzer (`PreprocessorKeywordsMustNotBePrecededBySpace`) crashes or reports an incorrect diagnostic when a source file ends with a bare `#` followed by optional whitespace and no directive name. For example, a file whose last line is `# ` should not cause the analyzer to throw an exception or produce a spacing-related warning. Instead, it should leave that line alone so the compiler emits its own error, CS1024 ("Preprocessor directive expected").

Acceptance criteria:
- When the token immediately following `#` is missing or does not represent a valid directive name (e.g., when `#` appears as the last meaningful content of the file), SA1006 must not raise any diagnostic for that line.
- The analyzer must not throw an exception in this scenario.
- The analyzer must continue to work correctly for normal preprocessor directives (those with a valid keyword, regardless of spacing).
- The fix should be robust for any scenario where the next token after the hash is not a real directive keyword (not just the last-line case).

Add test for edge case where the preprocessor directive name is missing


SA1629 (Documentation text must end with a period) should flag cases where a documentation comment ends with one or more empty inline XML elements (e.g., `<see cref="..." />`, `<paramref name="..." />`, etc.). Currently the rule only inspects trailing text nodes, so if the last content is an empty element after a complete sentence, no diagnostic is raised.

Treat empty inline elements as a "word that does not end with a period": when scanning documentation content backwards, an inline element is the last syntactic token that should end with a period, and it doesn’t. Report the diagnostic immediately after the closing `/>` of that element. If there are multiple consecutive empty elements at the end, report after the very last one. The code fix should insert a period at that location.

Treat empty XML elements as a "word not ending with a period"


The SA1003 "Symbols must be spaced correctly" analyzer reports incorrect spacing violations for several common C# constructs. The following patterns should not produce any SA1003 diagnostics but currently do:

1. **Postfix operators in the third clause of a `for` statement** – For example, `for (var i = 0; i < 99; k++, i++)` should be accepted without requiring or forbidding spaces around the `,` or the `++` operators.

2. **Unary operators and casts immediately inside string interpolation braces** – Expressions such as `$"{(byte)i:X2}"`, `$"{++i}"`, and `$"{i++}"` should be valid. The analyzer should not demand leading or trailing whitespace around the operator or cast that would position it against the `{` or `}` of the interpolation.

3. **Prefix unary operators at the beginning of a line** – When a prefix unary expression (like `++i`) is the first token on a line, for example after a line break inside a method argument list, the leading indentation whitespace should not be flagged as a spacing violation, and the analyzer should not require additional whitespace before the operator.

Additionally, ensure that postfix decrement (`i--`) is covered by the same spacing rules as postfix increment (`i++`); at present it appears to be ignored, leading to inconsistent behavior.

All existing spacing diagnostics for other contexts must continue to work correctly.


```
SA1135 (`UsingDirectivesMustBeQualified`) produces false positives for fully-qualified using alias directives that reference tuple types.

Example:
```csharp
namespace Test {
    using Example = System.ValueTuple<System.Collections.IList, int>;
}
```

SA1135 incorrectly reports a diagnostic for this directive, claiming it is not fully qualified, even though the type name is written in its completely qualified form. This does not happen with non‑tuple types. The problem appears to stem from a mismatch between the Roslyn symbol representation for tuple types and the textual representation used in the using directive: the symbol’s `ToString()` (or equivalent display string) does not match the `System.ValueTuple<...>` syntax that appears in source, so the analyzer’s comparison fails.

The desired behavior is that any using alias directive using a fully qualified tuple type name (e.g. `System.ValueTuple<...>`) is recognized as properly qualified and does not produce a SA1135 warning. The fix should handle tuple types that can be expressed as `System.ValueTuple` with any number of type arguments, in any valid location where an alias directive is allowed (directly inside a namespace, compilation unit, etc.). It should also work correctly in environments where the Roslyn version does not natively expose tuple‑related APIs (i.e., be compatible with the project’s existing lightup/fallback patterns for newer language features), and must not introduce regressions for non‑tuple alias directives or for already‑handled edge cases such as `global::` aliases.
```

Fix handling of tuple types in using alias directives


SA1113 should flag commas that are not on the same line as the previous parameter in array creation expressions.

Currently, SA1113 enforces comma placement for method calls, declarations, attributes, etc., but does not check commas inside array rank specifiers like `new int[1, 2]`. A comma that appears on a separate line in a multi‑dimensional array initializer should produce a diagnostic, just as it does for other comma‑separated lists. The rule should inspect commas in `new`‑based array creation expressions (for example, `new int[1, 2]`), and only report when the comma is on a different line than the preceding size expression. Single‑dimensional arrays such as `new int[1]` have no comma and should not be affected. Jagged‑array declarations with rank specifiers like `int[][,]` are also in scope—any commas within the rank specifier should be checked. This will bring array creation into line with the existing comma‑placement diagnostics.


**Title:** SA1413 code fix drops trailing comments when inserting missing trailing comma

**Observed behavior:**
When the SA1413 code fix (“Use trailing comma in multi-line initializers”) adds a missing trailing comma to the last member of a multi-line initializer or enum declaration, any comment that followed that member on the same line is silently deleted.

For example, after the fix is applied,
```csharp
enum TestEnum
{
    One = 2 /* test comment */
}
```
becomes
```csharp
enum TestEnum
{
    One = 2,
}
```
The expected output is:
```csharp
enum TestEnum
{
    One = 2, /* test comment */
}
```

The same problem occurs with object initializers, collection initializers, and anonymous object initializers that have trailing line comments or block comments on the last element.

**Impact:**
This causes data loss in the form of documentation and inline notes. Users either have to manually re-add the comment after each application of the fix or avoid the fix entirely, undermining the usefulness of the analyzer.

**Expected behavior:**
When the code fix inserts a comma, it must preserve any trailing trivia (comments, whitespace) that originally appeared on the same line after the last member. The inserted comma should appear immediately after the element value, and the original trailing trivia should be placed after the comma. The approach should work uniformly across enum members, initializer expressions, and anonymous object initializers, without dropping or reordering comments.


**Title:** SA1130 should flag anonymous method expressions used as arguments to constructors and indexers

**Description:**
The SA1130 diagnostic (replace anonymous method with lambda) currently only triggers when an anonymous method is passed as an argument in a regular method invocation (`SomeMethod(delegate { })`). It does **not** fire for other invocable expressions that accept argument lists, such as:

- Constructor invocations (`new SomeType(delegate { })`)
- Indexer accesses (`this[delegate { }]`)

**Expected behavior:**
SA1130 should flag anonymous method expressions in all invocable expression contexts where the anonymous method can be safely replaced with a lambda expression. The code fix should also produce the corresponding lambda replacement in those contexts.

**Overload resolution safety (must be preserved):**
The existing implementation avoids offering the replacement when converting to a lambda would change the target overload—for example, when there is a competing `Expression<Action>` overload that the anonymous method could resolve to, but a lambda might bind differently. This safety must be kept for the new contexts as well. Do not introduce a diagnostic or code fix in cases where the lambda would bind to a different overload than the original anonymous method.

**Additional constraints:**
- The analyzer should correctly handle `params` parameters in these contexts, as it does for regular method invocations.
- The analyzer must not crash or produce incorrect diagnostics when the invocation is invalid (e.g., passing an anonymous method to a parameter of type `int*`). In such cases it is acceptable to either produce no diagnostic or to leave the code as-is without offering a fix, but it must not throw an exception or generate a misleading diagnostic.

Make sure the SA1130 exception also works on other invocable expressions


When SA1503 (braces required for single-statement blocks) is suppressed, SA1501 (“statement must not be on a single line”) stops reporting some violations for `else` and `else if` clauses, and the code fix does not correctly move those statements onto their own line.

We need SA1501 to detect and fix the following patterns when SA1503 is disabled:

- An `else` with a statement on the same line:
  `else Debug.Assert(false);` → should be flagged and fixed to:
  ```
  else
      Debug.Assert(false);
  ```
  (no braces added).

- An `else if` with a statement on the same line:
  `else if (i == 4) Debug.Assert(false);` → should be flagged, and the fix should put the statement on the next line under the `else if` without braces.

- Chained `if`/`else if`/`else` where some conditions are multi-line and some are single-line; the single-line clauses should still be reported.

- Nested `if` statements inside `else` clauses (including nested `if`/`else` on a single line) must also be handled correctly so that the diagnostic is raised and the fix produces a reasonable result.

The root issue appears to be that the analyzer and fixer treat the inner `if` statement as the parent when it’s actually part of an `else` clause, causing the single-line check to miss the fact that the statement is on the same line as the `else` keyword. The fix should ensure that, when the clause is an `if` statement that is a direct child of an `ElseClause`, the `ElseClause` is used as the relevant parent for line-containment checks and code fix rewriting.

Constraints:
- The fix must not change behavior when SA1503 is enabled; only the interaction when SA1503 is suppressed matters.
- The code fix must not introduce braces (that’s SA1503’s job).
- All existing SA1501 diagnostics for other statement types must remain unaffected.
- The fix should be symmetric between the diagnostic detection logic and the code fix provider so that diagnostics and fixes correspond correctly.

Updated handling of if/else statements for improved overall behavior


```
Title: SA1001: Narrow comma-after-preprocessor-directive exception — don't silently suppress all spacing checks and don't exempt commas after a blank line

The SA1001 comma‑spacing rule currently has an exception: a comma that follows a conditional preprocessing directive (`#if`, `#elif`, `#else`, `#endif`) is automatically considered valid for all spacing rules. This exception is too broad.

**Problem**

1. **Blank line between directive and comma is ignored.** If a blank line (trailing whitespace / extra end‑of‑line) exists between the directive and the comma, the “comma should not be preceded by whitespace” diagnostic is still suppressed. It should fire because the comma is no longer immediately following the directive.
2. **All other comma‑spacing checks are suppressed.** When a comma follows a directive, diagnostics such as “comma must be followed by a space” are never reported, even though they have nothing to do with the directive. This allows real spacing violations to go undetected.

**Desired behaviour**

- When a comma’s leading trivia consist **only** of the directive trivia and optional whitespace trivia (i.e., the comma directly follows the directive with no intervening line break), suppress *only* the “comma should not be preceded by whitespace” diagnostic (`SA1001` “preceded by whitespace”). All other spacing checks (e.g., the space after the comma) must still be evaluated and reported as usual.
- If there is any extra line break (empty line) between the directive and the comma, treat the comma as no longer following the directive for spacing purposes. The ordinary “comma should not be preceded by whitespace” rule must apply, and the diagnostic must fire.
- The common pattern where a directive line ends and the next line starts with whitespace + comma (no blank line) must continue to be exempt from the “preceded by whitespace” diagnostic.

Concretely, the fix should be in the `SA1001CommasMustBeSpacedCorrectly` analyzer. The exemption logic must stop short‑circuiting all checks and instead only influence the “preceded by whitespace” check based on whether the comma is immediately after a directive trivia, with whitespace but no blank line.

**Acceptance criteria**

- Comma directly after `#if`/`#elif`/`#else`/`#endif` with only whitespace trivia (no blank line) → no “preceded by whitespace” diagnostic, but other spacing diagnostics are still reported.
- Comma after a blank line that follows the directive → “preceded by whitespace” diagnostic fires.
- No regression for ordinary commas (not following a directive).
```

Updated code to check for trailing whitespace and extra space. Updated and added Tests


```
The SA1129 "Do not use default value type constructor" analyzer crashes with a NullReferenceException when it encounters a `new` expression that uses an object initializer without an argument list (e.g. `new MyStruct { X = 1 }`). It also incorrectly flags `new T()` when the type parameter `T` has only a `new()` constraint but no `struct` constraint, suggesting `default(T)` which is invalid for reference types. Additionally, the corresponding code fix is not always offered even when the diagnostic is raised.

Expected behavior:
- No crash for any valid `new` expression. The analyzer should handle cases where `ArgumentList` is null.
- The diagnostic should only be reported when the constructed type is definitely a value type. For generic type parameters, that means the rule should fire only when the type parameter is constrained with `struct` (i.e., has value type constraint), and should not fire when it is only constrained by `new()` or unconstrained.
- The code fix that replaces `new T()` with `default(T)` should be offered for all correct diagnostics from this rule.
```


**Title:** SA1114 crashes on anonymous method with no parameter list

**Area:** Readability rule SA1114 (parameter list must follow declaration)

**Summary:**
The analyzer SA1114 throws a `NullReferenceException` when processing an anonymous method that omits the parameter list entirely, for example:

```csharp
System.Action c = delegate
{
    // ...
};
```

Because `delegate { ... }` has no parentheses and therefore no `ParameterListSyntax` node, the rule attempts to access a member on a null parameter-list object and crashes.

**Expected behavior:**
The rule should handle this case gracefully. Since there is no parameter list to examine and no opening parenthesis to position-check, the method should simply return without reporting any diagnostic. No diagnostic should be produced for these anonymous method declarations.

**Additional notes:**
- The fix should include a targeted test covering the anonymous-method-without-parentheses case, verifying that no diagnostic is raised and that the analyzer does not throw.
- Please make sure the early bail-out path does not accidentally skip valid cases where a parameter list is present but has a missing token (the existing logic checks for `IsMissing` tokens and empty parameter lists – those checks should still run when the list node exists).

SA1114 - fix NullReferenceException when an anonymous method declaration does not have opening parenthesis


Improve the SA1501 code fix so that a single "Fix All" pass expands all enclosed single-line statements, even when multiple violations appear on the same line (e.g., nested `if`/`else` statements on one line). Currently, fixing all violations requires multiple iterations. After the change, "Fix All" should handle all of them in one pass.

To enable this, the analyzer should report hidden diagnostics for secondary violations on the same line — only the first violation per line should remain user-visible. The code fix must collect all affected tokens and apply combined modifications, ensuring correct indentation and no conflicts when multiple violations touch overlapping tokens. This must also work when SA1503 (braces must not be omitted) is suppressed, covering `if`, `do`, `while`, `for`, `foreach`, `lock`, `using`, and `fixed` statements.

Ensure the indentation helper can determine indentation steps even for tokens that have been detached from a syntax tree (i.e., modified tokens during replacement) so that nested expansion always picks up the intended indentation level.

Improved SA1501 codefix to allow for a single pass fixall


The SA1020 analyzer (`SA1020IncrementDecrementSymbolsMustBeSpacedCorrectly`) reports diagnostics when increment/decrement operators (`++`/`--`) have incorrect spacing, but no code fix (lightbulb) is offered. Other spacing analyzers in the same ruleset (e.g., SA1019, SA1013, SA1015) already include code fixes that remove the offending space, and the overall spacing-code-fix infrastructure (`OpenCloseSpacingCodeFixProvider`) already supports “remove preceding space” and “remove following space” actions. The missing fix forces developers to manually delete the extra space for every SA1020 violation.

Expected behavior:
- When SA1020 flags a space before or after an increment/decrement operator, a code fix should be available that removes that space automatically.
- The fix must correctly distinguish “preceded by a space” vs. “followed by a space” violations and remove only the appropriate side.
- The fix should integrate with the existing `OpenCloseSpacingCodeFixProvider`, meaning the analyzer needs to emit the standard diagnostic properties (`LocationKey` and `ActionKey`) used by that provider.


**SA1623/SA1624 property summary rules incorrectly suppress when `<inheritdoc/>` appears after text**

The property summary documentation rules (SA1623/SA1624) currently skip the summary content check if an `<inheritdoc/>` tag is present anywhere inside the `<summary>` element. This is too permissive: when meaningful text appears *before* `<inheritdoc/>` in the summary, that text should still be subject to the normal property summary requirements (e.g., the summary must start with a phrase like “Gets or sets…”).

**Expected behavior**
- If the first non-whitespace content of the `<summary>` is an `<inheritdoc/>` element, the summary text requirement is ignored (the existing safe harbor remains).
- If any non-whitespace text appears before `<inheritdoc/>`, the summary must still satisfy the usual prefix requirement, and a diagnostic should be reported if it does not.

**To fix**
Adjust the `<inheritdoc/>` detection logic so that it only suppresses the diagnostic when the `<summary>` *starts* with `<inheritdoc/>` (allowing leading whitespace), rather than when `<inheritdoc/>` appears anywhere in the summary.


```
Implement the SA1638 analyzer (currently stubbed with a TODO) to report a warning when the file name declared in the `<copyright file="...">` attribute does not match the actual file name, case‑insensitive.

The existing placeholder is in `SA1638FileHeaderFileNameDocumentationMustMatchFileName.cs`; it currently uses `AnalyzerConstants.DisabledNoTests` and has placeholder message/description strings.

Requirements for the implementation:
- Use the same file‑header parsing helpers (`FileHeaderHelpers`) already employed by sibling rules (e.g., SA1634, SA1635, SA1637).
- Do **not** produce a diagnostic when:
  - the file header is missing or malformed (handled by SA1633),
  - the `<copyright>` element is missing (handled by SA1634),
  - the `file` attribute is absent on `<copyright>` (handled by SA1637).
- When the `file` attribute is present and its value does not exactly match the file name (ordinal, ignoring case), emit a diagnostic at the location of the `<copyright>` element.
- The diagnostic descriptor must be enabled by default. Update the `MessageFormat` and `Description` strings from their current placeholder/TODO values to appropriate, clear messages.
```


```markdown
Title: SA1015 / SA1023 incorrectly handle spacing for pointers to generic types

### Description

When declaring unsafe pointers to generic types (e.g., `Foo<T>*`), StyleCop’s spacing rules SA1015 (`ClosingGenericBracketsMustBeSpacedCorrectly`) and SA1023 (`DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly`) either produce false positives or fail to enforce the correct spacing. The expected formatting for a pointer to a generic type is the same as for any other pointer: the `*` should attach directly to the type name, with a space before the identifier (e.g., `Foo<T>* Next`).

### Current (incorrect) behaviour

- `Foo<T>* Next` may be flagged as a violation by SA1015 or SA1023, even though the spacing is correct.
- `Foo<T> * Next` (a space before the `*`) may not be reported by SA1023, or SA1015 may incorrectly demand that the space after `>` be removed or added.
- Code fixes do not reliably produce the canonical form `Type* identifier`.

### Expected behaviour

1. **SA1015 (closing generic bracket spacing):**
   After `>`, both zero spaces and a single space should be accepted when the next token is an `*` that belongs to a pointer type. This mirrors the existing handling for `?` after a closing generic bracket in nullable value types (e.g., `int?>`) where both spacing styles are allowed.

2. **SA1023 (dereference/access spacing):**
   When an `*` follows a closing generic bracket and is part of a pointer type, the rule must enforce pointer-type spacing:
   - No space is allowed between `>` and `*`.
   - A space is required after `*` before a subsequent identifier (unless the `*` is at the end of the line).

   The code fix should correct any deviation to `Type* identifier`.

   Specifically:
   - `Foo<T>* Next` → no diagnostic.
   - `Foo<T> * Next` → SA1023 should report a diagnostic on the `*` (space not allowed before `*`) and fix it to `Foo<T>* Next`.
   - `Foo<T>*Next` → SA1023 should report a diagnostic (space required after `*`) and fix it to `Foo<T>* Next`.

### Constraints

- The change must only affect `*` tokens that are part of a **pointer type** (i.e., enclosing syntax is a pointer-type declaration) in `unsafe` contexts. Multiplication, dereference-in-expressions, and other uses of `*` must not be impacted.
- The analysis must remain version-agnostic; the fix should apply to all C# versions that support unsafe pointers.
- Existing working cases (e.g., `int*`, `int?>`, `int? *`? – though the last is unlikely) must continue to work without regression.
```

Fix handling of pointers to generic types


**User story: SA1111 missing diagnostics for operator / conversion operator declarations**

SA1111 (Closing parenthesis must be on line of last parameter) currently only reports violations for method declarations and constructor declarations. It does not check operator declarations (e.g., `operator +`, `operator -`) or conversion operator declarations (`explicit operator`, `implicit operator`). This gap means that when the closing parenthesis of such a declaration appears on a line by itself after the last parameter, no warning is raised and no code fix is offered.

**Acceptance criteria**
- SA1111 must report a warning whenever the closing parenthesis of a unary operator, binary operator, or conversion operator declaration is not on the same line as the last parameter.
- The accompanying code fix must reposition the closing parenthesis onto the line of the last parameter (consistent with the existing fix for methods and constructors).
- Declarations that already have the closing parenthesis on the last parameter's line must remain clean (no false positives).

**Examples of violations that should be caught**
```csharp
// Unary operator
public static Foo operator +(Foo value
) { … }

// Binary operator
public static Foo operator +(Foo a, Foo b
) { … }

// Conversion operator
public static explicit operator Foo(int value
) { … }
```

**Non-goals / safety constraints**
- Parameter lists that are missing or empty (e.g., a conversion operator with no parameters—if that is even syntactically possible) should not cause exceptions or false positives.
- The behavior for existing method/constructor declarations must remain unchanged.
- The rule must not introduce new diagnostics for valid operator/conversion operator declarations.

Added support to SA1111 for operators and conversion operators