forked from oxc-project/oxc
/
minifier.rs
104 lines (87 loc) · 2.87 KB
/
minifier.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use std::path::{Path, PathBuf};
use oxc_allocator::Allocator;
use oxc_codegen::{Codegen, CodegenOptions};
use oxc_minifier::{CompressOptions, Minifier, MinifierOptions};
use oxc_parser::Parser;
use oxc_span::SourceType;
use crate::{
babel::BabelCase,
suite::{Case, TestResult},
test262::{Test262Case, TestFlag},
};
pub struct MinifierTest262Case {
base: Test262Case,
}
impl Case for MinifierTest262Case {
fn new(path: PathBuf, code: String) -> Self {
Self { base: Test262Case::new(path, code) }
}
fn code(&self) -> &str {
self.base.code()
}
fn path(&self) -> &Path {
self.base.path()
}
fn test_result(&self) -> &TestResult {
self.base.test_result()
}
fn skip_test_case(&self) -> bool {
self.base.should_fail()
}
fn run(&mut self) {
let source_text = self.base.code();
let is_module = self.base.meta().flags.contains(&TestFlag::Module);
let source_type = SourceType::default().with_module(is_module);
let result = get_result(source_text, source_type);
self.base.set_result(result);
}
}
pub struct MinifierBabelCase {
base: BabelCase,
}
impl Case for MinifierBabelCase {
fn new(path: PathBuf, code: String) -> Self {
Self { base: BabelCase::new(path, code) }
}
fn code(&self) -> &str {
self.base.code()
}
fn path(&self) -> &Path {
self.base.path()
}
fn test_result(&self) -> &TestResult {
self.base.test_result()
}
fn skip_test_case(&self) -> bool {
self.base.skip_test_case()
|| self.base.should_fail()
|| self.base.source_type().is_typescript()
}
fn run(&mut self) {
let source_text = self.base.code();
let source_type = self.base.source_type();
let result = get_result(source_text, source_type);
self.base.set_result(result);
}
}
// Test minification by minifying twice because it is a idempotent
fn get_result(source_text: &str, source_type: SourceType) -> TestResult {
let options = MinifierOptions {
compress: CompressOptions { evaluate: false, ..CompressOptions::default() },
..MinifierOptions::default()
};
let source_text1 = minify(source_text, source_type, options);
let source_text2 = minify(&source_text1, source_type, options);
if source_text1 == source_text2 {
TestResult::Passed
} else {
TestResult::ParseError(String::new(), false)
}
}
fn minify(source_text: &str, source_type: SourceType, options: MinifierOptions) -> String {
let allocator = Allocator::default();
let program = Parser::new(&allocator, source_text, source_type).parse().program;
let program = allocator.alloc(program);
Minifier::new(options).build(&allocator, program);
Codegen::<true>::new("", source_text, CodegenOptions::default()).build(program).source_text
}