소스 검색

[objc] Add support for Objetive-C protocols (interfaces)

- Use the `id <SomeInterface>` syntax for when extern @:objc interfaces
are referenced
- This commit needs the changes made by HaxeFoundation/haxe@3815c007e6a7e279e558d851624ec705b34f5214
- No solution was yet made to check if an optional method was
implemented by the interface; On Haxe they will have to be included with
@:noCompletion and @:deprecated to satisfy the typeload
Cauê Waneck 10 년 전
부모
커밋
6fce188a2c
4개의 변경된 파일85개의 추가작업 그리고 7개의 파일을 삭제
  1. 7 5
      gencpp.ml
  2. 47 1
      tests/misc/cppObjc/TestObjc.hx
  3. 21 1
      tests/misc/cppObjc/native/include/test.h
  4. 10 0
      tests/misc/cppObjc/native/test.m

+ 7 - 5
gencpp.ml

@@ -662,11 +662,13 @@ let rec class_string klass suffix params remap =
          | _ -> assert false);
    (* Objective-C class *)
    | path when is_objc_type (TInst(klass,[])) ->
-     let str = join_class_path_remap klass.cl_path "::" in
-     if suffix = "_obj" then
-       str
-     else
-       str ^ " *"
+      let str = join_class_path_remap klass.cl_path "::" in
+      if suffix = "_obj" then
+         str
+      else if klass.cl_interface then
+         "id <" ^ str ^ ">"
+      else
+         str ^ " *"
    (* Normal class *)
    | path when klass.cl_extern && (not (is_internal_class path) )->
             (join_class_path_remap klass.cl_path "::") ^ suffix

+ 47 - 1
tests/misc/cppObjc/TestObjc.hx

@@ -75,6 +75,7 @@ class TestObjc extends haxe.unit.TestCase
 		assertEquals(dyn,null);
 		assertTrue(dyn == cls);
 		assertEquals(dyn,cls);
+		cls.release();
 	}
 
 	static function getFieldB<T>(d:{ a:Int, b: T }):T
@@ -85,11 +86,49 @@ class TestObjc extends haxe.unit.TestCase
 		this.assertTrue(TestClass.isNull(null));
 		this.assertFalse(TestClass.isNull(TestClass.alloc().init()));
 	}
+
+	public function testInterface()
+	{
+		cls = TestClass.alloc().init();
+		cls.setOtherThing(21);
+		this.assertTrue(cls.getSelf() == cls);
+		this.assertEquals(cls.getSelf(), cls);
+
+		var iface:TestInterface = cls;
+		var obj:Dynamic = iface;
+		this.assertTrue(iface == cls);
+		this.assertEquals(iface, cls);
+		this.assertTrue(obj == cls);
+		this.assertEquals(obj, cls);
+		this.assertEquals(iface.getSelf(), cls);
+		this.assertEquals(iface.getSelf(), cls.getSelf());
+
+		this.assertEquals(iface.getOtherThing(), 21);
+		this.assertEquals(iface.getOtherThingChar(), 21);
+		cls.setOtherThing(100);
+		this.assertEquals(iface.getOtherThing(), 100);
+		this.assertEquals(iface.getOtherThingChar(), 100);
+
+		this.assertEquals("someOptionalMethod!",iface.someOptionalMethod());
+
+		cls.release();
+	}
+}
+
+@:include("./native/include/test.h")
+@:objc extern interface TestInterface
+{
+	function getSelf():TestInterface;
+	function getOtherThing():Int;
+	function getOtherThingChar():cpp.Int8;
+
+	@:optional function someOptionalMethod():NSString;
+	@:optional function unimplementedOptional():NSString;
 }
 
 @:include("./native/include/test.h")
 @:sourceFile("./native/test.m")
-@:objc extern class TestClass
+@:objc extern class TestClass implements TestInterface
 {
 	static function aStatic():Int;
 	static function isNull(t:TestClass):Bool;
@@ -116,6 +155,13 @@ class TestObjc extends haxe.unit.TestCase
 	function release():Void;
 	function retainCount():Int;
 
+	function getSelf():TestClass;
+
+	function someOptionalMethod():NSString;
+
+	@:deprecated('This method is not implemented on this class')
+	@:noCompletion @:optional function unimplementedOptional():NSString;
+
 	@:plain static function some_c_call(t:TestClass):Int;
 	@:plain static function is_bigger_than_10(t:TestClass, val:Int):Bool;
 }

+ 21 - 1
tests/misc/cppObjc/native/include/test.h

@@ -2,7 +2,23 @@
 #define TEST_H_INCLUDED
 #import <Foundation/Foundation.h>
 
-@interface TestClass : NSObject {
+@protocol TestInterface
+
+- (id <TestInterface>)getSelf;
+
+- (int)getOtherThing;
+
+- (char)getOtherThingChar;
+
+@optional
+
+- (NSString *)someOptionalMethod;
+
+- (NSString *)unimplementedOptional;
+
+@end
+
+@interface TestClass : NSObject <TestInterface> {
 	@public int otherThing;
 }
 
@@ -30,6 +46,10 @@
 
 - (BOOL)isBiggerThan10Int:(int)integer;
 
+- (TestClass *)getSelf;
+
+- (NSString *)someOptionalMethod;
+
 
 @end
 

+ 10 - 0
tests/misc/cppObjc/native/test.m

@@ -59,6 +59,16 @@
 	return integer > 10;
 }
 
+- (TestClass *)getSelf
+{
+	return self;
+}
+
+- (NSString *)someOptionalMethod
+{
+	return @"someOptionalMethod!";
+}
+
 @end
 
 int some_c_call(TestClass *t)