oxc 0.1.0-x86_64-linux-gnu

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +437 -0
  4. data/ext/oxc/extconf.rb +123 -0
  5. data/ext/oxc/include/oxc.h +40 -0
  6. data/ext/oxc/oxc.c +136 -0
  7. data/lib/oxc/3.2/oxc.so +0 -0
  8. data/lib/oxc/3.3/oxc.so +0 -0
  9. data/lib/oxc/3.4/oxc.so +0 -0
  10. data/lib/oxc/4.0/oxc.so +0 -0
  11. data/lib/oxc/backend.rb +41 -0
  12. data/lib/oxc/diagnosed.rb +33 -0
  13. data/lib/oxc/diagnostic.rb +86 -0
  14. data/lib/oxc/errors.rb +26 -0
  15. data/lib/oxc/minifier.rb +31 -0
  16. data/lib/oxc/minify_result.rb +25 -0
  17. data/lib/oxc/options.rb +113 -0
  18. data/lib/oxc/parse_result.rb +106 -0
  19. data/lib/oxc/result.rb +51 -0
  20. data/lib/oxc/transform_result.rb +47 -0
  21. data/lib/oxc/transformer.rb +31 -0
  22. data/lib/oxc/version.rb +5 -0
  23. data/lib/oxc.rb +52 -0
  24. data/licenses/README.md +12 -0
  25. data/licenses/oxc-MIT.txt +22 -0
  26. data/licenses/oxc-THIRD-PARTY.txt +763 -0
  27. data/oxc.gemspec +43 -0
  28. data/rust/Cargo.lock +1436 -0
  29. data/rust/Cargo.toml +32 -0
  30. data/rust/build.rs +52 -0
  31. data/rust/cbindgen.toml +24 -0
  32. data/rust/rustfmt.toml +3 -0
  33. data/rust/src/diagnostic.rs +75 -0
  34. data/rust/src/lib.rs +288 -0
  35. data/rust/src/module_record.rs +262 -0
  36. data/rust/src/options.rs +744 -0
  37. data/rust/src/parse.rs +93 -0
  38. data/rust/src/result.rs +55 -0
  39. data/rust/src/source_type.rs +26 -0
  40. data/rust/src/symbols.rs +101 -0
  41. data/rust/src/transform.rs +116 -0
  42. data/sig/oxc/backend.rbs +29 -0
  43. data/sig/oxc/diagnosed.rbs +23 -0
  44. data/sig/oxc/diagnostic.rbs +57 -0
  45. data/sig/oxc/errors.rbs +31 -0
  46. data/sig/oxc/minifier.rbs +21 -0
  47. data/sig/oxc/minify_result.rbs +11 -0
  48. data/sig/oxc/options.rbs +42 -0
  49. data/sig/oxc/parse_result.rbs +61 -0
  50. data/sig/oxc/result.rbs +32 -0
  51. data/sig/oxc/transform_result.rbs +22 -0
  52. data/sig/oxc/transformer.rbs +21 -0
  53. data/sig/oxc/types.rbs +96 -0
  54. data/sig/oxc/version.rbs +5 -0
  55. data/sig/oxc.rbs +15 -0
  56. metadata +107 -0
data/ext/oxc/oxc.c ADDED
@@ -0,0 +1,136 @@
1
+ #include <ruby.h>
2
+ #include <ruby/encoding.h>
3
+ #include <ruby/thread.h>
4
+ #include "include/oxc.h"
5
+
6
+ static VALUE rb_mOxc;
7
+ static VALUE rb_mBackend;
8
+ static VALUE rb_eError;
9
+ static VALUE rb_eOptionError;
10
+ static VALUE rb_eOxcEncodingError;
11
+ static VALUE rb_eTransformError;
12
+ static VALUE rb_eInternalError;
13
+ static VALUE rb_ePanicError;
14
+
15
+ typedef struct OxcResult (*oxc_function)(const char *, const char *);
16
+
17
+ struct call_arguments {
18
+ oxc_function function;
19
+ const char *source;
20
+ const char *options;
21
+ struct OxcResult result;
22
+ };
23
+
24
+ static VALUE make_utf8_string(const char *cstring) {
25
+ return rb_enc_str_new_cstr(cstring, rb_utf8_encoding());
26
+ }
27
+
28
+ static VALUE take_utf8_string(char *cstring) {
29
+ if (!cstring) return Qnil;
30
+
31
+ VALUE string = make_utf8_string(cstring);
32
+ oxc_string_free(cstring);
33
+
34
+ return string;
35
+ }
36
+
37
+ static VALUE error_class_for(enum OxcErrorCode code) {
38
+ switch (code) {
39
+ case OXC_ERROR_CODE_OPTION: return rb_eOptionError;
40
+ case OXC_ERROR_CODE_ENCODING: return rb_eOxcEncodingError;
41
+ case OXC_ERROR_CODE_TRANSFORM: return rb_eTransformError;
42
+ case OXC_ERROR_CODE_PANIC: return rb_ePanicError;
43
+ default: return rb_eInternalError;
44
+ }
45
+ }
46
+
47
+ static VALUE unwrap(struct OxcResult result) {
48
+ if (result.error) {
49
+ VALUE message = make_utf8_string(result.error);
50
+ VALUE error_class = error_class_for(result.code);
51
+
52
+ oxc_result_free(result);
53
+
54
+ rb_raise(error_class, "%s", StringValueCStr(message));
55
+ }
56
+
57
+ if (!result.value) {
58
+ oxc_result_free(result);
59
+
60
+ rb_raise(rb_eInternalError, "oxc returned no result");
61
+ }
62
+
63
+ VALUE value = rb_enc_str_new(result.value, (long) result.value_len, rb_utf8_encoding());
64
+
65
+ oxc_result_free(result);
66
+
67
+ return value;
68
+ }
69
+
70
+ static void *without_gvl(void *data) {
71
+ struct call_arguments *arguments = (struct call_arguments *) data;
72
+
73
+ arguments->result = arguments->function(arguments->source, arguments->options);
74
+
75
+ return NULL;
76
+ }
77
+
78
+ static VALUE call(oxc_function function, VALUE source, VALUE options) {
79
+ struct call_arguments arguments;
80
+
81
+ arguments.function = function;
82
+ arguments.source = StringValueCStr(source);
83
+ arguments.options = StringValueCStr(options);
84
+
85
+ rb_thread_call_without_gvl(without_gvl, &arguments, NULL, NULL);
86
+
87
+ return unwrap(arguments.result);
88
+ }
89
+
90
+ static VALUE rb_minify(VALUE self, VALUE source, VALUE options) {
91
+ (void) self;
92
+
93
+ return call(oxc_minify, source, options);
94
+ }
95
+
96
+ static VALUE rb_transform(VALUE self, VALUE source, VALUE options) {
97
+ (void) self;
98
+
99
+ return call(oxc_transform, source, options);
100
+ }
101
+
102
+ static VALUE rb_parse(VALUE self, VALUE source, VALUE options) {
103
+ (void) self;
104
+
105
+ return call(oxc_parse, source, options);
106
+ }
107
+
108
+ static VALUE rb_native_version(VALUE self) {
109
+ (void) self;
110
+
111
+ return take_utf8_string(oxc_version());
112
+ }
113
+
114
+ static VALUE rb_oxc_version(VALUE self) {
115
+ (void) self;
116
+
117
+ return take_utf8_string(oxc_oxc_version());
118
+ }
119
+
120
+ void Init_oxc(void) {
121
+ rb_mOxc = rb_define_module("Oxc");
122
+ rb_mBackend = rb_define_module_under(rb_mOxc, "Backend");
123
+
124
+ rb_eError = rb_define_class_under(rb_mOxc, "Error", rb_eStandardError);
125
+ rb_eOptionError = rb_define_class_under(rb_mOxc, "OptionError", rb_eError);
126
+ rb_eOxcEncodingError = rb_define_class_under(rb_mOxc, "EncodingError", rb_eError);
127
+ rb_eTransformError = rb_define_class_under(rb_mOxc, "TransformError", rb_eError);
128
+ rb_eInternalError = rb_define_class_under(rb_mOxc, "InternalError", rb_eError);
129
+ rb_ePanicError = rb_define_class_under(rb_mOxc, "PanicError", rb_eInternalError);
130
+
131
+ rb_define_singleton_method(rb_mBackend, "minify", rb_minify, 2);
132
+ rb_define_singleton_method(rb_mBackend, "transform", rb_transform, 2);
133
+ rb_define_singleton_method(rb_mBackend, "parse", rb_parse, 2);
134
+ rb_define_singleton_method(rb_mBackend, "version", rb_native_version, 0);
135
+ rb_define_singleton_method(rb_mBackend, "oxc_version", rb_oxc_version, 0);
136
+ }
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ module Backend
5
+ module Unavailable
6
+ #: (String, String) -> String
7
+ def minify(_source, _options_json)
8
+ unavailable(__method__)
9
+ end
10
+
11
+ #: (String, String) -> String
12
+ def transform(_source, _options_json)
13
+ unavailable(__method__)
14
+ end
15
+
16
+ #: (String, String) -> String
17
+ def parse(_source, _options_json)
18
+ unavailable(__method__)
19
+ end
20
+
21
+ #: () -> String
22
+ def version
23
+ unavailable(__method__)
24
+ end
25
+
26
+ #: () -> String
27
+ def oxc_version
28
+ unavailable(__method__)
29
+ end
30
+
31
+ private
32
+
33
+ #: (Symbol?) -> bot
34
+ def unavailable(name)
35
+ raise NotImplementedError, "Oxc::Backend.#{name} is defined by the native extension, which did not load"
36
+ end
37
+ end
38
+
39
+ extend Unavailable
40
+ end
41
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ # @rbs module-self _Diagnosed
5
+ module Diagnosed
6
+ # @rbs @panicked: bool
7
+
8
+ #: () -> Array[Oxc::Diagnostic]
9
+ def errors
10
+ diagnostics.select(&:error?)
11
+ end
12
+
13
+ #: () -> Array[Oxc::Diagnostic]
14
+ def warnings
15
+ diagnostics.select(&:warning?)
16
+ end
17
+
18
+ #: () -> bool
19
+ def errors?
20
+ !errors.empty?
21
+ end
22
+
23
+ #: () -> bool
24
+ def warnings?
25
+ !warnings.empty?
26
+ end
27
+
28
+ #: () -> bool
29
+ def panicked?
30
+ @panicked
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Diagnostic
5
+ ERROR = "error" #: String
6
+ WARNING = "warning" #: String
7
+
8
+ attr_reader :severity #: String
9
+ attr_reader :message #: String
10
+ attr_reader :labels #: Array[Oxc::Label]
11
+ attr_reader :help #: String?
12
+ attr_reader :codeframe #: String?
13
+
14
+ #: (Hash[String, untyped]) -> Oxc::Diagnostic
15
+ def self.from_hash(parsed)
16
+ new(
17
+ severity: parsed.fetch("severity"),
18
+ message: parsed.fetch("message"),
19
+ labels: parsed.fetch("labels").map { |label| Label.from_hash(label) },
20
+ help: parsed["help"],
21
+ codeframe: parsed["codeframe"]
22
+ )
23
+ end
24
+
25
+ #: (severity: String, message: String, labels: Array[Oxc::Label], ?help: String?, ?codeframe: String?) -> void
26
+ def initialize(severity:, message:, labels:, help: nil, codeframe: nil)
27
+ @severity = severity
28
+ @message = message
29
+ @labels = labels.freeze
30
+ @help = help
31
+ @codeframe = codeframe
32
+
33
+ freeze
34
+ end
35
+
36
+ #: () -> bool
37
+ def error?
38
+ severity == ERROR
39
+ end
40
+
41
+ #: () -> bool
42
+ def warning?
43
+ severity == WARNING
44
+ end
45
+
46
+ #: () -> String
47
+ def to_s
48
+ message
49
+ end
50
+
51
+ #: () -> String
52
+ def inspect
53
+ "#<#{self.class.name} #{severity} #{message.inspect}>"
54
+ end
55
+ end
56
+
57
+ class Label
58
+ attr_reader :message #: String?
59
+ attr_reader :start #: Integer
60
+ attr_reader :finish #: Integer
61
+
62
+ #: (Hash[String, untyped]) -> Oxc::Label
63
+ def self.from_hash(parsed)
64
+ new(message: parsed["message"], start: parsed.fetch("start"), finish: parsed.fetch("end"))
65
+ end
66
+
67
+ #: (start: Integer, finish: Integer, ?message: String?) -> void
68
+ def initialize(start:, finish:, message: nil)
69
+ @start = start
70
+ @finish = finish
71
+ @message = message
72
+
73
+ freeze
74
+ end
75
+
76
+ #: (String) -> String?
77
+ def slice(source)
78
+ source.byteslice(start, finish - start)
79
+ end
80
+
81
+ #: () -> String
82
+ def inspect
83
+ "#<#{self.class.name} #{start}..#{finish}#{" #{message.inspect}" if message}>"
84
+ end
85
+ end
86
+ end
data/lib/oxc/errors.rb ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Error < StandardError; end
5
+ class OptionError < Error; end
6
+ class EncodingError < Error; end
7
+ class TransformError < Error; end
8
+ class InternalError < Error; end
9
+ class PanicError < InternalError; end
10
+
11
+ class SyntaxError < Error
12
+ attr_reader :result #: (Oxc::Result | Oxc::ParseResult)?
13
+
14
+ #: (String, ?(Oxc::Result | Oxc::ParseResult)?) -> void
15
+ def initialize(message, result = nil)
16
+ super(message)
17
+
18
+ @result = result
19
+ end
20
+
21
+ #: () -> Array[Oxc::Diagnostic]
22
+ def diagnostics
23
+ result ? result.diagnostics : []
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Minifier
5
+ attr_reader :options #: Hash[Symbol, untyped]
6
+
7
+ #: (?filename: String?, ?lang: String?, ?source_type: String?, ?compress: compress?, ?mangle: mangle?, ?codegen: codegen?, ?sourcemap: bool, ?strict: bool) -> void
8
+ def initialize(**options)
9
+ @options = options.transform_keys(&:to_sym).freeze
10
+
11
+ freeze
12
+ end
13
+
14
+ #: (String, ?filename: String?, ?lang: String?, ?source_type: String?, ?compress: compress?, ?mangle: mangle?, ?codegen: codegen?, ?sourcemap: bool, ?strict: bool) -> Oxc::MinifyResult
15
+ def minify(source, **overrides)
16
+ Oxc.minify(source, **options, **overrides)
17
+ end
18
+
19
+ alias call minify
20
+
21
+ #: (?filename: String?, ?lang: String?, ?source_type: String?, ?compress: compress?, ?mangle: mangle?, ?codegen: codegen?, ?sourcemap: bool, ?strict: bool) -> Oxc::Minifier
22
+ def with(**overrides)
23
+ self.class.new(**options, **overrides)
24
+ end
25
+
26
+ #: () -> String
27
+ def inspect
28
+ "#<#{self.class.name} #{options.inspect}>"
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class MinifyResult < Result
5
+ #: (String) -> Oxc::MinifyResult
6
+ def self.from_json(payload)
7
+ parsed = JSON.parse(payload)
8
+
9
+ new(
10
+ code: parsed.fetch("code"),
11
+ map: parsed["map"],
12
+ legal_comments: parsed.fetch("legal_comments"),
13
+ diagnostics: parsed.fetch("errors").map { |diagnostic| Diagnostic.from_hash(diagnostic) },
14
+ panicked: parsed.fetch("panicked")
15
+ )
16
+ end
17
+
18
+ #: (code: String, diagnostics: Array[Oxc::Diagnostic], ?map: String?, ?legal_comments: Array[String], ?panicked: bool) -> void
19
+ def initialize(...)
20
+ super
21
+
22
+ freeze
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Options
5
+ MINIFY = [
6
+ :filename,
7
+ :lang,
8
+ :source_type,
9
+ :compress,
10
+ :mangle,
11
+ :codegen,
12
+ :sourcemap,
13
+ :strict
14
+ ].freeze #: Array[Symbol]
15
+
16
+ TRANSFORM = [
17
+ :filename,
18
+ :lang,
19
+ :source_type,
20
+ :cwd,
21
+ :target,
22
+ :jsx,
23
+ :typescript,
24
+ :assumptions,
25
+ :decorator,
26
+ :helpers,
27
+ :define,
28
+ :inject,
29
+ :minify,
30
+ :codegen,
31
+ :sourcemap,
32
+ :strict
33
+ ].freeze #: Array[Symbol]
34
+
35
+ PARSE = [
36
+ :filename,
37
+ :lang,
38
+ :source_type,
39
+ :ast_type,
40
+ :ast,
41
+ :ranges,
42
+ :preserve_parens,
43
+ :comments,
44
+ :module_record,
45
+ :symbols,
46
+ :semantic_errors
47
+ ].freeze #: Array[Symbol]
48
+
49
+ KNOWN = (MINIFY | TRANSFORM | PARSE).freeze #: Array[Symbol]
50
+ RUBY_ONLY = [:strict].freeze #: Array[Symbol]
51
+
52
+ # TODO: support mangle_props. It needs `lazy-regex` and `rustc-hash` as direct dependencies of the
53
+ # Rust crate, because `oxc_minifier::ManglePropertiesOptions` types `include` and `exclude` as
54
+ # `lazy_regex::Regex` and `reserved` as `FxHashSet<CompactStr>`.
55
+ UNSUPPORTED = [:mangle_props].freeze #: Array[Symbol]
56
+
57
+ attr_reader :to_h #: Hash[Symbol, untyped]
58
+
59
+ #: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> String
60
+ def self.serialize(options, allowed = KNOWN, subject = "a call")
61
+ new(options, allowed, subject).to_json
62
+ end
63
+
64
+ #: (Hash[Symbol, untyped], ?Array[Symbol], ?String) -> void
65
+ def initialize(options, allowed = KNOWN, subject = "a call")
66
+ given = options.transform_keys(&:to_sym)
67
+
68
+ validate!(given.keys, allowed, subject)
69
+
70
+ @to_h = normalize(given).freeze
71
+
72
+ freeze
73
+ end
74
+
75
+ #: (?untyped) -> String
76
+ def to_json(state = nil)
77
+ JSON.generate(to_h, state)
78
+ end
79
+
80
+ #: () -> String
81
+ def inspect
82
+ "#<#{self.class.name} #{to_h.inspect}>"
83
+ end
84
+
85
+ private
86
+
87
+ #: (Array[Symbol], Array[Symbol], String) -> void
88
+ def validate!(names, allowed, subject)
89
+ unsupported = names & UNSUPPORTED
90
+
91
+ raise OptionError, "#{unsupported.join(", ")} is not supported yet" if unsupported.any?
92
+
93
+ unknown = names - KNOWN
94
+
95
+ raise OptionError, "Unknown option#{"s" if unknown.length > 1}: #{unknown.join(", ")}" if unknown.any?
96
+
97
+ unsupported = names - allowed
98
+
99
+ return if unsupported.empty?
100
+
101
+ raise OptionError, "#{unsupported.join(", ")} #{unsupported.one? ? "is not an option" : "are not options"} for #{subject}"
102
+ end
103
+
104
+ #: (Hash[Symbol, untyped]) -> Hash[Symbol, untyped]
105
+ def normalize(options)
106
+ normalized = options.dup
107
+
108
+ RUBY_ONLY.each { |name| normalized.delete(name) }
109
+
110
+ normalized.compact
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class ParseResult
5
+ include Diagnosed
6
+
7
+ attr_reader :program #: Hash[String, untyped]?
8
+ attr_reader :module_record #: Hash[String, untyped]?
9
+ attr_reader :symbols #: Hash[String, untyped]?
10
+ attr_reader :comments #: Array[Oxc::Comment]
11
+ attr_reader :diagnostics #: Array[Oxc::Diagnostic]
12
+
13
+ #: (String) -> Oxc::ParseResult
14
+ def self.from_json(payload)
15
+ parsed = JSON.parse(payload)
16
+
17
+ new(
18
+ program: parsed["program"],
19
+ module_record: parsed["module_record"],
20
+ symbols: parsed["symbols"],
21
+ comments: parsed.fetch("comments").map { |comment| Comment.from_hash(comment) },
22
+ diagnostics: parsed.fetch("errors").map { |diagnostic| Diagnostic.from_hash(diagnostic) },
23
+ panicked: parsed.fetch("panicked")
24
+ )
25
+ end
26
+
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
+ @program = program.freeze
30
+ @module_record = module_record.freeze
31
+ @symbols = symbols.freeze
32
+ @comments = comments.freeze
33
+ @diagnostics = diagnostics.freeze
34
+ @panicked = panicked
35
+
36
+ freeze
37
+ end
38
+
39
+ #: () -> Oxc::ParseResult
40
+ def validate!
41
+ return self unless errors? || panicked?
42
+
43
+ raise SyntaxError.new(errors.first&.message || "oxc could not read the source", self)
44
+ end
45
+
46
+ #: () -> String
47
+ def inspect
48
+ parts = [] #: Array[String]
49
+ parts << "program=#{program["type"]}" if program
50
+ parts << "comments=#{comments.length}" unless comments.empty?
51
+ parts << "diagnostics=#{diagnostics.length}" unless diagnostics.empty?
52
+
53
+ "#<#{self.class.name}#{" #{parts.join(" ")}" unless parts.empty?}>"
54
+ end
55
+ end
56
+
57
+ class Comment
58
+ LINE = "Line" #: String
59
+ BLOCK = "Block" #: String
60
+
61
+ attr_reader :type #: String
62
+ attr_reader :value #: String
63
+ attr_reader :start #: Integer
64
+ attr_reader :finish #: Integer
65
+
66
+ #: (Hash[String, untyped]) -> Oxc::Comment
67
+ def self.from_hash(parsed)
68
+ new(
69
+ type: parsed.fetch("type"),
70
+ value: parsed.fetch("value"),
71
+ start: parsed.fetch("start"),
72
+ finish: parsed.fetch("end")
73
+ )
74
+ end
75
+
76
+ #: (type: String, value: String, start: Integer, finish: Integer) -> void
77
+ def initialize(type:, value:, start:, finish:)
78
+ @type = type
79
+ @value = value
80
+ @start = start
81
+ @finish = finish
82
+
83
+ freeze
84
+ end
85
+
86
+ #: () -> bool
87
+ def line?
88
+ type == LINE
89
+ end
90
+
91
+ #: () -> bool
92
+ def block?
93
+ type == BLOCK
94
+ end
95
+
96
+ #: (String) -> String?
97
+ def slice(source)
98
+ source.byteslice(start, finish - start)
99
+ end
100
+
101
+ #: () -> String
102
+ def inspect
103
+ "#<#{self.class.name} #{type} #{value.inspect}>"
104
+ end
105
+ end
106
+ end
data/lib/oxc/result.rb ADDED
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Oxc
4
+ class Result
5
+ include Diagnosed
6
+
7
+ attr_reader :code #: String
8
+ attr_reader :map #: String?
9
+ attr_reader :legal_comments #: Array[String]
10
+ attr_reader :diagnostics #: Array[Oxc::Diagnostic]
11
+
12
+ #: (code: String, diagnostics: Array[Oxc::Diagnostic], ?map: String?, ?legal_comments: Array[String], ?panicked: bool) -> void
13
+ def initialize(code:, diagnostics:, map: nil, legal_comments: [], panicked: false)
14
+ @code = code
15
+ @map = map
16
+ @legal_comments = legal_comments.freeze
17
+ @diagnostics = diagnostics.freeze
18
+ @panicked = panicked
19
+ end
20
+
21
+ #: (?strict: untyped) -> self
22
+ def validate!(strict: false)
23
+ return self unless errors? || panicked?
24
+ return self unless strict || panicked? || code.empty?
25
+
26
+ raise SyntaxError.new(errors.first&.message || "oxc could not read the source", self)
27
+ end
28
+
29
+ #: () -> String
30
+ def to_s
31
+ code
32
+ end
33
+
34
+ #: () -> String
35
+ def inspect
36
+ "#<#{self.class.name} #{parts.join(" ")}>"
37
+ end
38
+
39
+ private
40
+
41
+ #: () -> Array[String]
42
+ def parts
43
+ parts = ["code=#{code.inspect}"] #: Array[String]
44
+ parts << "map=#{map.length} bytes" if map
45
+ parts << "legal_comments=#{legal_comments.inspect}" unless legal_comments.empty?
46
+ parts << "diagnostics=#{diagnostics.length}" unless diagnostics.empty?
47
+
48
+ parts
49
+ end
50
+ end
51
+ end