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