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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +437 -0
- data/ext/oxc/extconf.rb +123 -0
- data/ext/oxc/include/oxc.h +40 -0
- data/ext/oxc/oxc.c +136 -0
- data/lib/oxc/3.2/oxc.so +0 -0
- data/lib/oxc/3.3/oxc.so +0 -0
- data/lib/oxc/3.4/oxc.so +0 -0
- data/lib/oxc/4.0/oxc.so +0 -0
- data/lib/oxc/backend.rb +41 -0
- data/lib/oxc/diagnosed.rb +33 -0
- data/lib/oxc/diagnostic.rb +86 -0
- data/lib/oxc/errors.rb +26 -0
- data/lib/oxc/minifier.rb +31 -0
- data/lib/oxc/minify_result.rb +25 -0
- data/lib/oxc/options.rb +113 -0
- data/lib/oxc/parse_result.rb +106 -0
- data/lib/oxc/result.rb +51 -0
- data/lib/oxc/transform_result.rb +47 -0
- data/lib/oxc/transformer.rb +31 -0
- data/lib/oxc/version.rb +5 -0
- data/lib/oxc.rb +52 -0
- data/licenses/README.md +12 -0
- data/licenses/oxc-MIT.txt +22 -0
- data/licenses/oxc-THIRD-PARTY.txt +763 -0
- data/oxc.gemspec +43 -0
- data/rust/Cargo.lock +1436 -0
- data/rust/Cargo.toml +32 -0
- data/rust/build.rs +52 -0
- data/rust/cbindgen.toml +24 -0
- data/rust/rustfmt.toml +3 -0
- data/rust/src/diagnostic.rs +75 -0
- data/rust/src/lib.rs +288 -0
- data/rust/src/module_record.rs +262 -0
- data/rust/src/options.rs +744 -0
- data/rust/src/parse.rs +93 -0
- data/rust/src/result.rs +55 -0
- data/rust/src/source_type.rs +26 -0
- data/rust/src/symbols.rs +101 -0
- data/rust/src/transform.rs +116 -0
- data/sig/oxc/backend.rbs +29 -0
- data/sig/oxc/diagnosed.rbs +23 -0
- data/sig/oxc/diagnostic.rbs +57 -0
- data/sig/oxc/errors.rbs +31 -0
- data/sig/oxc/minifier.rbs +21 -0
- data/sig/oxc/minify_result.rbs +11 -0
- data/sig/oxc/options.rbs +42 -0
- data/sig/oxc/parse_result.rbs +61 -0
- data/sig/oxc/result.rbs +32 -0
- data/sig/oxc/transform_result.rbs +22 -0
- data/sig/oxc/transformer.rbs +21 -0
- data/sig/oxc/types.rbs +96 -0
- data/sig/oxc/version.rbs +5 -0
- data/sig/oxc.rbs +15 -0
- 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
|
+
}
|
data/lib/oxc/3.2/oxc.so
ADDED
|
Binary file
|
data/lib/oxc/3.3/oxc.so
ADDED
|
Binary file
|
data/lib/oxc/3.4/oxc.so
ADDED
|
Binary file
|
data/lib/oxc/4.0/oxc.so
ADDED
|
Binary file
|
data/lib/oxc/backend.rb
ADDED
|
@@ -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
|
data/lib/oxc/minifier.rb
ADDED
|
@@ -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
|
data/lib/oxc/options.rb
ADDED
|
@@ -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
|