Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
public apply() {
for (const node of this.context.getFlatAst()) {
if (isElementAccessExpression(node) &&
// for compatiblity with typescript@<2.9.0
node.argumentExpression !== undefined && // wotan-disable-line no-useless-predicate
isTextualLiteral(node.argumentExpression) && isValidPropertyAccess(node.argumentExpression.text)) {
const property = node.argumentExpression.text;
this.addFailureAtNode(
node.argumentExpression,
`Prefer 'obj.${property}' over 'obj[${node.argumentExpression.getText(this.sourceFile)}]'.`,
Replacement.replace(node.expression.end, node.end, '.' + property),
);
}
}
}
}
for (let match = re.exec(this.sourceFile.text); match !== null; match = re.exec(this.sourceFile.text)) {
if (match[1].length & 1) // only check if backslash is not escaped
continue;
const {node} = getWrappedNodeAtPosition(wrappedAst || (wrappedAst = this.context.getWrappedAst()), match.index)!;
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
case ts.SyntaxKind.TemplateHead:
case ts.SyntaxKind.TemplateMiddle:
case ts.SyntaxKind.TemplateTail:
if (match.index >= node.getStart(this.sourceFile))
this.addFinding(
match.index + match[1].length,
re.lastIndex,
'Octal escape sequences are deprecated and not allowed in strict mode.',
Replacement.replace(
match.index + match[1].length + 1,
re.lastIndex,
`x${toHexSequence(parseInt(match[0].substr(match[1].length + 1), 8))}`,
),
);
}
}
}
}
function enforceAsTypeAssertion(context: RuleContext) {
for (const node of context.getFlatAst()) {
if (isTypeAssertion(node)) {
const assertionParens = assertionNeedsParens(node);
const expressionParens = node.expression.kind === ts.SyntaxKind.YieldExpression ||
!assertionParens && expressionNeedsParensWhenReplacingNode(node.expression, node);
const start = node.getStart(context.sourceFile);
context.addFinding(start, node.expression.pos, "Use 'obj as T' instead.", [
Replacement.replace(
start,
node.expression.getStart(context.sourceFile),
charIf(expressionParens, '(') + charIf(assertionParens, '('),
),
Replacement.append(
node.end,
`${charIf(expressionParens, ')')} as ${node.type.getText(context.sourceFile)}${charIf(assertionParens, ')')}`,
),
]);
}
}
}
function deleteStatement(node: ts.TryStatement) {
return isInSingleStatementContext(node)
? Replacement.replace(getStart(node), node.end, '{}')
: Replacement.delete(node.pos, node.end);
}
if (!isPropertyAccessExpression(parent) || !isIdentifier(parent.expression) || parent.expression.text !== 'Math')
continue;
const grandparent = parent.parent!;
if (
!isCallExpression(grandparent) ||
grandparent.expression !== parent ||
grandparent.arguments.length !== 2 ||
grandparent.arguments.some(isSpreadElement)
)
continue;
const fixed = ts.createBinary(
ts.getMutableClone(grandparent.arguments[0]),
ts.SyntaxKind.AsteriskAsteriskToken,
ts.getMutableClone(grandparent.arguments[1]),
);
const fix = [Replacement.replace(grandparent.arguments[1].pos - 1, grandparent.arguments[1].pos, '**')];
fixed.left.parent = fixed.right.parent = fixed;
if (expressionNeedsParensWhenReplacingNode(
fixed,
grandparent,
)) {
fix.push(Replacement.delete(grandparent.getStart(this.sourceFile), grandparent.arguments[0].pos - 1));
} else {
fix.push(
Replacement.delete(grandparent.getStart(this.sourceFile), grandparent.arguments[0].getStart(this.sourceFile)),
Replacement.delete(grandparent.end - 1, grandparent.end),
);
}
if (expressionNeedsParens(fixed.left))
fix.push(
Replacement.append(grandparent.arguments[0].getStart(this.sourceFile), '('),
Replacement.append(grandparent.arguments[0].end, ')'),
function createFix(node: ts.CallExpression, sourceFile: ts.SourceFile) {
const args = node.arguments;
const objectNeedsParens = objectLiteralNeedsParens(node);
const fix = [
Replacement.replace(node.getStart(sourceFile), args[0].getStart(sourceFile), `${objectNeedsParens ? '(' : ''}{`),
Replacement.replace(node.end - 1, node.end, `}${objectNeedsParens ? ')' : ''}`),
];
let removedPrevious = false;
for (let i = 0; i < args.length; ++i) {
const arg = args[i];
if (!isObjectLiteralExpression(arg)) {
fix.push(Replacement.append(arg.getStart(sourceFile), '...'));
removedPrevious = false;
continue;
}
if (arg.properties.length === 0) {
let end = arg.end;
if (i !== args.length - 1) {
end = args[i + 1].getStart(sourceFile);
} else if (args.hasTrailingComma) {
end = args.end;
fileName = fileName.substring(0, fileName.length - path.extname(fileName).length);
const importsFromFile = map.get(fileName);
if (importsFromFile === undefined) {
map.set(fileName, [binding.getText()]);
} else {
importsFromFile.push(binding.getText());
}
}
if (map.size === 1) {
fix = Replacement.replace(
moduleSpecifier.getStart() + 1,
moduleSpecifier.end - 1,
map.keys().next().value,
);
} else {
fix = Replacement.replace(
declaration.getStart(),
declaration.end,
Array.from(map, toImportStatement).join('\n'),
);
}
}
return fix;
}
function createFix(node: ts.CallExpression, sourceFile: ts.SourceFile) {
const args = node.arguments;
const objectNeedsParens = objectLiteralNeedsParens(node);
const fix = [
Replacement.replace(node.getStart(sourceFile), args[0].getStart(sourceFile), `${objectNeedsParens ? '(' : ''}{`),
Replacement.replace(node.end - 1, node.end, `}${objectNeedsParens ? ')' : ''}`),
];
let removedPrevious = false;
for (let i = 0; i < args.length; ++i) {
const arg = args[i];
if (!isObjectLiteralExpression(arg)) {
fix.push(Replacement.append(arg.getStart(sourceFile), '...'));
removedPrevious = false;
continue;
}
if (arg.properties.length === 0) {
let end = arg.end;
if (i !== args.length - 1) {
end = args[i + 1].getStart(sourceFile);
} else if (args.hasTrailingComma) {
end = args.end;
}