swift_republic 0.0.0

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/swift_republic.rb +230 -0
  3. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 17bc36b0374dd04497f6e0c137937baebb511f50
4
+ data.tar.gz: f95875307a577cfabda77181852e096ece0a5cce
5
+ SHA512:
6
+ metadata.gz: e0837d110dfe626689cb7a1f163d2b58a7ce9bb6219c4aa4985231ff28127f5d2646d0fcb4ed3ab549e39d197bc39581034d66384c72be3250997401c5686b6e
7
+ data.tar.gz: 6fe174025d66968c908f6aa5e47e518d69923b87176531ce15f14e9d834c7db328ad8a9ae4b8f30112acf1bae9c190dd7b4b719fd252c44ecca478e5dc5927e0
@@ -0,0 +1,230 @@
1
+ # require 'pry'
2
+
3
+ #################################################################################
4
+
5
+ class Property
6
+ attr_accessor :associated_struct, :declaration_String
7
+ attr_accessor :name, :type, :leading_spaces_count
8
+
9
+ def initialize(struct, declaration_String)
10
+ @associated_struct = struct
11
+ indent_offset = declaration_String =~ /\S/ # Any non-whitespace character
12
+ @leading_spaces_count = indent_offset
13
+ @declaration_String = declaration_String.strip # Eg. "var sourceOfIncome: String"
14
+
15
+ if declaration_String.include? ":"
16
+ arr = declaration_String.split(":")
17
+ name = arr.first.split(" ").last
18
+ @name = name
19
+ right_of_first_colon = arr.drop(1).join(":").strip
20
+ @type = right_of_first_colon.split("//").first.strip
21
+ else
22
+ @name = ""
23
+ @type = ""
24
+ p "Inferred types cannot be handled by the script --> #{declaration_String}"
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+ def create_initializer(properties_array)
31
+
32
+ initStr = "\n"
33
+ padding = " " * properties_array.first.leading_spaces_count # or use initStr.rjust(leading_spaces_count)
34
+ initStr += padding
35
+ initStr += "public init("
36
+
37
+ # loop once to create "init(p1, p2, p3, ...) {"
38
+ last_index = properties_array.size - 1
39
+ properties_array.each_with_index { |property, index|
40
+ initStr += property.name
41
+ initStr += ": "
42
+ initStr += property.type
43
+
44
+ if index == last_index
45
+ initStr += ") {\n"
46
+ else
47
+ initStr += ", "
48
+ end
49
+ }
50
+
51
+ # loop again to append "self.p1 = p1\n"
52
+ properties_array.each { |property|
53
+ initStr += "#{padding} self.#{property.name} = #{property.name}\n"
54
+ }
55
+
56
+ # append "}"
57
+ initStr += "#{padding}}"
58
+
59
+ # return string.
60
+ initStr
61
+ end
62
+
63
+ #################################################################################
64
+
65
+ public
66
+ def make_models_public(source_file, destination_file, reserved_keywords = [])
67
+ # source_file = "/A/B/C/D.swift"
68
+ # destination_file = "/W/X/Y/Z.swift"
69
+
70
+ lines = []
71
+ bracket_stack = Array.new # keeps track of brackets... they must be balanced.
72
+ struct_stack = Array.new # keeps track of latest struct containing current line.
73
+ property_stack = Array.new
74
+ protocol_stack = Array.new
75
+ can_update_property_scope = false # helps in skipping updates to local variables.
76
+ can_update_function_scope = true # helps in skipping updates to func inside protocols.
77
+ # reserved_keywords = ["reserved_keywords or file names"] # skip ENTIRE FILES containing these keywords.
78
+
79
+ file_name = File.basename(source_file)
80
+ p "Parsing #{file_name} to output --> #{destination_file}"
81
+
82
+ dirname = File.dirname(destination_file)
83
+ unless File.directory?(dirname)
84
+ FileUtils.mkdir_p(dirname)
85
+ end
86
+
87
+ t_file = File.new(destination_file, "w")
88
+
89
+ File.open(source_file) { |file|
90
+ lines = file.readlines
91
+ }
92
+
93
+ lines.each_with_index { |line, source_line_number|
94
+ indent_offset = line =~ /\S/
95
+
96
+ if reserved_keywords.any? { |keyword| line.include? keyword }
97
+ t_file.close
98
+ p "Could NOT parse #{file_name}. Dependencies/restricted keywords detected in line number #{source_line_number}: #{line}"
99
+ File.delete(destination_file)
100
+ break
101
+
102
+ elsif (line.include? "private") || (line.include? "fileprivate") || (line.include? "public")
103
+ if (line.include? "\{")
104
+ if not (line.include? "\}")
105
+ bracket_stack.push "other"
106
+ end
107
+ end
108
+ t_file.puts "#{line}"
109
+ # Script is intended to handle only "internal" for now.
110
+
111
+ elsif line.strip.start_with?("\/\/")
112
+ # commented out code
113
+ t_file.puts "#{line}"
114
+ # pending check for /* XXX */
115
+
116
+ elsif (line.include? "struct") && (line.include? "\{")
117
+ line["struct"] = "public struct"
118
+ t_file.puts "#{line}"
119
+ bracket_stack.push "#{line}"
120
+ struct_stack.push "#{line}"
121
+
122
+ elsif (line.include? "enum") && (line.include? "\{")
123
+ line["enum"] = "public enum"
124
+ t_file.puts "#{line}"
125
+ bracket_stack.push line # doesn't need initilizer.
126
+
127
+ elsif (line.include? "protocol ") && (line.include? "\{")
128
+ line["protocol"] = "public protocol"
129
+ t_file.puts "#{line}"
130
+ bracket_stack.push line
131
+ protocol_stack.push line
132
+
133
+ elsif line.include? " func "
134
+ if can_update_function_scope # if NOT in protocol:
135
+ line["func"] = "public func"
136
+ end
137
+ if line.include? "\{"
138
+ bracket_stack.push line
139
+ end
140
+ t_file.puts "#{line}"
141
+
142
+ elsif can_update_property_scope && (line.strip.start_with?("let"))
143
+ property_details = Property.new(struct_stack.last, line)
144
+ property_stack.push property_details
145
+ line.insert indent_offset, "public "
146
+ t_file.puts "#{line}"
147
+
148
+ elsif can_update_property_scope && (line.strip.start_with?("var"))
149
+ property_details = Property.new(struct_stack.last, line)
150
+ if line.strip.end_with?("\{")
151
+ # computed property:
152
+ bracket_stack.push line
153
+ else
154
+ property_stack.push property_details
155
+ end
156
+ line.insert indent_offset, "public "
157
+ t_file.puts "#{line}"
158
+
159
+ elsif can_update_property_scope && (line.strip.start_with?("static"))
160
+ line.insert indent_offset, "public "
161
+ t_file.puts "#{line}"
162
+ if (line.include? "\{")
163
+ if not (line.include? "\}")
164
+ bracket_stack.push "other"
165
+ end
166
+ end
167
+
168
+ elsif line.strip.start_with?("init(")
169
+ line["init("] = "public init("
170
+ if (line.include? "\{")
171
+ if not (line.include? "\}")
172
+ bracket_stack.push "other"
173
+ end
174
+ end
175
+ t_file.puts "#{line}"
176
+
177
+ elsif (line.include? "\{") # Eg. guard statements, etc.
178
+ if not (line.include? "\}")
179
+ bracket_stack.push "other"
180
+ end
181
+ t_file.puts "#{line}"
182
+
183
+ elsif (line.strip.length == 1) && (line.include? "\}")
184
+ # If end of struct, add its initializer.
185
+ top_object = bracket_stack.pop
186
+ if can_update_property_scope && (top_object.include? "struct")
187
+ latest_struct = struct_stack.pop
188
+ properties_array = Array.new
189
+
190
+ while (property_stack.size > 0) && (property_stack.last.associated_struct == latest_struct)
191
+ current_property = property_stack.pop
192
+ properties_array.push current_property
193
+ end
194
+
195
+ if properties_array.size > 0
196
+ # for structs which have both req and response inner structs
197
+ # i.e. skip structs with no properties.
198
+ struct_initializer = create_initializer(properties_array.reverse!)
199
+ t_file.puts struct_initializer
200
+ end
201
+
202
+ t_file.puts "#{line}"
203
+ # binding.pry
204
+ elsif top_object.include? "protocol"
205
+ protocol_stack.pop
206
+ t_file.puts "#{line}"
207
+ else
208
+ t_file.puts "#{line}"
209
+ end
210
+
211
+ elsif (line.include? "\}")
212
+ bracket_stack.pop
213
+ t_file.puts "#{line} <<--Please fix formatting there, and run again."
214
+
215
+ else
216
+ t_file.puts "#{line}"
217
+ end
218
+
219
+ can_update_property_scope = (struct_stack.size > 0) && ((bracket_stack.last.include? "struct") || (bracket_stack.last.include? "enum")) # skip func and protocol
220
+ can_update_function_scope = (protocol_stack.size == 0) # func in protocol are not to be made public.
221
+ }
222
+
223
+ t_file.close
224
+ end
225
+
226
+ public
227
+ def make_models_public_test(source_file, destination_file)
228
+ p source_file
229
+ p destination_file
230
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: swift_republic
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mehul M. Parmar
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-01-01 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem that helps make swift data models publicly accessible, and generate
14
+ default initializers for structs
15
+ email: mehulparmar078@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/swift_republic.rb
21
+ homepage: http://rubygems.org/gems/hola
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - ">="
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.5.2.3
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Makes swift data models publicly accessible, and generate default initializers
45
+ for structs
46
+ test_files: []