ObjCGenerator 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c1dc238605c220a535ee63afe585c956dbbbc1cd
4
+ data.tar.gz: 3e19101c22da3256f160b700daab9dee88c3145c
5
+ SHA512:
6
+ metadata.gz: af189b52e97e4145c16cfa71402e3edbd4a3abd43685f247333708e0b4e095fc8efba04754940853abf4ed31a8bd80ad743b7d6dab6e117e5162ac541d16d8eb
7
+ data.tar.gz: a785bf33caefa66e04ef46ab2505e2bc8e32196710bfbaa5d9ca56ee14193c37b42342bb02f9923faa52827eefea7ca92119953e3c56ad2d2c90eb03cc707844
data/bin/api_desc.json ADDED
@@ -0,0 +1,24 @@
1
+ [
2
+ {
3
+ "name": "SampleClass",
4
+ "type": "Class",
5
+ "vars": [
6
+ {
7
+ "name": "someBool",
8
+ "type": "Bool"
9
+ },
10
+ {
11
+ "name": "someInt",
12
+ "type": "Int"
13
+ },
14
+ {
15
+ "name": "someFloat",
16
+ "type": "Float"
17
+ },
18
+ {
19
+ "name": "someStr",
20
+ "type": "String"
21
+ }
22
+ ]
23
+ }
24
+ ]
data/bin/objcgenerator ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
4
+
5
+ require 'ObjCGenerator'
6
+
7
+
8
+ filename = "api_desc.json"
9
+ file = open(filename)
10
+ json = file.read
11
+
12
+ ObjCGenerator::Command.run json, Dir.pwd
@@ -0,0 +1,16 @@
1
+ require "json"
2
+ require "ObjCGenerator/version"
3
+ require "ObjCGenerator/command"
4
+ require "ObjCGenerator/types"
5
+ require "ObjCGenerator/class_implementation"
6
+ require "ObjCGenerator/test"
7
+
8
+ module Enumerable
9
+ def intersperse(obj=nil)
10
+ map {|el| [obj, el] }.flatten(1).drop(1)
11
+ end
12
+ end
13
+
14
+ module ObjCGenerator
15
+
16
+ end
@@ -0,0 +1,203 @@
1
+
2
+ module ObjCGenerator
3
+
4
+ def self.vertical_align_vars (strings , regexp, index)
5
+ max_lengt = strings.map { | str|
6
+ str.split(regexp)[0..index].join.length
7
+ }.max
8
+
9
+ result = strings.map { |str|
10
+ arr = str.split(regexp)
11
+ arr[0..index].join.ljust(max_lengt , ' ') + arr[index+1..arr.length].join
12
+ }
13
+ result
14
+ end
15
+
16
+ def self.class_implementation (class_name, vars)
17
+ text = "#import \"#{class_name}.h\"" + "\n" +
18
+ "" + "\n" +
19
+ "@implementation #{class_name}" + "\n" +
20
+ "" + "\n" +
21
+ "#{init_method vars}" + "\n" +
22
+ "" + "\n" +
23
+ "#{init_with_dict_method vars}" + "\n" +
24
+ "" + "\n" +
25
+ "#{class_init_with_dict class_name}" + "\n" +
26
+ "" + "\n" +
27
+ "#{to_dict_method vars}" + "\n" +
28
+ "" + "\n" +
29
+ "#{is_equals_method class_name}" + "\n" +
30
+ "" + "\n" +
31
+ "#{is_equals_to_Object_method class_name, vars}" + "\n" +
32
+ "" + "\n" +
33
+ "#{hash_method}" + "\n" +
34
+ "" + "\n" +
35
+ "#{description_method vars}" + "\n" +
36
+ "" + "\n" +
37
+ "#{copy_method class_name, vars}" + "\n" +
38
+ "" + "\n" +
39
+ "@end" + "\n" +
40
+ ""
41
+ end
42
+
43
+ def self.copy_method(class_name, vars)
44
+ t = class_name.dup
45
+ t[0] = t[0].chr.downcase
46
+ newName = "#{t}Copy"
47
+ text = "- (instancetype)copyWithZone:(NSZone *)zone {" + "\n" +
48
+ " #{class_name} *#{newName} = [[[self class] allocWithZone:zone] init];" + "\n" +
49
+ " #{copy_rows vars, newName}" + "\n" +
50
+ " return #{newName};" + "\n" +
51
+ "}"
52
+ end
53
+
54
+ def self.copy_rows vars, newVarName
55
+ result = []
56
+ vars.each do |var|
57
+ r = var.copyrow newVarName
58
+ result << r
59
+ end
60
+
61
+ result = vertical_align_vars result, /( = )/, 0
62
+ # result = vertical_align_vars result, /( , )/, 0
63
+ result = result.intersperse("\n ")
64
+ result.inject("") { |mem, var| mem << var }
65
+ end
66
+
67
+ def self.description_method vars
68
+ text = "- (NSString *)description {" + "\n" +
69
+ " NSString *params = [@[" + "\n" +
70
+ " #{description_rows vars}" + "\n" +
71
+ " ] componentsJoinedByString:@\", \"" + "\n" +
72
+ " ];" + "\n" +
73
+ " return [NSString stringWithFormat:@\"%@ { %@ }\", NSStringFromClass([self class]), params];" + "\n" +
74
+ "}"
75
+ end
76
+
77
+ def self.description_rows vars
78
+ result = []
79
+ vars.each do |var|
80
+ r = "[NSString stringWithFormat:#{var.description_row}]"
81
+ result << r
82
+ end
83
+
84
+ result = vertical_align_vars result, /( = )/, 0
85
+ result = vertical_align_vars result, /( , )/, 0
86
+ result = result.intersperse("\n , ")
87
+ result.inject("") { |mem, var| mem << var }
88
+ end
89
+
90
+ def self.hash_method
91
+ text = "- (NSUInteger)hash {" + "\n" +
92
+ " return [[self description] hash];" + "\n" +
93
+ "}"
94
+ end
95
+
96
+ def self.is_equals_method class_name
97
+ text = "- (BOOL)isEqual:(id)object {" + "\n" +
98
+ " if (self == object) { return true; }" + "\n" +
99
+ " else if ([object isKindOfClass:[self class]]) {" + "\n" +
100
+ " return [self isEqualTo#{class_name}:object];" + "\n" +
101
+ " }" + "\n" +
102
+ " else { return NO; }" + "\n" +
103
+ "}"
104
+ end
105
+
106
+ def self.is_equals_to_Object_method (class_name, vars)
107
+ text = "- (BOOL)isEqualTo#{class_name}:(#{class_name} *)other {" + "\n" +
108
+ " if (self == other) return YES;" + "\n" +
109
+ " #{equality_rows vars}" + "\n" +
110
+ " return YES;" + "\n" +
111
+ "}"
112
+ end
113
+
114
+ def self.equality_rows vars
115
+ result = []
116
+ vars.each do |var|
117
+ r = "if (#{var.inEquality_test("other")}) return NO;"
118
+ result << r
119
+ end
120
+
121
+ result = vertical_align_vars result, /( )/, 0
122
+ result = vertical_align_vars result, /(\) )/, 0
123
+ result = result.intersperse("\n ")
124
+ result.inject("") { |mem, var| mem << var }
125
+ end
126
+
127
+ def self.to_dict_method vars
128
+ text = "- (NSDictionary *)toDict {" + "\n" +
129
+ " return @{" + "\n" +
130
+ " #{value_to_dict vars}" + "\n" +
131
+ " };" + "\n" +
132
+ "}"
133
+ end
134
+
135
+ def self.value_to_dict vars
136
+ result = []
137
+ vars.each do |var|
138
+ r = var.to_dictionary_item
139
+ result << r
140
+ end
141
+ result = vertical_align_vars result, /( : )/, 0
142
+ result = vertical_align_vars result, /( \?: )/, 0
143
+ result = result.intersperse("\n , ")
144
+
145
+ result.inject("") { |mem, var| mem << var }
146
+ end
147
+
148
+ def self.class_init_with_dict class_name
149
+ t = class_name.dup
150
+ t[0] = t[0].chr.downcase
151
+ text = "+ (instancetype)#{t}WithDict:(NSDictionary *)dict {" + "\n" +
152
+ " return [[self alloc] initWithDict:dict];" + "\n" +
153
+ "}"
154
+ end
155
+
156
+ def self.init_with_dict_method vars
157
+ text = "- (instancetype)initWithDict:(NSDictionary *)dict {" + "\n" +
158
+ " if ((self = [self init])) {" + "\n" +
159
+ " id val = nil;" + "\n" +
160
+ " #{init_values vars}" + "\n" +
161
+ " }" + "\n" +
162
+ " return self;" + "\n" +
163
+ "}"
164
+ end
165
+
166
+ def self.init_values vars
167
+ result = []
168
+ vars.each do |var|
169
+ conversion_type = var.conversion_value("val")
170
+ result << "if ((val = dict[@\"#{var.varname}\"])) { _#{var.varname} = #{conversion_type}; } else { NSLog(@\"Error initWithDict: Unable to find: #{var.varname}\"); }"
171
+ end
172
+ result = vertical_align_vars result, /(\)\))/, 1
173
+ result = vertical_align_vars result, /( = )/, 2
174
+ result = vertical_align_vars result, /( } )/, 0
175
+ result = result.intersperse("\n ")
176
+
177
+ result.inject("") { |mem, var| mem << var }
178
+ end
179
+
180
+
181
+ def self.init_method vars
182
+ text = "- (instancetype)init {" + "\n" +
183
+ " if ((self = [super init])) {" + "\n" +
184
+ "#{default_values vars}" + "\n" +
185
+ " }" + "\n" +
186
+ " return self;" + "\n" +
187
+ "}"
188
+
189
+ end
190
+
191
+
192
+ def self.default_values vars
193
+ result = []
194
+ vars.each do |var|
195
+ result << " _#{var.varname} = #{var.default_value};"
196
+ end
197
+ result = vertical_align_vars result, /( = )/, 0
198
+ result = result.intersperse("\n")
199
+
200
+ result.inject("") { |mem, var| mem << var }
201
+ end
202
+
203
+ end
@@ -0,0 +1,92 @@
1
+ module ObjCGenerator
2
+ class Command
3
+
4
+ def self.vertical_align strings
5
+ max_lengt = strings.map { | str|
6
+ c = str.rpartition(" ").first.length
7
+ }.max
8
+
9
+ result = strings.map { |str|
10
+ l = str.rpartition(" ").last.start_with?("*") ? max_lengt : max_lengt+1
11
+ str.rpartition(" ").first.ljust(l , ' ') + str.rpartition(" ").last
12
+ }
13
+ result
14
+ end
15
+
16
+ def self.class_header (class_name, vars)
17
+ @text = "#import <Foundation/Foundation.h>" + "\n" +
18
+ "" + "\n" +
19
+ "@interface #{class_name} : NSObject <NSCopying>" + "\n" +
20
+ "" + "\n" +
21
+ "#{class_properties vars}" + "\n" +
22
+ "" + "\n" +
23
+ "#{class_methods class_name}" + "\n" +
24
+ "" + "\n" +
25
+ "@end" + "\n" +
26
+ "" + "\n" +
27
+ ""
28
+ end
29
+ def self.class_properties vars
30
+ result = []
31
+
32
+ vars.each do |var|
33
+ result << var.property_definition
34
+ end
35
+
36
+ result = vertical_align result
37
+ result = result.intersperse("\n")
38
+
39
+ result.inject("") { |mem, var| mem << var }
40
+ end
41
+
42
+ def self.class_methods class_name
43
+ t = class_name.dup
44
+ t[0] = t[0].chr.downcase
45
+ @text = "- (instancetype)init;" + "\n" +
46
+ "- (instancetype)initWithDict:(NSDictionary *)dict;" + "\n" +
47
+ "+ (instancetype)#{t}WithDict:(NSDictionary *)dict;" + "\n" +
48
+ "- (NSDictionary *)toDict;" + "\n" +
49
+ "" + "\n" +
50
+ "- (BOOL)isEqual:(id)object;" + "\n" +
51
+ "- (BOOL)isEqualTo#{class_name}:(#{class_name} *)other;" + "\n" +
52
+ "- (NSUInteger)hash;" + "\n" +
53
+ "- (NSString *)description;" + "\n" +
54
+ "- (instancetype)copyWithZone:(NSZone *)zone;"
55
+ end
56
+
57
+ def self.run input_file, output_dir
58
+
59
+ parsed = JSON.parse(input_file)
60
+
61
+ parsed.each do |var|
62
+ if var["type"] == "Class"
63
+ vars = var["vars"].map { |hash|
64
+ case hash["type"]
65
+ when "Bool"
66
+ TypeBool.new(hash["name"])
67
+ when "Int"
68
+ TypeInt.new(hash["name"])
69
+ when "Float"
70
+ TypeFloat.new(hash["name"])
71
+ when "String"
72
+ TypeString.new(hash["name"])
73
+ when "Date"
74
+ TypeDate.new(hash["name"])
75
+ end
76
+ }
77
+
78
+ header = class_header var["name"], vars
79
+ File.open( output_dir + "/#{var["name"]}.h", 'w') { |file| file.write(header) }
80
+
81
+ implementation = ObjCGenerator::class_implementation var["name"], vars
82
+ File.open( output_dir + "/#{var["name"]}.m", 'w') { |file| file.write(implementation) }
83
+
84
+ # ObjCGenerator::testa(var["name"])
85
+ end
86
+ end
87
+
88
+
89
+
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,17 @@
1
+ module ObjCGenerator
2
+
3
+ def self.testa (class_name)
4
+ if (File.read(File.dirname(__FILE__) + "/output/#{class_name}.h") == File.read("golden_master/#{class_name}.h"))
5
+ puts "**** TEST HEADER SUCCESS ****"
6
+ else
7
+ puts "[[[[ TEST HEADER FAILED ]]]]"
8
+ end
9
+
10
+ if (File.read(File.dirname(__FILE__) + "/output/#{class_name}.m") == File.read("golden_master/#{class_name}.m"))
11
+ puts "**** TEST IMPLEMENTATION SUCCESS ****"
12
+ else
13
+ puts "[[[[ TEST IMPLEMENTATION FAILED ]]]]"
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,153 @@
1
+ class ObjCType
2
+ attr_accessor :varname
3
+ def initialize( name )
4
+ @varname = name
5
+ end
6
+ def property_definition
7
+ "-subcalss-"
8
+ end
9
+ def default_value
10
+ "-subcalss-"
11
+ end
12
+ def conversion_value origin
13
+ "-subcalss-"
14
+ end
15
+ def to_dictionary_item
16
+ "-subcalss-"
17
+ end
18
+ def inEquality_test other
19
+ "-subcalss-"
20
+ end
21
+ def description_row
22
+ "-subcalss-"
23
+ end
24
+ def copyrow newVarName
25
+ "-subcalss-"
26
+ end
27
+ end
28
+
29
+ class TypeBool < ObjCType
30
+ attr_accessor :varname
31
+ def property_definition
32
+ "@property (nonatomic) BOOL #{@varname};"
33
+ end
34
+ def default_value
35
+ "NO"
36
+ end
37
+
38
+ def conversion_value origin
39
+ "[#{origin} boolValue]"
40
+ end
41
+ def to_dictionary_item
42
+ "@\"#{@varname}\" : @(self.#{@varname}) ?: @(YES)"
43
+ end
44
+ def inEquality_test other
45
+ "self.#{self.varname} != #{other}.#{self.varname}"
46
+ end
47
+ def description_row
48
+ "@\"self.#{self.varname} = %@\" , self.#{self.varname} ? @\"YES\" : @\"NO\""
49
+ end
50
+ def copyrow newVarName
51
+ "#{newVarName}.#{self.varname} = self.#{self.varname};"
52
+ end
53
+ end
54
+
55
+ class TypeInt < ObjCType
56
+ attr_accessor :varname
57
+ def property_definition
58
+ "@property (nonatomic) NSInteger #{@varname};"
59
+ end
60
+ def default_value
61
+ "0"
62
+ end
63
+ def conversion_value origin
64
+ "[#{origin} integerValue]"
65
+ end
66
+ def to_dictionary_item
67
+ "@\"#{@varname}\" : @(self.#{@varname}) ?: @(0)"
68
+ end
69
+ def inEquality_test other
70
+ "self.#{self.varname} != #{other}.#{self.varname}"
71
+ end
72
+ def description_row
73
+ "@\"self.#{self.varname} = %zd\" , self.#{self.varname}"
74
+ end
75
+ def copyrow newVarName
76
+ "#{newVarName}.#{self.varname} = self.#{self.varname};"
77
+ end
78
+ end
79
+
80
+ class TypeFloat < ObjCType
81
+ attr_accessor :varname
82
+ def property_definition
83
+ "@property (nonatomic) double #{@varname};"
84
+ end
85
+ def default_value
86
+ "0."
87
+ end
88
+ def conversion_value origin
89
+ "[#{origin} doubleValue]"
90
+ end
91
+ def to_dictionary_item
92
+ "@\"#{@varname}\" : @(self.#{@varname}) ?: @(0.)"
93
+ end
94
+ def inEquality_test other
95
+ "self.#{self.varname} != #{other}.#{self.varname}"
96
+ end
97
+ def description_row
98
+ "@\"self.#{self.varname} = %lf\" , self.#{self.varname}"
99
+ end
100
+ def copyrow newVarName
101
+ "#{newVarName}.#{self.varname} = self.#{self.varname};"
102
+ end
103
+ end
104
+
105
+ class TypeString < ObjCType
106
+ attr_accessor :varname
107
+ def property_definition
108
+ "@property (nonatomic) NSString *#{@varname};"
109
+ end
110
+ def default_value
111
+ "@\"\""
112
+ end
113
+ def conversion_value origin
114
+ "[#{origin} description]"
115
+ end
116
+ def to_dictionary_item
117
+ "@\"#{@varname}\" : self.#{@varname} ?: @\"\""
118
+ end
119
+ def inEquality_test other
120
+ "![self.#{self.varname} isEqual:#{other}.#{self.varname}]"
121
+ end
122
+ def description_row
123
+ "@\"self.#{self.varname} = %@\" , self.#{self.varname}"
124
+ end
125
+ def copyrow newVarName
126
+ "#{newVarName}.#{self.varname} = [self.#{self.varname} copy];"
127
+ end
128
+ end
129
+
130
+ class TypeDate < ObjCType
131
+ attr_accessor :varname
132
+ def property_definition
133
+ "@property (nonatomic) NSDate *#{@varname};"
134
+ end
135
+ def default_value
136
+ "[NSDate date]"
137
+ end
138
+ def conversion_value origin
139
+ ""
140
+ end
141
+ def to_dictionary_item
142
+ "@\"#{@varname}\" : self.#{@varname} ?: [NSDate date]"
143
+ end
144
+ def inEquality_test other
145
+ "![self.#{self.varname} isEqual:#{other}.#{self.varname}]"
146
+ end
147
+ def description_row
148
+ "@\"self.#{self.varname} = %@\" , self.#{self.varname}"
149
+ end
150
+ def copyrow newVarName
151
+ "#{newVarName}.#{self.varname} = [self.#{self.varname} copy];"
152
+ end
153
+ end
@@ -0,0 +1,3 @@
1
+ module ObjCGenerator
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ObjCGenerator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ignazio Calò
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - ignazioc@gmail.com
44
+ executables:
45
+ - objcgenerator
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - bin/api_desc.json
50
+ - bin/objcgenerator
51
+ - lib/ObjCGenerator.rb
52
+ - lib/ObjCGenerator/class_implementation.rb
53
+ - lib/ObjCGenerator/command.rb
54
+ - lib/ObjCGenerator/test.rb
55
+ - lib/ObjCGenerator/types.rb
56
+ - lib/ObjCGenerator/version.rb
57
+ homepage: ''
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - '>='
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.4.6
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: This ruby script generates Objective-C code based on a json description
81
+ test_files: []