| 1 | <?php |
| 2 | namespace Std\Lib\Syntax; |
| 3 | |
| 4 | /** |
| 5 | * Objective-C(Cの上位互換) |
| 6 | */ |
| 7 | class ObjC extends C { |
| 8 | protected array $headerDirectives = ['include', 'include_next', 'import']; |
| 9 | |
| 10 | protected array $rules = [ |
| 11 | // NSString @"…" |
| 12 | ['re' => '@"(?:[^"\\\\\n]|\\\\.)*"?', 'class' => 'string'], |
| 13 | // @interface, @property, @autoreleasepool等 |
| 14 | ['re' => '@[A-Za-z_]\w*', 'class' => 'keyword'], |
| 15 | // リテラル @[…] @{…} @(…) |
| 16 | ['re' => '@(?=[\[{(])', 'class' => 'keyword'], |
| 17 | ]; |
| 18 | |
| 19 | /** @var array Cに加えるObjective-Cのトークン */ |
| 20 | protected array $objcTokens = [ |
| 21 | 'keyword' => [ |
| 22 | 'self', 'super', 'id', 'instancetype', 'Class', 'SEL', 'IMP', 'BOOL', 'in', 'out', 'inout', 'oneway', 'bycopy', 'byref', |
| 23 | 'nonatomic', 'atomic', 'strong', 'weak', 'copy', 'assign', 'retain', 'readonly', 'readwrite', 'getter', 'setter', |
| 24 | 'nullable', 'nonnull', 'null_resettable', '_Nullable', '_Nonnull', '_Null_unspecified', '__nullable', '__nonnull', |
| 25 | '__bridge', '__bridge_transfer', '__bridge_retained', '__block', '__weak', '__strong', '__unsafe_unretained', '__autoreleasing', '__kindof', |
| 26 | ], |
| 27 | 'constant' => [ |
| 28 | 'YES', 'NO', 'nil', 'Nil', 'NULL', |
| 29 | ], |
| 30 | 'type' => [ |
| 31 | 'NSObject', 'NSString', 'NSMutableString', 'NSArray', 'NSMutableArray', 'NSDictionary', 'NSMutableDictionary', 'NSSet', 'NSMutableSet', |
| 32 | 'NSNumber', 'NSValue', 'NSData', 'NSMutableData', 'NSDate', 'NSURL', 'NSError', 'NSException', 'NSInteger', 'NSUInteger', 'NSTimeInterval', |
| 33 | 'NSRange', 'NSZone', 'NSNotification', 'NSNotificationCenter', 'NSUserDefaults', 'NSFileManager', 'NSBundle', 'NSThread', 'NSTimer', |
| 34 | 'NSRunLoop', 'NSAutoreleasePool', 'NSProcessInfo', 'NSApplication', 'NSWindow', 'NSView', 'NSViewController', 'NSColor', 'NSImage', |
| 35 | 'UIApplication', 'UIView', 'UIViewController', 'UIWindow', 'UIColor', 'UIImage', 'UILabel', 'UIButton', |
| 36 | 'CGFloat', 'CGRect', 'CGPoint', 'CGSize', 'CGContextRef', 'CFStringRef', 'CFTypeRef', 'dispatch_queue_t', 'dispatch_block_t', |
| 37 | 'MTLDevice', 'MTLCommandQueue', 'MTLCommandBuffer', 'MTLRenderPipelineState', 'MTLBuffer', 'MTLTexture', |
| 38 | ], |
| 39 | 'builtin' => [ |
| 40 | 'NSLog', 'NSStringFromClass', 'NSClassFromString', 'NSStringFromSelector', 'NSSelectorFromString', 'NSMakeRange', 'NSApplicationMain', |
| 41 | 'UIApplicationMain', 'CGRectMake', 'CGPointMake', 'CGSizeMake', 'objc_msgSend', 'objc_getClass', 'class_getName', 'sel_registerName', |
| 42 | 'dispatch_async', 'dispatch_sync', 'dispatch_get_main_queue', 'dispatch_get_global_queue', 'dispatch_once', 'dispatch_after', |
| 43 | 'MTLCreateSystemDefaultDevice', 'CFRelease', 'CFRetain', |
| 44 | 'NS_ENUM', 'NS_OPTIONS', 'NS_ASSUME_NONNULL_BEGIN', 'NS_ASSUME_NONNULL_END', 'NS_DESIGNATED_INITIALIZER', 'NS_UNAVAILABLE', |
| 45 | ], |
| 46 | ]; |
| 47 | |
| 48 | public function prepare(string $code): void { |
| 49 | parent::prepare($code); |
| 50 | foreach ($this->buildWords($this->objcTokens) as $w => $class) { |
| 51 | if (!isset($this->words[$w])) $this->words[$w] = $class; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | public function classify(string $word, array $ctx): ?string { |
| 56 | $class = parent::classify($word, $ctx); |
| 57 | if ($class !== null) return $class; |
| 58 | // メッセージのセレクター部分([obj setValue:x forKey:y])。「Foo : NSObject」の様に空白がある場合は除く |
| 59 | if ($ctx['nextRaw'] === ':') return 'function'; |
| 60 | return null; |
| 61 | } |
| 62 | } |