rails_best_practices 1.1.0 → 1.2.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.
- data/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/README.md +2 -0
- data/assets/result.html.erb +25 -2
- data/lib/rails_best_practices.rb +20 -9
- data/lib/rails_best_practices/core.rb +1 -0
- data/lib/rails_best_practices/core/check.rb +106 -25
- data/lib/rails_best_practices/core/controllers.rb +2 -1
- data/lib/rails_best_practices/core/error.rb +3 -2
- data/lib/rails_best_practices/core/klasses.rb +34 -0
- data/lib/rails_best_practices/core/mailers.rb +2 -1
- data/lib/rails_best_practices/core/methods.rb +113 -9
- data/lib/rails_best_practices/core/model_associations.rb +17 -0
- data/lib/rails_best_practices/core/model_attributes.rb +16 -0
- data/lib/rails_best_practices/core/models.rb +3 -2
- data/lib/rails_best_practices/core/nil.rb +9 -1
- data/lib/rails_best_practices/core/runner.rb +65 -26
- data/lib/rails_best_practices/core_ext/sexp.rb +57 -0
- data/lib/rails_best_practices/prepares.rb +12 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +13 -8
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/model_prepare.rb +44 -16
- data/lib/rails_best_practices/reviews.rb +1 -0
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +5 -2
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +77 -0
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +2 -2
- data/lib/rails_best_practices/reviews/review.rb +1 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.yml +1 -0
- data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +11 -0
- data/spec/rails_best_practices/core/check_spec.rb +22 -0
- data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
- data/spec/rails_best_practices/core/error_spec.rb +1 -1
- data/spec/rails_best_practices/core/klasses_spec.rb +12 -0
- data/spec/rails_best_practices/core/mailers_spec.rb +5 -0
- data/spec/rails_best_practices/core/methods_spec.rb +26 -4
- data/spec/rails_best_practices/core/models_spec.rb +2 -2
- data/spec/rails_best_practices/core/runner_spec.rb +13 -0
- data/spec/rails_best_practices/core_ext/sexp_spec.rb +26 -2
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +72 -60
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +1 -1
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +150 -59
- data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +20 -3
- data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +14 -0
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +387 -0
- metadata +15 -3
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -133,6 +133,7 @@ Now you can customize this configuration file, the default configuration is as f
|
|
133
133
|
RemoveEmptyHelpersCheck: {}
|
134
134
|
RemoveTabCheck: {}
|
135
135
|
RestrictAutoGeneratedRoutesCheck: { }
|
136
|
+
RemoveUnusedMethodsInModelsCheck: { except_methods: [] }
|
136
137
|
|
137
138
|
You can remove or comment one review to disable it, and you can change the options.
|
138
139
|
|
@@ -161,6 +162,7 @@ Model
|
|
161
162
|
2. the Law of Demeter
|
162
163
|
3. Use Observer
|
163
164
|
4. Use Query Attribute
|
165
|
+
5. Remove Unused Methods In Models (Experiment, not available by default configuration)
|
164
166
|
|
165
167
|
Mailer
|
166
168
|
|
data/assets/result.html.erb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
<head>
|
4
4
|
<meta charset='UTF-8' />
|
5
5
|
<title>Output of rails_best_practices</title>
|
6
|
-
|
7
6
|
<style type="text/css">
|
8
7
|
body {
|
9
8
|
color: #333;
|
@@ -34,6 +33,10 @@
|
|
34
33
|
table tr:hover {
|
35
34
|
background-color: #FFFFC0;
|
36
35
|
}
|
36
|
+
ul li {
|
37
|
+
list-style: none;
|
38
|
+
display: none;
|
39
|
+
}
|
37
40
|
</style>
|
38
41
|
</head>
|
39
42
|
<body>
|
@@ -50,6 +53,11 @@
|
|
50
53
|
Found <%= @errors.size %> errors.
|
51
54
|
<% end %>
|
52
55
|
</h2>
|
56
|
+
<ul>
|
57
|
+
<% @error_types.each do |error_type| %>
|
58
|
+
<li><input type="checkbox" value="<%= error_type.split(':').last %>" /><%= error_type.split(':').last %></li>
|
59
|
+
<% end %>
|
60
|
+
</ul>
|
53
61
|
<table>
|
54
62
|
<tr>
|
55
63
|
<th>Filename</th>
|
@@ -57,7 +65,7 @@
|
|
57
65
|
<th>Warning Message</th>
|
58
66
|
</tr>
|
59
67
|
<% @errors.each do |error| %>
|
60
|
-
<tr>
|
68
|
+
<tr class="<%= error.type.split(':').last %>">
|
61
69
|
<td class='filename'>
|
62
70
|
<% if @textmate %>
|
63
71
|
<a href='txmt://open/?url=file://<%= File.expand_path(error.filename) %>&line=<%= error.line_number %>'><%= error.filename %></a>
|
@@ -74,5 +82,20 @@
|
|
74
82
|
</tr>
|
75
83
|
<% end %>
|
76
84
|
</table>
|
85
|
+
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
|
86
|
+
<script type="text/javascript">
|
87
|
+
$(function() {
|
88
|
+
$('ul li').show();
|
89
|
+
$('input[type=checkbox]').prop('checked', true).click(function() {
|
90
|
+
if ($(this).attr('checked')) {
|
91
|
+
$(this).prop('checked', true);
|
92
|
+
$('.'+$(this).val()).show();
|
93
|
+
} else {
|
94
|
+
$(this).prop('checked', false);
|
95
|
+
$('.'+$(this).val()).hide();
|
96
|
+
}
|
97
|
+
});
|
98
|
+
});
|
99
|
+
</script>
|
77
100
|
</body>
|
78
101
|
</html>
|
data/lib/rails_best_practices.rb
CHANGED
@@ -83,6 +83,7 @@ module RailsBestPractices
|
|
83
83
|
|
84
84
|
@bar = ProgressBar.new('Analyzing', lexical_files.size + prepare_files.size + review_files.size)
|
85
85
|
["lexical", "prepare", "review"].each { |process| send(:process, process) }
|
86
|
+
@runner.on_complete
|
86
87
|
@bar.finish
|
87
88
|
|
88
89
|
if @options['format'] == 'html'
|
@@ -202,7 +203,7 @@ module RailsBestPractices
|
|
202
203
|
files.reject { |file| file.index(pattern) }
|
203
204
|
end
|
204
205
|
|
205
|
-
# output errors
|
206
|
+
# output errors on terminal.
|
206
207
|
def output_terminal_errors
|
207
208
|
@runner.errors.each { |error| plain_output(error.to_s, 'red') }
|
208
209
|
plain_output("\nPlease go to http://rails-bestpractices.com to see more useful Rails Best Practices.", 'green')
|
@@ -213,6 +214,21 @@ module RailsBestPractices
|
|
213
214
|
end
|
214
215
|
end
|
215
216
|
|
217
|
+
# output errors with html format.
|
218
|
+
def output_html_errors
|
219
|
+
require 'erubis'
|
220
|
+
template = File.read(File.join(File.dirname(__FILE__), "..", "assets", "result.html.erb"))
|
221
|
+
|
222
|
+
File.open("rails_best_practices_output.html", "w+") do |file|
|
223
|
+
eruby = Erubis::Eruby.new(template)
|
224
|
+
file.puts eruby.evaluate(:errors => @runner.errors, :error_types => error_types, :textmate => @options["with-textmate"], :mvim => @options["with-mvim"])
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# plain output with color.
|
229
|
+
#
|
230
|
+
# @param [String] message to output
|
231
|
+
# @param [String] color
|
216
232
|
def plain_output(message, color)
|
217
233
|
if @options["without-color"]
|
218
234
|
puts message
|
@@ -221,14 +237,9 @@ module RailsBestPractices
|
|
221
237
|
end
|
222
238
|
end
|
223
239
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
File.open("rails_best_practices_output.html", "w+") do |file|
|
229
|
-
eruby = Erubis::Eruby.new(template)
|
230
|
-
file.puts eruby.evaluate(:errors => @runner.errors, :textmate => @options["with-textmate"], :mvim => @options["with-mvim"])
|
231
|
-
end
|
240
|
+
# unique error types.
|
241
|
+
def error_types
|
242
|
+
@runner.errors.map(&:type).uniq
|
232
243
|
end
|
233
244
|
end
|
234
245
|
end
|
@@ -4,6 +4,7 @@ require 'rails_best_practices/core/runner'
|
|
4
4
|
require 'rails_best_practices/core/checking_visitor'
|
5
5
|
require 'rails_best_practices/core/error'
|
6
6
|
require 'rails_best_practices/core/nil'
|
7
|
+
require 'rails_best_practices/core/klasses'
|
7
8
|
require 'rails_best_practices/core/models'
|
8
9
|
require 'rails_best_practices/core/model_associations'
|
9
10
|
require 'rails_best_practices/core/model_attributes'
|
@@ -3,6 +3,7 @@ module RailsBestPractices
|
|
3
3
|
module Core
|
4
4
|
# A Check class that takes charge of checking the sexp.
|
5
5
|
class Check
|
6
|
+
|
6
7
|
CONTROLLER_FILES = /controllers\/.*\.rb$/
|
7
8
|
MIGRATION_FILES = /db\/migrate\/.*\.rb$/
|
8
9
|
MODEL_FILES = /models\/.*\.rb$/
|
@@ -13,12 +14,6 @@ module RailsBestPractices
|
|
13
14
|
SCHEMA_FILE = /db\/schema\.rb/
|
14
15
|
HELPER_FILES = /helpers.*\.rb$/
|
15
16
|
|
16
|
-
attr_reader :errors
|
17
|
-
|
18
|
-
def initialize
|
19
|
-
@errors = []
|
20
|
-
end
|
21
|
-
|
22
17
|
# default interesting nodes.
|
23
18
|
def interesting_nodes
|
24
19
|
[]
|
@@ -37,6 +32,9 @@ module RailsBestPractices
|
|
37
32
|
# @param [Sexp] node
|
38
33
|
def node_start(node)
|
39
34
|
@node = node
|
35
|
+
Array(self.class.callbacks["start_#{node.sexp_type}"]).each do |callback|
|
36
|
+
self.instance_exec node, &callback
|
37
|
+
end
|
40
38
|
self.send("start_#{node.sexp_type}", node)
|
41
39
|
end
|
42
40
|
|
@@ -49,14 +47,23 @@ module RailsBestPractices
|
|
49
47
|
def node_end(node)
|
50
48
|
@node = node
|
51
49
|
self.send("end_#{node.sexp_type}", node)
|
50
|
+
Array(self.class.callbacks["end_#{node.sexp_type}"]).each do |callback|
|
51
|
+
self.instance_exec node, &callback
|
52
|
+
end
|
52
53
|
end
|
53
54
|
|
54
55
|
# add error if source code violates rails best practice.
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
|
59
|
-
|
56
|
+
#
|
57
|
+
# @param [String] message, is the string message for violation of the rails best practice
|
58
|
+
# @param [String] file, is the filename of source code
|
59
|
+
# @param [Integer] line, is the line number of the source code which is reviewing
|
60
|
+
def add_error(message, file = @node.file, line = @node.line)
|
61
|
+
errors << RailsBestPractices::Core::Error.new("#{file}", "#{line}", message, self.class.to_s, url)
|
62
|
+
end
|
63
|
+
|
64
|
+
# errors that vialote the rails best practices.
|
65
|
+
def errors
|
66
|
+
@errors ||= []
|
60
67
|
end
|
61
68
|
|
62
69
|
# default url is empty.
|
@@ -84,31 +91,105 @@ module RailsBestPractices
|
|
84
91
|
end
|
85
92
|
end
|
86
93
|
|
87
|
-
|
88
|
-
#
|
89
|
-
def
|
90
|
-
|
94
|
+
class <<self
|
95
|
+
# callbacks for start_xxx and end_xxx.
|
96
|
+
def callbacks
|
97
|
+
@callbacks ||= {}
|
91
98
|
end
|
92
99
|
|
93
|
-
#
|
94
|
-
|
95
|
-
|
100
|
+
# add a callback.
|
101
|
+
#
|
102
|
+
# @param [String] name, callback name, can be start_xxx or end_xxx
|
103
|
+
# @param [Proc] block, be executed when callbacks are called
|
104
|
+
def add_callback(name, &block)
|
105
|
+
callbacks[name] ||= []
|
106
|
+
callbacks[name] << block
|
96
107
|
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Helper to parse the class name.
|
111
|
+
module Klassable
|
112
|
+
def self.included(base)
|
113
|
+
base.class_eval do
|
114
|
+
# remember module name
|
115
|
+
add_callback "start_module" do |node|
|
116
|
+
modules << node.module_name.to_s
|
117
|
+
end
|
118
|
+
|
119
|
+
# end of the module.
|
120
|
+
add_callback "end_module" do |node|
|
121
|
+
modules.pop
|
122
|
+
end
|
97
123
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
124
|
+
# remember the class anem
|
125
|
+
add_callback "start_class" do |node|
|
126
|
+
@klass = Core::Klass.new(node.class_name.to_s, node.base_class.to_s, modules)
|
127
|
+
end
|
128
|
+
|
129
|
+
# end of the class
|
130
|
+
add_callback "end_class" do |node|
|
131
|
+
@klass = nil
|
132
|
+
end
|
105
133
|
end
|
106
134
|
end
|
107
135
|
|
136
|
+
# get the current class name.
|
137
|
+
def current_class_name
|
138
|
+
@klass.to_s
|
139
|
+
end
|
140
|
+
|
141
|
+
# get the current extend class name.
|
142
|
+
def current_extend_class_name
|
143
|
+
@klass.extend_class_name
|
144
|
+
end
|
145
|
+
|
146
|
+
# modules.
|
108
147
|
def modules
|
109
148
|
@moduels ||= []
|
110
149
|
end
|
111
150
|
end
|
151
|
+
|
152
|
+
# Helper to add callback after all files reviewed.
|
153
|
+
module Completeable
|
154
|
+
def self.included(base)
|
155
|
+
base.class_eval do
|
156
|
+
add_callback "end_class" do |node|
|
157
|
+
if "RailsBestPractices::Complete" == node.class_name.to_s
|
158
|
+
on_complete
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Helper to parse the access control.
|
166
|
+
module Accessable
|
167
|
+
def self.included(base)
|
168
|
+
base.class_eval do
|
169
|
+
# remember the current access control for methods.
|
170
|
+
add_callback "start_var_ref" do |node|
|
171
|
+
if %w(public protected private).include? node.to_s
|
172
|
+
@access_control = node.to_s
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# set access control to "public" by default.
|
177
|
+
add_callback "start_class" do |node|
|
178
|
+
@access_control = "public"
|
179
|
+
end
|
180
|
+
|
181
|
+
# set access control to "public" by default.
|
182
|
+
add_callback "start_module" do |node|
|
183
|
+
@access_control = "public"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# get the current acces control.
|
188
|
+
def current_access_control
|
189
|
+
@access_control
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
112
193
|
end
|
113
194
|
end
|
114
195
|
end
|
@@ -5,12 +5,13 @@ module RailsBestPractices
|
|
5
5
|
#
|
6
6
|
# it indicates the filenname, line number and error message for the violation.
|
7
7
|
class Error
|
8
|
-
attr_reader :filename, :line_number, :message, :url
|
8
|
+
attr_reader :filename, :line_number, :message, :type, :url
|
9
9
|
|
10
|
-
def initialize(filename, line_number, message, url = nil)
|
10
|
+
def initialize(filename, line_number, message, type, url = nil)
|
11
11
|
@filename = filename
|
12
12
|
@line_number = line_number
|
13
13
|
@message = message
|
14
|
+
@type = type
|
14
15
|
@url = url
|
15
16
|
end
|
16
17
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RailsBestPractices
|
3
|
+
module Core
|
4
|
+
# Klass container.
|
5
|
+
class Klasses < Array
|
6
|
+
# If include the class.
|
7
|
+
#
|
8
|
+
# @param [String] class name
|
9
|
+
# @return [Boolean] include or not
|
10
|
+
def include?(class_name)
|
11
|
+
find { |klass| klass.to_s == class_name }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Class info includes clas name, extend class name and module names.
|
16
|
+
class Klass
|
17
|
+
attr_reader :class_name, :extend_class_name
|
18
|
+
|
19
|
+
def initialize(class_name, extend_class_name, modules)
|
20
|
+
@class_name = class_name
|
21
|
+
@extend_class_name = extend_class_name
|
22
|
+
@modules = modules.dup
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_s
|
26
|
+
if @modules.empty?
|
27
|
+
@class_name
|
28
|
+
else
|
29
|
+
@modules.map { |modu| "#{modu}::" }.join("") + @class_name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,24 +1,128 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module RailsBestPractices
|
3
3
|
module Core
|
4
|
+
# Method container.
|
4
5
|
class Methods
|
5
6
|
def initialize
|
6
7
|
@methods = {}
|
8
|
+
@possible_methods = {}
|
7
9
|
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
# Add a method.
|
12
|
+
#
|
13
|
+
# @param [String] class name
|
14
|
+
# @param [String] method name
|
15
|
+
# @param [Hash] method meta, file and line, {"file" => "app/models/post.rb", "line" => 5}
|
16
|
+
# @param [String] access control, public, protected or private
|
17
|
+
def add_method(class_name, method_name, meta={}, access_control="public")
|
18
|
+
return if class_name == ""
|
19
|
+
methods(class_name) << Method.new(class_name, method_name, access_control, meta)
|
20
|
+
if access_control == "public"
|
21
|
+
@possible_methods[method_name] = false
|
22
|
+
end
|
12
23
|
end
|
13
24
|
|
14
|
-
|
15
|
-
|
16
|
-
|
25
|
+
# Get methods of a class.
|
26
|
+
#
|
27
|
+
# @param [String] class name
|
28
|
+
# @param [String] access control
|
29
|
+
# @return [Array] all methods of a class for such access control, if access control is nil, return all public/protected/private methods
|
30
|
+
def get_methods(class_name, access_control=nil)
|
31
|
+
if access_control
|
32
|
+
methods(class_name).select { |method| method.access_control == access_control }
|
33
|
+
else
|
34
|
+
methods(class_name)
|
35
|
+
end
|
17
36
|
end
|
18
37
|
|
19
|
-
|
20
|
-
|
21
|
-
|
38
|
+
# If a class has a method.
|
39
|
+
#
|
40
|
+
# @param [String] class name
|
41
|
+
# @param [String] method name
|
42
|
+
# @param [String] access control
|
43
|
+
# @return [Boolean] has a method or not
|
44
|
+
def has_method?(class_name, method_name, access_control=nil)
|
45
|
+
if access_control
|
46
|
+
!!methods(class_name).find { |method| method.method_name == method_name && method.access_control == access_control }
|
47
|
+
else
|
48
|
+
!!methods(class_name).find { |method| method.method_name == method_name }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Mark parent class' method as used.
|
53
|
+
#
|
54
|
+
# @param [String] class name
|
55
|
+
# @param [String] method name
|
56
|
+
def mark_extend_class_method_used(class_name, method_name)
|
57
|
+
klass = Prepares.klasses.find { |klass| klass.to_s == class_name }
|
58
|
+
if klass && klass.extend_class_name
|
59
|
+
mark_extend_class_method_used(klass.extend_class_name, method_name)
|
60
|
+
method = get_method(klass.extend_class_name, method_name)
|
61
|
+
method.mark_used if method
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# remomber the method name, the method is probably be used for the class' public method.
|
66
|
+
#
|
67
|
+
# @param [String] method name
|
68
|
+
def possible_public_used(method_name)
|
69
|
+
@possible_methods[method_name] = true
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get a method in a class.
|
73
|
+
#
|
74
|
+
# @param [String] class name
|
75
|
+
# @param [String] method name
|
76
|
+
# @param [String] access control
|
77
|
+
# @return [Method] Method object
|
78
|
+
def get_method(class_name, method_name, access_control=nil)
|
79
|
+
if access_control
|
80
|
+
methods(class_name).find { |method| method.method_name == method_name && method.access_control == access_control }
|
81
|
+
else
|
82
|
+
methods(class_name).find { |method| method.method_name == method_name }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Get all unused methods.
|
87
|
+
#
|
88
|
+
# @param [String] access control
|
89
|
+
# @return [Array] array of Method
|
90
|
+
def get_all_unused_methods(access_control=nil)
|
91
|
+
@methods.inject([]) { |unused_methods, (class_name, methods)|
|
92
|
+
unused_methods += if access_control
|
93
|
+
methods.select { |method| method.access_control == access_control && !method.used }
|
94
|
+
else
|
95
|
+
methods.select { |method| !method.used }
|
96
|
+
end
|
97
|
+
}.reject { |method| method.access_control == "public" && @possible_methods[method.method_name] }
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
# Methods of a class.
|
102
|
+
#
|
103
|
+
# @param [String] class name
|
104
|
+
# @return [Array] array of methods
|
105
|
+
def methods(class_name)
|
106
|
+
@methods[class_name] ||= []
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Method info includes class name, method name, access control, file, line, used.
|
111
|
+
class Method
|
112
|
+
attr_reader :access_control, :class_name, :method_name, :used, :file, :line
|
113
|
+
|
114
|
+
def initialize(class_name, method_name, access_control, meta)
|
115
|
+
@class_name = class_name
|
116
|
+
@method_name = method_name
|
117
|
+
@file = meta["file"]
|
118
|
+
@line = meta["line"]
|
119
|
+
@access_control = access_control
|
120
|
+
@used = false
|
121
|
+
end
|
122
|
+
|
123
|
+
# Mark this method as used.
|
124
|
+
def mark_used
|
125
|
+
@used = true
|
22
126
|
end
|
23
127
|
end
|
24
128
|
end
|