Skip to content

Commit 61085b8

Browse files
committed
Guide zero duration migration
1 parent d6d5f94 commit 61085b8

4 files changed

Lines changed: 74 additions & 4 deletions

File tree

‎crates/splitscript-syntax/src/migration.rs‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub enum ForeignSpellingContext {
9898
StaticTypeReceiver,
9999
Method,
100100
ValuePath,
101+
AttachedProcessValuePath,
101102
Operator,
102103
}
103104

@@ -595,6 +596,14 @@ const DURATION_SPELLINGS: &[ForeignSpelling] = &[
595596
"SplitScript uses `Duration` instead of `TimeSpan` for timer durations",
596597
"replace this C# type name"
597598
),
599+
type_spelling!(
600+
SourceLanguage::CSharp,
601+
ForeignSpellingContext::ValuePath,
602+
"Duration.Zero",
603+
"Duration.zero()",
604+
"SplitScript constructs a zero duration with `Duration.zero()`",
605+
"replace this C# static property"
606+
),
598607
];
599608

600609
macro_rules! numeric_spelling {
@@ -632,7 +641,7 @@ const NUMERIC_SPELLINGS: &[ForeignSpelling] = &[
632641

633642
const ASL_PROCESS_IDENTITY_SPELLINGS: &[ForeignSpelling] = &[ForeignSpelling {
634643
source: SourceLanguage::Asl,
635-
context: ForeignSpellingContext::ValuePath,
644+
context: ForeignSpellingContext::AttachedProcessValuePath,
636645
spelling: "game.ProcessName",
637646
replacement: ForeignSpellingReplacement::Text("process.name()"),
638647
message: "ASL `game.ProcessName` is `process.name()` in SplitScript",

‎docs/ROADMAP_ARCHIVE.md‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
- Applying all offered edits now has regression coverage proving that the
99
result is canonical, compilable `Duration.fromSeconds(...)` and
1010
`Duration.fromMilliseconds(...)` source.
11+
- Added the corpus-proven C# static-property rewrite from `TimeSpan.Zero` to
12+
the canonical constructor call `Duration.zero()`; no compatibility property
13+
was introduced.
14+
- Separated ordinary value-path migrations from rewrites that require an
15+
attached native process, so process availability no longer leaks into
16+
unrelated fixes.
1117
- Kept JavaScript `${...}` out of typo recovery because it is valid
1218
SplitScript source with observably different literal-dollar semantics.
1319

‎src/typeck/call_resolution.rs‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,8 +1244,15 @@ impl Checker {
12441244
self.errors.push(diagnostic);
12451245
return None;
12461246
}
1247-
if let Some(rule) =
1248-
foreign_spelling(&spelling, ForeignSpellingContext::ValuePath)
1247+
let ordinary_rule =
1248+
foreign_spelling(&spelling, ForeignSpellingContext::ValuePath);
1249+
let attached_process_rule = foreign_spelling(
1250+
&spelling,
1251+
ForeignSpellingContext::AttachedProcessValuePath,
1252+
);
1253+
if let Some((rule, requires_attached_process)) = ordinary_rule
1254+
.map(|rule| (rule, false))
1255+
.or_else(|| attached_process_rule.map(|rule| (rule, true)))
12491256
{
12501257
let mut diagnostic = Diagnostic::type_error(rule.message, span)
12511258
.with_primary_label(rule.primary_label);
@@ -1269,7 +1276,7 @@ impl Checker {
12691276
self.standard_library.state_provider(provider).value_name
12701277
== "process"
12711278
});
1272-
if process_is_available {
1279+
if !requires_attached_process || process_is_available {
12731280
diagnostic = diagnostic.with_machine_applicable_fix(
12741281
rule.fix_title,
12751282
span,

‎tests/compiler/diagnostics_migration.rs‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,54 @@ fn common_timespan_constructors_have_composable_machine_fixes() {
845845
.expect("applying every constructor migration fix should produce valid source");
846846
}
847847

848+
#[test]
849+
fn timespan_zero_migrates_to_the_duration_constructor() {
850+
use splitscript::FixApplicability;
851+
852+
let source = r#"
853+
state "game.exe" {}
854+
855+
gameTime {
856+
return TimeSpan.Zero
857+
}
858+
"#;
859+
let parsed = splitscript::parse_recovering(source).unwrap();
860+
assert_eq!(parsed.diagnostics().len(), 1);
861+
let type_edit = &parsed.diagnostics()[0].fixes[0].edits[0];
862+
assert_eq!(
863+
&source[type_edit.span.start..type_edit.span.end],
864+
"TimeSpan"
865+
);
866+
assert_eq!(type_edit.replacement, "Duration");
867+
868+
let mut fixed = source.to_owned();
869+
fixed.replace_range(
870+
type_edit.span.start..type_edit.span.end,
871+
&type_edit.replacement,
872+
);
873+
let diagnostics = splitscript::compile(&fixed)
874+
.expect_err("the C# static property still needs a constructor-call rewrite");
875+
assert_eq!(diagnostics.len(), 1);
876+
let diagnostic = &diagnostics[0];
877+
assert_eq!(
878+
&fixed[diagnostic.span.start..diagnostic.span.end],
879+
"Duration.Zero"
880+
);
881+
assert_eq!(diagnostic.fixes.len(), 1);
882+
assert_eq!(
883+
diagnostic.fixes[0].applicability,
884+
FixApplicability::MachineApplicable
885+
);
886+
let value_edit = &diagnostic.fixes[0].edits[0];
887+
assert_eq!(value_edit.replacement, "Duration.zero()");
888+
fixed.replace_range(
889+
value_edit.span.start..value_edit.span.end,
890+
&value_edit.replacement,
891+
);
892+
893+
splitscript::compile(&fixed).expect("the fully migrated zero duration should compile");
894+
}
895+
848896
#[test]
849897
fn legacy_process_identity_points_to_the_attached_process_api() {
850898
use splitscript::FixApplicability;

0 commit comments

Comments
 (0)