ObjCGenerator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []