diff --git a/Package.swift b/Package.swift index 64871db..a737c77 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ let package = Package( .watchOS(.v6) ], products: [ - .library(name: "SwiftDocCoverage", targets: ["SwiftDocCoverage"]), + .library(name: "SwiftSource", targets: ["SwiftSource"]), .executable(name: "swift-doc-coverage", targets: ["swift-doc-coverage"]) ], dependencies: [ @@ -22,7 +22,7 @@ let package = Package( ], targets: [ .target( - name: "SwiftDocCoverage", + name: "SwiftSource", dependencies: [ .product(name: "SwiftSyntax", package: "swift-syntax"), .product(name: "SwiftParser", package: "swift-syntax"), @@ -31,7 +31,7 @@ let package = Package( .executableTarget( name: "swift-doc-coverage", dependencies: [ - .target(name: "SwiftDocCoverage"), + .target(name: "SwiftSource"), .product(name: "ArgumentParser", package: "swift-argument-parser") ] ), diff --git a/Sources/SwiftDocCoverage/Coverage.swift b/Sources/SwiftSource/Coverage.swift similarity index 95% rename from Sources/SwiftDocCoverage/Coverage.swift rename to Sources/SwiftSource/Coverage.swift index 8c96e95..fdda0f2 100644 --- a/Sources/SwiftDocCoverage/Coverage.swift +++ b/Sources/SwiftSource/Coverage.swift @@ -30,7 +30,7 @@ extension String : LocalizedError { public struct Coverage { let urls: [URL] - let minAccessLevel: AccessLevel + let minAccessLevel: SwiftAccessLevel let output: Output private static func files(path: String, ext: String, skipsHiddenFiles: Bool, ignoreFilenameRegex: String) throws -> [URL] { @@ -42,7 +42,9 @@ public struct Coverage { if isDirectory.boolValue { var urls = [URL]() - let regex: NSRegularExpression? = ignoreFilenameRegex.isEmpty ? nil : try NSRegularExpression(pattern: ignoreFilenameRegex) + let regex: NSRegularExpression? = ignoreFilenameRegex.isEmpty + ? nil + : try NSRegularExpression(pattern: ignoreFilenameRegex) let url = URL(fileURLWithPath: path) let resourceKeys = Set([.nameKey, .isDirectoryKey]) @@ -86,7 +88,7 @@ public struct Coverage { return formatter }() - public init(paths: [String], skipsHiddenFiles: Bool = true, ignoreFilenameRegex: String = "", minAccessLevel: AccessLevel = .public, output: Output = TerminalOutput()) throws { + public init(paths: [String], skipsHiddenFiles: Bool = true, ignoreFilenameRegex: String = "", minAccessLevel: SwiftAccessLevel = .public, output: Output = TerminalOutput()) throws { self.urls = try paths.flatMap { try Self.files(path: $0, ext: ".swift", skipsHiddenFiles: skipsHiddenFiles, ignoreFilenameRegex: ignoreFilenameRegex) } @@ -126,7 +128,7 @@ public struct Coverage { try urls.forEach { url in let time = Date() - let source = try Source(url: url) + let source = try SwiftSource(url: url) guard source.declarations.count > 0 else { return diff --git a/Sources/SwiftDocCoverage/DeclProtocol.swift b/Sources/SwiftSource/DeclProtocol.swift similarity index 82% rename from Sources/SwiftDocCoverage/DeclProtocol.swift rename to Sources/SwiftSource/DeclProtocol.swift index 930dcfd..5c0316c 100644 --- a/Sources/SwiftDocCoverage/DeclProtocol.swift +++ b/Sources/SwiftSource/DeclProtocol.swift @@ -28,7 +28,7 @@ protocol DeclProtocol: DeclSyntaxProtocol { // var attributes: AttributeListSyntax var modifiers: DeclModifierListSyntax { get } - var keyword: Keyword { get } + var keyword: SwiftKeyword { get } var name: TokenSyntax { get } var genericParameterClause: GenericParameterClauseSyntax? { get } @@ -43,50 +43,50 @@ extension DeclProtocol { var funcSignature: FunctionSignatureSyntax? { nil } var genericWhereClause: GenericWhereClauseSyntax? { nil } - var comments: [Comment] { - leadingTrivia.compactMap { Comment(piece: $0) } + var comments: [SwiftComment] { + leadingTrivia.compactMap { SwiftComment(piece: $0) } } - var accessLevel: AccessLevel { AccessLevel(modifiers: modifiers) } + var accessLevel: SwiftAccessLevel { SwiftAccessLevel(modifiers: modifiers) } } // MARK: - extension TypeAliasDeclSyntax: DeclProtocol { - var keyword: Keyword { .typealias } + var keyword: SwiftKeyword { .typealias } } extension AssociatedTypeDeclSyntax: DeclProtocol { - var keyword: Keyword { .associatedtype } + var keyword: SwiftKeyword { .associatedtype } } extension ClassDeclSyntax: DeclProtocol { - var keyword: Keyword { .class } + var keyword: SwiftKeyword { .class } } extension ActorDeclSyntax: DeclProtocol { - var keyword: Keyword { .actor } + var keyword: SwiftKeyword { .actor } } extension StructDeclSyntax: DeclProtocol { - var keyword: Keyword { .struct } + var keyword: SwiftKeyword { .struct } } extension ProtocolDeclSyntax: DeclProtocol { - var keyword: Keyword { .protocol } + var keyword: SwiftKeyword { .protocol } } extension ExtensionDeclSyntax: DeclProtocol { - var keyword: Keyword { .extension } + var keyword: SwiftKeyword { .extension } var name: TokenSyntax { TokenSyntax(.identifier(extendedType.trimmedDescription), presence: .present)} } extension FunctionDeclSyntax: DeclProtocol { - var keyword: Keyword { .func } + var keyword: SwiftKeyword { .func } var funcSignature: FunctionSignatureSyntax? { signature } } extension InitializerDeclSyntax: DeclProtocol { - var keyword: Keyword { .`init` } + var keyword: SwiftKeyword { .`init` } var name: TokenSyntax { let optionalMark = optionalMark?.trimmedDescription ?? "" @@ -97,7 +97,7 @@ extension InitializerDeclSyntax: DeclProtocol { } extension SubscriptDeclSyntax: DeclProtocol { - var keyword: Keyword { .subscript } + var keyword: SwiftKeyword { .subscript } var name: TokenSyntax { TokenSyntax(.identifier("subscript"), presence: .present) @@ -109,7 +109,7 @@ extension SubscriptDeclSyntax: DeclProtocol { } extension VariableDeclSyntax: DeclProtocol { - var keyword: Keyword { Keyword(token: bindingSpecifier)! } + var keyword: SwiftKeyword { SwiftKeyword(token: bindingSpecifier)! } var name: TokenSyntax { let name = bindings.map { $0.pattern.trimmedDescription }.joined(separator: ",") @@ -118,11 +118,11 @@ extension VariableDeclSyntax: DeclProtocol { } extension EnumDeclSyntax: DeclProtocol { - var keyword: Keyword { .enum } + var keyword: SwiftKeyword { .enum } } extension EnumCaseDeclSyntax: DeclProtocol { - var keyword: Keyword { .case } + var keyword: SwiftKeyword { .case } var name: TokenSyntax { let name = elements.map { @@ -135,10 +135,10 @@ extension EnumCaseDeclSyntax: DeclProtocol { } extension PrecedenceGroupDeclSyntax: DeclProtocol { - var keyword: Keyword { .precedencegroup } + var keyword: SwiftKeyword { .precedencegroup } } extension MacroDeclSyntax: DeclProtocol { - var keyword: Keyword { .macro } + var keyword: SwiftKeyword { .macro } var funcSignature: FunctionSignatureSyntax? { signature } } diff --git a/Sources/SwiftDocCoverage/Output.swift b/Sources/SwiftSource/Output.swift similarity index 100% rename from Sources/SwiftDocCoverage/Output.swift rename to Sources/SwiftSource/Output.swift diff --git a/Sources/SwiftDocCoverage/Report.swift b/Sources/SwiftSource/Report.swift similarity index 100% rename from Sources/SwiftDocCoverage/Report.swift rename to Sources/SwiftSource/Report.swift diff --git a/Sources/SwiftDocCoverage/AccessLevel.swift b/Sources/SwiftSource/SwiftAccessLevel.swift similarity index 93% rename from Sources/SwiftDocCoverage/AccessLevel.swift rename to Sources/SwiftSource/SwiftAccessLevel.swift index 8e15737..8a6a030 100644 --- a/Sources/SwiftDocCoverage/AccessLevel.swift +++ b/Sources/SwiftSource/SwiftAccessLevel.swift @@ -1,4 +1,4 @@ -// AccessLevel.swift +// SwiftAccessLevel.swift // // Created by Iurii Khvorost on 11.02.2022. // Copyright © 2022 Iurii Khvorost. All rights reserved. @@ -24,7 +24,7 @@ import SwiftSyntax -public enum AccessLevel: Int { +public enum SwiftAccessLevel: Int { case `open` case `public` case `internal` @@ -53,7 +53,7 @@ public enum AccessLevel: Int { continue } - if let accessLevel = AccessLevel(token: modifier.name) { + if let accessLevel = SwiftAccessLevel(token: modifier.name) { self = accessLevel return } diff --git a/Sources/SwiftDocCoverage/Comment.swift b/Sources/SwiftSource/SwiftComment.swift similarity index 97% rename from Sources/SwiftDocCoverage/Comment.swift rename to Sources/SwiftSource/SwiftComment.swift index 96fa9dc..2f90d80 100644 --- a/Sources/SwiftDocCoverage/Comment.swift +++ b/Sources/SwiftSource/SwiftComment.swift @@ -1,4 +1,4 @@ -// Comment.swift +// SwiftComment.swift // // Created by Iurii Khvorost on 11.02.2024. // Copyright © 2022 Iurii Khvorost. All rights reserved. @@ -24,7 +24,7 @@ import SwiftSyntax -public struct Comment { +public struct SwiftComment { private let piece: TriviaPiece public var text: String { diff --git a/Sources/SwiftDocCoverage/Declaration.swift b/Sources/SwiftSource/SwiftDeclaration.swift similarity index 93% rename from Sources/SwiftDocCoverage/Declaration.swift rename to Sources/SwiftSource/SwiftDeclaration.swift index 93faea8..6a0ffaa 100644 --- a/Sources/SwiftDocCoverage/Declaration.swift +++ b/Sources/SwiftSource/SwiftDeclaration.swift @@ -1,4 +1,4 @@ -// Declaration.swift +// SwiftDeclaration.swift // // Created by Iurii Khvorost on 09.08.2022. // Copyright © 2022 Iurii Khvorost. All rights reserved. @@ -35,10 +35,10 @@ fileprivate struct StringBuilder { } } -public struct Declaration { - public let comments: [Comment] - public let accessLevel: AccessLevel - public var keyword: Keyword +public struct SwiftDeclaration { + public let comments: [SwiftComment] + public let accessLevel: SwiftAccessLevel + public var keyword: SwiftKeyword public let name: String public let line: Int public let column: Int diff --git a/Sources/SwiftDocCoverage/Keyword.swift b/Sources/SwiftSource/SwiftKeyword.swift similarity index 97% rename from Sources/SwiftDocCoverage/Keyword.swift rename to Sources/SwiftSource/SwiftKeyword.swift index 8c7c15d..149872d 100644 --- a/Sources/SwiftDocCoverage/Keyword.swift +++ b/Sources/SwiftSource/SwiftKeyword.swift @@ -1,4 +1,4 @@ -// Keyword.swift +// SwiftKeyword.swift // // Created by Iurii Khvorost on 11.02.2024. // Copyright © 2022 Iurii Khvorost. All rights reserved. @@ -24,7 +24,7 @@ import SwiftSyntax -public enum Keyword: String { +public enum SwiftKeyword: String { case actor case `associatedtype` case `case` diff --git a/Sources/SwiftDocCoverage/Source.swift b/Sources/SwiftSource/SwiftSource.swift similarity index 94% rename from Sources/SwiftDocCoverage/Source.swift rename to Sources/SwiftSource/SwiftSource.swift index 83004d8..8ac0f00 100644 --- a/Sources/SwiftDocCoverage/Source.swift +++ b/Sources/SwiftSource/SwiftSource.swift @@ -1,4 +1,4 @@ -// Source.swift +// SwiftSource.swift // // Created by Iurii Khvorost on 08.08.2022. // Copyright © 2022 Iurii Khvorost. All rights reserved. @@ -25,9 +25,9 @@ import Foundation import SwiftSyntax -public struct Source { +public struct SwiftSource { public let url: URL? - public let declarations: [Declaration] + public let declarations: [SwiftDeclaration] private init(url: URL?, source: String) { self.url = url diff --git a/Sources/SwiftDocCoverage/Visitor.swift b/Sources/SwiftSource/Visitor.swift similarity index 97% rename from Sources/SwiftDocCoverage/Visitor.swift rename to Sources/SwiftSource/Visitor.swift index 6e51858..388a583 100644 --- a/Sources/SwiftDocCoverage/Visitor.swift +++ b/Sources/SwiftSource/Visitor.swift @@ -29,7 +29,7 @@ class Visitor: SyntaxVisitor { private var context = [DeclProtocol]() private let converter: SourceLocationConverter - private(set) var declarations = [Declaration]() + private(set) var declarations = [SwiftDeclaration]() init(source: String) { let sourceFile = Parser.parse(source: source) @@ -45,7 +45,7 @@ class Visitor: SyntaxVisitor { ? context.map { $0.name.trimmedDescription }.joined(separator: ".") : nil - let declaration = Declaration(decl: decl, path: path, location: startLocation) + let declaration = SwiftDeclaration(decl: decl, path: path, location: startLocation) declarations.append(declaration) } diff --git a/Sources/swift-doc-coverage/main.swift b/Sources/swift-doc-coverage/main.swift index de2dd0d..c93d7c2 100644 --- a/Sources/swift-doc-coverage/main.swift +++ b/Sources/swift-doc-coverage/main.swift @@ -23,13 +23,13 @@ import Foundation import ArgumentParser -import SwiftDocCoverage +import SwiftSource -enum AccessLevelArgument: String, ExpressibleByArgument { +enum AccessLevel: String, ExpressibleByArgument { case open, `public`, `internal`, `fileprivate`, `private` - var accessLevel: AccessLevel { + var accessLevel: SwiftAccessLevel { switch self { case .open: return .open case .public: return .public @@ -62,8 +62,8 @@ struct SwiftDocCoverage: ParsableCommand { @Option(name: .shortAndLong, help: "Skip source code files with file paths that match the given regular expression.") var ignoreFilenameRegex: String = "" - @Option(name: .shortAndLong, help: "The minimum access level of the symbols considered for coverage statistics: \(AccessLevelArgument.open), \(AccessLevelArgument.public), \(AccessLevelArgument.internal), \(AccessLevelArgument.fileprivate), \(AccessLevelArgument.private).") - var minimumAccessLevel: AccessLevelArgument = .public + @Option(name: .shortAndLong, help: "The minimum access level of the symbols considered for coverage statistics: \(AccessLevel.open), \(AccessLevel.public), \(AccessLevel.internal), \(AccessLevel.fileprivate), \(AccessLevel.private).") + var minimumAccessLevel: AccessLevel = .public @Option(name: .shortAndLong, help: "Report modes: \(ReportArgument.statistics.rawValue), \(ReportArgument.warnings.rawValue), \(ReportArgument.json.rawValue).") var report: ReportArgument = .statistics diff --git a/Tests/SwiftDocCoverageTests/SwiftDocCoverageTests.swift b/Tests/SwiftDocCoverageTests/SwiftDocCoverageTests.swift index 1bef623..77bfd77 100644 --- a/Tests/SwiftDocCoverageTests/SwiftDocCoverageTests.swift +++ b/Tests/SwiftDocCoverageTests/SwiftDocCoverageTests.swift @@ -1,5 +1,5 @@ import XCTest -/*@testable */import SwiftDocCoverage +/*@testable */import SwiftSource func tempDirectory() -> URL { let url = URL(fileURLWithPath: NSTemporaryDirectory()) @@ -18,7 +18,7 @@ final class DeclarationTests: XCTestCase { typealias AudioSample = UInt16 } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 3) XCTAssert(source.declarations[0].name == "typealias SSN") XCTAssert(source.declarations[1].name == "class Audio") @@ -34,7 +34,7 @@ final class DeclarationTests: XCTestCase { associatedtype Suffix: SuffixableContainer where Suffix.Item == Item } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 4) XCTAssert(source.declarations[0].name == "protocol Container") XCTAssert(source.declarations[1].name == "associatedtype Container.Item") @@ -59,7 +59,7 @@ final class DeclarationTests: XCTestCase { class E {} #endif """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 5) XCTAssert(source.declarations[0].name == "class A") XCTAssert(source.declarations[1].name == "class B") @@ -77,7 +77,7 @@ final class DeclarationTests: XCTestCase { class Stack: Base {} actor UserStorage {} """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 5) XCTAssert(source.declarations[0].name == "class Vehicle") XCTAssert(source.declarations[1].name == "class Bicycle: Vehicle") @@ -93,7 +93,7 @@ final class DeclarationTests: XCTestCase { struct Person: FullyNamed {} struct Stack {} """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 3) XCTAssert(source.declarations[0].name == "struct Book") XCTAssert(source.declarations[1].name == "struct Person: FullyNamed") @@ -108,7 +108,7 @@ final class DeclarationTests: XCTestCase { protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {} @objc protocol CounterDataSource {} """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 4) XCTAssert(source.declarations[0].name == "protocol Container") XCTAssert(source.declarations[1].name == "protocol InheritingProtocol: SomeProtocol, AnotherProtocol") @@ -123,7 +123,7 @@ final class DeclarationTests: XCTestCase { extension SomeType: SomeProtocol, AnotherProtocol {} extension Array: TextRepresentable where Element: TextRepresentable {} """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 3) XCTAssert(source.declarations[0].name == "extension Container") XCTAssert(source.declarations[1].name == "extension SomeType: SomeProtocol, AnotherProtocol") @@ -142,7 +142,7 @@ final class DeclarationTests: XCTestCase { static func + (left: Vector2D, right: Vector2D) -> Vector2D {} } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 7) XCTAssert(source.declarations[0].name == "func greet(person: String) -> String") XCTAssert(source.declarations[1].name == "func someFunction(argumentLabel parameterName: Int)") @@ -166,7 +166,7 @@ final class DeclarationTests: XCTestCase { init(item: Item) where Element: TextRepresentable {} } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 8) XCTAssert(source.declarations[0].name == "struct Color") XCTAssert(source.declarations[1].name == "Color.init()") @@ -188,7 +188,7 @@ final class DeclarationTests: XCTestCase { subscript(n: Int) -> Item {} } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 5) XCTAssert(source.declarations[0].name == "struct TimesTable") XCTAssert(source.declarations[1].name == "TimesTable.subscript(index: Int) -> Int") @@ -216,7 +216,7 @@ final class DeclarationTests: XCTestCase { } } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 9) XCTAssert(source.declarations[0].name == "let name") XCTAssert(source.declarations[1].name == "let id") @@ -240,7 +240,7 @@ final class DeclarationTests: XCTestCase { } enum Planet {} """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 6) XCTAssert(source.declarations[0].name == "enum CompassPoint") XCTAssert(source.declarations[1].name == "case CompassPoint.north,south") @@ -258,7 +258,7 @@ final class DeclarationTests: XCTestCase { } infix operator => : ForwardPipe """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 1) XCTAssert(source.declarations[0].name == "precedencegroup ForwardPipe") //XCTAssert(source.declarations[1].name == "operator =>") @@ -305,7 +305,7 @@ final class DeclarationTests: XCTestCase { } } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 11) XCTAssert(source.declarations[0].name == "struct BlackjackCard") XCTAssert(source.declarations[1].name == "enum BlackjackCard.Suit: Character") @@ -338,7 +338,7 @@ final class DeclarationTests: XCTestCase { static let shared = 10 } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 12) XCTAssert(source.declarations[0].accessLevel == .open) XCTAssert(source.declarations[1].accessLevel == .public) @@ -363,7 +363,7 @@ final class DocumentationTests: XCTestCase { """ public func eat(_ food: Food, quantity: Int) throws -> Int { return 0 } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 1) XCTAssert(source.declarations[0].comments.count == 0) } @@ -377,7 +377,7 @@ final class DocumentationTests: XCTestCase { /** A documentation block comment */ mutating public func eat(_ food: Food, quantity: Int) throws -> Int { return 0 } """ - let source = Source(source: code) + let source = SwiftSource(source: code) XCTAssert(source.declarations.count == 1) XCTAssert(source.declarations[0].comments.count == 4) XCTAssert(source.declarations[0].comments[0].text == "// A developer line comment") @@ -395,7 +395,7 @@ final class FileTests: XCTestCase { static let emptyDirURL = directoryURL.appendingPathComponent("Empty") func test_file() throws { - let source = try Source(url: Self.fileURL) + let source = try SwiftSource(url: Self.fileURL) XCTAssert(source.declarations.count == 4) }