How to use the @fimbul/ymir.Replacement.append function in @fimbul/ymir

To help you get started, we’ve selected a few @fimbul/ymir examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github fimbullinter / wotan / packages / mimir / src / rules / prefer-object-spread.ts View on Github external
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;
            }
            // remove empty object iteral and the following comma if exists
            fix.push(Replacement.delete(removedPrevious ? arg.getStart(sourceFile) : arg.pos, end));
            removedPrevious = true;
        } else {
            const start = arg.getStart(sourceFile);
            fix.push(
github fimbullinter / wotan / packages / mimir / src / rules / type-assertion.ts View on Github external
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, ')')}`,
                ),
            ]);
        }
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / try-catch-return-await.ts View on Github external
private checkReturnExpression(node: ts.Expression) {
        const {pos} = node;
        while (isParenthesizedExpression(node))
            node = node.expression;
        if (node.kind === ts.SyntaxKind.AwaitExpression)
            return;
        if (isThenableType(this.checker, node))
            this.addFinding(
                pos - 'return'.length,
                pos,
                "Missing 'await' of Promise returned inside try-catch.",
                needsParens(node)
                    ? [
                        Replacement.append(pos, ' await'),
                        Replacement.append(node.getStart(this.sourceFile), '('),
                        Replacement.append(node.end, ')'),
                    ]
                    : Replacement.append(pos, ' await'),
            );
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / await-only-promise.ts View on Github external
public apply() {
        const re = /\bawait\b/g;
        let wrappedAst: WrappedAst | undefined;
        for (let match = re.exec(this.sourceFile.text); match !== null; match = re.exec(this.sourceFile.text)) {
            const {node} = getWrappedNodeAtPosition(wrappedAst || (wrappedAst = this.context.getWrappedAst()), match.index)!;
            if (isAwaitExpression(node)) {
                if (
                    node.expression.pos !== re.lastIndex ||
                    this.maybePromiseLike(this.checker.getTypeAtLocation(node.expression)!, node.expression)
                )
                    continue;
                const fix = [Replacement.delete(match.index, node.expression.getStart(this.sourceFile))];
                if (expressionNeedsParensWhenReplacingNode(node.expression, node))
                    fix.push(
                        Replacement.append(match.index, '('),
                        Replacement.append(node.expression.end, ')'),
                    );
                this.addFinding(
                    match.index,
                    node.end,
                    "Unnecessary 'await' of a non-Promise value.",
                    fix,
                );
            } else if (node.kind === ts.SyntaxKind.AwaitKeyword && node.end === re.lastIndex) {
                const parent = node.parent!;
                if (isForOfStatement(parent) && !this.isAsyncIterable(parent.expression)) {
                    const start = node.pos - 'for'.length;
                    this.addFinding(
                        start,
                        parent.statement.pos,
                        "Unnecessary 'for await' of a non-AsyncIterable value.",
                        Replacement.delete(start + 'for'.length, re.lastIndex),
github fimbullinter / wotan / packages / mimir / src / rules / try-catch-return-await.ts View on Github external
private checkReturnExpression(node: ts.Expression) {
        const {pos} = node;
        while (isParenthesizedExpression(node))
            node = node.expression;
        if (node.kind === ts.SyntaxKind.AwaitExpression)
            return;
        if (isThenableType(this.checker, node))
            this.addFinding(
                pos - 'return'.length,
                pos,
                "Missing 'await' of Promise returned inside try-catch.",
                needsParens(node)
                    ? [
                        Replacement.append(pos, ' await'),
                        Replacement.append(node.getStart(this.sourceFile), '('),
                        Replacement.append(node.end, ')'),
                    ]
                    : Replacement.append(pos, ' await'),
            );
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / trailing-newline.ts View on Github external
public apply() {
        const sourceFile = this.sourceFile;
        const end = sourceFile.end;
        if (end === 0 || end === 1 && sourceFile.text[0] === '\uFEFF' || sourceFile.text[end - 1] === '\n')
            return;
        const lines = sourceFile.getLineStarts();
        this.addFinding(
            end,
            end,
            'File must end with a newline.',
            Replacement.append(end, lines.length === 0 || sourceFile.text[lines[1] - 2] !== '\r' ? '\n' : '\r\n'),
        );
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / try-catch-return-await.ts View on Github external
private checkReturnExpression(node: ts.Expression) {
        const {pos} = node;
        while (isParenthesizedExpression(node))
            node = node.expression;
        if (node.kind === ts.SyntaxKind.AwaitExpression)
            return;
        if (isThenableType(this.checker, node))
            this.addFinding(
                pos - 'return'.length,
                pos,
                "Missing 'await' of Promise returned inside try-catch.",
                needsParens(node)
                    ? [
                        Replacement.append(pos, ' await'),
                        Replacement.append(node.getStart(this.sourceFile), '('),
                        Replacement.append(node.end, ')'),
                    ]
                    : Replacement.append(pos, ' await'),
            );
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / prefer-exponentiation-operator.ts View on Github external
)) {
                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, ')'),
                );
            if (expressionNeedsParens(fixed.right))
                fix.push(
                    Replacement.append(grandparent.arguments[1].getStart(this.sourceFile), '('),
                    Replacement.append(grandparent.arguments[1].end, ')'),
                );

            this.addFailureAtNode(
                grandparent,
                "Prefer the exponentiation operator '**' over 'Math.pow'.",
                fix,
            );
        }
    }
}
github fimbullinter / wotan / packages / mimir / src / rules / type-assertion.ts View on Github external
function enforceClassicTypeAssertion(context: RuleContext) {
    const re = /\bas\b/g;
    let wrappedAst: WrappedAst | undefined;
    for (let match = re.exec(context.sourceFile.text); match !== null; match = re.exec(context.sourceFile.text)) {
        const {node} = getWrappedNodeAtPosition(wrappedAst || (wrappedAst = context.getWrappedAst()), match.index)!;
        if (!isAsExpression(node) || node.type.pos !== re.lastIndex)
            continue;
        const parent = node.parent!;
        const expressionNeedsParens = node.expression.kind === ts.SyntaxKind.BinaryExpression;
        const needsParens = isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.AsteriskAsteriskToken;
        context.addFinding(match.index, node.end, "Use the classic type assertion style 'obj' instead.", [
            Replacement.append(
                node.getStart(context.sourceFile),
                `${charIf(needsParens, '(')}<${node.type.getText(context.sourceFile)}>${charIf(expressionNeedsParens, '(')}`,
            ),
            Replacement.replace(node.expression.end, node.end, charIf(expressionNeedsParens, ')') + charIf(needsParens, ')')),
        ]);
    }
}