diff --git a/Configuration/Examples/Rich/.swiftplantuml.yml b/Configuration/Examples/Rich/.swiftplantuml.yml
index e6bf00d..490946a 100644
--- a/Configuration/Examples/Rich/.swiftplantuml.yml
+++ b/Configuration/Examples/Rich/.swiftplantuml.yml
@@ -8,6 +8,7 @@ elements:
- public
showMembersWithAccessLevel:
- public
+ - package
- internal
- private
showGenerics: true
@@ -74,4 +75,4 @@ texts:
on several lines and using html
legend: Some boxed text
caption: Second to last
- footer: The end
\ No newline at end of file
+ footer: The end
diff --git a/Configuration/Schema/json-schema-swiftplantuml.json b/Configuration/Schema/json-schema-swiftplantuml.json
index 12c1f86..34cde90 100644
--- a/Configuration/Schema/json-schema-swiftplantuml.json
+++ b/Configuration/Schema/json-schema-swiftplantuml.json
@@ -18,12 +18,14 @@
"havingAccessLevel": [
"open",
"public",
+ "package",
"internal",
"private"
],
"showMembersWithAccessLevel": [
"open",
"public",
+ "package",
"internal",
"private"
],
diff --git a/Sources/SwiftPlantUMLFramework/Configuration/Configuration.swift b/Sources/SwiftPlantUMLFramework/Configuration/Configuration.swift
index 168abf3..3075a45 100644
--- a/Sources/SwiftPlantUMLFramework/Configuration/Configuration.swift
+++ b/Sources/SwiftPlantUMLFramework/Configuration/Configuration.swift
@@ -6,6 +6,8 @@ public enum AccessLevel: String, Codable {
case open
/// `public`
case `public`
+ /// `package`
+ case `package`
/// `internal`
case `internal`
/// `private`
diff --git a/Sources/SwiftPlantUMLFramework/Configuration/ElementOptions.swift b/Sources/SwiftPlantUMLFramework/Configuration/ElementOptions.swift
index 90f0db6..67651d7 100644
--- a/Sources/SwiftPlantUMLFramework/Configuration/ElementOptions.swift
+++ b/Sources/SwiftPlantUMLFramework/Configuration/ElementOptions.swift
@@ -3,9 +3,9 @@ import Foundation
/// Options which and how elements shall be considered for class diagram generation
public struct ElementOptions: Codable {
/// only elements (classes, structs, ...) with the specified access level will be processed and rendered in the class diagram
- public private(set) var havingAccessLevel: [AccessLevel] = [.open, .public, .internal, .private]
+ public private(set) var havingAccessLevel: [AccessLevel] = [.open, .public, .package, .internal, .private]
/// only members (properties and functions) with the specified access level will be processed and renderd in the class diagram
- public private(set) var showMembersWithAccessLevel: [AccessLevel] = [.open, .public, .internal, .private]
+ public private(set) var showMembersWithAccessLevel: [AccessLevel] = [.open, .public, .package, .internal, .private]
/// show nested types
public private(set) var showNestedTypes: Bool = true
@@ -57,8 +57,8 @@ public struct ElementOptions: Codable {
/// memberwise initializer
public init(
- havingAccessLevel: [AccessLevel] = [.open, .public, .internal, .private],
- showMembersWithAccessLevel: [AccessLevel] = [.open, .public, .internal, .private],
+ havingAccessLevel: [AccessLevel] = [.open, .public, .package, .internal, .private],
+ showMembersWithAccessLevel: [AccessLevel] = [.open, .public, .package, .internal, .private],
showNestedTypes: Bool = true,
showGenerics: Bool = true,
showExtensions: ExtensionVisualization? = nil,
diff --git a/Sources/SwiftPlantUMLFramework/Internal/ElementAccessibility+Extensions.swift b/Sources/SwiftPlantUMLFramework/Internal/ElementAccessibility+Extensions.swift
index 9da9983..b8e03b3 100644
--- a/Sources/SwiftPlantUMLFramework/Internal/ElementAccessibility+Extensions.swift
+++ b/Sources/SwiftPlantUMLFramework/Internal/ElementAccessibility+Extensions.swift
@@ -5,7 +5,7 @@ extension ElementAccessibility {
switch self {
case .public, .open:
return "+"
- case .internal:
+ case .internal, .package:
return "~"
case .private, .fileprivate:
return "-"
diff --git a/Sources/SwiftPlantUMLFramework/Internal/SyntaxStructure.swift b/Sources/SwiftPlantUMLFramework/Internal/SyntaxStructure.swift
index 146f625..643d0a0 100644
--- a/Sources/SwiftPlantUMLFramework/Internal/SyntaxStructure.swift
+++ b/Sources/SwiftPlantUMLFramework/Internal/SyntaxStructure.swift
@@ -87,6 +87,8 @@ internal enum ElementAccessibility: String, RawRepresentable, Comparable {
case open = "source.lang.swift.accessibility.open"
/// `public`
case `public` = "source.lang.swift.accessibility.public"
+ /// `package`
+ case package = "source.lang.swift.accessibility.package"
/// `internal`
case `internal` = "source.lang.swift.accessibility.internal"
/// `private`
@@ -99,8 +101,10 @@ internal enum ElementAccessibility: String, RawRepresentable, Comparable {
private var value: Int {
switch self {
case .open:
- return 6
+ return 7
case .public:
+ return 6
+ case .package:
return 5
case .internal:
return 4
@@ -119,6 +123,8 @@ internal enum ElementAccessibility: String, RawRepresentable, Comparable {
self.init(rawValue: "source.lang.swift.accessibility.open")
case .public:
self.init(rawValue: "source.lang.swift.accessibility.public")
+ case .package:
+ self.init(rawValue: "source.lang.swift.accessibility.package")
case .internal:
self.init(rawValue: "source.lang.swift.accessibility.internal")
case .private:
diff --git a/Tests/SwiftPlantUMLFrameworkTests/ConfigurationTests.swift b/Tests/SwiftPlantUMLFrameworkTests/ConfigurationTests.swift
index 95b6fd0..800437a 100644
--- a/Tests/SwiftPlantUMLFrameworkTests/ConfigurationTests.swift
+++ b/Tests/SwiftPlantUMLFrameworkTests/ConfigurationTests.swift
@@ -4,8 +4,8 @@ import XCTest
final class PlantUMLConfigurationTests: XCTestCase {
func testDefault() {
let config = Configuration()
- XCTAssertEqual(config.elements.havingAccessLevel.count, 4)
- XCTAssertEqual(config.elements.showMembersWithAccessLevel.count, 4)
+ XCTAssertEqual(config.elements.havingAccessLevel.count, 5)
+ XCTAssertEqual(config.elements.showMembersWithAccessLevel.count, 5)
}
func testDecodingObsoleteShowExtensionsBooleanProperty() {
diff --git a/Tests/SwiftPlantUMLFrameworkTests/ElementAccessibilityTests.swift b/Tests/SwiftPlantUMLFrameworkTests/ElementAccessibilityTests.swift
index 23b7289..369db12 100644
--- a/Tests/SwiftPlantUMLFrameworkTests/ElementAccessibilityTests.swift
+++ b/Tests/SwiftPlantUMLFrameworkTests/ElementAccessibilityTests.swift
@@ -4,8 +4,10 @@ import XCTest
final class ElementAccessibilityTests: XCTestCase {
func testComparison() {
XCTAssertTrue(ElementAccessibility.open > ElementAccessibility.public)
+ XCTAssertTrue(ElementAccessibility.public > ElementAccessibility.package)
XCTAssertTrue(ElementAccessibility.public > ElementAccessibility.internal)
XCTAssertTrue(ElementAccessibility.public > ElementAccessibility.private)
+ XCTAssertTrue(ElementAccessibility.package > ElementAccessibility.internal)
XCTAssertTrue(ElementAccessibility.internal > ElementAccessibility.private)
XCTAssertTrue(ElementAccessibility.private > ElementAccessibility.fileprivate)
XCTAssertTrue(ElementAccessibility.private > ElementAccessibility.other)
@@ -15,6 +17,7 @@ final class ElementAccessibilityTests: XCTestCase {
func testIndicator() {
XCTAssertEqual(ElementAccessibility.open.indicator, "+")
XCTAssertEqual(ElementAccessibility.public.indicator, "+")
+ XCTAssertEqual(ElementAccessibility.package.indicator, "~")
XCTAssertEqual(ElementAccessibility.internal.indicator, "~")
XCTAssertEqual(ElementAccessibility(orig: .internal)?.indicator, "~")
XCTAssertEqual(ElementAccessibility.private.indicator, "-")
diff --git a/Tests/SwiftPlantUMLFrameworkTests/PlantUMLScriptTests.swift b/Tests/SwiftPlantUMLFrameworkTests/PlantUMLScriptTests.swift
index 27f721c..c4590fc 100644
--- a/Tests/SwiftPlantUMLFrameworkTests/PlantUMLScriptTests.swift
+++ b/Tests/SwiftPlantUMLFrameworkTests/PlantUMLScriptTests.swift
@@ -107,6 +107,17 @@ final class PlantUMLScriptTests: XCTestCase {
XCTAssertTrue(script.text.contains(headerText))
}
+ func testPackageAccessModifierE2E() {
+ guard let items = try! SyntaxStructure.create(from: getTestFile(named: "packageAccessModifier"))?.substructure else { return XCTFail("cannot read test data") }
+ let script = PlantUMLScript(items: items)
+ let expected = try! getTestFileContent(named: "packageAccessModifierAsPlantUML")
+ #if swift(>=5.9)
+ XCTAssertEqual(script.text.noSpacesAndNoLineBreaks, expected.noSpacesAndNoLineBreaks)
+ #else
+ XCTAssertNotNil("Compiling SwiftPlantUML with a lower Swift version will have incorrect result, i.e. ~{static}package()~aStaticPackageInstanceMethod()")
+ #endif
+ }
+
func getTestFile(named: String = "basics") throws -> URL {
// https://stackoverflow.com/questions/47177036/use-resources-in-unit-tests-with-swift-package-manager
let path = Bundle.module.path(forResource: named, ofType: "txt", inDirectory: "TestData") ?? "nonesense"
diff --git a/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifier.txt b/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifier.txt
new file mode 100644
index 0000000..31eb1ad
--- /dev/null
+++ b/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifier.txt
@@ -0,0 +1,5 @@
+import Foundation
+
+package struct anPackageInternalStruct {
+ static package func aStaticPackageInstanceMethod()
+}
\ No newline at end of file
diff --git a/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifierAsPlantUML.txt b/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifierAsPlantUML.txt
new file mode 100644
index 0000000..b7e41b3
--- /dev/null
+++ b/Tests/SwiftPlantUMLFrameworkTests/TestData/packageAccessModifierAsPlantUML.txt
@@ -0,0 +1,11 @@
+@startuml
+' STYLE START
+hide empty members
+skinparam shadowing false
+' STYLE END
+set namespaceSeparator none
+
+
+class "anPackageInternalStruct" as anPackageInternalStruct << (S, SkyBlue) struct >> { ~{static} aStaticPackageInstanceMethod()
+}
+@enduml