Skip to content

Commit

Permalink
Make the Objective-C APIs play slightly better with platform conventi…
Browse files Browse the repository at this point in the history
…ons. (#11823)

Change property names in structs to be lowerCamelCased.  This requires
three interesting changes:

1) Deal with property names that collide with NSObject properties by
   renaming them.
2) Deal with property names that start with several all-uppercase
   letters by lowercasing all but the last one.
3) Define getter names for some of the properties, because some start with
   'new', which makes the compiler complain.

Also change all the properties to be nonatomic.
  • Loading branch information
bzbarsky-apple authored Nov 17, 2021
1 parent bd4515c commit 1359f6e
Show file tree
Hide file tree
Showing 16 changed files with 2,407 additions and 2,381 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using namespace chip::app::Clusters;
ListFreer listFreer;
{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Type request;
{{#chip_cluster_command_arguments}}
{{>encode_value target=(concat "request." (asLowerCamelCase label)) source=(concat "payload." (asUpperCamelCase label)) cluster=parent.parent.name errorCode="return;" depth=0}}
{{>encode_value target=(concat "request." (asLowerCamelCase label)) source=(concat "payload." (asStructPropertyName label)) cluster=parent.parent.name errorCode="return;" depth=0}}
{{/chip_cluster_command_arguments}}

new CHIP{{>callbackName}}CallbackBridge(self.callbackQueue, responseHandler, ^(Cancelable * success, Cancelable * failure) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
{{#zcl_clusters}}
{{#zcl_commands}}
@interface CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Payload : NSObject
{{! Override the getter name because some of our properties start with things
like "new" or "init" }}
{{#zcl_command_arguments}}
@property (strong) {{asObjectiveCType type parent.parent.name}} {{asUpperCamelCase label}};
@property (strong, nonatomic{{#unless (isStrEqual (asGetterName label) (asStructPropertyName label))}}, getter={{asGetterName label}}{{/unless}}) {{asObjectiveCType type parent.parent.name}} {{asStructPropertyName label}};
{{/zcl_command_arguments}}
@end

Expand Down
4 changes: 3 additions & 1 deletion src/darwin/Framework/CHIP/templates/CHIPStructsObjc.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
{{#zcl_clusters}}
{{#zcl_structs}}
@interface CHIP{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}} : NSObject
{{! Override the getter name because some of our properties start with things
like "new" or "init" }}
{{#zcl_struct_items}}
@property (strong) {{asObjectiveCType type parent.parent.name}} {{asUpperCamelCase label}};
@property (strong, nonatomic{{#unless (isStrEqual (asGetterName label) (asStructPropertyName label))}}, getter={{asGetterName label}}{{/unless}}) {{asObjectiveCType type parent.parent.name}} {{asStructPropertyName label}};
{{/zcl_struct_items}}
@end

Expand Down
36 changes: 29 additions & 7 deletions src/darwin/Framework/CHIP/templates/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const zclHelper = require(zapPath + 'generator/helper-zcl.js')

const ChipTypesHelper = require('../../../../../src/app/zap-templates/common/ChipTypesHelper.js');
const StringHelper = require('../../../../../src/app/zap-templates/common/StringHelper.js');
const appHelper = require('../../../../../src/app/zap-templates/templates/app/helper.js');

// Ideally those clusters clusters endpoints should be retrieved from the
// descriptor cluster.
Expand Down Expand Up @@ -115,12 +116,6 @@ function asTestIndex(index)
return index.toString().padStart(6, 0);
}

function asUpperCamelCase(label)
{
let str = string.toCamelCase(label, false);
return str.replace(/[\.:]/g, '');
}

async function asObjectiveCClass(type, cluster, options)
{
let pkgId = await templateUtil.ensureZclPackageId(this);
Expand All @@ -139,7 +134,7 @@ async function asObjectiveCClass(type, cluster, options)
}

if (isStruct) {
return `CHIP${asUpperCamelCase(cluster)}Cluster${asUpperCamelCase(type)}`;
return `CHIP${appHelper.asUpperCamelCase(cluster)}Cluster${appHelper.asUpperCamelCase(type)}`;
}

return 'NSNumber';
Expand Down Expand Up @@ -168,6 +163,31 @@ function incrementDepth(depth)
return depth + 1;
}

function asStructPropertyName(prop)
{
prop = appHelper.asLowerCamelCase(prop);

// If prop is now "description", we need to rename it, because that's
// reserved.
if (prop == "description") {
return "descriptionString";
}

// If prop starts with a sequence of capital letters (which can happen for
// output of asLowerCamelCase if the original string started that way,
// lowercase all but the last one.
return prop.replace(/^([A-Z]+)([A-Z])/, (match, p1, p2) => { return p1.toLowerCase() + p2 });
}

function asGetterName(prop)
{
let propName = asStructPropertyName(prop);
if (propName.match(/^new[A-Z]/) || propName == "count") {
return "get" + appHelper.asUpperCamelCase(prop);
}
return propName;
}

//
// Module exports
//
Expand All @@ -180,3 +200,5 @@ exports.asObjectiveCClass = asObjectiveCClass;
exports.asObjectiveCType = asObjectiveCType;
exports.arrayElementObjectiveCClass = arrayElementObjectiveCClass;
exports.incrementDepth = incrementDepth;
exports.asStructPropertyName = asStructPropertyName;
exports.asGetterName = asGetterName;
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void CHIP{{> @partial-block}}Bridge::OnSuccessFn(void * context
{
id value;
{{>decode_value target="value" source=(concat "data." (asLowerCamelCase label)) cluster=parent.parent.name errorCode="OnFailureFn(context, EMBER_ZCL_STATUS_INVALID_VALUE); return;"}}
response[@"{{asUpperCamelCase label}}"] = value;
response[@"{{asStructPropertyName label}}"] = value;
}
{{/chip_cluster_response_arguments}}
DispatchSuccess(context, response);
Expand All @@ -60,16 +60,16 @@ void CHIP{{> @partial-block}}Bridge::OnSuccessFn(void * context
{{! TODO: Add support for nullable types, probably by having a templated ToObjectiveCType function }}
{{else if isArray}}
{{! TODO: Add support for list members of structs in list attributes }}
@"{{asUpperCamelCase name}}": [[NSMutableArray alloc] init],
@"{{asStructPropertyName name}}": [[NSMutableArray alloc] init],
{{else if (isOctetString type)}}
@"{{asUpperCamelCase name}}" : [NSData dataWithBytes:entry.{{asLowerCamelCase name}}.data() length:entry.{{asLowerCamelCase name}}.size()],
@"{{asStructPropertyName name}}" : [NSData dataWithBytes:entry.{{asLowerCamelCase name}}.data() length:entry.{{asLowerCamelCase name}}.size()],
{{else if (isCharString type)}}
@"{{asUpperCamelCase name}}" : [[NSString alloc] initWithBytes:entry.{{asLowerCamelCase name}}.data() length:entry.{{asLowerCamelCase name}}.size() encoding:NSUTF8StringEncoding],
@"{{asStructPropertyName name}}" : [[NSString alloc] initWithBytes:entry.{{asLowerCamelCase name}}.data() length:entry.{{asLowerCamelCase name}}.size() encoding:NSUTF8StringEncoding],
{{else if isStruct}}
{{! TODO: Add support for struct members of structs in list attributes }}
@"{{asUpperCamelCase name}}": @{}
@"{{asStructPropertyName name}}": @{}
{{else}}
@"{{asUpperCamelCase name}}" : [NSNumber numberWith{{asObjectiveCNumberType label type false}}:entry.{{asLowerCamelCase name}}],
@"{{asStructPropertyName name}}" : [NSNumber numberWith{{asObjectiveCNumberType label type false}}:entry.{{asLowerCamelCase name}}],
{{/if}}
{{/chip_attribute_list_entryTypes}}
}];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
{{#if (expectedValueHasProp ../expected (asLowerCamelCase label))}}
{{! TODO: This is a hack because right now some of our return values (attribute reads) are using NSDictionary for structs while others (commands) are using generated object types. Just support both for now. }}
if ([{{../actual}} isKindOfClass:[NSDictionary class]]) {
{{>check_test_value actual=(concat ../actual '[@"' (asUpperCamelCase label) '"]') expected=(lookup ../expected (asLowerCamelCase label)) cluster=../cluster}}
{{>check_test_value actual=(concat ../actual '[@"' (asStructPropertyName label) '"]') expected=(lookup ../expected (asLowerCamelCase label)) cluster=../cluster}}
} else {
{{>check_test_value actual=(concat "[" ../actual (asUpperCamelCase label) "]") expected=(lookup ../expected (asLowerCamelCase label)) cluster=../cluster}}
{{>check_test_value actual=(concat "((CHIP" (asUpperCamelCase ../cluster) "Cluster" (asUpperCamelCase ../type) " *)" ../actual ")." (asStructPropertyName label)) expected=(lookup ../expected (asLowerCamelCase label)) cluster=../cluster}}
}
{{/if}}
{{/zcl_struct_items_by_struct_name}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
{{else}}
{{#if_is_struct type}}
{{#zcl_struct_items_by_struct_name type}}
{{>decode_value target=(concat ../target "." (asUpperCamelCase label)) source=(concat ../source "." (asLowerCamelCase label)) cluster=../cluster}}
{{>decode_value target=(concat ../target "." (asStructPropertyName label)) source=(concat ../source "." (asLowerCamelCase label)) cluster=../cluster}}
{{/zcl_struct_items_by_struct_name}}
{{else if (isOctetString type)}}
{{target}} = [NSData dataWithBytes:{{source}}.data() length:{{source}}.size()];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
{{else}}
{{#if_is_struct type}}
{{#zcl_struct_items_by_struct_name type}}
{{>encode_value target=(concat ../target "." (asLowerCamelCase label)) source=(concat ../source "." (asUpperCamelCase label)) cluster=../cluster errorCode=../errorCode depth=(incrementDepth ../depth)}}
{{>encode_value target=(concat ../target "." (asLowerCamelCase label)) source=(concat ../source "." (asStructPropertyName label)) cluster=../cluster errorCode=../errorCode depth=(incrementDepth ../depth)}}
{{/zcl_struct_items_by_struct_name}}
{{else}}
{{#if_chip_enum type}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ bool testSendCluster{{parent.filename}}_{{asTestIndex index}}_{{asUpperCamelCase
{{#if isCommand}}
__auto_type * payload = [[CHIP{{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase command}}Payload alloc] init];
{{#chip_tests_item_parameters}}
{{>test_value target=(concat "payload." (asUpperCamelCase label)) definedValue=definedValue cluster=parent.cluster}}
{{>test_value target=(concat "payload." (asStructPropertyName label)) definedValue=definedValue cluster=parent.cluster}}
{{/chip_tests_item_parameters}}
[cluster {{asLowerCamelCase command}}:payload responseHandler:^(NSError * err, NSDictionary * values) {
{{else if isSubscribeAttribute}}
Expand Down Expand Up @@ -68,7 +68,7 @@ bool testSendCluster{{parent.filename}}_{{asTestIndex index}}_{{asUpperCamelCase
{{#chip_tests_item_response_parameters}}
{{#if hasExpectedValue}}
{
id actualValue = values[@"{{#if parent.isAttribute}}value{{else}}{{asUpperCamelCase name}}{{/if}}"];
id actualValue = values[@"{{#if parent.isAttribute}}value{{else}}{{asStructPropertyName name}}{{/if}}"];
{{>check_test_value actual="actualValue" expected=expectedValue cluster=../cluster}}
}
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{{#zcl_struct_items_by_struct_name type}}
{{! target may be some place where we lost type information (e.g. an id),
so add explicit cast when trying to assign to our properties. }}
{{>test_value target=(concat "((CHIP" (asUpperCamelCase ../cluster) "Cluster" (asUpperCamelCase ../type) " *)" ../target ")." (asUpperCamelCase label)) definedValue=(lookup ../definedValue name) cluster=../cluster}}
{{>test_value target=(concat "((CHIP" (asUpperCamelCase ../cluster) "Cluster" (asUpperCamelCase ../type) " *)" ../target ")." (asStructPropertyName label)) definedValue=(lookup ../definedValue name) cluster=../cluster}}
{{/zcl_struct_items_by_struct_name}}

{{else if (isCharString type)}}
Expand Down
Loading

0 comments on commit 1359f6e

Please sign in to comment.