MarcoEidinger / SwiftPlantUML

A command-line tool and Swift Package for generating class diagrams powered by PlantUML

Home Page:https://marcoeidinger.github.io/SwiftPlantUML/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support nested types in extensions and extending nested types

MarcoEidinger opened this issue · comments

Related: MarcoEidinger/SwiftPlantUML-Xcode-Extension#26

Example

public enum APublic {
    public enum BPublic {
        public static func publicFuncDefinedInType() {}
    }
}

// Extension is declared public, so each top level member "inherits" that access level.
public extension APublic.BPublic {
    
    // Hence this is public even if it is not annotated
    static func hasAccessLevel() -> String { return "public" }
    
    // Also this class is public
    class CPublic { // NEW: nested type defined in extension
        // However, its members must be annotated. This is public
        public static func publicFunc() {}
        
        // This is internal because no explicit access level modifier is used
        static func internalFunc() {}
    }
}

// Extension has no explicit access level modifier and therefore it is internal
// so each top level member "inherits" that access level.
extension APublic.BPublic {
    
    public static func publicFuncAddedInExtenion() {} // NEW: extending nested type
    
    class CInternal {
        public static func publicFunc() {}
    }
}

extension APublic.BPublic.CPublic {
    public static func publicFuncAddedInExtenion() {} // NEW: extending nested type

    static func internalFuncAddedInExtenion() {}
    
    private static func privateFuncAddedInExtenion() {}
}

private extension APublic.BPublic.CInternal {
    private class DPrivate {
        init() {}
    }
    
    // compiles but `DPublic` will not be accessible as it is defined in a private extension
    public class DPublic {
        public init() {}
    }
}

Expected output

Note: extensions will always be rendered/processed no matter what elements.havingAccessLevel you specify in configuration.

  • Reason: extensions may not have an explicit access-level modifier, i.e. any type members added in an extension have the same default access level as type members declared in the original type being extended but also it is possible to set explicitly set an access level for type member declaration.
  • Example: extension APublic.BPublic adding new type members have a default access level of internal but you can add also public or private type members. Hiding extension APublic.BPublicwhen specifyingelements.havingAccessLevel = public` would potentially result in loss of information as the extension may have added public-type members
elements:
  showNestedTypes: true
  showExtensions: all
  havingAccessLevel:
  - public
  - internal
  - private

Result


elements:
  showNestedTypes: true
  showExtensions: all
  havingAccessLevel:
  - public
  - internal

Result


elements:
  showNestedTypes: true
  showExtensions: all
  havingAccessLevel:
  - public

Result


elements:
  showNestedTypes: true
  showExtensions: merged
  havingAccessLevel:
  - public
  - internal
  - private

Result


elements:
  showNestedTypes: true
  showExtensions: merged
  havingAccessLevel:
  - public
  - internal

Result


elements:
  showNestedTypes: true
  showExtensions: merged
  havingAccessLevel:
  - public

Result


elements:
  showNestedTypes: false
  showExtensions: all
  havingAccessLevel:
  - public
  - internal
  - private

Result