Класс: RuboCop::Cop::FormulaAudit::ComponentsOrder Закрытый
- Наследует:
- RuboCop::Cop::FormulaCop
- Object
- Base
- RuboCop::Cop::FormulaCop
- RuboCop::Cop::FormulaAudit::ComponentsOrder
- Расширен модулем:
- AutoCorrector
- Определён в:
- rubocops/components_order.rb,
sorbet/rbi/dsl/rubo_cop/cop/formula_audit/components_order.rbi
Обзор
Этот класс является частью закрытого API. Этот класс можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого класса, поскольку он может быть удалён или изменён без предупреждения.
Эта проверка обнаруживает неправильный порядок компонентов в формулах.
-
component_precedence_listсодержит иерархию компонентов во вложенном списке, где каждый вложенный массив содержит сведения о компонентах одного уровня приоритета
Краткое описание атрибутов экземпляра
Атрибуты, унаследованные от RuboCop::Cop::FormulaCop
Краткое описание методов экземпляра свернуть
- #audit_formula(formula_nodes) ⇒ void закрытый
- #check_block_component_order(component_precedence_list, block) ⇒ void закрытый
- #check_on_system_block_content(component_precedence_list, on_system_block) ⇒ void закрытый
- #check_order(component_precedence_list, body_node) ⇒ Array<(Array<Array<RuboCop::AST::Node>>, Array<RuboCop::AST::Node>)>? закрытый
- #component_problem(component1, component2) ⇒ void закрытый
Метод для сообщения о нарушениях порядка компонентов и их исправления.
- #depends_on_node?(node, **kwargs, &block) ⇒ T.untyped закрытый
- #get_state(node1) ⇒ Array<(Integer, Integer, Array<RuboCop::AST::Node>)> закрытый
Возвращает индекс приоритета и индекс компонента, чтобы правильно переупорядочить и сгруппировать их при автоматическом исправлении.
- #initialize(config = nil, options = nil) ⇒ void конструктор закрытый
- #reorder_components(corrector, node1, node2) ⇒ void закрытый
Меняет порядок двух узлов в исходном коде с помощью экземпляра corrector в методе автоматического исправления.
Методы, унаследованные от RuboCop::Cop::FormulaCop
#audit_comments, #audit_urls, #caveats_strings, #dependency_name_hash_match?, #dependency_type_hash_match?, #depends_on?, #depends_on_name_type?, #formula_tap, #get_checksum_node, #on_class, #required_dependency?, #required_dependency_name?, #style_exceptions_dir, #tap_style_exception?, #versioned_formula?
Методы, включённые из HelperFunctions
#block_method_called_in_block?, #check_precedence, #class_name, #component_precedes?, #end_column, #expression_negated?, #find_all_blocks, #find_block, #find_blocks, #find_const, #find_every_func_call_by_name, #find_every_method_call_by_name, #find_instance_call, #find_instance_method_call, #find_method_calls_by_name, #find_method_def, #find_method_with_args, #find_node_method_by_name, #find_strings, #format_component, #line_number, #line_start_column, #method_called?, #method_called_ever?, #method_name, #node_equals?, #offending_node, #parameters, #parameters_passed?, #problem, #regex_match_group, #source_buffer, #start_column, #string_content
Подробное описание конструкторов
#initialize(config = nil, options = nil) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. Сторонним разработчикам следует по возможности избегать использования этого метода, поскольку он может быть удалён или изменён без предупреждения.
18 19 20 21 22 | # File 'rubocops/components_order.rb', line 18 def initialize(config = nil, = nil) super @present_components = T.let(nil, T.nilable(T::Array[T::Array[RuboCop::AST::Node]])) @offensive_nodes = T.let(nil, T.nilable(T::Array[RuboCop::AST::Node])) end |
Подробное описание методов экземпляра
#audit_formula(formula_nodes) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, так как он может быть удалён или изменён без предупреждения.
Этот метод возвращает неопределённое значение.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | # File 'rubocops/components_order.rb', line 25 def audit_formula(formula_nodes) return if (body_node = formula_nodes.body_node).nil? @present_components, @offensive_nodes = check_order(FORMULA_COMPONENT_PRECEDENCE_LIST, body_node) component_problem @offensive_nodes.fetch(0), @offensive_nodes.fetch(1) if @offensive_nodes component_precedence_list = [ [{ name: :depends_on, type: :method_call }], [{ name: :resource, type: :block_call }], [{ name: :patch, type: :method_call }, { name: :patch, type: :block_call }], ] head_blocks = find_blocks(body_node, :head) head_blocks.each do |head_block| check_block_component_order(FORMULA_COMPONENT_PRECEDENCE_LIST, head_block) end on_system_methods.each do |on_method| on_method_blocks = find_blocks(body_node, on_method) next if on_method_blocks.empty? if on_method_blocks.length > 1 @offensive_node = on_method_blocks.second problem "There can only be one `#{on_method}` block in a formula." end check_on_system_block_content(component_precedence_list, on_method_blocks.fetch(0)) end resource_blocks = find_blocks(body_node, :resource) resource_blocks.each do |resource_block| check_block_component_order(FORMULA_COMPONENT_PRECEDENCE_LIST, resource_block) on_system_blocks = {} on_system_methods.each do |on_method| on_system_blocks[on_method] = find_blocks(resource_block.body, on_method) end if on_system_blocks.empty? # Found nothing. Try without .body as depending on the code, # on_{system} might be in .body or not ... on_system_methods.each do |on_method| on_system_blocks[on_method] = find_blocks(resource_block, on_method) end end next if on_system_blocks.empty? @offensive_node = resource_block on_system_bodies = T.let([], T::Array[[RuboCop::AST::BlockNode, RuboCop::AST::Node]]) on_system_blocks.each_value do |blocks| blocks.each do |on_system_block| on_system_body = on_system_block.body branches = on_system_body.if_type? ? on_system_body.branches : [on_system_body] on_system_bodies += branches.map { |branch| [on_system_block, branch] } end end = T.let(nil, T.nilable(String)) allowed_methods = [ [:url, :sha256], [:url, :mirror, :sha256], [:url, :version, :sha256], [:url, :mirror, :version, :sha256], ] minimum_methods = allowed_methods.first.map { |m| "`#{m}`" }.to_sentence maximum_methods = allowed_methods.last.map { |m| "`#{m}`" }.to_sentence on_system_bodies.each do |on_system_block, on_system_body| method_name = on_system_block.method_name child_nodes = on_system_body.begin_type? ? on_system_body.child_nodes : [on_system_body] if child_nodes.all? { |n| n.send_type? || n.block_type? || n.lvasgn_type? } method_names = child_nodes.filter_map do |node| next if node.lvasgn_type? next if node.method_name == :patch next if on_system_methods.include? node.method_name node.method_name end next if method_names.empty? || allowed_methods.include?(method_names) end offending_node(on_system_block) = "`#{method_name}` blocks within `resource` blocks must contain at least " \ "#{minimum_methods} and at most #{maximum_methods} (in order)." break end if problem next end on_system_blocks.each do |on_method, blocks| if blocks.length > 1 problem "There can only be one `#{on_method}` block in a resource block." next end end end end |
#check_block_component_order(component_precedence_list, block) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, так как он может быть удалён или изменён без предупреждения.
Этот метод возвращает неопределённое значение.
135 136 137 138 | # File 'rubocops/components_order.rb', line 135 def check_block_component_order(component_precedence_list, block) @present_components, offensive_node = check_order(component_precedence_list, block.body) component_problem(*offensive_node) if offensive_node end |
#check_on_system_block_content(component_precedence_list, on_system_block) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, так как он может быть удалён или изменён без предупреждения.
Этот метод возвращает неопределённое значение.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | # File 'rubocops/components_order.rb', line 146 def check_on_system_block_content(component_precedence_list, on_system_block) if on_system_block.body.block_type? && !on_system_methods.include?(on_system_block.body.method_name) && on_system_block.body.method_name != :fails_with offending_node(on_system_block) problem "Nest `#{on_system_block.method_name}` blocks inside `#{on_system_block.body.method_name}` " \ "blocks when there is only one inner block." do |corrector| original_source = on_system_block.source.split("\n") new_source = [original_source.second, original_source.first, *original_source.drop(2)] corrector.replace(on_system_block.source_range, new_source.join("\n")) end end on_system_allowed_methods = %w[livecheckkeg_onlydisable!deprecate!depends_onconflicts_withfails_withresourcepatchpour_bottle?] on_system_allowed_methods += on_system_methods.map(&:to_s) _, offensive_node = check_order(component_precedence_list, on_system_block.body) component_problem(*offensive_node) if offensive_node child_nodes = on_system_block.body.begin_type? ? on_system_block.body.child_nodes : [on_system_block.body] child_nodes.each do |child| valid_node = depends_on_node?(child) # Check for RuboCop::AST::SendNode and RuboCop::AST::BlockNode instances # only, as we are checking the method_name for `patch`, `resource`, etc. method_type = child.send_type? || child.block_type? next unless method_type valid_node ||= on_system_allowed_methods.include? child.method_name.to_s @offensive_node = child next if valid_node problem "`#{on_system_block.method_name}` cannot include `#{child.method_name}`. " \ "Only #{on_system_allowed_methods.map { |m| "`#{m}`" }.to_sentence} are allowed." end end |
#check_order(component_precedence_list, body_node) ⇒ Array<(Array<Array<RuboCop::AST::Node>>, Array<RuboCop::AST::Node>)>?
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, так как он может быть удалён или изменён без предупреждения.
230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | # File 'rubocops/components_order.rb', line 230 def check_order(component_precedence_list, body_node) present_components = component_precedence_list.map do |components| components.flat_map do |component| case component[:type] when :method_call find_method_calls_by_name(body_node, component[:name]).to_a when :block_call find_blocks(body_node, component[:name]).to_a when :method_definition find_method_def(body_node, component[:name]) end end.compact end # Check if each present_components is above rest of the present_components offensive_nodes = T.let(nil, T.nilable(T::Array[RuboCop::AST::Node])) present_components.take(present_components.size - 1).each_with_index do |preceding_component, p_idx| next if preceding_component.empty? present_components.drop(p_idx + 1).each do |succeeding_component| next if succeeding_component.empty? offensive_nodes = check_precedence(preceding_component, succeeding_component) return [present_components, offensive_nodes] if offensive_nodes end end nil end |
#component_problem(component1, component2) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, поскольку он может быть удалён или изменён без предупреждения.
Метод возвращает неопределённое значение.
Метод для выявления и исправления нарушений приоритета компонентов.
261 262 263 264 265 266 267 268 269 | # File 'rubocops/components_order.rb', line 261 def component_problem(component1, component2) return if tap_style_exception? :components_order_exceptions problem "`#{format_component(component1)}` (line #{line_number(component1)}) " \ "should be put before `#{format_component(component2)}` " \ "(line #{line_number(component2)})" do |corrector| reorder_components(corrector, component1, component2) end end |
#depends_on_node?(node, **kwargs, &block) ⇒ T.untyped
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, поскольку он может быть удалён или изменён без предупреждения.
10 | # File 'sorbet/rbi/dsl/rubo_cop/cop/formula_audit/components_order.rbi', line 10 def depends_on_node?(node, **kwargs, &block); end |
#get_state(node1) ⇒ Array<(Integer, Integer, Array<RuboCop::AST::Node>)>
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, поскольку он может быть удалён или изменён без предупреждения.
Возвращает индекс приоритета и индекс компонента для правильной переупорядочивания и группировки при автоматическом исправлении.
217 218 219 220 221 222 | # File 'rubocops/components_order.rb', line 217 def get_state(node1) T.must(@present_components).each_with_index do |comp, idx| return [idx, T.must(comp.index(node1)), comp] if comp.member?(node1) end raise "Could not find node1 in present_components" end |
#reorder_components(corrector, node1, node2) ⇒ void
Этот метод является частью закрытого API. Этот метод можно использовать только в репозитории Homebrew/brew. По возможности сторонним разработчикам следует избегать использования этого метода, поскольку он может быть удалён или изменён без предупреждения.
Метод возвращает неопределённое значение.
Меняет порядок двух узлов в исходном коде с помощью экземпляра corrector в методе автоматического исправления. При переписывании исходного кода компоненты одного типа группируются вместе. Если компоненты относятся к двум разным методам, блокам или многострочным выражениям, добавляются переводы строк.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | # File 'rubocops/components_order.rb', line 194 def reorder_components(corrector, node1, node2) # order_idx : node1's index in component_precedence_list # curr_p_idx: node1's index in preceding_comp_arr # preceding_comp_arr: array containing components of same type order_idx, curr_p_idx, preceding_comp_arr = get_state(node1) # curr_p_idx.positive? means node1 needs to be grouped with its own kind if curr_p_idx.positive? node2 = preceding_comp_arr.fetch(curr_p_idx - 1) indentation = "" * (start_column(node2) - line_start_column(node2)) line_breaks = node2.multiline? ? "\n\n" : "\n" corrector.insert_after(node2.source_range, line_breaks + indentation + node1.source) else indentation = "" * (start_column(node2) - line_start_column(node2)) # No line breaks up to version_scheme, order_idx == 8 line_breaks = (order_idx > 8) ? "\n\n" : "\n" corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation) end corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left)) end |
© 2009–present Homebrew contributors
Licensed under the BSD 2-Clause License.
https://docs.brew.sh/rubydoc/RuboCop/Cop/FormulaAudit/ComponentsOrder.html