Skip to content

Commit

Permalink
Merge pull request #9 from Microsoft/lint-more
Browse files Browse the repository at this point in the history
Lint more
  • Loading branch information
Andy authored and sandersn committed Nov 29, 2021
1 parent 29a9097 commit f997150
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/dtslint/dtslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"no-redundant-modifiers": true,
"no-single-declare-module": true,
"no-useless-files": true,
"prefer-declare-function": true,
"trim-file": true,
"unified-signatures": true,
"void-return": true,
Expand Down
21 changes: 13 additions & 8 deletions packages/dtslint/src/rules/noRedundantModifiersRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,27 @@ export class Rule extends Lint.Rules.AbstractRule {
if (!sourceFile.isDeclarationFile) {
return [];
}

return this.applyWithFunction(sourceFile, walk);
}
}

function walk(ctx: Lint.WalkContext<void>): void {
for (const node of ctx.sourceFile.statements) {
const { sourceFile } = ctx;
for (const node of sourceFile.statements) {
if (isDeclare(node)) {
if (isExport(node)) {
ctx.addFailureAtNode(node, "'export declare' is redundant, just use 'export'.");
} else {
// Types do not need 'declare'.
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.TypeAliasDeclaration:
ctx.addFailureAtNode(node, "'declare' keyword is redundant here.");
if (ts.isExternalModule(sourceFile)) {
ctx.addFailureAtNode(node, "Prefer 'export' to 'declare' in an external module.");
} else {
// Types do not need 'declare'.
switch (node.kind) {
case ts.SyntaxKind.InterfaceDeclaration:
case ts.SyntaxKind.TypeAliasDeclaration:
ctx.addFailureAtNode(node, "'declare' keyword is redundant here.");
}
}
}
}
Expand All @@ -39,8 +45,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
}
}

function checkModule(s: ts.ModuleDeclaration): void {
const body = s.body;
function checkModule({ body }: ts.ModuleDeclaration): void {
if (!body) {
return;
}
Expand Down
66 changes: 66 additions & 0 deletions packages/dtslint/src/rules/preferDeclareFunctionRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as Lint from "tslint";
import * as ts from "typescript";

export class Rule extends Lint.Rules.AbstractRule {
public static metadata: Lint.IRuleMetadata = {
ruleName: "prefer-declare-function",
description: "Forbids `export const x = () => void`.",
optionsDescription: "Not configurable.",
options: null,
type: "style",
typescriptOnly: true,
};

public static FAILURE_STRING = "Use a function declaration instead of a variable of function type.";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithFunction(sourceFile, walk);
}
}

function walk(ctx: Lint.WalkContext<void>): void {
eachModuleStatement(ctx.sourceFile, (statement) => {
if (isVariableStatement(statement)) {
for (const varDecl of statement.declarationList.declarations) {
if (varDecl.type !== undefined && varDecl.type.kind === ts.SyntaxKind.FunctionType) {
ctx.addFailureAtNode(varDecl, Rule.FAILURE_STRING);
}
}
}
});
}

function isVariableStatement(node: ts.Node): node is ts.VariableStatement {
return node.kind === ts.SyntaxKind.VariableStatement;
}

function eachModuleStatement(sourceFile: ts.SourceFile, action: (statement: ts.Statement) => void): void{
if (!sourceFile.isDeclarationFile) {
return;
}

for (const node of sourceFile.statements) {
if (isModuleDeclaration(node)) {
let { body } = node;
if (!body) {
return;
}

while (body.kind === ts.SyntaxKind.ModuleDeclaration) {
body = body.body;
}

if (body.kind === ts.SyntaxKind.ModuleBlock) {
for (const statement of body.statements) {
action(statement);
}
}
} else {
action(node);
}
}
}

function isModuleDeclaration(node: ts.Node): node is ts.ModuleDeclaration {
return node.kind === ts.SyntaxKind.ModuleDeclaration;
}

0 comments on commit f997150

Please sign in to comment.