brain_damage 0.1.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 (215) hide show
  1. checksums.yaml +7 -0
  2. data/.byebug_history +32 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +4 -0
  6. data/CODE_OF_CONDUCT.md +13 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +41 -0
  10. data/Rakefile +6 -0
  11. data/app/assets/javascripts/ajax_delete.js.coffee +14 -0
  12. data/app/assets/javascripts/ajax_form.js.coffee +94 -0
  13. data/app/assets/javascripts/autocomplete-input.js.coffee +43 -0
  14. data/app/assets/javascripts/autocomplete-list.js.coffee +41 -0
  15. data/app/assets/javascripts/autocomplete-simple-select.js.coffee +39 -0
  16. data/app/assets/javascripts/autocomplete.js.coffee +17 -0
  17. data/app/assets/javascripts/brain_damage.js +3 -0
  18. data/app/assets/javascripts/datepicker.js.coffee +49 -0
  19. data/app/assets/javascripts/document_validity_input.js.coffee +16 -0
  20. data/app/assets/javascripts/expandable-list.js.coffee +16 -0
  21. data/app/assets/javascripts/form_initializer.js.coffee +8 -0
  22. data/app/assets/javascripts/helpers/conditionally-visible-field.js.coffee +13 -0
  23. data/app/assets/javascripts/hideable_content.js.coffee +25 -0
  24. data/app/assets/javascripts/inline_edit.js.coffee +58 -0
  25. data/app/assets/javascripts/label_file_field.js.coffee +22 -0
  26. data/app/assets/javascripts/label_file_field_ui_initializer.js.coffee +10 -0
  27. data/app/assets/javascripts/list_item.js.coffee +10 -0
  28. data/app/assets/javascripts/nested_form_controls.js.coffee +84 -0
  29. data/app/assets/javascripts/polymorphic_hibrid_input.js.coffee +14 -0
  30. data/app/assets/javascripts/polymorphic_select_input.js.coffee +28 -0
  31. data/app/assets/javascripts/rails.validations.actionView.js.coffee +18 -0
  32. data/app/assets/javascripts/scroll_loader.js.coffee +28 -0
  33. data/app/assets/javascripts/searchable_contents.js.coffee +62 -0
  34. data/app/assets/javascripts/selectable-list.js.coffee +92 -0
  35. data/app/assets/javascripts/sensible_to_ajax_view.js.coffee +60 -0
  36. data/app/assets/javascripts/single_page_manager.js.coffee +60 -0
  37. data/app/assets/javascripts/stylesheets/_custom-best-in-place.css.sass +12 -0
  38. data/app/assets/javascripts/stylesheets/_top-search.css.sass +0 -0
  39. data/app/assets/javascripts/stylesheets/application.css +0 -0
  40. data/app/assets/javascripts/trailing_form.js.coffee +16 -0
  41. data/app/assets/javascripts/ui_initializer.js.coffee +23 -0
  42. data/app/assets/javascripts/underscore.min.js +6 -0
  43. data/app/assets/stylesheets/brain_damage.css.sass +214 -0
  44. data/app/views/brain_damage/_empty.html.haml +1 -0
  45. data/app/views/brain_damage/empty.html.haml +1 -0
  46. data/bin/console +14 -0
  47. data/bin/setup +7 -0
  48. data/brain_damage.gemspec +36 -0
  49. data/lib/brain_damage.rb +16 -0
  50. data/lib/brain_damage/brain_damage_helper.rb +75 -0
  51. data/lib/brain_damage/version.rb +3 -0
  52. data/lib/generators/brain_damage/full/full_generator.rb +37 -0
  53. data/lib/generators/brain_damage/lib/controller/controller_generator.rb +45 -0
  54. data/lib/generators/brain_damage/lib/controller/templates/controller.rb +9 -0
  55. data/lib/generators/brain_damage/lib/controller/templates/private_methods/get_partial_locals.rb +3 -0
  56. data/lib/generators/brain_damage/lib/controller/templates/private_methods/set_singular_table_name.rb +3 -0
  57. data/lib/generators/brain_damage/lib/controller/templates/private_methods/singular_table_name_params.rb +3 -0
  58. data/lib/generators/brain_damage/lib/controller/templates/public_methods/create.rb +21 -0
  59. data/lib/generators/brain_damage/lib/controller/templates/public_methods/destroy.rb +14 -0
  60. data/lib/generators/brain_damage/lib/controller/templates/public_methods/edit.rb +2 -0
  61. data/lib/generators/brain_damage/lib/controller/templates/public_methods/index.rb +3 -0
  62. data/lib/generators/brain_damage/lib/controller/templates/public_methods/new.rb +3 -0
  63. data/lib/generators/brain_damage/lib/controller/templates/public_methods/show.rb +2 -0
  64. data/lib/generators/brain_damage/lib/controller/templates/public_methods/update.rb +25 -0
  65. data/lib/generators/brain_damage/lib/field.rb +163 -0
  66. data/lib/generators/brain_damage/lib/field_white_list.rb +21 -0
  67. data/lib/generators/brain_damage/lib/includes.rb +12 -0
  68. data/lib/generators/brain_damage/lib/migration.rb +76 -0
  69. data/lib/generators/brain_damage/lib/model/model_generator.rb +115 -0
  70. data/lib/generators/brain_damage/lib/model/templates/model.rb +12 -0
  71. data/lib/generators/brain_damage/lib/parametizer.rb +19 -0
  72. data/lib/generators/brain_damage/lib/relation/base.rb +50 -0
  73. data/lib/generators/brain_damage/lib/relation/belongs_to.rb +29 -0
  74. data/lib/generators/brain_damage/lib/relation/has_and_belongs_to_many.rb +22 -0
  75. data/lib/generators/brain_damage/lib/relation/has_many.rb +35 -0
  76. data/lib/generators/brain_damage/lib/relation/has_one.rb +18 -0
  77. data/lib/generators/brain_damage/lib/resource.rb +150 -0
  78. data/lib/generators/brain_damage/lib/ruby_simple_parser/block.rb +33 -0
  79. data/lib/generators/brain_damage/lib/ruby_simple_parser/class_definition.rb +19 -0
  80. data/lib/generators/brain_damage/lib/ruby_simple_parser/code_line.rb +16 -0
  81. data/lib/generators/brain_damage/lib/ruby_simple_parser/global_context.rb +8 -0
  82. data/lib/generators/brain_damage/lib/ruby_simple_parser/line_classifier.rb +107 -0
  83. data/lib/generators/brain_damage/lib/ruby_simple_parser/method.rb +23 -0
  84. data/lib/generators/brain_damage/lib/ruby_simple_parser/parser.rb +114 -0
  85. data/lib/generators/brain_damage/lib/ruby_simple_parser/ruby_simple_parser.rb +11 -0
  86. data/lib/generators/brain_damage/lib/templateable/base.rb +53 -0
  87. data/lib/generators/brain_damage/lib/templateable/class_templateable.rb +88 -0
  88. data/lib/generators/brain_damage/lib/templateable/field_templateable.rb +42 -0
  89. data/lib/generators/brain_damage/lib/templateable/view_templateable.rb +23 -0
  90. data/lib/generators/brain_damage/lib/views/displays/base.rb +14 -0
  91. data/lib/generators/brain_damage/lib/views/displays/bright_text.rb +14 -0
  92. data/lib/generators/brain_damage/lib/views/displays/collection_list.rb +22 -0
  93. data/lib/generators/brain_damage/lib/views/displays/default.rb +11 -0
  94. data/lib/generators/brain_damage/lib/views/displays/foreign_single_page_manager.rb +46 -0
  95. data/lib/generators/brain_damage/lib/views/displays/hidden.rb +26 -0
  96. data/lib/generators/brain_damage/lib/views/displays/inline_editable.rb +27 -0
  97. data/lib/generators/brain_damage/lib/views/displays/link_to.rb +42 -0
  98. data/lib/generators/brain_damage/lib/views/displays/linked_collection_list.rb +26 -0
  99. data/lib/generators/brain_damage/lib/views/displays/templates/bright_text.html.haml +7 -0
  100. data/lib/generators/brain_damage/lib/views/displays/templates/collection_list.html.haml +31 -0
  101. data/lib/generators/brain_damage/lib/views/displays/templates/custom.html.haml +5 -0
  102. data/lib/generators/brain_damage/lib/views/displays/templates/default.html.haml +4 -0
  103. data/lib/generators/brain_damage/lib/views/displays/templates/foreign_single_page_manager.html.haml +1 -0
  104. data/lib/generators/brain_damage/lib/views/displays/templates/inline_editable.html.haml +8 -0
  105. data/lib/generators/brain_damage/lib/views/displays/templates/link_to.html.haml +9 -0
  106. data/lib/generators/brain_damage/lib/views/displays/templates/linked_collection_list.html.haml +31 -0
  107. data/lib/generators/brain_damage/lib/views/displays/templates/text.html.haml +4 -0
  108. data/lib/generators/brain_damage/lib/views/displays/templates/yes_or_no.html.haml +4 -0
  109. data/lib/generators/brain_damage/lib/views/displays/text.rb +43 -0
  110. data/lib/generators/brain_damage/lib/views/factory.rb +29 -0
  111. data/lib/generators/brain_damage/lib/views/inputs/autocompletable.rb +26 -0
  112. data/lib/generators/brain_damage/lib/views/inputs/autocompletable_multiple_selection.rb +25 -0
  113. data/lib/generators/brain_damage/lib/views/inputs/autocompletable_simple_selection.rb +21 -0
  114. data/lib/generators/brain_damage/lib/views/inputs/base.rb +23 -0
  115. data/lib/generators/brain_damage/lib/views/inputs/checkbox.rb +14 -0
  116. data/lib/generators/brain_damage/lib/views/inputs/collection_checkboxes.rb +10 -0
  117. data/lib/generators/brain_damage/lib/views/inputs/collection_select.rb +11 -0
  118. data/lib/generators/brain_damage/lib/views/inputs/default.rb +11 -0
  119. data/lib/generators/brain_damage/lib/views/inputs/hierarchy_picker.rb +11 -0
  120. data/lib/generators/brain_damage/lib/views/inputs/nested_form.rb +34 -0
  121. data/lib/generators/brain_damage/lib/views/inputs/nested_on_hideable.rb +22 -0
  122. data/lib/generators/brain_damage/lib/views/inputs/polymorphic_hybrid.rb +44 -0
  123. data/lib/generators/brain_damage/lib/views/inputs/polymorphic_select.rb +33 -0
  124. data/lib/generators/brain_damage/lib/views/inputs/templates/autocompletable_multiple_selection.html.haml +20 -0
  125. data/lib/generators/brain_damage/lib/views/inputs/templates/autocompletable_simple_selection.html.haml +25 -0
  126. data/lib/generators/brain_damage/lib/views/inputs/templates/checkbox.html.haml +3 -0
  127. data/lib/generators/brain_damage/lib/views/inputs/templates/collection_checkboxes.html.haml +6 -0
  128. data/lib/generators/brain_damage/lib/views/inputs/templates/collection_select.html.haml +9 -0
  129. data/lib/generators/brain_damage/lib/views/inputs/templates/custom.html.haml +5 -0
  130. data/lib/generators/brain_damage/lib/views/inputs/templates/default.html.haml +1 -0
  131. data/lib/generators/brain_damage/lib/views/inputs/templates/file.html.haml +5 -0
  132. data/lib/generators/brain_damage/lib/views/inputs/templates/hierarchy_picker.html.haml +19 -0
  133. data/lib/generators/brain_damage/lib/views/inputs/templates/nested_form.html.haml +2 -0
  134. data/lib/generators/brain_damage/lib/views/inputs/templates/polymorphic_hybrid.html.haml +20 -0
  135. data/lib/generators/brain_damage/lib/views/inputs/templates/polymorphic_select.html.haml +22 -0
  136. data/lib/generators/brain_damage/lib/views/inputs/templates/simple_select.html.haml +1 -0
  137. data/lib/generators/brain_damage/lib/views/inputs/templates/text.html.haml +1 -0
  138. data/lib/generators/brain_damage/lib/views/labels/base.rb +26 -0
  139. data/lib/generators/brain_damage/lib/views/labels/default.rb +15 -0
  140. data/lib/generators/brain_damage/lib/views/labels/templates/default.html.haml +6 -0
  141. data/lib/generators/brain_damage/lib/views/modules/inline_editable.rb +16 -0
  142. data/lib/generators/brain_damage/lib/views/schemas/autocompletable.rb +36 -0
  143. data/lib/generators/brain_damage/lib/views/schemas/autocompletable/base.rb +26 -0
  144. data/lib/generators/brain_damage/lib/views/schemas/autocompletable/templates/_links.html.haml +8 -0
  145. data/lib/generators/brain_damage/lib/views/schemas/autocompletable/templates/_multiple_selection.html.haml +6 -0
  146. data/lib/generators/brain_damage/lib/views/schemas/autocompletable/templates/_simple_selection.html.haml +6 -0
  147. data/lib/generators/brain_damage/lib/views/schemas/base.rb +97 -0
  148. data/lib/generators/brain_damage/lib/views/schemas/base/base.rb +86 -0
  149. data/lib/generators/brain_damage/lib/views/schemas/base/form.rb +24 -0
  150. data/lib/generators/brain_damage/lib/views/schemas/base/templates/_fields.html.haml +10 -0
  151. data/lib/generators/brain_damage/lib/views/schemas/base/templates/_form.html.haml +15 -0
  152. data/lib/generators/brain_damage/lib/views/schemas/base/templates/index.html.haml +16 -0
  153. data/lib/generators/brain_damage/lib/views/schemas/base/templates/list/_index.html.haml +4 -0
  154. data/lib/generators/brain_damage/lib/views/schemas/base/templates/list/_item.html.haml +5 -0
  155. data/lib/generators/brain_damage/lib/views/schemas/base/templates/new.html.haml +3 -0
  156. data/lib/generators/brain_damage/lib/views/schemas/base/templates/show.html.haml +9 -0
  157. data/lib/generators/brain_damage/lib/views/schemas/base/templates/table/_header.html.haml +5 -0
  158. data/lib/generators/brain_damage/lib/views/schemas/base/templates/table/_index.html.haml +8 -0
  159. data/lib/generators/brain_damage/lib/views/schemas/base/templates/table/_item.html.haml +5 -0
  160. data/lib/generators/brain_damage/lib/views/schemas/custom.rb +36 -0
  161. data/lib/generators/brain_damage/lib/views/schemas/factory.rb +13 -0
  162. data/lib/generators/brain_damage/lib/views/schemas/inline_editable.rb +27 -0
  163. data/lib/generators/brain_damage/lib/views/schemas/inline_editable/base.rb +20 -0
  164. data/lib/generators/brain_damage/lib/views/schemas/inline_editable/field.rb +47 -0
  165. data/lib/generators/brain_damage/lib/views/schemas/inline_editable/inline_edit.rb +10 -0
  166. data/lib/generators/brain_damage/lib/views/schemas/inline_editable/templates/inline_edit/_field.html.haml +33 -0
  167. data/lib/generators/brain_damage/lib/views/schemas/inline_editable/templates/inline_edit/_inline_edit.html.haml +0 -0
  168. data/lib/generators/brain_damage/lib/views/schemas/nested_fields.rb +14 -0
  169. data/lib/generators/brain_damage/lib/views/schemas/nested_fields/base.rb +20 -0
  170. data/lib/generators/brain_damage/lib/views/schemas/nested_fields/templates/_nested.fields.html.haml +33 -0
  171. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager.rb +22 -0
  172. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/base.rb +40 -0
  173. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/list_item.rb +16 -0
  174. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/_single_page_manager.html.haml +20 -0
  175. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/index.html.haml +1 -0
  176. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_index.form.html.haml +20 -0
  177. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_index.html.haml +27 -0
  178. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_item.display.html.haml +5 -0
  179. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_item.form.html.haml +21 -0
  180. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_item.html.haml +33 -0
  181. data/lib/generators/brain_damage/lib/views/schemas/single_page_manager/templates/list/_simple.html.haml +4 -0
  182. data/lib/generators/brain_damage/lib/views/views_generator.rb +37 -0
  183. data/lib/generators/brain_damage/resource/USAGE +8 -0
  184. data/lib/generators/brain_damage/resource/helpers.rb +117 -0
  185. data/lib/generators/brain_damage/resource/monkeys/string.rb +17 -0
  186. data/lib/generators/brain_damage/resource/resource_generator.rb +139 -0
  187. data/lib/generators/brain_damage/resource/templates/controller.rb +40 -0
  188. data/lib/generators/brain_damage/resource/templates/inputs/_simple_select.html.haml +1 -0
  189. data/lib/generators/brain_damage/resource/templates/views/common/_fields.html.haml +11 -0
  190. data/lib/generators/brain_damage/resource/templates/views/common/show.html.haml +11 -0
  191. data/lib/generators/brain_damage/resource/templates/views/full_entity/_form.html.haml +13 -0
  192. data/lib/generators/brain_damage/resource/templates/views/full_entity/_index.body.html.haml +4 -0
  193. data/lib/generators/brain_damage/resource/templates/views/full_entity/_index.html.haml +5 -0
  194. data/lib/generators/brain_damage/resource/templates/views/full_entity/_table.header.html.haml +7 -0
  195. data/lib/generators/brain_damage/resource/templates/views/full_entity/_table.item.html.haml +8 -0
  196. data/lib/generators/brain_damage/resource/templates/views/full_entity/index.html.haml +16 -0
  197. data/lib/generators/brain_damage/resource/templates/views/full_entity/new.html.haml +3 -0
  198. data/lib/generators/brain_damage/resource/templates/views/scaffold/_menu.entry.html.haml +1 -0
  199. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_form.html.haml +15 -0
  200. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_index.body.html.haml +4 -0
  201. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_single_page_manager.html.haml +17 -0
  202. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.form.html.haml +21 -0
  203. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.header.html.haml +12 -0
  204. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.html.haml +27 -0
  205. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.item.form.html.haml +21 -0
  206. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.item.html.haml +32 -0
  207. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/_table.item.show.html.haml +13 -0
  208. data/lib/generators/brain_damage/resource/templates/views/single_page_manager/index.html.haml +4 -0
  209. data/lib/generators/brain_damage/resource/templates/views/special/_fields.show.inline.html.haml +10 -0
  210. data/lib/generators/brain_damage/resource/templates/views/special/_inline_edit.html.haml +2 -0
  211. data/lib/generators/brain_damage/resource/templates/views/special/_inner.show.inline.html.haml +20 -0
  212. data/lib/generators/brain_damage/resource/templates/views/special/_nested.fields.html.haml +33 -0
  213. data/lib/generators/brain_damage/resource/templates/views/special/_show.inline.html.haml +10 -0
  214. data/lib/generators/brain_damage/resource/templates/views/special/_trailing_form.show.inline.html.haml +12 -0
  215. metadata +328 -0
@@ -0,0 +1,33 @@
1
+ module RubySimpleParser
2
+ class Block
3
+ attr_reader :parent
4
+ attr_reader :lines
5
+ attr_reader :name
6
+
7
+ def initialize(definition, parent = nil)
8
+ @parent = parent
9
+ @lines = []
10
+
11
+ if definition
12
+ @name = "[#{definition.strip[0, 20]}...]"
13
+ RubySimpleParser::CodeLine.new(definition, self)
14
+ else
15
+ @name = :undefined_block
16
+ end
17
+
18
+ parent.add_line self if parent
19
+ end
20
+
21
+ def add_line(line)
22
+ if line.is_a? String
23
+ CodeLine.new line, self
24
+ else
25
+ @lines << line
26
+ end
27
+ end
28
+
29
+ def print
30
+ @lines.map(&:print).join "\n"
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module RubySimpleParser
2
+ class ClassDefinition < Block
3
+ CLASS_REGEX = /class\s+(?<class_name>\w+)/
4
+
5
+ def initialize(definition, visibility, parent = nil)
6
+ super definition, parent
7
+ @visibility = visibility
8
+ @name = ClassDefinition.extract_class_name definition
9
+ end
10
+
11
+ def self.extract_class_name(code)
12
+ (code.match CLASS_REGEX)[:class_name].to_sym
13
+ end
14
+
15
+ def definition
16
+ @lines.first.print
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module RubySimpleParser
2
+ class CodeLine
3
+ attr_accessor :line
4
+ attr_reader :parent
5
+
6
+ def initialize(line, parent = nil)
7
+ @parent = parent
8
+ @line = line
9
+ @parent.add_line self if @parent
10
+ end
11
+
12
+ def print
13
+ @line
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ module RubySimpleParser
2
+ class GlobalContext < Block
3
+ def initialize
4
+ super(nil, nil)
5
+ @name = 'Global'
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,107 @@
1
+ module RubySimpleParser
2
+ class LineClassifier
3
+ BLOCK_SPANNING_CONSTRUCTS = ['if', 'unless', 'each', 'while', 'until', 'loop', 'for', 'begin', 'do', 'then']
4
+
5
+ def classify(original_code_line, apply_normalize: true)
6
+ code_line = if apply_normalize then normalize original_code_line else original_code_line end
7
+
8
+ if code_line =~ /def (self\.)?\w+/
9
+ return METHOD_START
10
+
11
+ elsif code_line =~ /^\s*class\s*/
12
+ return CLASS_START
13
+
14
+ elsif code_line == ''
15
+ return EMPTY
16
+
17
+ elsif is_false_block_spanning_construct? code_line
18
+ return CODE_WITHOUT_BLOCK
19
+
20
+ elsif code_line == 'private'
21
+ return PRIVATE_BLOCK
22
+
23
+ end
24
+
25
+ block_balance = block_balance code_line, apply_normalize: false
26
+
27
+ if block_balance > 0
28
+ CODE_WITH_BLOCK
29
+ elsif block_balance < 0
30
+ BLOCK_END
31
+ else
32
+ CODE_WITHOUT_BLOCK
33
+ end
34
+ end
35
+
36
+ def normalize(original_line)
37
+ line = original_line.strip
38
+
39
+ return line if line == ''
40
+
41
+ substrings = line.scan(/".*?"|'.*?'/)
42
+ map = {}
43
+ count = 0
44
+
45
+ substrings.each do |substring|
46
+ placeholder = "RUBY_SIMPLE_PARSER_STRING_#{count}"
47
+ count += 1
48
+ line.gsub!(substring, placeholder)
49
+ map[placeholder] = substring
50
+ end
51
+
52
+ line.split('#').first.strip
53
+ end
54
+
55
+ def is_false_block_spanning_construct?(code_line)
56
+ keywords_regex_part = inline_block_spanning_constructs_regex_part
57
+
58
+ return false if code_line =~ /.+\s*=\s*#{keywords_regex_part}/ # variable = if condition
59
+
60
+ # return if condition then 'a' else 'b' end
61
+ return true if code_line =~ /\breturn\b\s*#{keywords_regex_part}\s+.+\bthen\b.+\bend\b/
62
+
63
+ # return if condition then
64
+ # 'a' else 'b' end
65
+ return false if code_line =~ /\breturn\b\s*#{keywords_regex_part}.+\bthen\b.*/
66
+
67
+ # return [something] if condition
68
+ return true if code_line =~ /\breturn\b.*#{keywords_regex_part}/
69
+
70
+ return true if code_line =~ /[^\s]+.*#{keywords_regex_part}/ # something if condition
71
+ end
72
+
73
+ def inline_block_spanning_constructs_regex_part
74
+ '(\b' + ['if', 'unless', 'while', 'until'].join('\b|\b') + '\b)'
75
+ end
76
+
77
+ def block_spanning_constructs_regex
78
+ Regexp.new '\b' + BLOCK_SPANNING_CONSTRUCTS.join('\b|\b') + '\b'
79
+ end
80
+
81
+ def block_wrappers_regex
82
+ Regexp.new('\b' + BLOCK_SPANNING_CONSTRUCTS.join('\b|\b') + '\b|\bend\b|\{|\}|\[|\]')
83
+ end
84
+
85
+ def strip_block_wrappers(original_code_line, apply_normalize: true)
86
+ code_line = if apply_normalize then normalize original_code_line else original_code_line end
87
+ code_line.strip.scan block_wrappers_regex
88
+ end
89
+
90
+ def block_balance(original_code_line, apply_normalize: true)
91
+ code_line = if apply_normalize then normalize original_code_line else original_code_line end
92
+ balance = 0
93
+
94
+ block_wrappers_tokens = strip_block_wrappers code_line, apply_normalize: false
95
+
96
+ block_wrappers_tokens.each do |token|
97
+ if BLOCK_SPANNING_CONSTRUCTS.include? token or token == '{' or token == '['
98
+ balance += 1
99
+ elsif ['end', '}', ']'].include? token
100
+ balance -= 1
101
+ end
102
+ end
103
+
104
+ balance
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,23 @@
1
+ module RubySimpleParser
2
+ class Method < Block
3
+ METHOD_REGEX = /def\s+(?<method_name>(self\.)?\w+[?!]?)/
4
+
5
+ def initialize(definition, visibility, parent = nil)
6
+ super definition, parent
7
+ @visibility = visibility
8
+ @name = Method.extract_method_name definition
9
+ end
10
+
11
+ def private?
12
+ @visibility == :private
13
+ end
14
+
15
+ def public?
16
+ @visibility == :public
17
+ end
18
+
19
+ def self.extract_method_name(code)
20
+ (code.match METHOD_REGEX)[:method_name].to_sym
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,114 @@
1
+ require_relative 'ruby_simple_parser'
2
+ require_relative 'block'
3
+ require_relative 'class_definition'
4
+ require_relative 'code_line'
5
+ require_relative 'global_context'
6
+ require_relative 'method'
7
+ require_relative 'line_classifier'
8
+
9
+ module RubySimpleParser
10
+ class Parser
11
+ attr_accessor :class_method_calls
12
+ attr_reader :class_definition
13
+
14
+ def initialize(code = '')
15
+ @code = code
16
+ @line_classifier = LineClassifier.new
17
+ parse if code
18
+ end
19
+
20
+ def public_methods
21
+ @methods[:public]
22
+ end
23
+
24
+ def private_methods
25
+ @methods[:private]
26
+ end
27
+
28
+ def parse
29
+ prepare_to_parse
30
+
31
+ @code_lines.each_index do |line_number|
32
+ line_code = @code_lines[line_number]
33
+ line_class = @line_classifier.classify line_code
34
+ new_block = nil
35
+
36
+ if line_class == CLASS_START
37
+ new_block = RubySimpleParser::ClassDefinition.new line_code, @context
38
+ @context = new_block
39
+ @class_definition = new_block
40
+ # puts "Entered context: #{@context.name}"
41
+
42
+ elsif line_class == CODE_WITH_BLOCK
43
+ new_block = RubySimpleParser::Block.new line_code, @context
44
+ @context = new_block
45
+
46
+ elsif line_class == METHOD_START
47
+ new_block = RubySimpleParser::Method.new line_code, @method_scope, @context
48
+ @context = new_block
49
+ @methods[@method_scope][new_block.name] = new_block
50
+ @last_method = new_block.name
51
+ # puts "Entered context: #{@context.name}"
52
+
53
+ elsif line_class == PRIVATE_BLOCK
54
+ @method_scope = :private
55
+ RubySimpleParser::CodeLine.new line_code, @context
56
+
57
+ else
58
+ new_block = RubySimpleParser::CodeLine.new line_code, @context
59
+
60
+ if line_class == BLOCK_END
61
+ if @context.parent
62
+ # puts "Left context: #{@context.name} (line_class: #{line_class})"
63
+ @context = @context.parent
64
+ end
65
+ end
66
+ end
67
+
68
+ if new_block and (![EMPTY, BLOCK_END].include? line_class) and !new_block.is_a? ClassDefinition and
69
+ (( line_class == CODE_WITH_BLOCK and @context.parent.is_a? ClassDefinition ) or
70
+ @context.is_a? ClassDefinition )
71
+
72
+ if @last_method
73
+ @class_method_calls[@last_method] ||= []
74
+ @class_method_calls[@last_method] << new_block
75
+ else
76
+ @class_method_calls[:after_class_definition] << new_block
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def class_method_calls_after(method)
83
+ if @class_method_calls.has_key? method
84
+ @class_method_calls[method]
85
+ else
86
+ []
87
+ end
88
+ end
89
+
90
+ def print
91
+ @global_context.print
92
+ end
93
+
94
+ private
95
+ def prepare_to_parse
96
+ @code_lines = @code.split("\n")
97
+ @parsed_code = {}
98
+ @global_context = GlobalContext.new
99
+ @context = @global_context
100
+
101
+ @methods = {
102
+ public: {},
103
+ private: {}
104
+ }
105
+
106
+ @last_method = nil
107
+
108
+ @class_method_calls = { after_class_definition: [] }
109
+ @class_definition = nil
110
+
111
+ @method_scope = :public
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,11 @@
1
+ module RubySimpleParser
2
+ CLASS_START = 'ClassDefinition'
3
+ METHOD_START = 'Method'
4
+ CODE_WITH_BLOCK = 'Block'
5
+
6
+ CODE_WITHOUT_BLOCK = :class_code_without_block
7
+ EMPTY = :empty
8
+ OTHER = :other
9
+ BLOCK_END = :block_end
10
+ PRIVATE_BLOCK = :private_block
11
+ end
@@ -0,0 +1,53 @@
1
+ require 'erb'
2
+ require 'erubis'
3
+ require 'pathname'
4
+
5
+ require_relative '../ruby_simple_parser/parser'
6
+
7
+ module BrainDamage
8
+ module Templateable
9
+ class Base
10
+ attr_reader :options
11
+ attr_reader :inner_html
12
+ attr_accessor :template_file
13
+
14
+ def initialize(resource, options = {})
15
+ @options = options
16
+ @resource = resource
17
+
18
+ @template_file = options[:template_file] || "#{self.class.to_s.split('::').last.underscore}.html.haml" unless @template_file
19
+ end
20
+
21
+ def render_erb_file(file)
22
+ raise "Trying to render a file that doesn't exist: #{file}" unless File.file? file
23
+ render_erb_string(File.open(file).read)
24
+ end
25
+
26
+ def render_erb_string(string)
27
+ return Erubis::Eruby.new(string).result(binding).strip.gsub(/\n\n\n+/, "\n").gsub(/NEW_LINE_\d+/, "").split("\n").map(&:rstrip).join("\n") if string.is_a? String
28
+ ''
29
+ end
30
+
31
+ def render_template_file(template_file = @template_file)
32
+ if Pathname.new(template_file).absolute?
33
+ render_erb_file template_file
34
+ else
35
+ render_erb_file "#{dir}/templates/#{template_file}"
36
+ end
37
+ end
38
+
39
+ def render(template_file = @template_file)
40
+ render_template_file template_file
41
+ end
42
+
43
+ def indent(level = nil)
44
+ level ||= @html_args[:indentation]
45
+ @inner_html.indent! level if level
46
+ end
47
+
48
+ def method_missing(method, *args, &block)
49
+ @resource.send method, *args, &block
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,88 @@
1
+ require_relative 'base'
2
+
3
+ module BrainDamage
4
+ module Templateable
5
+ class ClassTemplateable < Templateable::Base
6
+ attr_reader :current_file_name
7
+
8
+ def initialize(resource, options = {})
9
+ super
10
+ @public_methods_templates = "#{dir}/templates/public_methods/*"
11
+ @private_methods_templates = "#{dir}/templates/private_methods/*"
12
+
13
+ @removed_methods = []
14
+ end
15
+
16
+ def remove_methods(*methods)
17
+ @removed_methods += methods
18
+ end
19
+
20
+ def public_methods
21
+ methods :public
22
+ end
23
+
24
+ def private_methods
25
+ methods :private
26
+ end
27
+
28
+ def setup(file_name)
29
+ @current_file_name = file_name
30
+ @current_code = File.read @current_file_name if File.exists? @current_file_name
31
+ extract_definitions
32
+ end
33
+
34
+ def generate
35
+ render
36
+ end
37
+
38
+ def leading_class_method_calls
39
+ if @parser
40
+ @parser.class_method_calls[:after_class_definition].map(&:print).uniq.join("\n")
41
+
42
+ else
43
+ ''
44
+ end
45
+ end
46
+
47
+ def methods(visibility)
48
+ definitions = {}
49
+
50
+ identation = if visibility == :public then 1 else 2 end
51
+
52
+ Dir[instance_variable_get("@#{visibility}_methods_templates")].map { |template_file|
53
+ method_code = render_erb_file(template_file).indent identation
54
+ method_name = RubySimpleParser::Method.extract_method_name method_code
55
+ definitions[method_name] = method_code unless @removed_methods.include? method_name
56
+ }
57
+
58
+ if @parser
59
+ @parser.send("#{visibility}_methods").each do |method_name, method|
60
+ definitions[method_name] = method.print unless overwrite_method? method_name
61
+ end
62
+ end
63
+
64
+ definitions.values.join("\n\n")
65
+ end
66
+
67
+ def extract_definitions
68
+ if @current_code
69
+ @parser = RubySimpleParser::Parser.new @current_code
70
+ else
71
+ @parser = RubySimpleParser::Parser.new
72
+ end
73
+ end
74
+
75
+ def class_definition
76
+ @parser.class_definition.definition if @parser
77
+ end
78
+
79
+ def overwrite_method?(method_name)
80
+ always_overwrite_methods.include? method_name
81
+ end
82
+
83
+ def always_overwrite_methods
84
+ []
85
+ end
86
+ end
87
+ end
88
+ end