Skip to content

Commit ca0fafd

Browse files
authored
add baseline for linked editing (#54315)
1 parent 544d432 commit ca0fafd

7 files changed

+247
-90
lines changed

src/harness/fourslashImpl.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,6 +3586,73 @@ export class TestState {
35863586
}
35873587
}
35883588

3589+
public baselineLinkedEditing(): void {
3590+
const baselineFile = this.getBaselineFileNameForContainingTestFile(".linkedEditing.txt");
3591+
const files = this.testData.files;
3592+
3593+
let baselineContent = "";
3594+
let offset = 0;
3595+
for (const f of files) {
3596+
const result = getLinkedEditingBaselineWorker(f, offset, this.languageService);
3597+
baselineContent += result.baselineContent + `\n\n\n`;
3598+
offset = result.offset;
3599+
}
3600+
3601+
Harness.Baseline.runBaseline(baselineFile, baselineContent);
3602+
3603+
function getLinkedEditingBaselineWorker(activeFile: FourSlashFile, offset: number, languageService: ts.LanguageService) {
3604+
const fileName = activeFile.fileName;
3605+
let baselineContent = `=== ${fileName} ===\n`;
3606+
3607+
// get linkedEdit at every position in the file, then group positions by their linkedEdit
3608+
const linkedEditsInFile = new Map<string, number[]>();
3609+
for(let pos = 0; pos < activeFile.content.length; pos++) {
3610+
const linkedEditAtPosition = languageService.getLinkedEditingRangeAtPosition(fileName, pos);
3611+
if (!linkedEditAtPosition) continue;
3612+
3613+
const linkedEditString = JSON.stringify(linkedEditAtPosition);
3614+
const existingPositions = linkedEditsInFile.get(linkedEditString) ?? [];
3615+
linkedEditsInFile.set(linkedEditString, [...existingPositions, pos]);
3616+
}
3617+
3618+
const linkedEditsByRange = [...linkedEditsInFile.entries()].sort((a, b) => a[1][0] - b[1][0]);
3619+
if (linkedEditsByRange.length === 0) {
3620+
return { baselineContent: baselineContent + activeFile.content + `\n\n--No linked edits found--`, offset };
3621+
}
3622+
3623+
let inlineLinkedEditBaselines: { start: number, end: number, index: number }[] = [];
3624+
let linkedEditInfoBaseline = "";
3625+
for (const edit of linkedEditsByRange) {
3626+
const [linkedEdit, positions] = edit;
3627+
let rangeStart = 0;
3628+
for (let j = 0; j < positions.length - 1; j++) {
3629+
// for each distinct range in the list of positions, add an entry to the list of places that need to be annotated in the baseline
3630+
if (positions[j] + 1 !== positions[j + 1]) {
3631+
inlineLinkedEditBaselines.push({ start: positions[rangeStart], end: positions[j], index: offset });
3632+
rangeStart = j + 1;
3633+
}
3634+
}
3635+
inlineLinkedEditBaselines.push({ start: positions[rangeStart], end: positions[positions.length - 1], index: offset });
3636+
3637+
// add the LinkedEditInfo with its index to the baseline
3638+
linkedEditInfoBaseline += `\n\n=== ${offset} ===\n` + linkedEdit;
3639+
offset++;
3640+
}
3641+
3642+
inlineLinkedEditBaselines = inlineLinkedEditBaselines.sort((a, b) => a.start - b.start);
3643+
const fileText = activeFile.content;
3644+
baselineContent += fileText.slice(0, inlineLinkedEditBaselines[0].start);
3645+
for (let i = 0; i < inlineLinkedEditBaselines.length; i++) {
3646+
const e = inlineLinkedEditBaselines[i];
3647+
const sliceEnd = inlineLinkedEditBaselines[i + 1]?.start;
3648+
baselineContent += `[|/*${e.index}*/` + fileText.slice(e.start, e.end) + `|]` + fileText.slice(e.end, sliceEnd);
3649+
}
3650+
3651+
baselineContent += linkedEditInfoBaseline;
3652+
return { baselineContent, offset };
3653+
}
3654+
}
3655+
35893656
public verifyMatchingBracePosition(bracePosition: number, expectedMatchPosition: number) {
35903657
const actual = this.languageService.getBraceMatchingAtPosition(this.activeFile.fileName, bracePosition);
35913658

src/harness/fourslashInterfaceImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ export class VerifyNegatable {
181181
this.state.verifyLinkedEditingRange(map);
182182
}
183183

184+
public baselineLinkedEditing(): void {
185+
this.state.baselineLinkedEditing();
186+
}
187+
184188
public isInCommentAtPosition(onlyMultiLineDiverges?: boolean) {
185189
this.state.verifySpanOfEnclosingComment(this.negative, onlyMultiLineDiverges);
186190
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
=== /jsx0.tsx ===
2+
const jsx = <>
3+
4+
--No linked edits found--
5+
6+
7+
=== /jsx1.tsx ===
8+
const jsx = </>
9+
10+
--No linked edits found--
11+
12+
13+
=== /jsx2.tsx ===
14+
const jsx = <div>
15+
16+
--No linked edits found--
17+
18+
19+
=== /jsx3.tsx ===
20+
const jsx = </div>
21+
22+
--No linked edits found--
23+
24+
25+
=== /jsx4.tsx ===
26+
const jsx = <div> </>;
27+
28+
--No linked edits found--
29+
30+
31+
=== /jsx5.tsx ===
32+
const jsx = <> </div>;
33+
34+
--No linked edits found--
35+
36+
37+
=== /jsx6.tsx ===
38+
const jsx = div> </div>;
39+
40+
--No linked edits found--
41+
42+
43+
=== /jsx7.tsx ===
44+
const jsx = <div> /div>;
45+
46+
--No linked edits found--
47+
48+
49+
=== /jsx8.tsx ===
50+
const jsx = <div </div>;
51+
52+
--No linked edits found--
53+
54+
55+
=== /jsx9.tsx ===
56+
const jsx = <[|/*0*/div|]> </[|/*0*/div|];
57+
58+
=== 0 ===
59+
{"ranges":[{"start":13,"length":3},{"start":20,"length":3}],"wordPattern":"[a-zA-Z0-9:\\-\\._$]*"}
60+
61+
62+
=== /jsx10.tsx ===
63+
const jsx = <> </;
64+
65+
--No linked edits found--
66+
67+
68+
=== /jsx11.tsx ===
69+
const jsx = < </>;
70+
71+
--No linked edits found--
72+
73+
74+
=== /jsx12.tsx ===
75+
const jsx = > </>;
76+
77+
--No linked edits found--
78+
79+
80+
=== /jsx13.tsx ===
81+
const jsx = <> />;
82+
83+
--No linked edits found--
84+
85+
86+
=== /jsx14.tsx ===
87+
const jsx = <> <div> </> </div>;
88+
89+
--No linked edits found--
90+
91+
92+
=== /jsx15.tsx ===
93+
const jsx = <div> <> </div> </>;
94+
95+
--No linked edits found--
96+
97+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
=== /customElements.tsx ===
2+
const jsx = <[|/*0*/fbt:enum|] knownProp="accepted"
3+
unknownProp="rejected">
4+
</[|/*0*/fbt:enum|]>;
5+
6+
const customElement = <[|/*1*/custom-element|]></[|/*1*/custom-element|]>;
7+
8+
const standardElement =
9+
<[|/*2*/Link|] href="/hello" passHref>
10+
<[|/*3*/Button|] component="a">
11+
Next
12+
</[|/*3*/Button|]>
13+
</[|/*2*/Link|]>;
14+
15+
=== 0 ===
16+
{"ranges":[{"start":13,"length":8},{"start":73,"length":8}],"wordPattern":"[a-zA-Z0-9:\\-\\._$]*"}
17+
18+
=== 1 ===
19+
{"ranges":[{"start":108,"length":14},{"start":125,"length":14}],"wordPattern":"[a-zA-Z0-9:\\-\\._$]*"}
20+
21+
=== 2 ===
22+
{"ranges":[{"start":172,"length":4},{"start":269,"length":4}],"wordPattern":"[a-zA-Z0-9:\\-\\._$]*"}
23+
24+
=== 3 ===
25+
{"ranges":[{"start":209,"length":6},{"start":256,"length":6}],"wordPattern":"[a-zA-Z0-9:\\-\\._$]*"}
26+
27+

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ declare namespace FourSlashInterface {
263263
isValidBraceCompletionAtPosition(openingBrace?: string): void;
264264
jsxClosingTag(map: { [markerName: string]: { readonly newText: string } | undefined }): void;
265265
linkedEditing(map: { [markerName: string]: LinkedEditingInfo | undefined }): void;
266+
baselineLinkedEditing(): void;
266267
isInCommentAtPosition(onlyMultiLineDiverges?: boolean): void;
267268
codeFix(options: {
268269
description: string | [string, ...(string | number)[]] | DiagnosticIgnoredInterpolations,

tests/cases/fourslash/linkedEditingJsxTag10.ts

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -48,43 +48,46 @@
4848
// @Filename: /jsx15.tsx
4949
////const jsx = </*15*/div> </*15a*/> <//*15b*/div> <//*15c*/>;
5050

51-
const wordPattern = "[a-zA-Z0-9:\\-\\._$]*";
52-
const linkedCursors9 = {
53-
ranges: [{ start: test.markerByName("9").position, length: 3 }, { start: test.markerByName("9a").position, length: 3 }],
54-
wordPattern,
55-
};
56-
57-
verify.linkedEditing( {
58-
"0": undefined,
59-
"1": undefined,
60-
"2": undefined,
61-
"3": undefined,
62-
"4": undefined,
63-
"4a": undefined,
64-
"5": undefined,
65-
"5a": undefined,
66-
"6": undefined,
67-
"6a": undefined,
68-
"7": undefined,
69-
"7a": undefined,
70-
"8": undefined,
71-
"8a": undefined,
72-
"9": linkedCursors9,
73-
"9a": linkedCursors9,
74-
"10": undefined,
75-
"10a": undefined,
76-
"11": undefined,
77-
"11a": undefined,
78-
"12": undefined,
79-
"12a": undefined,
80-
"13": undefined,
81-
"13a": undefined,
82-
"14": undefined,
83-
"14a": undefined,
84-
"14b": undefined,
85-
"14c": undefined,
86-
"15": undefined,
87-
"15a": undefined,
88-
"15b": undefined,
89-
"15c": undefined,
90-
});
51+
verify.baselineLinkedEditing();
52+
53+
// below is the expected result
54+
55+
// const wordPattern = "[a-zA-Z0-9:\\-\\._$]*";
56+
// const linkedCursors9 = {
57+
// ranges: [{ start: test.markerByName("9").position, length: 3 }, { start: test.markerByName("9a").position, length: 3 }],
58+
// wordPattern,
59+
// };
60+
// verify.linkedEditing( {
61+
// "0": undefined,
62+
// "1": undefined,
63+
// "2": undefined,
64+
// "3": undefined,
65+
// "4": undefined,
66+
// "4a": undefined,
67+
// "5": undefined,
68+
// "5a": undefined,
69+
// "6": undefined,
70+
// "6a": undefined,
71+
// "7": undefined,
72+
// "7a": undefined,
73+
// "8": undefined,
74+
// "8a": undefined,
75+
// "9": linkedCursors9,
76+
// "9a": linkedCursors9,
77+
// "10": undefined,
78+
// "10a": undefined,
79+
// "11": undefined,
80+
// "11a": undefined,
81+
// "12": undefined,
82+
// "12a": undefined,
83+
// "13": undefined,
84+
// "13a": undefined,
85+
// "14": undefined,
86+
// "14a": undefined,
87+
// "14b": undefined,
88+
// "14c": undefined,
89+
// "15": undefined,
90+
// "15a": undefined,
91+
// "15b": undefined,
92+
// "15c": undefined,
93+
// });
Lines changed: 8 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,19 @@
11
/// <reference path='fourslash.ts' />
22

33
// for readability
4-
////const jsx = (
5-
//// <div style={{ color: 'red' }}>
6-
//// <p>
7-
//// <img />
8-
//// </p>
9-
//// </div>
10-
////);
114

125
// @Filename: /customElements.tsx
13-
//// const jsx = </*1*/fbt/*2*/:en/*3*/um knownProp="accepted"
6+
//// const jsx = <fbt:enum knownProp="accepted"
147
//// unknownProp="rejected">
15-
//// </f/*4*/bt:e/*5*/num>;
8+
//// </fbt:enum>;
169
////
17-
//// const customElement = </*6*/custom/*7*/-element/*8*/></custom/*9*/-element>;
10+
//// const customElement = <custom-element></custom-element>;
1811
////
1912
//// const standardElement =
20-
//// </*10*/Link/*11*/ href="/hello" passHref>
21-
//// </*12*/But/*13*/ton component="a">
13+
//// <Link href="/hello" passHref>
14+
//// <Button component="a">
2215
//// Next
23-
//// </But/*14*/ton>
24-
//// </Li/*15*/nk>;
16+
//// </Button>
17+
//// </Link>;
2518

26-
const wordPattern = "[a-zA-Z0-9:\\-\\._$]*";
27-
28-
const linkedCursors1 = {
29-
ranges: [{ start: test.markerByName("1").position, length: 8 }, { start: test.markerByName("4").position - 1, length: 8 }],
30-
wordPattern,
31-
};
32-
const linkedCursors2 = {
33-
ranges: [{ start: test.markerByName("6").position, length: 14 }, { start: test.markerByName("9").position - 6, length: 14 }],
34-
wordPattern,
35-
};
36-
const linkedCursors3 = {
37-
ranges: [{ start: test.markerByName("10").position, length: 4 }, { start: test.markerByName("15").position - 2, length: 4 }],
38-
wordPattern,
39-
};
40-
const linkedCursors4 = {
41-
ranges: [{ start: test.markerByName("12").position, length: 6 }, { start: test.markerByName("14").position - 3, length: 6 }],
42-
wordPattern,
43-
};
44-
45-
verify.linkedEditing( {
46-
"1": linkedCursors1,
47-
"2": linkedCursors1,
48-
"3": linkedCursors1,
49-
"4": linkedCursors1,
50-
"5": linkedCursors1,
51-
"6": linkedCursors2,
52-
"7": linkedCursors2,
53-
"8": linkedCursors2,
54-
"9": linkedCursors2,
55-
"10": linkedCursors3,
56-
"11": linkedCursors3,
57-
"12": linkedCursors4,
58-
"13": linkedCursors4,
59-
"14": linkedCursors4,
60-
"15": linkedCursors3,
61-
});
19+
verify.baselineLinkedEditing();

0 commit comments

Comments
 (0)