Skip to content

Commit 0068d62

Browse files
Replace Array.sort and Array.reverse with Array.toSorted and Array.toReversed (#3271)
Still keeps .sort and .reverse in performance critical areas
1 parent 95bc3fd commit 0068d62

32 files changed

Lines changed: 89 additions & 88 deletions

oxlint.config.mts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import type { OxlintConfig } from "oxlint";
22
import { defineConfig } from "oxlint";
33

4-
// These rules should probably be re-enabled eventually
5-
const temporarilyDisabledRules = [
6-
// Requires es2023
7-
"unicorn/no-array-sort",
8-
"unicorn/no-array-reverse",
9-
];
10-
114
const disabledRules = [
12-
...temporarilyDisabledRules,
135
"eslint/arrow-body-style",
146
"eslint/capitalized-comments",
157
"eslint/class-methods-use-this",

packages/app-vscode/src/ScopeTreeProvider.ts

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ export class ScopeTreeProvider implements TreeDataProvider<MyTreeItem> {
182182
};
183183
})();
184184

185-
return this.supportLevels
185+
const supportLevels = this.supportLevels
186186
.filter(
187187
(supportLevel) =>
188188
supportLevel.support === scopeSupport &&
@@ -201,26 +201,11 @@ export class ScopeTreeProvider implements TreeDataProvider<MyTreeItem> {
201201
isEqual(supportLevel.scopeType, this.scopeVisualizer.scopeType),
202202
getContainmentIcon?.(supportLevel.scopeType),
203203
),
204-
)
205-
.sort((a, b) => {
206-
if (
207-
a.scopeTypeInfo.spokenForm.type !== b.scopeTypeInfo.spokenForm.type
208-
) {
209-
// Scopes with no spoken form are sorted to the bottom
210-
return a.scopeTypeInfo.spokenForm.type === "error" ? 1 : -1;
211-
}
204+
);
212205

213-
if (
214-
a.scopeTypeInfo.isLanguageSpecific !==
215-
b.scopeTypeInfo.isLanguageSpecific
216-
) {
217-
// Then language-specific scopes are sorted to the top
218-
return a.scopeTypeInfo.isLanguageSpecific ? -1 : 1;
219-
}
206+
supportLevels.sort(compareScopeTypes);
220207

221-
// Then alphabetical by label
222-
return a.label.label.localeCompare(b.label.label);
223-
});
208+
return supportLevels;
224209
}
225210

226211
private getContainmentIcon(
@@ -255,6 +240,26 @@ export class ScopeTreeProvider implements TreeDataProvider<MyTreeItem> {
255240
}
256241
}
257242

243+
function compareScopeTypes(
244+
a: ScopeSupportTreeItem,
245+
b: ScopeSupportTreeItem,
246+
): number {
247+
if (a.scopeTypeInfo.spokenForm.type !== b.scopeTypeInfo.spokenForm.type) {
248+
// Scopes with no spoken form are sorted to the bottom
249+
return a.scopeTypeInfo.spokenForm.type === "error" ? 1 : -1;
250+
}
251+
252+
if (
253+
a.scopeTypeInfo.isLanguageSpecific !== b.scopeTypeInfo.isLanguageSpecific
254+
) {
255+
// Then language-specific scopes are sorted to the top
256+
return a.scopeTypeInfo.isLanguageSpecific ? -1 : 1;
257+
}
258+
259+
// Then alphabetical by label
260+
return a.label.label.localeCompare(b.label.label);
261+
}
262+
258263
function getSupportCategories(): SupportCategoryTreeItem[] {
259264
return [
260265
new SupportCategoryTreeItem(ScopeSupport.supportedAndPresentInEditor),

packages/app-vscode/src/keyboard/KeyboardCommandsModal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export class KeyboardCommandsModal {
9090
const acceptableTokenTypeInfos = getAcceptableTokenTypes(this.parser);
9191
// FIXME: Here's where we'd update sidebar
9292
const acceptableTokenTypes = sortedUniq(
93-
acceptableTokenTypeInfos.map(({ type }) => type).sort(),
93+
acceptableTokenTypeInfos.map(({ type }) => type).toSorted(),
9494
);
9595
let layer = this.layerCache.get(acceptableTokenTypes);
9696
if (layer == null) {

packages/app-vscode/src/keyboard/KeyboardHandler.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,9 @@ export class KeyboardHandler {
152152
// one. Eg if you're in the middle of typing a command and we turn off
153153
// the modal mode, we want to cancel the command
154154
if (index !== -1) {
155-
const listenersToCancel = this.listeners.slice(index + 1).reverse();
155+
const listenersToCancel = this.listeners
156+
.slice(index + 1)
157+
.toReversed();
156158
for (const entry of listenersToCancel) {
157159
entry.listener.handleCancelled();
158160
}

packages/app-vscode/src/keyboard/buildSuffixTrie.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ suite("buildSuffixTrie", () => {
125125
const { trie, conflicts } = buildSuffixTrie<string>(
126126
input.map((key) => [key, key]),
127127
);
128-
const chars = uniq(input.flatMap((key) => key.split(""))).sort();
128+
const chars = uniq(input.flatMap((key) => key.split(""))).toSorted();
129129
const actual = uniqWith(
130130
sortEntries(chars.flatMap((char) => trie.search(char))),
131131
isEqual,

packages/app-vscode/src/keyboard/grammar/getAcceptableTokenTypes.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ const testCases: TestCase[] = [
133133

134134
suite("keyboard.getAcceptableTokenTypes", () => {
135135
let parser: nearley.Parser;
136+
136137
setup(() => {
137138
parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
138139
});

packages/app-vscode/src/keyboard/grammar/grammar.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ const testCases: TestCase[] = [
180180

181181
suite("keyboard grammar", () => {
182182
let parser: nearley.Parser;
183+
183184
setup(() => {
184185
parser = new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
185186
});

packages/app-web-docs/src/docs/components/ScopeVisualizer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ function getScopeFixtures(
315315
}
316316

317317
const result: Scopes = { public: [], internal: [] };
318-
const sortedScopes = Object.values(scopeMap).sort(nameComparator);
318+
const sortedScopes = Object.values(scopeMap).toSorted(nameComparator);
319319

320320
for (const scope of sortedScopes) {
321321
scope.facets.sort(facetComparator);

packages/app-web-docs/src/docs/components/flattenHighlights.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ function getUniquePositions(highlights: Highlight[]): Position[] {
5353
const result: Position[] = [];
5454
const positions = highlights
5555
.flatMap((h) => [h.range.start, h.range.end])
56-
.sort((a, b) =>
56+
.toSorted((a, b) =>
5757
a.line === b.line ? a.character - b.character : a.line - b.line,
5858
);
5959
for (let i = 0; i < positions.length; i++) {

packages/app-web-docs/src/docs/contributing/MissingLanguageScopes.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010

1111
export function MissingLanguageScopes(): React.JSX.Element {
1212
const [showPrivate, setShowPrivate] = useState(false);
13-
const languageIds = Object.keys(languageScopeSupport).sort();
13+
const languageIds = Object.keys(languageScopeSupport).toSorted();
1414

1515
return (
1616
<>
@@ -48,10 +48,10 @@ function Language({
4848
.filter(
4949
(facet) => scopeSupport[facet] === ScopeSupportFacetLevel.unsupported,
5050
)
51-
.sort();
51+
.toSorted();
5252
let unspecifiedFacets = scopeSupportFacets
5353
.filter((facet) => scopeSupport[facet] == null)
54-
.sort();
54+
.toSorted();
5555

5656
if (!showPrivate) {
5757
unsupportedFacets = unsupportedFacets.filter((f) => !isPrivate(f));

0 commit comments

Comments
 (0)