Skip to content

Commit b7302c3

Browse files
committed
Added custom protocol for macros.
1 parent f9ec030 commit b7302c3

File tree

4 files changed

+89
-70
lines changed

4 files changed

+89
-70
lines changed

Sources/Clang/Cursors.swift

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,30 @@ public struct EnumConstantDecl: ClangCursorBacked {
109109
}
110110
}
111111

112+
protocol MacroCursor: ClangCursorBacked {}
113+
extension MacroCursor {
114+
/// Determine whether a macro is function like.
115+
public var isFunctionLike: Bool {
116+
return clang_Cursor_isMacroFunctionLike(clang) != 0
117+
}
118+
119+
/// Determine whether a macro is a built-in macro.
120+
public var isBuiltin: Bool {
121+
return clang_Cursor_isMacroBuiltin(clang) != 0
122+
}
123+
}
124+
public struct MacroExpansion: MacroCursor {
125+
let clang: CXCursor
126+
}
127+
128+
public struct MacroInstantiation: MacroCursor {
129+
let clang: CXCursor
130+
}
131+
132+
public struct MacroDefinition: MacroCursor {
133+
let clang: CXCursor
134+
}
135+
112136
/// An access specifier.
113137
public struct CXXAccessSpecifier: ClangCursorBacked {
114138
let clang: CXCursor
@@ -1183,21 +1207,6 @@ public struct PreprocessingDirective: ClangCursorBacked {
11831207
let clang: CXCursor
11841208
}
11851209

1186-
1187-
public struct MacroDefinition: ClangCursorBacked {
1188-
let clang: CXCursor
1189-
}
1190-
1191-
1192-
public struct MacroExpansion: ClangCursorBacked {
1193-
let clang: CXCursor
1194-
}
1195-
1196-
1197-
public struct MacroInstantiation: ClangCursorBacked {
1198-
let clang: CXCursor
1199-
}
1200-
12011210
/// A module import declaration.
12021211
public struct ModuleImportDecl: ClangCursorBacked {
12031212
let clang: CXCursor

Sources/Clang/Token.swift

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
#if !NO_SWIFTPM
22
import cclang
33
#endif
4+
45
import Foundation
56

6-
public struct Token {
7-
internal let clang: CXToken
7+
/// Represents a C, C++, or Objective-C token.
8+
public protocol Token {
9+
var clang: CXToken { get }
10+
}
811

9-
/// Retrieves the kind of the receiver.
10-
public var kind: TokenKind {
11-
return TokenKind(clang: clang_getTokenKind(clang))
12-
}
12+
extension Token {
1313

1414
/// Determine the spelling of the given token.
1515
/// The spelling of a token is the textual representation of that token,
@@ -18,8 +18,57 @@ public struct Token {
1818
return clang_getTokenSpelling(translationUnit.clang, clang).asSwift()
1919
}
2020

21-
public func asClang() -> CXToken {
22-
return clang
21+
/// Retrieve the source location of the given token.
22+
/// - param translationUnit: The translation unit in which you're looking
23+
/// for this token.
24+
func location(in translationUnit: TranslationUnit) -> SourceLocation {
25+
return SourceLocation(clang: clang_getTokenLocation(translationUnit.clang,
26+
clang))
27+
}
28+
29+
/// Retrieve a source range that covers the given token.
30+
/// - param translationUnit: The translation unit in which you're looking
31+
/// for this token.
32+
func range(in translationUnit: TranslationUnit) -> SourceRange {
33+
return SourceRange(clang: clang_getTokenExtent(translationUnit.clang,
34+
clang))
35+
}
36+
}
37+
38+
/// A token that contains some kind of punctuation.
39+
public struct PunctuationToken: Token {
40+
public let clang: CXToken
41+
}
42+
43+
/// A language keyword.
44+
public struct KeywordToken: Token {
45+
public let clang: CXToken
46+
}
47+
48+
/// An identifier (that is not a keyword).
49+
public struct IdentifierToken: Token {
50+
public let clang: CXToken
51+
}
52+
53+
/// A numeric, string, or character literal.
54+
public struct LiteralToken: Token {
55+
public let clang: CXToken
56+
}
57+
58+
/// A comment.
59+
public struct CommentToken: Token {
60+
public let clang: CXToken
61+
}
62+
63+
/// Converts a CXToken to a Token, returning `nil` if it was unsuccessful
64+
func convertToken(_ clang: CXToken) -> Token {
65+
switch clang_getTokenKind(clang) {
66+
case CXToken_Punctuation: return PunctuationToken(clang: clang)
67+
case CXToken_Keyword: return KeywordToken(clang: clang)
68+
case CXToken_Identifier: return IdentifierToken(clang: clang)
69+
case CXToken_Literal: return LiteralToken(clang: clang)
70+
case CXToken_Comment: return CommentToken(clang: clang)
71+
default: fatalError("invalid CXTokenKind \(clang)")
2372
}
2473
}
2574

@@ -78,42 +127,3 @@ public struct SourceRange {
78127
return SourceLocation(clang: clang_getRangeEnd(clang))
79128
}
80129
}
81-
82-
/// Represents the different kinds of tokens in C/C++/Objective-C
83-
public enum TokenKind {
84-
/// A piece of punctuation, like `{`, `;`, and `:`
85-
case punctuation
86-
87-
/// A keyword, like `if`, `else`, and `case`
88-
case keyword
89-
90-
/// An identifier, like a variable's name or type name
91-
case identifier
92-
93-
/// A literal, either character, string, or number
94-
case literal
95-
96-
/// A C comment
97-
case comment
98-
99-
init(clang: CXTokenKind) {
100-
switch clang {
101-
case CXToken_Comment: self = .comment
102-
case CXToken_Literal: self = .literal
103-
case CXToken_Identifier: self = .identifier
104-
case CXToken_Keyword: self = .keyword
105-
case CXToken_Punctuation: self = .punctuation
106-
default: fatalError("unknown CXTokenKind \(clang)")
107-
}
108-
}
109-
110-
func asClang() -> CXTokenKind {
111-
switch self {
112-
case .comment: return CXToken_Comment
113-
case .literal: return CXToken_Literal
114-
case .identifier: return CXToken_Identifier
115-
case .keyword: return CXToken_Keyword
116-
case .punctuation: return CXToken_Punctuation
117-
}
118-
}
119-
}

Sources/Clang/TranslationUnit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public class TranslationUnit {
165165
guard let tokensPtr = tokensPtrOpt else { return [] }
166166
var tokens = [Token]()
167167
for i in 0..<Int(numTokens) {
168-
tokens.append(Token(clang: tokensPtr[i]))
168+
tokens.append(convertToken(tokensPtr[i]))
169169
}
170170
clang_disposeTokens(clang, tokensPtr, numTokens)
171171
return tokens

Tests/ClangTests/ClangTests.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func generateStructs(forEnum decl: EnumDecl,
126126
prefix: String,
127127
suffix: String = "") {
128128
let protocolDecl = [
129-
"protocol \(type) {",
129+
"public protocol \(type) {",
130130
" var clang: CX\(type) { get }",
131131
"}",
132132
""
@@ -238,9 +238,9 @@ class ClangTests: XCTestCase {
238238
"-I/usr/local/opt/llvm/include"
239239
])
240240
let typesToMake: [String: (type: String, prefix: String, suffix: String)] = [
241-
"CX_StorageClass": (type: "StorageClass",
242-
prefix: "CX_SC_",
243-
suffix: "")
241+
"CXTokenKind": (type: "Token",
242+
prefix: "CXToken_",
243+
suffix: "Token")
244244
]
245245
for child in tu.cursor.children() {
246246
// if let decl = child as? TypedefDecl,
@@ -257,9 +257,9 @@ class ClangTests: XCTestCase {
257257
// print()
258258
if let values = typesToMake["\(enumDecl)"] {
259259
// generateSwiftOptionSet(forEnum: enumDecl, prefix: values.prefix, name: values.type)
260-
generateSwiftEnum(forEnum: enumDecl, prefix: values.prefix, name: values.type)
261-
// generateStructs(forEnum: enumDecl, type: values.type,
262-
// prefix: values.prefix, suffix: values.suffix)
260+
// generateSwiftEnum(forEnum: enumDecl, prefix: values.prefix, name: values.type)
261+
generateStructs(forEnum: enumDecl, type: values.type,
262+
prefix: values.prefix, suffix: values.suffix)
263263
}
264264
}
265265
// for child in tu.cursor.children() {

0 commit comments

Comments
 (0)