Skip to content

Commit 8f8896f

Browse files
committed
Added AccessLevel, DeclKeyword
1 parent 24f2d4f commit 8f8896f

File tree

5 files changed

+203
-94
lines changed

5 files changed

+203
-94
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// AccessLevel.swift
2+
//
3+
// Created by Iurii Khvorost <iurii.khvorost@gmail.com> on 11.02.2022.
4+
// Copyright © 2022 Iurii Khvorost. All rights reserved.
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
24+
import SwiftSyntax
25+
26+
27+
public enum AccessLevel: Int {
28+
case `open`
29+
case `public`
30+
case `internal`
31+
case `fileprivate`
32+
case `private`
33+
34+
init?(token: TokenSyntax) {
35+
guard case .keyword(let keyword) = token.tokenKind else {
36+
return nil
37+
}
38+
39+
switch keyword {
40+
case .open: self = .open
41+
case .public: self = .public
42+
case .internal: self = .internal
43+
case .fileprivate: self = .fileprivate
44+
case .private: self = .private
45+
default: return nil
46+
}
47+
}
48+
49+
init(modifiers: DeclModifierListSyntax) {
50+
for modifier in modifiers {
51+
if let accessLevel = AccessLevel(token: modifier.name) {
52+
self = accessLevel
53+
return
54+
}
55+
}
56+
self = .internal
57+
}
58+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// DeclKeyword.swift
2+
//
3+
// Created by Iurii Khvorost <iurii.khvorost@gmail.com> on 11.02.2024.
4+
// Copyright © 2022 Iurii Khvorost. All rights reserved.
5+
//
6+
// Permission is hereby granted, free of charge, to any person obtaining a copy
7+
// of this software and associated documentation files (the "Software"), to deal
8+
// in the Software without restriction, including without limitation the rights
9+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
// copies of the Software, and to permit persons to whom the Software is
11+
// furnished to do so, subject to the following conditions:
12+
//
13+
// The above copyright notice and this permission notice shall be included in
14+
// all copies or substantial portions of the Software.
15+
//
16+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
19+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
// THE SOFTWARE.
23+
24+
import SwiftSyntax
25+
26+
27+
enum DeclKeyword: String {
28+
case actor
29+
case `associatedtype`
30+
case `case`
31+
case `class`
32+
//case `deinit`
33+
case `enum`
34+
case `extension`
35+
case `func`
36+
//case `import`
37+
case `init`
38+
case `let`
39+
case macro
40+
case `operator`
41+
case `precedencegroup`
42+
case `protocol`
43+
case `struct`
44+
case `subscript`
45+
case `typealias`
46+
case `var`
47+
//case `inout`
48+
//case pound
49+
50+
init?(token: TokenSyntax) {
51+
guard case .keyword(let keyword) = token.tokenKind else {
52+
return nil
53+
}
54+
55+
switch keyword {
56+
case .actor: self = .actor
57+
case .associatedtype: self = .associatedtype
58+
case .case: self = .case
59+
case .class: self = .class
60+
//case .deinit:
61+
case .enum: self = .enum
62+
case .extension: self = .extension
63+
case .func: self = .func
64+
//case .import:
65+
case .`init`: self = .`init`
66+
case .let: self = .let
67+
case .macro: self = .macro
68+
case .operator: self = .operator
69+
case .precedencegroup: self = .precedencegroup
70+
case .protocol: self = .protocol
71+
case .struct: self = .struct
72+
case .subscript: self = .subscript
73+
case .typealias: self = .typealias
74+
case .var: self = .var
75+
//case .inout
76+
//case .pound
77+
default: return nil
78+
}
79+
}
80+
}

Sources/SwiftDocCoverage/DeclProtocol.swift

Lines changed: 61 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2222
// THE SOFTWARE.
2323

24-
import Foundation
2524
import SwiftSyntax
2625

2726

@@ -39,29 +38,39 @@ struct Comment {
3938
var isDoc: Bool { kind == .docLine || kind == .docBlock }
4039
}
4140

42-
public enum AccessLevel: Int {
43-
case `open`
44-
case `public`
45-
case `internal`
46-
case `fileprivate`
47-
case `private`
48-
}
49-
5041
protocol DeclProtocol: SyntaxProtocol {
5142

52-
// `attributes`: ``AttributeListSyntax``
43+
// var attributes: AttributeListSyntax
5344
var modifiers: DeclModifierListSyntax { get }
54-
// `classKeyword`: `'class'`
55-
//var name: TokenSyntax { get }
56-
// `genericParameterClause`: ``GenericParameterClauseSyntax``?
57-
// `inheritanceClause`: ``InheritanceClauseSyntax``?
58-
// `genericWhereClause`: ``GenericWhereClauseSyntax``?
59-
// `memberBlock`: ``MemberBlockSyntax``
45+
var keyword: DeclKeyword { get }
46+
var name: TokenSyntax { get }
47+
var genericParameterClause: GenericParameterClauseSyntax? { get }
48+
var inheritanceClause: InheritanceClauseSyntax? { get }
49+
var funcSignature: FunctionSignatureSyntax? { get }
50+
//var genericWhereClause: GenericWhereClauseSyntax? { get }
6051

6152
var id: String { get }
6253
}
6354

6455
extension DeclProtocol {
56+
57+
var genericParameterClause: GenericParameterClauseSyntax? { nil }
58+
var inheritanceClause: InheritanceClauseSyntax? { nil }
59+
var funcSignature: FunctionSignatureSyntax? { nil }
60+
61+
var id: String {
62+
63+
let generic = genericParameterClause?.trimmedDescription ?? ""
64+
let base = "\(keyword.rawValue) \(name.trimmedDescription)\(generic)"
65+
66+
if let inheritance = inheritanceClause?.trimmedDescription {
67+
return "\(base): \(inheritance)"
68+
}
69+
else if let funcSignature = funcSignature?.trimmedDescription {
70+
return "\(base)\(funcSignature)"
71+
}
72+
return base
73+
}
6574

6675
var comments: [Comment] {
6776
return leadingTrivia.compactMap {
@@ -80,131 +89,93 @@ extension DeclProtocol {
8089
}
8190
}
8291

83-
var accessLevel: AccessLevel {
84-
for modifier in modifiers {
85-
let name = modifier.trimmed.description
86-
switch name {
87-
case "open":
88-
return .open
89-
case "public":
90-
return .public
91-
case "fileprivate":
92-
return .fileprivate
93-
case "private":
94-
return .private
95-
default:
96-
return .internal
97-
}
98-
}
99-
return .internal
100-
}
92+
var accessLevel: AccessLevel { AccessLevel(modifiers: modifiers) }
10193
}
10294

10395
// MARK: -
10496

10597
extension TypeAliasDeclSyntax: DeclProtocol {
106-
var id: String {
107-
name.trimmed.description
108-
}
98+
var keyword: DeclKeyword { .typealias }
10999
}
110100

111101
extension AssociatedTypeDeclSyntax: DeclProtocol {
112-
var id: String {
113-
name.trimmed.description
114-
}
102+
var keyword: DeclKeyword { .associatedtype }
115103
}
116104

117105
extension ClassDeclSyntax: DeclProtocol {
118-
var id: String {
119-
let genericParameter = genericParameterClause?.trimmed.description ?? ""
120-
return "\(name.trimmed)\(genericParameter)"
121-
}
106+
var keyword: DeclKeyword { .class }
122107
}
123108

124109
extension ActorDeclSyntax: DeclProtocol {
125-
var id: String {
126-
let genericParameter = genericParameterClause?.trimmed.description ?? ""
127-
return "\(name.trimmed)\(genericParameter)"
128-
}
110+
var keyword: DeclKeyword { .actor }
129111
}
130112

131113
extension StructDeclSyntax: DeclProtocol {
132-
var id: String {
133-
let genericParameter = genericParameterClause?.trimmed.description ?? ""
134-
return "\(name.trimmed)\(genericParameter)"
135-
}
114+
var keyword: DeclKeyword { .struct }
136115
}
137116

138117
extension ProtocolDeclSyntax: DeclProtocol {
139-
var id: String {
140-
name.trimmed.description
141-
}
118+
var keyword: DeclKeyword { .protocol }
142119
}
143120

144121
extension ExtensionDeclSyntax: DeclProtocol {
145-
var id: String {
146-
extendedType.trimmed.description
147-
}
148-
149-
var name: TokenSyntax {
150-
TokenSyntax(.identifier(extendedType.trimmedDescription), presence: .present)
151-
}
122+
var keyword: DeclKeyword { .extension }
123+
var name: TokenSyntax { TokenSyntax(.identifier(extendedType.trimmedDescription), presence: .present)}
152124
}
153125

154126
extension FunctionDeclSyntax: DeclProtocol {
155-
var id: String {
156-
let generic = genericParameterClause?.trimmed.description ?? ""
157-
return "\(name.trimmed)\(generic)\(signature.trimmed)"
158-
}
127+
var keyword: DeclKeyword { .func }
128+
var funcSignature: FunctionSignatureSyntax? { signature }
159129
}
160130

161131
extension InitializerDeclSyntax: DeclProtocol {
162-
var id: String {
163-
let optionalMark = optionalMark?.trimmed.description ?? ""
164-
let generic = genericParameterClause?.trimmed.description ?? ""
165-
return "\(initKeyword.trimmed)\(optionalMark)\(generic)\(signature.trimmed)"
132+
var keyword: DeclKeyword { .`init` }
133+
134+
var name: TokenSyntax {
135+
let optionalMark = optionalMark?.trimmedDescription ?? ""
136+
return TokenSyntax(.identifier(optionalMark), presence: .present)
166137
}
167138
}
168139

169140
extension SubscriptDeclSyntax: DeclProtocol {
170-
var id: String {
171-
let generic = genericParameterClause?.trimmed.description ?? ""
172-
return "\(subscriptKeyword.trimmed)\(generic)\(parameterClause.trimmed) \(returnClause.trimmed)"
141+
var keyword: DeclKeyword { .subscript }
142+
143+
var name: TokenSyntax {
144+
TokenSyntax(.identifier("\(parameterClause.trimmedDescription) \(returnClause.trimmedDescription)"), presence: .present)
173145
}
174146
}
175147

176148
extension VariableDeclSyntax: DeclProtocol {
177-
var id: String {
178-
bindings.map { $0.pattern.trimmed.description }.joined(separator: ",")
149+
var keyword: DeclKeyword { DeclKeyword(token: bindingSpecifier)! }
150+
151+
var name: TokenSyntax {
152+
let name = bindings.map { $0.pattern.trimmedDescription }.joined(separator: ",")
153+
return TokenSyntax(.identifier(name), presence: .present)
179154
}
180155
}
181156

182157
extension EnumDeclSyntax: DeclProtocol {
183-
var id: String {
184-
let generic = genericParameterClause?.trimmed.description ?? ""
185-
return "\(name.trimmed.description)\(generic)"
186-
}
158+
var keyword: DeclKeyword { .enum }
187159
}
188160

189161
extension EnumCaseDeclSyntax: DeclProtocol {
190-
var id: String {
191-
elements.map {
192-
let name = $0.name.trimmed.description
193-
let associatedValue = $0.parameterClause?.trimmed.description ?? ""
162+
var keyword: DeclKeyword { .case }
163+
164+
var name: TokenSyntax {
165+
let name = elements.map {
166+
let name = $0.name.trimmedDescription
167+
let associatedValue = $0.parameterClause?.trimmedDescription ?? ""
194168
return "\(name)\(associatedValue)"
195169
}.joined(separator: ",")
170+
return TokenSyntax(.identifier(name), presence: .present)
196171
}
197172
}
198173

199174
extension PrecedenceGroupDeclSyntax: DeclProtocol {
200-
var id: String {
201-
"\(precedencegroupKeyword.trimmed) \(name.trimmed)"
202-
}
175+
var keyword: DeclKeyword { .precedencegroup }
203176
}
204177

205178
extension MacroDeclSyntax: DeclProtocol {
206-
var id: String {
207-
let generic = genericParameterClause?.trimmed.description ?? ""
208-
return "\(name.trimmed)\(generic)\(signature.trimmed)"
209-
}
179+
var keyword: DeclKeyword { .macro }
180+
var funcSignature: FunctionSignatureSyntax? { signature }
210181
}

Sources/SwiftDocCoverage/Declaration.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ class Declaration {
5252
return parent.isEmpty ? name : "\(parent).\(name)"
5353
}()
5454

55-
init(decl: DeclProtocol, context: [DeclProtocol], line: Int, column: Int) {
55+
init(decl: DeclProtocol, context: [DeclProtocol], location: SourceLocation) {
5656
self.decl = decl
5757
self.context = context
58-
self.line = line
59-
self.column = column
58+
self.line = location.line
59+
self.column = location.column
6060
}
6161
}

Sources/SwiftDocCoverage/Source.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fileprivate class Visitor: SyntaxVisitor {
4545
}
4646

4747
let startLocation = decl.startLocation(converter: converter, afterLeadingTrivia: true)
48-
let declaration = Declaration(decl: decl, context: context, line: startLocation.line, column: startLocation.column)
48+
let declaration = Declaration(decl: decl, context: context, location: startLocation)
4949
declarations.append(declaration)
5050
}
5151

0 commit comments

Comments
 (0)