@ui5/linter
Version:
A static code analysis tool for UI5
94 lines • 3.3 kB
JavaScript
import ts from "typescript";
export function matchPropertyAccessExpression(node, match) {
const propAccessChain = [];
propAccessChain.push(node.expression.getText());
let scanNode = node;
while (ts.isPropertyAccessExpression(scanNode)) {
propAccessChain.push(scanNode.name.getText());
scanNode = scanNode.parent;
}
return propAccessChain.join(".") === match;
}
export function collectIdentifierDeclarations(node) {
const declaredIdentifiers = new Set();
const extractDestructIdentifiers = (name, identifiers) => {
if (ts.isIdentifier(name)) {
identifiers.add(name.text);
}
else if (ts.isObjectBindingPattern(name) || ts.isArrayBindingPattern(name)) {
for (const element of name.elements) {
if (ts.isBindingElement(element)) {
extractDestructIdentifiers(element.name, identifiers);
}
}
}
};
const collectIdentifiers = (node) => {
if (ts.isVariableDeclaration(node) ||
ts.isFunctionDeclaration(node) ||
ts.isClassDeclaration(node)) {
if (node.name && ts.isIdentifier(node.name)) {
declaredIdentifiers.add(node.name.text);
}
}
if (ts.isParameter(node) || ts.isVariableDeclaration(node)) {
extractDestructIdentifiers(node.name, declaredIdentifiers);
}
ts.forEachChild(node, collectIdentifiers);
};
ts.forEachChild(node, collectIdentifiers);
return declaredIdentifiers;
}
export function collectIdentifiers(node) {
const identifiers = new Set();
const collect = (node) => {
if (ts.isIdentifier(node)) {
identifiers.add(node);
}
ts.forEachChild(node, collect);
};
ts.forEachChild(node, collect);
return identifiers;
}
export function removeConflictingFixes(fixes) {
const fixRanges = [];
for (const fix of fixes) {
if (!fix.getAffectedSourceCodeRange) {
continue;
}
const ranges = fix.getAffectedSourceCodeRange();
if (Array.isArray(ranges)) {
for (const range of ranges) {
fixRanges.push({
start: range.start,
end: range.end,
fix: fix,
});
}
}
else if (ranges) {
const { start, end } = ranges;
fixRanges.push({
start,
end,
fix: fix,
});
}
}
if (fixRanges.length === 0)
return;
// Sort fixRanges by start position; if start is the same, sort by end position (larger first)
// This ultimately prioritizes larger fixes over smaller ones
// Sometimes there are multiple fixes or a call expression chain which can each cover the same range
fixRanges.sort((a, b) => a.start - b.start || b.end - a.end);
let currentEnd = fixRanges[0].end;
for (let i = 1; i < fixRanges.length; i++) {
const fixRange = fixRanges[i];
if (fixRange.start < currentEnd) {
// Conflict
fixes.delete(fixRange.fix);
}
currentEnd = Math.max(currentEnd, fixRange.end);
}
}
//# sourceMappingURL=utils.js.map