sortier
Version:
An opinionated code sorter
71 lines (70 loc) • 3.08 kB
JavaScript
import { compare, getContextGroups, reorderValues } from "../../utilities/sort-utils.js";
import { getObjectTypeRanks, getSpreadGroups } from "../utilities/sort-utils.js";
export function sortTSPropertySignatures(properties, comments, fileContents, options) {
let newFileContents = fileContents.slice();
const allNodes = cleanProperties(fileContents, properties);
// Any time there is a spread operator, we need to sort around it... moving it could cause functionality changes
const spreadGroups = getSpreadGroups(allNodes);
for (const nodes of spreadGroups) {
const contextGroups = getContextGroups(nodes, comments, fileContents);
contextGroups.forEach((element) => {
const unsorted = element.nodes;
const sorted = element.nodes.slice().sort((a, b) => {
const aGroup = getSortGroupIndex(a, options);
const bGroup = getSortGroupIndex(b, options);
if (aGroup !== bGroup) {
return aGroup - bGroup;
}
// Certain types should not be sorted against one another
// so for these situations, we use their start index to make
// sure we maintain their order
if (a.type === b.type && a.type === "TSCallSignatureDeclaration") {
return a.range[0] - b.range[0];
}
const aString = getString(a, fileContents);
const bString = getString(b, fileContents);
return compare(aString, bString);
});
newFileContents = reorderValues(newFileContents, element.comments, unsorted, sorted);
});
}
return newFileContents;
}
function cleanProperties(fileContents, properties) {
// Interface properties are read in as "property: number," where we don't want to move the commas
return properties.map((property) => {
let lastIndex = property.range[1];
const lastCharacter = fileContents[lastIndex - 1];
if (0 < lastIndex && (lastCharacter === "," || lastCharacter === ";")) {
lastIndex--;
}
return {
...property,
range: [property.range[0], lastIndex],
};
});
}
function getString(property, fileContents) {
if (property.key != null) {
if (property.key.value != null) {
return property.key.value;
}
if (property.key.name != null) {
return property.key.name;
}
}
return fileContents.substring(property.range[0], property.range[1]);
}
function getSortGroupIndex(property, options) {
const ranks = getObjectTypeRanks(options.groups);
const annotationType = property.typeAnnotation?.typeAnnotation?.type;
if (property.type === "TSCallSignatureDeclaration" ||
property.type === "TSMethodSignature" ||
annotationType === "TSFunctionType") {
return ranks.function;
}
else if (annotationType === "TSTypeLiteral") {
return ranks.object;
}
return ranks.everything;
}