Skip to content
This repository was archived by the owner on Jul 16, 2020. It is now read-only.

Commit

Permalink
Add no-empty-interface rule (palantir#1889)
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy authored and adidahiya committed Dec 16, 2016
1 parent 9d29586 commit 4ab7691
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
14 changes: 13 additions & 1 deletion docs/_data/rules.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
{
"ruleName": "cyclomatic-complexity",
"description": "Enforces a threshold of cyclomatic complexity.",
"descriptionDetails": "\nCyclomatic complexity is assessed for each function of any type. A starting value of 1\nis assigned and this value is then incremented for every statement which can branch the\ncontrol flow within the function. The following statements and expressions contribute\nto cyclomatic complexity:\n* `catch`\n* `if` and `? :`\n* `||` and `&&` due to short-circuit evaluation\n* `for`, `for in` and `for of` loops\n* `while` and `do while` loops",
"descriptionDetails": "\nCyclomatic complexity is assessed for each function of any type. A starting value of 20\nis assigned and this value is then incremented for every statement which can branch the\ncontrol flow within the function. The following statements and expressions contribute\nto cyclomatic complexity:\n* `catch`\n* `if` and `? :`\n* `||` and `&&` due to short-circuit evaluation\n* `for`, `for in` and `for of` loops\n* `while` and `do while` loops",
"rationale": "\nCyclomatic complexity is a code metric which indicates the level of complexity in a\nfunction. High cyclomatic complexity indicates confusing code which may be prone to\nerrors or difficult to modify.",
"optionsDescription": "\nAn optional upper limit for cyclomatic complexity can be specified. If no limit option\nis provided a default value of $(Rule.DEFAULT_THRESHOLD) will be used.",
"options": {
Expand Down Expand Up @@ -600,6 +600,18 @@
"type": "functionality",
"typescriptOnly": false
},
{
"ruleName": "no-empty-interface",
"description": "Forbids empty interfaces.",
"rationale": "An empty interface is equivalent to its supertype (or `{}`).",
"optionsDescription": "Not configurable.",
"options": null,
"optionExamples": [
"true"
],
"type": "typescript",
"typescriptOnly": true
},
{
"ruleName": "no-empty",
"description": "Disallows empty blocks.",
Expand Down
2 changes: 1 addition & 1 deletion docs/rules/cyclomatic-complexity/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
description: Enforces a threshold of cyclomatic complexity.
descriptionDetails: |-

Cyclomatic complexity is assessed for each function of any type. A starting value of 1
Cyclomatic complexity is assessed for each function of any type. A starting value of 20
is assigned and this value is then incremented for every statement which can branch the
control flow within the function. The following statements and expressions contribute
to cyclomatic complexity:
Expand Down
14 changes: 14 additions & 0 deletions docs/rules/no-empty-interface/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
ruleName: no-empty-interface
description: Forbids empty interfaces.
rationale: 'An empty interface is equivalent to its supertype (or `{}`).'
optionsDescription: Not configurable.
options: null
optionExamples:
- 'true'
type: typescript
typescriptOnly: true
layout: rule
title: 'Rule: no-empty-interface'
optionsJSON: 'null'
---
51 changes: 51 additions & 0 deletions src/rules/noEmptyInterfaceRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* @license
* Copyright 2013 Palantir Technologies, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as ts from "typescript";

import * as Lint from "../index";

export class Rule extends Lint.Rules.AbstractRule {
/* tslint:disable:object-literal-sort-keys */
public static metadata: Lint.IRuleMetadata = {
ruleName: "no-empty-interface",
description: "Forbids empty interfaces.",
rationale: "An empty interface is equivalent to its supertype (or `{}`).",
optionsDescription: "Not configurable.",
options: null,
optionExamples: ["true"],
type: "typescript",
typescriptOnly: true,
};
/* tslint:enable:object-literal-sort-keys */

public static FAILURE_STRING = "An empty interface is equivalent to `{}`.";
public static FAILURE_STRING_FOR_EXTENDS = "An interface declaring no members is equivalent to its supertype.";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
}
}

class Walker extends Lint.RuleWalker {
public visitInterfaceDeclaration(node: ts.InterfaceDeclaration) {
if (node.members.length === 0) {
this.addFailureAtNode(node.name, node.heritageClauses ? Rule.FAILURE_STRING_FOR_EXTENDS : Rule.FAILURE_STRING);
}
super.visitInterfaceDeclaration(node);
}
}
7 changes: 7 additions & 0 deletions test/rules/no-empty-interface/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
interface I { }
~ [An empty interface is equivalent to `{}`.]

interface J extends I { }
~ [An interface declaring no members is equivalent to its supertype.]

interface K { x: number; }
5 changes: 5 additions & 0 deletions test/rules/no-empty-interface/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"no-empty-interface": true
}
}

0 comments on commit 4ab7691

Please sign in to comment.