oxc 0.1.0 → 0.149.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b3aadc726a7acfc689068f037abe6a3d4b71c80ea7ddb127e29afd58be57202
4
- data.tar.gz: 99bd9e250a6ad906936204dd0095321c0a3abb44e37f22e0018ebecc648ec26c
3
+ metadata.gz: 6b8f1ce3e98c0a406c9064fceaad9230055c4ff578f2be18bceb60a105b74673
4
+ data.tar.gz: 27ae1cbbb8e4a70215f7077cd639fa16da85f7568230ae2d812d834985568840
5
5
  SHA512:
6
- metadata.gz: aa9bcd252eb9f1b6a9cddbff7673fd691359206f25e55992709253dd2f41213252e7af98aea2d1662c22d1380d84fd5ae4075dc32c962fdb29b7b07653abe27a
7
- data.tar.gz: 4491e8c546a899cc58377166dafc4180318cd917111d0c2362c450d7de61d0ce79548b0db621e3dab239d4a35405eb7952a36b21cb3d3a2d95c7f899ee1149f9
6
+ metadata.gz: 3188012da83a08c5654052f3c961099ab0c372d6925d80e37d7550f3b01982bdcf414f81466a46e7c41cd2efce92861d1fd519ce551669c0eb3d5b473785c68c
7
+ data.tar.gz: 75ff1d95c75648ac42cdb56b2c2696f260a1b8ebed0af09ca5b94f891e95e48279a00bbe675c57829cd0d13bd4145f2a75387166baec936eb1f0608781c54fe4
data/README.md CHANGED
@@ -27,6 +27,14 @@ bundle add oxc
27
27
 
28
28
  Anywhere a precompiled gem is not published, the gem builds from source and needs the [Rust toolchain](https://rustup.rs) at 1.96 or newer.
29
29
 
30
+ ### Versioning
31
+
32
+ The gem carries the version of oxc it packages. Gem v0.149.0 bundles oxc v0.149.0, and `Oxc.oxc_version` reports what a given build was compiled against.
33
+
34
+ So the version tracks oxc, not the Ruby API here. A minor bump is a minor oxc release, and says nothing about whether this gem's own API moved. Pin on the oxc version you want.
35
+
36
+ If the gem needs releasing again for the same oxc version, that release adds a fourth digit, as in v0.149.0.1.
37
+
30
38
  ### Usage
31
39
 
32
40
  #### Minifying
@@ -205,6 +213,171 @@ Oxc.parse("let a; let a;", semantic_errors: true).errors.map(&:message)
205
213
  #=> ["Identifier `a` has already been declared"]
206
214
  ```
207
215
 
216
+ #### Walking the AST
217
+
218
+ `root` answers the program as an `Oxc::Node`, which walks, reads its fields by name, and knows what it sits inside.
219
+
220
+ ```ruby
221
+ root = Oxc.parse(source).root
222
+
223
+ root.type #=> "Program"
224
+ root.keys #=> the ESTree fields this node carries
225
+ root.fields #=> those fields and their values, without the span
226
+ root.child_nodes #=> the nodes directly under it
227
+ root.every("Identifier") #=> every identifier in the file
228
+ root.at(offset) #=> the innermost node covering a byte offset
229
+ root.each #=> an Enumerator over every node
230
+ ```
231
+
232
+ Inspecting a node shows every field it carries, so there is always something to reach for next.
233
+
234
+ ```
235
+ #<Oxc::Node VariableDeclaration range=[0, 13] kind="let" declarations=[... 1 item]>
236
+ #<Oxc::Node VariableDeclarator range=[4, 13] id=#<Oxc::Node Identifier> init=#<Oxc::Node Literal>>
237
+ #<Oxc::Node Identifier range=[4, 9] name="count">
238
+ ```
239
+
240
+ Every field is there, so what `inspect` prints and what `keys` answers never disagree. A field holding a node prints as that node's type, one holding a list prints how many it holds, and one holding nothing prints the `nil`, the `false` or the `[]` it holds.
241
+
242
+ An ESTree field always wins over a method of the gem's own, since `name`, `attributes` and `children` are all real fields. `Identifier#name` is the identifier's name, `JSXElement#children` is what the element wraps, and `ImportDeclaration#attributes` is the import's `with` clause. The walker spells its own versions `underscored_type`, `to_h` and `child_nodes`, which no ESTree field can be called.
243
+
244
+ A field comes back as a node when it holds one, so reads chain.
245
+
246
+ ```ruby
247
+ declaration = root.child_nodes.first
248
+
249
+ declaration.kind
250
+ #=> "let"
251
+
252
+ declaration.declarations.first.id.name
253
+ #=> "count"
254
+ ```
255
+
256
+ ESTree names its fields in camelCase, and a field answers to its snake_case name too, so reading an AST does not mean writing JavaScript casing in Ruby.
257
+
258
+ ```ruby
259
+ node.type_annotation # the same field as node.typeAnnotation
260
+ node.super_class # superClass
261
+ root.source_type # sourceType
262
+ ```
263
+
264
+ Patterns take either name as well, binding what you asked for.
265
+
266
+ ```ruby
267
+ node => { type_annotation: { type: }, readonly: }
268
+ ```
269
+
270
+ `ancestors` is what a rewrite needs, since a reference sits inside the expression that has to be replaced.
271
+
272
+ ```ruby
273
+ reference = root.at(source.index("count +="))
274
+ reference.ancestors.find { |node| node.type == "AssignmentExpression" }.slice
275
+ #=> "count += 1"
276
+ ```
277
+
278
+ A parse result keeps the source it read and hands it down to every node it builds, so `slice` answers with no argument at all.
279
+
280
+ ```ruby
281
+ parsed = Oxc.parse(source)
282
+
283
+ parsed.source
284
+ #=> "let count = 0\nfunction bump() { count += 1; render(count) }"
285
+
286
+ parsed.root.every("FunctionDeclaration").first.slice
287
+ #=> "function bump() { count += 1; render(count) }"
288
+ ```
289
+
290
+ It still takes one, for a node assembled by hand or read against a different string.
291
+
292
+ ```ruby
293
+ node.slice(other_source)
294
+ ```
295
+
296
+ Nodes pattern match, and nest, since a field holding a node comes back as one.
297
+
298
+ ```ruby
299
+ node => { type: "VariableDeclarator", id: { name: }, init: { value: } }
300
+ name #=> "count"
301
+ value #=> 0
302
+
303
+ root.select { |node| node in { type: "FunctionDeclaration", id: { name: /^handle/ } } }
304
+ ```
305
+
306
+ `deconstruct_keys` is the whole protocol here. There is no `deconstruct`, since `each` yields every descendant and an array pattern over direct children would disagree with `to_a`.
307
+
308
+ `to_h` and `to_json` answer the ESTree the node wraps, which is what a snapshot test or a dump to another tool wants.
309
+
310
+ ```ruby
311
+ node.to_h
312
+ #=> { "type" => "Identifier", "name" => "count", "start" => 4, "end" => 9 }
313
+
314
+ node.to_json
315
+ #=> "{\"type\":\"Identifier\",\"name\":\"count\",\"start\":4,\"end\":9}"
316
+ ```
317
+
318
+ `Oxc::Visitor` answers a node with the method named after its type, and walks through anything nothing answers.
319
+
320
+ ```ruby
321
+ class Reads < Oxc::Visitor
322
+ def visit_assignment_expression(node)
323
+ puts "#{node.left["name"]} #{node.operator}"
324
+
325
+ visit_children(node)
326
+ end
327
+ end
328
+
329
+ Reads.new.visit(Oxc.parse(source))
330
+ ```
331
+
332
+ It takes a parse result or a node, so the common case needs no `root`. A result with no AST is nothing to walk and visits nothing.
333
+
334
+ There is one node class, not one per type, so a type the gem has never seen still walks and still answers. The types and their fields are [ESTree](https://github.com/estree/estree). For the TypeScript and JSX nodes, which ESTree does not cover, oxc publishes the exact shapes it emits as [`@oxc-project/types`](https://www.npmjs.com/package/@oxc-project/types).
335
+
336
+ #### Rewriting
337
+
338
+ `Oxc::MutationVisitor` records what to do to a node and splices the original text at the end, so everything it did not touch survives byte for byte, comments and indentation included.
339
+
340
+ ```ruby
341
+ class Renamer < Oxc::MutationVisitor
342
+ def visit_identifier(node)
343
+ replace(node, "renamed") if node["name"] == "count"
344
+ end
345
+ end
346
+
347
+ Renamer.new.rewrite("let count = 1 // keep me")
348
+ #=> "let renamed = 1 // keep me"
349
+ ```
350
+
351
+ `replace`, `remove`, `insert_before`, `insert_after` and `wrap` are the operations, and each takes a node. Spans are exact, so removing `debugger;` removes what the node covered and leaves the newline after it alone.
352
+
353
+ Walking into a node that was replaced would edit text that is no longer there, so it stops. Two edits over the same span raise `Oxc::MutationVisitor::Overlap` instead of quietly producing something broken.
354
+
355
+ What goes in is text, so a node can become anything, including several statements or nothing at all. Nothing checks it on the way, so the result is read back afterwards and refused if it stopped being JavaScript.
356
+
357
+ ```ruby
358
+ Breaker.new.rewrite("foo(data)")
359
+ #=> Oxc::MutationVisitor::Invalid: what was rewritten no longer reads as JavaScript: Unexpected token
360
+ ```
361
+
362
+ Pass `verify: false` for a fragment that was never going to parse on its own.
363
+
364
+ `parsed` reaches what the source parsed to, so a rewrite can ask for symbols and drive from them. That is the difference between rewriting a name and rewriting the right one.
365
+
366
+ ```ruby
367
+ class ToState < Oxc::MutationVisitor
368
+ def rewrite(source) = super(source, symbols: true)
369
+
370
+ def visit_identifier(node)
371
+ reference = parsed.symbols.fetch("declared").flat_map { |symbol| symbol["references"] }
372
+ .find { |found| found["start"] == node.start }
373
+
374
+ replace(node, %(state.get("#{node["name"]}"))) if reference && !reference["write"]
375
+ end
376
+ end
377
+ ```
378
+
379
+ Drive from references, not from every `Identifier`. That is what keeps a declaration, a shadowed local, and a same-named property out of the rewrite.
380
+
208
381
  #### What a file declared, and what it only used
209
382
 
210
383
  `symbols: true` answers every binding with the span it was declared at and the spans of every reference to it, plus the names the file used without declaring.
data/ext/oxc/extconf.rb CHANGED
@@ -65,12 +65,12 @@ if target_platform
65
65
 
66
66
  system("rustup target add #{target_platform}") || warn("oxc: Failed to add Rust target #{target_platform}")
67
67
 
68
- cargo_args = "--release --target #{target_platform}"
68
+ cargo_args = "--release --locked --target #{target_platform}"
69
69
  lib_dir = File.join(target_dir, target_platform, "release")
70
70
  else
71
71
  puts "oxc: Compiling Rust library for native platform..."
72
72
 
73
- cargo_args = "--release"
73
+ cargo_args = "--release --locked"
74
74
  lib_dir = File.join(target_dir, "release")
75
75
  end
76
76
 
@@ -80,7 +80,7 @@ module Oxc
80
80
 
81
81
  #: () -> String
82
82
  def inspect
83
- "#<#{self.class.name} #{start}..#{finish}#{" #{message.inspect}" if message}>"
83
+ "#<#{self.class.name} range=[#{start}, #{finish}]#{" #{message.inspect}" if message}>"
84
84
  end
85
85
  end
86
86
  end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ # A visitor that rewrites the source it walked, by recording what to do to a node and splicing the
5
+ # original text at the end. Everything nothing touched survives byte for byte.
6
+ #
7
+ # class Renamer < Oxc::MutationVisitor
8
+ # def visit_identifier(node)
9
+ # replace(node, "renamed") if node["name"] == "count"
10
+ # end
11
+ # end
12
+ #
13
+ # Renamer.new.rewrite("let count = 1") #=> "let renamed = 1"
14
+ #
15
+ class MutationVisitor < Visitor
16
+ class Overlap < StandardError; end
17
+ class Invalid < Error; end
18
+
19
+ Edit = Data.define(
20
+ :start, #: Integer
21
+ :finish, #: Integer
22
+ :text, #: String
23
+ :order #: Integer
24
+ )
25
+
26
+ attr_reader :source #: String
27
+ attr_reader :parsed #: Oxc::ParseResult
28
+
29
+ #: (String, ?verify: bool, **untyped) -> String
30
+ def rewrite(source, verify: true, **options)
31
+ @source = source
32
+ @edits = [] #: Array[Edit]
33
+ @replaced = [] #: Array[[Integer, Integer]]
34
+ @parsed = Oxc.parse(source, **options).validate!
35
+
36
+ visit(parsed)
37
+
38
+ rewritten = apply
39
+
40
+ verify ? verified(rewritten, options) : rewritten
41
+ end
42
+
43
+ #: (Oxc::Node, String) -> void
44
+ def replace(node, text)
45
+ @replaced << [node.start, node.finish]
46
+
47
+ edit(node.start, node.finish, text)
48
+ end
49
+
50
+ #: (Oxc::Node) -> void
51
+ def remove(node)
52
+ replace(node, "")
53
+ end
54
+
55
+ #: (Oxc::Node, String) -> void
56
+ def insert_before(node, text)
57
+ edit(node.start, node.start, text)
58
+ end
59
+
60
+ #: (Oxc::Node, String) -> void
61
+ def insert_after(node, text)
62
+ edit(node.finish, node.finish, text)
63
+ end
64
+
65
+ #: (Oxc::Node, String, String) -> void
66
+ def wrap(node, before, after)
67
+ insert_before(node, before)
68
+ insert_after(node, after)
69
+ end
70
+
71
+ #: (Oxc::Node) -> void
72
+ def visit_children(node)
73
+ return nil if replaced?(node)
74
+
75
+ super
76
+ end
77
+
78
+ private
79
+
80
+ #: (String, Hash[Symbol, untyped]) -> String
81
+ def verified(rewritten, options)
82
+ answer = Oxc.parse(rewritten, **options, ast: false)
83
+
84
+ return rewritten unless answer.errors?
85
+
86
+ raise Invalid, "what was rewritten no longer reads as JavaScript: #{answer.errors.first&.message}"
87
+ end
88
+
89
+ #: (Oxc::Node) -> bool
90
+ def replaced?(node)
91
+ @replaced.any? { |start, finish| node.start >= start && node.finish <= finish }
92
+ end
93
+
94
+ #: (Integer, Integer, String) -> void
95
+ def edit(start, finish, text)
96
+ @edits.each do |existing|
97
+ next unless overlaps?(existing, start, finish)
98
+
99
+ raise Overlap, "an edit at #{start}..#{finish} overlaps one at #{existing.start}..#{existing.finish}"
100
+ end
101
+
102
+ @edits << Edit.new(start: start, finish: finish, text: text, order: @edits.length)
103
+
104
+ nil
105
+ end
106
+
107
+ #: (Edit, Integer, Integer) -> bool
108
+ def overlaps?(existing, start, finish)
109
+ return false if existing.start == existing.finish && start == finish
110
+
111
+ start < existing.finish && existing.start < finish
112
+ end
113
+
114
+ #: () -> String
115
+ def apply
116
+ taken = 0
117
+ result = +""
118
+
119
+ @edits.sort_by { |edit| [edit.start, edit.order] }.each do |edit|
120
+ result << source.byteslice(taken, edit.start - taken).to_s << edit.text
121
+
122
+ taken = edit.finish
123
+ end
124
+
125
+ result << source.byteslice(taken..).to_s
126
+ end
127
+ end
128
+ end
data/lib/oxc/node.rb ADDED
@@ -0,0 +1,186 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Node
5
+ include Enumerable #[Oxc::Node]
6
+
7
+ ACRONYM = /([A-Z]+)([A-Z][a-z])/ #: Regexp
8
+ BOUNDARY = /([a-z\d])([A-Z])/ #: Regexp
9
+ SPAN = ["type", "start", "end"].freeze #: Array[String]
10
+
11
+ attr_reader :parent #: Oxc::Node?
12
+
13
+ protected
14
+
15
+ attr_reader :attributes #: Hash[String, untyped]
16
+ attr_reader :text #: String?
17
+
18
+ public
19
+
20
+ #: (Hash[String, untyped], ?Oxc::Node?, ?String?) -> void
21
+ def initialize(attributes, parent = nil, text = nil)
22
+ @attributes = attributes
23
+ @parent = parent
24
+ @text = text || parent&.text
25
+ end
26
+
27
+ #: () -> String
28
+ def type
29
+ attributes.fetch("type")
30
+ end
31
+
32
+ #: () -> Integer
33
+ def start
34
+ attributes.fetch("start")
35
+ end
36
+
37
+ #: () -> Integer
38
+ def finish
39
+ attributes.fetch("end")
40
+ end
41
+
42
+ #: () -> String
43
+ def underscored_type
44
+ @underscored_type ||= type.gsub(ACRONYM, '\1_\2').gsub(BOUNDARY, '\1_\2').downcase
45
+ end
46
+
47
+ #: (String) -> untyped
48
+ def [](key)
49
+ attributes[key]
50
+ end
51
+
52
+ #: (?String?) -> String?
53
+ def slice(from = text)
54
+ raise ArgumentError, "this node does not know its source, so #slice needs it" unless from
55
+
56
+ from.byteslice(start, finish - start)
57
+ end
58
+
59
+ #: () -> Array[String]
60
+ def keys
61
+ attributes.keys
62
+ end
63
+
64
+ #: () -> Hash[String, untyped]
65
+ def to_h
66
+ attributes
67
+ end
68
+
69
+ #: (?untyped) -> String
70
+ def to_json(state = nil)
71
+ state ? attributes.to_json(state) : attributes.to_json
72
+ end
73
+
74
+ #: (Array[Symbol]?) -> Hash[Symbol, untyped]
75
+ def deconstruct_keys(keys)
76
+ found = {} #: Hash[Symbol, untyped]
77
+
78
+ if keys
79
+ keys.each do |name|
80
+ key = field_for(name.to_s)
81
+
82
+ found[name] = wrap(attributes[key]) if key
83
+ end
84
+ else
85
+ attributes.each_key { |key| found[key.to_sym] = wrap(attributes[key]) }
86
+ end
87
+
88
+ found
89
+ end
90
+
91
+ #: () -> Array[Oxc::Node]
92
+ def child_nodes
93
+ @child_nodes ||= attributes.each_value
94
+ .flat_map { |value| value.is_a?(Array) ? value : [value] }
95
+ .select { |value| value.is_a?(Hash) && value.key?("type") }
96
+ .map { |value| Node.new(value, self) }
97
+ .freeze
98
+ end
99
+
100
+ #: () { (Oxc::Node) -> void } -> void
101
+ #: () -> Enumerator[Oxc::Node, void]
102
+ def each(&)
103
+ return enum_for(:each) unless block_given?
104
+
105
+ yield self
106
+
107
+ child_nodes.each { |child| child.each(&) }
108
+ end
109
+
110
+ #: () -> Array[Oxc::Node]
111
+ def ancestors
112
+ parent ? [parent, *parent.ancestors] : []
113
+ end
114
+
115
+ #: (Integer) -> Oxc::Node?
116
+ def at(offset)
117
+ covering = each.select { |node| offset >= node.start && offset < node.finish }
118
+
119
+ covering.min_by { |node| node.finish - node.start }
120
+ end
121
+
122
+ #: (String) -> Array[Oxc::Node]
123
+ def every(type)
124
+ each.select { |node| node.type == type }
125
+ end
126
+
127
+ #: () -> Hash[String, untyped]
128
+ def fields
129
+ attributes.except(*SPAN)
130
+ end
131
+
132
+ #: () -> String
133
+ def inspect
134
+ described = fields.map { |key, value| described_field(key, value) }
135
+
136
+ "#<#{self.class.name} #{type} range=[#{start}, #{finish}]#{" #{described.join(" ")}" unless described.empty?}>"
137
+ end
138
+
139
+ #: (Symbol, *untyped) -> untyped
140
+ def method_missing(name, *arguments)
141
+ key = field_for(name.to_s)
142
+
143
+ return super unless key
144
+
145
+ wrap(attributes[key])
146
+ end
147
+
148
+ #: (Symbol, ?bool) -> bool
149
+ def respond_to_missing?(name, include_private = false)
150
+ !field_for(name.to_s).nil? || super
151
+ end
152
+
153
+ private
154
+
155
+ #: (String, untyped) -> String
156
+ def described_field(key, value)
157
+ case value
158
+ when Array then "#{key}=#{if value.empty?
159
+ "[]"
160
+ else
161
+ "[... #{value.length} #{value.length == 1 ? "item" : "items"}]"
162
+ end}"
163
+ when Hash then "#{key}=#<#{self.class.name} #{value["type"]}>"
164
+ else "#{key}=#{value.inspect}"
165
+ end
166
+ end
167
+
168
+ #: (String) -> String?
169
+ def field_for(name)
170
+ return name if attributes.key?(name)
171
+
172
+ camelized = name.gsub(/_([a-z\d])/) { Regexp.last_match(1).to_s.upcase }
173
+
174
+ camelized if attributes.key?(camelized)
175
+ end
176
+
177
+ #: (untyped) -> untyped
178
+ def wrap(value)
179
+ case value
180
+ when Hash then value.key?("type") ? Node.new(value, self, text) : value
181
+ when Array then value.map { |item| wrap(item) }
182
+ else value
183
+ end
184
+ end
185
+ end
186
+ end
data/lib/oxc/options.rb CHANGED
@@ -72,9 +72,9 @@ module Oxc
72
72
  freeze
73
73
  end
74
74
 
75
- #: (?untyped) -> String
75
+ #: (?JSON::options?) -> String
76
76
  def to_json(state = nil)
77
- JSON.generate(to_h, state)
77
+ state ? JSON.generate(to_h, state) : JSON.generate(to_h)
78
78
  end
79
79
 
80
80
  #: () -> String
@@ -4,17 +4,19 @@ module Oxc
4
4
  class ParseResult
5
5
  include Diagnosed
6
6
 
7
+ attr_reader :source #: String?
7
8
  attr_reader :program #: Hash[String, untyped]?
8
9
  attr_reader :module_record #: Hash[String, untyped]?
9
10
  attr_reader :symbols #: Hash[String, untyped]?
10
11
  attr_reader :comments #: Array[Oxc::Comment]
11
12
  attr_reader :diagnostics #: Array[Oxc::Diagnostic]
12
13
 
13
- #: (String) -> Oxc::ParseResult
14
- def self.from_json(payload)
14
+ #: (String, ?String?) -> Oxc::ParseResult
15
+ def self.from_json(payload, source = nil)
15
16
  parsed = JSON.parse(payload)
16
17
 
17
18
  new(
19
+ source: source,
18
20
  program: parsed["program"],
19
21
  module_record: parsed["module_record"],
20
22
  symbols: parsed["symbols"],
@@ -24,8 +26,9 @@ module Oxc
24
26
  )
25
27
  end
26
28
 
27
- #: (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
28
- def initialize(comments:, diagnostics:, program: nil, module_record: nil, symbols: nil, panicked: false)
29
+ #: (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?source: String?, ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
30
+ def initialize(comments:, diagnostics:, source: nil, program: nil, module_record: nil, symbols: nil, panicked: false)
31
+ @source = source
29
32
  @program = program.freeze
30
33
  @module_record = module_record.freeze
31
34
  @symbols = symbols.freeze
@@ -36,6 +39,11 @@ module Oxc
36
39
  freeze
37
40
  end
38
41
 
42
+ #: () -> Oxc::Node?
43
+ def root
44
+ program ? Node.new(program, nil, source) : nil
45
+ end
46
+
39
47
  #: () -> Oxc::ParseResult
40
48
  def validate!
41
49
  return self unless errors? || panicked?
@@ -46,7 +54,9 @@ module Oxc
46
54
  #: () -> String
47
55
  def inspect
48
56
  parts = [] #: Array[String]
49
- parts << "program=#{program["type"]}" if program
57
+ parts << "#{root&.type} range=[#{root&.start}, #{root&.finish}]" if program
58
+ parts << "module_record" if module_record
59
+ parts << "symbols=#{symbols.fetch("declared").length}" if symbols
50
60
  parts << "comments=#{comments.length}" unless comments.empty?
51
61
  parts << "diagnostics=#{diagnostics.length}" unless diagnostics.empty?
52
62
 
data/lib/oxc/result.rb CHANGED
@@ -18,7 +18,7 @@ module Oxc
18
18
  @panicked = panicked
19
19
  end
20
20
 
21
- #: (?strict: untyped) -> self
21
+ #: (?strict: bool?) -> self
22
22
  def validate!(strict: false)
23
23
  return self unless errors? || panicked?
24
24
  return self unless strict || panicked? || code.empty?
data/lib/oxc/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Oxc
4
- VERSION = "0.1.0"
4
+ VERSION = "0.149.0"
5
5
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Visitor
5
+ #: (Oxc::Node | Oxc::ParseResult) -> void
6
+ def visit(node)
7
+ node = node.root if node.is_a?(ParseResult)
8
+
9
+ return nil unless node
10
+
11
+ answer = "visit_#{node.underscored_type}"
12
+
13
+ respond_to?(answer) ? public_send(answer, node) : visit_children(node)
14
+
15
+ nil
16
+ end
17
+
18
+ #: (Oxc::Node) -> void
19
+ def visit_children(node)
20
+ node.child_nodes.each { |child| visit(child) }
21
+
22
+ nil
23
+ end
24
+ end
25
+ end
data/lib/oxc.rb CHANGED
@@ -19,6 +19,9 @@ require_relative "oxc/diagnosed"
19
19
  require_relative "oxc/result"
20
20
  require_relative "oxc/minify_result"
21
21
  require_relative "oxc/transform_result"
22
+ require_relative "oxc/node"
23
+ require_relative "oxc/visitor"
24
+ require_relative "oxc/mutation_visitor"
22
25
  require_relative "oxc/parse_result"
23
26
  require_relative "oxc/transformer"
24
27
  require_relative "oxc/minifier"
@@ -28,21 +31,21 @@ module Oxc
28
31
  def self.minify(source, **options)
29
32
  serialized = Options.serialize(options, Options::MINIFY, "minify")
30
33
 
31
- MinifyResult.from_json(Backend.minify(source.to_s, serialized)).validate!(strict: options[:strict])
34
+ MinifyResult.from_json(Backend.minify(source.to_s, serialized)).validate!(strict: options[:strict] ? true : false)
32
35
  end
33
36
 
34
37
  #: (String, ?filename: String?, ?lang: String?, ?source_type: String?, ?cwd: String?, ?target: targets?, ?jsx: jsx?, ?typescript: typescript?, ?assumptions: assumptions?, ?decorator: decorator?, ?helpers: helpers?, ?define: Hash[String, String]?, ?inject: inject?, ?minify: minify?, ?codegen: codegen?, ?sourcemap: bool, ?strict: bool) -> Oxc::TransformResult
35
38
  def self.transform(source, **options)
36
39
  serialized = Options.serialize(options, Options::TRANSFORM, "transform")
37
40
 
38
- TransformResult.from_json(Backend.transform(source.to_s, serialized)).validate!(strict: options[:strict])
41
+ TransformResult.from_json(Backend.transform(source.to_s, serialized)).validate!(strict: options[:strict] ? true : false)
39
42
  end
40
43
 
41
44
  #: (String, ?filename: String?, ?lang: String?, ?source_type: String?, ?ast_type: String?, ?ast: bool, ?ranges: bool, ?preserve_parens: bool, ?comments: bool, ?module_record: bool, ?symbols: bool, ?semantic_errors: bool) -> Oxc::ParseResult
42
45
  def self.parse(source, **options)
43
46
  serialized = Options.serialize(options, Options::PARSE, "parse")
44
47
 
45
- ParseResult.from_json(Backend.parse(source.to_s, serialized))
48
+ ParseResult.from_json(Backend.parse(source.to_s, serialized), source.to_s)
46
49
  end
47
50
 
48
51
  #: () -> String
data/rust/Cargo.lock CHANGED
@@ -470,17 +470,11 @@ version = "0.5.2"
470
470
  source = "registry+https://github.com/rust-lang/crates.io-index"
471
471
  checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
472
472
 
473
- [[package]]
474
- name = "owo-colors"
475
- version = "4.3.0"
476
- source = "registry+https://github.com/rust-lang/crates.io-index"
477
- checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d"
478
-
479
473
  [[package]]
480
474
  name = "oxc"
481
- version = "0.147.0"
475
+ version = "0.149.0"
482
476
  source = "registry+https://github.com/rust-lang/crates.io-index"
483
- checksum = "db297a5e119706ad508114ec9065a8a13d154efc14d830d3a1effb0b69cbd5eb"
477
+ checksum = "689ab90be0e2cbd3448dc88794ef7645196b82da6f3943c20c8710c34ac5d290"
484
478
  dependencies = [
485
479
  "oxc_allocator",
486
480
  "oxc_ast",
@@ -517,7 +511,7 @@ dependencies = [
517
511
 
518
512
  [[package]]
519
513
  name = "oxc-ruby-ffi"
520
- version = "0.1.0"
514
+ version = "0.0.0"
521
515
  dependencies = [
522
516
  "cbindgen",
523
517
  "oxc",
@@ -528,9 +522,9 @@ dependencies = [
528
522
 
529
523
  [[package]]
530
524
  name = "oxc_allocator"
531
- version = "0.147.0"
525
+ version = "0.149.0"
532
526
  source = "registry+https://github.com/rust-lang/crates.io-index"
533
- checksum = "c4e69b2400ab3c2f96eb3ae474ed80fa3a2959ba05e26afc5df45e634fc9a071"
527
+ checksum = "48c2dbd560f65d113e7114eb5857e346493062ac665d3bd49426d50a02cc1969"
534
528
  dependencies = [
535
529
  "allocator-api2",
536
530
  "hashbrown",
@@ -542,9 +536,9 @@ dependencies = [
542
536
 
543
537
  [[package]]
544
538
  name = "oxc_ast"
545
- version = "0.147.0"
539
+ version = "0.149.0"
546
540
  source = "registry+https://github.com/rust-lang/crates.io-index"
547
- checksum = "3dcf0e905263cc649c07e3494489de620462390de12cb2b5933247f91785a421"
541
+ checksum = "9e9bdb56efa22b6eb5c213f512a838521a2433905d25da4e3021d3fac0bc7d1d"
548
542
  dependencies = [
549
543
  "bitflags",
550
544
  "oxc_allocator",
@@ -560,9 +554,9 @@ dependencies = [
560
554
 
561
555
  [[package]]
562
556
  name = "oxc_ast_macros"
563
- version = "0.147.0"
557
+ version = "0.149.0"
564
558
  source = "registry+https://github.com/rust-lang/crates.io-index"
565
- checksum = "aa520723c19e83bcc683a988ac77d56bbca4b88178d5fc6c0c89fb73a45893cf"
559
+ checksum = "af8a6c6decb4887b04e0dc49c8dd862037d1f6b274cd32d931faf37184a5e5dd"
566
560
  dependencies = [
567
561
  "phf",
568
562
  "proc-macro2",
@@ -572,9 +566,9 @@ dependencies = [
572
566
 
573
567
  [[package]]
574
568
  name = "oxc_ast_visit"
575
- version = "0.147.0"
569
+ version = "0.149.0"
576
570
  source = "registry+https://github.com/rust-lang/crates.io-index"
577
- checksum = "7bcdfe65eec7cc091e52f73ea7f6546375a2dd5b88c43900afc94dafffebfb8c"
571
+ checksum = "83aaab313b5275faea8cee175d489589f6271a6223b128ec9abaa48339d0a66b"
578
572
  dependencies = [
579
573
  "oxc_allocator",
580
574
  "oxc_ast",
@@ -584,9 +578,9 @@ dependencies = [
584
578
 
585
579
  [[package]]
586
580
  name = "oxc_codegen"
587
- version = "0.147.0"
581
+ version = "0.149.0"
588
582
  source = "registry+https://github.com/rust-lang/crates.io-index"
589
- checksum = "bd265be822054de498537a8df29f0afef75f9e804f9c499c81c0ec8c9b9212bd"
583
+ checksum = "a313a091df12abad72542deeba21e6b44e37dd4a2ed66bf3159acc1aa68f0ef0"
590
584
  dependencies = [
591
585
  "bitflags",
592
586
  "cow-utils",
@@ -606,9 +600,9 @@ dependencies = [
606
600
 
607
601
  [[package]]
608
602
  name = "oxc_compat"
609
- version = "0.147.0"
603
+ version = "0.149.0"
610
604
  source = "registry+https://github.com/rust-lang/crates.io-index"
611
- checksum = "970fe81a0a43846ebe37c9250f3a1948e984ba79cbdf866681fd117dffe27e3d"
605
+ checksum = "367175d382eca8c9c2c931d4350fe66b7b10fc73f57b691acdf557fd8003c91d"
612
606
  dependencies = [
613
607
  "cow-utils",
614
608
  "oxc-browserslist",
@@ -619,24 +613,23 @@ dependencies = [
619
613
 
620
614
  [[package]]
621
615
  name = "oxc_data_structures"
622
- version = "0.147.0"
616
+ version = "0.149.0"
623
617
  source = "registry+https://github.com/rust-lang/crates.io-index"
624
- checksum = "e7903e8f1f76f148c943b5a2e192bf908d600b5fe0df1efc77ebeb75591ace56"
618
+ checksum = "ac25bee569c0af652786ab2e39dc7815957ca3767dc2c3e3e2776f5028f8d30d"
625
619
  dependencies = [
626
620
  "ropey",
627
621
  ]
628
622
 
629
623
  [[package]]
630
624
  name = "oxc_diagnostics"
631
- version = "0.147.0"
625
+ version = "0.149.0"
632
626
  source = "registry+https://github.com/rust-lang/crates.io-index"
633
- checksum = "acb70f89da6524e6a2d097f0d747f14731156996ee5400474ef19ad3f318646b"
627
+ checksum = "b92d1704adbad84b5d8a4e9d34e3937da7d230883726f0d96d7f2757a2b60aba"
634
628
  dependencies = [
635
629
  "bytecount",
636
630
  "cow-utils",
637
631
  "itoa",
638
632
  "memchr",
639
- "owo-colors",
640
633
  "oxc_span",
641
634
  "percent-encoding",
642
635
  "smallvec",
@@ -647,9 +640,9 @@ dependencies = [
647
640
 
648
641
  [[package]]
649
642
  name = "oxc_ecmascript"
650
- version = "0.147.0"
643
+ version = "0.149.0"
651
644
  source = "registry+https://github.com/rust-lang/crates.io-index"
652
- checksum = "9f1fdd494072a511d7df691282dbd4fe656ad6fd0bea24d4366c019ed1172a4f"
645
+ checksum = "1d3cb15b9e142737d38e50366be0ead824f7d16bee3ac47c79839d50deb2324b"
653
646
  dependencies = [
654
647
  "cow-utils",
655
648
  "dragonbox_ecma",
@@ -668,9 +661,9 @@ dependencies = [
668
661
 
669
662
  [[package]]
670
663
  name = "oxc_estree"
671
- version = "0.147.0"
664
+ version = "0.149.0"
672
665
  source = "registry+https://github.com/rust-lang/crates.io-index"
673
- checksum = "e2ef8cdc8d02a7e0b91ee51a2572963c914d3bb38261e11a54d068a092c4dc42"
666
+ checksum = "11c7a17be65f4c12b02e2e62eb9368272f2ed794801552b437fa654253ce06dd"
674
667
  dependencies = [
675
668
  "dragonbox_ecma",
676
669
  "itoa",
@@ -689,9 +682,9 @@ dependencies = [
689
682
 
690
683
  [[package]]
691
684
  name = "oxc_isolated_declarations"
692
- version = "0.147.0"
685
+ version = "0.149.0"
693
686
  source = "registry+https://github.com/rust-lang/crates.io-index"
694
- checksum = "88fe41a07cb943168e10efb18a3f5f56ffbb70c7eb6ef42d89de203cca5a73a3"
687
+ checksum = "f0993224aefb691db2297dd0a8d095fc15fe2ede8484273d8258004da0caa777"
695
688
  dependencies = [
696
689
  "bitflags",
697
690
  "oxc_allocator",
@@ -707,9 +700,9 @@ dependencies = [
707
700
 
708
701
  [[package]]
709
702
  name = "oxc_mangler"
710
- version = "0.147.0"
703
+ version = "0.149.0"
711
704
  source = "registry+https://github.com/rust-lang/crates.io-index"
712
- checksum = "efa851c466fb09783764de87e93fa44c27c2d0b918dbaa8b0a0364aca15b2f44"
705
+ checksum = "53188efb7700e8c17a6c65a7cc89b8f964de3eea8cf0012def779f35f54c23b7"
713
706
  dependencies = [
714
707
  "itertools",
715
708
  "oxc_allocator",
@@ -726,9 +719,9 @@ dependencies = [
726
719
 
727
720
  [[package]]
728
721
  name = "oxc_minifier"
729
- version = "0.147.0"
722
+ version = "0.149.0"
730
723
  source = "registry+https://github.com/rust-lang/crates.io-index"
731
- checksum = "4bba5313adecd3682455f4a830e26cfcd751ac8f9423ca95f93d7b8dcdee807c"
724
+ checksum = "ab7fa9470010de2d1ac8388b18a4c4165d3fa0cd137cb03a2a5066e56c3a8f5f"
732
725
  dependencies = [
733
726
  "cow-utils",
734
727
  "itoa",
@@ -752,9 +745,9 @@ dependencies = [
752
745
 
753
746
  [[package]]
754
747
  name = "oxc_parser"
755
- version = "0.147.0"
748
+ version = "0.149.0"
756
749
  source = "registry+https://github.com/rust-lang/crates.io-index"
757
- checksum = "12a55bfce994289467c88ed9732dbc4c8f03f3186af2b77e48dc4a71c502cb2c"
750
+ checksum = "c6ac968fd0450309168e18c761dee4b68377bc0bbd4e1eb4e23d1c4d2e2cc825"
758
751
  dependencies = [
759
752
  "bitflags",
760
753
  "cow-utils",
@@ -776,9 +769,9 @@ dependencies = [
776
769
 
777
770
  [[package]]
778
771
  name = "oxc_regular_expression"
779
- version = "0.147.0"
772
+ version = "0.149.0"
780
773
  source = "registry+https://github.com/rust-lang/crates.io-index"
781
- checksum = "d8455a292e58e24a0c51cfa2ec1d44e219e22d59a04b9af1ae050d4944a19d51"
774
+ checksum = "18ef364ac0d7e5beda9e59a3fea4ba050da6e34720c10c7c0a16b3993373ba52"
782
775
  dependencies = [
783
776
  "bitflags",
784
777
  "oxc_allocator",
@@ -793,9 +786,9 @@ dependencies = [
793
786
 
794
787
  [[package]]
795
788
  name = "oxc_semantic"
796
- version = "0.147.0"
789
+ version = "0.149.0"
797
790
  source = "registry+https://github.com/rust-lang/crates.io-index"
798
- checksum = "b9c35fc29f969e7f93ee41dc37c9d82816e9c2597495f6cc302477831c8fd2ed"
791
+ checksum = "62853caf83c33ff2da0dd2d5a7b2ed6f907a29306aae34ec65807d8bf10c2c68"
799
792
  dependencies = [
800
793
  "itertools",
801
794
  "memchr",
@@ -829,9 +822,9 @@ dependencies = [
829
822
 
830
823
  [[package]]
831
824
  name = "oxc_span"
832
- version = "0.147.0"
825
+ version = "0.149.0"
833
826
  source = "registry+https://github.com/rust-lang/crates.io-index"
834
- checksum = "378737bf42338e31badcdae2e6e2afc7a63cb7ffe82c418ac12d506c554adda4"
827
+ checksum = "8305f2b3c5e2030658fba8457260d313dbf5fe442c40c184f54a3a50eb42365c"
835
828
  dependencies = [
836
829
  "compact_str",
837
830
  "oxc_allocator",
@@ -843,9 +836,9 @@ dependencies = [
843
836
 
844
837
  [[package]]
845
838
  name = "oxc_str"
846
- version = "0.147.0"
839
+ version = "0.149.0"
847
840
  source = "registry+https://github.com/rust-lang/crates.io-index"
848
- checksum = "8564a0269f93153f856100db908af25434efdd1ec9d403ffa099cdab57385c8c"
841
+ checksum = "16486b3832d8f1355283030ae048c5ae530d8a57e2cdfd9514e0d6cdbd4c5506"
849
842
  dependencies = [
850
843
  "compact_str",
851
844
  "hashbrown",
@@ -856,9 +849,9 @@ dependencies = [
856
849
 
857
850
  [[package]]
858
851
  name = "oxc_syntax"
859
- version = "0.147.0"
852
+ version = "0.149.0"
860
853
  source = "registry+https://github.com/rust-lang/crates.io-index"
861
- checksum = "59f05978138676c9d54f021391409fcf1314a46adcdbbaabc670c2990f8387dd"
854
+ checksum = "8c10f6276b8d5e3df514299a6a93241276531f2801853c3309a86805be278664"
862
855
  dependencies = [
863
856
  "bitflags",
864
857
  "cow-utils",
@@ -877,9 +870,9 @@ dependencies = [
877
870
 
878
871
  [[package]]
879
872
  name = "oxc_transformer"
880
- version = "0.147.0"
873
+ version = "0.149.0"
881
874
  source = "registry+https://github.com/rust-lang/crates.io-index"
882
- checksum = "2e4443b3e36410882b44ed13e415ef8ddc3d31e6786d03f5a0e486e4c1d18090"
875
+ checksum = "801fc17aeac563535b2809ba775a73f7ba343412e36943d5733855f7a3c7be3e"
883
876
  dependencies = [
884
877
  "base64",
885
878
  "compact_str",
@@ -907,9 +900,9 @@ dependencies = [
907
900
 
908
901
  [[package]]
909
902
  name = "oxc_transformer_plugins"
910
- version = "0.147.0"
903
+ version = "0.149.0"
911
904
  source = "registry+https://github.com/rust-lang/crates.io-index"
912
- checksum = "f9db3729caa06dcea2f4a2a50a045c4e6148be0b579b3108ac181145f212fb0d"
905
+ checksum = "a36a4772e42d0c3c21de41f5cc6e2755af559aee0b326fc4dbc179e94fcdd1df"
913
906
  dependencies = [
914
907
  "cow-utils",
915
908
  "itoa",
@@ -930,9 +923,9 @@ dependencies = [
930
923
 
931
924
  [[package]]
932
925
  name = "oxc_traverse"
933
- version = "0.147.0"
926
+ version = "0.149.0"
934
927
  source = "registry+https://github.com/rust-lang/crates.io-index"
935
- checksum = "02a3cc8f1a31a1b08104ede1a6631dfc984282234249f4503f51f4d2b22036e4"
928
+ checksum = "cdd746d75af6792d45df91d68a7252834a9aab30f0ea2cedf270137ad6e7dde6"
936
929
  dependencies = [
937
930
  "itoa",
938
931
  "oxc_allocator",
data/rust/Cargo.toml CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [package]
4
4
  name = "oxc-ruby-ffi"
5
- version = "0.1.0"
6
5
  edition = "2021"
7
6
  authors = ["Marco Roth <marco.roth@intergga.ch>"]
8
7
  description = "C FFI bindings for oxc, used by the oxc gem"
@@ -16,7 +15,7 @@ path = "src/lib.rs"
16
15
  crate-type = ["cdylib", "staticlib", "rlib"]
17
16
 
18
17
  [dependencies]
19
- oxc = { version = "=0.147.0", features = ["full", "serialize"] }
18
+ oxc = { version = "=0.149.0", features = ["full", "serialize"] }
20
19
  oxc_sourcemap = "8"
21
20
  serde = { version = "1", features = ["derive"] }
22
21
  serde_json = { version = "1", features = ["raw_value"] }
data/rust/build.rs CHANGED
@@ -28,7 +28,29 @@ fn main() {
28
28
  PathBuf::from(&crate_dir).join("cbindgen.toml").display()
29
29
  );
30
30
 
31
+ let version_rb_path = PathBuf::from(&crate_dir).join("../lib/oxc/version.rb");
32
+
33
+ println!("cargo:rerun-if-changed={}", version_rb_path.display());
34
+
31
35
  println!("cargo:rustc-env=OXC_VERSION={}", locked_version(&lock_path, "oxc"));
36
+
37
+ println!("cargo:rustc-env=GEM_VERSION={}", gem_version(&version_rb_path));
38
+ }
39
+
40
+ fn gem_version(version_rb_path: &PathBuf) -> String {
41
+ let Ok(source) = fs::read_to_string(version_rb_path) else {
42
+ return "unknown".to_string();
43
+ };
44
+
45
+ for line in source.lines() {
46
+ let Some(rest) = line.trim().strip_prefix("VERSION = ") else {
47
+ continue;
48
+ };
49
+
50
+ return rest.trim().trim_matches('"').to_string();
51
+ }
52
+
53
+ "unknown".to_string()
32
54
  }
33
55
 
34
56
  fn locked_version(lock_path: &PathBuf, package: &str) -> String {
data/rust/src/lib.rs CHANGED
@@ -37,7 +37,7 @@ use crate::result::{MinifyPayload, TransformPayload};
37
37
  use crate::source_type::source_type_for;
38
38
  use crate::transform::Compiler;
39
39
 
40
- pub const VERSION: &str = env!("CARGO_PKG_VERSION");
40
+ pub const VERSION: &str = env!("GEM_VERSION");
41
41
  pub const OXC_VERSION: &str = env!("OXC_VERSION");
42
42
 
43
43
  #[repr(C)]
@@ -200,7 +200,7 @@ fn minify_source(source: &str, options: &MinifyOptions) -> Result<MinifyPayload,
200
200
  map,
201
201
  legal_comments,
202
202
  errors: Diagnostic::from_diagnostics(&filename, source, parsed.diagnostics),
203
- panicked: parsed.panicked,
203
+ panicked: parsed.fatal_error,
204
204
  })
205
205
  }
206
206
 
data/rust/src/parse.rs CHANGED
@@ -56,7 +56,7 @@ pub fn parse_source(source: &str, options: &ParseOptions) -> Result<ParsePayload
56
56
  symbols,
57
57
  comments,
58
58
  errors: Diagnostic::from_diagnostics(&filename, source, diagnostics),
59
- panicked: parsed.panicked,
59
+ panicked: parsed.fatal_error,
60
60
  })
61
61
  }
62
62
 
@@ -0,0 +1,80 @@
1
+ # Generated from lib/oxc/mutation_visitor.rb with RBS::Inline
2
+
3
+ module Oxc
4
+ # A visitor that rewrites the source it walked, by recording what to do to a node and splicing the
5
+ # original text at the end. Everything nothing touched survives byte for byte.
6
+ #
7
+ # class Renamer < Oxc::MutationVisitor
8
+ # def visit_identifier(node)
9
+ # replace(node, "renamed") if node["name"] == "count"
10
+ # end
11
+ # end
12
+ #
13
+ # Renamer.new.rewrite("let count = 1") #=> "let renamed = 1"
14
+ class MutationVisitor < Visitor
15
+ class Overlap < StandardError
16
+ end
17
+
18
+ class Invalid < Error
19
+ end
20
+
21
+ class Edit < Data
22
+ attr_reader start(): Integer
23
+
24
+ attr_reader finish(): Integer
25
+
26
+ attr_reader text(): String
27
+
28
+ attr_reader order(): Integer
29
+
30
+ def self.new: (Integer start, Integer finish, String text, Integer order) -> instance
31
+ | (start: Integer, finish: Integer, text: String, order: Integer) -> instance
32
+
33
+ def self.members: () -> [ :start, :finish, :text, :order ]
34
+
35
+ def members: () -> [ :start, :finish, :text, :order ]
36
+ end
37
+
38
+ attr_reader source: String
39
+
40
+ attr_reader parsed: Oxc::ParseResult
41
+
42
+ # : (String, ?verify: bool, **untyped) -> String
43
+ def rewrite: (String, ?verify: bool, **untyped) -> String
44
+
45
+ # : (Oxc::Node, String) -> void
46
+ def replace: (Oxc::Node, String) -> void
47
+
48
+ # : (Oxc::Node) -> void
49
+ def remove: (Oxc::Node) -> void
50
+
51
+ # : (Oxc::Node, String) -> void
52
+ def insert_before: (Oxc::Node, String) -> void
53
+
54
+ # : (Oxc::Node, String) -> void
55
+ def insert_after: (Oxc::Node, String) -> void
56
+
57
+ # : (Oxc::Node, String, String) -> void
58
+ def wrap: (Oxc::Node, String, String) -> void
59
+
60
+ # : (Oxc::Node) -> void
61
+ def visit_children: (Oxc::Node) -> void
62
+
63
+ private
64
+
65
+ # : (String, Hash[Symbol, untyped]) -> String
66
+ def verified: (String, Hash[Symbol, untyped]) -> String
67
+
68
+ # : (Oxc::Node) -> bool
69
+ def replaced?: (Oxc::Node) -> bool
70
+
71
+ # : (Integer, Integer, String) -> void
72
+ def edit: (Integer, Integer, String) -> void
73
+
74
+ # : (Edit, Integer, Integer) -> bool
75
+ def overlaps?: (Edit, Integer, Integer) -> bool
76
+
77
+ # : () -> String
78
+ def apply: () -> String
79
+ end
80
+ end
data/sig/oxc/node.rbs ADDED
@@ -0,0 +1,94 @@
1
+ # Generated from lib/oxc/node.rb with RBS::Inline
2
+
3
+ module Oxc
4
+ class Node
5
+ include Enumerable[Oxc::Node]
6
+
7
+ ACRONYM: Regexp
8
+
9
+ BOUNDARY: Regexp
10
+
11
+ SPAN: Array[String]
12
+
13
+ attr_reader parent: Oxc::Node?
14
+
15
+ attr_reader attributes: Hash[String, untyped]
16
+
17
+ attr_reader text: String?
18
+
19
+ public
20
+
21
+ # : (Hash[String, untyped], ?Oxc::Node?, ?String?) -> void
22
+ def initialize: (Hash[String, untyped], ?Oxc::Node?, ?String?) -> void
23
+
24
+ # : () -> String
25
+ def type: () -> String
26
+
27
+ # : () -> Integer
28
+ def start: () -> Integer
29
+
30
+ # : () -> Integer
31
+ def finish: () -> Integer
32
+
33
+ # : () -> String
34
+ def underscored_type: () -> String
35
+
36
+ # : (String) -> untyped
37
+ def []: (String) -> untyped
38
+
39
+ # : (?String?) -> String?
40
+ def slice: (?String?) -> String?
41
+
42
+ # : () -> Array[String]
43
+ def keys: () -> Array[String]
44
+
45
+ # : () -> Hash[String, untyped]
46
+ def to_h: () -> Hash[String, untyped]
47
+
48
+ # : (?untyped) -> String
49
+ def to_json: (?untyped) -> String
50
+
51
+ # : (Array[Symbol]?) -> Hash[Symbol, untyped]
52
+ def deconstruct_keys: (Array[Symbol]?) -> Hash[Symbol, untyped]
53
+
54
+ # : () -> Array[Oxc::Node]
55
+ def child_nodes: () -> Array[Oxc::Node]
56
+
57
+ # : () { (Oxc::Node) -> void } -> void
58
+ # : () -> Enumerator[Oxc::Node, void]
59
+ def each: () { (Oxc::Node) -> void } -> void
60
+ | () -> Enumerator[Oxc::Node, void]
61
+
62
+ # : () -> Array[Oxc::Node]
63
+ def ancestors: () -> Array[Oxc::Node]
64
+
65
+ # : (Integer) -> Oxc::Node?
66
+ def at: (Integer) -> Oxc::Node?
67
+
68
+ # : (String) -> Array[Oxc::Node]
69
+ def every: (String) -> Array[Oxc::Node]
70
+
71
+ # : () -> Hash[String, untyped]
72
+ def fields: () -> Hash[String, untyped]
73
+
74
+ # : () -> String
75
+ def inspect: () -> String
76
+
77
+ # : (Symbol, *untyped) -> untyped
78
+ def method_missing: (Symbol, *untyped) -> untyped
79
+
80
+ # : (Symbol, ?bool) -> bool
81
+ def respond_to_missing?: (Symbol, ?bool) -> bool
82
+
83
+ private
84
+
85
+ # : (String, untyped) -> String
86
+ def described_field: (String, untyped) -> String
87
+
88
+ # : (String) -> String?
89
+ def field_for: (String) -> String?
90
+
91
+ # : (untyped) -> untyped
92
+ def wrap: (untyped) -> untyped
93
+ end
94
+ end
data/sig/oxc/options.rbs CHANGED
@@ -25,8 +25,8 @@ module Oxc
25
25
  # : (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
26
26
  def initialize: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
27
27
 
28
- # : (?untyped) -> String
29
- def to_json: (?untyped) -> String
28
+ # : (?JSON::options?) -> String
29
+ def to_json: (?JSON::options?) -> String
30
30
 
31
31
  # : () -> String
32
32
  def inspect: () -> String
@@ -4,6 +4,8 @@ module Oxc
4
4
  class ParseResult
5
5
  include Diagnosed
6
6
 
7
+ attr_reader source: String?
8
+
7
9
  attr_reader program: Hash[String, untyped]?
8
10
 
9
11
  attr_reader module_record: Hash[String, untyped]?
@@ -14,11 +16,14 @@ module Oxc
14
16
 
15
17
  attr_reader diagnostics: Array[Oxc::Diagnostic]
16
18
 
17
- # : (String) -> Oxc::ParseResult
18
- def self.from_json: (String) -> Oxc::ParseResult
19
+ # : (String, ?String?) -> Oxc::ParseResult
20
+ def self.from_json: (String, ?String?) -> Oxc::ParseResult
21
+
22
+ # : (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?source: String?, ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
23
+ def initialize: (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?source: String?, ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
19
24
 
20
- # : (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
21
- def initialize: (comments: Array[Oxc::Comment], diagnostics: Array[Oxc::Diagnostic], ?program: Hash[String, untyped]?, ?module_record: Hash[String, untyped]?, ?symbols: Hash[String, untyped]?, ?panicked: bool) -> void
25
+ # : () -> Oxc::Node?
26
+ def root: () -> Oxc::Node?
22
27
 
23
28
  # : () -> Oxc::ParseResult
24
29
  def validate!: () -> Oxc::ParseResult
data/sig/oxc/result.rbs CHANGED
@@ -15,8 +15,8 @@ module Oxc
15
15
  # : (code: String, diagnostics: Array[Oxc::Diagnostic], ?map: String?, ?legal_comments: Array[String], ?panicked: bool) -> void
16
16
  def initialize: (code: String, diagnostics: Array[Oxc::Diagnostic], ?map: String?, ?legal_comments: Array[String], ?panicked: bool) -> void
17
17
 
18
- # : (?strict: untyped) -> self
19
- def validate!: (?strict: untyped) -> self
18
+ # : (?strict: bool?) -> self
19
+ def validate!: (?strict: bool?) -> self
20
20
 
21
21
  # : () -> String
22
22
  def to_s: () -> String
@@ -0,0 +1,11 @@
1
+ # Generated from lib/oxc/visitor.rb with RBS::Inline
2
+
3
+ module Oxc
4
+ class Visitor
5
+ # : (Oxc::Node | Oxc::ParseResult) -> void
6
+ def visit: (Oxc::Node | Oxc::ParseResult) -> void
7
+
8
+ # : (Oxc::Node) -> void
9
+ def visit_children: (Oxc::Node) -> void
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oxc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.149.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Roth
@@ -30,12 +30,15 @@ files:
30
30
  - lib/oxc/errors.rb
31
31
  - lib/oxc/minifier.rb
32
32
  - lib/oxc/minify_result.rb
33
+ - lib/oxc/mutation_visitor.rb
34
+ - lib/oxc/node.rb
33
35
  - lib/oxc/options.rb
34
36
  - lib/oxc/parse_result.rb
35
37
  - lib/oxc/result.rb
36
38
  - lib/oxc/transform_result.rb
37
39
  - lib/oxc/transformer.rb
38
40
  - lib/oxc/version.rb
41
+ - lib/oxc/visitor.rb
39
42
  - licenses/README.md
40
43
  - licenses/oxc-MIT.txt
41
44
  - licenses/oxc-THIRD-PARTY.txt
@@ -61,6 +64,8 @@ files:
61
64
  - sig/oxc/errors.rbs
62
65
  - sig/oxc/minifier.rbs
63
66
  - sig/oxc/minify_result.rbs
67
+ - sig/oxc/mutation_visitor.rbs
68
+ - sig/oxc/node.rbs
64
69
  - sig/oxc/options.rbs
65
70
  - sig/oxc/parse_result.rbs
66
71
  - sig/oxc/result.rbs
@@ -68,6 +73,7 @@ files:
68
73
  - sig/oxc/transformer.rbs
69
74
  - sig/oxc/types.rbs
70
75
  - sig/oxc/version.rbs
76
+ - sig/oxc/visitor.rbs
71
77
  homepage: https://github.com/marcoroth/oxc-ruby
72
78
  licenses:
73
79
  - MIT