diff --git a/spec/class.dd b/spec/class.dd index cf30240685..389cf872be 100644 --- a/spec/class.dd +++ b/spec/class.dd @@ -52,6 +52,7 @@ $(P Classes consist of:) $(UL $(LI a super class) $(LI interfaces) + $(LI a nested anonymous metaclass for classes declared with `extern (Objective-C)`) $(LI dynamic fields) $(LI static fields) $(LI types) @@ -205,9 +206,14 @@ $(H2 $(LNAME2 super_class, Super Class)) $(H2 $(LNAME2 member-functions, Member Functions)) - $(P Non-static member functions have an extra hidden parameter - called $(I this) through which the class object's other members - can be accessed. + $(P Non-static member functions or static member functions with + `Objective-C` linkage have an extra hidden parameter called $(I this) + through which the class object's other members can be accessed. + ) + + $(P Member functions with the Objective-C linkage has an additional + hidden, anonymous, parameter which is the selector the function was + called with. ) $(P Non-static member functions can have, in addition to the usual @@ -215,6 +221,10 @@ $(H2 $(LNAME2 member-functions, Member Functions)) $(D const), $(D immutable), $(D shared), or $(D inout). These attributes apply to the hidden $(I this) parameter. ) + + $(P Static member functions with the Objective-C linkage are placed in + the hidden nested metaclass as non-static member functions. + ) --- class C { diff --git a/spec/function.dd b/spec/function.dd index 046da8758a..0b318a5744 100644 --- a/spec/function.dd +++ b/spec/function.dd @@ -717,7 +717,8 @@ $(H2 $(LNAME2 virtual-functions, Virtual Functions)) are not templatized are virtual unless the compiler can determine that they will never be overridden (e.g. they are marked with $(D final) and do not override any functions in a base class), in which case, it will - make them non-virtual. This results in fewer bugs caused by not + make them non-virtual. Static or `final` functions with `Objective-C` + linkage are virtual as well. This results in fewer bugs caused by not declaring a function virtual and then overriding it anyway. ) @@ -799,6 +800,11 @@ class Bar : Foo the function is called. ) + $(P + Functions with `Objective-C` linkage has an additional hidden, + unnamed, parameter which is the selector it was called with. + ) + $(P To avoid dynamic binding on member function call, insert base class name before the member function name. For example: ) @@ -1043,6 +1049,8 @@ void main() ------ ) + $(P Static functions with `Objective-C` linkage are overridable.) + $(H2 $(LNAME2 inline-functions, Inline Functions)) $(P The compiler makes the decision whether to inline a function or not. diff --git a/spec/objc_interface.dd b/spec/objc_interface.dd index d023c7260f..5922bdd627 100644 --- a/spec/objc_interface.dd +++ b/spec/objc_interface.dd @@ -5,9 +5,9 @@ $(SPEC_S Interfacing to Objective-C, $(HEADERNAV_TOC) $(P - D has limited support for interfacing with Objective-C. It supports - external classes and calling instance and class methods. It is only - available on macOS, compiling for 64bit. + D has some support for interfacing with Objective-C. It supports + classes, instance and class methods. It is only available on macOS, + compiling for 64bit. ) $(P @@ -15,26 +15,69 @@ $(HEADERNAV_TOC) $(LINK2 #usage-example, the bottom). ) - $(SECTION2 $(LNAME2 external-class, Declaring an External Class)) + $(SECTION2 $(LNAME2 classes, Classes)) + + $(SECTION3 $(LNAME2 external-class, Declaring an External Class)) --- extern (Objective-C) - interface NSString + class NSString { const(char)* UTF8String() @selector("UTF8String"); } --- $(P - Currently all Objective-C classes need to be declared as interfaces in - D. All Objective-C classes that should be accessible from within D - need to be declared with the $(LINK2 #objc-linkage, Objective-C linkage). + All Objective-C classes that should be accessible from within D need to + be declared with the $(LINK2 #objc-linkage, Objective-C linkage). If all + methods inside an Objective-C class are without a body the class is + expected to be defined externally. ) $(P The $(LINK2 #selector-attribute, `@selector`) attribute indicates which - Objective-C selector should be used when calling this method from D. - This attribute needs to be attached to all methods. + Objective-C selector should be used when calling this method. + This attribute needs to be attached to all methods with the + `Objective-C` linkage. + ) + + $(SECTION3 $(LNAME2 defining-class, Defining a Class)) + + --- + // externally defined + extern (Objective-C) + class NSObject + { + static NSObject alloc() @selector("alloc"); + NSObject init() @selector("init"); + } + + extern (Objective-C) + class Foo : NSObject + { + override static Foo alloc() @selector("alloc"); + override Foo init() @selector("init"); + + final int bar(int a) @selector("bar:") + { + return a; + } + } + + void main() + { + assert(Foo.alloc.init.bar(3) == 3); + } + --- + + $(P + Defining an Objective-C class is exactly the same as declaring an + external class but it needs to have at least one method with a body. + ) + + $(P + To match the Objective-C semantics, `static` and `final` methods are + virtual. `static` methods are overridable as well. ) $(SECTION2 $(LNAME2 instance-method, Calling an Instance Method)) @@ -73,7 +116,7 @@ $(HEADERNAV_TOC) --- extern (Objective-C) - interface NSString + class NSString { NSString initWith(in char*) @selector("initWithUTF8String:"); NSString initWith(NSString) @selector("initWithString:"); @@ -133,19 +176,19 @@ $(HEADERNAV_TOC) $(P Objective-C linkage is achieved by attaching the `extern (Objective-C)` - attribute to an interface. Example: + attribute to a class. Example: ) --- extern (Objective-C) - interface NSObject + class NSObject { NSObject init() @selector("init"); } --- $(P - All methods inside an interface declared as `extern (Objective-C)` will + All methods inside a class declared as `extern (Objective-C)` will get implicit Objective-C linkage. ) @@ -229,7 +272,7 @@ $(HEADERNAV_TOC) --- extern (Objective-C) - interface NSString + class NSString { static NSString alloc() @selector("alloc"); NSString initWithUTF8String(in char* str) @selector("initWithUTF8String:"); @@ -295,7 +338,7 @@ $(HEADERNAV_TOC) module main; extern (Objective-C) - interface NSString + class NSString { static NSString alloc() @selector("alloc"); NSString initWithUTF8String(in char* str) @selector("initWithUTF8String:");