Skip to content

Commit 0b9739a

Browse files
committed
Objective-C namespaces support (#273)
* ObjC namespaces support * handle special case for Edm namespace * fix documentation
1 parent 8c6eb63 commit 0b9739a

File tree

114 files changed

+4784
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

114 files changed

+4784
-31
lines changed

Templates/ObjC/Base/SharedObjC.template.tt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ private string GetJsonToObjCExpressionConversionOpenType(OdcmProperty prop)
275275
{
276276
string objCIdentifierType = GetObjCTypeIdentifierCollection(prop);
277277

278-
if(model.GetComplexTypes().Any(complexType => objCIdentifierType.Equals(writer.GetPrefix() + complexType.Name.ToUpperFirstChar())))
278+
if(model.GetComplexTypes().Any(complexType => objCIdentifierType.Equals(writer.GetNamespacePrefixForType(complexType) + complexType.Name.ToUpperFirstChar())))
279279
{
280280
return String.Format("[[{0} alloc] initWithDictionary:value]", objCIdentifierType);
281281
}

Templates/ObjC/Models/ClientModels.h.tt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,23 @@ var enums = model.GetEnumTypes();
1010
foreach(var e in enums)
1111
{
1212
#>
13-
#import "<#=writer.GetPrefix() + e.Name.ToUpperFirstChar()#>.h"
13+
#import "<#=writer.GetNamespacePrefixForType(e) + e.Name.ToUpperFirstChar()#>.h"
1414
<#
1515
}
1616

1717
var complexTypes = model.GetComplexTypes().Where(complexType => !complexType.LongDescriptionContains("methodResponse"));
1818
foreach(var c in complexTypes)
1919
{
2020
#>
21-
#import "<#=writer.GetPrefix() + c.Name.ToUpperFirstChar()#>.h"
21+
#import "<#=writer.GetNamespacePrefixForType(c) + c.Name.ToUpperFirstChar()#>.h"
2222
<#
2323
}
2424

2525
var entityTypes = model.GetEntityTypes();
2626
foreach(var et in entityTypes)
2727
{
2828
#>
29-
#import "<#=writer.GetPrefix() + et.Name.ToUpperFirstChar()#>.h"
29+
#import "<#=writer.GetNamespacePrefixForType(et) + et.Name.ToUpperFirstChar()#>.h"
3030
<#
3131
}
3232

src/GraphODataTemplateWriter/CodeHelpers/ObjC/CodeWriterObjC.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,9 @@ public CodeWriterObjC(OdcmModel model) : base(model)
2121
{
2222
}
2323

24-
public string GetPrefix()
25-
{
26-
return TypeHelperObjC.Prefix;
27-
}
24+
public string GetPrefix() => ConfigurationService.Settings.NamespacePrefix;
25+
26+
public string GetNamespacePrefixForType(OdcmType type) => TypeHelperObjC.GetNamespacePrefixForType(type);
2827

2928
public string GetStaticCodePrefix()
3029
{
@@ -56,15 +55,15 @@ public string GetInterfaceLine(OdcmClass entityType, string baseClass = null)
5655
else
5756
{
5857
baseEntity = entityType.Base == null ? "NSObject"
59-
: this.GetPrefix() + entityType.Base.Name.Substring(entityType.Base.Name.LastIndexOf(".") + 1);
58+
: GetNamespacePrefixForType(entityType.Base) + entityType.Base.Name.Substring(entityType.Base.Name.LastIndexOf(".") + 1);
6059
}
6160
var interfaceLineBuilder = new StringBuilder();
6261
// NSObject lives in Foundation/Foundation.h
6362
var baseImport = (baseEntity.Equals("NSObject")) ? "#import <Foundation/Foundation.h>" : String.Format("#import \"{0}.h\"", baseEntity);
6463
interfaceLineBuilder.AppendLine(baseImport);
6564

6665
interfaceLineBuilder.AppendLine().AppendLine().AppendLine(this.GetHeaderDoc(entityType.Name))
67-
.AppendFormat("@interface {0}{1} : {2}", this.GetPrefix(), entityType.Name.ToUpperFirstChar(), baseEntity);
66+
.AppendFormat("@interface {0}{1} : {2}", GetNamespacePrefixForType(entityType), entityType.Name.ToUpperFirstChar(), baseEntity);
6867

6968
return interfaceLineBuilder.ToString();
7069
}

src/GraphODataTemplateWriter/CodeHelpers/ObjC/TypeHelperObjC.cs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ namespace Microsoft.Graph.ODataTemplateWriter.CodeHelpers.ObjC
88
using Microsoft.Graph.ODataTemplateWriter.Settings;
99
using Vipr.Core.CodeModel;
1010
using NLog;
11+
using System;
1112

1213
public static class TypeHelperObjC
1314
{
14-
public static string Prefix = ConfigurationService.Settings.NamespacePrefix;
15-
1615
private static Logger logger = LogManager.GetCurrentClassLogger();
1716

1817
private static ICollection<string> reservedNames;
@@ -136,8 +135,34 @@ public static string GetTypeString(this OdcmType type)
136135
return "Byte";
137136

138137
default:
139-
return Prefix + type.Name.ToUpperFirstChar();
138+
return GetNamespacePrefixForType(type) + type.Name.ToUpperFirstChar();
139+
}
140+
}
141+
public static string GetNamespacePrefixForType(OdcmType type) => GetNamespacePrefix(type.Namespace.Name);
142+
143+
/// <summary>
144+
/// Constructs a namespace prefix for ObjC types, microsoft.graph is converted into MSGraph and rest of
145+
/// the namespace parts are concatenated with PascalCase.
146+
/// e.g. microsoft.graph.sub1.sub2 is converted into the prefix MSGraphSub1Sub2
147+
/// </summary>
148+
/// <param name="namespace">namespace that will be converted into a prefix</param>
149+
/// <returns>ObjC representation of an Odcm namespace</returns>
150+
public static string GetNamespacePrefix(string @namespace)
151+
{
152+
if (@namespace.Equals("Edm", StringComparison.OrdinalIgnoreCase))
153+
{
154+
return string.Empty;
140155
}
156+
157+
var primaryNamespace = ConfigurationService.Settings.PrimaryNamespaceName; // microsoft.graph
158+
var defaultPrefix = ConfigurationService.Settings.NamespacePrefix; // MSGraph
159+
if (@namespace.Equals(primaryNamespace, StringComparison.OrdinalIgnoreCase))
160+
{
161+
return defaultPrefix;
162+
}
163+
164+
var subNamespace = @namespace.Substring(primaryNamespace.Length + 1); // extract sub1.sub2 from microsoft.graph.sub1.sub2
165+
return defaultPrefix + string.Join(string.Empty, subNamespace.Split('.').Select(x => x.ToPascalize()));
141166
}
142167

143168
public static string GetTypeString(this OdcmProperty property)

src/GraphODataTemplateWriter/PathWriters/ObjCPathWriter.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,22 @@ namespace Microsoft.Graph.ODataTemplateWriter.PathWriters
44
{
55
using System;
66
using System.IO;
7+
using Microsoft.Graph.ODataTemplateWriter.CodeHelpers.ObjC;
78
using Microsoft.Graph.ODataTemplateWriter.Settings;
89
using Microsoft.Graph.ODataTemplateWriter.TemplateProcessor;
910

1011
class ObjCPathWriter : PathWriterBase
1112
{
12-
13-
public override string WritePath(ITemplateInfo template, string entityTypeName)
13+
public override string WritePath(ITemplateInfo template, string @namespace, string entityTypeName)
1414
{
15-
string prefix = ConfigurationService.Settings.NamespacePrefix;
1615
string coreFileName = this.TransformFileName(template, entityTypeName);
16+
string prefix = TypeHelperObjC.GetNamespacePrefix(@namespace);
17+
return Path.Combine(template.OutputParentDirectory, prefix + coreFileName);
18+
}
1719

18-
return Path.Combine(
19-
template.OutputParentDirectory,
20-
String.Format("{0}{1}",
21-
prefix,
22-
coreFileName
23-
)
24-
);
20+
public override string WritePath(ITemplateInfo template, string entityTypeName)
21+
{
22+
return WritePath(template, ConfigurationService.Settings.PrimaryNamespaceName, entityTypeName);
2523
}
2624

2725
}

test/Typewriter.Test/MultipleNamespacesTestRunner.cs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ public enum TestLanguage
1313
CSharp,
1414
Java,
1515
TypeScript,
16-
PHP
16+
PHP,
17+
ObjC
1718
}
1819

1920
public static class MultipleNamespacesTestRunner
@@ -26,7 +27,7 @@ public static class MultipleNamespacesTestRunner
2627
private const string MetadataMultipleNamespacesFile = "MetadataMultipleNamespaces.xml";
2728

2829
// contains microsoft.graph and microsoft.graph.callRecords
29-
// TypeScript and PHP rely on the assumption that all namespaces will be a subnamespace to microsoft.graph
30+
// TypeScript, ObjC and PHP rely on the assumption that all namespaces will be a subnamespace to microsoft.graph
3031
// and generation process creates a single file with nested namespaces
3132
private const string MetadataWithSubNamespacesFile = "MetadataWithSubNamespaces.xml";
3233

@@ -44,6 +45,8 @@ string getMetadataFile(TestLanguage testLanguage)
4445
return MetadataWithSubNamespacesFile;
4546
case TestLanguage.PHP:
4647
return MetadataWithSubNamespacesFile;
48+
case TestLanguage.ObjC:
49+
return MetadataWithSubNamespacesFile;
4750
default:
4851
throw new ArgumentException("unexpected test language", nameof(testLanguage));
4952
}
@@ -136,26 +139,32 @@ private static void CompareFiles(StringBuilder testOutputBuilder, string expecte
136139
/// <returns></returns>
137140
private static IEnumerable<(string, string)> GetFilePaths(TestLanguage language, string dataDirectory, string testDataDirectoryName, string outputDirectoryName)
138141
{
139-
string extension = string.Empty;
142+
HashSet<string> extensions = new HashSet<string>();
140143
switch (language)
141144
{
142145
case TestLanguage.CSharp:
143-
extension = "*.cs";
146+
extensions.Add(".cs");
144147
break;
145148
case TestLanguage.Java:
146-
extension = "*.java";
149+
extensions.Add(".java");
147150
break;
148151
case TestLanguage.TypeScript:
149-
extension = "*.ts";
152+
extensions.Add(".ts");
150153
break;
151154
case TestLanguage.PHP:
152-
extension = "*.php";
155+
extensions.Add(".php");
156+
break;
157+
case TestLanguage.ObjC:
158+
extensions.Add(".m");
159+
extensions.Add(".h");
153160
break;
154161
default:
155162
throw new ArgumentException("unexpected test language", nameof(language));
156163
}
157164

158-
return from file in new DirectoryInfo(dataDirectory).GetFiles(extension, SearchOption.AllDirectories)
165+
return from file in new DirectoryInfo(dataDirectory)
166+
.EnumerateFiles("*", SearchOption.AllDirectories)
167+
.Where(f => extensions.Contains(f.Extension))
159168
let actualOutputFilePath = file.FullName.Replace(testDataDirectoryName, outputDirectoryName)
160169
let expectedFilePath = file.FullName
161170
select (expectedFilePath, actualOutputFilePath);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
3+
namespace Typewriter.Test
4+
{
5+
[TestClass]
6+
public class ObjCMultipeNamespacesTests
7+
{
8+
[TestMethod]
9+
public void Test()
10+
{
11+
MultipleNamespacesTestRunner.Run(TestLanguage.ObjC);
12+
}
13+
}
14+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
2+
3+
4+
5+
6+
#import "MSGraphEntity.h"
7+
8+
@interface MSGraphCall : MSGraphEntity
9+
10+
@property (nullable, nonatomic, setter=setSubject:, getter=subject) NSString* subject;
11+
12+
@end
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
2+
3+
4+
5+
#import "NSDate+MSSerialization.h"
6+
7+
#import "MSGraphClientModels.h"
8+
9+
@interface MSObject()
10+
11+
@property (strong, nonatomic) NSMutableDictionary *dictionary;
12+
13+
@end
14+
15+
@interface MSGraphCall()
16+
{
17+
NSString* _subject;
18+
}
19+
@end
20+
21+
@implementation MSGraphCall
22+
23+
- (id) init
24+
{
25+
if (self = [super init]) {
26+
self.oDataType = @"#microsoft.graph.call";
27+
}
28+
return self;
29+
}
30+
- (NSString*) subject
31+
{
32+
if([[NSNull null] isEqual:self.dictionary[@"subject"]])
33+
{
34+
return nil;
35+
}
36+
return self.dictionary[@"subject"];
37+
}
38+
39+
- (void) setSubject: (NSString*) val
40+
{
41+
self.dictionary[@"subject"] = val;
42+
}
43+
44+
45+
@end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
2+
3+
4+
@class MSGraphIdentitySet, MSGraphCallRecordsSession, MSGraphEntityType2;
5+
#import "MSGraphCallRecordsCallType.h"
6+
#import "MSGraphCallRecordsModality.h"
7+
8+
9+
#import "MSGraphEntity.h"
10+
11+
@interface MSGraphCallRecordsCallRecord : MSGraphEntity
12+
13+
@property (nonatomic, setter=setVersion:, getter=version) int64_t version;
14+
@property (nonnull, nonatomic, setter=setType:, getter=type) MSGraphCallRecordsCallType* type;
15+
@property (nonnull, nonatomic, setter=setModalities:, getter=modalities) NSArray* modalities;
16+
@property (nonnull, nonatomic, setter=setLastModifiedDateTime:, getter=lastModifiedDateTime) NSDate* lastModifiedDateTime;
17+
@property (nonnull, nonatomic, setter=setStartDateTime:, getter=startDateTime) NSDate* startDateTime;
18+
@property (nonnull, nonatomic, setter=setEndDateTime:, getter=endDateTime) NSDate* endDateTime;
19+
@property (nullable, nonatomic, setter=setOrganizer:, getter=organizer) MSGraphIdentitySet* organizer;
20+
@property (nullable, nonatomic, setter=setParticipants:, getter=participants) NSArray* participants;
21+
@property (nullable, nonatomic, setter=setJoinWebUrl:, getter=joinWebUrl) NSString* joinWebUrl;
22+
@property (nullable, nonatomic, setter=setSessions:, getter=sessions) NSArray* sessions;
23+
@property (nullable, nonatomic, setter=setRecipients:, getter=recipients) NSArray* recipients;
24+
25+
@end

0 commit comments

Comments
 (0)