Skip to content

Conversation

@ecito
Copy link
Contributor

@ecito ecito commented Oct 30, 2025

Description

Fixes an access control issue in the @Schemable macro where types defined inside public extensions would generate schema properties with (internal) access levels, making them inaccessible from other modules.

Problem:
When defining types inside public extensions like this:

public extension Weather {
  @Schemable
  struct Forecast {
    let temperature: Double
  }
}

The generated schema property was static var schema (internal) instead of public static var schema, preventing other modules from accessing it despite Forecast being effectively public.

Solution:

  • Added effectiveAccessLevel() function that inspects the macro's lexical context to detect parent extensions
  • When a type has no explicit access modifier, the macro now inherits the access level from any enclosing extension
  • Updated all schema generators (struct, class, enum) to accept and properly format the computed access level
  • Explicit modifiers on types still take precedence over extension modifiers

Impact:

  • Types in public extensions now correctly generate public schema properties
  • Backward compatible - existing code behavior unchanged

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Additional Notes

Test Coverage:

  • Added 274 lines of comprehensive tests covering:
    • Extension-defined types (1, 2, and 3 levels deep)
    • Mixed declaration types (struct, class, enum)
    • Parameterized tests ensuring both structs and classes work correctly
  • All 203 tests passing (including all existing tests)

Examples:

Before:

public extension Weather {
  @Schemable struct Forecast { }
}
// Generated: static var schema ❌ (internal - not accessible from other modules)

After:

public extension Weather {
  @Schemable struct Forecast { }
}
// Generated: public static var schema ✅ (accessible from other modules)

Edge Cases Handled:

  • Explicit modifiers override extension modifiers
  • Deep nesting (3+ levels) works correctly
  • Non-extension types unchanged (backward compatible)
  • Supports public, package, and internal extensions

ecito added 2 commits October 30, 2025 13:14
When types are defined inside public extensions (e.g., 'public extension Foo { struct Bar {} }'), the generated schema property needs to inherit the extension's public access modifier to be accessible from other modules.

Changes:
- Add effectiveAccessLevel() to check lexical context for parent extensions
- Update SchemaGenerator and EnumSchemaGenerator to accept access level parameter
- Pass computed access level to generators with proper trivia formatting
- Add comprehensive tests for extension-defined types at multiple nesting levels

Fixes access control issue where schema properties were internal despite being in public extensions.
@ajevans99 ajevans99 merged commit 9ffa3d1 into ajevans99:main Oct 30, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants