rails_best_practices 1.19.3 → 1.19.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/CHANGELOG.md +4 -0
- data/Gemfile +0 -4
- data/Gemfile.lock +120 -0
- data/README.md +4 -1
- data/lib/rails_best_practices.rb +2 -0
- data/lib/rails_best_practices/analyzer.rb +5 -4
- data/lib/rails_best_practices/cli.rb +22 -0
- data/lib/rails_best_practices/command.rb +1 -131
- data/lib/rails_best_practices/core/check.rb +24 -23
- data/lib/rails_best_practices/core/checks_loader.rb +17 -18
- data/lib/rails_best_practices/core/methods.rb +9 -8
- data/lib/rails_best_practices/core/model_associations.rb +1 -1
- data/lib/rails_best_practices/core/runner.rb +38 -38
- data/lib/rails_best_practices/option_parser.rb +140 -0
- data/lib/rails_best_practices/prepares/controller_prepare.rb +8 -14
- data/lib/rails_best_practices/prepares/gemfile_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +1 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +13 -13
- data/lib/rails_best_practices/prepares/route_prepare.rb +16 -15
- data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +25 -23
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +73 -72
- data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +2 -1
- data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +4 -3
- data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +1 -1
- data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +1 -1
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +11 -11
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +8 -8
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +5 -5
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +20 -19
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +3 -3
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +5 -5
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +5 -5
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +13 -13
- data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +1 -1
- data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +2 -2
- data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +1 -1
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +3 -3
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +32 -32
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -4
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +14 -14
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +6 -6
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +15 -15
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +8 -8
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +71 -70
- data/lib/rails_best_practices/reviews/review.rb +2 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +1 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +11 -11
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +12 -9
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +10 -10
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +14 -13
- data/lib/rails_best_practices/reviews/use_observer_review.rb +20 -20
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +6 -6
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +44 -41
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +7 -7
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +14 -14
- data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +1 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +8 -8
- data/spec/rails_best_practices/analyzer_spec.rb +4 -4
- data/spec/rails_best_practices/core/error_spec.rb +6 -3
- data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +21 -21
- data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +15 -15
- data/spec/rails_best_practices/prepares/route_prepare_spec.rb +17 -15
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +8 -8
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +4 -2
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +6 -4
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +8 -6
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +16 -14
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +4 -4
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +14 -14
- data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +1 -1
- data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +51 -51
- metadata +5 -2
@@ -27,21 +27,21 @@ module RailsBestPractices
|
|
27
27
|
first_argument = node.arguments.all.first
|
28
28
|
second_argument = node.arguments.all[1]
|
29
29
|
if @controller_names.last
|
30
|
-
if
|
30
|
+
if first_argument.sexp_type == :bare_assoc_hash
|
31
31
|
action_names = [first_argument.hash_values.first.to_s]
|
32
|
-
elsif
|
32
|
+
elsif first_argument.sexp_type == :array
|
33
33
|
action_names = first_argument.array_values.map(&:to_s)
|
34
|
-
elsif
|
35
|
-
if
|
34
|
+
elsif second_argument.try(:sexp_type) == :bare_assoc_hash && second_argument.hash_value('to').present?
|
35
|
+
if second_argument.hash_value('to').sexp_type == :string_literal
|
36
36
|
controller_name, action_name = second_argument.hash_value('to').to_s.split('#')
|
37
37
|
action_names = [action_name]
|
38
38
|
else
|
39
39
|
action_names = [second_argument.hash_value('to').to_s]
|
40
40
|
end
|
41
|
-
elsif
|
42
|
-
|
41
|
+
elsif first_argument.sexp_type == :symbol_literal && second_argument.try(:sexp_type) && \
|
42
|
+
second_argument.sexp_type == :symbol_literal
|
43
43
|
action_names = node.arguments.all.select \
|
44
|
-
{ |arg|
|
44
|
+
{ |arg| arg.sexp_type == :symbol_literal }.map(&:to_s)
|
45
45
|
else
|
46
46
|
action_names = [first_argument.to_s]
|
47
47
|
end
|
@@ -49,18 +49,18 @@ module RailsBestPractices
|
|
49
49
|
@routes.add_route(current_namespaces, current_controller_name, action_name)
|
50
50
|
end
|
51
51
|
else
|
52
|
-
if
|
52
|
+
if first_argument.sexp_type == :bare_assoc_hash
|
53
53
|
route_node = first_argument.hash_values.first
|
54
54
|
# do not parse redirect block
|
55
|
-
if
|
55
|
+
if route_node.sexp_type != :method_add_arg
|
56
56
|
controller_name, action_name = route_node.to_s.split('#')
|
57
57
|
@routes.add_route(current_namespaces, controller_name.underscore, action_name)
|
58
58
|
end
|
59
|
-
elsif
|
59
|
+
elsif first_argument.sexp_type == :array
|
60
60
|
first_argument.array_values.map(&:to_s).each do |action_node|
|
61
61
|
@routes.add_route(current_namespaces, controller_name, action_node.to_s)
|
62
62
|
end
|
63
|
-
elsif
|
63
|
+
elsif second_argument.try(:sexp_type) == :bare_assoc_hash
|
64
64
|
if second_argument.hash_value('to').present?
|
65
65
|
controller_name, action_name = second_argument.hash_value('to').to_s.split('#')
|
66
66
|
else
|
@@ -78,12 +78,13 @@ module RailsBestPractices
|
|
78
78
|
case options.sexp_type
|
79
79
|
when :bare_assoc_hash
|
80
80
|
if options.hash_value('controller').present?
|
81
|
-
return if
|
81
|
+
return if options.hash_value('controller').sexp_type == :regexp_literal
|
82
|
+
|
82
83
|
controller_name = options.hash_value('controller').to_s
|
83
84
|
action_name = options.hash_value('action').present? ? options.hash_value('action').to_s : '*'
|
84
85
|
@routes.add_route(current_namespaces, controller_name, action_name)
|
85
86
|
else
|
86
|
-
route_node = options.hash_values.find { |value_node|
|
87
|
+
route_node = options.hash_values.find { |value_node| value_node.sexp_type == :string_literal && value_node.to_s.include?('#') }
|
87
88
|
if route_node.present?
|
88
89
|
controller_name, action_name = route_node.to_s.split('#')
|
89
90
|
@routes.add_route(current_namespaces, controller_name.underscore, action_name)
|
@@ -100,7 +101,7 @@ module RailsBestPractices
|
|
100
101
|
options = node.arguments.all.last
|
101
102
|
case options.sexp_type
|
102
103
|
when :bare_assoc_hash
|
103
|
-
route_node = options.hash_values.find { |value_node|
|
104
|
+
route_node = options.hash_values.find { |value_node| value_node.sexp_type == :string_literal && value_node.to_s.include?('#') }
|
104
105
|
if route_node.present?
|
105
106
|
controller_name, action_name = route_node.to_s.split('#')
|
106
107
|
@routes.add_route(current_namespaces, controller_name.underscore, action_name)
|
@@ -151,7 +152,7 @@ module RailsBestPractices
|
|
151
152
|
end
|
152
153
|
when 'with_options'
|
153
154
|
argument = node.arguments.all.last
|
154
|
-
if
|
155
|
+
if argument.sexp_type == :bare_assoc_hash && argument.hash_value('controller').present?
|
155
156
|
@controller_name = [:with_option, argument.hash_value('controller').to_s]
|
156
157
|
end
|
157
158
|
else
|
@@ -48,44 +48,46 @@ module RailsBestPractices
|
|
48
48
|
|
49
49
|
# check an attribute assignment node, if there is a array reference node in the right value of assignment node,
|
50
50
|
# then remember this attribute assignment.
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
51
|
+
def assign(node)
|
52
|
+
left_value = node.left_value
|
53
|
+
right_value = node.right_value
|
54
|
+
return unless left_value.sexp_type == :field && right_value.sexp_type == :call
|
55
|
+
|
56
|
+
aref_node = right_value.grep_node(sexp_type: :aref)
|
57
|
+
if aref_node
|
58
|
+
assignments(left_value.receiver.to_s) << { message: left_value.message.to_s, arguments: aref_node.to_s }
|
59
59
|
end
|
60
|
+
end
|
60
61
|
|
61
62
|
# check a call node with message "save" or "save!",
|
62
63
|
# if there exists an attribute assignment for the receiver of this call node,
|
63
64
|
# and if the arguments of this attribute assignments has duplicated entries (different message and same arguments),
|
64
65
|
# then this node needs to add a virtual attribute.
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
66
|
+
def call_assignment(node)
|
67
|
+
if ['save', 'save!'].include? node.message.to_s
|
68
|
+
receiver = node.receiver.to_s
|
69
|
+
add_error "add model virtual attribute (for #{receiver})" if params_dup?(assignments(receiver).collect { |h| h[:arguments] })
|
70
70
|
end
|
71
|
+
end
|
71
72
|
|
72
73
|
# if the nodes are duplicated.
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
def params_dup?(nodes)
|
75
|
+
return false if nodes.nil?
|
76
|
+
|
77
|
+
!dups(nodes).empty?
|
78
|
+
end
|
77
79
|
|
78
80
|
# get the assignments of receiver.
|
79
|
-
|
80
|
-
|
81
|
-
|
81
|
+
def assignments(receiver)
|
82
|
+
@assignments[receiver] ||= []
|
83
|
+
end
|
82
84
|
|
83
85
|
# Get the duplicate entries from an Enumerable.
|
84
86
|
#
|
85
87
|
# @return [Enumerable] the duplicate entries.
|
86
|
-
|
87
|
-
|
88
|
-
|
88
|
+
def dups(nodes)
|
89
|
+
nodes.each_with_object({}) { |v, h| h[v] = h[v].to_i + 1; }.reject { |_k, v| v == 1 }.keys
|
90
|
+
end
|
89
91
|
end
|
90
92
|
end
|
91
93
|
end
|
@@ -42,7 +42,7 @@ module RailsBestPractices
|
|
42
42
|
add_callback :start_command_call do |node|
|
43
43
|
if %w[integer string].include? node.message.to_s
|
44
44
|
remember_foreign_key_columns(node)
|
45
|
-
elsif
|
45
|
+
elsif node.message.to_s == 'index'
|
46
46
|
remember_index_columns_inside_table(node)
|
47
47
|
end
|
48
48
|
end
|
@@ -87,107 +87,108 @@ module RailsBestPractices
|
|
87
87
|
# remember the node as index columns, when used outside a table
|
88
88
|
# block, i.e.
|
89
89
|
# add_index :table_name, :column_name
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
def remember_index_columns_outside_table(node)
|
91
|
+
table_name = node.arguments.all.first.to_s
|
92
|
+
index_column = node.arguments.all[1].to_object
|
93
93
|
|
94
|
-
|
95
|
-
|
96
|
-
|
94
|
+
@index_columns[table_name] ||= []
|
95
|
+
@index_columns[table_name] << index_column
|
96
|
+
end
|
97
97
|
|
98
98
|
# remember the node as index columns, when used inside a table
|
99
99
|
# block, i.e.
|
100
100
|
# t.index [:column_name, ...]
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
def remember_index_columns_inside_table(node)
|
102
|
+
table_name = @table_name
|
103
|
+
index_column = node.arguments.all.first.to_object
|
104
104
|
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
@index_columns[table_name] ||= []
|
106
|
+
@index_columns[table_name] << index_column
|
107
|
+
end
|
108
108
|
|
109
109
|
# remember table nodes
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
def remember_table_nodes(node)
|
111
|
+
@table_name = node.arguments.all.first.to_s
|
112
|
+
@table_nodes[@table_name] = node
|
113
|
+
end
|
114
114
|
|
115
115
|
# remember foreign key columns
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
end
|
133
|
-
foreign_id_column = "#{$1}_id"
|
116
|
+
def remember_foreign_key_columns(node)
|
117
|
+
table_name = @table_name
|
118
|
+
foreign_key_column = node.arguments.all.first.to_s
|
119
|
+
@foreign_keys[table_name] ||= []
|
120
|
+
if foreign_key_column =~ /(.*?)_id$/
|
121
|
+
if @foreign_keys[table_name].delete("#{$1}_type")
|
122
|
+
@foreign_keys[table_name] << ["#{$1}_id", "#{$1}_type"]
|
123
|
+
else
|
124
|
+
@foreign_keys[table_name] << foreign_key_column
|
125
|
+
end
|
126
|
+
foreign_id_column = foreign_key_column
|
127
|
+
elsif foreign_key_column =~ /(.*?)_type$/
|
128
|
+
if @foreign_keys[table_name].delete("#{$1}_id")
|
129
|
+
@foreign_keys[table_name] << ["#{$1}_id", "#{$1}_type"]
|
130
|
+
else
|
131
|
+
@foreign_keys[table_name] << foreign_key_column
|
134
132
|
end
|
133
|
+
foreign_id_column = "#{$1}_id"
|
134
|
+
end
|
135
135
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
end
|
136
|
+
if foreign_id_column
|
137
|
+
index_node = node.arguments.all.last.hash_value('index')
|
138
|
+
if index_node.present? && (index_node.to_s != 'false')
|
139
|
+
@index_columns[table_name] ||= []
|
140
|
+
@index_columns[table_name] << foreign_id_column
|
142
141
|
end
|
143
142
|
end
|
143
|
+
end
|
144
144
|
|
145
145
|
# remove the non foreign keys without corresponding tables.
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
146
|
+
def remove_table_not_exist_foreign_keys
|
147
|
+
@foreign_keys.each do |table, foreign_keys|
|
148
|
+
foreign_keys.delete_if do |key|
|
149
|
+
if key =~ /_id$/
|
150
|
+
class_name = Prepares.model_associations.get_association_class_name(table, key[0..-4])
|
151
|
+
class_name ? !@table_nodes[class_name.gsub('::', '').tableize] : !@table_nodes[key[0..-4].pluralize]
|
153
152
|
end
|
154
153
|
end
|
155
154
|
end
|
155
|
+
end
|
156
156
|
|
157
157
|
# remove the non foreign keys with only _type column.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
}
|
158
|
+
def remove_only_type_foreign_keys
|
159
|
+
@foreign_keys.each do |_table, foreign_keys|
|
160
|
+
foreign_keys.delete_if { |key| key =~ /_type$/ }
|
162
161
|
end
|
162
|
+
end
|
163
163
|
|
164
164
|
# combine polymorphic foreign keys, e.g.
|
165
165
|
# [tagger_id], [tagger_type] => [tagger_id, tagger_type]
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
166
|
+
def combine_polymorphic_foreign_keys
|
167
|
+
@index_columns.each do |_table, foreign_keys|
|
168
|
+
foreign_id_keys = foreign_keys.select { |key| key.size == 1 && key.first =~ /_id/ }
|
169
|
+
foreign_type_keys = foreign_keys.select { |key| key.size == 1 && key.first =~ /_type/ }
|
170
|
+
foreign_id_keys.each do |id_key|
|
171
|
+
next unless type_key = foreign_type_keys.detect { |type_key| type_key.first == id_key.first.sub(/_id/, '') + '_type' }
|
172
|
+
|
173
|
+
foreign_keys.delete(id_key)
|
174
|
+
foreign_keys.delete(type_key)
|
175
|
+
foreign_keys << id_key + type_key
|
176
|
+
end
|
177
177
|
end
|
178
|
+
end
|
178
179
|
|
179
180
|
# check if the table's column is indexed.
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
181
|
+
def not_indexed?(table, column)
|
182
|
+
index_columns = @index_columns[table]
|
183
|
+
!index_columns || index_columns.none? { |e| greater_than_or_equal(Array(e), Array(column)) }
|
184
|
+
end
|
184
185
|
|
185
186
|
# check if more_array is greater than less_array or equal to less_array.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
187
|
+
def greater_than_or_equal(more_array, less_array)
|
188
|
+
more_size = more_array.size
|
189
|
+
less_size = less_array.size
|
190
|
+
(more_array - less_array).size == more_size - less_size
|
191
|
+
end
|
191
192
|
end
|
192
193
|
end
|
193
194
|
end
|
@@ -28,7 +28,7 @@ module RailsBestPractices
|
|
28
28
|
# if our current binary is a subset of the @used_return_value_of
|
29
29
|
# then don't overwrite it
|
30
30
|
already_included = @used_return_value_of &&
|
31
|
-
|
31
|
+
(all_conditions - @used_return_value_of).empty?
|
32
32
|
|
33
33
|
@used_return_value_of = node.all_conditions unless already_included
|
34
34
|
end
|
@@ -36,6 +36,7 @@ module RailsBestPractices
|
|
36
36
|
|
37
37
|
def return_value_is_used?(node)
|
38
38
|
return false unless @used_return_value_of
|
39
|
+
|
39
40
|
node == @used_return_value_of or @used_return_value_of.include?(node)
|
40
41
|
end
|
41
42
|
|
@@ -33,7 +33,7 @@ module RailsBestPractices
|
|
33
33
|
# if our current binary is a subset of the @used_return_value_of
|
34
34
|
# then don't overwrite it
|
35
35
|
already_included = @used_return_value_of &&
|
36
|
-
|
36
|
+
(all_conditions - @used_return_value_of).empty?
|
37
37
|
|
38
38
|
@used_return_value_of = node.all_conditions unless already_included
|
39
39
|
end
|
@@ -41,6 +41,7 @@ module RailsBestPractices
|
|
41
41
|
|
42
42
|
def return_value_is_used?(node)
|
43
43
|
return false unless @used_return_value_of
|
44
|
+
|
44
45
|
node == @used_return_value_of or @used_return_value_of.include?(node)
|
45
46
|
end
|
46
47
|
|
@@ -58,8 +59,8 @@ module RailsBestPractices
|
|
58
59
|
elsif message == 'create'
|
59
60
|
# We're only interested in 'create' calls on model classes:
|
60
61
|
possible_receiver_classes = [node.receiver.to_s] + classable_modules.map do |mod|
|
61
|
-
|
62
|
-
|
62
|
+
"#{mod}::#{node.receiver}"
|
63
|
+
end
|
63
64
|
unless (possible_receiver_classes & model_classnames).empty?
|
64
65
|
add_error "use 'create!' instead of 'create' as the latter may not always save"
|
65
66
|
end
|
@@ -20,7 +20,7 @@ module RailsBestPractices
|
|
20
20
|
|
21
21
|
# check call node to see if it is with message "namespace" and argument "bundler".
|
22
22
|
add_callback :start_command do |node|
|
23
|
-
if
|
23
|
+
if node.message.to_s == 'namespace' && node.arguments.all[0].to_s == 'bundler'
|
24
24
|
add_error 'dry bundler in capistrano'
|
25
25
|
end
|
26
26
|
end
|
@@ -24,23 +24,23 @@ module RailsBestPractices
|
|
24
24
|
protected
|
25
25
|
|
26
26
|
# check if hash node is empty.
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
def empty_hash?(node)
|
28
|
+
s(:hash, nil) == node || s(:bare_assoc_hash, nil) == node
|
29
|
+
end
|
30
30
|
|
31
31
|
# check if hash key/value pairs are ruby 1.8 style.
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
def hash_is_18?(node)
|
33
|
+
pair_nodes = node.sexp_type == :hash ? node[1][1] : node[1]
|
34
|
+
return false if pair_nodes.blank?
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
pair_nodes.any? { |pair_node| pair_node[1].sexp_type == :symbol_literal }
|
37
|
+
end
|
38
38
|
|
39
39
|
# check if the hash keys are valid to be converted to ruby 1.9
|
40
40
|
# syntax.
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
def valid_keys?(node)
|
42
|
+
node.hash_keys.all? { |key| key =~ VALID_SYMBOL_KEY }
|
43
|
+
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|