import_js 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7281a4ddb53f991a2649b7fe3be8a49299cc5e4a
4
- data.tar.gz: 44a9e946d556775eda9572bdd1fd411fff8434ff
3
+ metadata.gz: 0c2841cf4974c8a53e788a4ec74e78091948e470
4
+ data.tar.gz: 97e8905dc410a022a31522585054fda588a622c9
5
5
  SHA512:
6
- metadata.gz: 768713a538e2e4c13eeb3fcb8d73df611a679add1f0a2bc65476c3c859f68aa260d61837e94b38aebdad234e776249347adccba2574c78817171ade902fc199c
7
- data.tar.gz: 198423cbd91368c37904ff26f9e2ceaf2bbcb83b4d9db37be3e26ee094b9341ebd7f75360021a67fc99bd61700fe07dff3fd3bfc56c36f29926dcf533964d6e1
6
+ metadata.gz: a0c6a2f736161c17bf7ad89b0921c36295618930f1b598c565e748e25ea74837662b78d835c9801464ced440bb8c2e52461942e75c598c3a80294229b5858603
7
+ data.tar.gz: 9695778534d541cf215728512635f7d78b01e4f2c72ab315021e2d5b2900170e5db7379a4205e06b9ec7c1393b2ca31527519235a7a167670f31267e7856411d
@@ -26,10 +26,22 @@ module ImportJS
26
26
  ;?\s*
27
27
  }xm
28
28
 
29
+ REGEX_DESTRUCTURE = %r{
30
+ (?: # non-capturing group
31
+ (?<default>.*?) # <default> variable
32
+ ,\s*
33
+ )?
34
+ \{
35
+ \s*
36
+ (?<destructured>.*) # <destructured> variables
37
+ \s*
38
+ \}
39
+ }x
40
+
29
41
  attr_accessor :assignment
30
42
  attr_accessor :original_import_string # a cache of the parsed import string
31
- attr_accessor :variables
32
- attr_accessor :is_destructured # can't use `destructured?` because of 1.9.3
43
+ attr_accessor :default_variable
44
+ attr_accessor :destructured_variables
33
45
  attr_accessor :path
34
46
 
35
47
  # @param string [String] a possible import statement, e.g.
@@ -45,66 +57,123 @@ module ImportJS
45
57
  statement.original_import_string = match.string
46
58
  statement.path = match[:path]
47
59
  statement.assignment = match[:assignment]
48
- if dest_match = statement.assignment.match(/\{\s*(.*)\s*\}/)
49
- statement.variables = dest_match[1].split(/,\s*/).map(&:strip)
50
- statement.is_destructured = true
60
+ if dest_match = statement.assignment.match(REGEX_DESTRUCTURE)
61
+ statement.default_variable = dest_match[:default]
62
+ statement.destructured_variables =
63
+ dest_match[:destructured].split(/,\s*/).map(&:strip)
51
64
  else
52
- statement.variables = [statement.assignment]
65
+ statement.default_variable = statement.assignment
53
66
  end
54
67
  statement
55
68
  end
56
69
 
70
+ # Sets the default_variable and clears the original import string cache.
71
+ # @param value [String]
72
+ def set_default_variable(value)
73
+ @default_variable = value
74
+ @original_import_string = nil # clear import string cache if there was one
75
+ end
76
+
57
77
  # Injects a new variable into an already existing set of destructured
58
78
  # variables.
59
79
  # @param variable_name [String]
60
- def inject_variable(variable_name)
61
- variables << variable_name
62
- variables.sort!.uniq!
80
+ def inject_destructured_variable(variable_name)
81
+ @destructured_variables ||= []
82
+ destructured_variables << variable_name
83
+ destructured_variables.sort!.uniq!
63
84
 
64
85
  @original_import_string = nil # clear import string cache if there was one
65
86
  end
66
87
 
67
- # Deletes a variable from an already existing set of destructured
68
- # variables.
88
+ # Deletes a variable from an already existing default variable or set of
89
+ # destructured variables.
69
90
  # @param variable_name [String]
70
91
  def delete_variable(variable_name)
71
- variables.delete(variable_name)
92
+ @default_variable = nil if default_variable == variable_name
93
+ @destructured_variables.delete(variable_name) unless destructured_variables.nil?
72
94
 
73
95
  @original_import_string = nil # clear import string cache if there was one
74
96
  end
75
97
 
98
+ # @return [Boolean] true if there are destructured variables
99
+ def destructured?
100
+ !destructured_variables.nil? && !destructured_variables.empty?
101
+ end
102
+
103
+ # @return [Boolean] true if there is no default variable and there are no
104
+ # destructured variables
105
+ def empty?
106
+ default_variable.nil? && !destructured?
107
+ end
108
+
76
109
  # @return [Array] an array that can be used in `uniq!` to dedupe equal
77
110
  # statements, e.g.
78
111
  # `const foo = require('foo');`
79
112
  # `import foo from 'foo';`
80
- def normalize
81
- [variables, path]
113
+ def to_normalized
114
+ [default_variable, destructured_variables, path]
82
115
  end
83
116
 
84
117
  # @param declaration_keyword [String] const, let, var, or import
85
118
  # @param max_line_length [Number] where to cap lines at
86
119
  # @param tab [String] e.g. ' ' (two spaces)
87
- # @return a generated import statement string
88
- def to_import_string(declaration_keyword, max_line_length, tab)
89
- return original_import_string if original_import_string
90
-
91
- declaration = if is_destructured
92
- "#{declaration_keyword} { #{variables.join(', ')} }"
93
- else
94
- "#{declaration_keyword} #{variables.first}"
95
- end
96
-
97
- equals, value = if declaration_keyword == 'import'
98
- ['from', "'#{path}';"]
99
- else
100
- ['=', "require('#{path}');"]
101
- end
120
+ # @return [Array] generated import statement strings
121
+ def to_import_strings(declaration_keyword, max_line_length, tab)
122
+ return [original_import_string] if original_import_string
123
+
124
+ if declaration_keyword == 'import'
125
+ # ES2015 Modules (ESM) syntax can support default values and
126
+ # destructuring on the same line.
127
+ declaration = declaration_keyword
128
+ if destructured?
129
+ declaration += " #{default_variable}," if default_variable
130
+ declaration += " #{destructured_string}"
131
+ else
132
+ declaration += " #{default_variable}"
133
+ end
134
+ declaration += ' from'
135
+
136
+ [wrap_import(declaration, "'#{path}';", max_line_length, tab)]
137
+ else # const/let/var
138
+ value = "require('#{path}');"
102
139
 
140
+ if destructured? && !default_variable.nil?
141
+ # We have both a default variable and a destructuring to do, so we
142
+ # need to generate 2 lines for CommonJS style syntax.
143
+ default_declaration = "#{declaration_keyword} #{default_variable} ="
144
+ destructured_declaration = "#{declaration_keyword} #{destructured_string} ="
145
+
146
+ return [
147
+ wrap_import(default_declaration, value, max_line_length, tab),
148
+ wrap_import(destructured_declaration, value, max_line_length, tab)
149
+ ]
150
+ end
151
+
152
+ declaration_assignment =
153
+ destructured? ? destructured_string : default_variable
154
+ declaration = "#{declaration_keyword} #{declaration_assignment} ="
155
+ [wrap_import(declaration, value, max_line_length, tab)]
156
+ end
157
+ end
158
+
159
+ private
160
+
161
+ # @return [String]
162
+ def destructured_string
163
+ "{ #{destructured_variables.join(', ')} }"
164
+ end
165
+
166
+ # @param declaration [String]
167
+ # @param value [String]
168
+ # @param max_line_length [Number] where to cap lines at
169
+ # @param tab [String] e.g. ' ' (two spaces)
170
+ # @return [String] import statement, wrapped at max line length if necessary
171
+ def wrap_import(declaration, value, max_line_length, tab)
103
172
  if max_line_length &&
104
- "#{declaration} #{equals} #{value}".length > max_line_length
105
- "#{declaration} #{equals}\n#{tab}#{value}"
173
+ "#{declaration} #{value}".length > max_line_length
174
+ "#{declaration}\n#{tab}#{value}"
106
175
  else
107
- "#{declaration} #{equals} #{value}"
176
+ "#{declaration} #{value}"
108
177
  end
109
178
  end
110
179
  end
@@ -68,7 +68,7 @@ module ImportJS
68
68
  unused_variables.each do |unused_variable|
69
69
  import_statement.delete_variable(unused_variable)
70
70
  end
71
- import_statement.variables.empty?
71
+ import_statement.empty?
72
72
  end
73
73
 
74
74
  undefined_variables.each do |variable|
@@ -128,18 +128,25 @@ module ImportJS
128
128
  resolve_one_js_module(js_modules, variable_name)
129
129
  end
130
130
 
131
+ # Add new import to the block of imports, wrapping at the max line length
131
132
  # @param variable_name [String]
132
133
  # @param js_module [ImportJS::JSModule]
133
134
  # @param imports [Array<ImportJS::ImportStatement>]
134
135
  def inject_js_module(variable_name, js_module, imports)
135
- # Add new import to the block of imports, wrapping at the max line length
136
- unless js_module.is_destructured && inject_destructured_variable(
137
- variable_name, js_module, imports)
136
+ import = imports.find { |import| import.path == js_module.import_path }
137
+
138
+ if import
139
+ if js_module.is_destructured
140
+ import.inject_destructured_variable(variable_name)
141
+ else
142
+ import.set_default_variable(variable_name)
143
+ end
144
+ else
138
145
  imports.unshift(js_module.to_import_statement(variable_name))
139
146
  end
140
147
 
141
148
  # Remove duplicate import statements
142
- imports.uniq!(&:normalize)
149
+ imports.uniq!(&:to_normalized)
143
150
  end
144
151
 
145
152
  # @param old_imports_lines [Number]
@@ -154,11 +161,11 @@ module ImportJS
154
161
 
155
162
  # Generate import strings
156
163
  import_strings = new_imports.map do |import|
157
- import.to_import_string(
164
+ import.to_import_strings(
158
165
  @config.get('declaration_keyword'),
159
166
  @editor.max_line_length,
160
167
  @editor.tab)
161
- end.sort
168
+ end.flatten.sort
162
169
 
163
170
  # Delete old imports, then add the modified list back in.
164
171
  old_imports_lines.times { @editor.delete_line(1 + imports_start_at) }
@@ -171,17 +178,6 @@ module ImportJS
171
178
  end
172
179
  end
173
180
 
174
- def inject_destructured_variable(variable_name, js_module, imports)
175
- imports.each do |import|
176
- next unless import.path == js_module.import_path
177
- next unless import.is_destructured
178
-
179
- import.inject_variable(variable_name)
180
- return true
181
- end
182
- false
183
- end
184
-
185
181
  # @return [Hash]
186
182
  def find_current_imports
187
183
  potential_import_lines = []
@@ -208,13 +204,32 @@ module ImportJS
208
204
 
209
205
  # Scan potential imports for everything ending in a semicolon, then
210
206
  # iterate through those and stop at anything that's not an import.
207
+ imports = {}
211
208
  potential_imports_blob.scan(/^.*?;/m).each do |potential_import|
212
209
  import_statement = ImportJS::ImportStatement.parse(potential_import)
213
210
  break unless import_statement
214
211
 
215
- result[:imports] << import_statement
212
+ if imports[import_statement.path]
213
+ # Import already exists, so this line is likely one of a destructuring
214
+ # pair. Combine it into the same ImportStatement.
215
+ unless import_statement.default_variable.nil?
216
+ imports[import_statement.path].default_variable =
217
+ import_statement.default_variable
218
+ end
219
+
220
+ if import_statement.destructured?
221
+ imports[import_statement.path].destructured_variables ||= []
222
+ imports[import_statement.path].destructured_variables
223
+ .concat(import_statement.destructured_variables)
224
+ end
225
+ else
226
+ # This is a new import, so we just add it to the hash.
227
+ imports[import_statement.path] = import_statement
228
+ end
229
+
216
230
  result[:newline_count] += potential_import.scan(/\n/).length + 1
217
231
  end
232
+ result[:imports] = imports.values
218
233
  result
219
234
  end
220
235
 
@@ -51,8 +51,11 @@ module ImportJS
51
51
  # @return [ImportJS::ImportStatement]
52
52
  def to_import_statement(variable_name)
53
53
  ImportJS::ImportStatement.new.tap do |statement|
54
- statement.is_destructured = is_destructured
55
- statement.variables = [variable_name]
54
+ if is_destructured
55
+ statement.inject_destructured_variable(variable_name)
56
+ else
57
+ statement.default_variable = variable_name
58
+ end
56
59
  statement.path = import_path
57
60
  end
58
61
  end
@@ -1,4 +1,4 @@
1
1
  # Defines the gem version.
2
2
  module ImportJS
3
- VERSION = '0.2.2'
3
+ VERSION = '0.2.3'
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: import_js
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henric Trotzig