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

Lint for strict-boolean-expressions #2408

Merged
merged 4 commits into from
May 9, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"compile:scripts": "tsc -p scripts",
"compile:test": "tsc -p test",
"lint": "npm-run-all -p lint:global lint:from-bin",
"lint:global": "tslint --project test/tsconfig.json --format stylish # test includes 'src' too",
"lint:from-bin": "node bin/tslint --project test/tsconfig.json --format stylish",
"lint:global": "tslint --project test/tsconfig.json --type-check --format stylish # test includes 'src' too",
"lint:from-bin": "node bin/tslint --project test/tsconfig.json --type-check --format stylish",
"test": "npm-run-all test:pre -p test:mocha test:rules",
"test:pre": "cd ./test/config && npm install",
"test:mocha": "mocha --reporter spec --colors \"build/test/**/*Tests.js\" build/test/assert.js",
Expand Down
24 changes: 12 additions & 12 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ function resolveConfigurationPath(filePath: string, relativeTo?: string) {
}
}

const basedir = relativeTo || process.cwd();
const basedir = relativeTo !== undefined ? relativeTo : process.cwd();
try {
return resolve.sync(filePath, { basedir });
} catch (err) {
Expand Down Expand Up @@ -244,7 +244,7 @@ function getHomeDir() {
// returns the absolute path (contrary to what the name implies)
export function getRelativePath(directory?: string | null, relativeTo?: string) {
if (directory != null) {
const basePath = relativeTo || process.cwd();
const basePath = relativeTo !== undefined ? relativeTo : process.cwd();
return path.resolve(basePath, directory);
}
return undefined;
Expand Down Expand Up @@ -291,7 +291,7 @@ function parseRuleOptions(ruleConfigValue: any): Partial<IOptions> {
// old style: boolean
ruleArguments = [];
ruleSeverity = ruleConfigValue === true ? "error" : "off";
} else if (ruleConfigValue.severity) {
} else if (ruleConfigValue.severity !== undefined) {
switch (ruleConfigValue.severity.toLowerCase()) {
case "warn":
case "warning":
Expand All @@ -309,7 +309,7 @@ function parseRuleOptions(ruleConfigValue: any): Partial<IOptions> {
ruleSeverity = "off";
}

if (ruleConfigValue && ruleConfigValue.options) {
if (ruleConfigValue != null && ruleConfigValue.options != null) {
ruleArguments = arrayify(ruleConfigValue.options);
}

Expand All @@ -329,17 +329,17 @@ export function parseConfigFile(configFile: any, configFileDir?: string): IConfi
const rules = new Map<string, Partial<IOptions>>();
const jsRules = new Map<string, Partial<IOptions>>();

if (configFile.rules) {
if (configFile.rules != null) {
for (const ruleName in configFile.rules) {
if (configFile.rules.hasOwnProperty(ruleName)) {
if (Object.prototype.hasOwnProperty.call(configFile.rules, ruleName) as boolean) {
rules.set(ruleName, parseRuleOptions(configFile.rules[ruleName]));
}
}
}

if (configFile.jsRules) {
if (configFile.jsRules != null) {
for (const ruleName in configFile.jsRules) {
if (configFile.jsRules.hasOwnProperty(ruleName)) {
if (Object.prototype.hasOwnProperty.call(configFile.jsRules, ruleName) as boolean) {
jsRules.set(ruleName, parseRuleOptions(configFile.jsRules[ruleName]));
}
}
Expand All @@ -348,7 +348,7 @@ export function parseConfigFile(configFile: any, configFileDir?: string): IConfi
return {
extends: arrayify(configFile.extends),
jsRules,
linterOptions: configFile.linterOptions || {},
linterOptions: configFile.linterOptions != null ? configFile.linterOptions : {},
rulesDirectory: getRulesDirectories(configFile.rulesDirectory, configFileDir),
rules,
};
Expand All @@ -359,12 +359,12 @@ export function parseConfigFile(configFile: any, configFileDir?: string): IConfi
*/
export function convertRuleOptions(ruleConfiguration: Map<string, Partial<IOptions>>): IOptions[] {
const output: IOptions[] = [];
ruleConfiguration.forEach((partialOptions, ruleName) => {
ruleConfiguration.forEach(({ ruleArguments, ruleSeverity }, ruleName) => {
const options: IOptions = {
disabledIntervals: [],
ruleArguments: partialOptions.ruleArguments || [],
ruleArguments: ruleArguments != null ? ruleArguments : [],
ruleName,
ruleSeverity: partialOptions.ruleSeverity || "error",
ruleSeverity: ruleSeverity != null ? ruleSeverity : "error",
};
output.push(options);
});
Expand Down
4 changes: 2 additions & 2 deletions src/enableDisableRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export class EnableDisableRulesWalker {
position: start,
});

if (end) {
if (end !== undefined) {
// we only get here when rule state changes therefore we can safely use opposite state
ruleStateMap.push({
isEnabled: !isEnabled,
Expand All @@ -96,7 +96,7 @@ export class EnableDisableRulesWalker {
// filter empty items coming from whitespaces at start, at end or empty list
let rulesList = commentText.substr(match[0].length)
.split(/\s+/)
.filter((rule) => !!rule);
.filter((rule) => rule !== "");
if (rulesList.length === 0 && match[3] === ":") {
// nothing to do here: an explicit separator was specified but no rules to switch
return;
Expand Down
4 changes: 2 additions & 2 deletions src/formatterLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export function findFormatter(name: string | FormatterFunction, formattersDirect
}

// then check for rules within the first level of rulesDirectory
if (formattersDirectory) {
if (formattersDirectory !== undefined) {
Formatter = loadFormatter(formattersDirectory, camelizedName);
if (Formatter) {
if (Formatter !== undefined) {
return Formatter;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/formatters/checkstyleFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ export class Formatter extends AbstractFormatter {
public format(failures: RuleFailure[]): string {
let output = '<?xml version="1.0" encoding="utf-8"?><checkstyle version="4.3">';

if (failures.length) {
if (failures.length !== 0) {
const failuresSorted = failures.sort((a, b) => {
return a.getFileName().localeCompare(b.getFileName());
});
let previousFilename: string | null = null;
for (const failure of failuresSorted) {
const severity = failure.getRuleSeverity();
if (failure.getFileName() !== previousFilename) {
if (previousFilename) {
if (previousFilename !== null) {
output += "</file>";
}
previousFilename = failure.getFileName();
Expand All @@ -63,7 +63,7 @@ export class Formatter extends AbstractFormatter {
// checkstyle parser wants "source" to have structure like <anything>dot<category>dot<type>
output += "source=\"failure.tslint." + this.escapeXml(failure.getRuleName()) + "\" />";
}
if (previousFilename) {
if (previousFilename !== null) {
output += "</file>";
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/formatters/proseFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ export class Formatter extends AbstractFormatter {
/* tslint:enable:object-literal-sort-keys */

public format(failures: RuleFailure[], fixes?: RuleFailure[]): string {
if (failures.length === 0 && (!fixes || fixes.length === 0)) {
if (failures.length === 0 && (fixes === undefined || fixes.length === 0)) {
return "\n";
}

const fixLines: string[] = [];
if (fixes) {
if (fixes !== undefined) {
const perFileFixes = new Map<string, number>();
for (const fix of fixes) {
perFileFixes.set(fix.getFileName(), (perFileFixes.get(fix.getFileName()) || 0) + 1);
const prevFixes = perFileFixes.get(fix.getFileName());
perFileFixes.set(fix.getFileName(), (prevFixes !== undefined ? prevFixes : 0) + 1);
}

perFileFixes.forEach((fixCount, fixedFile) => {
Expand Down
2 changes: 1 addition & 1 deletion src/formatters/stylishFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Formatter extends AbstractFormatter {
}

private mapToMessages(failures: RuleFailure[]): string[] {
if (!failures) {
if (failures.length === 0) {
return [];
}
const outputLines: string[] = [];
Expand Down
2 changes: 1 addition & 1 deletion src/formatters/vsoFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class Formatter extends AbstractFormatter {
const lineAndCharacter = failure.getStartPosition().getLineAndCharacter();
const line = lineAndCharacter.line + 1;
const character = lineAndCharacter.character + 1;
const code = (failure.getRuleName ? failure.getRuleName() : "");
const code = failure.getRuleName();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice

const properties = `sourcepath=${fileName};linenumber=${line};columnnumber=${character};code=${code};`;

return `##vso[task.logissue type=warning;${properties}]${failureString}`;
Expand Down
4 changes: 2 additions & 2 deletions src/language/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function doesIntersect(failure: RuleFailure, disabledIntervals: IDisabled
/**
* @returns true if any modifier kinds passed along exist in the given modifiers array
*/
export function hasModifier(modifiers: ts.ModifiersArray | undefined, ...modifierKinds: ts.SyntaxKind[]) {
export function hasModifier(modifiers: ts.ModifiersArray | undefined, ...modifierKinds: ts.SyntaxKind[]): boolean {
if (modifiers === undefined || modifierKinds.length === 0) {
return false;
}
Expand Down Expand Up @@ -99,7 +99,7 @@ export function ancestorWhere<T extends ts.Node>(node: ts.Node, predicate: (n: t
return cur as T;
}
cur = cur.parent;
} while (cur);
} while (cur !== undefined);
return undefined;
}

Expand Down
2 changes: 1 addition & 1 deletion src/language/walker/ruleWalker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class RuleWalker extends SyntaxWalker implements IWalker {
}

public hasOption(option: string): boolean {
if (this.options) {
if (this.options !== undefined) {
return this.options.indexOf(option) !== -1;
} else {
return false;
Expand Down
10 changes: 5 additions & 5 deletions src/linter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class Linter {
if (this.options.fix) {
for (const rule of enabledRules) {
const ruleFailures = this.applyRule(rule, sourceFile);
const fixes = ruleFailures.map((f) => f.getFix()).filter((f): f is Fix => !!f) as Fix[];
const fixes = ruleFailures.map((f) => f.getFix()).filter((f): f is Fix => f !== undefined) as Fix[];
source = fs.readFileSync(fileName, { encoding: "utf-8" });
if (fixes.length > 0) {
this.fixes = this.fixes.concat(ruleFailures);
Expand Down Expand Up @@ -148,9 +148,9 @@ class Linter {
let formatter: IFormatter;
const formattersDirectory = getRelativePath(this.options.formattersDirectory);

const formatterName = this.options.formatter || "prose";
const formatterName = this.options.formatter !== undefined ? this.options.formatter : "prose";
const Formatter = findFormatter(formatterName, formattersDirectory);
if (Formatter) {
if (Formatter !== undefined) {
formatter = new Formatter();
} else {
throw new Error(`formatter '${formatterName}' not found`);
Expand All @@ -172,7 +172,7 @@ class Linter {
private applyRule(rule: IRule, sourceFile: ts.SourceFile) {
let ruleFailures: RuleFailure[] = [];
try {
if (this.program && isTypedRule(rule)) {
if (this.program !== undefined && isTypedRule(rule)) {
ruleFailures = rule.applyWithProgram(sourceFile, this.program);
} else {
ruleFailures = rule.apply(sourceFile);
Expand Down Expand Up @@ -208,7 +208,7 @@ class Linter {
}

private getSourceFile(fileName: string, source: string) {
if (this.program) {
if (this.program !== undefined) {
const sourceFile = this.program.getSourceFile(fileName);
if (sourceFile === undefined) {
const INVALID_SOURCE_ERROR = dedent`
Expand Down
14 changes: 7 additions & 7 deletions src/ruleLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,27 @@ export interface IEnableDisablePosition {
export function loadRules(ruleOptionsList: IOptions[],
enableDisableRuleMap: Map<string, IEnableDisablePosition[]>,
rulesDirectories?: string | string[],
isJs?: boolean): IRule[] {
isJs = false): IRule[] {
const rules: IRule[] = [];
const notFoundRules: string[] = [];
const notAllowedInJsRules: string[] = [];

for (const ruleOptions of ruleOptionsList) {
const ruleName = ruleOptions.ruleName;
const enableDisableRules = enableDisableRuleMap.get(ruleName);
if (ruleOptions.ruleSeverity !== "off" || enableDisableRuleMap) {
if (ruleOptions.ruleSeverity !== "off" || enableDisableRuleMap !== undefined) {
const Rule: (typeof AbstractRule) | null = findRule(ruleName, rulesDirectories);
if (Rule == null) {
notFoundRules.push(ruleName);
} else {
if (isJs && Rule.metadata && Rule.metadata.typescriptOnly) {
if (isJs && Rule.metadata !== undefined && Rule.metadata.typescriptOnly) {
notAllowedInJsRules.push(ruleName);
} else {
const ruleSpecificList = enableDisableRules || [];
const ruleSpecificList = enableDisableRules !== undefined ? enableDisableRules : [];
ruleOptions.disabledIntervals = buildDisabledIntervalsFromSwitches(ruleSpecificList);
rules.push(new (Rule as any)(ruleOptions));

if (Rule.metadata && Rule.metadata.deprecationMessage) {
if (Rule.metadata !== undefined && Rule.metadata.deprecationMessage !== undefined) {
showWarningOnce(`${Rule.metadata.ruleName} is deprecated. ${Rule.metadata.deprecationMessage}`);
}
}
Expand Down Expand Up @@ -127,7 +127,7 @@ function loadRule(directory: string, ruleName: string) {
const fullPath = path.join(directory, ruleName);
if (fs.existsSync(fullPath + ".js")) {
const ruleModule = require(fullPath);
if (ruleModule && ruleModule.Rule) {
if (ruleModule !== undefined && ruleModule.Rule !== undefined) {
return ruleModule.Rule;
}
}
Expand Down Expand Up @@ -175,7 +175,7 @@ function buildDisabledIntervalsFromSwitches(ruleSpecificList: IEnableDisablePosi

// rule enabled state is always alternating therefore we can use position of next switch as end of disabled interval
// set endPosition as Infinity in case when last switch for rule in a file is disabled
const endPosition = ruleSpecificList[i + 1] ? ruleSpecificList[i + 1].position : Infinity;
const endPosition = ruleSpecificList[i + 1] !== undefined ? ruleSpecificList[i + 1].position : Infinity;

disabledIntervalList.push({
endPosition,
Expand Down
20 changes: 11 additions & 9 deletions src/rules/adjacentOverloadSignaturesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class AdjacentOverloadSignaturesWalker extends Lint.RuleWalker {

public visitModuleDeclaration(node: ts.ModuleDeclaration) {
const { body } = node;
if (body && body.kind === ts.SyntaxKind.ModuleBlock) {
if (body !== undefined && body.kind === ts.SyntaxKind.ModuleBlock) {
this.visitStatements((body as ts.ModuleBlock).statements);
}
super.visitModuleDeclaration(node);
Expand All @@ -77,7 +77,7 @@ class AdjacentOverloadSignaturesWalker extends Lint.RuleWalker {
this.checkOverloadsAdjacent(statements, (statement) => {
if (statement.kind === ts.SyntaxKind.FunctionDeclaration) {
const name = (statement as ts.FunctionDeclaration).name;
return name && { name: name.text, key: name.text };
return name === undefined ? undefined : { name: name.text, key: name.text };
} else {
return undefined;
}
Expand All @@ -94,7 +94,7 @@ class AdjacentOverloadSignaturesWalker extends Lint.RuleWalker {
const seen = new Set<string>();
for (const node of overloads) {
const overload = getOverload(node);
if (overload) {
if (overload !== undefined) {
const { name, key } = overload;
if (seen.has(key) && lastKey !== key) {
this.addFailureAtNode(node, Rule.FAILURE_STRING_FACTORY(name));
Expand All @@ -117,7 +117,7 @@ interface Overload {

export function getOverloadKey(node: ts.SignatureDeclaration): string | undefined {
const o = getOverload(node);
return o && o.key;
return o === undefined ? undefined : o.key;
}

function getOverloadIfSignature(node: ts.TypeElement | ts.ClassElement): Overload | undefined {
Expand All @@ -139,7 +139,7 @@ function getOverload(node: ts.SignatureDeclaration): Overload | undefined {
}

const propertyInfo = getPropertyInfo(node.name);
if (!propertyInfo) {
if (propertyInfo === undefined) {
return undefined;
}

Expand All @@ -149,14 +149,16 @@ function getOverload(node: ts.SignatureDeclaration): Overload | undefined {
return { name, key };
}

function getPropertyInfo(name: ts.PropertyName): { name: string, computed?: boolean } | undefined {
function getPropertyInfo(name: ts.PropertyName): { name: string, computed: boolean } | undefined {
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return { name: (name as ts.Identifier).text };
return { name: (name as ts.Identifier).text, computed: false };
case ts.SyntaxKind.ComputedPropertyName:
const { expression } = (name as ts.ComputedPropertyName);
return utils.isLiteralExpression(expression) ? { name: expression.text } : { name: expression.getText(), computed: true };
return utils.isLiteralExpression(expression)
? { name: expression.text, computed: false }
: { name: expression.getText(), computed: true };
default:
return utils.isLiteralExpression(name) ? { name: (name as ts.StringLiteral).text } : undefined;
return utils.isLiteralExpression(name) ? { name: (name as ts.StringLiteral).text, computed: false } : undefined;
}
}
Loading