Skip to content

Commit a360d9f

Browse files
TypeScript BotiisaduanDanielRosenwasser
authored
🤖 Pick PR #54315 (add baseline for linked editing) into release-5.1 (#54419)
Co-authored-by: Isabel Duan <[email protected]> Co-authored-by: Daniel Rosenwasser <[email protected]>
1 parent c8da9d5 commit a360d9f

7 files changed

+206
-90
lines changed

Diff for: ‎src/harness/fourslashImpl.ts

+67
Original file line numberDiff line numberDiff line change
@@ -3576,6 +3576,73 @@ export class TestState {
35763576
}
35773577
}
35783578

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

Diff for: ‎src/harness/fourslashInterfaceImpl.ts

+4
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
}
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+
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+

Diff for: ‎tests/cases/fourslash/fourslash.ts

+1
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,

Diff for: ‎tests/cases/fourslash/linkedEditingJsxTag10.ts

+2-40
Original file line numberDiff line numberDiff line change
@@ -48,43 +48,5 @@
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+

Diff for: ‎tests/cases/fourslash/linkedEditingJsxTag11.ts

+8-50
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)