forked from palantir/tslint
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add optional type information to rules (palantir#1363)
Addresses palantir#1323. * Changed `Linter` to accept an optional program object in the constructor * Added helper functions for creating a program using a tsconfig and getting relevant files * Created `TypedRule` class which receives the program object * Rules extending this class must implement `applyWithProgram` * `Linter` passes program to `TypedRule`s if available * Calling `apply` on a `TypedRule` throws an error * Added `requiresTypeInfo` boolean to metadata * Created `ProgramAwareRuleWalker` which walks with the program / typechecker * Added cli options `--project` and `--type-check` * `--project` takes a `tsconfig.json` file * `--type-check` enables type checking and `TypedRule`s, requires `--project` * Added an example `restrictPlusOperands` rule and tests that uses types
- Loading branch information
Showing
19 changed files
with
391 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/** | ||
* @license | ||
* Copyright 2016 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 {AbstractRule} from "./abstractRule"; | ||
import {RuleFailure} from "./rule"; | ||
|
||
export abstract class TypedRule extends AbstractRule { | ||
public apply(sourceFile: ts.SourceFile): RuleFailure[] { | ||
// if no program is given to the linter, throw an error | ||
throw new Error(`${this.getOptions().ruleName} requires type checking`); | ||
} | ||
|
||
public abstract applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): RuleFailure[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* @license | ||
* Copyright 2016 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 {IOptions} from "../../lint"; | ||
import {RuleWalker} from "./ruleWalker"; | ||
|
||
export class ProgramAwareRuleWalker extends RuleWalker { | ||
private typeChecker: ts.TypeChecker; | ||
|
||
constructor(sourceFile: ts.SourceFile, options: IOptions, private program: ts.Program) { | ||
super(sourceFile, options); | ||
|
||
this.typeChecker = program.getTypeChecker(); | ||
} | ||
|
||
public getProgram(): ts.Program { | ||
return this.program; | ||
} | ||
|
||
public getTypeChecker(): ts.TypeChecker { | ||
return this.typeChecker; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,3 +16,4 @@ | |
*/ | ||
|
||
export * from "./language/rule/abstractRule"; | ||
export * from "./language/rule/typedRule"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/** | ||
* @license | ||
* Copyright 2016 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 "../lint"; | ||
|
||
export class Rule extends Lint.Rules.TypedRule { | ||
/* tslint:disable:object-literal-sort-keys */ | ||
public static metadata: Lint.IRuleMetadata = { | ||
ruleName: "restrict-plus-operands", | ||
description: "When adding two variables, operands must both be of type number or of type string.", | ||
optionsDescription: "Not configurable.", | ||
options: null, | ||
optionExamples: ["true"], | ||
type: "functionality", | ||
requiresTypeInfo: true, | ||
}; | ||
/* tslint:enable:object-literal-sort-keys */ | ||
|
||
public static MISMATCHED_TYPES_FAILURE = "Types of values used in '+' operation must match"; | ||
public static UNSUPPORTED_TYPE_FAILURE_FACTORY = (type: string) => `cannot add type ${type}`; | ||
|
||
public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] { | ||
return this.applyWithWalker(new RestrictPlusOperandsWalker(sourceFile, this.getOptions(), program)); | ||
} | ||
} | ||
|
||
class RestrictPlusOperandsWalker extends Lint.ProgramAwareRuleWalker { | ||
public visitBinaryExpression(node: ts.BinaryExpression) { | ||
if (node.operatorToken.kind === ts.SyntaxKind.PlusToken) { | ||
const tc = this.getTypeChecker(); | ||
const leftType = tc.typeToString(tc.getTypeAtLocation(node.left)); | ||
const rightType = tc.typeToString(tc.getTypeAtLocation(node.right)); | ||
|
||
const width = node.getWidth(); | ||
const position = node.getStart(); | ||
|
||
if (leftType !== rightType) { | ||
// mismatched types | ||
this.addFailure(this.createFailure(position, width, Rule.MISMATCHED_TYPES_FAILURE)); | ||
} else if (leftType !== "number" && leftType !== "string") { | ||
// adding unsupported types | ||
const failureString = Rule.UNSUPPORTED_TYPE_FAILURE_FACTORY(leftType); | ||
this.addFailure(this.createFailure(position, width, failureString)); | ||
} | ||
} | ||
|
||
super.visitBinaryExpression(node); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.