diff --git a/swift-ingestion-gaps.md b/swift-ingestion-gaps.md new file mode 100644 index 000000000..858bf8935 --- /dev/null +++ b/swift-ingestion-gaps.md @@ -0,0 +1,79 @@ +# Swift Ingestion Gaps + +Tracks missing Swift features in the GitNexus ingestion pipeline. Organized by priority. + +## 🔴 High Priority + +### Type Inference + +| Gap | Description | Impact | +|-----|-------------|--------| +| `if let` / `guard let` inside for-loop bodies | Type-env binds the variable correctly but call-processor's re-parse path doesn't propagate for-loop element bindings to receiver resolution | Calls inside `for item in collection` are unresolved | +| `while let` binding | `while let x = iter.next()` not in `DECLARATION_NODE_TYPES` | Uncommon but valid Swift pattern | + +### Call Resolution + +| Gap | Description | Impact | +|-----|-------------|--------| +| `await expr` / `try expr` as call wrappers | `await_expression` and `try_expression` wrap `call_expression` — call extraction queries match but the outer wrapper can interfere with receiver resolution in some paths | Most cases work via `unwrapSwiftExpression` but edge cases remain | +| Multi-hop chains | `a.b.c()` — only single-hop `receiver.method()` resolved | Common in UIKit/SwiftUI code | +| Trailing closures | `items.map { $0.save() }` — `$0` type not inferrable | Functional-style Swift code | + +## 🟡 Medium Priority + +### Symbol Extraction + +| Gap | Description | Impact | +|-----|-------------|--------| +| Enum `case` as callable | `MyEnum.case` calls are member-form, not caught by constructor fallback | Enum-heavy code (Result, State enums) | +| Subscript declarations | `subscript(i:) -> T` not captured | Protocol conformance tracking | +| Operator overloads | `static func + (lhs:, rhs:)` not captured | Mathematical types | +| `deinit` | `deinit {}` not captured | Minor — rarely called explicitly | + +### Heritage / Inheritance + +| Gap | Description | Impact | +|-----|-------------|--------| +| Multiple inheritance specifiers | `class Foo: Bar, P1, P2` — only first specifier captured | Missing protocol conformance edges | +| Generic constraints | `class Foo` — bounds not tracked | Advanced generics | +| Conditional conformance | `extension Array: P where Element: Q` — `where` clause not processed | Cross-platform code | +| Protocol composition | `typealias Codable = Encodable & Decodable` — not expanded | Type alias resolution | + +### Export / Visibility + +| Gap | Description | Impact | +|-----|-------------|--------| +| Nested function declarations | Inner `func` marked as exported — should be private | Conservative resolution still correct (over-exports) | + +### Module / Import + +| Gap | Description | Impact | +|-----|-------------|--------| +| `@testable import` | Test target imports treated as opaque | Test file cross-references | +| Cross-package SPM imports | External package symbols not resolved | Only affects multi-package repos | +| `@_exported import` | Module re-exports not tracked | Framework wrapper patterns | + +## 🟢 Low Priority + +### Type Inference + +| Gap | Description | Impact | +|-----|-------------|--------| +| `switch` / `case` pattern binding | `case let x as Foo:` not tracked | Enum pattern matching | +| Tuple destructuring | `let (a, b) = fn()` not handled | Uncommon pattern | +| `@Environment` / `@EnvironmentObject` | SwiftUI dependency injection — no AST representation | Would need heuristic resolution | +| `@Query` (SwiftData) | Property wrapper types not inferrable from AST | SwiftData-specific | +| `#if canImport(...)` | Conditional compilation not evaluated | Cross-platform projects | + +## ✅ Resolved + +| Gap | Resolution | Commit | +|-----|-----------|--------| +| Cross-chunk implicit imports | `addSwiftImplicitImports` now uses `allFileList` instead of chunk-only `files` | `956dfd0` | +| `private(set)` false positive | Regex excludes `private(set)` / `fileprivate(set)` from unexported check | `0a3cdce` | +| `if let` / `guard let` binding | `extractIfGuardBinding` handles optional bindings | `16b1a63` | +| `await` / `try` unwrapping | `unwrapSwiftExpression` strips wrappers before RHS analysis | `16b1a63` | +| For-loop element type extraction | `extractForLoopBinding` + `extractSwiftElementTypeFromTypeNode` + type_annotation population in type-env | `956dfd0` | +| `self` / `super` resolution | `lookupInEnv` handles `self`/`super` via AST walk | `16b1a63` | +| Optional chaining `obj?.method()` | Handled via `optional_chaining_expression` | `16b1a63` | +| Multi-inheritance specifiers | First specifier captured via `inheritance_specifier` query | `16b1a63` | diff --git a/type-resolution-system.md b/type-resolution-system.md index 62a59e760..702e04dca 100644 --- a/type-resolution-system.md +++ b/type-resolution-system.md @@ -381,15 +381,15 @@ So return-type-aware receiver inference already exists in a constrained downstre | Parameters | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | Initializer / constructor inference | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | | Constructor binding scan | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | -| For-loop element types | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | -| Pattern binding | Yes | Yes | Yes | Yes | No | Yes | Yes | No | No | No | No | No | No | +| For-loop element types | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes††† | Yes | Yes | +| Pattern binding | Yes | Yes | Yes | Yes | No | Yes | Yes | No | No | No | Partial‡‡‡ | No | No | | Assignment chains | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | | Field/property type resolution | Yes | No† | Yes | Yes | Yes | Yes | Yes | Yes* | Yes | YARD | No | Yes | No‡ | | Comment-based types | JSDoc | JSDoc | No | No | No | No | No | No | PHPDoc | YARD | No | No | No | | Return type extraction | JSDoc | JSDoc | No | No | No | No | No | No | PHPDoc | YARD | No | No | No | -| Call-result variable binding | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes¶ | No | Yes | No | -| Field access binding | Yes | No† | Yes | Yes | Yes | Yes | Yes | No‖ | Yes | N/A | No | Yes | No | -| Method-call-result binding | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes¶ | No | Yes | No | +| Call-result variable binding | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes¶ | Yes††† | Yes | No | +| Field access binding | Yes | No† | Yes | Yes | Yes | Yes | Yes | No‖ | Yes | N/A | Yes††† | Yes | No | +| Method-call-result binding | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes¶ | Yes††† | Yes | No | | Write access (ACCESSES write) | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes§ | Yes | Yes | Yes | No | | Parameter types extracted | Yes** | No | Yes | Yes | Yes | Yes | Yes | Partial†† | No | No | No | Yes | No | | Method overload disambiguation | Yes** | No | Yes | Yes | Yes | No | No | No | No | No | No | Yes | No | @@ -423,6 +423,10 @@ So return-type-aware receiver inference already exists in a constrained downstre ¶¶ C#: `using static NS.Type;` now captured (last segment as class binding). Non-alias `using NS;` still unsupported — namespace imports can't be reduced to per-symbol bindings without type inference. +††† Swift: `extractPendingAssignment` handles `callResult`, `methodCallResult`, `fieldAccess`, and `copy` bindings. `if let` / `guard let` optional bindings supported via `extractIfGuardBinding`. `await` / `try` expression wrappers are unwrapped before RHS analysis. For-loop element type extraction supports `[User]` array sugar and `Array` generics. See `swift-ingestion-gaps.md` for remaining limitations. + +‡‡‡ Swift: `if let` / `guard let` optional bindings supported. `while let`, `switch` / `case` pattern matching, and tuple destructuring not yet implemented. + \*\*\* Whole-module-import languages (Go, Ruby, C/C++, Swift): namedImportMap entries synthesized from graph-exported symbols via `synthesizeWildcardImportBindings()`. Not from import AST node extraction. --- @@ -458,7 +462,7 @@ Important gaps still remain: - no general cross-file propagation of inferred bindings - `this`/`self`/`$this` receivers are not resolved in the fixpoint loop (resolved on-demand at call sites via AST walk instead) - limited branch-sensitive narrowing outside selected pattern constructs -- limited Swift support compared with other languages +- limited Swift support compared with other languages (see `swift-ingestion-gaps.md`) - no complete destructuring-based field typing - no MRO/inheritance walking for field lookups (`lookupFieldByOwner` is direct-only) - for-loop variables bound at walk time cannot see fixpoint-resolved types (Phase 9B gap)