Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

Adding the ability to declare properties in interfaces. #287

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

BrassLion
Copy link

This pull request allows interfaces to define properties with Djinni-supported data types that are implemented as C++ variables and accessed from Java, through auto-generated getter and setter methods, and Obj-C, through auto-generated @property methods.

Properties are defined in IDL files identically to Djinni record elements. Platform-specific getters and setters are auto-generated. Developers then must implement the generated C++ getters and setters and the backing variable. Properties may be preceded with a readonly keyword, in which case only the platform-specific getter is generated.

This pull request is mostly syntactic sugar and can be implemented by manually defining the getter and setter methods in the IDL file, but provides a more platform-native way of accessing member variables, particularly through the use of @property in Obj-C.

@smarx
Copy link

smarx commented Nov 7, 2016

Automated message from Dropbox CLA bot

@BrassLion, thanks for the pull request! It looks like you haven't yet signed the Dropbox CLA. Please sign it here.

@smarx
Copy link

smarx commented Nov 7, 2016

Automated message from Dropbox CLA bot

@BrassLion, thanks for signing the CLA!

Copy link
Contributor

@artwyman artwyman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking on an oft-requested feature. This looks great overall. I've made some suggestions inline. One which I made in the CppGenerator really deserves to be a top-level design comment:

I'd love to see more code reuse between method generation and property generation, to avoid duplicate code which might not receive the same bugfixes over time. In all generators other than ObjC, properties are generated in the same way as methods. I can see two potential approaches to that:

  1. In the generator, one property at at a time, transform the Property into two Method objects, then invoke the normal method generation code.
  2. At the top level, perform a transformation on the AST to produce an alternative AST without properties, then feed that AST into all generators except for ObjC (ideally with some sort of global "supportsProperties" query which can be extended later.

Option 1 seems most straightforward, but I thought Option 2 might be an interesting step in the direction of supporting other sorts of syntactic-sugar at the AST level.

@@ -14,4 +15,4 @@
@import "single_language_interfaces.djinni"
@import "extended_record.djinni"
@import "varnames.djinni"
@import "relative_paths.djinni"
@import "relative_paths.djinni"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline at end of file

readonly read_only_bool: bool;

static create_new(): properties_test_helper;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline at end of file

test_string: string;
test_list: list<i32>;
readonly read_only_bool: bool;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case should include some methods as well as properties, to test that they can be freely mixed. I'd suggest interspersing them in the file too, rather than grouping them together.


static std::shared_ptr<PropertiesTestHelper> create_new();

virtual int32_t get_item() = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getters should be const methods in C++, unless you think there's an issue with that I'm not considering.

@@ -0,0 +1,9 @@
properties_test_helper = interface +c {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you include a +o +j test case as well?


private:

int32_t m_item;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does seem to just beg for there to be a way to auto-generate the members and getter/setter implementations too, at least optionally in the style of @synthesize in ObjC. That can potentially be tackled separately, though, not necessarily in this diff.

@@ -297,6 +300,16 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
w.wl(s"virtual $ret ${idCpp.method(m.ident)}${params.mkString("(", ", ", ")")}$constFlag = 0;")
}
}
// Properties
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if this shared more code with the method-generating codepaths, since that will help to keep the code simple and make it likely to all be updated in sync with future changes. You should be able to create method definitions from the properties, then use the normal method-generation code.

One option to consider (though it might be too aggressive) would be to implement property generation in most languages as a transformation on the AST, by generating a new AST with methods in place of properties, then running the normal generator on them. That could be a suitable approach for all generators which don't have special support for properties (i.e. ObjC with its @Property declaration).

@BrassLion
Copy link
Author

I'll have a look into making these changes when I next get a chance. In regards to your suggestion of transforming the AST to another without properties, what way of achieving this in Scala would you be envisioning? My Scala knowledge is fairly basic, so any pointers would be appreciated!

@artwyman
Copy link
Contributor

I don't have specifics in mind, really. It's more of a theoretical suggestion. By AST I think I just mean the list of TypeDecl objects which is the allIdl variable in Main.

@choiip
Copy link
Contributor

choiip commented Oct 2, 2017

This is a remarkable feature. The generated API for objective-c looks better. @BrassLion, any update on the changes? It is good the hear that this nice feature could be included in Djinni.

@BrassLion
Copy link
Author

I'm afraid I haven't had any time to return to these changes and I don't see myself getting back to this in the near future. Hopefully someone will be able to continue this feature or use it as inspiration. Apologies!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants