mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 04:08:41 +00:00
fix(coverage): apply always_strict to test262 and typescript per the specifcation (#5555)
This also removes the confusing `SourceType::always_strict` field. I hacked it with `SourceType::always_strict`, but what we actually want is add `'use strict'`. This is technically a breaking change but I don't expect anyone using this outside of oxc. The snapshot has a large diff due to every single line shifting by 1 row :-/
This commit is contained in:
parent
b06052501a
commit
28b934ca74
9 changed files with 21204 additions and 21169 deletions
|
|
@ -1400,7 +1400,7 @@ const _: () = {
|
|||
assert!(offset_of!(Span, start) == 0usize);
|
||||
assert!(offset_of!(Span, end) == 4usize);
|
||||
|
||||
assert!(size_of::<SourceType>() == 4usize);
|
||||
assert!(size_of::<SourceType>() == 3usize);
|
||||
assert!(align_of::<SourceType>() == 1usize);
|
||||
|
||||
assert!(size_of::<Language>() == 1usize);
|
||||
|
|
@ -2954,7 +2954,7 @@ const _: () = {
|
|||
assert!(offset_of!(Span, start) == 0usize);
|
||||
assert!(offset_of!(Span, end) == 4usize);
|
||||
|
||||
assert!(size_of::<SourceType>() == 4usize);
|
||||
assert!(size_of::<SourceType>() == 3usize);
|
||||
assert!(align_of::<SourceType>() == 1usize);
|
||||
|
||||
assert!(size_of::<Language>() == 1usize);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ impl SourceType {
|
|||
language: Language::JavaScript,
|
||||
module_kind: ModuleKind::Script,
|
||||
variant: LanguageVariant::Standard,
|
||||
always_strict: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -110,7 +109,6 @@ impl SourceType {
|
|||
language: Language::TypeScript,
|
||||
module_kind: ModuleKind::Module,
|
||||
variant: LanguageVariant::Standard,
|
||||
always_strict: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +148,6 @@ impl SourceType {
|
|||
language: Language::TypeScriptDefinition,
|
||||
module_kind: ModuleKind::Module,
|
||||
variant: LanguageVariant::Standard,
|
||||
always_strict: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -185,12 +182,8 @@ impl SourceType {
|
|||
self.variant == LanguageVariant::Jsx
|
||||
}
|
||||
|
||||
pub fn always_strict(self) -> bool {
|
||||
self.always_strict
|
||||
}
|
||||
|
||||
pub fn is_strict(self) -> bool {
|
||||
self.is_module() || self.always_strict
|
||||
self.is_module()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
|
@ -235,12 +228,6 @@ impl SourceType {
|
|||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn with_always_strict(mut self, yes: bool) -> Self {
|
||||
self.always_strict = yes;
|
||||
self
|
||||
}
|
||||
|
||||
/// Converts a file [`Path`] to [`SourceType`].
|
||||
///
|
||||
/// ## Examples
|
||||
|
|
@ -329,7 +316,7 @@ impl SourceType {
|
|||
_ => LanguageVariant::Standard,
|
||||
};
|
||||
|
||||
Ok(Self { language, module_kind, variant, always_strict: false })
|
||||
Ok(Self { language, module_kind, variant })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use oxc_ast_macros::ast;
|
||||
#[cfg(feature = "serialize")]
|
||||
use ::{serde::Serialize, tsify::Tsify};
|
||||
use {serde::Serialize, tsify::Tsify};
|
||||
|
||||
/// Source Type for JavaScript vs TypeScript / Script vs Module / JSX
|
||||
#[ast]
|
||||
|
|
@ -19,11 +19,6 @@ pub struct SourceType {
|
|||
|
||||
/// Support JSX for JavaScript and TypeScript? default without JSX
|
||||
pub(super) variant: LanguageVariant,
|
||||
|
||||
/// Mark strict mode as always strict
|
||||
///
|
||||
/// See <https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode>
|
||||
pub(super) always_strict: bool,
|
||||
}
|
||||
|
||||
/// JavaScript or TypeScript
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3,7 +3,7 @@ commit: a709f989
|
|||
parser_typescript Summary:
|
||||
AST Parsed : 6470/6479 (99.86%)
|
||||
Positive Passed: 6445/6479 (99.48%)
|
||||
Negative Passed: 1208/5715 (21.14%)
|
||||
Negative Passed: 1212/5715 (21.21%)
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration10.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration11.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ClassDeclaration13.ts
|
||||
|
|
@ -50,10 +50,6 @@ Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/allowSynthet
|
|||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/allowSyntheticDefaultImports3.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/allowSyntheticDefaultImports6.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/allowSyntheticDefaultImports8.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/alwaysStrict.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/alwaysStrictES6.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/alwaysStrictModule.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ambientEnum1.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ambientExportDefaultErrors.ts
|
||||
Expect Syntax Error: tasks/coverage/typescript/tests/cases/compiler/ambientExternalModuleInAnotherExternalModule.ts
|
||||
|
|
@ -5091,11 +5087,43 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/typeFro
|
|||
╰────
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrictModule2.ts:3:13]
|
||||
2 │ export function f() {
|
||||
3 │ var arguments = [];
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrict.ts:3:9]
|
||||
2 │ function f() {
|
||||
3 │ var arguments = [];
|
||||
· ─────────
|
||||
4 │ }
|
||||
╰────
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrictES6.ts:3:9]
|
||||
2 │ function f() {
|
||||
3 │ var arguments = [];
|
||||
· ─────────
|
||||
4 │ }
|
||||
╰────
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrictModule.ts:4:13]
|
||||
3 │ export function f() {
|
||||
4 │ var arguments = [];
|
||||
· ─────────
|
||||
4 │ }
|
||||
5 │ }
|
||||
╰────
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrictModule2.ts:4:13]
|
||||
3 │ export function f() {
|
||||
4 │ var arguments = [];
|
||||
· ─────────
|
||||
5 │ }
|
||||
╰────
|
||||
|
||||
× Cannot assign to 'arguments' in strict mode
|
||||
╭─[typescript/tests/cases/compiler/alwaysStrictNoImplicitUseStrict.ts:4:13]
|
||||
3 │ export function f() {
|
||||
4 │ var arguments = [];
|
||||
· ─────────
|
||||
5 │ }
|
||||
╰────
|
||||
|
||||
× TS(1039): Initializers are not allowed in ambient contexts.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
fs,
|
||||
io::{stdout, Read, Write},
|
||||
panic::UnwindSafe,
|
||||
|
|
@ -291,6 +292,13 @@ pub trait Case: Sized + Sync + Send + UnwindSafe {
|
|||
false
|
||||
}
|
||||
|
||||
/// Mark strict mode as always strict
|
||||
///
|
||||
/// See <https://github.com/tc39/test262/blob/main/INTERPRETING.md#strict-mode>
|
||||
fn always_strict(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn test_passed(&self) -> bool {
|
||||
let result = self.test_result();
|
||||
assert!(!matches!(result, TestResult::ToBeRun), "test should be run");
|
||||
|
|
@ -317,7 +325,6 @@ pub trait Case: Sized + Sync + Send + UnwindSafe {
|
|||
|
||||
/// Execute the parser once and get the test result
|
||||
fn execute(&mut self, source_type: SourceType) -> TestResult {
|
||||
let source_text = self.code();
|
||||
let path = self.path();
|
||||
|
||||
let mut driver = Driver {
|
||||
|
|
@ -325,7 +332,17 @@ pub trait Case: Sized + Sync + Send + UnwindSafe {
|
|||
allow_return_outside_function: self.allow_return_outside_function(),
|
||||
..Driver::default()
|
||||
};
|
||||
driver.run(source_text, source_type);
|
||||
|
||||
let source_text = if self.always_strict() {
|
||||
// To run in strict mode, the test contents must be modified prior to execution--
|
||||
// a "use strict" directive must be inserted as the initial character sequence of the file,
|
||||
// followed by a semicolon (;) and newline character (\n): "use strict";
|
||||
Cow::Owned(format!("'use strict';\n{}", self.code()))
|
||||
} else {
|
||||
Cow::Borrowed(self.code())
|
||||
};
|
||||
|
||||
driver.run(&source_text, source_type);
|
||||
let errors = driver.errors();
|
||||
|
||||
let result = if errors.is_empty() {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ pub struct Test262Case {
|
|||
code: String,
|
||||
meta: MetaData,
|
||||
should_fail: bool,
|
||||
always_strict: bool,
|
||||
result: TestResult,
|
||||
}
|
||||
|
||||
|
|
@ -79,7 +80,7 @@ impl Case for Test262Case {
|
|||
fn new(path: PathBuf, code: String) -> Self {
|
||||
let meta = Self::read_metadata(&code);
|
||||
let should_fail = Self::compute_should_fail(&meta);
|
||||
Self { path, code, meta, should_fail, result: TestResult::ToBeRun }
|
||||
Self { path, code, meta, should_fail, always_strict: false, result: TestResult::ToBeRun }
|
||||
}
|
||||
|
||||
fn code(&self) -> &str {
|
||||
|
|
@ -98,6 +99,10 @@ impl Case for Test262Case {
|
|||
self.should_fail
|
||||
}
|
||||
|
||||
fn always_strict(&self) -> bool {
|
||||
self.always_strict
|
||||
}
|
||||
|
||||
fn skip_test_case(&self) -> bool {
|
||||
[
|
||||
// ES2025 https://github.com/tc39/proposal-duplicate-named-capturing-groups
|
||||
|
|
@ -124,15 +129,18 @@ impl Case for Test262Case {
|
|||
let source_type = SourceType::default().with_script(true);
|
||||
|
||||
self.result = if flags.contains(&TestFlag::OnlyStrict) {
|
||||
self.execute(source_type.with_always_strict(true))
|
||||
self.always_strict = true;
|
||||
self.execute(source_type)
|
||||
} else if flags.contains(&TestFlag::Module) {
|
||||
self.execute(source_type.with_module(true))
|
||||
} else if flags.contains(&TestFlag::NoStrict) || flags.contains(&TestFlag::Raw) {
|
||||
self.execute(source_type)
|
||||
} else {
|
||||
let res = self.execute(source_type.with_always_strict(true));
|
||||
self.always_strict = true;
|
||||
let res = self.execute(source_type);
|
||||
if matches!(res, TestResult::Passed) {
|
||||
self.execute(source_type.with_always_strict(false))
|
||||
self.always_strict = false;
|
||||
self.execute(source_type)
|
||||
} else {
|
||||
res
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,10 @@ impl Case for TypeScriptCase {
|
|||
!self.error_files.is_empty()
|
||||
}
|
||||
|
||||
fn always_strict(&self) -> bool {
|
||||
self.settings.always_strict
|
||||
}
|
||||
|
||||
fn run(&mut self) {
|
||||
let units = self.units.clone();
|
||||
for unit in units {
|
||||
|
|
|
|||
|
|
@ -106,13 +106,9 @@ fn source_type_from_code_element(code: ElementRef) -> Option<SourceType> {
|
|||
};
|
||||
|
||||
match *lang {
|
||||
"javascript" | "js" => Some(SourceType::default().with_always_strict(true)),
|
||||
"typescript" | "ts" => {
|
||||
Some(SourceType::default().with_typescript(true).with_always_strict(true))
|
||||
}
|
||||
"tsx" => Some(
|
||||
SourceType::default().with_typescript(true).with_jsx(true).with_always_strict(true),
|
||||
),
|
||||
"javascript" | "js" => Some(SourceType::default()),
|
||||
"typescript" | "ts" => Some(SourceType::default().with_typescript(true)),
|
||||
"tsx" => Some(SourceType::default().with_typescript(true).with_jsx(true)),
|
||||
// FIXME: lots of jsx examples are usefully succinct but not valid JSX.
|
||||
// "jsx" => Some(SourceType::default().with_jsx(true).with_always_strict(true)),
|
||||
_ => None,
|
||||
|
|
|
|||
Loading…
Reference in a new issue