objective.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. # -*- coding: utf-8 -*-
  2. """
  3. pygments.lexers.objective
  4. ~~~~~~~~~~~~~~~~~~~~~~~~~
  5. Lexers for Objective-C family languages.
  6. :copyright: Copyright 2006-2019 by the Pygments team, see AUTHORS.
  7. :license: BSD, see LICENSE for details.
  8. """
  9. import re
  10. from pygments.lexer import RegexLexer, include, bygroups, using, this, words, \
  11. inherit, default
  12. from pygments.token import Text, Keyword, Name, String, Operator, \
  13. Number, Punctuation, Literal, Comment
  14. from pygments.lexers.c_cpp import CLexer, CppLexer
  15. __all__ = ['ObjectiveCLexer', 'ObjectiveCppLexer', 'LogosLexer', 'SwiftLexer']
  16. def objective(baselexer):
  17. """
  18. Generate a subclass of baselexer that accepts the Objective-C syntax
  19. extensions.
  20. """
  21. # Have to be careful not to accidentally match JavaDoc/Doxygen syntax here,
  22. # since that's quite common in ordinary C/C++ files. It's OK to match
  23. # JavaDoc/Doxygen keywords that only apply to Objective-C, mind.
  24. #
  25. # The upshot of this is that we CANNOT match @class or @interface
  26. _oc_keywords = re.compile(r'@(?:end|implementation|protocol)')
  27. # Matches [ <ws>? identifier <ws> ( identifier <ws>? ] | identifier? : )
  28. # (note the identifier is *optional* when there is a ':'!)
  29. _oc_message = re.compile(r'\[\s*[a-zA-Z_]\w*\s+'
  30. r'(?:[a-zA-Z_]\w*\s*\]|'
  31. r'(?:[a-zA-Z_]\w*)?:)')
  32. class GeneratedObjectiveCVariant(baselexer):
  33. """
  34. Implements Objective-C syntax on top of an existing C family lexer.
  35. """
  36. tokens = {
  37. 'statements': [
  38. (r'@"', String, 'string'),
  39. (r'@(YES|NO)', Number),
  40. (r"@'(\\.|\\[0-7]{1,3}|\\x[a-fA-F0-9]{1,2}|[^\\\'\n])'", String.Char),
  41. (r'@(\d+\.\d*|\.\d+|\d+)[eE][+-]?\d+[lL]?', Number.Float),
  42. (r'@(\d+\.\d*|\.\d+|\d+[fF])[fF]?', Number.Float),
  43. (r'@0x[0-9a-fA-F]+[Ll]?', Number.Hex),
  44. (r'@0[0-7]+[Ll]?', Number.Oct),
  45. (r'@\d+[Ll]?', Number.Integer),
  46. (r'@\(', Literal, 'literal_number'),
  47. (r'@\[', Literal, 'literal_array'),
  48. (r'@\{', Literal, 'literal_dictionary'),
  49. (words((
  50. '@selector', '@private', '@protected', '@public', '@encode',
  51. '@synchronized', '@try', '@throw', '@catch', '@finally',
  52. '@end', '@property', '@synthesize', '__bridge', '__bridge_transfer',
  53. '__autoreleasing', '__block', '__weak', '__strong', 'weak', 'strong',
  54. 'copy', 'retain', 'assign', 'unsafe_unretained', 'atomic', 'nonatomic',
  55. 'readonly', 'readwrite', 'setter', 'getter', 'typeof', 'in',
  56. 'out', 'inout', 'release', 'class', '@dynamic', '@optional',
  57. '@required', '@autoreleasepool', '@import'), suffix=r'\b'),
  58. Keyword),
  59. (words(('id', 'instancetype', 'Class', 'IMP', 'SEL', 'BOOL',
  60. 'IBOutlet', 'IBAction', 'unichar'), suffix=r'\b'),
  61. Keyword.Type),
  62. (r'@(true|false|YES|NO)\n', Name.Builtin),
  63. (r'(YES|NO|nil|self|super)\b', Name.Builtin),
  64. # Carbon types
  65. (r'(Boolean|UInt8|SInt8|UInt16|SInt16|UInt32|SInt32)\b', Keyword.Type),
  66. # Carbon built-ins
  67. (r'(TRUE|FALSE)\b', Name.Builtin),
  68. (r'(@interface|@implementation)(\s+)', bygroups(Keyword, Text),
  69. ('#pop', 'oc_classname')),
  70. (r'(@class|@protocol)(\s+)', bygroups(Keyword, Text),
  71. ('#pop', 'oc_forward_classname')),
  72. # @ can also prefix other expressions like @{...} or @(...)
  73. (r'@', Punctuation),
  74. inherit,
  75. ],
  76. 'oc_classname': [
  77. # interface definition that inherits
  78. (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?(\s*)(\{)',
  79. bygroups(Name.Class, Text, Name.Class, Text, Punctuation),
  80. ('#pop', 'oc_ivars')),
  81. (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?',
  82. bygroups(Name.Class, Text, Name.Class), '#pop'),
  83. # interface definition for a category
  84. (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))(\s*)(\{)',
  85. bygroups(Name.Class, Text, Name.Label, Text, Punctuation),
  86. ('#pop', 'oc_ivars')),
  87. (r'([a-zA-Z$_][\w$]*)(\s*)(\([a-zA-Z$_][\w$]*\))',
  88. bygroups(Name.Class, Text, Name.Label), '#pop'),
  89. # simple interface / implementation
  90. (r'([a-zA-Z$_][\w$]*)(\s*)(\{)',
  91. bygroups(Name.Class, Text, Punctuation), ('#pop', 'oc_ivars')),
  92. (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop')
  93. ],
  94. 'oc_forward_classname': [
  95. (r'([a-zA-Z$_][\w$]*)(\s*,\s*)',
  96. bygroups(Name.Class, Text), 'oc_forward_classname'),
  97. (r'([a-zA-Z$_][\w$]*)(\s*;?)',
  98. bygroups(Name.Class, Text), '#pop')
  99. ],
  100. 'oc_ivars': [
  101. include('whitespace'),
  102. include('statements'),
  103. (';', Punctuation),
  104. (r'\{', Punctuation, '#push'),
  105. (r'\}', Punctuation, '#pop'),
  106. ],
  107. 'root': [
  108. # methods
  109. (r'^([-+])(\s*)' # method marker
  110. r'(\(.*?\))?(\s*)' # return type
  111. r'([a-zA-Z$_][\w$]*:?)', # begin of method name
  112. bygroups(Punctuation, Text, using(this),
  113. Text, Name.Function),
  114. 'method'),
  115. inherit,
  116. ],
  117. 'method': [
  118. include('whitespace'),
  119. # TODO unsure if ellipses are allowed elsewhere, see
  120. # discussion in Issue 789
  121. (r',', Punctuation),
  122. (r'\.\.\.', Punctuation),
  123. (r'(\(.*?\))(\s*)([a-zA-Z$_][\w$]*)',
  124. bygroups(using(this), Text, Name.Variable)),
  125. (r'[a-zA-Z$_][\w$]*:', Name.Function),
  126. (';', Punctuation, '#pop'),
  127. (r'\{', Punctuation, 'function'),
  128. default('#pop'),
  129. ],
  130. 'literal_number': [
  131. (r'\(', Punctuation, 'literal_number_inner'),
  132. (r'\)', Literal, '#pop'),
  133. include('statement'),
  134. ],
  135. 'literal_number_inner': [
  136. (r'\(', Punctuation, '#push'),
  137. (r'\)', Punctuation, '#pop'),
  138. include('statement'),
  139. ],
  140. 'literal_array': [
  141. (r'\[', Punctuation, 'literal_array_inner'),
  142. (r'\]', Literal, '#pop'),
  143. include('statement'),
  144. ],
  145. 'literal_array_inner': [
  146. (r'\[', Punctuation, '#push'),
  147. (r'\]', Punctuation, '#pop'),
  148. include('statement'),
  149. ],
  150. 'literal_dictionary': [
  151. (r'\}', Literal, '#pop'),
  152. include('statement'),
  153. ],
  154. }
  155. def analyse_text(text):
  156. if _oc_keywords.search(text):
  157. return 1.0
  158. elif '@"' in text: # strings
  159. return 0.8
  160. elif re.search('@[0-9]+', text):
  161. return 0.7
  162. elif _oc_message.search(text):
  163. return 0.8
  164. return 0
  165. def get_tokens_unprocessed(self, text):
  166. from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \
  167. COCOA_PROTOCOLS, COCOA_PRIMITIVES
  168. for index, token, value in \
  169. baselexer.get_tokens_unprocessed(self, text):
  170. if token is Name or token is Name.Class:
  171. if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \
  172. or value in COCOA_PRIMITIVES:
  173. token = Name.Builtin.Pseudo
  174. yield index, token, value
  175. return GeneratedObjectiveCVariant
  176. class ObjectiveCLexer(objective(CLexer)):
  177. """
  178. For Objective-C source code with preprocessor directives.
  179. """
  180. name = 'Objective-C'
  181. aliases = ['objective-c', 'objectivec', 'obj-c', 'objc']
  182. filenames = ['*.m', '*.h']
  183. mimetypes = ['text/x-objective-c']
  184. priority = 0.05 # Lower than C
  185. class ObjectiveCppLexer(objective(CppLexer)):
  186. """
  187. For Objective-C++ source code with preprocessor directives.
  188. """
  189. name = 'Objective-C++'
  190. aliases = ['objective-c++', 'objectivec++', 'obj-c++', 'objc++']
  191. filenames = ['*.mm', '*.hh']
  192. mimetypes = ['text/x-objective-c++']
  193. priority = 0.05 # Lower than C++
  194. class LogosLexer(ObjectiveCppLexer):
  195. """
  196. For Logos + Objective-C source code with preprocessor directives.
  197. .. versionadded:: 1.6
  198. """
  199. name = 'Logos'
  200. aliases = ['logos']
  201. filenames = ['*.x', '*.xi', '*.xm', '*.xmi']
  202. mimetypes = ['text/x-logos']
  203. priority = 0.25
  204. tokens = {
  205. 'statements': [
  206. (r'(%orig|%log)\b', Keyword),
  207. (r'(%c)\b(\()(\s*)([a-zA-Z$_][\w$]*)(\s*)(\))',
  208. bygroups(Keyword, Punctuation, Text, Name.Class, Text, Punctuation)),
  209. (r'(%init)\b(\()',
  210. bygroups(Keyword, Punctuation), 'logos_init_directive'),
  211. (r'(%init)(?=\s*;)', bygroups(Keyword)),
  212. (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)',
  213. bygroups(Keyword, Text, Name.Class), '#pop'),
  214. (r'(%subclass)(\s+)', bygroups(Keyword, Text),
  215. ('#pop', 'logos_classname')),
  216. inherit,
  217. ],
  218. 'logos_init_directive': [
  219. (r'\s+', Text),
  220. (',', Punctuation, ('logos_init_directive', '#pop')),
  221. (r'([a-zA-Z$_][\w$]*)(\s*)(=)(\s*)([^);]*)',
  222. bygroups(Name.Class, Text, Punctuation, Text, Text)),
  223. (r'([a-zA-Z$_][\w$]*)', Name.Class),
  224. (r'\)', Punctuation, '#pop'),
  225. ],
  226. 'logos_classname': [
  227. (r'([a-zA-Z$_][\w$]*)(\s*:\s*)([a-zA-Z$_][\w$]*)?',
  228. bygroups(Name.Class, Text, Name.Class), '#pop'),
  229. (r'([a-zA-Z$_][\w$]*)', Name.Class, '#pop')
  230. ],
  231. 'root': [
  232. (r'(%subclass)(\s+)', bygroups(Keyword, Text),
  233. 'logos_classname'),
  234. (r'(%hook|%group)(\s+)([a-zA-Z$_][\w$]+)',
  235. bygroups(Keyword, Text, Name.Class)),
  236. (r'(%config)(\s*\(\s*)(\w+)(\s*=\s*)(.*?)(\s*\)\s*)',
  237. bygroups(Keyword, Text, Name.Variable, Text, String, Text)),
  238. (r'(%ctor)(\s*)(\{)', bygroups(Keyword, Text, Punctuation),
  239. 'function'),
  240. (r'(%new)(\s*)(\()(\s*.*?\s*)(\))',
  241. bygroups(Keyword, Text, Keyword, String, Keyword)),
  242. (r'(\s*)(%end)(\s*)', bygroups(Text, Keyword, Text)),
  243. inherit,
  244. ],
  245. }
  246. _logos_keywords = re.compile(r'%(?:hook|ctor|init|c\()')
  247. def analyse_text(text):
  248. if LogosLexer._logos_keywords.search(text):
  249. return 1.0
  250. return 0
  251. class SwiftLexer(RegexLexer):
  252. """
  253. For `Swift <https://developer.apple.com/swift/>`_ source.
  254. .. versionadded:: 2.0
  255. """
  256. name = 'Swift'
  257. filenames = ['*.swift']
  258. aliases = ['swift']
  259. mimetypes = ['text/x-swift']
  260. tokens = {
  261. 'root': [
  262. # Whitespace and Comments
  263. (r'\n', Text),
  264. (r'\s+', Text),
  265. (r'//', Comment.Single, 'comment-single'),
  266. (r'/\*', Comment.Multiline, 'comment-multi'),
  267. (r'#(if|elseif|else|endif|available)\b', Comment.Preproc, 'preproc'),
  268. # Keywords
  269. include('keywords'),
  270. # Global Types
  271. (words((
  272. 'Array', 'AutoreleasingUnsafeMutablePointer', 'BidirectionalReverseView',
  273. 'Bit', 'Bool', 'CFunctionPointer', 'COpaquePointer', 'CVaListPointer',
  274. 'Character', 'ClosedInterval', 'CollectionOfOne', 'ContiguousArray',
  275. 'Dictionary', 'DictionaryGenerator', 'DictionaryIndex', 'Double',
  276. 'EmptyCollection', 'EmptyGenerator', 'EnumerateGenerator',
  277. 'EnumerateSequence', 'FilterCollectionView',
  278. 'FilterCollectionViewIndex', 'FilterGenerator', 'FilterSequenceView',
  279. 'Float', 'Float80', 'FloatingPointClassification', 'GeneratorOf',
  280. 'GeneratorOfOne', 'GeneratorSequence', 'HalfOpenInterval', 'HeapBuffer',
  281. 'HeapBufferStorage', 'ImplicitlyUnwrappedOptional', 'IndexingGenerator',
  282. 'Int', 'Int16', 'Int32', 'Int64', 'Int8', 'LazyBidirectionalCollection',
  283. 'LazyForwardCollection', 'LazyRandomAccessCollection',
  284. 'LazySequence', 'MapCollectionView', 'MapSequenceGenerator',
  285. 'MapSequenceView', 'MirrorDisposition', 'ObjectIdentifier', 'OnHeap',
  286. 'Optional', 'PermutationGenerator', 'QuickLookObject',
  287. 'RandomAccessReverseView', 'Range', 'RangeGenerator', 'RawByte', 'Repeat',
  288. 'ReverseBidirectionalIndex', 'ReverseRandomAccessIndex', 'SequenceOf',
  289. 'SinkOf', 'Slice', 'StaticString', 'StrideThrough', 'StrideThroughGenerator',
  290. 'StrideTo', 'StrideToGenerator', 'String', 'UInt', 'UInt16', 'UInt32',
  291. 'UInt64', 'UInt8', 'UTF16', 'UTF32', 'UTF8', 'UnicodeDecodingResult',
  292. 'UnicodeScalar', 'Unmanaged', 'UnsafeBufferPointer',
  293. 'UnsafeBufferPointerGenerator', 'UnsafeMutableBufferPointer',
  294. 'UnsafeMutablePointer', 'UnsafePointer', 'Zip2', 'ZipGenerator2',
  295. # Protocols
  296. 'AbsoluteValuable', 'AnyObject', 'ArrayLiteralConvertible',
  297. 'BidirectionalIndexType', 'BitwiseOperationsType',
  298. 'BooleanLiteralConvertible', 'BooleanType', 'CVarArgType',
  299. 'CollectionType', 'Comparable', 'DebugPrintable',
  300. 'DictionaryLiteralConvertible', 'Equatable',
  301. 'ExtendedGraphemeClusterLiteralConvertible',
  302. 'ExtensibleCollectionType', 'FloatLiteralConvertible',
  303. 'FloatingPointType', 'ForwardIndexType', 'GeneratorType', 'Hashable',
  304. 'IntegerArithmeticType', 'IntegerLiteralConvertible', 'IntegerType',
  305. 'IntervalType', 'MirrorType', 'MutableCollectionType', 'MutableSliceable',
  306. 'NilLiteralConvertible', 'OutputStreamType', 'Printable',
  307. 'RandomAccessIndexType', 'RangeReplaceableCollectionType',
  308. 'RawOptionSetType', 'RawRepresentable', 'Reflectable', 'SequenceType',
  309. 'SignedIntegerType', 'SignedNumberType', 'SinkType', 'Sliceable',
  310. 'Streamable', 'Strideable', 'StringInterpolationConvertible',
  311. 'StringLiteralConvertible', 'UnicodeCodecType',
  312. 'UnicodeScalarLiteralConvertible', 'UnsignedIntegerType',
  313. '_ArrayBufferType', '_BidirectionalIndexType', '_CocoaStringType',
  314. '_CollectionType', '_Comparable', '_ExtensibleCollectionType',
  315. '_ForwardIndexType', '_Incrementable', '_IntegerArithmeticType',
  316. '_IntegerType', '_ObjectiveCBridgeable', '_RandomAccessIndexType',
  317. '_RawOptionSetType', '_SequenceType', '_Sequence_Type',
  318. '_SignedIntegerType', '_SignedNumberType', '_Sliceable', '_Strideable',
  319. '_SwiftNSArrayRequiredOverridesType', '_SwiftNSArrayType',
  320. '_SwiftNSCopyingType', '_SwiftNSDictionaryRequiredOverridesType',
  321. '_SwiftNSDictionaryType', '_SwiftNSEnumeratorType',
  322. '_SwiftNSFastEnumerationType', '_SwiftNSStringRequiredOverridesType',
  323. '_SwiftNSStringType', '_UnsignedIntegerType',
  324. # Variables
  325. 'C_ARGC', 'C_ARGV', 'Process',
  326. # Typealiases
  327. 'Any', 'AnyClass', 'BooleanLiteralType', 'CBool', 'CChar', 'CChar16',
  328. 'CChar32', 'CDouble', 'CFloat', 'CInt', 'CLong', 'CLongLong', 'CShort',
  329. 'CSignedChar', 'CUnsignedInt', 'CUnsignedLong', 'CUnsignedShort',
  330. 'CWideChar', 'ExtendedGraphemeClusterType', 'Float32', 'Float64',
  331. 'FloatLiteralType', 'IntMax', 'IntegerLiteralType', 'StringLiteralType',
  332. 'UIntMax', 'UWord', 'UnicodeScalarType', 'Void', 'Word',
  333. # Foundation/Cocoa
  334. 'NSErrorPointer', 'NSObjectProtocol', 'Selector'), suffix=r'\b'),
  335. Name.Builtin),
  336. # Functions
  337. (words((
  338. 'abs', 'advance', 'alignof', 'alignofValue', 'assert', 'assertionFailure',
  339. 'contains', 'count', 'countElements', 'debugPrint', 'debugPrintln',
  340. 'distance', 'dropFirst', 'dropLast', 'dump', 'enumerate', 'equal',
  341. 'extend', 'fatalError', 'filter', 'find', 'first', 'getVaList', 'indices',
  342. 'insert', 'isEmpty', 'join', 'last', 'lazy', 'lexicographicalCompare',
  343. 'map', 'max', 'maxElement', 'min', 'minElement', 'numericCast', 'overlaps',
  344. 'partition', 'precondition', 'preconditionFailure', 'prefix', 'print',
  345. 'println', 'reduce', 'reflect', 'removeAll', 'removeAtIndex', 'removeLast',
  346. 'removeRange', 'reverse', 'sizeof', 'sizeofValue', 'sort', 'sorted',
  347. 'splice', 'split', 'startsWith', 'stride', 'strideof', 'strideofValue',
  348. 'suffix', 'swap', 'toDebugString', 'toString', 'transcode',
  349. 'underestimateCount', 'unsafeAddressOf', 'unsafeBitCast', 'unsafeDowncast',
  350. 'withExtendedLifetime', 'withUnsafeMutablePointer',
  351. 'withUnsafeMutablePointers', 'withUnsafePointer', 'withUnsafePointers',
  352. 'withVaList'), suffix=r'\b'),
  353. Name.Builtin.Pseudo),
  354. # Implicit Block Variables
  355. (r'\$\d+', Name.Variable),
  356. # Binary Literal
  357. (r'0b[01_]+', Number.Bin),
  358. # Octal Literal
  359. (r'0o[0-7_]+', Number.Oct),
  360. # Hexadecimal Literal
  361. (r'0x[0-9a-fA-F_]+', Number.Hex),
  362. # Decimal Literal
  363. (r'[0-9][0-9_]*(\.[0-9_]+[eE][+\-]?[0-9_]+|'
  364. r'\.[0-9_]*|[eE][+\-]?[0-9_]+)', Number.Float),
  365. (r'[0-9][0-9_]*', Number.Integer),
  366. # String Literal
  367. (r'"', String, 'string'),
  368. # Operators and Punctuation
  369. (r'[(){}\[\].,:;=@#`?]|->|[<&?](?=\w)|(?<=\w)[>!?]', Punctuation),
  370. (r'[/=\-+!*%<>&|^?~]+', Operator),
  371. # Identifier
  372. (r'[a-zA-Z_]\w*', Name)
  373. ],
  374. 'keywords': [
  375. (words((
  376. 'as', 'break', 'case', 'catch', 'continue', 'default', 'defer',
  377. 'do', 'else', 'fallthrough', 'for', 'guard', 'if', 'in', 'is',
  378. 'repeat', 'return', '#selector', 'switch', 'throw', 'try',
  379. 'where', 'while'), suffix=r'\b'),
  380. Keyword),
  381. (r'@availability\([^)]+\)', Keyword.Reserved),
  382. (words((
  383. 'associativity', 'convenience', 'dynamic', 'didSet', 'final',
  384. 'get', 'indirect', 'infix', 'inout', 'lazy', 'left', 'mutating',
  385. 'none', 'nonmutating', 'optional', 'override', 'postfix',
  386. 'precedence', 'prefix', 'Protocol', 'required', 'rethrows',
  387. 'right', 'set', 'throws', 'Type', 'unowned', 'weak', 'willSet',
  388. '@availability', '@autoclosure', '@noreturn',
  389. '@NSApplicationMain', '@NSCopying', '@NSManaged', '@objc',
  390. '@UIApplicationMain', '@IBAction', '@IBDesignable',
  391. '@IBInspectable', '@IBOutlet'), suffix=r'\b'),
  392. Keyword.Reserved),
  393. (r'(as|dynamicType|false|is|nil|self|Self|super|true|__COLUMN__'
  394. r'|__FILE__|__FUNCTION__|__LINE__|_'
  395. r'|#(?:file|line|column|function))\b', Keyword.Constant),
  396. (r'import\b', Keyword.Declaration, 'module'),
  397. (r'(class|enum|extension|struct|protocol)(\s+)([a-zA-Z_]\w*)',
  398. bygroups(Keyword.Declaration, Text, Name.Class)),
  399. (r'(func)(\s+)([a-zA-Z_]\w*)',
  400. bygroups(Keyword.Declaration, Text, Name.Function)),
  401. (r'(var|let)(\s+)([a-zA-Z_]\w*)', bygroups(Keyword.Declaration,
  402. Text, Name.Variable)),
  403. (words((
  404. 'class', 'deinit', 'enum', 'extension', 'func', 'import', 'init',
  405. 'internal', 'let', 'operator', 'private', 'protocol', 'public',
  406. 'static', 'struct', 'subscript', 'typealias', 'var'), suffix=r'\b'),
  407. Keyword.Declaration)
  408. ],
  409. 'comment': [
  410. (r':param: [a-zA-Z_]\w*|:returns?:|(FIXME|MARK|TODO):',
  411. Comment.Special)
  412. ],
  413. # Nested
  414. 'comment-single': [
  415. (r'\n', Text, '#pop'),
  416. include('comment'),
  417. (r'[^\n]', Comment.Single)
  418. ],
  419. 'comment-multi': [
  420. include('comment'),
  421. (r'[^*/]', Comment.Multiline),
  422. (r'/\*', Comment.Multiline, '#push'),
  423. (r'\*/', Comment.Multiline, '#pop'),
  424. (r'[*/]', Comment.Multiline)
  425. ],
  426. 'module': [
  427. (r'\n', Text, '#pop'),
  428. (r'[a-zA-Z_]\w*', Name.Class),
  429. include('root')
  430. ],
  431. 'preproc': [
  432. (r'\n', Text, '#pop'),
  433. include('keywords'),
  434. (r'[A-Za-z]\w*', Comment.Preproc),
  435. include('root')
  436. ],
  437. 'string': [
  438. (r'\\\(', String.Interpol, 'string-intp'),
  439. (r'"', String, '#pop'),
  440. (r"""\\['"\\nrt]|\\x[0-9a-fA-F]{2}|\\[0-7]{1,3}"""
  441. r"""|\\u[0-9a-fA-F]{4}|\\U[0-9a-fA-F]{8}""", String.Escape),
  442. (r'[^\\"]+', String),
  443. (r'\\', String)
  444. ],
  445. 'string-intp': [
  446. (r'\(', String.Interpol, '#push'),
  447. (r'\)', String.Interpol, '#pop'),
  448. include('root')
  449. ]
  450. }
  451. def get_tokens_unprocessed(self, text):
  452. from pygments.lexers._cocoa_builtins import COCOA_INTERFACES, \
  453. COCOA_PROTOCOLS, COCOA_PRIMITIVES
  454. for index, token, value in \
  455. RegexLexer.get_tokens_unprocessed(self, text):
  456. if token is Name or token is Name.Class:
  457. if value in COCOA_INTERFACES or value in COCOA_PROTOCOLS \
  458. or value in COCOA_PRIMITIVES:
  459. token = Name.Builtin.Pseudo
  460. yield index, token, value