mirror of
https://github.com/danbulant/oxc
synced 2026-05-21 05:08:45 +00:00
feat(coverage): add regular expression idempotency test (#5676)
closes #5634
This commit is contained in:
parent
b9bf54494f
commit
2016bae98c
6 changed files with 63 additions and 6 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1409,6 +1409,7 @@ dependencies = [
|
||||||
"oxc_mangler",
|
"oxc_mangler",
|
||||||
"oxc_minifier",
|
"oxc_minifier",
|
||||||
"oxc_parser",
|
"oxc_parser",
|
||||||
|
"oxc_regular_expression",
|
||||||
"oxc_semantic",
|
"oxc_semantic",
|
||||||
"oxc_sourcemap",
|
"oxc_sourcemap",
|
||||||
"oxc_span",
|
"oxc_span",
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ required-features = ["full"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
oxc_allocator = { workspace = true }
|
oxc_allocator = { workspace = true }
|
||||||
oxc_ast = { workspace = true }
|
oxc_ast = { workspace = true }
|
||||||
|
oxc_parser = { workspace = true }
|
||||||
|
oxc_regular_expression = { workspace = true }
|
||||||
|
|
||||||
oxc_cfg = { workspace = true, optional = true }
|
oxc_cfg = { workspace = true, optional = true }
|
||||||
oxc_codegen = { workspace = true, optional = true }
|
oxc_codegen = { workspace = true, optional = true }
|
||||||
oxc_diagnostics = { workspace = true }
|
oxc_diagnostics = { workspace = true }
|
||||||
|
|
@ -35,7 +38,6 @@ oxc_index = { workspace = true }
|
||||||
oxc_isolated_declarations = { workspace = true, optional = true }
|
oxc_isolated_declarations = { workspace = true, optional = true }
|
||||||
oxc_mangler = { workspace = true, optional = true }
|
oxc_mangler = { workspace = true, optional = true }
|
||||||
oxc_minifier = { workspace = true, optional = true }
|
oxc_minifier = { workspace = true, optional = true }
|
||||||
oxc_parser = { workspace = true }
|
|
||||||
oxc_semantic = { workspace = true, optional = true }
|
oxc_semantic = { workspace = true, optional = true }
|
||||||
oxc_sourcemap = { workspace = true, optional = true }
|
oxc_sourcemap = { workspace = true, optional = true }
|
||||||
oxc_span = { workspace = true }
|
oxc_span = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,11 @@ pub mod parser {
|
||||||
pub use oxc_parser::*;
|
pub use oxc_parser::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod regular_expression {
|
||||||
|
#[doc(inline)]
|
||||||
|
pub use oxc_regular_expression::*;
|
||||||
|
}
|
||||||
|
|
||||||
pub mod span {
|
pub mod span {
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use oxc_span::*;
|
pub use oxc_span::*;
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@ commit: d62fa93c
|
||||||
|
|
||||||
parser_test262 Summary:
|
parser_test262 Summary:
|
||||||
AST Parsed : 43765/43765 (100.00%)
|
AST Parsed : 43765/43765 (100.00%)
|
||||||
Positive Passed: 43765/43765 (100.00%)
|
Positive Passed: 43764/43765 (100.00%)
|
||||||
Negative Passed: 4237/4237 (100.00%)
|
Negative Passed: 4237/4237 (100.00%)
|
||||||
|
Expect to Parse: tasks/coverage/test262/test/annexB/language/literals/regexp/legacy-octal-escape.js
|
||||||
|
|
||||||
|
× Regular Expression mismatch: \03 \3
|
||||||
|
|
||||||
× '0'-prefixed octal literals and octal escape sequences are deprecated
|
× '0'-prefixed octal literals and octal escape sequences are deprecated
|
||||||
╭─[test262/test/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict.js:19:4]
|
╭─[test262/test/annexB/language/expressions/template-literal/legacy-octal-escape-sequence-strict.js:19:4]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ commit: d62fa93c
|
||||||
|
|
||||||
semantic_test262 Summary:
|
semantic_test262 Summary:
|
||||||
AST Parsed : 43765/43765 (100.00%)
|
AST Parsed : 43765/43765 (100.00%)
|
||||||
Positive Passed: 43565/43765 (99.54%)
|
Positive Passed: 43564/43765 (99.54%)
|
||||||
tasks/coverage/test262/test/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
|
tasks/coverage/test262/test/annexB/language/function-code/if-decl-else-decl-a-func-block-scoping.js
|
||||||
semantic error: Symbol scope ID mismatch:
|
semantic error: Symbol scope ID mismatch:
|
||||||
after transform: SymbolId(3): ScopeId(4294967294)
|
after transform: SymbolId(3): ScopeId(4294967294)
|
||||||
|
|
@ -1119,6 +1119,9 @@ semantic error: Symbol scope ID mismatch:
|
||||||
after transform: SymbolId(0): ScopeId(4294967294)
|
after transform: SymbolId(0): ScopeId(4294967294)
|
||||||
rebuilt : SymbolId(0): ScopeId(4294967294)
|
rebuilt : SymbolId(0): ScopeId(4294967294)
|
||||||
|
|
||||||
|
tasks/coverage/test262/test/annexB/language/literals/regexp/legacy-octal-escape.js
|
||||||
|
semantic error: Regular Expression mismatch: \03 \3
|
||||||
|
|
||||||
tasks/coverage/test262/test/language/module-code/eval-rqstd-once.js
|
tasks/coverage/test262/test/language/module-code/eval-rqstd-once.js
|
||||||
semantic error: Bindings mismatch:
|
semantic error: Bindings mismatch:
|
||||||
after transform: ScopeId(0): ["dflt1", "dflt2", "dflt3", "global", "ns1", "ns3"]
|
after transform: ScopeId(0): ["dflt1", "dflt2", "dflt3", "global", "ns1", "ns3"]
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,19 @@
|
||||||
use std::{collections::HashSet, ops::ControlFlow, path::PathBuf};
|
use std::{collections::HashSet, ops::ControlFlow, path::PathBuf};
|
||||||
|
|
||||||
use oxc::{
|
use oxc::{
|
||||||
ast::{ast::Program, Trivias},
|
allocator::Allocator,
|
||||||
|
ast::{
|
||||||
|
ast::{Program, RegExpFlags},
|
||||||
|
Trivias,
|
||||||
|
},
|
||||||
codegen::CodegenOptions,
|
codegen::CodegenOptions,
|
||||||
diagnostics::OxcDiagnostic,
|
diagnostics::OxcDiagnostic,
|
||||||
minifier::CompressOptions,
|
minifier::CompressOptions,
|
||||||
parser::{ParseOptions, ParserReturn},
|
parser::{ParseOptions, ParserReturn},
|
||||||
|
regular_expression::{ParserOptions, PatternParser},
|
||||||
semantic::{
|
semantic::{
|
||||||
post_transform_checker::{check_semantic_after_transform, check_semantic_ids},
|
post_transform_checker::{check_semantic_after_transform, check_semantic_ids},
|
||||||
SemanticBuilderReturn,
|
Semantic, SemanticBuilderReturn,
|
||||||
},
|
},
|
||||||
span::{SourceType, Span},
|
span::{SourceType, Span},
|
||||||
transformer::{TransformOptions, TransformerReturn},
|
transformer::{TransformOptions, TransformerReturn},
|
||||||
|
|
@ -78,7 +83,7 @@ impl CompilerInterface for Driver {
|
||||||
fn after_semantic(
|
fn after_semantic(
|
||||||
&mut self,
|
&mut self,
|
||||||
program: &mut Program<'_>,
|
program: &mut Program<'_>,
|
||||||
_semantic_return: &mut SemanticBuilderReturn,
|
ret: &mut SemanticBuilderReturn,
|
||||||
) -> ControlFlow<()> {
|
) -> ControlFlow<()> {
|
||||||
if self.check_semantic {
|
if self.check_semantic {
|
||||||
if let Some(errors) = check_semantic_ids(program) {
|
if let Some(errors) = check_semantic_ids(program) {
|
||||||
|
|
@ -86,6 +91,7 @@ impl CompilerInterface for Driver {
|
||||||
return ControlFlow::Break(());
|
return ControlFlow::Break(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
self.check_regular_expressions(&ret.semantic);
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -150,4 +156,41 @@ impl Driver {
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Idempotency test for printing regular expressions.
|
||||||
|
fn check_regular_expressions(&mut self, semantic: &Semantic<'_>) {
|
||||||
|
let allocator = Allocator::default();
|
||||||
|
for literal in semantic.nodes().iter().filter_map(|node| node.kind().as_reg_exp_literal()) {
|
||||||
|
let Some(pattern) = literal.regex.pattern.as_pattern() else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let printed1 = pattern.to_string();
|
||||||
|
let flags = literal.regex.flags;
|
||||||
|
let printed2 = match PatternParser::new(
|
||||||
|
&allocator,
|
||||||
|
&printed1,
|
||||||
|
ParserOptions {
|
||||||
|
span_offset: 0,
|
||||||
|
unicode_mode: flags.contains(RegExpFlags::U) || flags.contains(RegExpFlags::V),
|
||||||
|
unicode_sets_mode: flags.contains(RegExpFlags::V),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.parse()
|
||||||
|
{
|
||||||
|
Ok(pattern) => pattern.to_string(),
|
||||||
|
Err(error) => {
|
||||||
|
self.errors.push(OxcDiagnostic::error(format!(
|
||||||
|
"Failed to re-parse `{}`, printed as `/{printed1}/{flags}`, {error}",
|
||||||
|
literal.span.source_text(semantic.source_text()),
|
||||||
|
)));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if printed1 != printed2 {
|
||||||
|
self.errors.push(OxcDiagnostic::error(format!(
|
||||||
|
"Regular Expression mismatch: {printed1} {printed2}"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue