@@ -71,11 +71,11 @@ public class ObjectiveCFocusedCodeFinder: KnownLanguageFocusedCodeFinder<
7171 ) -> NodeInfo ? {
7272 switch ObjectiveCNodeType ( rawValue: node. nodeType ?? " " ) {
7373 case . classInterface, . categoryInterface:
74- return parseClassInterfaceNode ( node, textProvider: textProvider)
74+ return parseDeclarationInterfaceNode ( node, textProvider: textProvider)
7575 case . classImplementation, . categoryImplementation:
76- return parseClassImplementationNode ( node, textProvider: textProvider)
76+ return parseDeclarationInterfaceNode ( node, textProvider: textProvider)
7777 case . protocolDeclaration:
78- return parseProtocolNode ( node, textProvider: textProvider)
78+ return parseDeclarationInterfaceNode ( node, textProvider: textProvider)
7979 case . methodDefinition:
8080 return parseMethodDefinitionNode ( node, textProvider: textProvider)
8181 case . functionDefinition:
@@ -89,16 +89,23 @@ public class ObjectiveCFocusedCodeFinder: KnownLanguageFocusedCodeFinder<
8989 }
9090 }
9191
92- func parseClassInterfaceNode (
92+ func parseDeclarationInterfaceNode (
9393 _ node: ASTNode ,
9494 textProvider: @escaping TextProvider
9595 ) -> NodeInfo ? {
9696 var name = " "
97- var superClass = " "
9897 var category = " "
99- var protocols = [ String] ( )
98+ /// Attributes, declaration kind, and name.
99+ var prefix = " "
100+ /// Generics, super class, etc.
101+ var extra = " "
102+
100103 if let nameNode = node. child ( byFieldName: " name " ) {
101104 name = textProvider ( . node( nameNode) )
105+ prefix = textProvider ( . range(
106+ range: node. range. notSurpassing ( nameNode. range) ,
107+ pointRange: node. pointRange. notSurpassing ( nameNode. pointRange)
108+ ) )
102109 }
103110 if let categoryNode = node. child ( byFieldName: " category " ) {
104111 category = textProvider ( . node( categoryNode) )
@@ -107,135 +114,45 @@ public class ObjectiveCFocusedCodeFinder: KnownLanguageFocusedCodeFinder<
107114 for i in 0 ..< node. childCount {
108115 guard let childNode = node. child ( at: i) else { continue }
109116 switch ObjectiveCNodeType ( rawValue: childNode. nodeType) {
110- case . protocolQualifiers:
111- var protocolNames = [ String] ( )
112- for j in 0 ..< childNode. childCount {
113- guard let protocolNode = childNode. child ( at: j) else { continue }
114- guard ObjectiveCNodeType ( rawValue: protocolNode. nodeType) == . identifier
115- else { continue }
116- protocolNames. append (
117- textProvider ( . node( protocolNode) )
118- . trimmingCharacters ( in: . whitespacesAndNewlines)
119- )
117+ case . superclassReference,
118+ . protocolQualifiers,
119+ . parameterizedClassTypeArguments:
120+ extra. append ( textProvider ( . node( childNode) ) )
121+ case . genericsTypeReference:
122+ // When it's a category of a generic type, e.g.
123+ // @interface __GENERICS(NSArray, ObjectType) (BlocksKit)
124+ if let nameNode = childNode. child ( byFieldName: " name " ) {
125+ name = textProvider ( . node( nameNode) )
120126 }
121- protocols = protocolNames. filter { $0 != " , " && !$0. isEmpty }
122- case . superclassReference:
123- if let superClassNode = childNode. child ( byFieldName: " name " ) {
124- superClass = textProvider ( . node( superClassNode) )
125- . trimmingCharacters ( in: . whitespacesAndNewlines)
126- }
127- default :
128- continue
127+ prefix = textProvider( . range(
128+ range: node. range. notSurpassing ( childNode. range) ,
129+ pointRange: node. pointRange. notSurpassing ( childNode. pointRange)
130+ ) )
131+ default: continue
129132 }
130133 }
131134
132- var signature = " @interface \( name) "
133- if !category. isEmpty {
134- signature += " ( \( category) ) "
135- }
136- if !protocols. isEmpty {
137- signature += " < \( protocols. joined ( separator: " , " ) ) > "
138- }
139- if !superClass. isEmpty {
140- signature += " : \( superClass) "
141- }
142-
143- return . init(
144- node: node,
145- signature: signature,
146- name: name,
147- canBeUsedAsCodeRange: true
148- )
149- }
150-
151- func parseClassImplementationNode(
152- _ node: ASTNode ,
153- textProvider: @escaping TextProvider
154- ) -> NodeInfo ? {
155- var name = " "
156- var superClass = " "
157- var category = " "
158- var protocols = [ String] ( )
159- if let nameNode = node. child ( byFieldName: " name " ) {
160- name = textProvider ( . node( nameNode) )
161- }
162- if let categoryNode = node. child ( byFieldName: " category " ) {
163- category = textProvider ( . node( categoryNode) )
164- }
165-
166- for i in 0 ..< node. childCount {
167- guard let childNode = node. child ( at: i) else { continue }
168- switch ObjectiveCNodeType ( rawValue: childNode. nodeType) {
169- case . protocolQualifiers:
170- var protocolNames = [ String] ( )
171- for j in 0 ..< childNode. childCount {
172- guard let protocolNode = childNode. child ( at: j) else { continue }
173- guard ObjectiveCNodeType ( rawValue: protocolNode. nodeType) == . identifier
174- else { continue }
175- protocolNames. append (
176- textProvider ( . node( protocolNode) )
177- . trimmingCharacters ( in: . whitespacesAndNewlines)
178- )
179- }
180- protocols = protocolNames. filter { $0 != " , " && !$0. isEmpty }
181- case . superclassReference:
182- if let superClassNode = childNode. child ( byFieldName: " name " ) {
183- superClass = textProvider ( . node( superClassNode) )
184- . trimmingCharacters ( in: . whitespacesAndNewlines)
185- }
186- default :
187- continue
188- }
189- }
135+ prefix = prefix. split ( separator: " \n " )
136+ . joined ( separator: " " )
137+ . trimmingCharacters ( in: . whitespacesAndNewlines)
138+
139+ extra = extra. split ( separator: " \n " )
140+ . joined ( separator: " " )
141+ . trimmingCharacters ( in: . whitespacesAndNewlines)
190142
191- var signature = " @implementation \( name ) "
143+ var signature = " \( prefix ) \( extra ) "
192144 if !category . isEmpty {
193145 signature += " ( \( category) ) "
194146 }
195- if !protocols. isEmpty {
196- signature += " < \( protocols. joined ( separator: " , " ) ) > "
197- }
198- if !superClass. isEmpty {
199- signature += " : \( superClass) "
200- }
201- return . init(
202- node: node,
203- signature: signature,
204- name: name,
205- canBeUsedAsCodeRange: true
206- )
207- }
208147
209- func parseProtocolNode(
210- _ node: ASTNode ,
211- textProvider: @escaping TextProvider
212- ) -> NodeInfo ? {
213- var name = " "
214- var protocols = [ String] ( )
215- if let nameNode = node. child ( byFieldName: " name " ) {
216- name = textProvider ( . node( nameNode) )
217- }
218- if let protocolsNode = node. child ( byFieldName: " protocols " ) {
219- for protocolNode in protocolsNode. children {
220- let protocolName = textProvider ( . node( protocolNode) )
221- if !protocolName. isEmpty {
222- protocols. append ( protocolName)
223- }
224- }
225- }
226-
227- var signature = " @protocol \( name) "
228- if !protocols. isEmpty {
229- signature += " < \( protocols. joined ( separator: " , " ) ) > "
230- }
231148 return . init (
232149 node: node,
233150 signature: signature,
234151 name: name,
235152 canBeUsedAsCodeRange: true
236153 )
237154 }
238-
155+
239156 func parseMethodDefinitionNode(
240157 _ node: ASTNode,
241158 textProvider: @escaping TextProvider
@@ -273,7 +190,7 @@ public class ObjectiveCFocusedCodeFinder: KnownLanguageFocusedCodeFinder<
273190 signaturePointRange
274191 ) = node. extractInformationBeforeNode ( withFieldName: " body " )
275192 let signature = textProvider ( . range( range: signatureRange, pointRange: signaturePointRange) )
276- . replacingOccurrences ( of: " \n " , with: " " )
193+ . replacingOccurrences ( of: " \n " , with: " " )
277194 . trimmingCharacters ( in: . whitespacesAndNewlines)
278195 if signature. isEmpty { return nil }
279196 return . init(
@@ -342,6 +259,12 @@ extension NSRange {
342259 let end = Swift . max ( lowerBound, Swift . min ( upperBound, range. lowerBound) )
343260 return NSRange ( location: start, length: end - start)
344261 }
262+
263+ func notSurpassing( _ range: NSRange ) -> NSRange {
264+ let start = lowerBound
265+ let end = Swift . max ( lowerBound, Swift . min ( upperBound, range. upperBound) )
266+ return NSRange ( location: start, length: end - start)
267+ }
345268}
346269
347270extension Range where Bound == Point {
@@ -354,5 +277,15 @@ extension Range where Bound == Point {
354277 }
355278 return Range ( uncheckedBounds: ( start, end) )
356279 }
280+
281+ func notSurpassing( _ range: Range < Bound > ) -> Range < Bound > {
282+ let start = lowerBound
283+ let end = if range. lowerBound >= upperBound {
284+ upperBound
285+ } else {
286+ Swift . max ( range. upperBound, lowerBound)
287+ }
288+ return Range ( uncheckedBounds: ( start, end) )
289+ }
357290}
358291
0 commit comments