Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Added fixer for newline-before-return rule #4482

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 3 additions & 21 deletions src/rules/curlyRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { isBlock, isIfStatement, isIterationStatement, isSameLine } from "tsutil
import * as ts from "typescript";

import * as Lint from "../index";
import { newLineWithIndentation } from "../utils";

import { codeExamples } from "./code-examples/curly.examples";

Expand Down Expand Up @@ -172,29 +173,10 @@ class CurlyWalker extends Lint.AbstractWalker<Options> {
Lint.Replacement.appendText(statement.end, " }"),
];
} else {
const match = /\n([\t ])/.exec(node.getFullText(this.sourceFile)); // determine which character to use (tab or space)
const indentation =
match === null
? ""
: // indentation should match start of statement
match[1].repeat(
ts.getLineAndCharacterOfPosition(
this.sourceFile,
node.getStart(this.sourceFile),
).character,
);

const maybeCarriageReturn =
this.sourceFile.text[this.sourceFile.getLineEndOfPosition(node.pos) - 1] === "\r"
? "\r"
: "";

const newLine = newLineWithIndentation(node, this.sourceFile);
return [
Lint.Replacement.appendText(statement.pos, " {"),
Lint.Replacement.appendText(
statement.end,
`${maybeCarriageReturn}\n${indentation}}`,
),
Lint.Replacement.appendText(statement.end, `${newLine}}`),
];
}
}
Expand Down
13 changes: 11 additions & 2 deletions src/rules/newlineBeforeReturnRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import { getPreviousStatement } from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
import { newLineWithIndentation } from "../utils";

export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "newline-before-return",
description: "Enforces blank line before return when not the only line in the block.",
rationale: "Helps maintain a readable style in your codebase.",
hasFix: true,
optionsDescription: "Not configurable.",
options: {},
optionExamples: [true],
Expand Down Expand Up @@ -78,10 +80,17 @@ class NewlineBeforeReturnWalker extends Lint.AbstractWalker<void> {
}
}
const prevLine = ts.getLineAndCharacterOfPosition(this.sourceFile, prev.end).line;

if (prevLine >= line - 1) {
const fixer = Lint.Replacement.replaceFromTo(
line === prevLine ? node.pos : node.pos + 1,
start,
line === prevLine
? newLineWithIndentation(prev, this.sourceFile, 2)
: newLineWithIndentation(prev, this.sourceFile),
);

// Previous statement is on the same or previous line
this.addFailure(start, start, Rule.FAILURE_STRING);
this.addFailure(start, start, Rule.FAILURE_STRING, fixer);
}
}
}
25 changes: 25 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,31 @@ function tryResolveSync(packageName: string, relativeTo?: string): string | unde
}
}

/**
* Gets the full indentation of the provided node
*/
export function getIndentation(node: ts.Node, sourceFile: ts.SourceFile): string {
const text = sourceFile.text.substr(node.pos, node.getStart() - node.pos);
const matches = text.match(/([ \t]*)$/);
return matches !== null ? matches[1] : "";
}

/**
* Creates x new lines with a proper indentation at the last one based on the provided node
*/
export function newLineWithIndentation(
node: ts.Node,
sourceFile: ts.SourceFile,
linesCount: number = 1,
) {
const maybeCarriageReturn =
sourceFile.text[sourceFile.getLineEndOfPosition(node.pos) - 1] === "\r" ? "\r" : "";

const indentation = getIndentation(node, sourceFile);

return `${`${maybeCarriageReturn}\n`.repeat(linesCount)}${indentation}`;
}

/**
* @deprecated Copied from tsutils 2.27.2. This will be removed once TSLint requires tsutils > 3.0.
*/
Expand Down
126 changes: 126 additions & 0 deletions test/rules/newline-before-return/default/test.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
function foo(bar) {
if (!bar) {
return;
}

return bar;
}

function foo(bar) {
if (!bar) {
var statement = '';

return statement;
}

return bar;
}

function foo(bar) {
if (!bar) {
return;
}

/* multi-line
comment */
return bar;
}

var fn = () => null;
function foo() {
fn();

return;
}

function foo(fn) {
fn();

return;
}

function foo(fn) {
fn();

return;
}

function foo(fn) {
fn();

return;
}

function foo() {
return;
}

function foo() {

return;
}

function foo(bar) {
if (!bar) return;
}

function foo(bar) {
let someCall;
if (!bar) return;
}

function foo(bar) {
if (!bar) { return };
}

function foo(bar) {
if (!bar) {
return;
}
}

function foo(bar) {
if (!bar) {
return;
}

return bar;
}

function foo(bar) {
if (!bar) {

return;
}
}

function foo() {

// comment
return;
}

function test() {
console.log("Any statement");
// Any comment

return;
}

function foo() {
fn();
// comment

// comment
return;
}

function bar() {
"some statement";

//comment
//comment
//comment
return;
}

10 changes: 10 additions & 0 deletions test/rules/newline-before-return/default/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ function foo(fn) {
~nil [0]
}

function foo(fn) {
fn(); return;
~nil [0]
}

function foo(fn) {
fn(); return;
~nil [0]
}

function foo() {
return;
}
Expand Down
17 changes: 17 additions & 0 deletions test/rules/newline-before-return/default/test.tsx.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as React from 'react';

<div>{ [].map((child: any) => {
let i = 0;

return <span />;
}) }</div>

<div>{ [].map((child: any) => {
return <span />;
}) }</div>

<div>{ [].map((child: any) =>
<span />;
) }</div>