Module: MilkTea::Linter::LinterReservedNames
- Included in:
- MilkTea::Linter
- Defined in:
- lib/milk_tea/tooling/linter/reserved_names.rb
Instance Method Summary collapse
- #declare_reserved_import_alias_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
- #declare_reserved_module_binding(name, kind_label:, line:, column:, unavailable_names:, reserved_names:) ⇒ Object
- #declare_reserved_primitive_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
- #declare_reserved_value_type_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
- #next_available_reserved_primitive_name(base_name, unavailable_names) ⇒ Object
- #record_reserved_primitive_identifier_use(binding, identifier) ⇒ Object
- #register_reserved_primitive_name_fix(binding, kind_label:, replacement_name:) ⇒ Object
- #resolve_reserved_primitive_name_conflicts!(declared_name) ⇒ Object
- #suggested_reserved_primitive_name(name, kind_label:) ⇒ Object
- #visible_binding_names(excluding_name: nil) ⇒ Object
- #visible_bindings ⇒ Object
- #warn_large_event_capacity(event_decl, owner_name:) ⇒ Object
- #warn_redundant_ignored_match_binding(name, line:, column:) ⇒ Object
- #warn_reserved_primitive_name(name, line:, column:, kind_label:, reserved_names: RESERVED_VALUE_TYPE_NAMES) ⇒ Object
- #warn_reserved_primitive_type_params(type_params, kind_label:) ⇒ Object
Instance Method Details
#declare_reserved_import_alias_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
17 18 19 20 21 22 23 24 25 26 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 17 def declare_reserved_import_alias_module_binding(name, kind_label:, line:, column:, unavailable_names:) declare_reserved_module_binding( name, kind_label:, line:, column:, unavailable_names:, reserved_names: RESERVED_IMPORT_ALIAS_NAMES, ) end |
#declare_reserved_module_binding(name, kind_label:, line:, column:, unavailable_names:, reserved_names:) ⇒ Object
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 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 28 def declare_reserved_module_binding(name, kind_label:, line:, column:, unavailable_names:, reserved_names:) replacement_name = nil replacement_base_name = nil if reserved_names.include?(name) replacement_base_name = suggested_reserved_primitive_name(name, kind_label:) replacement_name = next_available_reserved_primitive_name( replacement_base_name, unavailable_names, ) end binding = Binding.new( name:, line:, column:, used: false, binding_kind: :module, allow_prefer_let: false, mutated: false, replacement_name:, replacement_base_name:, ) register_reserved_primitive_name_fix(binding, kind_label:, replacement_name:) if replacement_name @module_bindings[name] = binding end |
#declare_reserved_primitive_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
54 55 56 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 54 def declare_reserved_primitive_module_binding(name, kind_label:, line:, column:, unavailable_names:) declare_reserved_value_type_module_binding(name, kind_label:, line:, column:, unavailable_names:) end |
#declare_reserved_value_type_module_binding(name, kind_label:, line:, column:, unavailable_names:) ⇒ Object
6 7 8 9 10 11 12 13 14 15 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 6 def declare_reserved_value_type_module_binding(name, kind_label:, line:, column:, unavailable_names:) declare_reserved_module_binding( name, kind_label:, line:, column:, unavailable_names:, reserved_names: RESERVED_VALUE_TYPE_NAMES, ) end |
#next_available_reserved_primitive_name(base_name, unavailable_names) ⇒ Object
142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 142 def next_available_reserved_primitive_name(base_name, unavailable_names) unavailable = unavailable_names.to_set return base_name unless unavailable.include?(base_name) suffix = 2 loop do candidate = "#{base_name}_#{suffix}" return candidate unless unavailable.include?(candidate) suffix += 1 end end |
#record_reserved_primitive_identifier_use(binding, identifier) ⇒ Object
185 186 187 188 189 190 191 192 193 194 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 185 def record_reserved_primitive_identifier_use(binding, identifier) return unless binding.fix_index return unless identifier&.line && identifier&.column @reserved_primitive_name_fixes[binding.fix_index].sites << ReservedPrimitiveNameSite.new( line: identifier.line, column: identifier.column, length: binding.name.length, ) end |
#register_reserved_primitive_name_fix(binding, kind_label:, replacement_name:) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 118 def register_reserved_primitive_name_fix(binding, kind_label:, replacement_name:) warn_reserved_primitive_name(binding.name, line: binding.line, column: binding.column, kind_label:) return unless binding.line && binding.column binding.fix_index = @reserved_primitive_name_fixes.length @reserved_primitive_name_fixes << ReservedPrimitiveNameFix.new( kind: kind_label, original_name: binding.name, replacement_name: replacement_name, sites: [ReservedPrimitiveNameSite.new(line: binding.line, column: binding.column, length: binding.name.length)], ) end |
#resolve_reserved_primitive_name_conflicts!(declared_name) ⇒ Object
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 168 def resolve_reserved_primitive_name_conflicts!(declared_name) visible_bindings.each do |binding| next unless binding.replacement_name == declared_name replacement_name = next_available_reserved_primitive_name( binding.replacement_base_name || binding.replacement_name, visible_binding_names(excluding_name: binding.name), ) next if replacement_name == binding.replacement_name binding.replacement_name = replacement_name next unless binding.fix_index fix = @reserved_primitive_name_fixes[binding.fix_index] @reserved_primitive_name_fixes[binding.fix_index] = fix.with(replacement_name:) end end |
#suggested_reserved_primitive_name(name, kind_label:) ⇒ Object
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 131 def suggested_reserved_primitive_name(name, kind_label:) case kind_label when "function" "#{name}_fn" when "import alias" "#{name}_module" else "#{name}_value" end end |
#visible_binding_names(excluding_name: nil) ⇒ Object
155 156 157 158 159 160 161 162 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 155 def visible_binding_names(excluding_name: nil) names = visible_bindings.each_with_object(Set.new) do |binding, result| result << binding.name result << binding.replacement_name if binding.replacement_name end names.delete(excluding_name) if excluding_name names end |
#visible_bindings ⇒ Object
164 165 166 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 164 def visible_bindings @module_bindings.values + @scopes.flat_map(&:values) end |
#warn_large_event_capacity(event_decl, owner_name:) ⇒ Object
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 72 def warn_large_event_capacity(event_decl, owner_name:) label = owner_name ? "#{owner_name}.#{event_decl.name}" : event_decl.name @warnings << Warning.new( path: @path, line: event_decl.line, column: event_decl.column, length: event_decl.name.length, code: "event-capacity", message: "event '#{label}' capacity #{event_decl.capacity} makes emit() copy up to #{event_decl.capacity} listeners onto the stack; prefer a smaller fixed capacity or a managed queue abstraction", severity: :warning, symbol_name: event_decl.name, ) end |
#warn_redundant_ignored_match_binding(name, line:, column:) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 87 def warn_redundant_ignored_match_binding(name, line:, column:) return unless name == "_" span = nil if line && column source_line = @source_lines[line - 1].to_s span = self.class.redundant_ignored_match_binding_span(source_line, column:) end @warnings << Warning.new( path: @path, line:, column: span ? span[:start_char] + 1 : column, length: span ? span[:end_char] - span[:start_char] : 1, code: "redundant-ignored-match-binding", message: "ignored match binding is redundant; remove 'as _'", severity: :hint, ) end |
#warn_reserved_primitive_name(name, line:, column:, kind_label:, reserved_names: RESERVED_VALUE_TYPE_NAMES) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 57 def warn_reserved_primitive_name(name, line:, column:, kind_label:, reserved_names: RESERVED_VALUE_TYPE_NAMES) return unless reserved_names.include?(name) @warnings << Warning.new( path: @path, line:, column:, length: name.length, code: "reserved-primitive-name", message: "#{kind_label} '#{name}' uses reserved built-in type name '#{name}'; rename it before this becomes a hard error", severity: :warning, symbol_name: name, ) end |
#warn_reserved_primitive_type_params(type_params, kind_label:) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/milk_tea/tooling/linter/reserved_names.rb', line 107 def warn_reserved_primitive_type_params(type_params, kind_label:) Array(type_params).each do |type_param| warn_reserved_primitive_name( type_param.name, line: type_param.line, column: type_param.column, kind_label:, reserved_names: RESERVED_VALUE_TYPE_NAMES, ) end end |