brain_damage 0.1.0

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