Class: ImportJS::Importer

Inherits:
Object
  • Object
show all
Defined in:
lib/import_js/importer.rb

Constant Summary collapse

REGEX_ESLINT_RESULT =
/
  :
  (?<line>\d+)                # <line> line number
  :\d+:
  \s
  (?<quote>["'])              # <quote> opening quote
  (?<variable_name>[^\1]+)    # <variable_name>
  \k<quote>
  \s
  (?<type>                    # <type>
   is\sdefined\sbut\snever\sused         # is defined but never used
   |
   is\snot\sdefined                      # is not defined
   |
   must\sbe\sin\sscope\swhen\susing\sJSX # must be in scope when using JSX
  )
/x

Instance Method Summary collapse

Constructor Details

#initialize(editor = VIMEditor.new) ⇒ Importer

Returns a new instance of Importer.



8
9
10
# File 'lib/import_js/importer.rb', line 8

def initialize(editor = VIMEditor.new)
  @editor = editor
end

Instance Method Details

#fix_importsObject

Removes unused imports and adds imports for undefined variables



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
# File 'lib/import_js/importer.rb', line 76

def fix_imports
  reload_config
  eslint_result = run_eslint_command

  return if eslint_result.empty?

  unused_variables = {}
  undefined_variables = Set.new

  eslint_result.each do |line|
    match = REGEX_ESLINT_RESULT.match(line)
    next unless match
    if match[:type] == 'is defined but never used'
      unused_variables[match[:variable_name]] ||= Set.new
      unused_variables[match[:variable_name]].add match[:line].to_i
    else
      undefined_variables.add match[:variable_name]
    end
  end

  return if unused_variables.empty? && undefined_variables.empty?

  old_imports = find_current_imports

  # Filter out unused variables that do not appear within the imports block.
  unused_variables.select! do |_, line_numbers|
    any_numbers_within_range?(line_numbers, old_imports[:range])
  end

  new_imports = old_imports[:imports].clone
  new_imports.delete_variables!(unused_variables.keys)

  undefined_variables.each do |variable|
    js_module = find_one_js_module(variable)
    next unless js_module
    new_imports << js_module.to_import_statement(variable, @config)
  end

  replace_imports(old_imports[:range], new_imports)
end

#gotoObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/import_js/importer.rb', line 36

def goto
  reload_config
  js_modules = []
  variable_name = @editor.current_word
  time do
    js_modules = find_js_modules_for(variable_name)
  end

  js_module = resolve_module_using_current_imports(
    js_modules, variable_name)

  unless js_module
    # The current word is not mappable to one of the JS modules that we
    # found. This can happen if the user does not select one from the list.
    # We have nothing to go to, so we return early.
    return message("Could not resolve a module for `#{variable_name}`")
  end

  @editor.open_file(js_module.open_file_path(@editor.path_to_current_file))
end

#importObject

Finds variable under the cursor to import. By default, this is bound to ‘<Leader>j`.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/import_js/importer.rb', line 14

def import
  reload_config
  variable_name = @editor.current_word
  if variable_name.empty?
    message(<<-EOS.split.join(' '))
      No variable to import. Place your cursor on a variable, then try
      again.
    EOS
    return
  end

  js_module = find_one_js_module(variable_name)
  return unless js_module

  maintain_cursor_position do
    old_imports = find_current_imports
    import_statement = js_module.to_import_statement(variable_name, @config)
    old_imports[:imports] << import_statement
    replace_imports(old_imports[:range], old_imports[:imports])
  end
end

#rewrite_importsObject



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/import_js/importer.rb', line 117

def rewrite_imports
  reload_config

  old_imports = find_current_imports
  new_imports = old_imports[:imports].clone

  old_imports[:imports].each do |import|
    import.variables.each do |variable|
      js_module = resolve_module_using_current_imports(
        find_js_modules_for(variable), variable)
      next unless js_module
      new_imports << js_module.to_import_statement(variable, @config)
    end
  end

  replace_imports(old_imports[:range], new_imports)
end