vinter 0.1.0 → 0.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/vinter/parser.rb +165 -14
  4. data/lib/vinter.rb +1 -1
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0916f02e9f17998516fc27eb0d2b2ec2807d1f4ae3ab12050590556c6d78e0ba'
4
- data.tar.gz: 21cec3329527181dde80ebe5e12d5dba094c4596c1bcb725a1ef7dc95505b43e
3
+ metadata.gz: 503bb79a2701783c22c7ef7f269bfc51dc93a72d68abc61286c4c0236aaa4d8f
4
+ data.tar.gz: f9f58293732eb9179228ec8e4c04bd87f279fc2e7edf65dc9969d1fe6f680b66
5
5
  SHA512:
6
- metadata.gz: ce1879809bfc52ff91ad591bbd862ef347cfc8a6595a042cd7bc9efb0c9bb95824ee177844a5499b9264c9dc3c81f4e5bda1b7ccbdb9a85800ab2a87697d07d0
7
- data.tar.gz: 10741136273e679ba2cf0c334e4ba815a9ba8fae25ba677fb0d7bd9f441bd912cff8c87e8919c27db110b6bab066102de5188f23305cbde76542793a4a4cb7c2
6
+ metadata.gz: 577a51ca98e7bd940ab48a6482978c5f098fbba5c5e6921105950086f92cc327e44edf10259a3aafdf6fe8ff068690fb5d8b387aed85f5e07f2fc57b7ea8ce5d
7
+ data.tar.gz: 5f5e7316bd62168356532c07186e0a3ff03c2c4a49c8d43d7dff51d64f261bf9368598b80acc69ebcc802af64d5ef0906f8422a0c78e2401d87429668721e3f6
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Vinter
2
2
 
3
- A Ruby gem that provides linting capabilities for Vim9 script files. This linter helps identify syntax errors and enforce best practices for the new Vim9 script language introduced in Vim 9.0.
3
+ A Ruby gem that provides linting capabilities for Vim9 script files. This linter helps identify syntax errors and enforce best practices for for Vim9 script.
4
4
 
5
5
  ## Features
6
6
 
@@ -24,7 +24,7 @@ gem install vinter
24
24
  Lint a Vim9 script file:
25
25
 
26
26
  ```bash
27
- vim9-lint path/to/your/script.vim
27
+ vinter path/to/your/script.vim
28
28
  ```
29
29
 
30
30
  ### Ruby API
@@ -33,7 +33,7 @@ vim9-lint path/to/your/script.vim
33
33
  require 'vinter'
34
34
 
35
35
  content = File.read('path/to/your/script.vim')
36
- linter = Vim9Linter::Linter.new
36
+ linter = Vinter::Linter.new
37
37
  issues = linter.lint(content)
38
38
 
39
39
  issues.each do |issue|
data/lib/vinter/parser.rb CHANGED
@@ -180,6 +180,157 @@ module Vinter
180
180
  }
181
181
  end
182
182
 
183
+ def parse_while_statement
184
+ token = advance # Skip 'while'
185
+ line = token[:line]
186
+ column = token[:column]
187
+ condition = parse_expression
188
+
189
+ body = []
190
+
191
+ # Parse statements until we hit 'endwhile'
192
+ while @position < @tokens.length
193
+ if current_token[:type] == :keyword && current_token[:value] == 'endwhile'
194
+ break
195
+ end
196
+
197
+ stmt = parse_statement
198
+ body << stmt if stmt
199
+ end
200
+
201
+ # Expect endwhile
202
+ expect(:keyword) # This should be 'endwhile'
203
+
204
+ {
205
+ type: :while_statement,
206
+ condition: condition,
207
+ body: body,
208
+ line: line,
209
+ column: column
210
+ }
211
+ end
212
+
213
+ def parse_for_statement
214
+ token = advance # Skip 'for'
215
+ line = token[:line]
216
+ column = token[:column]
217
+
218
+ # Parse the loop variable(s)
219
+ if current_token && current_token[:type] == :paren_open
220
+ # Handle tuple assignment: for (key, val) in dict
221
+ advance # Skip '('
222
+
223
+ loop_vars = []
224
+
225
+ loop do
226
+ if current_token && current_token[:type] == :identifier
227
+ loop_vars << advance[:value]
228
+ else
229
+ @errors << {
230
+ message: "Expected identifier in for loop variables",
231
+ position: @position,
232
+ line: current_token ? current_token[:line] : 0,
233
+ column: current_token ? current_token[:column] : 0
234
+ }
235
+ break
236
+ end
237
+
238
+ if current_token && current_token[:type] == :comma
239
+ advance # Skip ','
240
+ else
241
+ break
242
+ end
243
+ end
244
+
245
+ expect(:paren_close) # Skip ')'
246
+
247
+ if !current_token || (current_token[:type] != :identifier || current_token[:value] != 'in')
248
+ @errors << {
249
+ message: "Expected 'in' after for loop variables",
250
+ position: @position,
251
+ line: current_token ? current_token[:line] : 0,
252
+ column: current_token ? current_token[:column] : 0
253
+ }
254
+ else
255
+ advance # Skip 'in'
256
+ end
257
+
258
+ iterable = parse_expression
259
+
260
+ # Parse the body until 'endfor'
261
+ body = []
262
+ while @position < @tokens.length
263
+ if current_token[:type] == :keyword && current_token[:value] == 'endfor'
264
+ break
265
+ end
266
+
267
+ stmt = parse_statement
268
+ body << stmt if stmt
269
+ end
270
+
271
+ # Expect endfor
272
+ expect(:keyword) # This should be 'endfor'
273
+
274
+ return {
275
+ type: :for_statement,
276
+ loop_vars: loop_vars,
277
+ iterable: iterable,
278
+ body: body,
279
+ line: line,
280
+ column: column
281
+ }
282
+ else
283
+ # Simple for var in list
284
+ if !current_token || current_token[:type] != :identifier
285
+ @errors << {
286
+ message: "Expected identifier as for loop variable",
287
+ position: @position,
288
+ line: current_token ? current_token[:line] : 0,
289
+ column: current_token ? current_token[:column] : 0
290
+ }
291
+ return nil
292
+ end
293
+
294
+ loop_var = advance[:value]
295
+
296
+ if !current_token || (current_token[:type] != :identifier || current_token[:value] != 'in')
297
+ @errors << {
298
+ message: "Expected 'in' after for loop variable",
299
+ position: @position,
300
+ line: current_token ? current_token[:line] : 0,
301
+ column: current_token ? current_token[:column] : 0
302
+ }
303
+ else
304
+ advance # Skip 'in'
305
+ end
306
+
307
+ iterable = parse_expression
308
+
309
+ # Parse the body until 'endfor'
310
+ body = []
311
+ while @position < @tokens.length
312
+ if current_token[:type] == :keyword && current_token[:value] == 'endfor'
313
+ break
314
+ end
315
+
316
+ stmt = parse_statement
317
+ body << stmt if stmt
318
+ end
319
+
320
+ # Expect endfor
321
+ expect(:keyword) # This should be 'endfor'
322
+
323
+ return {
324
+ type: :for_statement,
325
+ loop_var: loop_var,
326
+ iterable: iterable,
327
+ body: body,
328
+ line: line,
329
+ column: column
330
+ }
331
+ end
332
+ end
333
+
183
334
  def parse_def_function
184
335
  token = advance # Skip 'def'
185
336
  line = token[:line]
@@ -541,23 +692,23 @@ module Vinter
541
692
  token = advance # Skip 'import'
542
693
  line = token[:line]
543
694
  column = token[:column]
544
-
695
+
545
696
  # Handle 'import autoload'
546
697
  is_autoload = false
547
698
  module_name = nil
548
699
  path = nil
549
-
700
+
550
701
  if current_token && current_token[:type] == :identifier && current_token[:value] == 'autoload'
551
702
  is_autoload = true
552
703
  module_name = advance[:value] # Store "autoload" as the module name
553
-
704
+
554
705
  # After "autoload" keyword, expect a string path
555
706
  if current_token && current_token[:type] == :string
556
707
  path = current_token[:value]
557
708
  advance
558
709
  else
559
- @errors << {
560
- message: "Expected string path after 'autoload'",
710
+ @errors << {
711
+ message: "Expected string path after 'autoload'",
561
712
  position: @position,
562
713
  line: current_token ? current_token[:line] : 0,
563
714
  column: current_token ? current_token[:column] : 0
@@ -567,11 +718,11 @@ module Vinter
567
718
  # Regular import with a string path
568
719
  if current_token && current_token[:type] == :string
569
720
  path = current_token[:value]
570
-
721
+
571
722
  # Extract module name from the path
572
723
  # This is simplified logic - you might need more complex extraction
573
724
  module_name = path.gsub(/['"]/, '').split('/').last.split('.').first
574
-
725
+
575
726
  advance
576
727
  else
577
728
  # Handle other import formats
@@ -582,7 +733,7 @@ module Vinter
582
733
  end
583
734
  end
584
735
  end
585
-
736
+
586
737
  # Handle 'as name'
587
738
  as_name = nil
588
739
  if current_token && current_token[:type] == :identifier && current_token[:value] == 'as'
@@ -590,17 +741,17 @@ module Vinter
590
741
  if current_token && current_token[:type] == :identifier
591
742
  as_name = advance[:value]
592
743
  else
593
- @errors << {
594
- message: "Expected identifier after 'as'",
744
+ @errors << {
745
+ message: "Expected identifier after 'as'",
595
746
  position: @position,
596
747
  line: current_token ? current_token[:line] : 0,
597
748
  column: current_token ? current_token[:column] : 0
598
749
  }
599
750
  end
600
751
  end
601
-
602
- {
603
- type: :import_statement,
752
+
753
+ {
754
+ type: :import_statement,
604
755
  module: module_name,
605
756
  path: path,
606
757
  is_autoload: is_autoload,
@@ -608,7 +759,7 @@ module Vinter
608
759
  line: line,
609
760
  column: column
610
761
  }
611
- end
762
+ end
612
763
  def parse_export_statement
613
764
  token = advance # Skip 'export'
614
765
  line = token[:line]
data/lib/vinter.rb CHANGED
@@ -4,5 +4,5 @@ require "vinter/linter"
4
4
  require "vinter/cli"
5
5
 
6
6
  module Vinter
7
- VERSION = "0.1.0"
7
+ VERSION = "0.2.0"
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vinter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Bradbury
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-04 00:00:00.000000000 Z
11
+ date: 2025-04-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A linter for the Vim9 script language, helping to identify issues and
14
14
  enforce best practices