diff --git a/Gruntfile.js b/Gruntfile.js index 93e3919e872..feed240ad33 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -14,8 +14,7 @@ module.exports = function (grunt) { typescriptBin: "node_modules/typescript/lib/typescriptServices.js", clean: { - bin: ["bin/tslint-cli.js"], - core: ["build/rules/", "build/formatters", "lib/tslint.*"], + lib: ["lib/**/*.js", "lib/**/*.d.ts"], test: ["build/test/"], }, diff --git a/bin/tslint b/bin/tslint index 19f10164332..e052e09d9b6 100755 --- a/bin/tslint +++ b/bin/tslint @@ -1,3 +1,3 @@ #!/usr/bin/env node -require("./tslint-cli"); +require("../lib/tslint-cli"); diff --git a/lib/configuration.d.ts b/lib/configuration.d.ts new file mode 100644 index 00000000000..d277ec7d5ad --- /dev/null +++ b/lib/configuration.d.ts @@ -0,0 +1 @@ +export declare function findConfiguration(configFile: string, inputFileLocation: string): any; diff --git a/lib/configuration.js b/lib/configuration.js new file mode 100644 index 00000000000..806ec067f87 --- /dev/null +++ b/lib/configuration.js @@ -0,0 +1,73 @@ +/* + * 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. + */ +var fs = require("fs"); +var path = require("path"); +var findup = require("findup-sync"); +var CONFIG_FILENAME = "tslint.json"; +var DEFAULT_CONFIG = { + "rules": { + "curly": true, + "indent": [true, 4], + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-trailing-whitespace": true, + "no-unreachable": true, + "no-use-before-declare": true, + "quotemark": [true, "double"], + "semicolon": true + } +}; +function findConfiguration(configFile, inputFileLocation) { + if (configFile) { + return JSON.parse(fs.readFileSync(configFile, "utf8")); + } + // first look for package.json from input file location + configFile = findup("package.json", { cwd: inputFileLocation, nocase: true }); + if (configFile) { + var content = require(configFile); + if (content.tslintConfig) { + return content.tslintConfig; + } + } + // next look for tslint.json + var homeDir = getHomeDir(); + if (!homeDir) { + return undefined; + } + var defaultPath = path.join(homeDir, CONFIG_FILENAME); + configFile = findup(CONFIG_FILENAME, { cwd: inputFileLocation, nocase: true }) || defaultPath; + if (fs.existsSync(configFile)) { + return JSON.parse(fs.readFileSync(configFile, "utf8")); + } + else { + return DEFAULT_CONFIG; + } +} +exports.findConfiguration = findConfiguration; +function getHomeDir() { + var environment = global.process.env; + var paths = [environment.USERPROFILE, environment.HOME, environment.HOMEPATH, environment.HOMEDRIVE + environment.HOMEPATH]; + for (var homeIndex in paths) { + if (paths.hasOwnProperty(homeIndex)) { + var homePath = paths[homeIndex]; + if (homePath && fs.existsSync(homePath)) { + return homePath; + } + } + } +} diff --git a/lib/enableDisableRules.d.ts b/lib/enableDisableRules.d.ts new file mode 100644 index 00000000000..92b093ddcf4 --- /dev/null +++ b/lib/enableDisableRules.d.ts @@ -0,0 +1,9 @@ +import * as Lint from "./lint"; +import * as ts from "typescript"; +export declare class EnableDisableRulesWalker extends Lint.SkippableTokenAwareRuleWalker { + enableDisableRuleMap: { + [rulename: string]: Lint.IEnableDisablePosition[]; + }; + visitSourceFile(node: ts.SourceFile): void; + private handlePossibleTslintSwitch(commentText, startingPosition); +} diff --git a/lib/enableDisableRules.js b/lib/enableDisableRules.js new file mode 100644 index 00000000000..c23869cc668 --- /dev/null +++ b/lib/enableDisableRules.js @@ -0,0 +1,78 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* +* Copyright 2014 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. +*/ +var Lint = require("./lint"); +var ts = require("typescript"); +var EnableDisableRulesWalker = (function (_super) { + __extends(EnableDisableRulesWalker, _super); + function EnableDisableRulesWalker() { + _super.apply(this, arguments); + this.enableDisableRuleMap = {}; + } + EnableDisableRulesWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + var scan = ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text); + Lint.scanAllTokens(scan, function (scanner) { + var startPos = scanner.getStartPos(); + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + return; + } + if (scanner.getToken() === 3 /* MultiLineCommentTrivia */) { + var commentText = scanner.getTokenText(); + var startPosition = scanner.getTokenPos(); + _this.handlePossibleTslintSwitch(commentText, startPosition); + } + }); + }; + EnableDisableRulesWalker.prototype.handlePossibleTslintSwitch = function (commentText, startingPosition) { + var _this = this; + var currentPosition = startingPosition; + // regex is: start of string followed by "/*" followed by any amount of whitespace followed by "tslint:" + if (commentText.match(/^\/\*\s*tslint:/)) { + var commentTextParts = commentText.split(":"); + // regex is: start of string followed by either "enable" or "disable" + // followed by either whitespace or end of string + var enableOrDisableMatch = commentTextParts[1].match(/^(enable|disable)(\s|$)/); + if (enableOrDisableMatch != null) { + var isEnabled = enableOrDisableMatch[1] === "enable"; + var position = currentPosition; + var rulesList = ["all"]; + if (commentTextParts.length > 2) { + rulesList = commentTextParts[2].split(/\s+/); + } + rulesList.forEach(function (ruleToAdd) { + if (!(ruleToAdd in _this.enableDisableRuleMap)) { + _this.enableDisableRuleMap[ruleToAdd] = []; + } + _this.enableDisableRuleMap[ruleToAdd].push({ + isEnabled: isEnabled, + position: position + }); + }); + } + } + }; + return EnableDisableRulesWalker; +})(Lint.SkippableTokenAwareRuleWalker); +exports.EnableDisableRulesWalker = EnableDisableRulesWalker; diff --git a/lib/formatterLoader.d.ts b/lib/formatterLoader.d.ts new file mode 100644 index 00000000000..d26bef5e1d5 --- /dev/null +++ b/lib/formatterLoader.d.ts @@ -0,0 +1 @@ +export declare function findFormatter(name: string, formattersDirectory?: string): any; diff --git a/lib/formatterLoader.js b/lib/formatterLoader.js new file mode 100644 index 00000000000..a96b0ab6732 --- /dev/null +++ b/lib/formatterLoader.js @@ -0,0 +1,64 @@ +/* +* 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. +*/ +var fs = require("fs"); +var path = require("path"); +var underscore_string_1 = require("underscore.string"); +var moduleDirectory = path.dirname(module.filename); +var CORE_FORMATTERS_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "formatters"); +function findFormatter(name, formattersDirectory) { + if (typeof (name) === "function") { + return name; + } + var camelizedName = underscore_string_1.camelize(name + "Formatter"); + // first check for core formatters + var Formatter = loadFormatter(CORE_FORMATTERS_DIRECTORY, camelizedName); + if (Formatter) { + return Formatter; + } + // then check for rules within the first level of rulesDirectory + if (formattersDirectory) { + Formatter = loadFormatter(formattersDirectory, camelizedName); + if (Formatter) { + return Formatter; + } + } + // else try to resolve as module + return loadFormatterModule(name); +} +exports.findFormatter = findFormatter; +function loadFormatter() { + var paths = []; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; + } + var formatterPath = paths.reduce(function (p, c) { return path.join(p, c); }, ""); + var fullPath = path.resolve(moduleDirectory, formatterPath); + if (fs.existsSync(fullPath + ".js")) { + var formatterModule = require(fullPath); + return formatterModule.Formatter; + } + return undefined; +} +function loadFormatterModule(name) { + var src; + try { + src = require.resolve(name); + } + catch (e) { + return undefined; + } + return require(src).Formatter; +} diff --git a/lib/formatters.d.ts b/lib/formatters.d.ts new file mode 100644 index 00000000000..a808faea53a --- /dev/null +++ b/lib/formatters.d.ts @@ -0,0 +1,2 @@ +export * from "./language/formatter/abstractFormatter"; +export * from "./formatters/index"; diff --git a/lib/formatters.js b/lib/formatters.js new file mode 100644 index 00000000000..e1207f472d4 --- /dev/null +++ b/lib/formatters.js @@ -0,0 +1,5 @@ +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./language/formatter/abstractFormatter")); +__export(require("./formatters/index")); diff --git a/lib/formatters/index.d.ts b/lib/formatters/index.d.ts new file mode 100644 index 00000000000..fa45bfa3872 --- /dev/null +++ b/lib/formatters/index.d.ts @@ -0,0 +1,4 @@ +export * from "./jsonFormatter"; +export * from "./pmdFormatter"; +export * from "./proseFormatter"; +export * from "./verboseFormatter"; diff --git a/lib/formatters/index.js b/lib/formatters/index.js new file mode 100644 index 00000000000..5c48d1ff13e --- /dev/null +++ b/lib/formatters/index.js @@ -0,0 +1,7 @@ +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./jsonFormatter")); +__export(require("./pmdFormatter")); +__export(require("./proseFormatter")); +__export(require("./verboseFormatter")); diff --git a/lib/formatters/jsonFormatter.d.ts b/lib/formatters/jsonFormatter.d.ts new file mode 100644 index 00000000000..31be0e48222 --- /dev/null +++ b/lib/formatters/jsonFormatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../lint"; +export declare class Formatter extends Lint.Formatters.AbstractFormatter { + format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/formatters/jsonFormatter.js b/lib/formatters/jsonFormatter.js new file mode 100644 index 00000000000..bc6e9710ccb --- /dev/null +++ b/lib/formatters/jsonFormatter.js @@ -0,0 +1,33 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Formatter = (function (_super) { + __extends(Formatter, _super); + function Formatter() { + _super.apply(this, arguments); + } + Formatter.prototype.format = function (failures) { + var failuresJSON = failures.map(function (failure) { return failure.toJson(); }); + return JSON.stringify(failuresJSON); + }; + return Formatter; +})(Lint.Formatters.AbstractFormatter); +exports.Formatter = Formatter; diff --git a/lib/formatters/pmdFormatter.d.ts b/lib/formatters/pmdFormatter.d.ts new file mode 100644 index 00000000000..31be0e48222 --- /dev/null +++ b/lib/formatters/pmdFormatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../lint"; +export declare class Formatter extends Lint.Formatters.AbstractFormatter { + format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/formatters/pmdFormatter.js b/lib/formatters/pmdFormatter.js new file mode 100644 index 00000000000..ec86ab07170 --- /dev/null +++ b/lib/formatters/pmdFormatter.js @@ -0,0 +1,49 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Formatter = (function (_super) { + __extends(Formatter, _super); + function Formatter() { + _super.apply(this, arguments); + } + Formatter.prototype.format = function (failures) { + var output = ""; + for (var _i = 0; _i < failures.length; _i++) { + var failure = failures[_i]; + var failureString = failure.getFailure() + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/\'/g, "'") + .replace(/\"/g, """); + var lineAndCharacter = failure.getStartPosition().getLineAndCharacter(); + output += " "; + } + output += ""; + return output; + }; + return Formatter; +})(Lint.Formatters.AbstractFormatter); +exports.Formatter = Formatter; diff --git a/lib/formatters/proseFormatter.d.ts b/lib/formatters/proseFormatter.d.ts new file mode 100644 index 00000000000..31be0e48222 --- /dev/null +++ b/lib/formatters/proseFormatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../lint"; +export declare class Formatter extends Lint.Formatters.AbstractFormatter { + format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/formatters/proseFormatter.js b/lib/formatters/proseFormatter.js new file mode 100644 index 00000000000..5a0a0339ab0 --- /dev/null +++ b/lib/formatters/proseFormatter.js @@ -0,0 +1,39 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Formatter = (function (_super) { + __extends(Formatter, _super); + function Formatter() { + _super.apply(this, arguments); + } + Formatter.prototype.format = function (failures) { + var outputLines = failures.map(function (failure) { + var fileName = failure.getFileName(); + var failureString = failure.getFailure(); + var lineAndCharacter = failure.getStartPosition().getLineAndCharacter(); + var positionTuple = "[" + (lineAndCharacter.line + 1) + ", " + (lineAndCharacter.character + 1) + "]"; + return "" + fileName + positionTuple + ": " + failureString; + }); + return outputLines.join("\n") + "\n"; + }; + return Formatter; +})(Lint.Formatters.AbstractFormatter); +exports.Formatter = Formatter; diff --git a/lib/formatters/verboseFormatter.d.ts b/lib/formatters/verboseFormatter.d.ts new file mode 100644 index 00000000000..31be0e48222 --- /dev/null +++ b/lib/formatters/verboseFormatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../lint"; +export declare class Formatter extends Lint.Formatters.AbstractFormatter { + format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/formatters/verboseFormatter.js b/lib/formatters/verboseFormatter.js new file mode 100644 index 00000000000..386309b1494 --- /dev/null +++ b/lib/formatters/verboseFormatter.js @@ -0,0 +1,40 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. +*/ +var Lint = require("../lint"); +var Formatter = (function (_super) { + __extends(Formatter, _super); + function Formatter() { + _super.apply(this, arguments); + } + Formatter.prototype.format = function (failures) { + var outputLines = failures.map(function (failure) { + var fileName = failure.getFileName(); + var failureString = failure.getFailure(); + var ruleName = failure.getRuleName(); + var lineAndCharacter = failure.getStartPosition().getLineAndCharacter(); + var positionTuple = "[" + (lineAndCharacter.line + 1) + ", " + (lineAndCharacter.character + 1) + "]"; + return "(" + ruleName + ") " + fileName + positionTuple + ": " + failureString; + }); + return outputLines.join("\n") + "\n"; + }; + return Formatter; +})(Lint.Formatters.AbstractFormatter); +exports.Formatter = Formatter; diff --git a/lib/language/formatter/abstractFormatter.d.ts b/lib/language/formatter/abstractFormatter.d.ts new file mode 100644 index 00000000000..3eca091fabd --- /dev/null +++ b/lib/language/formatter/abstractFormatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../../lint"; +export declare abstract class AbstractFormatter implements Lint.IFormatter { + abstract format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/language/formatter/abstractFormatter.js b/lib/language/formatter/abstractFormatter.js new file mode 100644 index 00000000000..bced361792f --- /dev/null +++ b/lib/language/formatter/abstractFormatter.js @@ -0,0 +1,6 @@ +var AbstractFormatter = (function () { + function AbstractFormatter() { + } + return AbstractFormatter; +})(); +exports.AbstractFormatter = AbstractFormatter; diff --git a/lib/language/formatter/formatter.d.ts b/lib/language/formatter/formatter.d.ts new file mode 100644 index 00000000000..3bfc3b0f184 --- /dev/null +++ b/lib/language/formatter/formatter.d.ts @@ -0,0 +1,4 @@ +import * as Lint from "../../lint"; +export interface IFormatter { + format(failures: Lint.RuleFailure[]): string; +} diff --git a/lib/language/formatter/formatter.js b/lib/language/formatter/formatter.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/language/languageServiceHost.d.ts b/lib/language/languageServiceHost.d.ts new file mode 100644 index 00000000000..e06729bd6e3 --- /dev/null +++ b/lib/language/languageServiceHost.d.ts @@ -0,0 +1,3 @@ +import * as ts from "typescript"; +export declare function createLanguageServiceHost(fileName: string, source: string): ts.LanguageServiceHost; +export declare function createLanguageService(fileName: string, source: string): ts.LanguageService; diff --git a/lib/language/languageServiceHost.js b/lib/language/languageServiceHost.js new file mode 100644 index 00000000000..0fd2a87f909 --- /dev/null +++ b/lib/language/languageServiceHost.js @@ -0,0 +1,35 @@ +/* + * Copyright 2014 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +function createLanguageServiceHost(fileName, source) { + var host = { + getCompilationSettings: function () { return Lint.createCompilerOptions(); }, + getCurrentDirectory: function () { return ""; }, + getDefaultLibFileName: function () { return "lib.d.ts"; }, + getScriptFileNames: function () { return [fileName]; }, + getScriptSnapshot: function (name) { return ts.ScriptSnapshot.fromString(name === fileName ? source : ""); }, + getScriptVersion: function () { return "1"; }, + log: function (message) { } + }; + return host; +} +exports.createLanguageServiceHost = createLanguageServiceHost; +function createLanguageService(fileName, source) { + var languageServiceHost = Lint.createLanguageServiceHost(fileName, source); + return ts.createLanguageService(languageServiceHost); +} +exports.createLanguageService = createLanguageService; diff --git a/lib/language/rule/abstractRule.d.ts b/lib/language/rule/abstractRule.d.ts new file mode 100644 index 00000000000..61f61384460 --- /dev/null +++ b/lib/language/rule/abstractRule.d.ts @@ -0,0 +1,12 @@ +import * as Lint from "../../lint"; +import { RuleWalker } from "../walker/ruleWalker"; +import * as ts from "typescript"; +export declare abstract class AbstractRule implements Lint.IRule { + private value; + private options; + constructor(ruleName: string, value: any, disabledIntervals: Lint.IDisabledInterval[]); + getOptions(): Lint.IOptions; + abstract apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; + applyWithWalker(walker: RuleWalker): Lint.RuleFailure[]; + isEnabled(): boolean; +} diff --git a/lib/language/rule/abstractRule.js b/lib/language/rule/abstractRule.js new file mode 100644 index 00000000000..9cd95a86d2f --- /dev/null +++ b/lib/language/rule/abstractRule.js @@ -0,0 +1,33 @@ +var AbstractRule = (function () { + function AbstractRule(ruleName, value, disabledIntervals) { + var ruleArguments = []; + if (Array.isArray(value) && value.length > 1) { + ruleArguments = value.slice(1); + } + this.value = value; + this.options = { + disabledIntervals: disabledIntervals, + ruleArguments: ruleArguments, + ruleName: ruleName + }; + } + AbstractRule.prototype.getOptions = function () { + return this.options; + }; + AbstractRule.prototype.applyWithWalker = function (walker) { + walker.walk(walker.getSourceFile()); + return walker.getFailures(); + }; + AbstractRule.prototype.isEnabled = function () { + var value = this.value; + if (typeof value === "boolean") { + return value; + } + if (Array.isArray(value) && value.length > 0) { + return value[0]; + } + return false; + }; + return AbstractRule; +})(); +exports.AbstractRule = AbstractRule; diff --git a/lib/language/rule/rule.d.ts b/lib/language/rule/rule.d.ts new file mode 100644 index 00000000000..38508a7bbde --- /dev/null +++ b/lib/language/rule/rule.d.ts @@ -0,0 +1,47 @@ +import * as Lint from "../../lint"; +import * as ts from "typescript"; +export interface IOptions { + ruleArguments?: any[]; + ruleName: string; + disabledIntervals: Lint.IDisabledInterval[]; +} +export interface IDisabledInterval { + startPosition: number; + endPosition: number; +} +export interface IRule { + getOptions(): IOptions; + isEnabled(): boolean; + apply(sourceFile: ts.SourceFile): RuleFailure[]; + applyWithWalker(walker: Lint.RuleWalker): RuleFailure[]; +} +export declare class RuleFailurePosition { + private position; + private lineAndCharacter; + constructor(position: number, lineAndCharacter: ts.LineAndCharacter); + getPosition(): number; + getLineAndCharacter(): ts.LineAndCharacter; + toJson(): { + character: number; + line: number; + position: number; + }; + equals(ruleFailurePosition: RuleFailurePosition): boolean; +} +export declare class RuleFailure { + private sourceFile; + private fileName; + private startPosition; + private endPosition; + private failure; + private ruleName; + constructor(sourceFile: ts.SourceFile, start: number, end: number, failure: string, ruleName: string); + getFileName(): string; + getRuleName(): string; + getStartPosition(): RuleFailurePosition; + getEndPosition(): RuleFailurePosition; + getFailure(): string; + toJson(): any; + equals(ruleFailure: RuleFailure): boolean; + private createFailurePosition(position); +} diff --git a/lib/language/rule/rule.js b/lib/language/rule/rule.js new file mode 100644 index 00000000000..129f66bf78c --- /dev/null +++ b/lib/language/rule/rule.js @@ -0,0 +1,74 @@ +var RuleFailurePosition = (function () { + function RuleFailurePosition(position, lineAndCharacter) { + this.position = position; + this.lineAndCharacter = lineAndCharacter; + } + RuleFailurePosition.prototype.getPosition = function () { + return this.position; + }; + RuleFailurePosition.prototype.getLineAndCharacter = function () { + return this.lineAndCharacter; + }; + RuleFailurePosition.prototype.toJson = function () { + return { + character: this.lineAndCharacter.character, + line: this.lineAndCharacter.line, + position: this.position + }; + }; + RuleFailurePosition.prototype.equals = function (ruleFailurePosition) { + var ll = this.lineAndCharacter; + var rr = ruleFailurePosition.lineAndCharacter; + return this.position === ruleFailurePosition.position + && ll.line === rr.line + && ll.character === rr.character; + }; + return RuleFailurePosition; +})(); +exports.RuleFailurePosition = RuleFailurePosition; +var RuleFailure = (function () { + function RuleFailure(sourceFile, start, end, failure, ruleName) { + this.sourceFile = sourceFile; + this.fileName = sourceFile.fileName; + this.startPosition = this.createFailurePosition(start); + this.endPosition = this.createFailurePosition(end); + this.failure = failure; + this.ruleName = ruleName; + } + RuleFailure.prototype.getFileName = function () { + return this.fileName; + }; + RuleFailure.prototype.getRuleName = function () { + return this.ruleName; + }; + RuleFailure.prototype.getStartPosition = function () { + return this.startPosition; + }; + RuleFailure.prototype.getEndPosition = function () { + return this.endPosition; + }; + RuleFailure.prototype.getFailure = function () { + return this.failure; + }; + RuleFailure.prototype.toJson = function () { + return { + endPosition: this.endPosition.toJson(), + failure: this.failure, + name: this.fileName, + ruleName: this.ruleName, + startPosition: this.startPosition.toJson() + }; + }; + RuleFailure.prototype.equals = function (ruleFailure) { + return this.failure === ruleFailure.getFailure() + && this.fileName === ruleFailure.getFileName() + && this.startPosition.equals(ruleFailure.getStartPosition()) + && this.endPosition.equals(ruleFailure.getEndPosition()); + }; + RuleFailure.prototype.createFailurePosition = function (position) { + var lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(position); + return new RuleFailurePosition(position, lineAndCharacter); + }; + return RuleFailure; +})(); +exports.RuleFailure = RuleFailure; diff --git a/lib/language/utils.d.ts b/lib/language/utils.d.ts new file mode 100644 index 00000000000..3524821c148 --- /dev/null +++ b/lib/language/utils.d.ts @@ -0,0 +1,21 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare function getSourceFile(fileName: string, source: string): ts.SourceFile; +export declare function createCompilerOptions(): ts.CompilerOptions; +export declare function doesIntersect(failure: Lint.RuleFailure, disabledIntervals: Lint.IDisabledInterval[]): boolean; +export declare function abstract(): string; +export declare function scanAllTokens(scanner: ts.Scanner, callback: (s: ts.Scanner) => void): void; +/** + * @returns true if any modifier kinds passed along exist in the given modifiers array + */ +export declare function hasModifier(modifiers: ts.ModifiersArray, ...modifierKinds: ts.SyntaxKind[]): boolean; +/** + * Determines if the appropriate bit in the parent (VariableDeclarationList) is set, + * which indicates this is a "let" or "const". + */ +export declare function isBlockScopedVariable(node: ts.VariableDeclaration | ts.VariableStatement): boolean; +export declare function isBlockScopedBindingElement(node: ts.BindingElement): boolean; +/** + * Bitwise check for node flags. + */ +export declare function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean; diff --git a/lib/language/utils.js b/lib/language/utils.js new file mode 100644 index 00000000000..01b99e4373b --- /dev/null +++ b/lib/language/utils.js @@ -0,0 +1,122 @@ +/* + * 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. + */ +var ts = require("typescript"); +var path = require("path"); +function getSourceFile(fileName, source) { + var normalizedName = path.normalize(fileName).replace(/\\/g, "/"); + var compilerOptions = createCompilerOptions(); + var compilerHost = { + fileExists: function () { return true; }, + getCanonicalFileName: function (filename) { return filename; }, + getCurrentDirectory: function () { return ""; }, + getDefaultLibFileName: function () { return "lib.d.ts"; }, + getNewLine: function () { return "\n"; }, + getSourceFile: function (filenameToGet) { + if (filenameToGet === normalizedName) { + return ts.createSourceFile(filenameToGet, source, compilerOptions.target, true); + } + }, + readFile: function () { return null; }, + useCaseSensitiveFileNames: function () { return true; }, + writeFile: function () { return null; } + }; + var program = ts.createProgram([normalizedName], compilerOptions, compilerHost); + return program.getSourceFile(normalizedName); +} +exports.getSourceFile = getSourceFile; +function createCompilerOptions() { + return { + noResolve: true, + target: 1 /* ES5 */ + }; +} +exports.createCompilerOptions = createCompilerOptions; +function doesIntersect(failure, disabledIntervals) { + return disabledIntervals.some(function (interval) { + var maxStart = Math.max(interval.startPosition, failure.getStartPosition().getPosition()); + var minEnd = Math.min(interval.endPosition, failure.getEndPosition().getPosition()); + return maxStart <= minEnd; + }); +} +exports.doesIntersect = doesIntersect; +function abstract() { + console.warn("Lint.abstract() is deprecated and will be removed in a future release. TSLint now uses abstract classes."); + return "abstract method not implemented"; +} +exports.abstract = abstract; +function scanAllTokens(scanner, callback) { + var lastStartPos = -1; + while (scanner.scan() !== 1 /* EndOfFileToken */) { + var startPos = scanner.getStartPos(); + if (startPos === lastStartPos) { + break; + } + lastStartPos = startPos; + callback(scanner); + } +} +exports.scanAllTokens = scanAllTokens; +/** + * @returns true if any modifier kinds passed along exist in the given modifiers array + */ +function hasModifier(modifiers) { + var modifierKinds = []; + for (var _i = 1; _i < arguments.length; _i++) { + modifierKinds[_i - 1] = arguments[_i]; + } + if (modifiers == null || modifierKinds == null) { + return false; + } + return modifiers.some(function (m) { + return modifierKinds.some(function (k) { return m.kind === k; }); + }); +} +exports.hasModifier = hasModifier; +/** + * Determines if the appropriate bit in the parent (VariableDeclarationList) is set, + * which indicates this is a "let" or "const". + */ +function isBlockScopedVariable(node) { + var parentNode = (node.kind === 209 /* VariableDeclaration */) + ? node.parent + : node.declarationList; + return isNodeFlagSet(parentNode, 16384 /* Let */) + || isNodeFlagSet(parentNode, 32768 /* Const */); +} +exports.isBlockScopedVariable = isBlockScopedVariable; +function isBlockScopedBindingElement(node) { + var currentParent = node.parent; + while (currentParent.kind !== 209 /* VariableDeclaration */) { + if (currentParent.parent == null) { + // if we didn't encounter a VariableDeclaration, this must be a function parameter, which is block scoped + return true; + } + else { + currentParent = currentParent.parent; + } + } + return isBlockScopedVariable(currentParent); +} +exports.isBlockScopedBindingElement = isBlockScopedBindingElement; +/** + * Bitwise check for node flags. + */ +function isNodeFlagSet(node, flagToCheck) { + /* tslint:disable:no-bitwise */ + return (node.flags & flagToCheck) !== 0; + /* tslint:enable:no-bitwise */ +} +exports.isNodeFlagSet = isNodeFlagSet; diff --git a/lib/language/walker/blockScopeAwareRuleWalker.d.ts b/lib/language/walker/blockScopeAwareRuleWalker.d.ts new file mode 100644 index 00000000000..b3c814e96c9 --- /dev/null +++ b/lib/language/walker/blockScopeAwareRuleWalker.d.ts @@ -0,0 +1,17 @@ +import { ScopeAwareRuleWalker } from "./scopeAwareRuleWalker"; +import * as ts from "typescript"; +/** + * An AST walker that is aware of block scopes in addition to regular scopes. Block scopes + * are a superset of regular scopes (new block scopes are created more frequently in a program). + */ +export declare abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker { + private blockScopeStack; + constructor(sourceFile: ts.SourceFile, options?: any); + abstract createBlockScope(): U; + getCurrentBlockScope(): U; + onBlockScopeStart(): void; + getCurrentBlockDepth(): number; + onBlockScopeEnd(): void; + protected visitNode(node: ts.Node): void; + private isBlockScopeBoundary(node); +} diff --git a/lib/language/walker/blockScopeAwareRuleWalker.js b/lib/language/walker/blockScopeAwareRuleWalker.js new file mode 100644 index 00000000000..e210b8963d3 --- /dev/null +++ b/lib/language/walker/blockScopeAwareRuleWalker.js @@ -0,0 +1,60 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var scopeAwareRuleWalker_1 = require("./scopeAwareRuleWalker"); +var ts = require("typescript"); +/** + * An AST walker that is aware of block scopes in addition to regular scopes. Block scopes + * are a superset of regular scopes (new block scopes are created more frequently in a program). + */ +var BlockScopeAwareRuleWalker = (function (_super) { + __extends(BlockScopeAwareRuleWalker, _super); + function BlockScopeAwareRuleWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + // initialize stack with global scope + this.blockScopeStack = [this.createBlockScope()]; + } + BlockScopeAwareRuleWalker.prototype.getCurrentBlockScope = function () { + return this.blockScopeStack[this.blockScopeStack.length - 1]; + }; + // callback notifier when a block scope begins + BlockScopeAwareRuleWalker.prototype.onBlockScopeStart = function () { + return; + }; + BlockScopeAwareRuleWalker.prototype.getCurrentBlockDepth = function () { + return this.blockScopeStack.length; + }; + // callback notifier when a block scope ends + BlockScopeAwareRuleWalker.prototype.onBlockScopeEnd = function () { + return; + }; + BlockScopeAwareRuleWalker.prototype.visitNode = function (node) { + var isNewBlockScope = this.isBlockScopeBoundary(node); + if (isNewBlockScope) { + this.blockScopeStack.push(this.createBlockScope()); + } + this.onBlockScopeStart(); + _super.prototype.visitNode.call(this, node); + this.onBlockScopeEnd(); + if (isNewBlockScope) { + this.blockScopeStack.pop(); + } + }; + BlockScopeAwareRuleWalker.prototype.isBlockScopeBoundary = function (node) { + return _super.prototype.isScopeBoundary.call(this, node) + || node.kind === 195 /* DoStatement */ + || node.kind === 196 /* WhileStatement */ + || node.kind === 197 /* ForStatement */ + || node.kind === 198 /* ForInStatement */ + || node.kind === 199 /* ForOfStatement */ + || node.kind === 203 /* WithStatement */ + || node.kind === 204 /* SwitchStatement */ + || (node.parent != null + && (node.parent.kind === 207 /* TryStatement */ + || node.parent.kind === 194 /* IfStatement */)); + }; + return BlockScopeAwareRuleWalker; +})(scopeAwareRuleWalker_1.ScopeAwareRuleWalker); +exports.BlockScopeAwareRuleWalker = BlockScopeAwareRuleWalker; diff --git a/lib/language/walker/index.d.ts b/lib/language/walker/index.d.ts new file mode 100644 index 00000000000..3ebe7c6135b --- /dev/null +++ b/lib/language/walker/index.d.ts @@ -0,0 +1,5 @@ +export * from "./blockScopeAwareRuleWalker"; +export * from "./ruleWalker"; +export * from "./scopeAwareRuleWalker"; +export * from "./skippableTokenAwareRuleWalker"; +export * from "./syntaxWalker"; diff --git a/lib/language/walker/index.js b/lib/language/walker/index.js new file mode 100644 index 00000000000..692f805cc10 --- /dev/null +++ b/lib/language/walker/index.js @@ -0,0 +1,8 @@ +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./blockScopeAwareRuleWalker")); +__export(require("./ruleWalker")); +__export(require("./scopeAwareRuleWalker")); +__export(require("./skippableTokenAwareRuleWalker")); +__export(require("./syntaxWalker")); diff --git a/lib/language/walker/ruleWalker.d.ts b/lib/language/walker/ruleWalker.d.ts new file mode 100644 index 00000000000..cd8898c84b4 --- /dev/null +++ b/lib/language/walker/ruleWalker.d.ts @@ -0,0 +1,22 @@ +import * as Lint from "../../lint"; +import { SyntaxWalker } from "./syntaxWalker"; +import * as ts from "typescript"; +export declare class RuleWalker extends SyntaxWalker { + private limit; + private position; + private options; + private failures; + private sourceFile; + private disabledIntervals; + private ruleName; + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); + getSourceFile(): ts.SourceFile; + getFailures(): Lint.RuleFailure[]; + getLimit(): number; + getOptions(): any; + hasOption(option: string): boolean; + skip(node: ts.Node): void; + createFailure(start: number, width: number, failure: string): Lint.RuleFailure; + addFailure(failure: Lint.RuleFailure): void; + private existsFailure(failure); +} diff --git a/lib/language/walker/ruleWalker.js b/lib/language/walker/ruleWalker.js new file mode 100644 index 00000000000..3a504f08420 --- /dev/null +++ b/lib/language/walker/ruleWalker.js @@ -0,0 +1,74 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../../lint"); +var syntaxWalker_1 = require("./syntaxWalker"); +var RuleWalker = (function (_super) { + __extends(RuleWalker, _super); + function RuleWalker(sourceFile, options) { + _super.call(this); + this.position = 0; + this.failures = []; + this.options = options.ruleArguments; + this.sourceFile = sourceFile; + this.limit = this.sourceFile.getFullWidth(); + this.disabledIntervals = options.disabledIntervals; + this.ruleName = options.ruleName; + } + RuleWalker.prototype.getSourceFile = function () { + return this.sourceFile; + }; + RuleWalker.prototype.getFailures = function () { + return this.failures; + }; + RuleWalker.prototype.getLimit = function () { + return this.limit; + }; + RuleWalker.prototype.getOptions = function () { + return this.options; + }; + RuleWalker.prototype.hasOption = function (option) { + if (this.options) { + return this.options.indexOf(option) !== -1; + } + else { + return false; + } + }; + RuleWalker.prototype.skip = function (node) { + this.position += node.getFullWidth(); + }; + RuleWalker.prototype.createFailure = function (start, width, failure) { + var from = (start > this.limit) ? this.limit : start; + var to = ((start + width) > this.limit) ? this.limit : (start + width); + return new Lint.RuleFailure(this.sourceFile, from, to, failure, this.ruleName); + }; + RuleWalker.prototype.addFailure = function (failure) { + // don't add failures for a rule if the failure intersects an interval where that rule is disabled + if (!this.existsFailure(failure) && !Lint.doesIntersect(failure, this.disabledIntervals)) { + this.failures.push(failure); + } + }; + RuleWalker.prototype.existsFailure = function (failure) { + return this.failures.some(function (f) { return f.equals(failure); }); + }; + return RuleWalker; +})(syntaxWalker_1.SyntaxWalker); +exports.RuleWalker = RuleWalker; diff --git a/lib/language/walker/scopeAwareRuleWalker.d.ts b/lib/language/walker/scopeAwareRuleWalker.d.ts new file mode 100644 index 00000000000..7043f13f9e3 --- /dev/null +++ b/lib/language/walker/scopeAwareRuleWalker.d.ts @@ -0,0 +1,14 @@ +import { RuleWalker } from "./ruleWalker"; +import * as ts from "typescript"; +export declare abstract class ScopeAwareRuleWalker extends RuleWalker { + private scopeStack; + constructor(sourceFile: ts.SourceFile, options?: any); + abstract createScope(): T; + getCurrentScope(): T; + getAllScopes(): T[]; + getCurrentDepth(): number; + onScopeStart(): void; + onScopeEnd(): void; + protected visitNode(node: ts.Node): void; + protected isScopeBoundary(node: ts.Node): boolean; +} diff --git a/lib/language/walker/scopeAwareRuleWalker.js b/lib/language/walker/scopeAwareRuleWalker.js new file mode 100644 index 00000000000..24f4eecfb7a --- /dev/null +++ b/lib/language/walker/scopeAwareRuleWalker.js @@ -0,0 +1,62 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ruleWalker_1 = require("./ruleWalker"); +var ts = require("typescript"); +var ScopeAwareRuleWalker = (function (_super) { + __extends(ScopeAwareRuleWalker, _super); + function ScopeAwareRuleWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + // initialize stack with global scope + this.scopeStack = [this.createScope()]; + } + ScopeAwareRuleWalker.prototype.getCurrentScope = function () { + return this.scopeStack[this.scopeStack.length - 1]; + }; + // get all scopes available at this depth + ScopeAwareRuleWalker.prototype.getAllScopes = function () { + return this.scopeStack.slice(); + }; + ScopeAwareRuleWalker.prototype.getCurrentDepth = function () { + return this.scopeStack.length; + }; + // callback notifier when a scope begins + ScopeAwareRuleWalker.prototype.onScopeStart = function () { + return; + }; + // callback notifier when a scope ends + ScopeAwareRuleWalker.prototype.onScopeEnd = function () { + return; + }; + ScopeAwareRuleWalker.prototype.visitNode = function (node) { + var isNewScope = this.isScopeBoundary(node); + if (isNewScope) { + this.scopeStack.push(this.createScope()); + } + this.onScopeStart(); + _super.prototype.visitNode.call(this, node); + this.onScopeEnd(); + if (isNewScope) { + this.scopeStack.pop(); + } + }; + ScopeAwareRuleWalker.prototype.isScopeBoundary = function (node) { + return node.kind === 211 /* FunctionDeclaration */ + || node.kind === 171 /* FunctionExpression */ + || node.kind === 243 /* PropertyAssignment */ + || node.kind === 244 /* ShorthandPropertyAssignment */ + || node.kind === 141 /* MethodDeclaration */ + || node.kind === 142 /* Constructor */ + || node.kind === 216 /* ModuleDeclaration */ + || node.kind === 172 /* ArrowFunction */ + || node.kind === 170 /* ParenthesizedExpression */ + || node.kind === 212 /* ClassDeclaration */ + || node.kind === 213 /* InterfaceDeclaration */ + || node.kind === 143 /* GetAccessor */ + || node.kind === 144 /* SetAccessor */; + }; + return ScopeAwareRuleWalker; +})(ruleWalker_1.RuleWalker); +exports.ScopeAwareRuleWalker = ScopeAwareRuleWalker; diff --git a/lib/language/walker/skippableTokenAwareRuleWalker.d.ts b/lib/language/walker/skippableTokenAwareRuleWalker.d.ts new file mode 100644 index 00000000000..eb01f0087c0 --- /dev/null +++ b/lib/language/walker/skippableTokenAwareRuleWalker.d.ts @@ -0,0 +1,13 @@ +import * as Lint from "../../lint"; +import { RuleWalker } from "./ruleWalker"; +import * as ts from "typescript"; +export declare class SkippableTokenAwareRuleWalker extends RuleWalker { + protected tokensToSkipStartEndMap: { + [start: number]: number; + }; + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); + protected visitRegularExpressionLiteral(node: ts.Node): void; + protected visitIdentifier(node: ts.Identifier): void; + protected visitTemplateExpression(node: ts.TemplateExpression): void; + protected addTokenToSkipFromNode(node: ts.Node): void; +} diff --git a/lib/language/walker/skippableTokenAwareRuleWalker.js b/lib/language/walker/skippableTokenAwareRuleWalker.js new file mode 100644 index 00000000000..bf23c288bfb --- /dev/null +++ b/lib/language/walker/skippableTokenAwareRuleWalker.js @@ -0,0 +1,33 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var ruleWalker_1 = require("./ruleWalker"); +var SkippableTokenAwareRuleWalker = (function (_super) { + __extends(SkippableTokenAwareRuleWalker, _super); + function SkippableTokenAwareRuleWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + this.tokensToSkipStartEndMap = {}; + } + SkippableTokenAwareRuleWalker.prototype.visitRegularExpressionLiteral = function (node) { + this.addTokenToSkipFromNode(node); + _super.prototype.visitRegularExpressionLiteral.call(this, node); + }; + SkippableTokenAwareRuleWalker.prototype.visitIdentifier = function (node) { + this.addTokenToSkipFromNode(node); + _super.prototype.visitIdentifier.call(this, node); + }; + SkippableTokenAwareRuleWalker.prototype.visitTemplateExpression = function (node) { + this.addTokenToSkipFromNode(node); + _super.prototype.visitTemplateExpression.call(this, node); + }; + SkippableTokenAwareRuleWalker.prototype.addTokenToSkipFromNode = function (node) { + if (node.getStart() < node.getEnd()) { + // only add to the map nodes whose end comes after their start, to prevent infinite loops + this.tokensToSkipStartEndMap[node.getStart()] = node.getEnd(); + } + }; + return SkippableTokenAwareRuleWalker; +})(ruleWalker_1.RuleWalker); +exports.SkippableTokenAwareRuleWalker = SkippableTokenAwareRuleWalker; diff --git a/lib/language/walker/syntaxWalker.d.ts b/lib/language/walker/syntaxWalker.d.ts new file mode 100644 index 00000000000..d4254f6ae21 --- /dev/null +++ b/lib/language/walker/syntaxWalker.d.ts @@ -0,0 +1,71 @@ +import * as ts from "typescript"; +export declare class SyntaxWalker { + walk(node: ts.Node): void; + protected visitAnyKeyword(node: ts.Node): void; + protected visitArrowFunction(node: ts.FunctionLikeDeclaration): void; + protected visitBinaryExpression(node: ts.BinaryExpression): void; + protected visitBindingElement(node: ts.BindingElement): void; + protected visitBlock(node: ts.Block): void; + protected visitBreakStatement(node: ts.BreakOrContinueStatement): void; + protected visitCallExpression(node: ts.CallExpression): void; + protected visitCallSignature(node: ts.SignatureDeclaration): void; + protected visitCaseClause(node: ts.CaseClause): void; + protected visitClassDeclaration(node: ts.ClassDeclaration): void; + protected visitCatchClause(node: ts.CatchClause): void; + protected visitConditionalExpression(node: ts.ConditionalExpression): void; + protected visitConstructorDeclaration(node: ts.ConstructorDeclaration): void; + protected visitConstructorType(node: ts.FunctionOrConstructorTypeNode): void; + protected visitContinueStatement(node: ts.BreakOrContinueStatement): void; + protected visitDebuggerStatement(node: ts.Statement): void; + protected visitDefaultClause(node: ts.DefaultClause): void; + protected visitDoStatement(node: ts.DoStatement): void; + protected visitElementAccessExpression(node: ts.ElementAccessExpression): void; + protected visitEnumDeclaration(node: ts.EnumDeclaration): void; + protected visitExportAssignment(node: ts.ExportAssignment): void; + protected visitExpressionStatement(node: ts.ExpressionStatement): void; + protected visitForStatement(node: ts.ForStatement): void; + protected visitForInStatement(node: ts.ForInStatement): void; + protected visitForOfStatement(node: ts.ForOfStatement): void; + protected visitFunctionDeclaration(node: ts.FunctionDeclaration): void; + protected visitFunctionExpression(node: ts.FunctionExpression): void; + protected visitFunctionType(node: ts.FunctionOrConstructorTypeNode): void; + protected visitGetAccessor(node: ts.AccessorDeclaration): void; + protected visitIdentifier(node: ts.Identifier): void; + protected visitIfStatement(node: ts.IfStatement): void; + protected visitImportDeclaration(node: ts.ImportDeclaration): void; + protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration): void; + protected visitIndexSignatureDeclaration(node: ts.IndexSignatureDeclaration): void; + protected visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void; + protected visitJsxElement(node: ts.JsxElement): void; + protected visitJsxSelfClosingElement(node: ts.JsxSelfClosingElement): void; + protected visitLabeledStatement(node: ts.LabeledStatement): void; + protected visitMethodDeclaration(node: ts.MethodDeclaration): void; + protected visitMethodSignature(node: ts.SignatureDeclaration): void; + protected visitModuleDeclaration(node: ts.ModuleDeclaration): void; + protected visitNamedImports(node: ts.NamedImports): void; + protected visitNamespaceImport(node: ts.NamespaceImport): void; + protected visitNewExpression(node: ts.NewExpression): void; + protected visitObjectLiteralExpression(node: ts.ObjectLiteralExpression): void; + protected visitParameterDeclaration(node: ts.ParameterDeclaration): void; + protected visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression): void; + protected visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression): void; + protected visitPropertyAccessExpression(node: ts.PropertyAccessExpression): void; + protected visitPropertyAssignment(node: ts.PropertyAssignment): void; + protected visitPropertyDeclaration(node: ts.PropertyDeclaration): void; + protected visitPropertySignature(node: ts.Node): void; + protected visitRegularExpressionLiteral(node: ts.Node): void; + protected visitReturnStatement(node: ts.ReturnStatement): void; + protected visitSetAccessor(node: ts.AccessorDeclaration): void; + protected visitSourceFile(node: ts.SourceFile): void; + protected visitSwitchStatement(node: ts.SwitchStatement): void; + protected visitTemplateExpression(node: ts.TemplateExpression): void; + protected visitThrowStatement(node: ts.ThrowStatement): void; + protected visitTryStatement(node: ts.TryStatement): void; + protected visitTypeAssertionExpression(node: ts.TypeAssertion): void; + protected visitTypeLiteral(node: ts.TypeLiteralNode): void; + protected visitVariableDeclaration(node: ts.VariableDeclaration): void; + protected visitVariableStatement(node: ts.VariableStatement): void; + protected visitWhileStatement(node: ts.WhileStatement): void; + protected visitNode(node: ts.Node): void; + protected walkChildren(node: ts.Node): void; +} diff --git a/lib/language/walker/syntaxWalker.js b/lib/language/walker/syntaxWalker.js new file mode 100644 index 00000000000..09029a36167 --- /dev/null +++ b/lib/language/walker/syntaxWalker.js @@ -0,0 +1,429 @@ +/* + * 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. + */ +var ts = require("typescript"); +var SyntaxWalker = (function () { + function SyntaxWalker() { + } + SyntaxWalker.prototype.walk = function (node) { + this.visitNode(node); + }; + SyntaxWalker.prototype.visitAnyKeyword = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitArrowFunction = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitBinaryExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitBindingElement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitBlock = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitBreakStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitCallExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitCallSignature = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitCaseClause = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitClassDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitCatchClause = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitConditionalExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitConstructorDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitConstructorType = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitContinueStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitDebuggerStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitDefaultClause = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitDoStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitElementAccessExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitEnumDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitExportAssignment = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitExpressionStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitForStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitForInStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitForOfStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitFunctionDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitFunctionExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitFunctionType = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitGetAccessor = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitIdentifier = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitIfStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitImportDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitImportEqualsDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitIndexSignatureDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitInterfaceDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitJsxElement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitJsxSelfClosingElement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitLabeledStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitMethodDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitMethodSignature = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitModuleDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitNamedImports = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitNamespaceImport = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitNewExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitObjectLiteralExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitParameterDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPostfixUnaryExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPrefixUnaryExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPropertyAccessExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPropertyAssignment = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPropertyDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitPropertySignature = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitRegularExpressionLiteral = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitReturnStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitSetAccessor = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitSourceFile = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitSwitchStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitTemplateExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitThrowStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitTryStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitTypeAssertionExpression = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitTypeLiteral = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitVariableDeclaration = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitVariableStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitWhileStatement = function (node) { + this.walkChildren(node); + }; + SyntaxWalker.prototype.visitNode = function (node) { + switch (node.kind) { + case 115 /* AnyKeyword */: + this.visitAnyKeyword(node); + break; + case 161 /* BindingElement */: + this.visitBindingElement(node); + break; + case 172 /* ArrowFunction */: + this.visitArrowFunction(node); + break; + case 179 /* BinaryExpression */: + this.visitBinaryExpression(node); + break; + case 161 /* BindingElement */: + this.visitBindingElement(node); + break; + case 190 /* Block */: + this.visitBlock(node); + break; + case 201 /* BreakStatement */: + this.visitBreakStatement(node); + break; + case 166 /* CallExpression */: + this.visitCallExpression(node); + break; + case 145 /* CallSignature */: + this.visitCallSignature(node); + break; + case 239 /* CaseClause */: + this.visitCaseClause(node); + break; + case 212 /* ClassDeclaration */: + this.visitClassDeclaration(node); + break; + case 242 /* CatchClause */: + this.visitCatchClause(node); + break; + case 180 /* ConditionalExpression */: + this.visitConditionalExpression(node); + break; + case 142 /* Constructor */: + this.visitConstructorDeclaration(node); + break; + case 151 /* ConstructorType */: + this.visitConstructorType(node); + break; + case 200 /* ContinueStatement */: + this.visitContinueStatement(node); + break; + case 208 /* DebuggerStatement */: + this.visitDebuggerStatement(node); + break; + case 240 /* DefaultClause */: + this.visitDefaultClause(node); + break; + case 195 /* DoStatement */: + this.visitDoStatement(node); + break; + case 165 /* ElementAccessExpression */: + this.visitElementAccessExpression(node); + break; + case 215 /* EnumDeclaration */: + this.visitEnumDeclaration(node); + break; + case 225 /* ExportAssignment */: + this.visitExportAssignment(node); + break; + case 193 /* ExpressionStatement */: + this.visitExpressionStatement(node); + break; + case 197 /* ForStatement */: + this.visitForStatement(node); + break; + case 198 /* ForInStatement */: + this.visitForInStatement(node); + break; + case 199 /* ForOfStatement */: + this.visitForOfStatement(node); + break; + case 211 /* FunctionDeclaration */: + this.visitFunctionDeclaration(node); + break; + case 171 /* FunctionExpression */: + this.visitFunctionExpression(node); + break; + case 150 /* FunctionType */: + this.visitFunctionType(node); + break; + case 143 /* GetAccessor */: + this.visitGetAccessor(node); + break; + case 67 /* Identifier */: + this.visitIdentifier(node); + break; + case 194 /* IfStatement */: + this.visitIfStatement(node); + break; + case 220 /* ImportDeclaration */: + this.visitImportDeclaration(node); + break; + case 219 /* ImportEqualsDeclaration */: + this.visitImportEqualsDeclaration(node); + break; + case 147 /* IndexSignature */: + this.visitIndexSignatureDeclaration(node); + break; + case 213 /* InterfaceDeclaration */: + this.visitInterfaceDeclaration(node); + break; + case 231 /* JsxElement */: + this.visitJsxElement(node); + break; + case 232 /* JsxSelfClosingElement */: + this.visitJsxSelfClosingElement(node); + break; + case 205 /* LabeledStatement */: + this.visitLabeledStatement(node); + break; + case 141 /* MethodDeclaration */: + this.visitMethodDeclaration(node); + break; + case 140 /* MethodSignature */: + this.visitMethodSignature(node); + break; + case 216 /* ModuleDeclaration */: + this.visitModuleDeclaration(node); + break; + case 223 /* NamedImports */: + this.visitNamedImports(node); + break; + case 222 /* NamespaceImport */: + this.visitNamespaceImport(node); + break; + case 167 /* NewExpression */: + this.visitNewExpression(node); + break; + case 163 /* ObjectLiteralExpression */: + this.visitObjectLiteralExpression(node); + break; + case 136 /* Parameter */: + this.visitParameterDeclaration(node); + break; + case 178 /* PostfixUnaryExpression */: + this.visitPostfixUnaryExpression(node); + break; + case 177 /* PrefixUnaryExpression */: + this.visitPrefixUnaryExpression(node); + break; + case 164 /* PropertyAccessExpression */: + this.visitPropertyAccessExpression(node); + break; + case 243 /* PropertyAssignment */: + this.visitPropertyAssignment(node); + break; + case 139 /* PropertyDeclaration */: + this.visitPropertyDeclaration(node); + break; + case 138 /* PropertySignature */: + this.visitPropertySignature(node); + break; + case 10 /* RegularExpressionLiteral */: + this.visitRegularExpressionLiteral(node); + break; + case 202 /* ReturnStatement */: + this.visitReturnStatement(node); + break; + case 144 /* SetAccessor */: + this.visitSetAccessor(node); + break; + case 246 /* SourceFile */: + this.visitSourceFile(node); + break; + case 204 /* SwitchStatement */: + this.visitSwitchStatement(node); + break; + case 181 /* TemplateExpression */: + this.visitTemplateExpression(node); + break; + case 206 /* ThrowStatement */: + this.visitThrowStatement(node); + break; + case 207 /* TryStatement */: + this.visitTryStatement(node); + break; + case 169 /* TypeAssertionExpression */: + this.visitTypeAssertionExpression(node); + break; + case 153 /* TypeLiteral */: + this.visitTypeLiteral(node); + break; + case 209 /* VariableDeclaration */: + this.visitVariableDeclaration(node); + break; + case 191 /* VariableStatement */: + this.visitVariableStatement(node); + break; + case 196 /* WhileStatement */: + this.visitWhileStatement(node); + break; + default: + this.walkChildren(node); + break; + } + }; + SyntaxWalker.prototype.walkChildren = function (node) { + var _this = this; + ts.forEachChild(node, function (child) { return _this.visitNode(child); }); + }; + return SyntaxWalker; +})(); +exports.SyntaxWalker = SyntaxWalker; diff --git a/lib/lint.d.ts b/lib/lint.d.ts new file mode 100644 index 00000000000..6c603664cc9 --- /dev/null +++ b/lib/lint.d.ts @@ -0,0 +1,14 @@ +import * as formatters from "./formatters"; +import * as configuration from "./configuration"; +import * as rules from "./rules"; +export * from "./language/rule/rule"; +export * from "./enableDisableRules"; +export * from "./formatterLoader"; +export * from "./ruleLoader"; +export * from "./language/utils"; +export * from "./language/languageServiceHost"; +export * from "./language/walker"; +export * from "./language/formatter/formatter"; +export declare var Formatters: typeof formatters; +export declare var Configuration: typeof configuration; +export declare var Rules: typeof rules; diff --git a/lib/lint.js b/lib/lint.js new file mode 100644 index 00000000000..fc9ad72c5a5 --- /dev/null +++ b/lib/lint.js @@ -0,0 +1,17 @@ +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +var formatters = require("./formatters"); +var configuration = require("./configuration"); +var rules = require("./rules"); +__export(require("./language/rule/rule")); +__export(require("./enableDisableRules")); +__export(require("./formatterLoader")); +__export(require("./ruleLoader")); +__export(require("./language/utils")); +__export(require("./language/languageServiceHost")); +__export(require("./language/walker")); +__export(require("./language/formatter/formatter")); +exports.Formatters = formatters; +exports.Configuration = configuration; +exports.Rules = rules; diff --git a/lib/ruleLoader.d.ts b/lib/ruleLoader.d.ts new file mode 100644 index 00000000000..9842b59a2b1 --- /dev/null +++ b/lib/ruleLoader.d.ts @@ -0,0 +1,11 @@ +import * as Lint from "./lint"; +export interface IEnableDisablePosition { + isEnabled: boolean; + position: number; +} +export declare function loadRules(ruleConfiguration: { + [name: string]: any; +}, enableDisableRuleMap: { + [rulename: string]: Lint.IEnableDisablePosition[]; +}, rulesDirectory?: string): Lint.IRule[]; +export declare function findRule(name: string, rulesDirectory?: string): any; diff --git a/lib/ruleLoader.js b/lib/ruleLoader.js new file mode 100644 index 00000000000..9ebe13c480c --- /dev/null +++ b/lib/ruleLoader.js @@ -0,0 +1,140 @@ +/* +* 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. +*/ +var fs = require("fs"); +var path = require("path"); +var underscore_string_1 = require("underscore.string"); +var moduleDirectory = path.dirname(module.filename); +var CORE_RULES_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "rules"); +function loadRules(ruleConfiguration, enableDisableRuleMap, rulesDirectory) { + var rules = []; + for (var ruleName in ruleConfiguration) { + if (ruleConfiguration.hasOwnProperty(ruleName)) { + var ruleValue = ruleConfiguration[ruleName]; + var Rule = findRule(ruleName, rulesDirectory); + if (Rule !== undefined) { + var all = "all"; // make the linter happy until we can turn it on and off + var allList = (all in enableDisableRuleMap ? enableDisableRuleMap[all] : []); + var ruleSpecificList = (ruleName in enableDisableRuleMap ? enableDisableRuleMap[ruleName] : []); + var disabledIntervals = buildDisabledIntervalsFromSwitches(ruleSpecificList, allList); + rules.push(new Rule(ruleName, ruleValue, disabledIntervals)); + } + } + } + return rules; +} +exports.loadRules = loadRules; +function findRule(name, rulesDirectory) { + var camelizedName = transformName(name); + // first check for core rules + var Rule = loadRule(CORE_RULES_DIRECTORY, camelizedName); + if (Rule) { + return Rule; + } + // then check for rules within the first level of rulesDirectory + if (rulesDirectory) { + Rule = loadRule(rulesDirectory, camelizedName); + if (Rule) { + return Rule; + } + } + // finally check for rules within the first level of directories, + // using dash prefixes as the sub-directory names + if (rulesDirectory) { + var subDirectory = underscore_string_1.strLeft(rulesDirectory, "-"); + var ruleName = underscore_string_1.strRight(rulesDirectory, "-"); + if (subDirectory !== rulesDirectory && ruleName !== rulesDirectory) { + camelizedName = transformName(ruleName); + Rule = loadRule(rulesDirectory, subDirectory, camelizedName); + if (Rule) { + return Rule; + } + } + } + return undefined; +} +exports.findRule = findRule; +function transformName(name) { + // camelize strips out leading and trailing underscores and dashes, so make sure they aren't passed to camelize + // the regex matches the groups (leading underscores and dashes)(other characters)(trailing underscores and dashes) + var nameMatch = name.match(/^([-_]*)(.*?)([-_]*)$/); + if (nameMatch == null) { + return name + "Rule"; + } + return nameMatch[1] + underscore_string_1.camelize(nameMatch[2]) + nameMatch[3] + "Rule"; +} +function loadRule() { + var paths = []; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; + } + var rulePath = paths.reduce(function (p, c) { return path.join(p, c); }, ""); + var fullPath = path.resolve(moduleDirectory, rulePath); + if (fs.existsSync(fullPath + ".js")) { + var ruleModule = require(fullPath); + if (ruleModule && ruleModule.Rule) { + return ruleModule.Rule; + } + } + return undefined; +} +/* + * We're assuming both lists are already sorted top-down so compare the tops, use the smallest of the two, + * and build the intervals that way. + */ +function buildDisabledIntervalsFromSwitches(ruleSpecificList, allList) { + var isCurrentlyDisabled = false; + var disabledStartPosition; + var disabledIntervalList = []; + var i = 0; + var j = 0; + while (i < ruleSpecificList.length || j < allList.length) { + var ruleSpecificTopPositon = (i < ruleSpecificList.length ? ruleSpecificList[i].position : Infinity); + var allTopPositon = (j < allList.length ? allList[j].position : Infinity); + var newPositionToCheck = void 0; + if (ruleSpecificTopPositon < allTopPositon) { + newPositionToCheck = ruleSpecificList[i]; + i++; + } + else { + newPositionToCheck = allList[j]; + j++; + } + // we're currently disabled and enabling, or currently enabled and disabling -- a switch + if (newPositionToCheck.isEnabled === isCurrentlyDisabled) { + if (!isCurrentlyDisabled) { + // start a new interval + disabledStartPosition = newPositionToCheck.position; + isCurrentlyDisabled = true; + } + else { + // we're currently disabled and about to enable -- end the interval + disabledIntervalList.push({ + endPosition: newPositionToCheck.position, + startPosition: disabledStartPosition + }); + isCurrentlyDisabled = false; + } + } + } + if (isCurrentlyDisabled) { + // we started an interval but didn't finish one -- so finish it with an Infinity + disabledIntervalList.push({ + endPosition: Infinity, + startPosition: disabledStartPosition + }); + } + return disabledIntervalList; +} diff --git a/lib/rules.d.ts b/lib/rules.d.ts new file mode 100644 index 00000000000..afbb322733c --- /dev/null +++ b/lib/rules.d.ts @@ -0,0 +1 @@ +export * from "./language/rule/abstractRule"; diff --git a/lib/rules.js b/lib/rules.js new file mode 100644 index 00000000000..4013af469a4 --- /dev/null +++ b/lib/rules.js @@ -0,0 +1,4 @@ +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +} +__export(require("./language/rule/abstractRule")); diff --git a/lib/rules/alignRule.d.ts b/lib/rules/alignRule.d.ts new file mode 100644 index 00000000000..9ffc1f979cb --- /dev/null +++ b/lib/rules/alignRule.d.ts @@ -0,0 +1,9 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static PARAMETERS_OPTION: string; + static ARGUMENTS_OPTION: string; + static STATEMENTS_OPTION: string; + static FAILURE_STRING_SUFFIX: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/alignRule.js b/lib/rules/alignRule.js new file mode 100644 index 00000000000..d265d63b02a --- /dev/null +++ b/lib/rules/alignRule.js @@ -0,0 +1,92 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var alignWalker = new AlignWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(alignWalker); + }; + Rule.PARAMETERS_OPTION = "parameters"; + Rule.ARGUMENTS_OPTION = "arguments"; + Rule.STATEMENTS_OPTION = "statements"; + Rule.FAILURE_STRING_SUFFIX = " are not aligned"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var AlignWalker = (function (_super) { + __extends(AlignWalker, _super); + function AlignWalker() { + _super.apply(this, arguments); + } + AlignWalker.prototype.visitConstructorDeclaration = function (node) { + this.checkAlignment(Rule.PARAMETERS_OPTION, node.parameters); + _super.prototype.visitConstructorDeclaration.call(this, node); + }; + AlignWalker.prototype.visitFunctionDeclaration = function (node) { + this.checkAlignment(Rule.PARAMETERS_OPTION, node.parameters); + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + AlignWalker.prototype.visitFunctionExpression = function (node) { + this.checkAlignment(Rule.PARAMETERS_OPTION, node.parameters); + _super.prototype.visitFunctionExpression.call(this, node); + }; + AlignWalker.prototype.visitMethodDeclaration = function (node) { + this.checkAlignment(Rule.PARAMETERS_OPTION, node.parameters); + _super.prototype.visitMethodDeclaration.call(this, node); + }; + AlignWalker.prototype.visitCallExpression = function (node) { + this.checkAlignment(Rule.ARGUMENTS_OPTION, node.arguments); + _super.prototype.visitCallExpression.call(this, node); + }; + AlignWalker.prototype.visitNewExpression = function (node) { + this.checkAlignment(Rule.ARGUMENTS_OPTION, node.arguments); + _super.prototype.visitNewExpression.call(this, node); + }; + AlignWalker.prototype.visitBlock = function (node) { + this.checkAlignment(Rule.STATEMENTS_OPTION, node.statements); + _super.prototype.visitBlock.call(this, node); + }; + AlignWalker.prototype.checkAlignment = function (kind, nodes) { + if (nodes == null || nodes.length === 0 || !this.hasOption(kind)) { + return; + } + var prevPos = this.getPosition(nodes[0]); + var alignToColumn = prevPos.character; + // skip first node in list + for (var _i = 0, _a = nodes.slice(1); _i < _a.length; _i++) { + var node = _a[_i]; + var curPos = this.getPosition(node); + if (curPos.line !== prevPos.line && curPos.character !== alignToColumn) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), kind + Rule.FAILURE_STRING_SUFFIX)); + break; + } + prevPos = curPos; + } + }; + AlignWalker.prototype.getPosition = function (node) { + return node.getSourceFile().getLineAndCharacterOfPosition(node.getStart()); + }; + return AlignWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/banRule.d.ts b/lib/rules/banRule.d.ts new file mode 100644 index 00000000000..6bc781f7716 --- /dev/null +++ b/lib/rules/banRule.d.ts @@ -0,0 +1,11 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_PART: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class BanFunctionWalker extends Lint.RuleWalker { + private bannedFunctions; + addBannedFunction(bannedFunction: string[]): void; + visitCallExpression(node: ts.CallExpression): void; +} diff --git a/lib/rules/banRule.js b/lib/rules/banRule.js new file mode 100644 index 00000000000..851e05d3f91 --- /dev/null +++ b/lib/rules/banRule.js @@ -0,0 +1,73 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var options = this.getOptions(); + var banFunctionWalker = new BanFunctionWalker(sourceFile, options); + var functionsToBan = options.ruleArguments; + functionsToBan.forEach(function (functionToBan) { + banFunctionWalker.addBannedFunction(functionToBan); + }); + return this.applyWithWalker(banFunctionWalker); + }; + Rule.FAILURE_STRING_PART = "function invocation disallowed: "; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var BanFunctionWalker = (function (_super) { + __extends(BanFunctionWalker, _super); + function BanFunctionWalker() { + _super.apply(this, arguments); + this.bannedFunctions = []; + } + BanFunctionWalker.prototype.addBannedFunction = function (bannedFunction) { + this.bannedFunctions.push(bannedFunction); + }; + BanFunctionWalker.prototype.visitCallExpression = function (node) { + var _this = this; + var expression = node.expression; + if (expression.kind === 164 /* PropertyAccessExpression */ && + expression.getChildCount() >= 3) { + var firstToken = expression.getFirstToken(); + var secondToken = expression.getChildAt(1); + var thirdToken = expression.getChildAt(2); + var firstText = firstToken.getText(); + var thirdText = thirdToken.getFullText(); + if (secondToken.kind === 21 /* DotToken */) { + this.bannedFunctions.forEach(function (bannedFunction) { + if (firstText === bannedFunction[0] && thirdText === bannedFunction[1]) { + var failure = _this.createFailure(expression.getStart(), expression.getWidth(), Rule.FAILURE_STRING_PART + firstText + "." + thirdText); + _this.addFailure(failure); + } + }); + } + } + _super.prototype.visitCallExpression.call(this, node); + }; + return BanFunctionWalker; +})(Lint.RuleWalker); +exports.BanFunctionWalker = BanFunctionWalker; diff --git a/lib/rules/classNameRule.d.ts b/lib/rules/classNameRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/classNameRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/classNameRule.js b/lib/rules/classNameRule.js new file mode 100644 index 00000000000..fc2f92771fc --- /dev/null +++ b/lib/rules/classNameRule.js @@ -0,0 +1,68 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NameWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "name must be in pascal case"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NameWalker = (function (_super) { + __extends(NameWalker, _super); + function NameWalker() { + _super.apply(this, arguments); + } + NameWalker.prototype.visitClassDeclaration = function (node) { + // classes declared as default exports will be unnamed + if (node.name != null) { + var className = node.name.getText(); + if (!this.isPascalCased(className)) { + this.addFailureAt(node.name.getStart(), node.name.getWidth()); + } + } + _super.prototype.visitClassDeclaration.call(this, node); + }; + NameWalker.prototype.visitInterfaceDeclaration = function (node) { + var interfaceName = node.name.getText(); + if (!this.isPascalCased(interfaceName)) { + this.addFailureAt(node.name.getStart(), node.name.getWidth()); + } + _super.prototype.visitInterfaceDeclaration.call(this, node); + }; + NameWalker.prototype.isPascalCased = function (name) { + if (name.length <= 0) { + return true; + } + var firstCharacter = name.charAt(0); + return ((firstCharacter === firstCharacter.toUpperCase()) && name.indexOf("_") === -1); + }; + NameWalker.prototype.addFailureAt = function (position, width) { + var failure = this.createFailure(position, width, Rule.FAILURE_STRING); + this.addFailure(failure); + }; + return NameWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/commentFormatRule.d.ts b/lib/rules/commentFormatRule.d.ts new file mode 100644 index 00000000000..a06861ef5ae --- /dev/null +++ b/lib/rules/commentFormatRule.d.ts @@ -0,0 +1,8 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static LOWERCASE_FAILURE: string; + static UPPERCASE_FAILURE: string; + static LEADING_SPACE_FAILURE: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/commentFormatRule.js b/lib/rules/commentFormatRule.js new file mode 100644 index 00000000000..853e1b742d8 --- /dev/null +++ b/lib/rules/commentFormatRule.js @@ -0,0 +1,116 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_SPACE = "check-space"; +var OPTION_LOWERCASE = "check-lowercase"; +var OPTION_UPPERCASE = "check-uppercase"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new CommentWalker(sourceFile, this.getOptions())); + }; + Rule.LOWERCASE_FAILURE = "comment must start with lowercase letter"; + Rule.UPPERCASE_FAILURE = "comment must start with uppercase letter"; + Rule.LEADING_SPACE_FAILURE = "comment must start with a space"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var CommentWalker = (function (_super) { + __extends(CommentWalker, _super); + function CommentWalker() { + _super.apply(this, arguments); + } + CommentWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + Lint.scanAllTokens(ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text), function (scanner) { + var startPos = scanner.getStartPos(); + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + return; + } + if (scanner.getToken() === 2 /* SingleLineCommentTrivia */) { + var commentText = scanner.getTokenText(); + var startPosition = scanner.getTokenPos() + 2; + var width = commentText.length - 2; + if (_this.hasOption(OPTION_SPACE)) { + if (!_this.startsWithSpace(commentText)) { + var leadingSpaceFailure = _this.createFailure(startPosition, width, Rule.LEADING_SPACE_FAILURE); + _this.addFailure(leadingSpaceFailure); + } + } + if (_this.hasOption(OPTION_LOWERCASE)) { + if (!_this.startsWithLowercase(commentText)) { + var lowercaseFailure = _this.createFailure(startPosition, width, Rule.LOWERCASE_FAILURE); + _this.addFailure(lowercaseFailure); + } + } + if (_this.hasOption(OPTION_UPPERCASE)) { + if (!_this.startsWithUppercase(commentText)) { + var uppercaseFailure = _this.createFailure(startPosition, width, Rule.UPPERCASE_FAILURE); + _this.addFailure(uppercaseFailure); + } + } + } + }); + }; + CommentWalker.prototype.startsWithSpace = function (commentText) { + if (commentText.length <= 2) { + return true; // comment is "//"? Technically not a violation. + } + // whitelist //#region and //#endregion + if ((/^#(end)?region/).test(commentText.substring(2))) { + return true; + } + var firstCharacter = commentText.charAt(2); // first character after the space + // three slashes (///) also works, to allow for /// + return firstCharacter === " " || firstCharacter === "/"; + }; + CommentWalker.prototype.startsWithLowercase = function (commentText) { + return this.startsWith(commentText, function (c) { return c.toLowerCase(); }); + }; + CommentWalker.prototype.startsWithUppercase = function (commentText) { + return this.startsWith(commentText, function (c) { return c.toUpperCase(); }); + }; + CommentWalker.prototype.startsWith = function (commentText, changeCase) { + if (commentText.length <= 2) { + return true; // comment is "//"? Technically not a violation. + } + // regex is "start of string"//"any amount of whitespace"("word character") + var firstCharacterMatch = commentText.match(/^\/\/\s*(\w)/); + if (firstCharacterMatch != null) { + // the first group matched, i.e. the thing in the parens, is the first non-space character, if it's alphanumeric + var firstCharacter = firstCharacterMatch[1]; + return firstCharacter === changeCase(firstCharacter); + } + else { + // first character isn't alphanumeric/doesn't exist? Technically not a violation + return true; + } + }; + return CommentWalker; +})(Lint.SkippableTokenAwareRuleWalker); diff --git a/lib/rules/curlyRule.d.ts b/lib/rules/curlyRule.d.ts new file mode 100644 index 00000000000..3448646fa7b --- /dev/null +++ b/lib/rules/curlyRule.d.ts @@ -0,0 +1,10 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static DO_FAILURE_STRING: string; + static ELSE_FAILURE_STRING: string; + static FOR_FAILURE_STRING: string; + static IF_FAILURE_STRING: string; + static WHILE_FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/curlyRule.js b/lib/rules/curlyRule.js new file mode 100644 index 00000000000..6e2ea252682 --- /dev/null +++ b/lib/rules/curlyRule.js @@ -0,0 +1,94 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new CurlyWalker(sourceFile, this.getOptions())); + }; + Rule.DO_FAILURE_STRING = "do statements must be braced"; + Rule.ELSE_FAILURE_STRING = "else statements must be braced"; + Rule.FOR_FAILURE_STRING = "for statements must be braced"; + Rule.IF_FAILURE_STRING = "if statements must be braced"; + Rule.WHILE_FAILURE_STRING = "while statements must be braced"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var CurlyWalker = (function (_super) { + __extends(CurlyWalker, _super); + function CurlyWalker() { + _super.apply(this, arguments); + } + CurlyWalker.prototype.visitForInStatement = function (node) { + if (!this.isStatementBraced(node.statement)) { + this.addFailureForNode(node, Rule.FOR_FAILURE_STRING); + } + _super.prototype.visitForInStatement.call(this, node); + }; + CurlyWalker.prototype.visitForOfStatement = function (node) { + if (!this.isStatementBraced(node.statement)) { + this.addFailureForNode(node, Rule.FOR_FAILURE_STRING); + } + _super.prototype.visitForInStatement.call(this, node); + }; + CurlyWalker.prototype.visitForStatement = function (node) { + if (!this.isStatementBraced(node.statement)) { + this.addFailureForNode(node, Rule.FOR_FAILURE_STRING); + } + _super.prototype.visitForStatement.call(this, node); + }; + CurlyWalker.prototype.visitIfStatement = function (node) { + if (!this.isStatementBraced(node.thenStatement)) { + this.addFailure(this.createFailure(node.getStart(), node.thenStatement.getEnd() - node.getStart(), Rule.IF_FAILURE_STRING)); + } + if (node.elseStatement != null + && node.elseStatement.kind !== 194 /* IfStatement */ + && !this.isStatementBraced(node.elseStatement)) { + // find the else keyword to place the error appropriately + var elseKeywordNode = node.getChildren().filter(function (child) { return child.kind === 78 /* ElseKeyword */; })[0]; + this.addFailure(this.createFailure(elseKeywordNode.getStart(), node.elseStatement.getEnd() - elseKeywordNode.getStart(), Rule.ELSE_FAILURE_STRING)); + } + _super.prototype.visitIfStatement.call(this, node); + }; + CurlyWalker.prototype.visitDoStatement = function (node) { + if (!this.isStatementBraced(node.statement)) { + this.addFailureForNode(node, Rule.DO_FAILURE_STRING); + } + _super.prototype.visitDoStatement.call(this, node); + }; + CurlyWalker.prototype.visitWhileStatement = function (node) { + if (!this.isStatementBraced(node.statement)) { + this.addFailureForNode(node, Rule.WHILE_FAILURE_STRING); + } + _super.prototype.visitWhileStatement.call(this, node); + }; + CurlyWalker.prototype.isStatementBraced = function (node) { + return node.kind === 190 /* Block */; + }; + CurlyWalker.prototype.addFailureForNode = function (node, failure) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), failure)); + }; + return CurlyWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/eoflineRule.d.ts b/lib/rules/eoflineRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/eoflineRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/eoflineRule.js b/lib/rules/eoflineRule.js new file mode 100644 index 00000000000..8df46593305 --- /dev/null +++ b/lib/rules/eoflineRule.js @@ -0,0 +1,45 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + if (sourceFile.text === "") { + // if the file is empty, it "ends with a newline", so don't return a failure + return []; + } + var eofToken = sourceFile.endOfFileToken; + var eofTokenFullText = eofToken.getFullText(); + if (eofTokenFullText.length === 0 || eofTokenFullText.charAt(eofTokenFullText.length - 1) !== "\n") { + var start = eofToken.getStart(); + return [ + new Lint.RuleFailure(sourceFile, start, start, Rule.FAILURE_STRING, this.getOptions().ruleName) + ]; + } + return []; + }; + Rule.FAILURE_STRING = "file should end with a newline"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; diff --git a/lib/rules/forinRule.d.ts b/lib/rules/forinRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/forinRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/forinRule.js b/lib/rules/forinRule.js new file mode 100644 index 00000000000..e9b8aab25c7 --- /dev/null +++ b/lib/rules/forinRule.js @@ -0,0 +1,87 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new ForInWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "for (... in ...) statements must be filtered with an if statement"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var ForInWalker = (function (_super) { + __extends(ForInWalker, _super); + function ForInWalker() { + _super.apply(this, arguments); + } + ForInWalker.prototype.visitForInStatement = function (node) { + this.handleForInStatement(node); + _super.prototype.visitForInStatement.call(this, node); + }; + ForInWalker.prototype.handleForInStatement = function (node) { + var statement = node.statement; + var statementKind = node.statement.kind; + // a direct if statement under a for...in is valid + if (statementKind === 194 /* IfStatement */) { + return; + } + // if there is a block, verify that it has a single if statement or starts with if (..) continue; + if (statementKind === 190 /* Block */) { + var blockNode = statement; + var blockStatements = blockNode.statements; + if (blockStatements.length >= 1) { + var firstBlockStatement = blockStatements[0]; + if (firstBlockStatement.kind === 194 /* IfStatement */) { + // if this "if" statement is the only statement within the block + if (blockStatements.length === 1) { + return; + } + // if this "if" statement has a single continue block + var ifStatement = firstBlockStatement.thenStatement; + if (nodeIsContinue(ifStatement)) { + return; + } + } + } + } + var failure = this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING); + this.addFailure(failure); + }; + return ForInWalker; +})(Lint.RuleWalker); +function nodeIsContinue(node) { + var kind = node.kind; + if (kind === 200 /* ContinueStatement */) { + return true; + } + if (kind === 190 /* Block */) { + var blockStatements = node.statements; + if (blockStatements.length === 1 && blockStatements[0].kind === 200 /* ContinueStatement */) { + return true; + } + } + return false; +} diff --git a/lib/rules/indentRule.d.ts b/lib/rules/indentRule.d.ts new file mode 100644 index 00000000000..0d8d7e87fdc --- /dev/null +++ b/lib/rules/indentRule.d.ts @@ -0,0 +1,7 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_TABS: string; + static FAILURE_STRING_SPACES: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/indentRule.js b/lib/rules/indentRule.js new file mode 100644 index 00000000000..67b4fa2b0ca --- /dev/null +++ b/lib/rules/indentRule.js @@ -0,0 +1,95 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_USE_TABS = "tabs"; +var OPTION_USE_SPACES = "spaces"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new IndentWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING_TABS = "tab indentation expected"; + Rule.FAILURE_STRING_SPACES = "space indentation expected"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +// visit every token and enforce that only the right character is used for indentation +var IndentWalker = (function (_super) { + __extends(IndentWalker, _super); + function IndentWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + if (this.hasOption(OPTION_USE_TABS)) { + this.regExp = new RegExp(" "); + this.failureString = Rule.FAILURE_STRING_TABS; + } + else if (this.hasOption(OPTION_USE_SPACES)) { + this.regExp = new RegExp("\t"); + this.failureString = Rule.FAILURE_STRING_SPACES; + } + } + IndentWalker.prototype.visitSourceFile = function (node) { + if (!this.hasOption(OPTION_USE_TABS) && !this.hasOption(OPTION_USE_SPACES)) { + // if we don't have either option, no need to check anything, and no need to call super, so just return + return; + } + var endOfComment = -1; + var scanner = ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text); + for (var _i = 0, _a = node.getLineStarts(); _i < _a.length; _i++) { + var lineStart = _a[_i]; + if (lineStart < endOfComment) { + // skip checking lines inside multi-line comments + continue; + } + scanner.setTextPos(lineStart); + var currentScannedType = scanner.scan(); + var fullLeadingWhitespace = ""; + var lastStartPos = -1; + while (currentScannedType === 5 /* WhitespaceTrivia */) { + var startPos = scanner.getStartPos(); + if (startPos === lastStartPos) { + break; + } + lastStartPos = startPos; + fullLeadingWhitespace += scanner.getTokenText(); + currentScannedType = scanner.scan(); + } + var commentRanges = ts.getTrailingCommentRanges(node.text, lineStart); + if (commentRanges) { + endOfComment = commentRanges[commentRanges.length - 1].end; + } + if (currentScannedType === 2 /* SingleLineCommentTrivia */ + || currentScannedType === 3 /* MultiLineCommentTrivia */ + || currentScannedType === 4 /* NewLineTrivia */) { + // ignore lines that have comments before the first token + continue; + } + if (fullLeadingWhitespace.match(this.regExp)) { + this.addFailure(this.createFailure(lineStart, fullLeadingWhitespace.length, this.failureString)); + } + } + // no need to call super to visit the rest of the nodes, so don't call super here + }; + return IndentWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/interfaceNameRule.d.ts b/lib/rules/interfaceNameRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/interfaceNameRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/interfaceNameRule.js b/lib/rules/interfaceNameRule.js new file mode 100644 index 00000000000..069a3804533 --- /dev/null +++ b/lib/rules/interfaceNameRule.js @@ -0,0 +1,58 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NameWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "interface name must be a capitalized I"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NameWalker = (function (_super) { + __extends(NameWalker, _super); + function NameWalker() { + _super.apply(this, arguments); + } + NameWalker.prototype.visitInterfaceDeclaration = function (node) { + var interfaceName = node.name.text; + if (!this.startsWithI(interfaceName)) { + this.addFailureAt(node.name.getStart(), node.name.getWidth()); + } + _super.prototype.visitInterfaceDeclaration.call(this, node); + }; + NameWalker.prototype.startsWithI = function (name) { + if (name.length <= 0) { + return true; + } + var firstCharacter = name.charAt(0); + return (firstCharacter === "I"); + }; + NameWalker.prototype.addFailureAt = function (position, width) { + var failure = this.createFailure(position, width, Rule.FAILURE_STRING); + this.addFailure(failure); + }; + return NameWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/jsdocFormatRule.d.ts b/lib/rules/jsdocFormatRule.d.ts new file mode 100644 index 00000000000..c189c457ab3 --- /dev/null +++ b/lib/rules/jsdocFormatRule.d.ts @@ -0,0 +1,7 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static ALIGNMENT_FAILURE_STRING: string; + static FORMAT_FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/jsdocFormatRule.js b/lib/rules/jsdocFormatRule.js new file mode 100644 index 00000000000..8d5bed620fb --- /dev/null +++ b/lib/rules/jsdocFormatRule.js @@ -0,0 +1,113 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new JsdocWalker(sourceFile, this.getOptions())); + }; + Rule.ALIGNMENT_FAILURE_STRING = "asterisks in jsdoc must be aligned"; + Rule.FORMAT_FAILURE_STRING = "jsdoc is not formatted correctly on this line"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var JsdocWalker = (function (_super) { + __extends(JsdocWalker, _super); + function JsdocWalker() { + _super.apply(this, arguments); + } + JsdocWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + Lint.scanAllTokens(ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text), function (scanner) { + var startPos = scanner.getStartPos(); + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + return; + } + if (scanner.getToken() === 3 /* MultiLineCommentTrivia */) { + var commentText = scanner.getTokenText(); + var startPosition = scanner.getTokenPos(); + _this.findFailuresForJsdocComment(commentText, startPosition, node); + } + }); + }; + JsdocWalker.prototype.findFailuresForJsdocComment = function (commentText, startingPosition, sourceFile) { + var currentPosition = startingPosition; + // the file may be different depending on the OS it was originally authored on + // can't rely on require('os').EOL or process.platform as that is the execution env + // regex is: split optionally on \r\n, but alwasy split on \n if no \r exists + var lines = commentText.split(/\r?\n/); + var firstLine = lines[0]; + var jsdocPosition = currentPosition; + // regex is: start of string, followed by any amount of whitespace, followed by /** + var isJsdocMatch = firstLine.match(/^\s*\/\*\*/); + if (isJsdocMatch != null) { + if (lines.length === 1) { + var firstLineMatch = firstLine.match(/^\s*\/\*\* (.* )?\*\/$/); + if (firstLineMatch == null) { + this.addFailureAt(jsdocPosition, firstLine.length, Rule.FORMAT_FAILURE_STRING); + } + return; + } + var indexToMatch = firstLine.indexOf("**") + sourceFile.getLineAndCharacterOfPosition(currentPosition).character; + // all lines but the first and last + var otherLines = lines.splice(1, lines.length - 2); + jsdocPosition += firstLine.length + 1; // + 1 for the splitted-out newline + for (var _i = 0; _i < otherLines.length; _i++) { + var line = otherLines[_i]; + // regex is: start of string, followed by any amount of whitespace, followed by *, + // followed by either a space or the end of the string + var asteriskMatch = line.match(/^\s*\*( |$)/); + if (asteriskMatch == null) { + this.addFailureAt(jsdocPosition, line.length, Rule.FORMAT_FAILURE_STRING); + } + var asteriskIndex = line.indexOf("*"); + if (asteriskIndex !== indexToMatch) { + this.addFailureAt(jsdocPosition, line.length, Rule.ALIGNMENT_FAILURE_STRING); + } + jsdocPosition += line.length + 1; // + 1 for the splitted-out newline + } + var lastLine = lines[lines.length - 1]; + // regex is: start of string, followed by any amount of whitespace, followed by */, + // followed by the end of the string + var endBlockCommentMatch = lastLine.match(/^\s*\*\/$/); + if (endBlockCommentMatch == null) { + this.addFailureAt(jsdocPosition, lastLine.length, Rule.FORMAT_FAILURE_STRING); + } + var lastAsteriskIndex = lastLine.indexOf("*"); + if (lastAsteriskIndex !== indexToMatch) { + this.addFailureAt(jsdocPosition, lastLine.length, Rule.ALIGNMENT_FAILURE_STRING); + } + } + }; + JsdocWalker.prototype.addFailureAt = function (currentPosition, width, failureString) { + var failure = this.createFailure(currentPosition, width, failureString); + this.addFailure(failure); + }; + return JsdocWalker; +})(Lint.SkippableTokenAwareRuleWalker); diff --git a/lib/rules/labelPositionRule.d.ts b/lib/rules/labelPositionRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/labelPositionRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/labelPositionRule.js b/lib/rules/labelPositionRule.js new file mode 100644 index 00000000000..5c0c85cbb23 --- /dev/null +++ b/lib/rules/labelPositionRule.js @@ -0,0 +1,53 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new LabelPositionWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "unexpected label on statement"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var LabelPositionWalker = (function (_super) { + __extends(LabelPositionWalker, _super); + function LabelPositionWalker() { + _super.apply(this, arguments); + } + LabelPositionWalker.prototype.visitLabeledStatement = function (node) { + var statement = node.statement; + if (statement.kind !== 195 /* DoStatement */ + && statement.kind !== 197 /* ForStatement */ + && statement.kind !== 198 /* ForInStatement */ + && statement.kind !== 196 /* WhileStatement */ + && statement.kind !== 204 /* SwitchStatement */) { + var failure = this.createFailure(node.label.getStart(), node.label.getWidth(), Rule.FAILURE_STRING); + this.addFailure(failure); + } + _super.prototype.visitLabeledStatement.call(this, node); + }; + return LabelPositionWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/labelUndefinedRule.d.ts b/lib/rules/labelUndefinedRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/labelUndefinedRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/labelUndefinedRule.js b/lib/rules/labelUndefinedRule.js new file mode 100644 index 00000000000..8459153e90e --- /dev/null +++ b/lib/rules/labelUndefinedRule.js @@ -0,0 +1,65 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. +*/ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new LabelUndefinedWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "undefined label: '"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var LabelUndefinedWalker = (function (_super) { + __extends(LabelUndefinedWalker, _super); + function LabelUndefinedWalker() { + _super.apply(this, arguments); + } + LabelUndefinedWalker.prototype.createScope = function () { + return {}; + }; + LabelUndefinedWalker.prototype.visitLabeledStatement = function (node) { + var label = node.label.text; + var currentScope = this.getCurrentScope(); + currentScope[label] = true; + _super.prototype.visitLabeledStatement.call(this, node); + }; + LabelUndefinedWalker.prototype.visitBreakStatement = function (node) { + this.validateLabelAt(node.label, node.getStart(), node.getChildAt(0).getWidth()); + _super.prototype.visitBreakStatement.call(this, node); + }; + LabelUndefinedWalker.prototype.visitContinueStatement = function (node) { + this.validateLabelAt(node.label, node.getStart(), node.getChildAt(0).getWidth()); + _super.prototype.visitContinueStatement.call(this, node); + }; + LabelUndefinedWalker.prototype.validateLabelAt = function (label, position, width) { + var currentScope = this.getCurrentScope(); + if (label != null && !currentScope[label.text]) { + var failureString = Rule.FAILURE_STRING + label.text + "'"; + var failure = this.createFailure(position, width, failureString); + this.addFailure(failure); + } + }; + return LabelUndefinedWalker; +})(Lint.ScopeAwareRuleWalker); diff --git a/lib/rules/maxLineLengthRule.d.ts b/lib/rules/maxLineLengthRule.d.ts new file mode 100644 index 00000000000..55379f870b5 --- /dev/null +++ b/lib/rules/maxLineLengthRule.d.ts @@ -0,0 +1,7 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + isEnabled(): boolean; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/maxLineLengthRule.js b/lib/rules/maxLineLengthRule.js new file mode 100644 index 00000000000..d17e1d61608 --- /dev/null +++ b/lib/rules/maxLineLengthRule.js @@ -0,0 +1,62 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.isEnabled = function () { + if (_super.prototype.isEnabled.call(this)) { + var option = this.getOptions().ruleArguments[0]; + if (typeof option === "number" && option > 0) { + return true; + } + } + return false; + }; + Rule.prototype.apply = function (sourceFile) { + var ruleFailures = []; + var lineLimit = this.getOptions().ruleArguments[0]; + var lineStarts = sourceFile.getLineStarts(); + var errorString = Rule.FAILURE_STRING + lineLimit; + var disabledIntervals = this.getOptions().disabledIntervals; + var source = sourceFile.getFullText(); + for (var i = 0; i < lineStarts.length - 1; ++i) { + var from = lineStarts[i], to = lineStarts[i + 1]; + if ((to - from - 1) > lineLimit && !((to - from - 2) === lineLimit && source[to - 2] === "\r")) { + // first condition above is whether the line (minus the newline) is larger than the line limit + // second two check for windows line endings, that is, check to make sure it is not the case + // that we are only over by the limit by exactly one and that the character we are over the + // limit by is a '\r' character which does not count against the limit + // (and thus we are not actually over the limit). + var ruleFailure = new Lint.RuleFailure(sourceFile, from, to - 1, errorString, this.getOptions().ruleName); + if (!Lint.doesIntersect(ruleFailure, disabledIntervals)) { + ruleFailures.push(ruleFailure); + } + } + } + return ruleFailures; + }; + Rule.FAILURE_STRING = "exceeds maximum line length of "; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; diff --git a/lib/rules/memberAccessRule.d.ts b/lib/rules/memberAccessRule.d.ts new file mode 100644 index 00000000000..9e86e07652f --- /dev/null +++ b/lib/rules/memberAccessRule.d.ts @@ -0,0 +1,12 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class MemberAccessWalker extends Lint.RuleWalker { + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); + visitMethodDeclaration(node: ts.MethodDeclaration): void; + visitPropertyDeclaration(node: ts.PropertyDeclaration): void; + private validateVisibilityModifiers(node); +} diff --git a/lib/rules/memberAccessRule.js b/lib/rules/memberAccessRule.js new file mode 100644 index 00000000000..8fa7a228a0b --- /dev/null +++ b/lib/rules/memberAccessRule.js @@ -0,0 +1,54 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new MemberAccessWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "default access modifier on member/method not allowed"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var MemberAccessWalker = (function (_super) { + __extends(MemberAccessWalker, _super); + function MemberAccessWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + } + MemberAccessWalker.prototype.visitMethodDeclaration = function (node) { + this.validateVisibilityModifiers(node); + }; + MemberAccessWalker.prototype.visitPropertyDeclaration = function (node) { + this.validateVisibilityModifiers(node); + }; + MemberAccessWalker.prototype.validateVisibilityModifiers = function (node) { + var hasAnyVisibilityModifiers = Lint.hasModifier(node.modifiers, 110 /* PublicKeyword */, 108 /* PrivateKeyword */, 109 /* ProtectedKeyword */); + if (!hasAnyVisibilityModifiers) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + }; + return MemberAccessWalker; +})(Lint.RuleWalker); +exports.MemberAccessWalker = MemberAccessWalker; diff --git a/lib/rules/memberOrderingRule.d.ts b/lib/rules/memberOrderingRule.d.ts new file mode 100644 index 00000000000..defb4265a31 --- /dev/null +++ b/lib/rules/memberOrderingRule.d.ts @@ -0,0 +1,19 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class MemberOrderingWalker extends Lint.RuleWalker { + private previousMember; + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); + visitClassDeclaration(node: ts.ClassDeclaration): void; + visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void; + visitMethodDeclaration(node: ts.MethodDeclaration): void; + visitMethodSignature(node: ts.SignatureDeclaration): void; + visitPropertyDeclaration(node: ts.PropertyDeclaration): void; + visitPropertySignature(node: ts.Node): void; + visitTypeLiteral(node: ts.TypeLiteralNode): void; + private resetPreviousModifiers(); + private checkModifiersAndSetPrevious(node, currentMember); + private canAppearAfter(previousMember, currentMember); +} diff --git a/lib/rules/memberOrderingRule.js b/lib/rules/memberOrderingRule.js new file mode 100644 index 00000000000..e28214a26c7 --- /dev/null +++ b/lib/rules/memberOrderingRule.js @@ -0,0 +1,115 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_VARIABLES_BEFORE_FUNCTIONS = "variables-before-functions"; +var OPTION_STATIC_BEFORE_INSTANCE = "static-before-instance"; +var OPTION_PUBLIC_BEFORE_PRIVATE = "public-before-private"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new MemberOrderingWalker(sourceFile, this.getOptions())); + }; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +function getModifiers(isMethod, modifiers) { + return { + isInstance: !Lint.hasModifier(modifiers, 111 /* StaticKeyword */), + isMethod: isMethod, + isPrivate: Lint.hasModifier(modifiers, 108 /* PrivateKeyword */) + }; +} +function toString(modifiers) { + return [ + modifiers.isPrivate ? "private" : "public", + modifiers.isInstance ? "instance" : "static", + "member", + modifiers.isMethod ? "function" : "variable" + ].join(" "); +} +var MemberOrderingWalker = (function (_super) { + __extends(MemberOrderingWalker, _super); + function MemberOrderingWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + } + MemberOrderingWalker.prototype.visitClassDeclaration = function (node) { + this.resetPreviousModifiers(); + _super.prototype.visitClassDeclaration.call(this, node); + }; + MemberOrderingWalker.prototype.visitInterfaceDeclaration = function (node) { + this.resetPreviousModifiers(); + _super.prototype.visitInterfaceDeclaration.call(this, node); + }; + MemberOrderingWalker.prototype.visitMethodDeclaration = function (node) { + this.checkModifiersAndSetPrevious(node, getModifiers(true, node.modifiers)); + _super.prototype.visitMethodDeclaration.call(this, node); + }; + MemberOrderingWalker.prototype.visitMethodSignature = function (node) { + this.checkModifiersAndSetPrevious(node, getModifiers(true, node.modifiers)); + _super.prototype.visitMethodSignature.call(this, node); + }; + MemberOrderingWalker.prototype.visitPropertyDeclaration = function (node) { + this.checkModifiersAndSetPrevious(node, getModifiers(false, node.modifiers)); + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + MemberOrderingWalker.prototype.visitPropertySignature = function (node) { + this.checkModifiersAndSetPrevious(node, getModifiers(false, node.modifiers)); + _super.prototype.visitPropertySignature.call(this, node); + }; + MemberOrderingWalker.prototype.visitTypeLiteral = function (node) { + // don't call super from here -- we want to skip the property declarations in type literals + }; + MemberOrderingWalker.prototype.resetPreviousModifiers = function () { + this.previousMember = { + isInstance: false, + isMethod: false, + isPrivate: false + }; + }; + MemberOrderingWalker.prototype.checkModifiersAndSetPrevious = function (node, currentMember) { + if (!this.canAppearAfter(this.previousMember, currentMember)) { + var failure = this.createFailure(node.getStart(), node.getWidth(), "Declaration of " + toString(currentMember) + " not allowed to appear after declaration of " + toString(this.previousMember)); + this.addFailure(failure); + } + this.previousMember = currentMember; + }; + MemberOrderingWalker.prototype.canAppearAfter = function (previousMember, currentMember) { + if (previousMember == null || currentMember == null) { + return true; + } + if (this.hasOption(OPTION_VARIABLES_BEFORE_FUNCTIONS) && previousMember.isMethod !== currentMember.isMethod) { + return Number(previousMember.isMethod) < Number(currentMember.isMethod); + } + if (this.hasOption(OPTION_STATIC_BEFORE_INSTANCE) && previousMember.isInstance !== currentMember.isInstance) { + return Number(previousMember.isInstance) < Number(currentMember.isInstance); + } + if (this.hasOption(OPTION_PUBLIC_BEFORE_PRIVATE) && previousMember.isPrivate !== currentMember.isPrivate) { + return Number(previousMember.isPrivate) < Number(currentMember.isPrivate); + } + return true; + }; + return MemberOrderingWalker; +})(Lint.RuleWalker); +exports.MemberOrderingWalker = MemberOrderingWalker; diff --git a/lib/rules/noAnyRule.d.ts b/lib/rules/noAnyRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noAnyRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noAnyRule.js b/lib/rules/noAnyRule.js new file mode 100644 index 00000000000..c3c712315d9 --- /dev/null +++ b/lib/rules/noAnyRule.js @@ -0,0 +1,44 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker((new NoAnyWalker(sourceFile, this.getOptions()))); + }; + Rule.FAILURE_STRING = "type decoration of 'any' is forbidden"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoAnyWalker = (function (_super) { + __extends(NoAnyWalker, _super); + function NoAnyWalker() { + _super.apply(this, arguments); + } + NoAnyWalker.prototype.visitAnyKeyword = function (node) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + _super.prototype.visitAnyKeyword.call(this, node); + }; + return NoAnyWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noArgRule.d.ts b/lib/rules/noArgRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noArgRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noArgRule.js b/lib/rules/noArgRule.js new file mode 100644 index 00000000000..b7b6362bc29 --- /dev/null +++ b/lib/rules/noArgRule.js @@ -0,0 +1,52 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoArgWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "access forbidden to arguments property"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoArgWalker = (function (_super) { + __extends(NoArgWalker, _super); + function NoArgWalker() { + _super.apply(this, arguments); + } + NoArgWalker.prototype.visitPropertyAccessExpression = function (node) { + var expression = node.expression; + var name = node.name; + if (expression.kind === 67 /* Identifier */ && name.text === "callee") { + var identifierExpression = expression; + if (identifierExpression.text === "arguments") { + this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), Rule.FAILURE_STRING)); + } + } + _super.prototype.visitPropertyAccessExpression.call(this, node); + }; + return NoArgWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noBitwiseRule.d.ts b/lib/rules/noBitwiseRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noBitwiseRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noBitwiseRule.js b/lib/rules/noBitwiseRule.js new file mode 100644 index 00000000000..d56af3fdb4d --- /dev/null +++ b/lib/rules/noBitwiseRule.js @@ -0,0 +1,66 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoBitwiseWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "forbidden bitwise operation"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoBitwiseWalker = (function (_super) { + __extends(NoBitwiseWalker, _super); + function NoBitwiseWalker() { + _super.apply(this, arguments); + } + NoBitwiseWalker.prototype.visitBinaryExpression = function (node) { + switch (node.operatorToken.kind) { + case 45 /* AmpersandToken */: + case 64 /* AmpersandEqualsToken */: + case 46 /* BarToken */: + case 65 /* BarEqualsToken */: + case 47 /* CaretToken */: + case 66 /* CaretEqualsToken */: + case 42 /* LessThanLessThanToken */: + case 61 /* LessThanLessThanEqualsToken */: + case 43 /* GreaterThanGreaterThanToken */: + case 62 /* GreaterThanGreaterThanEqualsToken */: + case 44 /* GreaterThanGreaterThanGreaterThanToken */: + case 63 /* GreaterThanGreaterThanGreaterThanEqualsToken */: + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + break; + } + _super.prototype.visitBinaryExpression.call(this, node); + }; + NoBitwiseWalker.prototype.visitPrefixUnaryExpression = function (node) { + if (node.operator === 49 /* TildeToken */) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitPrefixUnaryExpression.call(this, node); + }; + return NoBitwiseWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noConditionalAssignmentRule.d.ts b/lib/rules/noConditionalAssignmentRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noConditionalAssignmentRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noConditionalAssignmentRule.js b/lib/rules/noConditionalAssignmentRule.js new file mode 100644 index 00000000000..ce41c1e5784 --- /dev/null +++ b/lib/rules/noConditionalAssignmentRule.js @@ -0,0 +1,85 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2015 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var walker = new NoConditionalAssignmentWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(walker); + }; + Rule.FAILURE_STRING = "assignment in conditional: "; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoConditionalAssignmentWalker = (function (_super) { + __extends(NoConditionalAssignmentWalker, _super); + function NoConditionalAssignmentWalker() { + _super.apply(this, arguments); + this.isInConditional = false; + } + NoConditionalAssignmentWalker.prototype.visitIfStatement = function (node) { + this.validateConditionalExpression(node.expression); + _super.prototype.visitIfStatement.call(this, node); + }; + NoConditionalAssignmentWalker.prototype.visitWhileStatement = function (node) { + this.validateConditionalExpression(node.expression); + _super.prototype.visitWhileStatement.call(this, node); + }; + NoConditionalAssignmentWalker.prototype.visitDoStatement = function (node) { + this.validateConditionalExpression(node.expression); + _super.prototype.visitWhileStatement.call(this, node); + }; + NoConditionalAssignmentWalker.prototype.visitForStatement = function (node) { + if (node.condition != null) { + this.validateConditionalExpression(node.condition); + } + _super.prototype.visitForStatement.call(this, node); + }; + NoConditionalAssignmentWalker.prototype.visitBinaryExpression = function (expression) { + if (this.isInConditional) { + this.checkForAssignment(expression); + } + _super.prototype.visitBinaryExpression.call(this, expression); + }; + NoConditionalAssignmentWalker.prototype.validateConditionalExpression = function (expression) { + this.isInConditional = true; + if (expression.kind === 179 /* BinaryExpression */) { + // check for simple assignment in a conditional, like `if (a = 1) {` + this.checkForAssignment(expression); + } + // walk the children of the conditional expression for nested assignments, like `if ((a = 1) && (b == 1)) {` + this.walkChildren(expression); + this.isInConditional = false; + }; + NoConditionalAssignmentWalker.prototype.checkForAssignment = function (expression) { + if (this.isAssignmentToken(expression.operatorToken)) { + this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), Rule.FAILURE_STRING)); + } + }; + NoConditionalAssignmentWalker.prototype.isAssignmentToken = function (token) { + return token.kind >= 55 /* FirstAssignment */ && token.kind <= 66 /* LastAssignment */; + }; + return NoConditionalAssignmentWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noConsecutiveBlankLinesRule.d.ts b/lib/rules/noConsecutiveBlankLinesRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noConsecutiveBlankLinesRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noConsecutiveBlankLinesRule.js b/lib/rules/noConsecutiveBlankLinesRule.js new file mode 100644 index 00000000000..c7821863f43 --- /dev/null +++ b/lib/rules/noConsecutiveBlankLinesRule.js @@ -0,0 +1,67 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new BlankLinesWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "consecutive blank lines are disallowed"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var BlankLinesWalker = (function (_super) { + __extends(BlankLinesWalker, _super); + function BlankLinesWalker() { + _super.apply(this, arguments); + } + BlankLinesWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + // starting with 1 to cover the case where the file starts with two blank lines + var newLinesInARowSeenSoFar = 1; + Lint.scanAllTokens(ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text), function (scanner) { + var startPos = scanner.getStartPos(); + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + newLinesInARowSeenSoFar = 0; + return; + } + if (scanner.getToken() === 4 /* NewLineTrivia */) { + newLinesInARowSeenSoFar += 1; + if (newLinesInARowSeenSoFar >= 3) { + var failure = _this.createFailure(scanner.getStartPos(), 1, Rule.FAILURE_STRING); + _this.addFailure(failure); + } + } + else { + newLinesInARowSeenSoFar = 0; + } + }); + }; + return BlankLinesWalker; +})(Lint.SkippableTokenAwareRuleWalker); diff --git a/lib/rules/noConsoleRule.d.ts b/lib/rules/noConsoleRule.d.ts new file mode 100644 index 00000000000..87e98100ad1 --- /dev/null +++ b/lib/rules/noConsoleRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +import BanRule = require("./banRule"); +export declare class Rule extends BanRule.Rule { + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noConsoleRule.js b/lib/rules/noConsoleRule.js new file mode 100644 index 00000000000..6dd65a609da --- /dev/null +++ b/lib/rules/noConsoleRule.js @@ -0,0 +1,23 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +var BanRule = require("./banRule"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var options = this.getOptions(); + var consoleBanWalker = new BanRule.BanFunctionWalker(sourceFile, this.getOptions()); + for (var _i = 0, _a = options.ruleArguments; _i < _a.length; _i++) { + var option = _a[_i]; + consoleBanWalker.addBannedFunction(["console", option]); + } + return this.applyWithWalker(consoleBanWalker); + }; + return Rule; +})(BanRule.Rule); +exports.Rule = Rule; diff --git a/lib/rules/noConstructRule.d.ts b/lib/rules/noConstructRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noConstructRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noConstructRule.js b/lib/rules/noConstructRule.js new file mode 100644 index 00000000000..c6f072817d7 --- /dev/null +++ b/lib/rules/noConstructRule.js @@ -0,0 +1,57 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoConstructWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "undesirable constructor use"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoConstructWalker = (function (_super) { + __extends(NoConstructWalker, _super); + function NoConstructWalker() { + _super.apply(this, arguments); + } + NoConstructWalker.prototype.visitNewExpression = function (node) { + if (node.expression.kind === 67 /* Identifier */) { + var identifier = node.expression; + var constructorName = identifier.text; + if (NoConstructWalker.FORBIDDEN_CONSTRUCTORS.indexOf(constructorName) !== -1) { + var failure = this.createFailure(node.getStart(), identifier.getEnd() - node.getStart(), Rule.FAILURE_STRING); + this.addFailure(failure); + } + } + _super.prototype.visitNewExpression.call(this, node); + }; + NoConstructWalker.FORBIDDEN_CONSTRUCTORS = [ + "Boolean", + "Number", + "String" + ]; + return NoConstructWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noConstructorVarsRule.d.ts b/lib/rules/noConstructorVarsRule.d.ts new file mode 100644 index 00000000000..e43da65548e --- /dev/null +++ b/lib/rules/noConstructorVarsRule.d.ts @@ -0,0 +1,9 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_PART: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class NoConstructorVariableDeclarationsWalker extends Lint.RuleWalker { + visitConstructorDeclaration(node: ts.ConstructorDeclaration): void; +} diff --git a/lib/rules/noConstructorVarsRule.js b/lib/rules/noConstructorVarsRule.js new file mode 100644 index 00000000000..570db0a66d9 --- /dev/null +++ b/lib/rules/noConstructorVarsRule.js @@ -0,0 +1,55 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoConstructorVariableDeclarationsWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING_PART = " cannot be declared in the constructor"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoConstructorVariableDeclarationsWalker = (function (_super) { + __extends(NoConstructorVariableDeclarationsWalker, _super); + function NoConstructorVariableDeclarationsWalker() { + _super.apply(this, arguments); + } + NoConstructorVariableDeclarationsWalker.prototype.visitConstructorDeclaration = function (node) { + var parameters = node.parameters; + for (var _i = 0; _i < parameters.length; _i++) { + var parameter = parameters[_i]; + if (parameter.modifiers != null && parameter.modifiers.length > 0) { + var name_1 = parameter.name; + var errorMessage = "'" + name_1.text + "'" + Rule.FAILURE_STRING_PART; + var lastModifier = parameter.modifiers[parameter.modifiers.length - 1]; + var position = lastModifier.getEnd() - parameter.getStart(); + this.addFailure(this.createFailure(parameter.getStart(), position, errorMessage)); + } + } + _super.prototype.visitConstructorDeclaration.call(this, node); + }; + return NoConstructorVariableDeclarationsWalker; +})(Lint.RuleWalker); +exports.NoConstructorVariableDeclarationsWalker = NoConstructorVariableDeclarationsWalker; diff --git a/lib/rules/noDebuggerRule.d.ts b/lib/rules/noDebuggerRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noDebuggerRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noDebuggerRule.js b/lib/rules/noDebuggerRule.js new file mode 100644 index 00000000000..f7763d038a0 --- /dev/null +++ b/lib/rules/noDebuggerRule.js @@ -0,0 +1,45 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoDebuggerWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "use of debugger statements is disallowed"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoDebuggerWalker = (function (_super) { + __extends(NoDebuggerWalker, _super); + function NoDebuggerWalker() { + _super.apply(this, arguments); + } + NoDebuggerWalker.prototype.visitDebuggerStatement = function (node) { + var debuggerKeywordNode = node.getChildAt(0); + this.addFailure(this.createFailure(debuggerKeywordNode.getStart(), debuggerKeywordNode.getWidth(), Rule.FAILURE_STRING)); + _super.prototype.visitDebuggerStatement.call(this, node); + }; + return NoDebuggerWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noDuplicateKeyRule.d.ts b/lib/rules/noDuplicateKeyRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noDuplicateKeyRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noDuplicateKeyRule.js b/lib/rules/noDuplicateKeyRule.js new file mode 100644 index 00000000000..cf45cd6efc8 --- /dev/null +++ b/lib/rules/noDuplicateKeyRule.js @@ -0,0 +1,62 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoDuplicateKeyWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "duplicate key '"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoDuplicateKeyWalker = (function (_super) { + __extends(NoDuplicateKeyWalker, _super); + function NoDuplicateKeyWalker() { + _super.apply(this, arguments); + this.objectKeysStack = []; + } + NoDuplicateKeyWalker.prototype.visitObjectLiteralExpression = function (node) { + this.objectKeysStack.push(Object.create(null)); + _super.prototype.visitObjectLiteralExpression.call(this, node); + this.objectKeysStack.pop(); + }; + NoDuplicateKeyWalker.prototype.visitPropertyAssignment = function (node) { + var objectKeys = this.objectKeysStack[this.objectKeysStack.length - 1]; + var keyNode = node.name; + if (keyNode.kind === 67 /* Identifier */) { + var key = keyNode.text; + if (objectKeys[key]) { + var failureString = Rule.FAILURE_STRING + key + "'"; + this.addFailure(this.createFailure(keyNode.getStart(), keyNode.getWidth(), failureString)); + } + else { + objectKeys[key] = true; + } + } + _super.prototype.visitPropertyAssignment.call(this, node); + }; + return NoDuplicateKeyWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noDuplicateVariableRule.d.ts b/lib/rules/noDuplicateVariableRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noDuplicateVariableRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noDuplicateVariableRule.js b/lib/rules/noDuplicateVariableRule.js new file mode 100644 index 00000000000..1cd3fd85fa0 --- /dev/null +++ b/lib/rules/noDuplicateVariableRule.js @@ -0,0 +1,95 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoDuplicateVariableWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "duplicate variable: '"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoDuplicateVariableWalker = (function (_super) { + __extends(NoDuplicateVariableWalker, _super); + function NoDuplicateVariableWalker() { + _super.apply(this, arguments); + } + NoDuplicateVariableWalker.prototype.createScope = function () { + return null; + }; + NoDuplicateVariableWalker.prototype.createBlockScope = function () { + return new ScopeInfo(); + }; + NoDuplicateVariableWalker.prototype.visitBindingElement = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + var isBlockScoped = Lint.isBlockScopedBindingElement(node); + // duplicate-variable errors for block-scoped vars are caught by tsc + if (isSingleVariable && !isBlockScoped) { + this.handleSingleVariableIdentifier(node.name); + } + _super.prototype.visitBindingElement.call(this, node); + }; + NoDuplicateVariableWalker.prototype.visitCatchClause = function (node) { + // don't visit the catch clause variable declaration, just visit the block + // the catch clause variable declaration has its own special scoping rules + this.visitBlock(node.block); + }; + NoDuplicateVariableWalker.prototype.visitMethodSignature = function (node) { + // don't call super, we don't want to walk method signatures either + }; + NoDuplicateVariableWalker.prototype.visitTypeLiteral = function (node) { + // don't call super, we don't want to walk the inside of type nodes + }; + NoDuplicateVariableWalker.prototype.visitVariableDeclaration = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + // destructuring is handled by this.visitBindingElement() + if (isSingleVariable && !Lint.isBlockScopedVariable(node)) { + this.handleSingleVariableIdentifier(node.name); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + NoDuplicateVariableWalker.prototype.handleSingleVariableIdentifier = function (variableIdentifier) { + var variableName = variableIdentifier.text; + var currentBlockScope = this.getCurrentBlockScope(); + if (currentBlockScope.varNames.indexOf(variableName) >= 0) { + this.addFailureOnIdentifier(variableIdentifier); + } + else { + currentBlockScope.varNames.push(variableName); + } + }; + NoDuplicateVariableWalker.prototype.addFailureOnIdentifier = function (ident) { + var failureString = "" + Rule.FAILURE_STRING + ident.text + "'"; + this.addFailure(this.createFailure(ident.getStart(), ident.getWidth(), failureString)); + }; + return NoDuplicateVariableWalker; +})(Lint.BlockScopeAwareRuleWalker); +var ScopeInfo = (function () { + function ScopeInfo() { + this.varNames = []; + } + return ScopeInfo; +})(); diff --git a/lib/rules/noEmptyRule.d.ts b/lib/rules/noEmptyRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noEmptyRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noEmptyRule.js b/lib/rules/noEmptyRule.js new file mode 100644 index 00000000000..d80d59a47d0 --- /dev/null +++ b/lib/rules/noEmptyRule.js @@ -0,0 +1,71 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new BlockWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "block is empty"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var BlockWalker = (function (_super) { + __extends(BlockWalker, _super); + function BlockWalker() { + _super.apply(this, arguments); + this.ignoredBlocks = []; + } + BlockWalker.prototype.visitBlock = function (node) { + var openBrace = node.getChildAt(0); + var closeBrace = node.getChildAt(node.getChildCount() - 1); + var sourceFileText = node.getSourceFile().text; + var hasCommentAfter = ts.getTrailingCommentRanges(sourceFileText, openBrace.getEnd()) != null; + var hasCommentBefore = ts.getLeadingCommentRanges(sourceFileText, closeBrace.getFullStart()) != null; + var isSkipped = this.ignoredBlocks.indexOf(node) !== -1; + if (node.statements.length <= 0 && !hasCommentAfter && !hasCommentBefore && !isSkipped) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitBlock.call(this, node); + }; + BlockWalker.prototype.visitConstructorDeclaration = function (node) { + var parameters = node.parameters; + var isSkipped = false; + for (var _i = 0; _i < parameters.length; _i++) { + var param = parameters[_i]; + var hasPropertyAccessModifier = Lint.hasModifier(param.modifiers, 108 /* PrivateKeyword */, 109 /* ProtectedKeyword */, 110 /* PublicKeyword */); + if (hasPropertyAccessModifier) { + isSkipped = true; + this.ignoredBlocks.push(node.body); + break; + } + if (isSkipped) { + break; + } + } + _super.prototype.visitConstructorDeclaration.call(this, node); + }; + return BlockWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noEvalRule.d.ts b/lib/rules/noEvalRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noEvalRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noEvalRule.js b/lib/rules/noEvalRule.js new file mode 100644 index 00000000000..a65fefaba23 --- /dev/null +++ b/lib/rules/noEvalRule.js @@ -0,0 +1,51 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoEvalWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "forbidden eval"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoEvalWalker = (function (_super) { + __extends(NoEvalWalker, _super); + function NoEvalWalker() { + _super.apply(this, arguments); + } + NoEvalWalker.prototype.visitCallExpression = function (node) { + var expression = node.expression; + if (expression.kind === 67 /* Identifier */) { + var expressionName = expression.text; + if (expressionName === "eval") { + this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), Rule.FAILURE_STRING)); + } + } + _super.prototype.visitCallExpression.call(this, node); + }; + return NoEvalWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noInferrableTypesRule.d.ts b/lib/rules/noInferrableTypesRule.d.ts new file mode 100644 index 00000000000..b0b50697cc1 --- /dev/null +++ b/lib/rules/noInferrableTypesRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_FACTORY: (type: string) => string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noInferrableTypesRule.js b/lib/rules/noInferrableTypesRule.js new file mode 100644 index 00000000000..9c791afee57 --- /dev/null +++ b/lib/rules/noInferrableTypesRule.js @@ -0,0 +1,80 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2015 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new InferrableTypeWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING_FACTORY = function (type) { return ("LHS type (" + type + ") inferred by RHS expression, remove type annotation"); }; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var InferrableTypeWalker = (function (_super) { + __extends(InferrableTypeWalker, _super); + function InferrableTypeWalker() { + _super.apply(this, arguments); + } + InferrableTypeWalker.prototype.visitVariableDeclaration = function (node) { + this.checkDeclaration(node); + _super.prototype.visitVariableDeclaration.call(this, node); + }; + InferrableTypeWalker.prototype.visitParameterDeclaration = function (node) { + this.checkDeclaration(node); + _super.prototype.visitParameterDeclaration.call(this, node); + }; + InferrableTypeWalker.prototype.checkDeclaration = function (node) { + if (node.type != null && node.initializer != null) { + var failure; + switch (node.type.kind) { + case 118 /* BooleanKeyword */: + if (node.initializer.kind === 97 /* TrueKeyword */ || node.initializer.kind === 82 /* FalseKeyword */) { + failure = "boolean"; + } + break; + case 126 /* NumberKeyword */: + if (node.initializer.kind === 8 /* NumericLiteral */) { + failure = "number"; + } + break; + case 128 /* StringKeyword */: + switch (node.initializer.kind) { + case 9 /* StringLiteral */: + case 11 /* NoSubstitutionTemplateLiteral */: + case 181 /* TemplateExpression */: + failure = "string"; + break; + default: + break; + } + break; + } + if (failure) { + this.addFailure(this.createFailure(node.type.getStart(), node.type.getWidth(), Rule.FAILURE_STRING_FACTORY(failure))); + } + } + }; + return InferrableTypeWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noInternalModuleRule.d.ts b/lib/rules/noInternalModuleRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noInternalModuleRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noInternalModuleRule.js b/lib/rules/noInternalModuleRule.js new file mode 100644 index 00000000000..3e55d7d5ebc --- /dev/null +++ b/lib/rules/noInternalModuleRule.js @@ -0,0 +1,59 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoInternalModuleWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "forbidden internal module"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoInternalModuleWalker = (function (_super) { + __extends(NoInternalModuleWalker, _super); + function NoInternalModuleWalker() { + _super.apply(this, arguments); + } + NoInternalModuleWalker.prototype.visitModuleDeclaration = function (node) { + if (this.isInternalModuleDeclaration(node)) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitModuleDeclaration.call(this, node); + }; + NoInternalModuleWalker.prototype.isInternalModuleDeclaration = function (node) { + // an internal module declaration is not a namespace or a nested declaration + // for external modules, node.name.kind will be a LiteralExpression instead of Identifier + return !Lint.isNodeFlagSet(node, 131072 /* Namespace */) + && !this.isNestedDeclaration(node) + && node.name.kind === 67 /* Identifier */; + }; + NoInternalModuleWalker.prototype.isNestedDeclaration = function (node) { + // in a declaration expression like 'module a.b.c' - 'a' is the top level module declaration node and 'b' and 'c' are nested + // therefore we can depend that a node's position will only match with its name's position for nested nodes + return node.name.pos === node.pos; + }; + return NoInternalModuleWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noRequireImportsRule.d.ts b/lib/rules/noRequireImportsRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noRequireImportsRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noRequireImportsRule.js b/lib/rules/noRequireImportsRule.js new file mode 100644 index 00000000000..bf4e1cd1d0f --- /dev/null +++ b/lib/rules/noRequireImportsRule.js @@ -0,0 +1,62 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2015 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. + */ +var Lint = require("../lint"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoRequireImportsWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "require() style import is forbidden"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoRequireImportsWalker = (function (_super) { + __extends(NoRequireImportsWalker, _super); + function NoRequireImportsWalker() { + _super.apply(this, arguments); + } + NoRequireImportsWalker.prototype.visitVariableStatement = function (node) { + var declarations = node.declarationList.declarations; + for (var _i = 0; _i < declarations.length; _i++) { + var decl = declarations[_i]; + this.handleDeclaration(decl); + } + _super.prototype.visitVariableStatement.call(this, node); + }; + NoRequireImportsWalker.prototype.visitImportEqualsDeclaration = function (node) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + _super.prototype.visitImportEqualsDeclaration.call(this, node); + }; + NoRequireImportsWalker.prototype.handleDeclaration = function (decl) { + // make sure the RHS is a call expression. + var call = (decl.initializer); + if (call && call.arguments && call.expression) { + var callExpressionText = call.expression.getText(this.getSourceFile()); + if (callExpressionText === "require") { + this.addFailure(this.createFailure(decl.getStart(), decl.getWidth(), Rule.FAILURE_STRING)); + } + } + }; + return NoRequireImportsWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noShadowedVariableRule.d.ts b/lib/rules/noShadowedVariableRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noShadowedVariableRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noShadowedVariableRule.js b/lib/rules/noShadowedVariableRule.js new file mode 100644 index 00000000000..46a836e67b1 --- /dev/null +++ b/lib/rules/noShadowedVariableRule.js @@ -0,0 +1,121 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoShadowedVariableWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "shadowed variable: '"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoShadowedVariableWalker = (function (_super) { + __extends(NoShadowedVariableWalker, _super); + function NoShadowedVariableWalker() { + _super.apply(this, arguments); + } + NoShadowedVariableWalker.prototype.createScope = function () { + return new ScopeInfo(); + }; + NoShadowedVariableWalker.prototype.createBlockScope = function () { + return new ScopeInfo(); + }; + NoShadowedVariableWalker.prototype.visitBindingElement = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + var isBlockScoped = Lint.isBlockScopedBindingElement(node); + if (isSingleVariable) { + this.handleSingleVariableIdentifier(node.name, isBlockScoped); + } + _super.prototype.visitBindingElement.call(this, node); + }; + NoShadowedVariableWalker.prototype.visitCatchClause = function (node) { + // don't visit the catch clause variable declaration, just visit the block + // the catch clause variable declaration has its own special scoping rules + this.visitBlock(node.block); + }; + NoShadowedVariableWalker.prototype.visitCallSignature = function (node) { + // don't call super, we don't need to check parameter names in call signatures + }; + NoShadowedVariableWalker.prototype.visitFunctionType = function (node) { + // don't call super, we don't need to check names in function types + }; + NoShadowedVariableWalker.prototype.visitMethodSignature = function (node) { + // don't call super, we don't want to walk method signatures either + }; + NoShadowedVariableWalker.prototype.visitParameterDeclaration = function (node) { + // treat parameters as block-scoped variables + var variableIdentifier = node.name; + var variableName = variableIdentifier.text; + var currentScope = this.getCurrentScope(); + if (this.isVarInAnyScope(variableName)) { + this.addFailureOnIdentifier(variableIdentifier); + } + currentScope.varNames.push(variableName); + _super.prototype.visitParameterDeclaration.call(this, node); + }; + NoShadowedVariableWalker.prototype.visitTypeLiteral = function (node) { + // don't call super, we don't want to walk the inside of type nodes + }; + NoShadowedVariableWalker.prototype.visitVariableDeclaration = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + if (isSingleVariable) { + this.handleSingleVariableIdentifier(node.name, Lint.isBlockScopedVariable(node)); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + NoShadowedVariableWalker.prototype.handleSingleVariableIdentifier = function (variableIdentifier, isBlockScoped) { + var variableName = variableIdentifier.text; + var currentScope = this.getCurrentScope(); + var currentBlockScope = this.getCurrentBlockScope(); + // this var is shadowing if there's already a var of the same name in any available scope AND + // it is not in the current block (those are handled by the 'no-duplicate-variable' rule) + if (this.isVarInAnyScope(variableName) && currentBlockScope.varNames.indexOf(variableName) < 0) { + this.addFailureOnIdentifier(variableIdentifier); + } + // regular vars should always be added to the scope; block-scoped vars should be added iff + // the current scope is same as current block scope + if (!isBlockScoped + || this.getCurrentBlockDepth() === 1 + || this.getCurrentBlockDepth() === this.getCurrentDepth()) { + currentScope.varNames.push(variableName); + } + currentBlockScope.varNames.push(variableName); + }; + NoShadowedVariableWalker.prototype.isVarInAnyScope = function (varName) { + return this.getAllScopes().some(function (scopeInfo) { return scopeInfo.varNames.indexOf(varName) >= 0; }); + }; + NoShadowedVariableWalker.prototype.addFailureOnIdentifier = function (ident) { + var failureString = Rule.FAILURE_STRING + ident.text + "'"; + this.addFailure(this.createFailure(ident.getStart(), ident.getWidth(), failureString)); + }; + return NoShadowedVariableWalker; +})(Lint.BlockScopeAwareRuleWalker); +var ScopeInfo = (function () { + function ScopeInfo() { + this.varNames = []; + } + return ScopeInfo; +})(); diff --git a/lib/rules/noStringLiteralRule.d.ts b/lib/rules/noStringLiteralRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noStringLiteralRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noStringLiteralRule.js b/lib/rules/noStringLiteralRule.js new file mode 100644 index 00000000000..dd7ad81f5f0 --- /dev/null +++ b/lib/rules/noStringLiteralRule.js @@ -0,0 +1,60 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoStringLiteralWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "object access via string literals is disallowed"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoStringLiteralWalker = (function (_super) { + __extends(NoStringLiteralWalker, _super); + function NoStringLiteralWalker() { + _super.apply(this, arguments); + } + NoStringLiteralWalker.prototype.visitElementAccessExpression = function (node) { + var argument = node.argumentExpression; + var accessorText = argument.getText(); + // the argument expression should be a string of length at least 2 (due to quote characters) + if (argument.kind === 9 /* StringLiteral */ && accessorText.length > 2) { + var unquotedAccessorText = accessorText.substring(1, accessorText.length - 1); + // only create a failure if the identifier is valid, in which case there's no need to use string literals + if (this.isValidIdentifier(unquotedAccessorText)) { + this.addFailure(this.createFailure(argument.getStart(), argument.getWidth(), Rule.FAILURE_STRING)); + } + } + _super.prototype.visitElementAccessExpression.call(this, node); + }; + NoStringLiteralWalker.prototype.isValidIdentifier = function (token) { + var scanner = ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, token); + scanner.scan(); + // if we scanned to the end of the token, we can check if the scanned item was an identifier + return scanner.getTokenText() === token && scanner.isIdentifier(); + }; + return NoStringLiteralWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noSwitchCaseFallThroughRule.d.ts b/lib/rules/noSwitchCaseFallThroughRule.d.ts new file mode 100644 index 00000000000..4d9c1f40f8f --- /dev/null +++ b/lib/rules/noSwitchCaseFallThroughRule.d.ts @@ -0,0 +1,11 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_PART: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class NoSwitchCaseFallThroughWalker extends Lint.RuleWalker { + visitSwitchStatement(node: ts.SwitchStatement): void; + private fallThroughAllowed(nextCaseOrDefaultStatement); + private fallsThrough(statements); +} diff --git a/lib/rules/noSwitchCaseFallThroughRule.js b/lib/rules/noSwitchCaseFallThroughRule.js new file mode 100644 index 00000000000..d02edaf3f52 --- /dev/null +++ b/lib/rules/noSwitchCaseFallThroughRule.js @@ -0,0 +1,93 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoSwitchCaseFallThroughWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING_PART = "expected a 'break' before "; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoSwitchCaseFallThroughWalker = (function (_super) { + __extends(NoSwitchCaseFallThroughWalker, _super); + function NoSwitchCaseFallThroughWalker() { + _super.apply(this, arguments); + } + NoSwitchCaseFallThroughWalker.prototype.visitSwitchStatement = function (node) { + var _this = this; + var isFallingThrough = false; + // get the position for the first case statement + var switchClauses = node.caseBlock.clauses; + switchClauses.forEach(function (child, i) { + var kind = child.kind; + if (kind === 239 /* CaseClause */) { + var switchClause = child; + isFallingThrough = _this.fallsThrough(switchClause.statements); + // no break statements and no statements means the fallthrough is expected. + // last item doesn't need a break + if (isFallingThrough && switchClause.statements.length > 0 && ((switchClauses.length - 1) > i)) { + if (!_this.fallThroughAllowed(switchClauses[i + 1])) { + _this.addFailure(_this.createFailure(child.getEnd(), 1, Rule.FAILURE_STRING_PART + "'case'")); + } + } + } + else { + // case statement falling through a default + if (isFallingThrough && !_this.fallThroughAllowed(child)) { + var failureString = Rule.FAILURE_STRING_PART + "'default'"; + _this.addFailure(_this.createFailure(switchClauses[i - 1].getEnd(), 1, failureString)); + } + } + }); + _super.prototype.visitSwitchStatement.call(this, node); + }; + NoSwitchCaseFallThroughWalker.prototype.fallThroughAllowed = function (nextCaseOrDefaultStatement) { + var sourceFileText = nextCaseOrDefaultStatement.getSourceFile().text; + var firstChild = nextCaseOrDefaultStatement.getChildAt(0); + var commentRanges = ts.getLeadingCommentRanges(sourceFileText, firstChild.getFullStart()); + if (commentRanges != null) { + for (var _i = 0; _i < commentRanges.length; _i++) { + var commentRange = commentRanges[_i]; + var commentText = sourceFileText.substring(commentRange.pos, commentRange.end); + if (commentText === "/* falls through */") { + return true; + } + } + } + return false; + }; + NoSwitchCaseFallThroughWalker.prototype.fallsThrough = function (statements) { + return !statements.some(function (statement) { + return statement.kind === 201 /* BreakStatement */ + || statement.kind === 206 /* ThrowStatement */ + || statement.kind === 202 /* ReturnStatement */ + || statement.kind === 200 /* ContinueStatement */; + }); + }; + return NoSwitchCaseFallThroughWalker; +})(Lint.RuleWalker); +exports.NoSwitchCaseFallThroughWalker = NoSwitchCaseFallThroughWalker; diff --git a/lib/rules/noTrailingCommaRule.d.ts b/lib/rules/noTrailingCommaRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noTrailingCommaRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noTrailingCommaRule.js b/lib/rules/noTrailingCommaRule.js new file mode 100644 index 00000000000..49a7c7c8ddf --- /dev/null +++ b/lib/rules/noTrailingCommaRule.js @@ -0,0 +1,54 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoTrailingCommaWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "trailing comma"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoTrailingCommaWalker = (function (_super) { + __extends(NoTrailingCommaWalker, _super); + function NoTrailingCommaWalker() { + _super.apply(this, arguments); + } + NoTrailingCommaWalker.prototype.visitObjectLiteralExpression = function (node) { + var child = node.getChildAt(1); + if (child != null && child.kind === 269 /* SyntaxList */) { + var grandChildren = child.getChildren(); + if (grandChildren.length > 0) { + var lastGrandChild = grandChildren[grandChildren.length - 1]; + if (lastGrandChild.kind === 24 /* CommaToken */) { + this.addFailure(this.createFailure(lastGrandChild.getStart(), 1, Rule.FAILURE_STRING)); + } + } + } + _super.prototype.visitObjectLiteralExpression.call(this, node); + }; + return NoTrailingCommaWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noTrailingWhitespaceRule.d.ts b/lib/rules/noTrailingWhitespaceRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noTrailingWhitespaceRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noTrailingWhitespaceRule.js b/lib/rules/noTrailingWhitespaceRule.js new file mode 100644 index 00000000000..6daee260b6e --- /dev/null +++ b/lib/rules/noTrailingWhitespaceRule.js @@ -0,0 +1,72 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoTrailingWhitespaceWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "trailing whitespace"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoTrailingWhitespaceWalker = (function (_super) { + __extends(NoTrailingWhitespaceWalker, _super); + function NoTrailingWhitespaceWalker() { + _super.apply(this, arguments); + } + NoTrailingWhitespaceWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + var lastSeenWasWhitespace = false; + var lastSeenWhitespacePosition = 0; + Lint.scanAllTokens(ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.text), function (scanner) { + var startPos = scanner.getStartPos(); + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + lastSeenWasWhitespace = false; + return; + } + if (scanner.getToken() === 4 /* NewLineTrivia */) { + if (lastSeenWasWhitespace) { + var width = scanner.getStartPos() - lastSeenWhitespacePosition; + var failure = _this.createFailure(lastSeenWhitespacePosition, width, Rule.FAILURE_STRING); + _this.addFailure(failure); + } + lastSeenWasWhitespace = false; + } + else if (scanner.getToken() === 5 /* WhitespaceTrivia */) { + lastSeenWasWhitespace = true; + lastSeenWhitespacePosition = scanner.getStartPos(); + } + else { + lastSeenWasWhitespace = false; + } + }); + }; + return NoTrailingWhitespaceWalker; +})(Lint.SkippableTokenAwareRuleWalker); diff --git a/lib/rules/noUnreachableRule.d.ts b/lib/rules/noUnreachableRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noUnreachableRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noUnreachableRule.js b/lib/rules/noUnreachableRule.js new file mode 100644 index 00000000000..ad536b98a55 --- /dev/null +++ b/lib/rules/noUnreachableRule.js @@ -0,0 +1,96 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new UnreachableWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "unreachable code"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var UnreachableWalker = (function (_super) { + __extends(UnreachableWalker, _super); + function UnreachableWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + this.hasReturned = false; + } + UnreachableWalker.prototype.visitNode = function (node) { + var previousReturned = this.hasReturned; + // function declarations can be hoisted -- so set hasReturned to false until we're done with the function + if (node.kind === 211 /* FunctionDeclaration */) { + this.hasReturned = false; + } + if (this.hasReturned) { + this.hasReturned = false; + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitNode.call(this, node); + // if there is further code after the hoisted function and we returned before that code is unreachable + // so reset hasReturned to its previous state to check for that + if (node.kind === 211 /* FunctionDeclaration */) { + this.hasReturned = previousReturned; + } + }; + UnreachableWalker.prototype.visitBlock = function (node) { + _super.prototype.visitBlock.call(this, node); + this.hasReturned = false; + }; + UnreachableWalker.prototype.visitCaseClause = function (node) { + _super.prototype.visitCaseClause.call(this, node); + this.hasReturned = false; + }; + UnreachableWalker.prototype.visitDefaultClause = function (node) { + _super.prototype.visitDefaultClause.call(this, node); + this.hasReturned = false; + }; + UnreachableWalker.prototype.visitIfStatement = function (node) { + this.visitNode(node.expression); + this.visitNode(node.thenStatement); + this.hasReturned = false; + if (node.elseStatement != null) { + this.visitNode(node.elseStatement); + this.hasReturned = false; + } + }; + UnreachableWalker.prototype.visitBreakStatement = function (node) { + _super.prototype.visitBreakStatement.call(this, node); + this.hasReturned = true; + }; + UnreachableWalker.prototype.visitContinueStatement = function (node) { + _super.prototype.visitContinueStatement.call(this, node); + this.hasReturned = true; + }; + UnreachableWalker.prototype.visitReturnStatement = function (node) { + _super.prototype.visitReturnStatement.call(this, node); + this.hasReturned = true; + }; + UnreachableWalker.prototype.visitThrowStatement = function (node) { + _super.prototype.visitThrowStatement.call(this, node); + this.hasReturned = true; + }; + return UnreachableWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noUnusedExpressionRule.d.ts b/lib/rules/noUnusedExpressionRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noUnusedExpressionRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noUnusedExpressionRule.js b/lib/rules/noUnusedExpressionRule.js new file mode 100644 index 00000000000..71f89cd1aab --- /dev/null +++ b/lib/rules/noUnusedExpressionRule.js @@ -0,0 +1,119 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2014 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new UnusedExpressionWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "expected an assignment or function call"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var UnusedExpressionWalker = (function (_super) { + __extends(UnusedExpressionWalker, _super); + function UnusedExpressionWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + this.expressionIsUnused = true; + } + UnusedExpressionWalker.prototype.visitExpressionStatement = function (node) { + this.expressionIsUnused = true; + _super.prototype.visitExpressionStatement.call(this, node); + if (this.expressionIsUnused) { + // ignore valid unused expressions + if (node.expression.kind === 9 /* StringLiteral */) { + var expressionText = node.expression.getText(); + if (expressionText === "\"use strict\"" || expressionText === "'use strict'") { + return; + } + } + else if (node.expression.kind === 173 /* DeleteExpression */) { + return; + } + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + }; + UnusedExpressionWalker.prototype.visitBinaryExpression = function (node) { + _super.prototype.visitBinaryExpression.call(this, node); + switch (node.operatorToken.kind) { + case 55 /* EqualsToken */: + case 56 /* PlusEqualsToken */: + case 57 /* MinusEqualsToken */: + case 58 /* AsteriskEqualsToken */: + case 59 /* SlashEqualsToken */: + case 60 /* PercentEqualsToken */: + case 64 /* AmpersandEqualsToken */: + case 66 /* CaretEqualsToken */: + case 65 /* BarEqualsToken */: + case 61 /* LessThanLessThanEqualsToken */: + case 62 /* GreaterThanGreaterThanEqualsToken */: + case 63 /* GreaterThanGreaterThanGreaterThanEqualsToken */: + this.expressionIsUnused = false; + break; + default: + this.expressionIsUnused = true; + } + }; + UnusedExpressionWalker.prototype.visitPrefixUnaryExpression = function (node) { + _super.prototype.visitPrefixUnaryExpression.call(this, node); + switch (node.operator) { + case 40 /* PlusPlusToken */: + case 41 /* MinusMinusToken */: + this.expressionIsUnused = false; + break; + default: + this.expressionIsUnused = true; + } + }; + UnusedExpressionWalker.prototype.visitPostfixUnaryExpression = function (node) { + _super.prototype.visitPostfixUnaryExpression.call(this, node); + this.expressionIsUnused = false; // the only kinds of postfix expressions are postincrement and postdecrement + }; + UnusedExpressionWalker.prototype.visitBlock = function (node) { + _super.prototype.visitBlock.call(this, node); + this.expressionIsUnused = true; + }; + UnusedExpressionWalker.prototype.visitArrowFunction = function (node) { + _super.prototype.visitArrowFunction.call(this, node); + this.expressionIsUnused = true; + }; + UnusedExpressionWalker.prototype.visitCallExpression = function (node) { + _super.prototype.visitCallExpression.call(this, node); + this.expressionIsUnused = false; + }; + UnusedExpressionWalker.prototype.visitConditionalExpression = function (node) { + this.visitNode(node.condition); + this.expressionIsUnused = true; + this.visitNode(node.whenTrue); + var firstExpressionIsUnused = this.expressionIsUnused; + this.expressionIsUnused = true; + this.visitNode(node.whenFalse); + var secondExpressionIsUnused = this.expressionIsUnused; + // if either expression is unused, then that expression's branch is a no-op unless it's + // being assigned to something or passed to a function, so consider the entire expression unused + this.expressionIsUnused = firstExpressionIsUnused || secondExpressionIsUnused; + }; + return UnusedExpressionWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noUnusedVariableRule.d.ts b/lib/rules/noUnusedVariableRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noUnusedVariableRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noUnusedVariableRule.js b/lib/rules/noUnusedVariableRule.js new file mode 100644 index 00000000000..aa73d4b9b70 --- /dev/null +++ b/lib/rules/noUnusedVariableRule.js @@ -0,0 +1,184 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2014 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_CHECK_PARAMETERS = "check-parameters"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var languageService = Lint.createLanguageService(sourceFile.fileName, sourceFile.getFullText()); + return this.applyWithWalker(new NoUnusedVariablesWalker(sourceFile, this.getOptions(), languageService)); + }; + Rule.FAILURE_STRING = "unused variable: "; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoUnusedVariablesWalker = (function (_super) { + __extends(NoUnusedVariablesWalker, _super); + function NoUnusedVariablesWalker(sourceFile, options, languageService) { + _super.call(this, sourceFile, options); + this.languageService = languageService; + this.skipVariableDeclaration = false; + this.skipParameterDeclaration = false; + } + NoUnusedVariablesWalker.prototype.visitBindingElement = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + if (isSingleVariable && !this.skipBindingElement) { + var variableIdentifier = node.name; + this.validateReferencesForVariable(variableIdentifier.text, variableIdentifier.getStart()); + } + _super.prototype.visitBindingElement.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitImportDeclaration = function (node) { + if (!Lint.hasModifier(node.modifiers, 80 /* ExportKeyword */)) { + var importClause = node.importClause; + // named imports & namespace imports handled by other walker methods + // importClause will be null for bare imports + if (importClause != null && importClause.name != null) { + var variableIdentifier = importClause.name; + this.validateReferencesForVariable(variableIdentifier.text, variableIdentifier.getStart()); + } + } + _super.prototype.visitImportDeclaration.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitImportEqualsDeclaration = function (node) { + if (!Lint.hasModifier(node.modifiers, 80 /* ExportKeyword */)) { + var name_1 = node.name; + this.validateReferencesForVariable(name_1.text, name_1.getStart()); + } + _super.prototype.visitImportEqualsDeclaration.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitCatchClause = function (node) { + // don't visit the catch clause variable declaration, just visit the block + // the catch clause variable declaration needs to be there but doesn't need to be used + this.visitBlock(node.block); + }; + NoUnusedVariablesWalker.prototype.visitNamedImports = function (node) { + var _this = this; + node.elements.forEach(function (namedImport) { + _this.validateReferencesForVariable(namedImport.name.text, namedImport.name.getStart()); + }); + _super.prototype.visitNamedImports.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitNamespaceImport = function (node) { + this.validateReferencesForVariable(node.name.text, node.name.getStart()); + _super.prototype.visitNamespaceImport.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitVariableDeclaration = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + if (isSingleVariable && !this.skipVariableDeclaration) { + var variableIdentifier = node.name; + this.validateReferencesForVariable(variableIdentifier.text, variableIdentifier.getStart()); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + // skip parameters in interfaces + NoUnusedVariablesWalker.prototype.visitInterfaceDeclaration = function (node) { + this.skipParameterDeclaration = true; + _super.prototype.visitInterfaceDeclaration.call(this, node); + this.skipParameterDeclaration = false; + }; + // skip parameters in index signatures (stuff like [key: string]: string) + NoUnusedVariablesWalker.prototype.visitIndexSignatureDeclaration = function (node) { + this.skipParameterDeclaration = true; + _super.prototype.visitIndexSignatureDeclaration.call(this, node); + this.skipParameterDeclaration = false; + }; + // skip exported and declared variables + NoUnusedVariablesWalker.prototype.visitVariableStatement = function (node) { + if (Lint.hasModifier(node.modifiers, 80 /* ExportKeyword */, 120 /* DeclareKeyword */)) { + this.skipBindingElement = true; + this.skipVariableDeclaration = true; + } + _super.prototype.visitVariableStatement.call(this, node); + this.skipBindingElement = false; + this.skipVariableDeclaration = false; + }; + NoUnusedVariablesWalker.prototype.visitFunctionType = function (node) { + this.skipParameterDeclaration = true; + _super.prototype.visitFunctionType.call(this, node); + this.skipParameterDeclaration = false; + }; + // skip exported and declared functions + NoUnusedVariablesWalker.prototype.visitFunctionDeclaration = function (node) { + if (!Lint.hasModifier(node.modifiers, 80 /* ExportKeyword */, 120 /* DeclareKeyword */)) { + var variableName = node.name.text; + this.validateReferencesForVariable(variableName, node.name.getStart()); + } + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + NoUnusedVariablesWalker.prototype.visitParameterDeclaration = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + var isPropertyParameter = Lint.hasModifier(node.modifiers, 110 /* PublicKeyword */, 108 /* PrivateKeyword */, 109 /* ProtectedKeyword */); + if (!isSingleVariable && isPropertyParameter) { + // tsc error: a parameter property may not be a binding pattern + this.skipBindingElement = true; + } + if (this.hasOption(OPTION_CHECK_PARAMETERS) + && isSingleVariable + && !this.skipParameterDeclaration + && !Lint.hasModifier(node.modifiers, 110 /* PublicKeyword */)) { + var nameNode = node.name; + this.validateReferencesForVariable(nameNode.text, node.name.getStart()); + } + _super.prototype.visitParameterDeclaration.call(this, node); + this.skipBindingElement = false; + }; + // check private member variables + NoUnusedVariablesWalker.prototype.visitPropertyDeclaration = function (node) { + if (node.name != null && node.name.kind === 67 /* Identifier */) { + var modifiers = node.modifiers; + var variableName = node.name.text; + // check only if an explicit 'private' modifier is specified + if (Lint.hasModifier(modifiers, 108 /* PrivateKeyword */)) { + this.validateReferencesForVariable(variableName, node.name.getStart()); + } + } + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + // check private member functions + NoUnusedVariablesWalker.prototype.visitMethodDeclaration = function (node) { + if (node.name != null && node.name.kind === 67 /* Identifier */) { + var modifiers = node.modifiers; + var variableName = node.name.text; + if (Lint.hasModifier(modifiers, 108 /* PrivateKeyword */)) { + this.validateReferencesForVariable(variableName, node.name.getStart()); + } + } + // abstract methods can't have a body so their parameters are always unused + if (Lint.hasModifier(node.modifiers, 113 /* AbstractKeyword */)) { + this.skipParameterDeclaration = true; + } + _super.prototype.visitMethodDeclaration.call(this, node); + this.skipParameterDeclaration = false; + }; + NoUnusedVariablesWalker.prototype.validateReferencesForVariable = function (name, position) { + var fileName = this.getSourceFile().fileName; + var highlights = this.languageService.getDocumentHighlights(fileName, position, [fileName]); + if (highlights == null || highlights[0].highlightSpans.length <= 1) { + this.addFailure(this.createFailure(position, name.length, Rule.FAILURE_STRING + "'" + name + "'")); + } + }; + return NoUnusedVariablesWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noUseBeforeDeclareRule.d.ts b/lib/rules/noUseBeforeDeclareRule.d.ts new file mode 100644 index 00000000000..54e13adec9c --- /dev/null +++ b/lib/rules/noUseBeforeDeclareRule.d.ts @@ -0,0 +1,7 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING_PREFIX: string; + static FAILURE_STRING_POSTFIX: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noUseBeforeDeclareRule.js b/lib/rules/noUseBeforeDeclareRule.js new file mode 100644 index 00000000000..491d037368d --- /dev/null +++ b/lib/rules/noUseBeforeDeclareRule.js @@ -0,0 +1,109 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2014 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var languageService = Lint.createLanguageService(sourceFile.fileName, sourceFile.getFullText()); + return this.applyWithWalker(new NoUseBeforeDeclareWalker(sourceFile, this.getOptions(), languageService)); + }; + Rule.FAILURE_STRING_PREFIX = "variable '"; + Rule.FAILURE_STRING_POSTFIX = "' used before declaration"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoUseBeforeDeclareWalker = (function (_super) { + __extends(NoUseBeforeDeclareWalker, _super); + function NoUseBeforeDeclareWalker(sourceFile, options, languageService) { + _super.call(this, sourceFile, options); + this.languageService = languageService; + } + NoUseBeforeDeclareWalker.prototype.createScope = function () { + return {}; + }; + NoUseBeforeDeclareWalker.prototype.visitBindingElement = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + var isBlockScoped = Lint.isBlockScopedBindingElement(node); + // use-before-declare errors for block-scoped vars are caught by tsc + if (isSingleVariable && !isBlockScoped) { + var variableName = node.name.text; + this.validateUsageForVariable(variableName, node.name.getStart()); + } + _super.prototype.visitBindingElement.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.visitImportDeclaration = function (node) { + var importClause = node.importClause; + // named imports & namespace imports handled by other walker methods + // importClause will be null for bare imports + if (importClause != null && importClause.name != null) { + var variableIdentifier = importClause.name; + this.validateUsageForVariable(variableIdentifier.text, variableIdentifier.getStart()); + } + _super.prototype.visitImportDeclaration.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.visitImportEqualsDeclaration = function (node) { + var name = node.name; + this.validateUsageForVariable(name.text, name.getStart()); + _super.prototype.visitImportEqualsDeclaration.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.visitNamedImports = function (node) { + for (var _i = 0, _a = node.elements; _i < _a.length; _i++) { + var namedImport = _a[_i]; + this.validateUsageForVariable(namedImport.name.text, namedImport.name.getStart()); + } + _super.prototype.visitNamedImports.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.visitNamespaceImport = function (node) { + this.validateUsageForVariable(node.name.text, node.name.getStart()); + _super.prototype.visitNamespaceImport.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.visitVariableDeclaration = function (node) { + var isSingleVariable = node.name.kind === 67 /* Identifier */; + var variableName = node.name.text; + var currentScope = this.getCurrentScope(); + // only validate on the first variable declaration within the current scope + if (isSingleVariable && currentScope[variableName] == null) { + this.validateUsageForVariable(variableName, node.getStart()); + } + currentScope[variableName] = true; + _super.prototype.visitVariableDeclaration.call(this, node); + }; + NoUseBeforeDeclareWalker.prototype.validateUsageForVariable = function (name, position) { + var fileName = this.getSourceFile().fileName; + var highlights = this.languageService.getDocumentHighlights(fileName, position, [fileName]); + for (var _i = 0; _i < highlights.length; _i++) { + var highlight = highlights[_i]; + for (var _a = 0, _b = highlight.highlightSpans; _a < _b.length; _a++) { + var highlightSpan = _b[_a]; + var referencePosition = highlightSpan.textSpan.start; + if (referencePosition < position) { + var failureString = Rule.FAILURE_STRING_PREFIX + name + Rule.FAILURE_STRING_POSTFIX; + this.addFailure(this.createFailure(referencePosition, name.length, failureString)); + } + } + } + }; + return NoUseBeforeDeclareWalker; +})(Lint.ScopeAwareRuleWalker); diff --git a/lib/rules/noVarKeywordRule.d.ts b/lib/rules/noVarKeywordRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noVarKeywordRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noVarKeywordRule.js b/lib/rules/noVarKeywordRule.js new file mode 100644 index 00000000000..1eff9b26a4d --- /dev/null +++ b/lib/rules/noVarKeywordRule.js @@ -0,0 +1,49 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2015 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var noVarKeywordWalker = new NoVarKeywordWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(noVarKeywordWalker); + }; + Rule.FAILURE_STRING = "forbidden var keyword"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var NoVarKeywordWalker = (function (_super) { + __extends(NoVarKeywordWalker, _super); + function NoVarKeywordWalker() { + _super.apply(this, arguments); + } + NoVarKeywordWalker.prototype.visitVariableStatement = function (node) { + if (!Lint.hasModifier(node.modifiers, 80 /* ExportKeyword */, 120 /* DeclareKeyword */) + && !Lint.isBlockScopedVariable(node)) { + this.addFailure(this.createFailure(node.getStart(), "var".length, Rule.FAILURE_STRING)); + } + _super.prototype.visitVariableStatement.call(this, node); + }; + return NoVarKeywordWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/noVarRequiresRule.d.ts b/lib/rules/noVarRequiresRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/noVarRequiresRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/noVarRequiresRule.js b/lib/rules/noVarRequiresRule.js new file mode 100644 index 00000000000..e32511c42c0 --- /dev/null +++ b/lib/rules/noVarRequiresRule.js @@ -0,0 +1,56 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2014 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var requiresWalker = new RequiresWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(requiresWalker); + }; + Rule.FAILURE_STRING = "require statement not part of an import statement"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var RequiresWalker = (function (_super) { + __extends(RequiresWalker, _super); + function RequiresWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + } + RequiresWalker.prototype.createScope = function () { + return {}; + }; + RequiresWalker.prototype.visitCallExpression = function (node) { + var expression = node.expression; + if (this.getCurrentDepth() <= 1 && expression.kind === 67 /* Identifier */) { + var identifierName = expression.text; + if (identifierName === "require") { + // if we're calling (invoking) require, then it's not part of an import statement + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + } + _super.prototype.visitCallExpression.call(this, node); + }; + return RequiresWalker; +})(Lint.ScopeAwareRuleWalker); diff --git a/lib/rules/oneLineRule.d.ts b/lib/rules/oneLineRule.d.ts new file mode 100644 index 00000000000..e5b1691fa54 --- /dev/null +++ b/lib/rules/oneLineRule.d.ts @@ -0,0 +1,9 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static BRACE_FAILURE_STRING: string; + static CATCH_FAILURE_STRING: string; + static ELSE_FAILURE_STRING: string; + static WHITESPACE_FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/oneLineRule.js b/lib/rules/oneLineRule.js new file mode 100644 index 00000000000..56f76d66838 --- /dev/null +++ b/lib/rules/oneLineRule.js @@ -0,0 +1,246 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_BRACE = "check-open-brace"; +var OPTION_CATCH = "check-catch"; +var OPTION_ELSE = "check-else"; +var OPTION_WHITESPACE = "check-whitespace"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var oneLineWalker = new OneLineWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(oneLineWalker); + }; + Rule.BRACE_FAILURE_STRING = "misplaced opening brace"; + Rule.CATCH_FAILURE_STRING = "misplaced 'catch'"; + Rule.ELSE_FAILURE_STRING = "misplaced 'else'"; + Rule.WHITESPACE_FAILURE_STRING = "missing whitespace"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var OneLineWalker = (function (_super) { + __extends(OneLineWalker, _super); + function OneLineWalker() { + _super.apply(this, arguments); + } + OneLineWalker.prototype.visitIfStatement = function (node) { + var sourceFile = node.getSourceFile(); + var thenStatement = node.thenStatement; + if (thenStatement.kind === 190 /* Block */) { + var expressionCloseParen = node.getChildAt(3); + var thenOpeningBrace = thenStatement.getChildAt(0); + this.handleOpeningBrace(expressionCloseParen, thenOpeningBrace); + } + var elseStatement = node.elseStatement; + if (elseStatement != null) { + // find the else keyword + var elseKeyword = getFirstChildOfKind(node, 78 /* ElseKeyword */); + if (elseStatement.kind === 190 /* Block */) { + var elseOpeningBrace = elseStatement.getChildAt(0); + this.handleOpeningBrace(elseKeyword, elseOpeningBrace); + } + if (this.hasOption(OPTION_ELSE)) { + var thenStatementEndLine = sourceFile.getLineAndCharacterOfPosition(thenStatement.getEnd()).line; + var elseKeywordLine = sourceFile.getLineAndCharacterOfPosition(elseKeyword.getStart()).line; + if (thenStatementEndLine !== elseKeywordLine) { + var failure = this.createFailure(elseKeyword.getStart(), elseKeyword.getWidth(), Rule.ELSE_FAILURE_STRING); + this.addFailure(failure); + } + } + } + _super.prototype.visitIfStatement.call(this, node); + }; + OneLineWalker.prototype.visitCatchClause = function (node) { + var catchKeyword = node.getChildAt(0); + var catchOpeningBrace = node.block.getChildAt(0); + this.handleOpeningBrace(catchKeyword, catchOpeningBrace); + _super.prototype.visitCatchClause.call(this, node); + }; + OneLineWalker.prototype.visitTryStatement = function (node) { + var sourceFile = node.getSourceFile(); + var catchClause = node.catchClause; + // "visit" try block + var tryKeyword = node.getChildAt(0); + var tryBlock = node.tryBlock; + var tryOpeningBrace = tryBlock.getChildAt(0); + this.handleOpeningBrace(tryKeyword, tryOpeningBrace); + if (this.hasOption(OPTION_CATCH) && catchClause != null) { + var tryClosingBrace = node.tryBlock.getChildAt(node.tryBlock.getChildCount() - 1); + var catchKeyword = catchClause.getChildAt(0); + var tryClosingBraceLine = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd()).line; + var catchKeywordLine = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart()).line; + if (tryClosingBraceLine !== catchKeywordLine) { + var failure = this.createFailure(catchKeyword.getStart(), catchKeyword.getWidth(), Rule.CATCH_FAILURE_STRING); + this.addFailure(failure); + } + } + _super.prototype.visitTryStatement.call(this, node); + }; + OneLineWalker.prototype.visitForStatement = function (node) { + this.handleIterationStatement(node); + _super.prototype.visitForStatement.call(this, node); + }; + OneLineWalker.prototype.visitForInStatement = function (node) { + this.handleIterationStatement(node); + _super.prototype.visitForInStatement.call(this, node); + }; + OneLineWalker.prototype.visitWhileStatement = function (node) { + this.handleIterationStatement(node); + _super.prototype.visitWhileStatement.call(this, node); + }; + OneLineWalker.prototype.visitBinaryExpression = function (node) { + var rightkind = node.right.kind; + var opkind = node.operatorToken.kind; + if (opkind === 55 /* EqualsToken */ && rightkind === 163 /* ObjectLiteralExpression */) { + var equalsToken = node.getChildAt(1); + var openBraceToken = node.right.getChildAt(0); + this.handleOpeningBrace(equalsToken, openBraceToken); + } + _super.prototype.visitBinaryExpression.call(this, node); + }; + OneLineWalker.prototype.visitVariableDeclaration = function (node) { + var initializer = node.initializer; + if (initializer != null && initializer.kind === 163 /* ObjectLiteralExpression */) { + var equalsToken = node.getChildAt(1); + var openBraceToken = initializer.getChildAt(0); + this.handleOpeningBrace(equalsToken, openBraceToken); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitDoStatement = function (node) { + var doKeyword = node.getChildAt(0); + var statement = node.statement; + if (statement.kind === 190 /* Block */) { + var openBraceToken = statement.getChildAt(0); + this.handleOpeningBrace(doKeyword, openBraceToken); + } + _super.prototype.visitDoStatement.call(this, node); + }; + OneLineWalker.prototype.visitModuleDeclaration = function (node) { + var nameNode = node.name; + var body = node.body; + if (body.kind === 217 /* ModuleBlock */) { + var openBraceToken = body.getChildAt(0); + this.handleOpeningBrace(nameNode, openBraceToken); + } + _super.prototype.visitModuleDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitEnumDeclaration = function (node) { + var nameNode = node.name; + var openBraceToken = getFirstChildOfKind(node, 15 /* OpenBraceToken */); + this.handleOpeningBrace(nameNode, openBraceToken); + _super.prototype.visitEnumDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitSwitchStatement = function (node) { + var closeParenToken = node.getChildAt(3); + var openBraceToken = node.caseBlock.getChildAt(0); + this.handleOpeningBrace(closeParenToken, openBraceToken); + _super.prototype.visitSwitchStatement.call(this, node); + }; + OneLineWalker.prototype.visitInterfaceDeclaration = function (node) { + this.handleClassLikeDeclaration(node); + _super.prototype.visitInterfaceDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitClassDeclaration = function (node) { + this.handleClassLikeDeclaration(node); + _super.prototype.visitClassDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitFunctionDeclaration = function (node) { + this.handleFunctionLikeDeclaration(node); + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitMethodDeclaration = function (node) { + this.handleFunctionLikeDeclaration(node); + _super.prototype.visitMethodDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitConstructorDeclaration = function (node) { + this.handleFunctionLikeDeclaration(node); + _super.prototype.visitConstructorDeclaration.call(this, node); + }; + OneLineWalker.prototype.visitArrowFunction = function (node) { + var body = node.body; + if (body != null && body.kind === 190 /* Block */) { + var arrowToken = getFirstChildOfKind(node, 34 /* EqualsGreaterThanToken */); + var openBraceToken = node.body.getChildAt(0); + this.handleOpeningBrace(arrowToken, openBraceToken); + } + _super.prototype.visitArrowFunction.call(this, node); + }; + OneLineWalker.prototype.handleFunctionLikeDeclaration = function (node) { + var body = node.body; + if (body != null && body.kind === 190 /* Block */) { + var openBraceToken = node.body.getChildAt(0); + if (node.type != null) { + this.handleOpeningBrace(node.type, openBraceToken); + } + else { + var closeParenToken = getFirstChildOfKind(node, 18 /* CloseParenToken */); + this.handleOpeningBrace(closeParenToken, openBraceToken); + } + } + }; + OneLineWalker.prototype.handleClassLikeDeclaration = function (node) { + var lastNodeOfDeclaration = node.name; + var openBraceToken = getFirstChildOfKind(node, 15 /* OpenBraceToken */); + if (node.heritageClauses != null) { + lastNodeOfDeclaration = node.heritageClauses[node.heritageClauses.length - 1]; + } + else if (node.typeParameters != null) { + lastNodeOfDeclaration = node.typeParameters[node.typeParameters.length - 1]; + } + this.handleOpeningBrace(lastNodeOfDeclaration, openBraceToken); + }; + OneLineWalker.prototype.handleIterationStatement = function (node) { + // last child is the statement, second to last child is the close paren + var closeParenToken = node.getChildAt(node.getChildCount() - 2); + var statement = node.statement; + if (statement.kind === 190 /* Block */) { + var openBraceToken = statement.getChildAt(0); + this.handleOpeningBrace(closeParenToken, openBraceToken); + } + }; + OneLineWalker.prototype.handleOpeningBrace = function (previousNode, openBraceToken) { + if (previousNode == null || openBraceToken == null) { + return; + } + var sourceFile = previousNode.getSourceFile(); + var previousNodeLine = sourceFile.getLineAndCharacterOfPosition(previousNode.getEnd()).line; + var openBraceLine = sourceFile.getLineAndCharacterOfPosition(openBraceToken.getStart()).line; + var failure; + if (this.hasOption(OPTION_BRACE) && previousNodeLine !== openBraceLine) { + failure = this.createFailure(openBraceToken.getStart(), openBraceToken.getWidth(), Rule.BRACE_FAILURE_STRING); + } + else if (this.hasOption(OPTION_WHITESPACE) && previousNode.getEnd() === openBraceToken.getStart()) { + failure = this.createFailure(openBraceToken.getStart(), openBraceToken.getWidth(), Rule.WHITESPACE_FAILURE_STRING); + } + if (failure) { + this.addFailure(failure); + } + }; + return OneLineWalker; +})(Lint.RuleWalker); +function getFirstChildOfKind(node, kind) { + return node.getChildren().filter(function (child) { return child.kind === kind; })[0]; +} diff --git a/lib/rules/quotemarkRule.d.ts b/lib/rules/quotemarkRule.d.ts new file mode 100644 index 00000000000..ecbb2b5c4bc --- /dev/null +++ b/lib/rules/quotemarkRule.d.ts @@ -0,0 +1,8 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static SINGLE_QUOTE_FAILURE: string; + static DOUBLE_QUOTE_FAILURE: string; + isEnabled(): boolean; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/quotemarkRule.js b/lib/rules/quotemarkRule.js new file mode 100644 index 00000000000..f7c6c7d055b --- /dev/null +++ b/lib/rules/quotemarkRule.js @@ -0,0 +1,88 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var QuoteMark; +(function (QuoteMark) { + QuoteMark[QuoteMark["SINGLE_QUOTES"] = 0] = "SINGLE_QUOTES"; + QuoteMark[QuoteMark["DOUBLE_QUOTES"] = 1] = "DOUBLE_QUOTES"; +})(QuoteMark || (QuoteMark = {})); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.isEnabled = function () { + if (_super.prototype.isEnabled.call(this)) { + var quoteMarkString = this.getOptions().ruleArguments[0]; + return (quoteMarkString === "single" || quoteMarkString === "double"); + } + return false; + }; + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new QuoteWalker(sourceFile, this.getOptions())); + }; + Rule.SINGLE_QUOTE_FAILURE = "\" should be '"; + Rule.DOUBLE_QUOTE_FAILURE = "' should be \""; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var QuoteWalker = (function (_super) { + __extends(QuoteWalker, _super); + function QuoteWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + this.quoteMark = QuoteMark.DOUBLE_QUOTES; + var ruleArguments = this.getOptions(); + var quoteMarkString = ruleArguments[0]; + if (quoteMarkString === "single") { + this.quoteMark = QuoteMark.SINGLE_QUOTES; + } + else { + this.quoteMark = QuoteMark.DOUBLE_QUOTES; + } + this.avoidEscape = ruleArguments.indexOf("avoid-escape") > 0; + } + QuoteWalker.prototype.visitNode = function (node) { + this.handleNode(node); + _super.prototype.visitNode.call(this, node); + }; + QuoteWalker.prototype.handleNode = function (node) { + if (node.kind === 9 /* StringLiteral */) { + var text = node.getText(); + var width = node.getWidth(); + var position = node.getStart(); + var firstCharacter = text.charAt(0); + var lastCharacter = text.charAt(text.length - 1); + var expectedQuoteMark = (this.quoteMark === QuoteMark.SINGLE_QUOTES) ? "'" : "\""; + if (firstCharacter !== expectedQuoteMark || lastCharacter !== expectedQuoteMark) { + // allow the "other" quote mark to be used, but only to avoid having to escape + var includesOtherQuoteMark = text.slice(1, -1).indexOf(expectedQuoteMark) !== -1; + if (!(this.avoidEscape && includesOtherQuoteMark)) { + var failureMessage = (this.quoteMark === QuoteMark.SINGLE_QUOTES) + ? Rule.SINGLE_QUOTE_FAILURE + : Rule.DOUBLE_QUOTE_FAILURE; + this.addFailure(this.createFailure(position, width, failureMessage)); + } + } + } + }; + return QuoteWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/radixRule.d.ts b/lib/rules/radixRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/radixRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/radixRule.js b/lib/rules/radixRule.js new file mode 100644 index 00000000000..d50375228a4 --- /dev/null +++ b/lib/rules/radixRule.js @@ -0,0 +1,51 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var radixWalker = new RadixWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(radixWalker); + }; + Rule.FAILURE_STRING = "missing radix parameter"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var RadixWalker = (function (_super) { + __extends(RadixWalker, _super); + function RadixWalker() { + _super.apply(this, arguments); + } + RadixWalker.prototype.visitCallExpression = function (node) { + var expression = node.expression; + if (expression.kind === 67 /* Identifier */ + && node.getFirstToken().getText() === "parseInt" + && node.arguments.length < 2) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitCallExpression.call(this, node); + }; + return RadixWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/semicolonRule.d.ts b/lib/rules/semicolonRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/semicolonRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/semicolonRule.js b/lib/rules/semicolonRule.js new file mode 100644 index 00000000000..8bc6016a933 --- /dev/null +++ b/lib/rules/semicolonRule.js @@ -0,0 +1,105 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new SemicolonWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "missing semicolon"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var SemicolonWalker = (function (_super) { + __extends(SemicolonWalker, _super); + function SemicolonWalker() { + _super.apply(this, arguments); + } + SemicolonWalker.prototype.visitVariableStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitVariableStatement.call(this, node); + }; + SemicolonWalker.prototype.visitExpressionStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitExpressionStatement.call(this, node); + }; + SemicolonWalker.prototype.visitReturnStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitReturnStatement.call(this, node); + }; + SemicolonWalker.prototype.visitBreakStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitBreakStatement.call(this, node); + }; + SemicolonWalker.prototype.visitContinueStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitContinueStatement.call(this, node); + }; + SemicolonWalker.prototype.visitThrowStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitThrowStatement.call(this, node); + }; + SemicolonWalker.prototype.visitImportDeclaration = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitImportDeclaration.call(this, node); + }; + SemicolonWalker.prototype.visitImportEqualsDeclaration = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitImportEqualsDeclaration.call(this, node); + }; + SemicolonWalker.prototype.visitDoStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitDoStatement.call(this, node); + }; + SemicolonWalker.prototype.visitDebuggerStatement = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitDebuggerStatement.call(this, node); + }; + SemicolonWalker.prototype.visitPropertyDeclaration = function (node) { + this.checkSemicolonAt(node); + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + SemicolonWalker.prototype.visitInterfaceDeclaration = function (node) { + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + this.checkSemicolonAt(member); + } + _super.prototype.visitInterfaceDeclaration.call(this, node); + }; + SemicolonWalker.prototype.checkSemicolonAt = function (node) { + var children = node.getChildren(this.getSourceFile()); + for (var _i = 0; _i < children.length; _i++) { + var child = children[_i]; + if (child.kind === 23 /* SemicolonToken */) { + return; + } + } + // no semicolon token was found, so add a failure at the given position + var sourceFile = this.getSourceFile(); + var position = node.getStart(sourceFile) + node.getWidth(sourceFile); + this.addFailure(this.createFailure(Math.min(position, this.getLimit()), 0, Rule.FAILURE_STRING)); + }; + return SemicolonWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/sortObjectLiteralKeysRule.d.ts b/lib/rules/sortObjectLiteralKeysRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/sortObjectLiteralKeysRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/sortObjectLiteralKeysRule.js b/lib/rules/sortObjectLiteralKeysRule.js new file mode 100644 index 00000000000..7dcd523151c --- /dev/null +++ b/lib/rules/sortObjectLiteralKeysRule.js @@ -0,0 +1,75 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new SortedKeyWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "unsorted key '"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var SortedKeyWalker = (function (_super) { + __extends(SortedKeyWalker, _super); + function SortedKeyWalker() { + _super.apply(this, arguments); + // stacks are used to maintain state while recursing through nested object literals + this.lastSortedKeyStack = []; + this.sortedStateStack = []; + } + SortedKeyWalker.prototype.visitObjectLiteralExpression = function (node) { + // char code 0; every string should be >= to this + this.lastSortedKeyStack.push(""); + // sorted state is always initially true + this.sortedStateStack.push(true); + _super.prototype.visitObjectLiteralExpression.call(this, node); + this.lastSortedKeyStack.pop(); + this.sortedStateStack.pop(); + }; + SortedKeyWalker.prototype.visitPropertyAssignment = function (node) { + var sortedState = this.sortedStateStack[this.sortedStateStack.length - 1]; + // skip remainder of object literal scan if a previous key was found + // in an unsorted position. This ensures only one error is thrown at + // a time and keeps error output clean. + if (sortedState) { + var lastSortedKey = this.lastSortedKeyStack[this.lastSortedKeyStack.length - 1]; + var keyNode = node.name; + if (keyNode.kind === 67 /* Identifier */) { + var key = keyNode.text; + if (key < lastSortedKey) { + var failureString = Rule.FAILURE_STRING + key + "'"; + this.addFailure(this.createFailure(keyNode.getStart(), keyNode.getWidth(), failureString)); + this.sortedStateStack[this.sortedStateStack.length - 1] = false; + } + else { + this.lastSortedKeyStack[this.lastSortedKeyStack.length - 1] = key; + } + } + } + _super.prototype.visitPropertyAssignment.call(this, node); + }; + return SortedKeyWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/switchDefaultRule.d.ts b/lib/rules/switchDefaultRule.d.ts new file mode 100644 index 00000000000..12885ed66c2 --- /dev/null +++ b/lib/rules/switchDefaultRule.d.ts @@ -0,0 +1,9 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} +export declare class SwitchDefaultWalker extends Lint.RuleWalker { + visitSwitchStatement(node: ts.SwitchStatement): void; +} diff --git a/lib/rules/switchDefaultRule.js b/lib/rules/switchDefaultRule.js new file mode 100644 index 00000000000..2e2a8955517 --- /dev/null +++ b/lib/rules/switchDefaultRule.js @@ -0,0 +1,49 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * Copyright 2015 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new SwitchDefaultWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "switch statement doesn't include a 'default' case"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var SwitchDefaultWalker = (function (_super) { + __extends(SwitchDefaultWalker, _super); + function SwitchDefaultWalker() { + _super.apply(this, arguments); + } + SwitchDefaultWalker.prototype.visitSwitchStatement = function (node) { + var hasDefaultCase = node.caseBlock.clauses.some(function (clause) { return clause.kind === 240 /* DefaultClause */; }); + if (!hasDefaultCase) { + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_STRING)); + } + _super.prototype.visitSwitchStatement.call(this, node); + }; + return SwitchDefaultWalker; +})(Lint.RuleWalker); +exports.SwitchDefaultWalker = SwitchDefaultWalker; diff --git a/lib/rules/tripleEqualsRule.d.ts b/lib/rules/tripleEqualsRule.d.ts new file mode 100644 index 00000000000..fa880d630e3 --- /dev/null +++ b/lib/rules/tripleEqualsRule.d.ts @@ -0,0 +1,7 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static EQ_FAILURE_STRING: string; + static NEQ_FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/tripleEqualsRule.js b/lib/rules/tripleEqualsRule.js new file mode 100644 index 00000000000..d8b5bd4bea0 --- /dev/null +++ b/lib/rules/tripleEqualsRule.js @@ -0,0 +1,67 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_ALLOW_NULL_CHECK = "allow-null-check"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var comparisonWalker = new ComparisonWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(comparisonWalker); + }; + Rule.EQ_FAILURE_STRING = "== should be ==="; + Rule.NEQ_FAILURE_STRING = "!= should be !=="; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var ComparisonWalker = (function (_super) { + __extends(ComparisonWalker, _super); + function ComparisonWalker() { + _super.apply(this, arguments); + } + ComparisonWalker.prototype.visitBinaryExpression = function (node) { + if (!this.isExpressionAllowed(node)) { + var position = node.getChildAt(1).getStart(); + this.handleOperatorToken(position, node.operatorToken.kind); + } + _super.prototype.visitBinaryExpression.call(this, node); + }; + ComparisonWalker.prototype.handleOperatorToken = function (position, operator) { + switch (operator) { + case 30 /* EqualsEqualsToken */: + this.addFailure(this.createFailure(position, ComparisonWalker.COMPARISON_OPERATOR_WIDTH, Rule.EQ_FAILURE_STRING)); + break; + case 31 /* ExclamationEqualsToken */: + this.addFailure(this.createFailure(position, ComparisonWalker.COMPARISON_OPERATOR_WIDTH, Rule.NEQ_FAILURE_STRING)); + break; + } + }; + ComparisonWalker.prototype.isExpressionAllowed = function (node) { + var nullKeyword = 91 /* NullKeyword */; + return this.hasOption(OPTION_ALLOW_NULL_CHECK) + && (node.left.kind === nullKeyword || node.right.kind === nullKeyword); + }; + ComparisonWalker.COMPARISON_OPERATOR_WIDTH = 2; + return ComparisonWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/typedefRule.d.ts b/lib/rules/typedefRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/typedefRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/typedefRule.js b/lib/rules/typedefRule.js new file mode 100644 index 00000000000..496e460adb5 --- /dev/null +++ b/lib/rules/typedefRule.js @@ -0,0 +1,136 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var typedefWalker = new TypedefWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(typedefWalker); + }; + Rule.FAILURE_STRING = "missing type declaration"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var TypedefWalker = (function (_super) { + __extends(TypedefWalker, _super); + function TypedefWalker() { + _super.apply(this, arguments); + } + TypedefWalker.prototype.visitFunctionDeclaration = function (node) { + this.handleCallSignature(node); + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + TypedefWalker.prototype.visitFunctionExpression = function (node) { + this.handleCallSignature(node); + _super.prototype.visitFunctionExpression.call(this, node); + }; + TypedefWalker.prototype.visitGetAccessor = function (node) { + this.handleCallSignature(node); + _super.prototype.visitGetAccessor.call(this, node); + }; + TypedefWalker.prototype.visitMethodDeclaration = function (node) { + this.handleCallSignature(node); + _super.prototype.visitMethodDeclaration.call(this, node); + }; + TypedefWalker.prototype.visitMethodSignature = function (node) { + this.handleCallSignature(node); + _super.prototype.visitMethodSignature.call(this, node); + }; + TypedefWalker.prototype.visitObjectLiteralExpression = function (node) { + for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { + var property = _a[_i]; + switch (property.kind) { + case 243 /* PropertyAssignment */: + this.visitPropertyAssignment(property); + break; + case 141 /* MethodDeclaration */: + this.visitMethodDeclaration(property); + break; + case 143 /* GetAccessor */: + this.visitGetAccessor(property); + break; + case 144 /* SetAccessor */: + this.visitSetAccessor(property); + break; + } + } + }; + TypedefWalker.prototype.visitParameterDeclaration = function (node) { + // a parameter's "type" could be a specific string value, for example `fn(option: "someOption", anotherOption: number)` + if (node.type == null || node.type.kind !== 9 /* StringLiteral */) { + this.checkTypeAnnotation("parameter", node.getEnd(), node.type, node.name); + } + _super.prototype.visitParameterDeclaration.call(this, node); + }; + TypedefWalker.prototype.visitPropertyAssignment = function (node) { + switch (node.initializer.kind) { + case 172 /* ArrowFunction */: + case 171 /* FunctionExpression */: + this.handleCallSignature(node.initializer); + break; + } + _super.prototype.visitPropertyAssignment.call(this, node); + }; + TypedefWalker.prototype.visitPropertyDeclaration = function (node) { + var optionName = "member-variable-declaration"; + this.checkTypeAnnotation(optionName, node.name.getEnd(), node.type, node.name); + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + TypedefWalker.prototype.visitPropertySignature = function (node) { + var optionName = "property-declaration"; + this.checkTypeAnnotation(optionName, node.name.getEnd(), node.type, node.name); + _super.prototype.visitPropertySignature.call(this, node); + }; + TypedefWalker.prototype.visitSetAccessor = function (node) { + this.handleCallSignature(node); + _super.prototype.visitSetAccessor.call(this, node); + }; + TypedefWalker.prototype.visitVariableDeclaration = function (node) { + // first parent is the variableDeclarationList, grandparent would be the for-in statement + if (node.parent.parent.kind !== 198 /* ForInStatement */ + && node.parent.kind !== 242 /* CatchClause */) { + this.checkTypeAnnotation("variable-declaration", node.name.getEnd(), node.type, node.name); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + TypedefWalker.prototype.handleCallSignature = function (node) { + var location = (node.parameters != null) ? node.parameters.end : null; + // set accessors can't have a return type. + if (node.kind !== 144 /* SetAccessor */) { + this.checkTypeAnnotation("call-signature", location, node.type, node.name); + } + }; + TypedefWalker.prototype.checkTypeAnnotation = function (option, location, typeAnnotation, name) { + if (this.hasOption(option) && typeAnnotation == null) { + var ns = ""; + if (name != null && name.kind === 67 /* Identifier */) { + ns = ": '" + name.text + "'"; + } + var failure = this.createFailure(location, 1, "expected " + option + ns + " to have a typedef"); + this.addFailure(failure); + } + }; + return TypedefWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/typedefWhitespaceRule.d.ts b/lib/rules/typedefWhitespaceRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/typedefWhitespaceRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/typedefWhitespaceRule.js b/lib/rules/typedefWhitespaceRule.js new file mode 100644 index 00000000000..a527bca39f4 --- /dev/null +++ b/lib/rules/typedefWhitespaceRule.js @@ -0,0 +1,116 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new TypedefWhitespaceWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "missing type declaration"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var TypedefWhitespaceWalker = (function (_super) { + __extends(TypedefWhitespaceWalker, _super); + function TypedefWhitespaceWalker() { + _super.apply(this, arguments); + } + TypedefWhitespaceWalker.prototype.visitFunctionDeclaration = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitFunctionExpression = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitFunctionExpression.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitGetAccessor = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitGetAccessor.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitIndexSignatureDeclaration = function (node) { + var indexParameter = node.parameters[0]; + if (indexParameter != null) { + this.checkSpace("index-signature", indexParameter, indexParameter.type, indexParameter.name.getEnd()); + } + _super.prototype.visitIndexSignatureDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitMethodDeclaration = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitMethodDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitMethodSignature = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitMethodSignature.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitParameterDeclaration = function (node) { + this.checkSpace("parameter", node, node.type, node.name.getEnd()); + _super.prototype.visitParameterDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitPropertyDeclaration = function (node) { + this.checkSpace("property-declaration", node, node.type, node.name.getEnd()); + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitPropertySignature = function (node) { + this.checkSpace("property-declaration", node, node.type, node.name.getEnd()); + _super.prototype.visitPropertySignature.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitSetAccessor = function (node) { + this.checkSpace("call-signature", node, node.type, node.parameters.end + 1); + _super.prototype.visitSetAccessor.call(this, node); + }; + TypedefWhitespaceWalker.prototype.visitVariableDeclaration = function (node) { + this.checkSpace("variable-declaration", node, node.type, node.name.getEnd()); + _super.prototype.visitVariableDeclaration.call(this, node); + }; + TypedefWhitespaceWalker.prototype.checkSpace = function (option, node, typeNode, positionBeforeColon) { + if (this.hasOption(option) && typeNode != null && positionBeforeColon != null) { + var scanner = ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, node.getText()); + var hasLeadingWhitespace; + scanner.setTextPos(positionBeforeColon - node.getStart()); + hasLeadingWhitespace = scanner.scan() === 5 /* WhitespaceTrivia */; + if (hasLeadingWhitespace !== (this.getOption(option) === "space")) { + var message = "expected " + this.getOption(option) + " in " + option; + this.addFailure(this.createFailure(positionBeforeColon, 1, message)); + } + } + }; + TypedefWhitespaceWalker.prototype.hasOption = function (option) { + var allOptions = this.getOptions(); + if (allOptions == null || allOptions.length === 0) { + return false; + } + var options = allOptions[0]; + return options == null || options[option] != null; + }; + TypedefWhitespaceWalker.prototype.getOption = function (option) { + var allOptions = this.getOptions(); + if (allOptions == null || allOptions.length === 0) { + return null; + } + var options = allOptions[0]; + return options[option]; + }; + return TypedefWhitespaceWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/useStrictRule.d.ts b/lib/rules/useStrictRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/useStrictRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/useStrictRule.js b/lib/rules/useStrictRule.js new file mode 100644 index 00000000000..6c7aef43ff2 --- /dev/null +++ b/lib/rules/useStrictRule.js @@ -0,0 +1,84 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var useStrictWalker = new UseStrictWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(useStrictWalker); + }; + Rule.FAILURE_STRING = "missing 'use strict'"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var UseStrictWalker = (function (_super) { + __extends(UseStrictWalker, _super); + function UseStrictWalker() { + _super.apply(this, arguments); + } + UseStrictWalker.prototype.createScope = function () { + return {}; + }; + UseStrictWalker.prototype.visitModuleDeclaration = function (node) { + // current depth is 2: global scope and the scope created by this module + if (this.getCurrentDepth() === 2 + && !Lint.hasModifier(node.modifiers, 120 /* DeclareKeyword */) + && this.hasOption(UseStrictWalker.OPTION_CHECK_MODULE) + && node.body != null + && node.body.kind === 217 /* ModuleBlock */) { + this.handleBlock(node, node.body); + } + _super.prototype.visitModuleDeclaration.call(this, node); + }; + UseStrictWalker.prototype.visitFunctionDeclaration = function (node) { + // current depth is 2: global scope and the scope created by this function + if (this.getCurrentDepth() === 2 && + this.hasOption(UseStrictWalker.OPTION_CHECK_FUNCTION) && + node.body != null) { + this.handleBlock(node, node.body); + } + _super.prototype.visitFunctionDeclaration.call(this, node); + }; + UseStrictWalker.prototype.handleBlock = function (node, block) { + var isFailure = true; + if (block.statements != null && block.statements.length > 0) { + var firstStatement = block.statements[0]; + if (firstStatement.kind === 193 /* ExpressionStatement */) { + var firstChild = firstStatement.getChildAt(0); + if (firstChild.kind === 9 /* StringLiteral */ + && firstChild.text === UseStrictWalker.USE_STRICT_STRING) { + isFailure = false; + } + } + } + if (isFailure) { + this.addFailure(this.createFailure(node.getStart(), node.getFirstToken().getWidth(), Rule.FAILURE_STRING)); + } + }; + UseStrictWalker.OPTION_CHECK_FUNCTION = "check-function"; + UseStrictWalker.OPTION_CHECK_MODULE = "check-module"; + UseStrictWalker.USE_STRICT_STRING = "use strict"; + return UseStrictWalker; +})(Lint.ScopeAwareRuleWalker); diff --git a/lib/rules/variableNameRule.d.ts b/lib/rules/variableNameRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/variableNameRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/variableNameRule.js b/lib/rules/variableNameRule.js new file mode 100644 index 00000000000..769c272145b --- /dev/null +++ b/lib/rules/variableNameRule.js @@ -0,0 +1,98 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_LEADING_UNDERSCORE = "allow-leading-underscore"; +var OPTION_TRAILING_UNDERSCORE = "allow-trailing-underscore"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + var variableNameWalker = new VariableNameWalker(sourceFile, this.getOptions()); + return this.applyWithWalker(variableNameWalker); + }; + Rule.FAILURE_STRING = "variable name must be in camelcase or uppercase"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var VariableNameWalker = (function (_super) { + __extends(VariableNameWalker, _super); + function VariableNameWalker() { + _super.apply(this, arguments); + } + VariableNameWalker.prototype.visitBindingElement = function (node) { + if (node.name.kind === 67 /* Identifier */) { + this.handleVariableName(node.name); + } + _super.prototype.visitBindingElement.call(this, node); + }; + VariableNameWalker.prototype.visitParameterDeclaration = function (node) { + if (node.name.kind === 67 /* Identifier */) { + this.handleVariableName(node.name); + } + _super.prototype.visitParameterDeclaration.call(this, node); + }; + VariableNameWalker.prototype.visitPropertyDeclaration = function (node) { + if (node.name != null && node.name.kind === 67 /* Identifier */) { + this.handleVariableName(node.name); + } + _super.prototype.visitPropertyDeclaration.call(this, node); + }; + VariableNameWalker.prototype.visitVariableDeclaration = function (node) { + if (node.name.kind === 67 /* Identifier */) { + this.handleVariableName(node.name); + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + VariableNameWalker.prototype.visitVariableStatement = function (node) { + // skip 'declare' keywords + if (!Lint.hasModifier(node.modifiers, 120 /* DeclareKeyword */)) { + _super.prototype.visitVariableStatement.call(this, node); + } + }; + VariableNameWalker.prototype.handleVariableName = function (name) { + var variableName = name.text; + if (!this.isCamelCase(variableName) && !this.isUpperCase(variableName)) { + this.addFailure(this.createFailure(name.getStart(), name.getWidth(), Rule.FAILURE_STRING)); + } + }; + VariableNameWalker.prototype.isCamelCase = function (name) { + var firstCharacter = name.charAt(0); + var lastCharacter = name.charAt(name.length - 1); + var middle = name.substr(1, name.length - 2); + if (name.length <= 0) { + return true; + } + if (!this.hasOption(OPTION_LEADING_UNDERSCORE) && firstCharacter === "_") { + return false; + } + if (!this.hasOption(OPTION_TRAILING_UNDERSCORE) && lastCharacter === "_") { + return false; + } + return firstCharacter === firstCharacter.toLowerCase() && middle.indexOf("_") === -1; + }; + VariableNameWalker.prototype.isUpperCase = function (name) { + return name === name.toUpperCase(); + }; + return VariableNameWalker; +})(Lint.RuleWalker); diff --git a/lib/rules/whitespaceRule.d.ts b/lib/rules/whitespaceRule.d.ts new file mode 100644 index 00000000000..18efa882318 --- /dev/null +++ b/lib/rules/whitespaceRule.d.ts @@ -0,0 +1,6 @@ +import * as Lint from "../lint"; +import * as ts from "typescript"; +export declare class Rule extends Lint.Rules.AbstractRule { + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/lib/rules/whitespaceRule.js b/lib/rules/whitespaceRule.js new file mode 100644 index 00000000000..d100fc00f6d --- /dev/null +++ b/lib/rules/whitespaceRule.js @@ -0,0 +1,217 @@ +var __extends = (this && this.__extends) || function (d, b) { + for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); +}; +/* + * 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. + */ +var Lint = require("../lint"); +var ts = require("typescript"); +var OPTION_BRANCH = "check-branch"; +var OPTION_DECL = "check-decl"; +var OPTION_OPERATOR = "check-operator"; +var OPTION_MODULE = "check-module"; +var OPTION_SEPARATOR = "check-separator"; +var OPTION_TYPE = "check-type"; +var OPTION_TYPECAST = "check-typecast"; +var Rule = (function (_super) { + __extends(Rule, _super); + function Rule() { + _super.apply(this, arguments); + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new WhitespaceWalker(sourceFile, this.getOptions())); + }; + Rule.FAILURE_STRING = "missing whitespace"; + return Rule; +})(Lint.Rules.AbstractRule); +exports.Rule = Rule; +var WhitespaceWalker = (function (_super) { + __extends(WhitespaceWalker, _super); + function WhitespaceWalker(sourceFile, options) { + _super.call(this, sourceFile, options); + this.scanner = ts.createScanner(1 /* ES5 */, false, 0 /* Standard */, sourceFile.text); + } + WhitespaceWalker.prototype.visitSourceFile = function (node) { + var _this = this; + _super.prototype.visitSourceFile.call(this, node); + var prevTokenShouldBeFollowedByWhitespace = false; + this.scanner.setTextPos(0); + Lint.scanAllTokens(this.scanner, function (scanner) { + var startPos = scanner.getStartPos(); + var tokenKind = scanner.getToken(); + if (tokenKind === 5 /* WhitespaceTrivia */ || tokenKind === 4 /* NewLineTrivia */) { + prevTokenShouldBeFollowedByWhitespace = false; + } + else if (prevTokenShouldBeFollowedByWhitespace) { + var failure = _this.createFailure(startPos, 1, Rule.FAILURE_STRING); + _this.addFailure(failure); + prevTokenShouldBeFollowedByWhitespace = false; + } + if (_this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(_this.tokensToSkipStartEndMap[startPos]); + return; + } + // check for trailing space after the given tokens + switch (tokenKind) { + case 70 /* CatchKeyword */: + case 84 /* ForKeyword */: + case 86 /* IfKeyword */: + case 94 /* SwitchKeyword */: + case 102 /* WhileKeyword */: + case 103 /* WithKeyword */: + if (_this.hasOption(OPTION_BRANCH)) { + prevTokenShouldBeFollowedByWhitespace = true; + } + break; + case 24 /* CommaToken */: + case 23 /* SemicolonToken */: + if (_this.hasOption(OPTION_SEPARATOR)) { + prevTokenShouldBeFollowedByWhitespace = true; + } + break; + case 55 /* EqualsToken */: + if (_this.hasOption(OPTION_DECL)) { + prevTokenShouldBeFollowedByWhitespace = true; + } + break; + case 53 /* ColonToken */: + if (_this.hasOption(OPTION_TYPE)) { + prevTokenShouldBeFollowedByWhitespace = true; + } + break; + case 87 /* ImportKeyword */: + case 80 /* ExportKeyword */: + case 131 /* FromKeyword */: + if (_this.hasOption(OPTION_MODULE)) { + prevTokenShouldBeFollowedByWhitespace = true; + } + break; + } + }); + }; + WhitespaceWalker.prototype.visitArrowFunction = function (node) { + this.checkEqualsGreaterThanTokenInNode(node); + _super.prototype.visitArrowFunction.call(this, node); + }; + // check for spaces between the operator symbol (except in the case of comma statements) + WhitespaceWalker.prototype.visitBinaryExpression = function (node) { + if (this.hasOption(OPTION_OPERATOR) && node.operatorToken.kind !== 24 /* CommaToken */) { + this.checkForTrailingWhitespace(node.left.getEnd()); + this.checkForTrailingWhitespace(node.right.getFullStart()); + } + _super.prototype.visitBinaryExpression.call(this, node); + }; + // check for spaces between ternary operator symbols + WhitespaceWalker.prototype.visitConditionalExpression = function (node) { + if (this.hasOption(OPTION_OPERATOR)) { + this.checkForTrailingWhitespace(node.condition.getEnd()); + this.checkForTrailingWhitespace(node.whenTrue.getFullStart()); + this.checkForTrailingWhitespace(node.whenTrue.getEnd()); + } + _super.prototype.visitConditionalExpression.call(this, node); + }; + WhitespaceWalker.prototype.visitConstructorType = function (node) { + this.checkEqualsGreaterThanTokenInNode(node); + _super.prototype.visitConstructorType.call(this, node); + }; + WhitespaceWalker.prototype.visitExportAssignment = function (node) { + if (this.hasOption(OPTION_MODULE)) { + var exportKeyword = node.getChildAt(0); + var position = exportKeyword.getEnd(); + this.checkForTrailingWhitespace(position); + } + _super.prototype.visitExportAssignment.call(this, node); + }; + WhitespaceWalker.prototype.visitFunctionType = function (node) { + this.checkEqualsGreaterThanTokenInNode(node); + _super.prototype.visitFunctionType.call(this, node); + }; + WhitespaceWalker.prototype.visitImportDeclaration = function (node) { + var importClause = node.importClause; + if (this.hasOption(OPTION_MODULE) && importClause != null) { + // an import clause can have _both_ named bindings and a name (the latter for the default import) + // but the named bindings always come last, so we only need to check that for whitespace + var position = (importClause.namedBindings == null) ? importClause.name.getEnd() + : importClause.namedBindings.getEnd(); + this.checkForTrailingWhitespace(position); + } + _super.prototype.visitImportDeclaration.call(this, node); + }; + WhitespaceWalker.prototype.visitImportEqualsDeclaration = function (node) { + if (this.hasOption(OPTION_MODULE)) { + var position = node.name.getEnd(); + this.checkForTrailingWhitespace(position); + } + _super.prototype.visitImportEqualsDeclaration.call(this, node); + }; + WhitespaceWalker.prototype.visitJsxElement = function (node) { + this.addTokenToSkipFromNode(node); + _super.prototype.visitJsxElement.call(this, node); + }; + WhitespaceWalker.prototype.visitJsxSelfClosingElement = function (node) { + this.addTokenToSkipFromNode(node); + _super.prototype.visitJsxSelfClosingElement.call(this, node); + }; + WhitespaceWalker.prototype.visitTypeAssertionExpression = function (node) { + if (this.hasOption(OPTION_TYPECAST)) { + var position = node.expression.getFullStart(); + this.checkForTrailingWhitespace(position); + } + _super.prototype.visitTypeAssertionExpression.call(this, node); + }; + WhitespaceWalker.prototype.visitVariableDeclaration = function (node) { + if (this.hasOption(OPTION_DECL) && node.initializer != null) { + if (node.type != null) { + this.checkForTrailingWhitespace(node.type.getEnd()); + } + else { + this.checkForTrailingWhitespace(node.name.getEnd()); + } + } + _super.prototype.visitVariableDeclaration.call(this, node); + }; + WhitespaceWalker.prototype.checkEqualsGreaterThanTokenInNode = function (node) { + var arrowChildNumber = -1; + node.getChildren().forEach(function (child, i) { + if (child.kind === 34 /* EqualsGreaterThanToken */) { + arrowChildNumber = i; + } + }); + // condition so we don't crash if the arrow is somehow missing + if (arrowChildNumber !== -1) { + var equalsGreaterThanToken = node.getChildAt(arrowChildNumber); + if (this.hasOption(OPTION_OPERATOR)) { + var position = equalsGreaterThanToken.getFullStart(); + this.checkForTrailingWhitespace(position); + position = equalsGreaterThanToken.getEnd(); + this.checkForTrailingWhitespace(position); + } + } + }; + WhitespaceWalker.prototype.checkForTrailingWhitespace = function (position) { + this.scanner.setTextPos(position); + var nextTokenType = this.scanner.scan(); + if (nextTokenType !== 5 /* WhitespaceTrivia */ + && nextTokenType !== 4 /* NewLineTrivia */ + && nextTokenType !== 1 /* EndOfFileToken */) { + this.addFailure(this.createFailure(position, 1, Rule.FAILURE_STRING)); + } + }; + return WhitespaceWalker; +})(Lint.SkippableTokenAwareRuleWalker); diff --git a/lib/tslint-cli.d.ts b/lib/tslint-cli.d.ts new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/tslint-cli.js b/lib/tslint-cli.js new file mode 100644 index 00000000000..ba744a4a598 --- /dev/null +++ b/lib/tslint-cli.js @@ -0,0 +1,115 @@ +/* + * 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. + */ +var Linter = require("./tslint"); +var fs = require("fs"); +var optimist = require("optimist"); +optimist + .usage("Usage: $0 [options] [file ...]") + .check(function (argv) { + // at least one of file, help, version or unqualified argument must be present + if (!(argv.h || argv.v || argv._.length > 0)) { + throw "Missing files"; + } + if (argv.f) { + throw "-f option is no longer available. Supply files directly to the tslint command instead."; + } +}) + .options({ + "c": { + alias: "config", + describe: "configuration file" + }, + "h": { + alias: "help", + describe: "display detailed help" + }, + "o": { + alias: "out", + describe: "output file" + }, + "r": { + alias: "rules-dir", + describe: "rules directory" + }, + "s": { + alias: "formatters-dir", + describe: "formatters directory" + }, + "t": { + alias: "format", + default: "prose", + describe: "output format (prose, json, verbose)" + }, + "v": { + alias: "version", + describe: "current version" + } +}); +var argv = optimist.argv; +var outputStream; +if (argv.o !== undefined) { + outputStream = fs.createWriteStream(argv.o, { + flags: "w+", + mode: 420 + }); +} +else { + outputStream = process.stdout; +} +if (argv.v !== undefined) { + outputStream.write(Linter.VERSION + "\n"); + process.exit(0); +} +if ("help" in argv) { + outputStream.write(optimist.help()); + var outputString = "\ntslint accepts the following commandline options:\n\n -c, --config:\n The location of the configuration file that tslint will use to\n determine which rules are activated and what options to provide\n to the rules. If no option is specified, the config file named\n tslint.json is used, so long as it exists in the path.\n The format of the file is { rules: { /* rules list */ } },\n where /* rules list */ is a key: value comma-seperated list of\n rulename: rule-options pairs. Rule-options can be either a\n boolean true/false value denoting whether the rule is used or not,\n or a list [boolean, ...] where the boolean provides the same role\n as in the non-list case, and the rest of the list are options passed\n to the rule that will determine what it checks for (such as number\n of characters for the max-line-length rule, or what functions to ban\n for the ban rule).\n\n -o, --out:\n A filename to output the results to. By default, tslint outputs to\n stdout, which is usually the console where you're running it from.\n\n -r, --rules-dir:\n An additional rules directory, for additional user-created rules.\n tslint will always check its default rules directory, in\n node_modules/tslint/build/rules, before checking the user-provided\n rules directory, so rules in the user-provided rules directory\n with the same name as the base rules will not be loaded.\n\n -s, --formatters-dir:\n An additional formatters directory, for user-created formatters.\n Formatters are files that will format the tslint output, before\n writing it to stdout or the file passed in --out. The default\n directory, node_modules/tslint/build/formatters, will always be\n checked first, so user-created formatters with the same names\n as the base formatters will not be loaded.\n\n -t, --format:\n The formatter to use to format the results of the linter before\n outputting it to stdout or the file passed in --out. The core\n formatters are prose (human readable), json (machine readable)\n and verbose. prose is the default if this option is not used. Additonal\n formatters can be added and used if the --formatters-dir option is set.\n\n -v, --version:\n The current version of tslint.\n\n -h, --help:\n Prints this help message.\n"; + outputStream.write(outputString); + process.exit(0); +} +// when provided, it should point to an existing location +if (argv.c && !fs.existsSync(argv.c)) { + console.error("Invalid option for configuration: " + argv.c); + process.exit(1); +} +var processFile = function (file) { + if (!fs.existsSync(file)) { + console.error("Unable to open file: " + file); + process.exit(1); + } + var contents = fs.readFileSync(file, "utf8"); + var configuration = Linter.findConfiguration(argv.c, file); + if (configuration === undefined) { + console.error("unable to find tslint configuration"); + process.exit(1); + } + var linter = new Linter(file, contents, { + configuration: configuration, + formatter: argv.t, + formattersDirectory: argv.s, + rulesDirectory: argv.r + }); + var lintResult = linter.lint(); + if (lintResult.failureCount > 0) { + outputStream.write(lintResult.output, function () { + process.exit(2); + }); + } +}; +var files = argv._; +for (var _i = 0; _i < files.length; _i++) { + var file = files[_i]; + processFile(file); +} diff --git a/lib/tslint.d.ts b/lib/tslint.d.ts index db1832ed825..7cf90020412 100644 --- a/lib/tslint.d.ts +++ b/lib/tslint.d.ts @@ -1,249 +1,20 @@ -declare module Lint { - class SyntaxWalker { - walk(node: ts.Node): void; - protected visitAnyKeyword(node: ts.Node): void; - protected visitArrowFunction(node: ts.FunctionLikeDeclaration): void; - protected visitBinaryExpression(node: ts.BinaryExpression): void; - protected visitBindingElement(node: ts.BindingElement): void; - protected visitBlock(node: ts.Block): void; - protected visitBreakStatement(node: ts.BreakOrContinueStatement): void; - protected visitCallExpression(node: ts.CallExpression): void; - protected visitCallSignature(node: ts.SignatureDeclaration): void; - protected visitCaseClause(node: ts.CaseClause): void; - protected visitClassDeclaration(node: ts.ClassDeclaration): void; - protected visitCatchClause(node: ts.CatchClause): void; - protected visitConditionalExpression(node: ts.ConditionalExpression): void; - protected visitConstructorDeclaration(node: ts.ConstructorDeclaration): void; - protected visitConstructorType(node: ts.FunctionOrConstructorTypeNode): void; - protected visitContinueStatement(node: ts.BreakOrContinueStatement): void; - protected visitDebuggerStatement(node: ts.Statement): void; - protected visitDefaultClause(node: ts.DefaultClause): void; - protected visitDoStatement(node: ts.DoStatement): void; - protected visitElementAccessExpression(node: ts.ElementAccessExpression): void; - protected visitEnumDeclaration(node: ts.EnumDeclaration): void; - protected visitExportAssignment(node: ts.ExportAssignment): void; - protected visitExpressionStatement(node: ts.ExpressionStatement): void; - protected visitForStatement(node: ts.ForStatement): void; - protected visitForInStatement(node: ts.ForInStatement): void; - protected visitForOfStatement(node: ts.ForOfStatement): void; - protected visitFunctionDeclaration(node: ts.FunctionDeclaration): void; - protected visitFunctionExpression(node: ts.FunctionExpression): void; - protected visitFunctionType(node: ts.FunctionOrConstructorTypeNode): void; - protected visitGetAccessor(node: ts.AccessorDeclaration): void; - protected visitIdentifier(node: ts.Identifier): void; - protected visitIfStatement(node: ts.IfStatement): void; - protected visitImportDeclaration(node: ts.ImportDeclaration): void; - protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration): void; - protected visitIndexSignatureDeclaration(node: ts.IndexSignatureDeclaration): void; - protected visitInterfaceDeclaration(node: ts.InterfaceDeclaration): void; - protected visitJsxElement(node: ts.JsxElement): void; - protected visitJsxSelfClosingElement(node: ts.JsxSelfClosingElement): void; - protected visitLabeledStatement(node: ts.LabeledStatement): void; - protected visitMethodDeclaration(node: ts.MethodDeclaration): void; - protected visitMethodSignature(node: ts.SignatureDeclaration): void; - protected visitModuleDeclaration(node: ts.ModuleDeclaration): void; - protected visitNamedImports(node: ts.NamedImports): void; - protected visitNamespaceImport(node: ts.NamespaceImport): void; - protected visitNewExpression(node: ts.NewExpression): void; - protected visitObjectLiteralExpression(node: ts.ObjectLiteralExpression): void; - protected visitParameterDeclaration(node: ts.ParameterDeclaration): void; - protected visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression): void; - protected visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression): void; - protected visitPropertyAccessExpression(node: ts.PropertyAccessExpression): void; - protected visitPropertyAssignment(node: ts.PropertyAssignment): void; - protected visitPropertyDeclaration(node: ts.PropertyDeclaration): void; - protected visitPropertySignature(node: ts.Node): void; - protected visitRegularExpressionLiteral(node: ts.Node): void; - protected visitReturnStatement(node: ts.ReturnStatement): void; - protected visitSetAccessor(node: ts.AccessorDeclaration): void; - protected visitSourceFile(node: ts.SourceFile): void; - protected visitSwitchStatement(node: ts.SwitchStatement): void; - protected visitTemplateExpression(node: ts.TemplateExpression): void; - protected visitThrowStatement(node: ts.ThrowStatement): void; - protected visitTryStatement(node: ts.TryStatement): void; - protected visitTypeAssertionExpression(node: ts.TypeAssertion): void; - protected visitTypeLiteral(node: ts.TypeLiteralNode): void; - protected visitVariableDeclaration(node: ts.VariableDeclaration): void; - protected visitVariableStatement(node: ts.VariableStatement): void; - protected visitWhileStatement(node: ts.WhileStatement): void; - protected visitNode(node: ts.Node): void; - protected walkChildren(node: ts.Node): void; - } -} -declare module Lint { - class RuleWalker extends Lint.SyntaxWalker { - private limit; - private position; - private options; - private failures; - private sourceFile; - private disabledIntervals; - private ruleName; - constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); - getSourceFile(): ts.SourceFile; - getFailures(): RuleFailure[]; - getLimit(): number; - getOptions(): any; - hasOption(option: string): boolean; - skip(node: ts.Node): void; - createFailure(start: number, width: number, failure: string): RuleFailure; - addFailure(failure: RuleFailure): void; - private existsFailure(failure); - } -} -declare module Lint { - abstract class ScopeAwareRuleWalker extends RuleWalker { - private scopeStack; - constructor(sourceFile: ts.SourceFile, options?: any); - abstract createScope(): T; - getCurrentScope(): T; - getAllScopes(): T[]; - getCurrentDepth(): number; - onScopeStart(): void; - onScopeEnd(): void; - protected visitNode(node: ts.Node): void; - protected isScopeBoundary(node: ts.Node): boolean; - } -} -declare module Lint.Formatters { - abstract class AbstractFormatter implements Lint.IFormatter { - abstract format(failures: Lint.RuleFailure[]): string; - } -} -declare module Lint { - interface IFormatter { - format(failures: Lint.RuleFailure[]): string; - } -} -declare module Lint { - function createLanguageServiceHost(fileName: string, source: string): ts.LanguageServiceHost; - function createLanguageService(fileName: string, source: string): ts.LanguageService; -} -declare module Lint.Rules { - abstract class AbstractRule implements Lint.IRule { - private value; - private options; - constructor(ruleName: string, value: any, disabledIntervals: Lint.IDisabledInterval[]); - getOptions(): Lint.IOptions; - abstract apply(sourceFile: ts.SourceFile): RuleFailure[]; - applyWithWalker(walker: Lint.RuleWalker): RuleFailure[]; - isEnabled(): boolean; - } -} -declare module Lint { - interface IOptions { - ruleArguments?: any[]; - ruleName: string; - disabledIntervals: Lint.IDisabledInterval[]; - } - interface IDisabledInterval { - startPosition: number; - endPosition: number; - } - interface IRule { - getOptions(): IOptions; - isEnabled(): boolean; - apply(sourceFile: ts.SourceFile): RuleFailure[]; - applyWithWalker(walker: Lint.RuleWalker): RuleFailure[]; - } - class RuleFailurePosition { - private position; - private lineAndCharacter; - constructor(position: number, lineAndCharacter: ts.LineAndCharacter); - getPosition(): number; - getLineAndCharacter(): ts.LineAndCharacter; - toJson(): { - character: number; - line: number; - position: number; - }; - equals(ruleFailurePosition: RuleFailurePosition): boolean; - } - class RuleFailure { - private sourceFile; - private fileName; - private startPosition; - private endPosition; - private failure; - private ruleName; - constructor(sourceFile: ts.SourceFile, start: number, end: number, failure: string, ruleName: string); - getFileName(): string; - getRuleName(): string; - getStartPosition(): RuleFailurePosition; - getEndPosition(): RuleFailurePosition; - getFailure(): string; - toJson(): any; - equals(ruleFailure: RuleFailure): boolean; - private createFailurePosition(position); - } -} -declare module Lint { - function getSourceFile(fileName: string, source: string): ts.SourceFile; - function createCompilerOptions(): ts.CompilerOptions; - function doesIntersect(failure: RuleFailure, disabledIntervals: Lint.IDisabledInterval[]): boolean; - function abstract(): string; - function scanAllTokens(scanner: ts.Scanner, callback: (s: ts.Scanner) => void): void; - function hasModifier(modifiers: ts.ModifiersArray, ...modifierKinds: ts.SyntaxKind[]): boolean; - function isBlockScopedVariable(node: ts.VariableDeclaration | ts.VariableStatement): boolean; - function isBlockScopedBindingElement(node: ts.BindingElement): boolean; - function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean; -} -declare module Lint { - abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker { - private blockScopeStack; - constructor(sourceFile: ts.SourceFile, options?: any); - abstract createBlockScope(): U; - getCurrentBlockScope(): U; - onBlockScopeStart(): void; - getCurrentBlockDepth(): number; - onBlockScopeEnd(): void; - protected visitNode(node: ts.Node): void; - private isBlockScopeBoundary(node); - } -} -declare module Lint { - class SkippableTokenAwareRuleWalker extends RuleWalker { - protected tokensToSkipStartEndMap: { - [start: number]: number; - }; - constructor(sourceFile: ts.SourceFile, options: Lint.IOptions); - protected visitRegularExpressionLiteral(node: ts.Node): void; - protected visitIdentifier(node: ts.Identifier): void; - protected visitTemplateExpression(node: ts.TemplateExpression): void; - protected addTokenToSkipFromNode(node: ts.Node): void; - } -} -declare module Lint.Configuration { - function findConfiguration(configFile: string, inputFileLocation: string): any; -} -declare module Lint { - class EnableDisableRulesWalker extends Lint.SkippableTokenAwareRuleWalker { - enableDisableRuleMap: { - [rulename: string]: Lint.IEnableDisablePosition[]; - }; - visitSourceFile(node: ts.SourceFile): void; - private handlePossibleTslintSwitch(commentText, startingPosition); - } -} -declare module Lint { - function findFormatter(name: string, formattersDirectory?: string): any; -} -declare module Lint { - interface IEnableDisablePosition { - isEnabled: boolean; - position: number; - } - function loadRules(ruleConfiguration: { - [name: string]: any; - }, enableDisableRuleMap: { - [rulename: string]: Lint.IEnableDisablePosition[]; - }, rulesDirectory?: string): IRule[]; - function findRule(name: string, rulesDirectory?: string): any; -} -declare module Lint { +import * as Lint from "./lint"; +declare class Linter { + static VERSION: string; + private fileName; + private source; + private options; + constructor(fileName: string, source: string, options: Linter.ILinterOptions); + lint(): Linter.LintResult; + private getRelativePath(directory); + private containsRule(rules, rule); +} +import { findConfiguration as config } from "./configuration"; +declare namespace Linter { + var findConfiguration: typeof config; interface LintResult { failureCount: number; - failures: RuleFailure[]; + failures: Lint.RuleFailure[]; format: string; output: string; } @@ -253,18 +24,5 @@ declare module Lint { formattersDirectory: string; rulesDirectory: string; } - class Linter { - static VERSION: string; - private fileName; - private source; - private options; - constructor(fileName: string, source: string, options: ILinterOptions); - lint(): LintResult; - private getRelativePath(directory); - private containsRule(rules, rule); - } -} -declare module "tslint" { - import Linter = Lint.Linter; - export = Linter; } +export = Linter; diff --git a/package.json b/package.json index 7de9f77088f..0152d962354 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "tslint": "./bin/tslint" }, "main": "./lib/tslint", + "typings": "./lib/tslint", "repository": { "type": "git", "url": "https://github.com/palantir/tslint.git" diff --git a/src/.configuration.ts.swp b/src/.configuration.ts.swp deleted file mode 100644 index 5a4044b4653..00000000000 Binary files a/src/.configuration.ts.swp and /dev/null differ diff --git a/src/configuration.ts b/src/configuration.ts index 553124514aa..64d80d41895 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -14,71 +14,69 @@ * limitations under the License. */ -module Lint.Configuration { - const fs = require("fs"); - const path = require("path"); - const findup = require("findup-sync"); +import * as fs from "fs"; +import * as path from "path"; +import * as findup from "findup-sync"; - const CONFIG_FILENAME = "tslint.json"; - const DEFAULT_CONFIG = { - "rules": { - "curly": true, - "indent": [true, 4], - "no-duplicate-key": true, - "no-duplicate-variable": true, - "no-empty": true, - "no-eval": true, - "no-trailing-whitespace": true, - "no-unreachable": true, - "no-use-before-declare": true, - "quotemark": [true, "double"], - "semicolon": true - } - }; +const CONFIG_FILENAME = "tslint.json"; +const DEFAULT_CONFIG = { + "rules": { + "curly": true, + "indent": [true, 4], + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-trailing-whitespace": true, + "no-unreachable": true, + "no-use-before-declare": true, + "quotemark": [true, "double"], + "semicolon": true + } +}; - export function findConfiguration(configFile: string, inputFileLocation: string): any { - if (configFile) { - return JSON.parse(fs.readFileSync(configFile, "utf8")); - } +export function findConfiguration(configFile: string, inputFileLocation: string): any { + if (configFile) { + return JSON.parse(fs.readFileSync(configFile, "utf8")); + } - // first look for package.json from input file location - configFile = findup("package.json", { cwd: inputFileLocation, nocase: true }); + // first look for package.json from input file location + configFile = findup("package.json", { cwd: inputFileLocation, nocase: true }); - if (configFile) { - const content = require(configFile); + if (configFile) { + const content = require(configFile); - if (content.tslintConfig) { - return content.tslintConfig; - } + if (content.tslintConfig) { + return content.tslintConfig; } + } - // next look for tslint.json - const homeDir = getHomeDir(); - if (!homeDir) { - return undefined; - } + // next look for tslint.json + const homeDir = getHomeDir(); + if (!homeDir) { + return undefined; + } - const defaultPath = path.join(homeDir, CONFIG_FILENAME); + const defaultPath = path.join(homeDir, CONFIG_FILENAME); - configFile = findup(CONFIG_FILENAME, { cwd: inputFileLocation, nocase: true }) || defaultPath; + configFile = findup(CONFIG_FILENAME, { cwd: inputFileLocation, nocase: true }) || defaultPath; - if (fs.existsSync(configFile)) { - return JSON.parse(fs.readFileSync(configFile, "utf8")); - } else { - return DEFAULT_CONFIG; - } + if (fs.existsSync(configFile)) { + return JSON.parse(fs.readFileSync(configFile, "utf8")); + } else { + return DEFAULT_CONFIG; } +} - function getHomeDir() { - const environment = global.process.env; - const paths = [environment.USERPROFILE, environment.HOME, environment.HOMEPATH, environment.HOMEDRIVE + environment.HOMEPATH]; +function getHomeDir() { + const environment = global.process.env; + const paths = [environment.USERPROFILE, environment.HOME, environment.HOMEPATH, environment.HOMEDRIVE + environment.HOMEPATH]; - for (const homeIndex in paths) { - if (paths.hasOwnProperty(homeIndex)) { - const homePath = paths[homeIndex]; - if (homePath && fs.existsSync(homePath)) { - return homePath; - } + for (const homeIndex in paths) { + if (paths.hasOwnProperty(homeIndex)) { + const homePath = paths[homeIndex]; + if (homePath && fs.existsSync(homePath)) { + return homePath; } } } diff --git a/src/enableDisableRules.ts b/src/enableDisableRules.ts index 9f63b42e12a..45c6a99f36f 100644 --- a/src/enableDisableRules.ts +++ b/src/enableDisableRules.ts @@ -1,68 +1,68 @@ /* - * Copyright 2014 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. - */ +* Copyright 2014 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 Lint from "./lint"; +import * as ts from "typescript"; -module Lint { - export class EnableDisableRulesWalker extends Lint.SkippableTokenAwareRuleWalker { - public enableDisableRuleMap: {[rulename: string]: Lint.IEnableDisablePosition[]} = {}; +export class EnableDisableRulesWalker extends Lint.SkippableTokenAwareRuleWalker { + public enableDisableRuleMap: {[rulename: string]: Lint.IEnableDisablePosition[]} = {}; - public visitSourceFile(node: ts.SourceFile) { - super.visitSourceFile(node); - const scan = ts.createScanner(ts.ScriptTarget.ES5, false, ts.LanguageVariant.Standard, node.text); - Lint.scanAllTokens(scan, (scanner: ts.Scanner) => { - const startPos = scanner.getStartPos(); - if (this.tokensToSkipStartEndMap[startPos] != null) { - // tokens to skip are places where the scanner gets confused about what the token is, without the proper context - // (specifically, regex, identifiers, and templates). So skip those tokens. - scanner.setTextPos(this.tokensToSkipStartEndMap[startPos]); - return; - } + public visitSourceFile(node: ts.SourceFile) { + super.visitSourceFile(node); + const scan = ts.createScanner(ts.ScriptTarget.ES5, false, ts.LanguageVariant.Standard, node.text); + Lint.scanAllTokens(scan, (scanner: ts.Scanner) => { + const startPos = scanner.getStartPos(); + if (this.tokensToSkipStartEndMap[startPos] != null) { + // tokens to skip are places where the scanner gets confused about what the token is, without the proper context + // (specifically, regex, identifiers, and templates). So skip those tokens. + scanner.setTextPos(this.tokensToSkipStartEndMap[startPos]); + return; + } - if (scanner.getToken() === ts.SyntaxKind.MultiLineCommentTrivia) { - const commentText = scanner.getTokenText(); - const startPosition = scanner.getTokenPos(); - this.handlePossibleTslintSwitch(commentText, startPosition); - } - }); - } + if (scanner.getToken() === ts.SyntaxKind.MultiLineCommentTrivia) { + const commentText = scanner.getTokenText(); + const startPosition = scanner.getTokenPos(); + this.handlePossibleTslintSwitch(commentText, startPosition); + } + }); + } - private handlePossibleTslintSwitch(commentText: string, startingPosition: number) { - const currentPosition = startingPosition; - // regex is: start of string followed by "/*" followed by any amount of whitespace followed by "tslint:" - if (commentText.match(/^\/\*\s*tslint:/)) { - const commentTextParts = commentText.split(":"); - // regex is: start of string followed by either "enable" or "disable" - // followed by either whitespace or end of string - const enableOrDisableMatch = commentTextParts[1].match(/^(enable|disable)(\s|$)/); - if (enableOrDisableMatch != null) { - const isEnabled = enableOrDisableMatch[1] === "enable"; - const position = currentPosition; - let rulesList = ["all"]; - if (commentTextParts.length > 2) { - rulesList = commentTextParts[2].split(/\s+/); + private handlePossibleTslintSwitch(commentText: string, startingPosition: number) { + const currentPosition = startingPosition; + // regex is: start of string followed by "/*" followed by any amount of whitespace followed by "tslint:" + if (commentText.match(/^\/\*\s*tslint:/)) { + const commentTextParts = commentText.split(":"); + // regex is: start of string followed by either "enable" or "disable" + // followed by either whitespace or end of string + const enableOrDisableMatch = commentTextParts[1].match(/^(enable|disable)(\s|$)/); + if (enableOrDisableMatch != null) { + const isEnabled = enableOrDisableMatch[1] === "enable"; + const position = currentPosition; + let rulesList = ["all"]; + if (commentTextParts.length > 2) { + rulesList = commentTextParts[2].split(/\s+/); + } + rulesList.forEach((ruleToAdd) => { + if (!(ruleToAdd in this.enableDisableRuleMap)) { + this.enableDisableRuleMap[ruleToAdd] = []; } - rulesList.forEach((ruleToAdd) => { - if (!(ruleToAdd in this.enableDisableRuleMap)) { - this.enableDisableRuleMap[ruleToAdd] = []; - } - this.enableDisableRuleMap[ruleToAdd].push({ - isEnabled: isEnabled, - position: position - }); + this.enableDisableRuleMap[ruleToAdd].push({ + isEnabled: isEnabled, + position: position }); - } + }); } } } diff --git a/src/formatterLoader.ts b/src/formatterLoader.ts index 96fc0ae79b9..218bcbadf93 100644 --- a/src/formatterLoader.ts +++ b/src/formatterLoader.ts @@ -1,71 +1,69 @@ /* - * 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. - */ +* 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. +*/ -module Lint { - const fs = require("fs"); - const path = require("path"); - const {camelize} = require("underscore.string"); +import * as fs from "fs"; +import * as path from "path"; +import {camelize} from "underscore.string"; - const moduleDirectory = path.dirname(module.filename); - const CORE_FORMATTERS_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "formatters"); +const moduleDirectory = path.dirname(module.filename); +const CORE_FORMATTERS_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "formatters"); - export function findFormatter(name: string, formattersDirectory?: string) { - if (typeof(name) === "function") { - return name; - } +export function findFormatter(name: string, formattersDirectory?: string) { + if (typeof(name) === "function") { + return name; + } - const camelizedName = camelize(name + "Formatter"); + const camelizedName = camelize(name + "Formatter"); + + // first check for core formatters + let Formatter = loadFormatter(CORE_FORMATTERS_DIRECTORY, camelizedName); + if (Formatter) { + return Formatter; + } - // first check for core formatters - let Formatter = loadFormatter(CORE_FORMATTERS_DIRECTORY, camelizedName); + // then check for rules within the first level of rulesDirectory + if (formattersDirectory) { + Formatter = loadFormatter(formattersDirectory, camelizedName); if (Formatter) { return Formatter; } - - // then check for rules within the first level of rulesDirectory - if (formattersDirectory) { - Formatter = loadFormatter(formattersDirectory, camelizedName); - if (Formatter) { - return Formatter; - } - } - - // else try to resolve as module - return loadFormatterModule(name); } - function loadFormatter(...paths: string[]) { - const formatterPath = paths.reduce((p, c) => path.join(p, c), ""); - const fullPath = path.resolve(moduleDirectory, formatterPath); + // else try to resolve as module + return loadFormatterModule(name); +} - if (fs.existsSync(fullPath + ".js")) { - const formatterModule = require(fullPath); - return formatterModule.Formatter; - } +function loadFormatter(...paths: string[]) { + const formatterPath = paths.reduce((p, c) => path.join(p, c), ""); + const fullPath = path.resolve(moduleDirectory, formatterPath); - return undefined; + if (fs.existsSync(fullPath + ".js")) { + const formatterModule = require(fullPath); + return formatterModule.Formatter; } - function loadFormatterModule(name: string) { - let src: string; - try { - src = require.resolve(name); - } catch (e) { - return undefined; - } - return require(src).Formatter; + return undefined; +} + +function loadFormatterModule(name: string) { + let src: string; + try { + src = require.resolve(name); + } catch (e) { + return undefined; } + return require(src).Formatter; } diff --git a/src/formatters.ts b/src/formatters.ts new file mode 100644 index 00000000000..a808faea53a --- /dev/null +++ b/src/formatters.ts @@ -0,0 +1,2 @@ +export * from "./language/formatter/abstractFormatter"; +export * from "./formatters/index"; diff --git a/src/formatters/index.ts b/src/formatters/index.ts new file mode 100644 index 00000000000..d6688b04d90 --- /dev/null +++ b/src/formatters/index.ts @@ -0,0 +1,4 @@ +export * from "./jsonFormatter"; +export * from "./pmdFormatter"; +export * from "./proseFormatter"; +export * from "./verboseFormatter"; \ No newline at end of file diff --git a/src/formatters/jsonFormatter.ts b/src/formatters/jsonFormatter.ts index c8803d63404..15191df2832 100644 --- a/src/formatters/jsonFormatter.ts +++ b/src/formatters/jsonFormatter.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; export class Formatter extends Lint.Formatters.AbstractFormatter { public format(failures: Lint.RuleFailure[]): string { diff --git a/src/formatters/pmdFormatter.ts b/src/formatters/pmdFormatter.ts index 7c67b64bae2..0ed084a8ec8 100644 --- a/src/formatters/pmdFormatter.ts +++ b/src/formatters/pmdFormatter.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; export class Formatter extends Lint.Formatters.AbstractFormatter { public format(failures: Lint.RuleFailure[]): string { diff --git a/src/formatters/proseFormatter.ts b/src/formatters/proseFormatter.ts index b4fb3204b41..c9ab42d4cf1 100644 --- a/src/formatters/proseFormatter.ts +++ b/src/formatters/proseFormatter.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; export class Formatter extends Lint.Formatters.AbstractFormatter { public format(failures: Lint.RuleFailure[]): string { diff --git a/src/formatters/tsconfig.json b/src/formatters/tsconfig.json deleted file mode 100644 index 4154dde2810..00000000000 --- a/src/formatters/tsconfig.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": "1.6.2", - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": true, - "sourceMap": false, - "target": "es5", - "outDir": "../../build/formatters/" - }, - "filesGlob": [ - "../../lib/tslint.d.ts", - "../../typings/*.d.ts", - "./*.ts" - ], - "files": [ - "../../lib/tslint.d.ts", - "../../typings/node.d.ts", - "../../typings/typescriptServices.d.ts", - "../../typings/typescriptServicesScanner.d.ts", - "./jsonFormatter.ts", - "./pmdFormatter.ts", - "./proseFormatter.ts", - "./verboseFormatter.ts" - ] -} diff --git a/src/formatters/verboseFormatter.ts b/src/formatters/verboseFormatter.ts index 049b703f62e..b92049a2680 100644 --- a/src/formatters/verboseFormatter.ts +++ b/src/formatters/verboseFormatter.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; export class Formatter extends Lint.Formatters.AbstractFormatter { public format(failures: Lint.RuleFailure[]): string { diff --git a/src/language/formatter/abstractFormatter.ts b/src/language/formatter/abstractFormatter.ts index 90f0fe02b48..963ffc7058b 100644 --- a/src/language/formatter/abstractFormatter.ts +++ b/src/language/formatter/abstractFormatter.ts @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; -module Lint.Formatters { - export abstract class AbstractFormatter implements Lint.IFormatter { - public abstract format(failures: Lint.RuleFailure[]): string; - } +export abstract class AbstractFormatter implements Lint.IFormatter { + public abstract format(failures: Lint.RuleFailure[]): string; } diff --git a/src/language/formatter/formatter.ts b/src/language/formatter/formatter.ts index 53a81dbc1f0..7f78ef3fa8c 100644 --- a/src/language/formatter/formatter.ts +++ b/src/language/formatter/formatter.ts @@ -13,9 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; -module Lint { - export interface IFormatter { - format(failures: Lint.RuleFailure[]): string; - } +export interface IFormatter { + format(failures: Lint.RuleFailure[]): string; } diff --git a/src/language/languageServiceHost.ts b/src/language/languageServiceHost.ts index 03186886c1f..d4811aa352c 100644 --- a/src/language/languageServiceHost.ts +++ b/src/language/languageServiceHost.ts @@ -14,23 +14,24 @@ * limitations under the License. */ -module Lint { - export function createLanguageServiceHost(fileName: string, source: string) { - const host: ts.LanguageServiceHost = { - getCompilationSettings: () => Lint.createCompilerOptions(), - getCurrentDirectory: () => "", - getDefaultLibFileName: () => "lib.d.ts", - getScriptFileNames: () => [fileName], - getScriptSnapshot: (name) => ts.ScriptSnapshot.fromString(name === fileName ? source : ""), - getScriptVersion: () => "1", - log: (message) => { /* */ } - }; +import * as Lint from "../lint"; +import * as ts from "typescript"; - return host; - } +export function createLanguageServiceHost(fileName: string, source: string) { + const host: ts.LanguageServiceHost = { + getCompilationSettings: () => Lint.createCompilerOptions(), + getCurrentDirectory: () => "", + getDefaultLibFileName: () => "lib.d.ts", + getScriptFileNames: () => [fileName], + getScriptSnapshot: (name) => ts.ScriptSnapshot.fromString(name === fileName ? source : ""), + getScriptVersion: () => "1", + log: (message) => { /* */ } + }; - export function createLanguageService(fileName: string, source: string) { - const languageServiceHost = Lint.createLanguageServiceHost(fileName, source); - return ts.createLanguageService(languageServiceHost); - } + return host; +} + +export function createLanguageService(fileName: string, source: string) { + const languageServiceHost = Lint.createLanguageServiceHost(fileName, source); + return ts.createLanguageService(languageServiceHost); } diff --git a/src/language/rule/abstractRule.ts b/src/language/rule/abstractRule.ts index 5c60a1bacf7..498b5d7490d 100644 --- a/src/language/rule/abstractRule.ts +++ b/src/language/rule/abstractRule.ts @@ -13,50 +13,51 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import {RuleWalker} from "../walker/ruleWalker"; +import * as ts from "typescript"; -module Lint.Rules { - export abstract class AbstractRule implements Lint.IRule { - private value: any; - private options: Lint.IOptions; +export abstract class AbstractRule implements Lint.IRule { + private value: any; + private options: Lint.IOptions; - constructor(ruleName: string, value: any, disabledIntervals: Lint.IDisabledInterval[]) { - let ruleArguments: any[] = []; + constructor(ruleName: string, value: any, disabledIntervals: Lint.IDisabledInterval[]) { + let ruleArguments: any[] = []; - if (Array.isArray(value) && value.length > 1) { - ruleArguments = value.slice(1); - } - - this.value = value; - this.options = { - disabledIntervals: disabledIntervals, - ruleArguments: ruleArguments, - ruleName: ruleName - }; + if (Array.isArray(value) && value.length > 1) { + ruleArguments = value.slice(1); } - public getOptions(): Lint.IOptions { - return this.options; - } + this.value = value; + this.options = { + disabledIntervals: disabledIntervals, + ruleArguments: ruleArguments, + ruleName: ruleName + }; + } - public abstract apply(sourceFile: ts.SourceFile): RuleFailure[]; + public getOptions(): Lint.IOptions { + return this.options; + } - public applyWithWalker(walker: Lint.RuleWalker): RuleFailure[] { - walker.walk(walker.getSourceFile()); - return walker.getFailures(); - } + public abstract apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; - public isEnabled(): boolean { - const value = this.value; + public applyWithWalker(walker: RuleWalker): Lint.RuleFailure[] { + walker.walk(walker.getSourceFile()); + return walker.getFailures(); + } - if (typeof value === "boolean") { - return value; - } + public isEnabled(): boolean { + const value = this.value; - if (Array.isArray(value) && value.length > 0) { - return value[0]; - } + if (typeof value === "boolean") { + return value; + } - return false; + if (Array.isArray(value) && value.length > 0) { + return value[0]; } + + return false; } } diff --git a/src/language/rule/rule.ts b/src/language/rule/rule.ts index 5d7a1674a71..13042bf1c4b 100644 --- a/src/language/rule/rule.ts +++ b/src/language/rule/rule.ts @@ -13,123 +13,123 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import * as ts from "typescript"; -module Lint { - export interface IOptions { - ruleArguments?: any[]; - ruleName: string; - disabledIntervals: Lint.IDisabledInterval[]; +export interface IOptions { + ruleArguments?: any[]; + ruleName: string; + disabledIntervals: Lint.IDisabledInterval[]; +} + +export interface IDisabledInterval { + startPosition: number; + endPosition: number; +} + +export interface IRule { + getOptions(): IOptions; + isEnabled(): boolean; + apply(sourceFile: ts.SourceFile): RuleFailure[]; + applyWithWalker(walker: Lint.RuleWalker): RuleFailure[]; +} + +export class RuleFailurePosition { + private position: number; + private lineAndCharacter: ts.LineAndCharacter; + + constructor(position: number, lineAndCharacter: ts.LineAndCharacter) { + this.position = position; + this.lineAndCharacter = lineAndCharacter; + } + + public getPosition() { + return this.position; + } + + public getLineAndCharacter() { + return this.lineAndCharacter; + } + + public toJson() { + return { + character: this.lineAndCharacter.character, + line: this.lineAndCharacter.line, + position: this.position + }; + } + + public equals(ruleFailurePosition: RuleFailurePosition) { + const ll = this.lineAndCharacter; + const rr = ruleFailurePosition.lineAndCharacter; + + return this.position === ruleFailurePosition.position + && ll.line === rr.line + && ll.character === rr.character; + } +} + +export class RuleFailure { + private sourceFile: ts.SourceFile; + private fileName: string; + private startPosition: Lint.RuleFailurePosition; + private endPosition: Lint.RuleFailurePosition; + private failure: string; + private ruleName: string; + + constructor(sourceFile: ts.SourceFile, + start: number, + end: number, + failure: string, + ruleName: string) { + + this.sourceFile = sourceFile; + this.fileName = sourceFile.fileName; + this.startPosition = this.createFailurePosition(start); + this.endPosition = this.createFailurePosition(end); + this.failure = failure; + this.ruleName = ruleName; + } + + public getFileName() { + return this.fileName; + } + + public getRuleName() { + return this.ruleName; + } + + public getStartPosition(): RuleFailurePosition { + return this.startPosition; + } + + public getEndPosition(): RuleFailurePosition { + return this.endPosition; } - export interface IDisabledInterval { - startPosition: number; - endPosition: number; + public getFailure() { + return this.failure; } - export interface IRule { - getOptions(): IOptions; - isEnabled(): boolean; - apply(sourceFile: ts.SourceFile): RuleFailure[]; - applyWithWalker(walker: Lint.RuleWalker): RuleFailure[]; + public toJson(): any { + return { + endPosition: this.endPosition.toJson(), + failure: this.failure, + name: this.fileName, + ruleName: this.ruleName, + startPosition: this.startPosition.toJson() + }; } - export class RuleFailurePosition { - private position: number; - private lineAndCharacter: ts.LineAndCharacter; - - constructor(position: number, lineAndCharacter: ts.LineAndCharacter) { - this.position = position; - this.lineAndCharacter = lineAndCharacter; - } - - public getPosition() { - return this.position; - } - - public getLineAndCharacter() { - return this.lineAndCharacter; - } - - public toJson() { - return { - character: this.lineAndCharacter.character, - line: this.lineAndCharacter.line, - position: this.position - }; - } - - public equals(ruleFailurePosition: RuleFailurePosition) { - const ll = this.lineAndCharacter; - const rr = ruleFailurePosition.lineAndCharacter; - - return this.position === ruleFailurePosition.position - && ll.line === rr.line - && ll.character === rr.character; - } + public equals(ruleFailure: RuleFailure) { + return this.failure === ruleFailure.getFailure() + && this.fileName === ruleFailure.getFileName() + && this.startPosition.equals(ruleFailure.getStartPosition()) + && this.endPosition.equals(ruleFailure.getEndPosition()); } - export class RuleFailure { - private sourceFile: ts.SourceFile; - private fileName: string; - private startPosition: Lint.RuleFailurePosition; - private endPosition: Lint.RuleFailurePosition; - private failure: string; - private ruleName: string; - - constructor(sourceFile: ts.SourceFile, - start: number, - end: number, - failure: string, - ruleName: string) { - - this.sourceFile = sourceFile; - this.fileName = sourceFile.fileName; - this.startPosition = this.createFailurePosition(start); - this.endPosition = this.createFailurePosition(end); - this.failure = failure; - this.ruleName = ruleName; - } - - public getFileName() { - return this.fileName; - } - - public getRuleName() { - return this.ruleName; - } - - public getStartPosition(): RuleFailurePosition { - return this.startPosition; - } - - public getEndPosition(): RuleFailurePosition { - return this.endPosition; - } - - public getFailure() { - return this.failure; - } - - public toJson(): any { - return { - endPosition: this.endPosition.toJson(), - failure: this.failure, - name: this.fileName, - ruleName: this.ruleName, - startPosition: this.startPosition.toJson() - }; - } - - public equals(ruleFailure: RuleFailure) { - return this.failure === ruleFailure.getFailure() - && this.fileName === ruleFailure.getFileName() - && this.startPosition.equals(ruleFailure.getStartPosition()) - && this.endPosition.equals(ruleFailure.getEndPosition()); - } - - private createFailurePosition(position: number) { - const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(position); - return new RuleFailurePosition(position, lineAndCharacter); - } + private createFailurePosition(position: number) { + const lineAndCharacter = this.sourceFile.getLineAndCharacterOfPosition(position); + return new RuleFailurePosition(position, lineAndCharacter); } } diff --git a/src/language/utils.ts b/src/language/utils.ts index d34176dd326..1c3fe3920b0 100644 --- a/src/language/utils.ts +++ b/src/language/utils.ts @@ -14,111 +14,111 @@ * limitations under the License. */ -module Lint { - const path = require("path"); +import * as Lint from "../lint"; +import * as ts from "typescript"; +import * as path from "path"; - export function getSourceFile(fileName: string, source: string): ts.SourceFile { - const normalizedName = path.normalize(fileName).replace(/\\/g, "/"); - const compilerOptions = createCompilerOptions(); +export function getSourceFile(fileName: string, source: string): ts.SourceFile { + const normalizedName = path.normalize(fileName).replace(/\\/g, "/"); + const compilerOptions = createCompilerOptions(); - const compilerHost: ts.CompilerHost = { - fileExists: () => true, - getCanonicalFileName: (filename: string) => filename, - getCurrentDirectory: () => "", - getDefaultLibFileName: () => "lib.d.ts", - getNewLine: () => "\n", - getSourceFile: function (filenameToGet: string) { - if (filenameToGet === normalizedName) { - return ts.createSourceFile(filenameToGet, source, compilerOptions.target, true); - } - }, - readFile: () => null, - useCaseSensitiveFileNames: () => true, - writeFile: () => null - }; + const compilerHost: ts.CompilerHost = { + fileExists: () => true, + getCanonicalFileName: (filename: string) => filename, + getCurrentDirectory: () => "", + getDefaultLibFileName: () => "lib.d.ts", + getNewLine: () => "\n", + getSourceFile: function (filenameToGet: string) { + if (filenameToGet === normalizedName) { + return ts.createSourceFile(filenameToGet, source, compilerOptions.target, true); + } + }, + readFile: () => null, + useCaseSensitiveFileNames: () => true, + writeFile: () => null + }; - const program = ts.createProgram([normalizedName], compilerOptions, compilerHost); + const program = ts.createProgram([normalizedName], compilerOptions, compilerHost); - return program.getSourceFile(normalizedName); - } + return program.getSourceFile(normalizedName); +} - export function createCompilerOptions(): ts.CompilerOptions { - return { - noResolve: true, - target: ts.ScriptTarget.ES5 - }; - } +export function createCompilerOptions(): ts.CompilerOptions { + return { + noResolve: true, + target: ts.ScriptTarget.ES5 + }; +} - export function doesIntersect(failure: RuleFailure, disabledIntervals: Lint.IDisabledInterval[]) { - return disabledIntervals.some((interval) => { - const maxStart = Math.max(interval.startPosition, failure.getStartPosition().getPosition()); - const minEnd = Math.min(interval.endPosition, failure.getEndPosition().getPosition()); - return maxStart <= minEnd; - }); - } +export function doesIntersect(failure: Lint.RuleFailure, disabledIntervals: Lint.IDisabledInterval[]) { + return disabledIntervals.some((interval) => { + const maxStart = Math.max(interval.startPosition, failure.getStartPosition().getPosition()); + const minEnd = Math.min(interval.endPosition, failure.getEndPosition().getPosition()); + return maxStart <= minEnd; + }); +} - export function abstract() { - console.warn("Lint.abstract() is deprecated and will be removed in a future release. TSLint now uses abstract classes."); - return "abstract method not implemented"; - } +export function abstract() { + console.warn("Lint.abstract() is deprecated and will be removed in a future release. TSLint now uses abstract classes."); + return "abstract method not implemented"; +} - export function scanAllTokens(scanner: ts.Scanner, callback: (s: ts.Scanner) => void) { - let lastStartPos = -1; - while (scanner.scan() !== ts.SyntaxKind.EndOfFileToken) { - const startPos = scanner.getStartPos(); - if (startPos === lastStartPos) { - break; - } - lastStartPos = startPos; - callback(scanner); +export function scanAllTokens(scanner: ts.Scanner, callback: (s: ts.Scanner) => void) { + let lastStartPos = -1; + while (scanner.scan() !== ts.SyntaxKind.EndOfFileToken) { + const startPos = scanner.getStartPos(); + if (startPos === lastStartPos) { + break; } + lastStartPos = startPos; + callback(scanner); } +} - /** - * @returns true if any modifier kinds passed along exist in the given modifiers array - */ - export function hasModifier(modifiers: ts.ModifiersArray, ...modifierKinds: ts.SyntaxKind[]) { - if (modifiers == null || modifierKinds == null) { - return false; - } - - return modifiers.some((m) => { - return modifierKinds.some((k) => m.kind === k); - }); +/** + * @returns true if any modifier kinds passed along exist in the given modifiers array + */ +export function hasModifier(modifiers: ts.ModifiersArray, ...modifierKinds: ts.SyntaxKind[]) { + if (modifiers == null || modifierKinds == null) { + return false; } - /** - * Determines if the appropriate bit in the parent (VariableDeclarationList) is set, - * which indicates this is a "let" or "const". - */ - export function isBlockScopedVariable(node: ts.VariableDeclaration | ts.VariableStatement): boolean { - const parentNode = (node.kind === ts.SyntaxKind.VariableDeclaration) - ? ( node).parent - : ( node).declarationList; + return modifiers.some((m) => { + return modifierKinds.some((k) => m.kind === k); + }); +} - return isNodeFlagSet(parentNode, ts.NodeFlags.Let) - || isNodeFlagSet(parentNode, ts.NodeFlags.Const); - } +/** + * Determines if the appropriate bit in the parent (VariableDeclarationList) is set, + * which indicates this is a "let" or "const". + */ +export function isBlockScopedVariable(node: ts.VariableDeclaration | ts.VariableStatement): boolean { + const parentNode = (node.kind === ts.SyntaxKind.VariableDeclaration) + ? ( node).parent + : ( node).declarationList; - export function isBlockScopedBindingElement(node: ts.BindingElement): boolean { - let currentParent = node.parent; - while (currentParent.kind !== ts.SyntaxKind.VariableDeclaration) { - if (currentParent.parent == null) { - // if we didn't encounter a VariableDeclaration, this must be a function parameter, which is block scoped - return true; - } else { - currentParent = currentParent.parent; - } + return isNodeFlagSet(parentNode, ts.NodeFlags.Let) + || isNodeFlagSet(parentNode, ts.NodeFlags.Const); +} + +export function isBlockScopedBindingElement(node: ts.BindingElement): boolean { + let currentParent = node.parent; + while (currentParent.kind !== ts.SyntaxKind.VariableDeclaration) { + if (currentParent.parent == null) { + // if we didn't encounter a VariableDeclaration, this must be a function parameter, which is block scoped + return true; + } else { + currentParent = currentParent.parent; } - return isBlockScopedVariable( currentParent); } + return isBlockScopedVariable( currentParent); +} - /** - * Bitwise check for node flags. - */ - export function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean { - /* tslint:disable:no-bitwise */ - return (node.flags & flagToCheck) !== 0; - /* tslint:enable:no-bitwise */ - } +/** + * Bitwise check for node flags. + */ +export function isNodeFlagSet(node: ts.Node, flagToCheck: ts.NodeFlags): boolean { + /* tslint:disable:no-bitwise */ + return (node.flags & flagToCheck) !== 0; + /* tslint:enable:no-bitwise */ } diff --git a/src/language/walker/blockScopeAwareRuleWalker.ts b/src/language/walker/blockScopeAwareRuleWalker.ts index 4f44a7d080f..f6061392436 100644 --- a/src/language/walker/blockScopeAwareRuleWalker.ts +++ b/src/language/walker/blockScopeAwareRuleWalker.ts @@ -13,71 +13,72 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import {ScopeAwareRuleWalker} from "./scopeAwareRuleWalker"; +import * as ts from "typescript"; -module Lint { - /** - * An AST walker that is aware of block scopes in addition to regular scopes. Block scopes - * are a superset of regular scopes (new block scopes are created more frequently in a program). - */ - export abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker { - private blockScopeStack: U[]; +/** + * An AST walker that is aware of block scopes in addition to regular scopes. Block scopes + * are a superset of regular scopes (new block scopes are created more frequently in a program). + */ +export abstract class BlockScopeAwareRuleWalker extends ScopeAwareRuleWalker { + private blockScopeStack: U[]; - constructor(sourceFile: ts.SourceFile, options?: any) { - super(sourceFile, options); + constructor(sourceFile: ts.SourceFile, options?: any) { + super(sourceFile, options); - // initialize stack with global scope - this.blockScopeStack = [this.createBlockScope()]; - } + // initialize stack with global scope + this.blockScopeStack = [this.createBlockScope()]; + } - public abstract createBlockScope(): U; + public abstract createBlockScope(): U; - public getCurrentBlockScope(): U { - return this.blockScopeStack[this.blockScopeStack.length - 1]; - } + public getCurrentBlockScope(): U { + return this.blockScopeStack[this.blockScopeStack.length - 1]; + } - // callback notifier when a block scope begins - public onBlockScopeStart() { - return; - } + // callback notifier when a block scope begins + public onBlockScopeStart() { + return; + } - public getCurrentBlockDepth(): number { - return this.blockScopeStack.length; - } + public getCurrentBlockDepth(): number { + return this.blockScopeStack.length; + } - // callback notifier when a block scope ends - public onBlockScopeEnd() { - return; - } + // callback notifier when a block scope ends + public onBlockScopeEnd() { + return; + } - protected visitNode(node: ts.Node) { - const isNewBlockScope = this.isBlockScopeBoundary(node); + protected visitNode(node: ts.Node) { + const isNewBlockScope = this.isBlockScopeBoundary(node); - if (isNewBlockScope) { - this.blockScopeStack.push(this.createBlockScope()); - } + if (isNewBlockScope) { + this.blockScopeStack.push(this.createBlockScope()); + } - this.onBlockScopeStart(); - super.visitNode(node); - this.onBlockScopeEnd(); + this.onBlockScopeStart(); + super.visitNode(node); + this.onBlockScopeEnd(); - if (isNewBlockScope) { - this.blockScopeStack.pop(); - } + if (isNewBlockScope) { + this.blockScopeStack.pop(); } + } - private isBlockScopeBoundary(node: ts.Node): boolean { - return super.isScopeBoundary(node) - || node.kind === ts.SyntaxKind.DoStatement - || node.kind === ts.SyntaxKind.WhileStatement - || node.kind === ts.SyntaxKind.ForStatement - || node.kind === ts.SyntaxKind.ForInStatement - || node.kind === ts.SyntaxKind.ForOfStatement - || node.kind === ts.SyntaxKind.WithStatement - || node.kind === ts.SyntaxKind.SwitchStatement - || (node.parent != null - && (node.parent.kind === ts.SyntaxKind.TryStatement - || node.parent.kind === ts.SyntaxKind.IfStatement) - ); - } + private isBlockScopeBoundary(node: ts.Node): boolean { + return super.isScopeBoundary(node) + || node.kind === ts.SyntaxKind.DoStatement + || node.kind === ts.SyntaxKind.WhileStatement + || node.kind === ts.SyntaxKind.ForStatement + || node.kind === ts.SyntaxKind.ForInStatement + || node.kind === ts.SyntaxKind.ForOfStatement + || node.kind === ts.SyntaxKind.WithStatement + || node.kind === ts.SyntaxKind.SwitchStatement + || (node.parent != null + && (node.parent.kind === ts.SyntaxKind.TryStatement + || node.parent.kind === ts.SyntaxKind.IfStatement) + ); } } diff --git a/src/language/walker/index.ts b/src/language/walker/index.ts new file mode 100644 index 00000000000..3ebe7c6135b --- /dev/null +++ b/src/language/walker/index.ts @@ -0,0 +1,5 @@ +export * from "./blockScopeAwareRuleWalker"; +export * from "./ruleWalker"; +export * from "./scopeAwareRuleWalker"; +export * from "./skippableTokenAwareRuleWalker"; +export * from "./syntaxWalker"; diff --git a/src/language/walker/ruleWalker.ts b/src/language/walker/ruleWalker.ts index 45a6cefd601..07e2fa52de7 100644 --- a/src/language/walker/ruleWalker.ts +++ b/src/language/walker/ruleWalker.ts @@ -13,73 +13,73 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import {SyntaxWalker} from "./syntaxWalker"; +import * as ts from "typescript"; -module Lint { - export class RuleWalker extends Lint.SyntaxWalker { - private limit: number; - private position: number; - private options: any[]; - private failures: RuleFailure[]; - private sourceFile: ts.SourceFile; - private disabledIntervals: Lint.IDisabledInterval[]; - private ruleName: string; +export class RuleWalker extends SyntaxWalker { + private limit: number; + private position: number; + private options: any[]; + private failures: Lint.RuleFailure[]; + private sourceFile: ts.SourceFile; + private disabledIntervals: Lint.IDisabledInterval[]; + private ruleName: string; - constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { - super(); + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { + super(); - this.position = 0; - this.failures = []; - this.options = options.ruleArguments; - this.sourceFile = sourceFile; - this.limit = this.sourceFile.getFullWidth(); - this.disabledIntervals = options.disabledIntervals; - this.ruleName = options.ruleName; - } - - public getSourceFile(): ts.SourceFile { - return this.sourceFile; - } + this.position = 0; + this.failures = []; + this.options = options.ruleArguments; + this.sourceFile = sourceFile; + this.limit = this.sourceFile.getFullWidth(); + this.disabledIntervals = options.disabledIntervals; + this.ruleName = options.ruleName; + } - public getFailures(): RuleFailure[] { - return this.failures; - } + public getSourceFile(): ts.SourceFile { + return this.sourceFile; + } - public getLimit() { - return this.limit; - } + public getFailures(): Lint.RuleFailure[] { + return this.failures; + } - public getOptions(): any { - return this.options; - } + public getLimit() { + return this.limit; + } - public hasOption(option: string): boolean { - if (this.options) { - return this.options.indexOf(option) !== -1; - } else { - return false; - } - } + public getOptions(): any { + return this.options; + } - public skip(node: ts.Node) { - this.position += node.getFullWidth(); + public hasOption(option: string): boolean { + if (this.options) { + return this.options.indexOf(option) !== -1; + } else { + return false; } + } - public createFailure(start: number, width: number, failure: string): RuleFailure { - const from = (start > this.limit) ? this.limit : start; - const to = ((start + width) > this.limit) ? this.limit : (start + width); - return new Lint.RuleFailure(this.sourceFile, from, to, failure, this.ruleName); - } + public skip(node: ts.Node) { + this.position += node.getFullWidth(); + } - public addFailure(failure: RuleFailure) { - // don't add failures for a rule if the failure intersects an interval where that rule is disabled - if (!this.existsFailure(failure) && !Lint.doesIntersect(failure, this.disabledIntervals)) { - this.failures.push(failure); - } - } + public createFailure(start: number, width: number, failure: string): Lint.RuleFailure { + const from = (start > this.limit) ? this.limit : start; + const to = ((start + width) > this.limit) ? this.limit : (start + width); + return new Lint.RuleFailure(this.sourceFile, from, to, failure, this.ruleName); + } - private existsFailure(failure: RuleFailure) { - return this.failures.some((f) => f.equals(failure)); + public addFailure(failure: Lint.RuleFailure) { + // don't add failures for a rule if the failure intersects an interval where that rule is disabled + if (!this.existsFailure(failure) && !Lint.doesIntersect(failure, this.disabledIntervals)) { + this.failures.push(failure); } } + private existsFailure(failure: Lint.RuleFailure) { + return this.failures.some((f) => f.equals(failure)); + } } diff --git a/src/language/walker/scopeAwareRuleWalker.ts b/src/language/walker/scopeAwareRuleWalker.ts index fe44aa0e152..cdee4037855 100644 --- a/src/language/walker/scopeAwareRuleWalker.ts +++ b/src/language/walker/scopeAwareRuleWalker.ts @@ -13,73 +13,74 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import {RuleWalker} from "./ruleWalker"; +import * as ts from "typescript"; -module Lint { - export abstract class ScopeAwareRuleWalker extends RuleWalker { - private scopeStack: T[]; +export abstract class ScopeAwareRuleWalker extends RuleWalker { + private scopeStack: T[]; - constructor(sourceFile: ts.SourceFile, options?: any) { - super(sourceFile, options); + constructor(sourceFile: ts.SourceFile, options?: any) { + super(sourceFile, options); - // initialize stack with global scope - this.scopeStack = [this.createScope()]; - } + // initialize stack with global scope + this.scopeStack = [this.createScope()]; + } - public abstract createScope(): T; + public abstract createScope(): T; - public getCurrentScope(): T { - return this.scopeStack[this.scopeStack.length - 1]; - } + public getCurrentScope(): T { + return this.scopeStack[this.scopeStack.length - 1]; + } - // get all scopes available at this depth - public getAllScopes(): T[] { - return this.scopeStack.slice(); - } + // get all scopes available at this depth + public getAllScopes(): T[] { + return this.scopeStack.slice(); + } - public getCurrentDepth(): number { - return this.scopeStack.length; - } + public getCurrentDepth(): number { + return this.scopeStack.length; + } - // callback notifier when a scope begins - public onScopeStart() { - return; - } + // callback notifier when a scope begins + public onScopeStart() { + return; + } - // callback notifier when a scope ends - public onScopeEnd() { - return; - } + // callback notifier when a scope ends + public onScopeEnd() { + return; + } - protected visitNode(node: ts.Node) { - const isNewScope = this.isScopeBoundary(node); + protected visitNode(node: ts.Node) { + const isNewScope = this.isScopeBoundary(node); - if (isNewScope) { - this.scopeStack.push(this.createScope()); - } + if (isNewScope) { + this.scopeStack.push(this.createScope()); + } - this.onScopeStart(); - super.visitNode(node); - this.onScopeEnd(); + this.onScopeStart(); + super.visitNode(node); + this.onScopeEnd(); - if (isNewScope) { - this.scopeStack.pop(); - } + if (isNewScope) { + this.scopeStack.pop(); } + } - protected isScopeBoundary(node: ts.Node): boolean { - return node.kind === ts.SyntaxKind.FunctionDeclaration - || node.kind === ts.SyntaxKind.FunctionExpression - || node.kind === ts.SyntaxKind.PropertyAssignment - || node.kind === ts.SyntaxKind.ShorthandPropertyAssignment - || node.kind === ts.SyntaxKind.MethodDeclaration - || node.kind === ts.SyntaxKind.Constructor - || node.kind === ts.SyntaxKind.ModuleDeclaration - || node.kind === ts.SyntaxKind.ArrowFunction - || node.kind === ts.SyntaxKind.ParenthesizedExpression - || node.kind === ts.SyntaxKind.ClassDeclaration - || node.kind === ts.SyntaxKind.InterfaceDeclaration - || node.kind === ts.SyntaxKind.GetAccessor - || node.kind === ts.SyntaxKind.SetAccessor; - } + protected isScopeBoundary(node: ts.Node): boolean { + return node.kind === ts.SyntaxKind.FunctionDeclaration + || node.kind === ts.SyntaxKind.FunctionExpression + || node.kind === ts.SyntaxKind.PropertyAssignment + || node.kind === ts.SyntaxKind.ShorthandPropertyAssignment + || node.kind === ts.SyntaxKind.MethodDeclaration + || node.kind === ts.SyntaxKind.Constructor + || node.kind === ts.SyntaxKind.ModuleDeclaration + || node.kind === ts.SyntaxKind.ArrowFunction + || node.kind === ts.SyntaxKind.ParenthesizedExpression + || node.kind === ts.SyntaxKind.ClassDeclaration + || node.kind === ts.SyntaxKind.InterfaceDeclaration + || node.kind === ts.SyntaxKind.GetAccessor + || node.kind === ts.SyntaxKind.SetAccessor; } } diff --git a/src/language/walker/skippableTokenAwareRuleWalker.ts b/src/language/walker/skippableTokenAwareRuleWalker.ts index 448bba2dc09..7f5dc570a83 100644 --- a/src/language/walker/skippableTokenAwareRuleWalker.ts +++ b/src/language/walker/skippableTokenAwareRuleWalker.ts @@ -13,36 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../../lint"; +import {RuleWalker} from "./ruleWalker"; +import * as ts from "typescript"; -module Lint { - export class SkippableTokenAwareRuleWalker extends RuleWalker { - protected tokensToSkipStartEndMap: {[start: number]: number}; +export class SkippableTokenAwareRuleWalker extends RuleWalker { + protected tokensToSkipStartEndMap: {[start: number]: number}; - constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { - super(sourceFile, options); - this.tokensToSkipStartEndMap = {}; - } + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { + super(sourceFile, options); + this.tokensToSkipStartEndMap = {}; + } - protected visitRegularExpressionLiteral(node: ts.Node) { - this.addTokenToSkipFromNode(node); - super.visitRegularExpressionLiteral(node); - } + protected visitRegularExpressionLiteral(node: ts.Node) { + this.addTokenToSkipFromNode(node); + super.visitRegularExpressionLiteral(node); + } - protected visitIdentifier(node: ts.Identifier) { - this.addTokenToSkipFromNode(node); - super.visitIdentifier(node); - } + protected visitIdentifier(node: ts.Identifier) { + this.addTokenToSkipFromNode(node); + super.visitIdentifier(node); + } - protected visitTemplateExpression(node: ts.TemplateExpression) { - this.addTokenToSkipFromNode(node); - super.visitTemplateExpression(node); - } + protected visitTemplateExpression(node: ts.TemplateExpression) { + this.addTokenToSkipFromNode(node); + super.visitTemplateExpression(node); + } - protected addTokenToSkipFromNode(node: ts.Node) { - if (node.getStart() < node.getEnd()) { - // only add to the map nodes whose end comes after their start, to prevent infinite loops - this.tokensToSkipStartEndMap[node.getStart()] = node.getEnd(); - } + protected addTokenToSkipFromNode(node: ts.Node) { + if (node.getStart() < node.getEnd()) { + // only add to the map nodes whose end comes after their start, to prevent infinite loops + this.tokensToSkipStartEndMap[node.getStart()] = node.getEnd(); } } } diff --git a/src/language/walker/syntaxWalker.ts b/src/language/walker/syntaxWalker.ts index bfb51072ef1..994991cb84f 100644 --- a/src/language/walker/syntaxWalker.ts +++ b/src/language/walker/syntaxWalker.ts @@ -13,547 +13,546 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as ts from "typescript"; -module Lint { - export class SyntaxWalker { - public walk(node: ts.Node) { - this.visitNode(node); - } +export class SyntaxWalker { + public walk(node: ts.Node) { + this.visitNode(node); + } - protected visitAnyKeyword(node: ts.Node) { - this.walkChildren(node); - } + protected visitAnyKeyword(node: ts.Node) { + this.walkChildren(node); + } - protected visitArrowFunction(node: ts.FunctionLikeDeclaration) { - this.walkChildren(node); - } + protected visitArrowFunction(node: ts.FunctionLikeDeclaration) { + this.walkChildren(node); + } - protected visitBinaryExpression(node: ts.BinaryExpression) { - this.walkChildren(node); - } + protected visitBinaryExpression(node: ts.BinaryExpression) { + this.walkChildren(node); + } - protected visitBindingElement(node: ts.BindingElement) { - this.walkChildren(node); - } + protected visitBindingElement(node: ts.BindingElement) { + this.walkChildren(node); + } - protected visitBlock(node: ts.Block) { - this.walkChildren(node); - } + protected visitBlock(node: ts.Block) { + this.walkChildren(node); + } - protected visitBreakStatement(node: ts.BreakOrContinueStatement) { - this.walkChildren(node); - } + protected visitBreakStatement(node: ts.BreakOrContinueStatement) { + this.walkChildren(node); + } - protected visitCallExpression(node: ts.CallExpression) { - this.walkChildren(node); - } + protected visitCallExpression(node: ts.CallExpression) { + this.walkChildren(node); + } - protected visitCallSignature(node: ts.SignatureDeclaration) { - this.walkChildren(node); - } + protected visitCallSignature(node: ts.SignatureDeclaration) { + this.walkChildren(node); + } - protected visitCaseClause(node: ts.CaseClause) { - this.walkChildren(node); - } + protected visitCaseClause(node: ts.CaseClause) { + this.walkChildren(node); + } - protected visitClassDeclaration(node: ts.ClassDeclaration) { - this.walkChildren(node); - } + protected visitClassDeclaration(node: ts.ClassDeclaration) { + this.walkChildren(node); + } - protected visitCatchClause(node: ts.CatchClause) { - this.walkChildren(node); - } + protected visitCatchClause(node: ts.CatchClause) { + this.walkChildren(node); + } - protected visitConditionalExpression(node: ts.ConditionalExpression) { - this.walkChildren(node); - } + protected visitConditionalExpression(node: ts.ConditionalExpression) { + this.walkChildren(node); + } - protected visitConstructorDeclaration(node: ts.ConstructorDeclaration) { - this.walkChildren(node); - } + protected visitConstructorDeclaration(node: ts.ConstructorDeclaration) { + this.walkChildren(node); + } - protected visitConstructorType(node: ts.FunctionOrConstructorTypeNode) { - this.walkChildren(node); - } + protected visitConstructorType(node: ts.FunctionOrConstructorTypeNode) { + this.walkChildren(node); + } - protected visitContinueStatement(node: ts.BreakOrContinueStatement) { - this.walkChildren(node); - } + protected visitContinueStatement(node: ts.BreakOrContinueStatement) { + this.walkChildren(node); + } - protected visitDebuggerStatement(node: ts.Statement) { - this.walkChildren(node); - } + protected visitDebuggerStatement(node: ts.Statement) { + this.walkChildren(node); + } - protected visitDefaultClause(node: ts.DefaultClause) { - this.walkChildren(node); - } + protected visitDefaultClause(node: ts.DefaultClause) { + this.walkChildren(node); + } - protected visitDoStatement(node: ts.DoStatement) { - this.walkChildren(node); - } + protected visitDoStatement(node: ts.DoStatement) { + this.walkChildren(node); + } - protected visitElementAccessExpression(node: ts.ElementAccessExpression) { - this.walkChildren(node); - } + protected visitElementAccessExpression(node: ts.ElementAccessExpression) { + this.walkChildren(node); + } - protected visitEnumDeclaration(node: ts.EnumDeclaration) { - this.walkChildren(node); - } + protected visitEnumDeclaration(node: ts.EnumDeclaration) { + this.walkChildren(node); + } - protected visitExportAssignment(node: ts.ExportAssignment) { - this.walkChildren(node); - } + protected visitExportAssignment(node: ts.ExportAssignment) { + this.walkChildren(node); + } - protected visitExpressionStatement(node: ts.ExpressionStatement) { - this.walkChildren(node); - } + protected visitExpressionStatement(node: ts.ExpressionStatement) { + this.walkChildren(node); + } - protected visitForStatement(node: ts.ForStatement) { - this.walkChildren(node); - } + protected visitForStatement(node: ts.ForStatement) { + this.walkChildren(node); + } - protected visitForInStatement(node: ts.ForInStatement) { - this.walkChildren(node); - } + protected visitForInStatement(node: ts.ForInStatement) { + this.walkChildren(node); + } - protected visitForOfStatement(node: ts.ForOfStatement) { - this.walkChildren(node); - } + protected visitForOfStatement(node: ts.ForOfStatement) { + this.walkChildren(node); + } - protected visitFunctionDeclaration(node: ts.FunctionDeclaration) { - this.walkChildren(node); - } + protected visitFunctionDeclaration(node: ts.FunctionDeclaration) { + this.walkChildren(node); + } - protected visitFunctionExpression(node: ts.FunctionExpression) { - this.walkChildren(node); - } + protected visitFunctionExpression(node: ts.FunctionExpression) { + this.walkChildren(node); + } - protected visitFunctionType(node: ts.FunctionOrConstructorTypeNode) { - this.walkChildren(node); - } + protected visitFunctionType(node: ts.FunctionOrConstructorTypeNode) { + this.walkChildren(node); + } - protected visitGetAccessor(node: ts.AccessorDeclaration) { - this.walkChildren(node); - } + protected visitGetAccessor(node: ts.AccessorDeclaration) { + this.walkChildren(node); + } - protected visitIdentifier(node: ts.Identifier) { - this.walkChildren(node); - } + protected visitIdentifier(node: ts.Identifier) { + this.walkChildren(node); + } - protected visitIfStatement(node: ts.IfStatement) { - this.walkChildren(node); - } + protected visitIfStatement(node: ts.IfStatement) { + this.walkChildren(node); + } - protected visitImportDeclaration(node: ts.ImportDeclaration) { - this.walkChildren(node); - } + protected visitImportDeclaration(node: ts.ImportDeclaration) { + this.walkChildren(node); + } - protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) { - this.walkChildren(node); - } + protected visitImportEqualsDeclaration(node: ts.ImportEqualsDeclaration) { + this.walkChildren(node); + } - protected visitIndexSignatureDeclaration(node: ts.IndexSignatureDeclaration) { - this.walkChildren(node); - } + protected visitIndexSignatureDeclaration(node: ts.IndexSignatureDeclaration) { + this.walkChildren(node); + } - protected visitInterfaceDeclaration(node: ts.InterfaceDeclaration) { - this.walkChildren(node); - } + protected visitInterfaceDeclaration(node: ts.InterfaceDeclaration) { + this.walkChildren(node); + } - protected visitJsxElement(node: ts.JsxElement) { - this.walkChildren(node); - } + protected visitJsxElement(node: ts.JsxElement) { + this.walkChildren(node); + } - protected visitJsxSelfClosingElement(node: ts.JsxSelfClosingElement) { - this.walkChildren(node); - } + protected visitJsxSelfClosingElement(node: ts.JsxSelfClosingElement) { + this.walkChildren(node); + } - protected visitLabeledStatement(node: ts.LabeledStatement) { - this.walkChildren(node); - } + protected visitLabeledStatement(node: ts.LabeledStatement) { + this.walkChildren(node); + } - protected visitMethodDeclaration(node: ts.MethodDeclaration) { - this.walkChildren(node); - } + protected visitMethodDeclaration(node: ts.MethodDeclaration) { + this.walkChildren(node); + } - protected visitMethodSignature(node: ts.SignatureDeclaration) { - this.walkChildren(node); - } + protected visitMethodSignature(node: ts.SignatureDeclaration) { + this.walkChildren(node); + } - protected visitModuleDeclaration(node: ts.ModuleDeclaration) { - this.walkChildren(node); - } + protected visitModuleDeclaration(node: ts.ModuleDeclaration) { + this.walkChildren(node); + } - protected visitNamedImports(node: ts.NamedImports) { - this.walkChildren(node); - } + protected visitNamedImports(node: ts.NamedImports) { + this.walkChildren(node); + } - protected visitNamespaceImport(node: ts.NamespaceImport) { - this.walkChildren(node); - } + protected visitNamespaceImport(node: ts.NamespaceImport) { + this.walkChildren(node); + } - protected visitNewExpression(node: ts.NewExpression) { - this.walkChildren(node); - } + protected visitNewExpression(node: ts.NewExpression) { + this.walkChildren(node); + } - protected visitObjectLiteralExpression(node: ts.ObjectLiteralExpression) { - this.walkChildren(node); - } + protected visitObjectLiteralExpression(node: ts.ObjectLiteralExpression) { + this.walkChildren(node); + } - protected visitParameterDeclaration(node: ts.ParameterDeclaration) { - this.walkChildren(node); - } + protected visitParameterDeclaration(node: ts.ParameterDeclaration) { + this.walkChildren(node); + } - protected visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) { - this.walkChildren(node); - } + protected visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) { + this.walkChildren(node); + } - protected visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) { - this.walkChildren(node); - } + protected visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) { + this.walkChildren(node); + } - protected visitPropertyAccessExpression(node: ts.PropertyAccessExpression) { - this.walkChildren(node); - } + protected visitPropertyAccessExpression(node: ts.PropertyAccessExpression) { + this.walkChildren(node); + } - protected visitPropertyAssignment(node: ts.PropertyAssignment) { - this.walkChildren(node); - } + protected visitPropertyAssignment(node: ts.PropertyAssignment) { + this.walkChildren(node); + } - protected visitPropertyDeclaration(node: ts.PropertyDeclaration) { - this.walkChildren(node); - } + protected visitPropertyDeclaration(node: ts.PropertyDeclaration) { + this.walkChildren(node); + } - protected visitPropertySignature(node: ts.Node) { - this.walkChildren(node); - } + protected visitPropertySignature(node: ts.Node) { + this.walkChildren(node); + } - protected visitRegularExpressionLiteral(node: ts.Node) { - this.walkChildren(node); - } + protected visitRegularExpressionLiteral(node: ts.Node) { + this.walkChildren(node); + } - protected visitReturnStatement(node: ts.ReturnStatement) { - this.walkChildren(node); - } + protected visitReturnStatement(node: ts.ReturnStatement) { + this.walkChildren(node); + } - protected visitSetAccessor(node: ts.AccessorDeclaration) { - this.walkChildren(node); - } + protected visitSetAccessor(node: ts.AccessorDeclaration) { + this.walkChildren(node); + } - protected visitSourceFile(node: ts.SourceFile) { - this.walkChildren(node); - } + protected visitSourceFile(node: ts.SourceFile) { + this.walkChildren(node); + } - protected visitSwitchStatement(node: ts.SwitchStatement) { - this.walkChildren(node); - } + protected visitSwitchStatement(node: ts.SwitchStatement) { + this.walkChildren(node); + } - protected visitTemplateExpression(node: ts.TemplateExpression) { - this.walkChildren(node); - } + protected visitTemplateExpression(node: ts.TemplateExpression) { + this.walkChildren(node); + } - protected visitThrowStatement(node: ts.ThrowStatement) { - this.walkChildren(node); - } + protected visitThrowStatement(node: ts.ThrowStatement) { + this.walkChildren(node); + } - protected visitTryStatement(node: ts.TryStatement) { - this.walkChildren(node); - } + protected visitTryStatement(node: ts.TryStatement) { + this.walkChildren(node); + } - protected visitTypeAssertionExpression(node: ts.TypeAssertion) { - this.walkChildren(node); - } + protected visitTypeAssertionExpression(node: ts.TypeAssertion) { + this.walkChildren(node); + } - protected visitTypeLiteral(node: ts.TypeLiteralNode) { - this.walkChildren(node); - } + protected visitTypeLiteral(node: ts.TypeLiteralNode) { + this.walkChildren(node); + } - protected visitVariableDeclaration(node: ts.VariableDeclaration) { - this.walkChildren(node); - } + protected visitVariableDeclaration(node: ts.VariableDeclaration) { + this.walkChildren(node); + } - protected visitVariableStatement(node: ts.VariableStatement) { - this.walkChildren(node); - } + protected visitVariableStatement(node: ts.VariableStatement) { + this.walkChildren(node); + } - protected visitWhileStatement(node: ts.WhileStatement) { - this.walkChildren(node); - } + protected visitWhileStatement(node: ts.WhileStatement) { + this.walkChildren(node); + } - protected visitNode(node: ts.Node) { - switch (node.kind) { - case ts.SyntaxKind.AnyKeyword: - this.visitAnyKeyword(node); - break; + protected visitNode(node: ts.Node) { + switch (node.kind) { + case ts.SyntaxKind.AnyKeyword: + this.visitAnyKeyword(node); + break; - case ts.SyntaxKind.BindingElement: - this.visitBindingElement( node); - break; + case ts.SyntaxKind.BindingElement: + this.visitBindingElement( node); + break; - case ts.SyntaxKind.ArrowFunction: - this.visitArrowFunction( node); - break; + case ts.SyntaxKind.ArrowFunction: + this.visitArrowFunction( node); + break; - case ts.SyntaxKind.BinaryExpression: - this.visitBinaryExpression( node); - break; + case ts.SyntaxKind.BinaryExpression: + this.visitBinaryExpression( node); + break; - case ts.SyntaxKind.BindingElement: - this.visitBindingElement( node); - break; + case ts.SyntaxKind.BindingElement: + this.visitBindingElement( node); + break; - case ts.SyntaxKind.Block: - this.visitBlock( node); - break; + case ts.SyntaxKind.Block: + this.visitBlock( node); + break; - case ts.SyntaxKind.BreakStatement: - this.visitBreakStatement( node); - break; + case ts.SyntaxKind.BreakStatement: + this.visitBreakStatement( node); + break; - case ts.SyntaxKind.CallExpression: - this.visitCallExpression( node); - break; + case ts.SyntaxKind.CallExpression: + this.visitCallExpression( node); + break; - case ts.SyntaxKind.CallSignature: - this.visitCallSignature( node); - break; + case ts.SyntaxKind.CallSignature: + this.visitCallSignature( node); + break; - case ts.SyntaxKind.CaseClause: - this.visitCaseClause( node); - break; + case ts.SyntaxKind.CaseClause: + this.visitCaseClause( node); + break; - case ts.SyntaxKind.ClassDeclaration: - this.visitClassDeclaration( node); - break; + case ts.SyntaxKind.ClassDeclaration: + this.visitClassDeclaration( node); + break; - case ts.SyntaxKind.CatchClause: - this.visitCatchClause( node); - break; + case ts.SyntaxKind.CatchClause: + this.visitCatchClause( node); + break; - case ts.SyntaxKind.ConditionalExpression: - this.visitConditionalExpression( node); - break; + case ts.SyntaxKind.ConditionalExpression: + this.visitConditionalExpression( node); + break; - case ts.SyntaxKind.Constructor: - this.visitConstructorDeclaration( node); - break; + case ts.SyntaxKind.Constructor: + this.visitConstructorDeclaration( node); + break; - case ts.SyntaxKind.ConstructorType: - this.visitConstructorType( node); - break; + case ts.SyntaxKind.ConstructorType: + this.visitConstructorType( node); + break; - case ts.SyntaxKind.ContinueStatement: - this.visitContinueStatement( node); - break; + case ts.SyntaxKind.ContinueStatement: + this.visitContinueStatement( node); + break; - case ts.SyntaxKind.DebuggerStatement: - this.visitDebuggerStatement( node); - break; + case ts.SyntaxKind.DebuggerStatement: + this.visitDebuggerStatement( node); + break; - case ts.SyntaxKind.DefaultClause: - this.visitDefaultClause( node); - break; + case ts.SyntaxKind.DefaultClause: + this.visitDefaultClause( node); + break; - case ts.SyntaxKind.DoStatement: - this.visitDoStatement( node); - break; + case ts.SyntaxKind.DoStatement: + this.visitDoStatement( node); + break; - case ts.SyntaxKind.ElementAccessExpression: - this.visitElementAccessExpression( node); - break; + case ts.SyntaxKind.ElementAccessExpression: + this.visitElementAccessExpression( node); + break; - case ts.SyntaxKind.EnumDeclaration: - this.visitEnumDeclaration( node); - break; + case ts.SyntaxKind.EnumDeclaration: + this.visitEnumDeclaration( node); + break; - case ts.SyntaxKind.ExportAssignment: - this.visitExportAssignment( node); - break; + case ts.SyntaxKind.ExportAssignment: + this.visitExportAssignment( node); + break; - case ts.SyntaxKind.ExpressionStatement: - this.visitExpressionStatement( node); - break; + case ts.SyntaxKind.ExpressionStatement: + this.visitExpressionStatement( node); + break; - case ts.SyntaxKind.ForStatement: - this.visitForStatement( node); - break; + case ts.SyntaxKind.ForStatement: + this.visitForStatement( node); + break; - case ts.SyntaxKind.ForInStatement: - this.visitForInStatement( node); - break; + case ts.SyntaxKind.ForInStatement: + this.visitForInStatement( node); + break; - case ts.SyntaxKind.ForOfStatement: - this.visitForOfStatement( node); - break; + case ts.SyntaxKind.ForOfStatement: + this.visitForOfStatement( node); + break; - case ts.SyntaxKind.FunctionDeclaration: - this.visitFunctionDeclaration( node); - break; + case ts.SyntaxKind.FunctionDeclaration: + this.visitFunctionDeclaration( node); + break; - case ts.SyntaxKind.FunctionExpression: - this.visitFunctionExpression( node); - break; + case ts.SyntaxKind.FunctionExpression: + this.visitFunctionExpression( node); + break; - case ts.SyntaxKind.FunctionType: - this.visitFunctionType( node); - break; + case ts.SyntaxKind.FunctionType: + this.visitFunctionType( node); + break; - case ts.SyntaxKind.GetAccessor: - this.visitGetAccessor( node); - break; + case ts.SyntaxKind.GetAccessor: + this.visitGetAccessor( node); + break; - case ts.SyntaxKind.Identifier: - this.visitIdentifier( node); - break; + case ts.SyntaxKind.Identifier: + this.visitIdentifier( node); + break; - case ts.SyntaxKind.IfStatement: - this.visitIfStatement( node); - break; + case ts.SyntaxKind.IfStatement: + this.visitIfStatement( node); + break; - case ts.SyntaxKind.ImportDeclaration: - this.visitImportDeclaration( node); - break; + case ts.SyntaxKind.ImportDeclaration: + this.visitImportDeclaration( node); + break; - case ts.SyntaxKind.ImportEqualsDeclaration: - this.visitImportEqualsDeclaration( node); - break; + case ts.SyntaxKind.ImportEqualsDeclaration: + this.visitImportEqualsDeclaration( node); + break; - case ts.SyntaxKind.IndexSignature: - this.visitIndexSignatureDeclaration( node); - break; + case ts.SyntaxKind.IndexSignature: + this.visitIndexSignatureDeclaration( node); + break; - case ts.SyntaxKind.InterfaceDeclaration: - this.visitInterfaceDeclaration( node); - break; + case ts.SyntaxKind.InterfaceDeclaration: + this.visitInterfaceDeclaration( node); + break; - case ts.SyntaxKind.JsxElement: - this.visitJsxElement( node); - break; + case ts.SyntaxKind.JsxElement: + this.visitJsxElement( node); + break; - case ts.SyntaxKind.JsxSelfClosingElement: - this.visitJsxSelfClosingElement( node); - break; + case ts.SyntaxKind.JsxSelfClosingElement: + this.visitJsxSelfClosingElement( node); + break; - case ts.SyntaxKind.LabeledStatement: - this.visitLabeledStatement( node); - break; + case ts.SyntaxKind.LabeledStatement: + this.visitLabeledStatement( node); + break; - case ts.SyntaxKind.MethodDeclaration: - this.visitMethodDeclaration( node); - break; + case ts.SyntaxKind.MethodDeclaration: + this.visitMethodDeclaration( node); + break; - case ts.SyntaxKind.MethodSignature: - this.visitMethodSignature( node); - break; + case ts.SyntaxKind.MethodSignature: + this.visitMethodSignature( node); + break; - case ts.SyntaxKind.ModuleDeclaration: - this.visitModuleDeclaration( node); - break; + case ts.SyntaxKind.ModuleDeclaration: + this.visitModuleDeclaration( node); + break; - case ts.SyntaxKind.NamedImports: - this.visitNamedImports( node); - break; + case ts.SyntaxKind.NamedImports: + this.visitNamedImports( node); + break; - case ts.SyntaxKind.NamespaceImport: - this.visitNamespaceImport( node); - break; + case ts.SyntaxKind.NamespaceImport: + this.visitNamespaceImport( node); + break; - case ts.SyntaxKind.NewExpression: - this.visitNewExpression( node); - break; + case ts.SyntaxKind.NewExpression: + this.visitNewExpression( node); + break; - case ts.SyntaxKind.ObjectLiteralExpression: - this.visitObjectLiteralExpression( node); - break; + case ts.SyntaxKind.ObjectLiteralExpression: + this.visitObjectLiteralExpression( node); + break; - case ts.SyntaxKind.Parameter: - this.visitParameterDeclaration( node); - break; + case ts.SyntaxKind.Parameter: + this.visitParameterDeclaration( node); + break; - case ts.SyntaxKind.PostfixUnaryExpression: - this.visitPostfixUnaryExpression( node); - break; + case ts.SyntaxKind.PostfixUnaryExpression: + this.visitPostfixUnaryExpression( node); + break; - case ts.SyntaxKind.PrefixUnaryExpression: - this.visitPrefixUnaryExpression( node); - break; + case ts.SyntaxKind.PrefixUnaryExpression: + this.visitPrefixUnaryExpression( node); + break; - case ts.SyntaxKind.PropertyAccessExpression: - this.visitPropertyAccessExpression( node); - break; + case ts.SyntaxKind.PropertyAccessExpression: + this.visitPropertyAccessExpression( node); + break; - case ts.SyntaxKind.PropertyAssignment: - this.visitPropertyAssignment( node); - break; + case ts.SyntaxKind.PropertyAssignment: + this.visitPropertyAssignment( node); + break; - case ts.SyntaxKind.PropertyDeclaration: - this.visitPropertyDeclaration( node); - break; + case ts.SyntaxKind.PropertyDeclaration: + this.visitPropertyDeclaration( node); + break; - case ts.SyntaxKind.PropertySignature: - this.visitPropertySignature(node); - break; + case ts.SyntaxKind.PropertySignature: + this.visitPropertySignature(node); + break; - case ts.SyntaxKind.RegularExpressionLiteral: - this.visitRegularExpressionLiteral(node); - break; + case ts.SyntaxKind.RegularExpressionLiteral: + this.visitRegularExpressionLiteral(node); + break; - case ts.SyntaxKind.ReturnStatement: - this.visitReturnStatement( node); - break; + case ts.SyntaxKind.ReturnStatement: + this.visitReturnStatement( node); + break; - case ts.SyntaxKind.SetAccessor: - this.visitSetAccessor( node); - break; + case ts.SyntaxKind.SetAccessor: + this.visitSetAccessor( node); + break; - case ts.SyntaxKind.SourceFile: - this.visitSourceFile( node); - break; + case ts.SyntaxKind.SourceFile: + this.visitSourceFile( node); + break; - case ts.SyntaxKind.SwitchStatement: - this.visitSwitchStatement( node); - break; + case ts.SyntaxKind.SwitchStatement: + this.visitSwitchStatement( node); + break; - case ts.SyntaxKind.TemplateExpression: - this.visitTemplateExpression( node); - break; + case ts.SyntaxKind.TemplateExpression: + this.visitTemplateExpression( node); + break; - case ts.SyntaxKind.ThrowStatement: - this.visitThrowStatement( node); - break; + case ts.SyntaxKind.ThrowStatement: + this.visitThrowStatement( node); + break; - case ts.SyntaxKind.TryStatement: - this.visitTryStatement( node); - break; + case ts.SyntaxKind.TryStatement: + this.visitTryStatement( node); + break; - case ts.SyntaxKind.TypeAssertionExpression: - this.visitTypeAssertionExpression( node); - break; + case ts.SyntaxKind.TypeAssertionExpression: + this.visitTypeAssertionExpression( node); + break; - case ts.SyntaxKind.TypeLiteral: - this.visitTypeLiteral( node); - break; + case ts.SyntaxKind.TypeLiteral: + this.visitTypeLiteral( node); + break; - case ts.SyntaxKind.VariableDeclaration: - this.visitVariableDeclaration( node); - break; + case ts.SyntaxKind.VariableDeclaration: + this.visitVariableDeclaration( node); + break; - case ts.SyntaxKind.VariableStatement: - this.visitVariableStatement( node); - break; + case ts.SyntaxKind.VariableStatement: + this.visitVariableStatement( node); + break; - case ts.SyntaxKind.WhileStatement: - this.visitWhileStatement( node); - break; + case ts.SyntaxKind.WhileStatement: + this.visitWhileStatement( node); + break; - default: - this.walkChildren(node); - break; - } + default: + this.walkChildren(node); + break; } + } - protected walkChildren(node: ts.Node) { - ts.forEachChild(node, (child) => this.visitNode(child)); - } + protected walkChildren(node: ts.Node) { + ts.forEachChild(node, (child) => this.visitNode(child)); } } diff --git a/src/lint.ts b/src/lint.ts new file mode 100644 index 00000000000..e752f1c918c --- /dev/null +++ b/src/lint.ts @@ -0,0 +1,16 @@ +import * as formatters from "./formatters"; +import * as configuration from "./configuration"; +import * as rules from "./rules"; + +export * from "./language/rule/rule"; +export * from "./enableDisableRules"; +export * from "./formatterLoader"; +export * from "./ruleLoader"; +export * from "./language/utils"; +export * from "./language/languageServiceHost"; +export * from "./language/walker"; +export * from "./language/formatter/formatter"; + +export var Formatters = formatters; +export var Configuration = configuration; +export var Rules = rules; diff --git a/src/ruleLoader.ts b/src/ruleLoader.ts index 6e4a787173d..25e64c30d18 100644 --- a/src/ruleLoader.ts +++ b/src/ruleLoader.ts @@ -1,159 +1,158 @@ /* - * 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. - */ - -module Lint { - const fs = require("fs"); - const path = require("path"); - const {camelize, strLeft, strRight} = require("underscore.string"); - - const moduleDirectory = path.dirname(module.filename); - const CORE_RULES_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "rules"); - - export interface IEnableDisablePosition { - isEnabled: boolean; - position: number; - } +* 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 fs from "fs"; +import * as path from "path"; +import {camelize, strLeft, strRight} from "underscore.string"; +import * as Lint from "./lint"; + +const moduleDirectory = path.dirname(module.filename); +const CORE_RULES_DIRECTORY = path.resolve(moduleDirectory, "..", "build", "rules"); + +export interface IEnableDisablePosition { + isEnabled: boolean; + position: number; +} - export function loadRules(ruleConfiguration: {[name: string]: any}, - enableDisableRuleMap: {[rulename: string]: Lint.IEnableDisablePosition[]}, - rulesDirectory?: string): IRule[] { - const rules: IRule[] = []; - for (const ruleName in ruleConfiguration) { - if (ruleConfiguration.hasOwnProperty(ruleName)) { - const ruleValue = ruleConfiguration[ruleName]; - const Rule = findRule(ruleName, rulesDirectory); - if (Rule !== undefined) { - const all = "all"; // make the linter happy until we can turn it on and off - const allList = (all in enableDisableRuleMap ? enableDisableRuleMap[all] : []); - const ruleSpecificList = (ruleName in enableDisableRuleMap ? enableDisableRuleMap[ruleName] : []); - const disabledIntervals = buildDisabledIntervalsFromSwitches(ruleSpecificList, allList); - rules.push(new Rule(ruleName, ruleValue, disabledIntervals)); - } +export function loadRules(ruleConfiguration: {[name: string]: any}, + enableDisableRuleMap: {[rulename: string]: Lint.IEnableDisablePosition[]}, + rulesDirectory?: string): Lint.IRule[] { + const rules: Lint.IRule[] = []; + for (const ruleName in ruleConfiguration) { + if (ruleConfiguration.hasOwnProperty(ruleName)) { + const ruleValue = ruleConfiguration[ruleName]; + const Rule = findRule(ruleName, rulesDirectory); + if (Rule !== undefined) { + const all = "all"; // make the linter happy until we can turn it on and off + const allList = (all in enableDisableRuleMap ? enableDisableRuleMap[all] : []); + const ruleSpecificList = (ruleName in enableDisableRuleMap ? enableDisableRuleMap[ruleName] : []); + const disabledIntervals = buildDisabledIntervalsFromSwitches(ruleSpecificList, allList); + rules.push(new Rule(ruleName, ruleValue, disabledIntervals)); } } - - return rules; } - export function findRule(name: string, rulesDirectory?: string) { - let camelizedName = transformName(name); + return rules; +} + +export function findRule(name: string, rulesDirectory?: string) { + let camelizedName = transformName(name); + + // first check for core rules + let Rule = loadRule(CORE_RULES_DIRECTORY, camelizedName); + if (Rule) { + return Rule; + } - // first check for core rules - let Rule = loadRule(CORE_RULES_DIRECTORY, camelizedName); + // then check for rules within the first level of rulesDirectory + if (rulesDirectory) { + Rule = loadRule(rulesDirectory, camelizedName); if (Rule) { return Rule; } + } - // then check for rules within the first level of rulesDirectory - if (rulesDirectory) { - Rule = loadRule(rulesDirectory, camelizedName); + // finally check for rules within the first level of directories, + // using dash prefixes as the sub-directory names + if (rulesDirectory) { + const subDirectory = strLeft(rulesDirectory, "-"); + const ruleName = strRight(rulesDirectory, "-"); + if (subDirectory !== rulesDirectory && ruleName !== rulesDirectory) { + camelizedName = transformName(ruleName); + Rule = loadRule(rulesDirectory, subDirectory, camelizedName); if (Rule) { return Rule; } } + } - // finally check for rules within the first level of directories, - // using dash prefixes as the sub-directory names - if (rulesDirectory) { - const subDirectory = strLeft(rulesDirectory, "-"); - const ruleName = strRight(rulesDirectory, "-"); - if (subDirectory !== rulesDirectory && ruleName !== rulesDirectory) { - camelizedName = transformName(ruleName); - Rule = loadRule(rulesDirectory, subDirectory, camelizedName); - if (Rule) { - return Rule; - } - } - } + return undefined; +} - return undefined; +function transformName(name: string) { + // camelize strips out leading and trailing underscores and dashes, so make sure they aren't passed to camelize + // the regex matches the groups (leading underscores and dashes)(other characters)(trailing underscores and dashes) + const nameMatch = name.match(/^([-_]*)(.*?)([-_]*)$/); + if (nameMatch == null) { + return name + "Rule"; } + return nameMatch[1] + camelize(nameMatch[2]) + nameMatch[3] + "Rule"; +} - function transformName(name: string) { - // camelize strips out leading and trailing underscores and dashes, so make sure they aren't passed to camelize - // the regex matches the groups (leading underscores and dashes)(other characters)(trailing underscores and dashes) - const nameMatch = name.match(/^([-_]*)(.*?)([-_]*)$/); - if (nameMatch == null) { - return name + "Rule"; +function loadRule(...paths: string[]) { + const rulePath = paths.reduce((p, c) => path.join(p, c), ""); + const fullPath = path.resolve(moduleDirectory, rulePath); + + if (fs.existsSync(fullPath + ".js")) { + const ruleModule = require(fullPath); + if (ruleModule && ruleModule.Rule) { + return ruleModule.Rule; } - return nameMatch[1] + camelize(nameMatch[2]) + nameMatch[3] + "Rule"; } - function loadRule(...paths: string[]) { - const rulePath = paths.reduce((p, c) => path.join(p, c), ""); - const fullPath = path.resolve(moduleDirectory, rulePath); + return undefined; +} - if (fs.existsSync(fullPath + ".js")) { - const ruleModule = require(fullPath); - if (ruleModule && ruleModule.Rule) { - return ruleModule.Rule; - } +/* + * We're assuming both lists are already sorted top-down so compare the tops, use the smallest of the two, + * and build the intervals that way. + */ +function buildDisabledIntervalsFromSwitches(ruleSpecificList: IEnableDisablePosition[], allList: IEnableDisablePosition[]) { + let isCurrentlyDisabled = false; + let disabledStartPosition: number; + const disabledIntervalList: Lint.IDisabledInterval[] = []; + let i = 0; + let j = 0; + + while (i < ruleSpecificList.length || j < allList.length) { + const ruleSpecificTopPositon = (i < ruleSpecificList.length ? ruleSpecificList[i].position : Infinity); + const allTopPositon = (j < allList.length ? allList[j].position : Infinity); + let newPositionToCheck: IEnableDisablePosition; + if (ruleSpecificTopPositon < allTopPositon) { + newPositionToCheck = ruleSpecificList[i]; + i++; + } else { + newPositionToCheck = allList[j]; + j++; } - return undefined; - } - - /* - * We're assuming both lists are already sorted top-down so compare the tops, use the smallest of the two, - * and build the intervals that way. - */ - function buildDisabledIntervalsFromSwitches(ruleSpecificList: IEnableDisablePosition[], allList: IEnableDisablePosition[]) { - let isCurrentlyDisabled = false; - let disabledStartPosition: number; - const disabledIntervalList: Lint.IDisabledInterval[] = []; - let i = 0; - let j = 0; - - while (i < ruleSpecificList.length || j < allList.length) { - const ruleSpecificTopPositon = (i < ruleSpecificList.length ? ruleSpecificList[i].position : Infinity); - const allTopPositon = (j < allList.length ? allList[j].position : Infinity); - let newPositionToCheck: IEnableDisablePosition; - if (ruleSpecificTopPositon < allTopPositon) { - newPositionToCheck = ruleSpecificList[i]; - i++; + // we're currently disabled and enabling, or currently enabled and disabling -- a switch + if (newPositionToCheck.isEnabled === isCurrentlyDisabled) { + if (!isCurrentlyDisabled) { + // start a new interval + disabledStartPosition = newPositionToCheck.position; + isCurrentlyDisabled = true; } else { - newPositionToCheck = allList[j]; - j++; + // we're currently disabled and about to enable -- end the interval + disabledIntervalList.push({ + endPosition: newPositionToCheck.position, + startPosition: disabledStartPosition + }); + isCurrentlyDisabled = false; } - - // we're currently disabled and enabling, or currently enabled and disabling -- a switch - if (newPositionToCheck.isEnabled === isCurrentlyDisabled) { - if (!isCurrentlyDisabled) { - // start a new interval - disabledStartPosition = newPositionToCheck.position; - isCurrentlyDisabled = true; - } else { - // we're currently disabled and about to enable -- end the interval - disabledIntervalList.push({ - endPosition: newPositionToCheck.position, - startPosition: disabledStartPosition - }); - isCurrentlyDisabled = false; - } - } - } - - if (isCurrentlyDisabled) { - // we started an interval but didn't finish one -- so finish it with an Infinity - disabledIntervalList.push({ - endPosition: Infinity, - startPosition: disabledStartPosition - }); } + } - return disabledIntervalList; + if (isCurrentlyDisabled) { + // we started an interval but didn't finish one -- so finish it with an Infinity + disabledIntervalList.push({ + endPosition: Infinity, + startPosition: disabledStartPosition + }); } + + return disabledIntervalList; } diff --git a/src/rules.ts b/src/rules.ts new file mode 100644 index 00000000000..afbb322733c --- /dev/null +++ b/src/rules.ts @@ -0,0 +1 @@ +export * from "./language/rule/abstractRule"; diff --git a/src/rules/alignRule.ts b/src/rules/alignRule.ts index 66a9dce69d4..a6a3767603f 100644 --- a/src/rules/alignRule.ts +++ b/src/rules/alignRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static PARAMETERS_OPTION = "parameters"; diff --git a/src/rules/banRule.ts b/src/rules/banRule.ts index 811427b5010..b1460d94e21 100644 --- a/src/rules/banRule.ts +++ b/src/rules/banRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING_PART = "function invocation disallowed: "; diff --git a/src/rules/classNameRule.ts b/src/rules/classNameRule.ts index 8cb87557f85..4aafb9a75fb 100644 --- a/src/rules/classNameRule.ts +++ b/src/rules/classNameRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING = "name must be in pascal case"; diff --git a/src/rules/commentFormatRule.ts b/src/rules/commentFormatRule.ts index d4547518523..ba2a3e9f4b2 100644 --- a/src/rules/commentFormatRule.ts +++ b/src/rules/commentFormatRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_SPACE = "check-space"; const OPTION_LOWERCASE = "check-lowercase"; diff --git a/src/rules/curlyRule.ts b/src/rules/curlyRule.ts index 68d8a156718..e658a8381b6 100644 --- a/src/rules/curlyRule.ts +++ b/src/rules/curlyRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static DO_FAILURE_STRING = "do statements must be braced"; diff --git a/src/rules/eoflineRule.ts b/src/rules/eoflineRule.ts index 1df213e7197..467e58ea745 100644 --- a/src/rules/eoflineRule.ts +++ b/src/rules/eoflineRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "file should end with a newline"; diff --git a/src/rules/forinRule.ts b/src/rules/forinRule.ts index 017a8f44f81..a788a5c74f1 100644 --- a/src/rules/forinRule.ts +++ b/src/rules/forinRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "for (... in ...) statements must be filtered with an if statement"; diff --git a/src/rules/indentRule.ts b/src/rules/indentRule.ts index 398f881b1d3..ce241132f5d 100644 --- a/src/rules/indentRule.ts +++ b/src/rules/indentRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_USE_TABS = "tabs"; const OPTION_USE_SPACES = "spaces"; diff --git a/src/rules/interfaceNameRule.ts b/src/rules/interfaceNameRule.ts index 4116f53f249..7e84cde0fc4 100644 --- a/src/rules/interfaceNameRule.ts +++ b/src/rules/interfaceNameRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING = "interface name must be a capitalized I"; diff --git a/src/rules/jsdocFormatRule.ts b/src/rules/jsdocFormatRule.ts index d5c792dc972..db6bd0d815d 100644 --- a/src/rules/jsdocFormatRule.ts +++ b/src/rules/jsdocFormatRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static ALIGNMENT_FAILURE_STRING = "asterisks in jsdoc must be aligned"; diff --git a/src/rules/labelPositionRule.ts b/src/rules/labelPositionRule.ts index d31f5f01b2a..725989a2396 100644 --- a/src/rules/labelPositionRule.ts +++ b/src/rules/labelPositionRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "unexpected label on statement"; diff --git a/src/rules/labelUndefinedRule.ts b/src/rules/labelUndefinedRule.ts index bae942bf424..4fca184a05f 100644 --- a/src/rules/labelUndefinedRule.ts +++ b/src/rules/labelUndefinedRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "undefined label: '"; diff --git a/src/rules/maxLineLengthRule.ts b/src/rules/maxLineLengthRule.ts index 90437710da2..e3d484fd891 100644 --- a/src/rules/maxLineLengthRule.ts +++ b/src/rules/maxLineLengthRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "exceeds maximum line length of "; diff --git a/src/rules/memberAccessRule.ts b/src/rules/memberAccessRule.ts index 2830ea2d463..37dacde5cd3 100644 --- a/src/rules/memberAccessRule.ts +++ b/src/rules/memberAccessRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING = "default access modifier on member/method not allowed"; diff --git a/src/rules/memberOrderingRule.ts b/src/rules/memberOrderingRule.ts index 4d0f824f741..2633a585e3c 100644 --- a/src/rules/memberOrderingRule.ts +++ b/src/rules/memberOrderingRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_VARIABLES_BEFORE_FUNCTIONS = "variables-before-functions"; const OPTION_STATIC_BEFORE_INSTANCE = "static-before-instance"; diff --git a/src/rules/noAnyRule.ts b/src/rules/noAnyRule.ts index 9e16ac3beeb..d696b07ad06 100644 --- a/src/rules/noAnyRule.ts +++ b/src/rules/noAnyRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "type decoration of 'any' is forbidden"; diff --git a/src/rules/noArgRule.ts b/src/rules/noArgRule.ts index a6cb4348c15..799c2236c64 100644 --- a/src/rules/noArgRule.ts +++ b/src/rules/noArgRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "access forbidden to arguments property"; diff --git a/src/rules/noBitwiseRule.ts b/src/rules/noBitwiseRule.ts index dd9a88a1f81..aea9a926ab0 100644 --- a/src/rules/noBitwiseRule.ts +++ b/src/rules/noBitwiseRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "forbidden bitwise operation"; diff --git a/src/rules/noConditionalAssignmentRule.ts b/src/rules/noConditionalAssignmentRule.ts index 86f74c4c46e..2e05fde2592 100644 --- a/src/rules/noConditionalAssignmentRule.ts +++ b/src/rules/noConditionalAssignmentRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "assignment in conditional: "; diff --git a/src/rules/noConsecutiveBlankLinesRule.ts b/src/rules/noConsecutiveBlankLinesRule.ts index 6970f01a930..2e7fdd44c8c 100644 --- a/src/rules/noConsecutiveBlankLinesRule.ts +++ b/src/rules/noConsecutiveBlankLinesRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING = "consecutive blank lines are disallowed"; diff --git a/src/rules/noConsoleRule.ts b/src/rules/noConsoleRule.ts index cd22d8214fd..cd0e29ecc60 100644 --- a/src/rules/noConsoleRule.ts +++ b/src/rules/noConsoleRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; import BanRule = require("./banRule"); diff --git a/src/rules/noConstructRule.ts b/src/rules/noConstructRule.ts index 0d5eb19bd09..9834b9c7534 100644 --- a/src/rules/noConstructRule.ts +++ b/src/rules/noConstructRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "undesirable constructor use"; diff --git a/src/rules/noConstructorVarsRule.ts b/src/rules/noConstructorVarsRule.ts index 47e51c895f9..1ff0cea878d 100644 --- a/src/rules/noConstructorVarsRule.ts +++ b/src/rules/noConstructorVarsRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING_PART = " cannot be declared in the constructor"; diff --git a/src/rules/noDebuggerRule.ts b/src/rules/noDebuggerRule.ts index efef88e0dba..a7d9fd4432a 100644 --- a/src/rules/noDebuggerRule.ts +++ b/src/rules/noDebuggerRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "use of debugger statements is disallowed"; diff --git a/src/rules/noDuplicateKeyRule.ts b/src/rules/noDuplicateKeyRule.ts index 4502eaee14a..f1319fd4a50 100644 --- a/src/rules/noDuplicateKeyRule.ts +++ b/src/rules/noDuplicateKeyRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "duplicate key '"; diff --git a/src/rules/noDuplicateVariableRule.ts b/src/rules/noDuplicateVariableRule.ts index b871110273e..2536b920db4 100644 --- a/src/rules/noDuplicateVariableRule.ts +++ b/src/rules/noDuplicateVariableRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "duplicate variable: '"; diff --git a/src/rules/noEmptyRule.ts b/src/rules/noEmptyRule.ts index d5693f2957a..ec4f726b5fb 100644 --- a/src/rules/noEmptyRule.ts +++ b/src/rules/noEmptyRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "block is empty"; diff --git a/src/rules/noEvalRule.ts b/src/rules/noEvalRule.ts index 2100683f985..2334df48333 100644 --- a/src/rules/noEvalRule.ts +++ b/src/rules/noEvalRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "forbidden eval"; diff --git a/src/rules/noInferrableTypesRule.ts b/src/rules/noInferrableTypesRule.ts index 3f960ce3b23..03067af0006 100644 --- a/src/rules/noInferrableTypesRule.ts +++ b/src/rules/noInferrableTypesRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING_FACTORY = (type: string) => `LHS type (${type}) inferred by RHS expression, remove type annotation`; diff --git a/src/rules/noInternalModuleRule.ts b/src/rules/noInternalModuleRule.ts index 29824e00dff..bfe1e864f71 100644 --- a/src/rules/noInternalModuleRule.ts +++ b/src/rules/noInternalModuleRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "forbidden internal module"; diff --git a/src/rules/noRequireImportsRule.ts b/src/rules/noRequireImportsRule.ts index 617efbe3792..714aa6e036e 100644 --- a/src/rules/noRequireImportsRule.ts +++ b/src/rules/noRequireImportsRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "require() style import is forbidden"; diff --git a/src/rules/noShadowedVariableRule.ts b/src/rules/noShadowedVariableRule.ts index 03fc1d6e28c..a1b776c89d5 100644 --- a/src/rules/noShadowedVariableRule.ts +++ b/src/rules/noShadowedVariableRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "shadowed variable: '"; diff --git a/src/rules/noStringLiteralRule.ts b/src/rules/noStringLiteralRule.ts index c3ef30b90cf..cd830c326f7 100644 --- a/src/rules/noStringLiteralRule.ts +++ b/src/rules/noStringLiteralRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "object access via string literals is disallowed"; diff --git a/src/rules/noSwitchCaseFallThroughRule.ts b/src/rules/noSwitchCaseFallThroughRule.ts index d2a0785359f..43947351107 100644 --- a/src/rules/noSwitchCaseFallThroughRule.ts +++ b/src/rules/noSwitchCaseFallThroughRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING_PART = "expected a 'break' before "; diff --git a/src/rules/noTrailingCommaRule.ts b/src/rules/noTrailingCommaRule.ts index d91d2b7b70e..acdd6f8fb0c 100644 --- a/src/rules/noTrailingCommaRule.ts +++ b/src/rules/noTrailingCommaRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "trailing comma"; diff --git a/src/rules/noTrailingWhitespaceRule.ts b/src/rules/noTrailingWhitespaceRule.ts index 472b0020e0f..2216cf39c26 100644 --- a/src/rules/noTrailingWhitespaceRule.ts +++ b/src/rules/noTrailingWhitespaceRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "trailing whitespace"; diff --git a/src/rules/noUnreachableRule.ts b/src/rules/noUnreachableRule.ts index a3a55e1f18e..6e3bb0182ce 100644 --- a/src/rules/noUnreachableRule.ts +++ b/src/rules/noUnreachableRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "unreachable code"; diff --git a/src/rules/noUnusedExpressionRule.ts b/src/rules/noUnusedExpressionRule.ts index f659b3b5e54..7d4d255c6ed 100644 --- a/src/rules/noUnusedExpressionRule.ts +++ b/src/rules/noUnusedExpressionRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "expected an assignment or function call"; diff --git a/src/rules/noUnusedVariableRule.ts b/src/rules/noUnusedVariableRule.ts index 120ef8cc901..bd2c258e248 100644 --- a/src/rules/noUnusedVariableRule.ts +++ b/src/rules/noUnusedVariableRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_CHECK_PARAMETERS = "check-parameters"; diff --git a/src/rules/noUseBeforeDeclareRule.ts b/src/rules/noUseBeforeDeclareRule.ts index f4273e8a565..6e6f5cabc6b 100644 --- a/src/rules/noUseBeforeDeclareRule.ts +++ b/src/rules/noUseBeforeDeclareRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING_PREFIX = "variable '"; diff --git a/src/rules/noVarKeywordRule.ts b/src/rules/noVarKeywordRule.ts index 5292da04b0f..fa3e8dc86a8 100644 --- a/src/rules/noVarKeywordRule.ts +++ b/src/rules/noVarKeywordRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "forbidden var keyword"; diff --git a/src/rules/noVarRequiresRule.ts b/src/rules/noVarRequiresRule.ts index 0e8cab9bd67..e7d2caec047 100644 --- a/src/rules/noVarRequiresRule.ts +++ b/src/rules/noVarRequiresRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "require statement not part of an import statement"; diff --git a/src/rules/oneLineRule.ts b/src/rules/oneLineRule.ts index 56fc183c3ff..4e752f0d24d 100644 --- a/src/rules/oneLineRule.ts +++ b/src/rules/oneLineRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_BRACE = "check-open-brace"; const OPTION_CATCH = "check-catch"; diff --git a/src/rules/quotemarkRule.ts b/src/rules/quotemarkRule.ts index 882bf30eba4..8f0b37b2c89 100644 --- a/src/rules/quotemarkRule.ts +++ b/src/rules/quotemarkRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; enum QuoteMark { SINGLE_QUOTES, diff --git a/src/rules/radixRule.ts b/src/rules/radixRule.ts index c11b8328fb3..154341c9c36 100644 --- a/src/rules/radixRule.ts +++ b/src/rules/radixRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "missing radix parameter"; diff --git a/src/rules/semicolonRule.ts b/src/rules/semicolonRule.ts index b4fc4470152..c1290e4bf21 100644 --- a/src/rules/semicolonRule.ts +++ b/src/rules/semicolonRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "missing semicolon"; diff --git a/src/rules/sortObjectLiteralKeysRule.ts b/src/rules/sortObjectLiteralKeysRule.ts index e8722fdbf26..2ed6ed64762 100644 --- a/src/rules/sortObjectLiteralKeysRule.ts +++ b/src/rules/sortObjectLiteralKeysRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "unsorted key '"; diff --git a/src/rules/switchDefaultRule.ts b/src/rules/switchDefaultRule.ts index 01473230a65..2a6e34b235a 100644 --- a/src/rules/switchDefaultRule.ts +++ b/src/rules/switchDefaultRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "switch statement doesn't include a 'default' case"; diff --git a/src/rules/tripleEqualsRule.ts b/src/rules/tripleEqualsRule.ts index c38f1df8e4d..edcc328eb89 100644 --- a/src/rules/tripleEqualsRule.ts +++ b/src/rules/tripleEqualsRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_ALLOW_NULL_CHECK = "allow-null-check"; diff --git a/src/rules/tsconfig.json b/src/rules/tsconfig.json deleted file mode 100644 index 9fadf1a3a39..00000000000 --- a/src/rules/tsconfig.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "version": "1.6.2", - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": true, - "sourceMap": false, - "target": "es5", - "outDir": "../../build/rules/" - }, - "filesGlob": [ - "../../lib/tslint.d.ts", - "../../typings/*.d.ts", - "./*.ts" - ], - "files": [ - "../../lib/tslint.d.ts", - "../../typings/node.d.ts", - "../../typings/typescriptServices.d.ts", - "./alignRule.ts", - "./banRule.ts", - "./classNameRule.ts", - "./commentFormatRule.ts", - "./curlyRule.ts", - "./eoflineRule.ts", - "./forinRule.ts", - "./indentRule.ts", - "./interfaceNameRule.ts", - "./jsdocFormatRule.ts", - "./labelPositionRule.ts", - "./labelUndefinedRule.ts", - "./maxLineLengthRule.ts", - "./memberAccessRule.ts", - "./memberOrderingRule.ts", - "./noAnyRule.ts", - "./noArgRule.ts", - "./noBitwiseRule.ts", - "./noConditionalAssignmentRule.ts", - "./noConsecutiveBlankLinesRule.ts", - "./noConsoleRule.ts", - "./noConstructRule.ts", - "./noConstructorVarsRule.ts", - "./noDebuggerRule.ts", - "./noDuplicateKeyRule.ts", - "./noDuplicateVariableRule.ts", - "./noEmptyRule.ts", - "./noEvalRule.ts", - "./noInferrableTypesRule.ts", - "./noInternalModuleRule.ts", - "./noRequireImportsRule.ts", - "./noShadowedVariableRule.ts", - "./noStringLiteralRule.ts", - "./noSwitchCaseFallThroughRule.ts", - "./noTrailingCommaRule.ts", - "./noTrailingWhitespaceRule.ts", - "./noUnreachableRule.ts", - "./noUnusedExpressionRule.ts", - "./noUnusedVariableRule.ts", - "./noUseBeforeDeclareRule.ts", - "./noVarKeywordRule.ts", - "./noVarRequiresRule.ts", - "./oneLineRule.ts", - "./quotemarkRule.ts", - "./radixRule.ts", - "./semicolonRule.ts", - "./sortObjectLiteralKeysRule.ts", - "./switchDefaultRule.ts", - "./tripleEqualsRule.ts", - "./typedefRule.ts", - "./typedefWhitespaceRule.ts", - "./useStrictRule.ts", - "./variableNameRule.ts", - "./whitespaceRule.ts" - ] -} diff --git a/src/rules/typedefRule.ts b/src/rules/typedefRule.ts index 246e5014299..bd6cdf8ff6e 100644 --- a/src/rules/typedefRule.ts +++ b/src/rules/typedefRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "missing type declaration"; diff --git a/src/rules/typedefWhitespaceRule.ts b/src/rules/typedefWhitespaceRule.ts index 961c19c88b0..c727ae6b06f 100644 --- a/src/rules/typedefWhitespaceRule.ts +++ b/src/rules/typedefWhitespaceRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "missing type declaration"; diff --git a/src/rules/useStrictRule.ts b/src/rules/useStrictRule.ts index ea5e1ffb0ea..9b24663fd24 100644 --- a/src/rules/useStrictRule.ts +++ b/src/rules/useStrictRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; export class Rule extends Lint.Rules.AbstractRule { public static FAILURE_STRING = "missing 'use strict'"; diff --git a/src/rules/variableNameRule.ts b/src/rules/variableNameRule.ts index bf27cafd3e3..adc0e820edb 100644 --- a/src/rules/variableNameRule.ts +++ b/src/rules/variableNameRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_LEADING_UNDERSCORE = "allow-leading-underscore"; const OPTION_TRAILING_UNDERSCORE = "allow-trailing-underscore"; diff --git a/src/rules/whitespaceRule.ts b/src/rules/whitespaceRule.ts index 5dafd23489e..5181db8c698 100644 --- a/src/rules/whitespaceRule.ts +++ b/src/rules/whitespaceRule.ts @@ -13,6 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import * as Lint from "../lint"; +import * as ts from "typescript"; const OPTION_BRANCH = "check-branch"; const OPTION_DECL = "check-decl"; diff --git a/src/tsconfig.json b/src/tsconfig.json deleted file mode 100644 index eb1ebf07bf2..00000000000 --- a/src/tsconfig.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": "1.6.2", - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": true, - "declaration": true, - "sourceMap": false, - "target": "es5", - "out": "../build/tslint.js" - }, - "filesGlob": [ - "../typings/*.d.ts", - "./language/walker/syntaxWalker.ts", - "./language/walker/ruleWalker.ts", - "./language/walker/scopeAwareRuleWalker.ts", - "./language/**/*.ts", - "./*.ts", - "!./tslint-cli.ts" - ], - "files": [ - "../typings/node.d.ts", - "../typings/typescriptServices.d.ts", - "./language/walker/syntaxWalker.ts", - "./language/walker/ruleWalker.ts", - "./language/walker/scopeAwareRuleWalker.ts", - "./language/formatter/abstractFormatter.ts", - "./language/formatter/formatter.ts", - "./language/languageServiceHost.ts", - "./language/rule/abstractRule.ts", - "./language/rule/rule.ts", - "./language/utils.ts", - "./language/walker/blockScopeAwareRuleWalker.ts", - "./language/walker/skippableTokenAwareRuleWalker.ts", - "./configuration.ts", - "./enableDisableRules.ts", - "./formatterLoader.ts", - "./ruleLoader.ts", - "./tslint.ts" - ] -} diff --git a/src/tslint-cli.ts b/src/tslint-cli.ts index 69370655149..7c6686e59f5 100644 --- a/src/tslint-cli.ts +++ b/src/tslint-cli.ts @@ -14,167 +14,162 @@ * limitations under the License. */ -/// -/// -/// - -module Lint { - const fs = require("fs"); - const optimist = require("optimist") - .usage("Usage: $0 [options] [file ...]") - .check((argv: any) => { - // at least one of file, help, version or unqualified argument must be present - if (!(argv.h || argv.v || argv._.length > 0)) { - throw "Missing files"; - } - - if (argv.f) { - throw "-f option is no longer available. Supply files directly to the tslint command instead."; - } - }) - .options({ - "c": { - alias: "config", - describe: "configuration file" - }, - "h": { - alias: "help", - describe: "display detailed help" - }, - "o": { - alias: "out", - describe: "output file" - }, - "r": { - alias: "rules-dir", - describe: "rules directory" - }, - "s": { - alias: "formatters-dir", - describe: "formatters directory" - }, - "t": { - alias: "format", - default: "prose", - describe: "output format (prose, json, verbose)" - }, - "v": { - alias: "version", - describe: "current version" - } - }); - const argv = optimist.argv; - - let outputStream: any; - if (argv.o !== undefined) { - outputStream = fs.createWriteStream(argv.o, { - end: false, - flags: "w+", - mode: 420 - }); - } else { - outputStream = process.stdout; - } +import * as Linter from "./tslint"; +import * as fs from "fs"; +import * as optimist from "optimist"; +optimist + .usage("Usage: $0 [options] [file ...]") + .check((argv: any) => { + // at least one of file, help, version or unqualified argument must be present + if (!(argv.h || argv.v || argv._.length > 0)) { + throw "Missing files"; + } - if (argv.v !== undefined) { - outputStream.write(Linter.VERSION + "\n"); - process.exit(0); - } + if (argv.f) { + throw "-f option is no longer available. Supply files directly to the tslint command instead."; + } + }) + .options({ + "c": { + alias: "config", + describe: "configuration file" + }, + "h": { + alias: "help", + describe: "display detailed help" + }, + "o": { + alias: "out", + describe: "output file" + }, + "r": { + alias: "rules-dir", + describe: "rules directory" + }, + "s": { + alias: "formatters-dir", + describe: "formatters directory" + }, + "t": { + alias: "format", + default: "prose", + describe: "output format (prose, json, verbose)" + }, + "v": { + alias: "version", + describe: "current version" + } + }); +const argv = optimist.argv; + +let outputStream: any; +if (argv.o !== undefined) { + outputStream = fs.createWriteStream(argv.o, { + flags: "w+", + mode: 420 + }); +} else { + outputStream = process.stdout; +} - if ("help" in argv) { - outputStream.write(optimist.help()); - const outputString = ` - tslint accepts the following commandline options: - - -c, --config: - The location of the configuration file that tslint will use to - determine which rules are activated and what options to provide - to the rules. If no option is specified, the config file named - tslint.json is used, so long as it exists in the path. - The format of the file is { rules: { /* rules list */ } }, - where /* rules list */ is a key: value comma-seperated list of - rulename: rule-options pairs. Rule-options can be either a - boolean true/false value denoting whether the rule is used or not, - or a list [boolean, ...] where the boolean provides the same role - as in the non-list case, and the rest of the list are options passed - to the rule that will determine what it checks for (such as number - of characters for the max-line-length rule, or what functions to ban - for the ban rule). - - -o, --out: - A filename to output the results to. By default, tslint outputs to - stdout, which is usually the console where you're running it from. - - -r, --rules-dir: - An additional rules directory, for additional user-created rules. - tslint will always check its default rules directory, in - node_modules/tslint/build/rules, before checking the user-provided - rules directory, so rules in the user-provided rules directory - with the same name as the base rules will not be loaded. - - -s, --formatters-dir: - An additional formatters directory, for user-created formatters. - Formatters are files that will format the tslint output, before - writing it to stdout or the file passed in --out. The default - directory, node_modules/tslint/build/formatters, will always be - checked first, so user-created formatters with the same names - as the base formatters will not be loaded. - - -t, --format: - The formatter to use to format the results of the linter before - outputting it to stdout or the file passed in --out. The core - formatters are prose (human readable), json (machine readable) - and verbose. prose is the default if this option is not used. Additonal - formatters can be added and used if the --formatters-dir option is set. - - -v, --version: - The current version of tslint. - - -h, --help: - Prints this help message.\n`; - outputStream.write(outputString); - process.exit(0); - } +if (argv.v !== undefined) { + outputStream.write(Linter.VERSION + "\n"); + process.exit(0); +} + +if ("help" in argv) { + outputStream.write(optimist.help()); + const outputString = ` +tslint accepts the following commandline options: + + -c, --config: + The location of the configuration file that tslint will use to + determine which rules are activated and what options to provide + to the rules. If no option is specified, the config file named + tslint.json is used, so long as it exists in the path. + The format of the file is { rules: { /* rules list */ } }, + where /* rules list */ is a key: value comma-seperated list of + rulename: rule-options pairs. Rule-options can be either a + boolean true/false value denoting whether the rule is used or not, + or a list [boolean, ...] where the boolean provides the same role + as in the non-list case, and the rest of the list are options passed + to the rule that will determine what it checks for (such as number + of characters for the max-line-length rule, or what functions to ban + for the ban rule). + + -o, --out: + A filename to output the results to. By default, tslint outputs to + stdout, which is usually the console where you're running it from. + + -r, --rules-dir: + An additional rules directory, for additional user-created rules. + tslint will always check its default rules directory, in + node_modules/tslint/build/rules, before checking the user-provided + rules directory, so rules in the user-provided rules directory + with the same name as the base rules will not be loaded. + + -s, --formatters-dir: + An additional formatters directory, for user-created formatters. + Formatters are files that will format the tslint output, before + writing it to stdout or the file passed in --out. The default + directory, node_modules/tslint/build/formatters, will always be + checked first, so user-created formatters with the same names + as the base formatters will not be loaded. + + -t, --format: + The formatter to use to format the results of the linter before + outputting it to stdout or the file passed in --out. The core + formatters are prose (human readable), json (machine readable) + and verbose. prose is the default if this option is not used. Additonal + formatters can be added and used if the --formatters-dir option is set. + + -v, --version: + The current version of tslint. + + -h, --help: + Prints this help message.\n`; + outputStream.write(outputString); + process.exit(0); +} - // when provided, it should point to an existing location - if (argv.c && !fs.existsSync(argv.c)) { - console.error("Invalid option for configuration: " + argv.c); +// when provided, it should point to an existing location +if (argv.c && !fs.existsSync(argv.c)) { + console.error("Invalid option for configuration: " + argv.c); + process.exit(1); +} + +const processFile = (file: string) => { + if (!fs.existsSync(file)) { + console.error("Unable to open file: " + file); process.exit(1); } - const processFile = (file: string) => { - if (!fs.existsSync(file)) { - console.error("Unable to open file: " + file); - process.exit(1); - } - - const contents = fs.readFileSync(file, "utf8"); - const configuration = Configuration.findConfiguration(argv.c, file); + const contents = fs.readFileSync(file, "utf8"); + const configuration = Linter.findConfiguration(argv.c, file); - if (configuration === undefined) { - console.error("unable to find tslint configuration"); - process.exit(1); - } + if (configuration === undefined) { + console.error("unable to find tslint configuration"); + process.exit(1); + } - const linter = new Linter(file, contents, { - configuration: configuration, - formatter: argv.t, - formattersDirectory: argv.s, - rulesDirectory: argv.r - }); + const linter = new Linter(file, contents, { + configuration: configuration, + formatter: argv.t, + formattersDirectory: argv.s, + rulesDirectory: argv.r + }); - const lintResult = linter.lint(); + const lintResult = linter.lint(); - if (lintResult.failureCount > 0) { - outputStream.write(lintResult.output, () => { - process.exit(2); - }); - } - }; + if (lintResult.failureCount > 0) { + outputStream.write(lintResult.output, () => { + process.exit(2); + }); + } +}; - const files = argv._; +const files = argv._; - for (const file of files) { - processFile(file); - } +for (const file of files) { + processFile(file); } diff --git a/src/tslint.ts b/src/tslint.ts index 8cf7811946d..43af460cb94 100644 --- a/src/tslint.ts +++ b/src/tslint.ts @@ -14,106 +14,100 @@ * limitations under the License. */ -module Lint { - const path = require("path"); - const moduleDirectory = path.dirname(module.filename); +import * as Lint from "./lint"; +import * as path from "path"; +const moduleDirectory = path.dirname(module.filename); - export interface LintResult { - failureCount: number; - failures: RuleFailure[]; - format: string; - output: string; - } +class Linter { + public static VERSION = "2.5.1"; - export interface ILinterOptions { - configuration: any; - formatter: string; - formattersDirectory: string; - rulesDirectory: string; - } - - export class Linter { - public static VERSION = "2.5.1"; - - private fileName: string; - private source: string; - private options: ILinterOptions; + private fileName: string; + private source: string; + private options: Linter.ILinterOptions; - constructor(fileName: string, source: string, options: ILinterOptions) { - this.fileName = fileName; - this.source = source; - this.options = options; - } + constructor(fileName: string, source: string, options: Linter.ILinterOptions) { + this.fileName = fileName; + this.source = source; + this.options = options; + } - public lint(): LintResult { - const failures: RuleFailure[] = []; - const sourceFile = Lint.getSourceFile(this.fileName, this.source); - - // walk the code first to find all the intervals where rules are disabled - const rulesWalker = new EnableDisableRulesWalker(sourceFile, { - disabledIntervals: [], - ruleName: "" - }); - rulesWalker.walk(sourceFile); - const enableDisableRuleMap = rulesWalker.enableDisableRuleMap; - - const rulesDirectory = this.getRelativePath(this.options.rulesDirectory); - const configuration = this.options.configuration.rules; - const configuredRules = Lint.loadRules(configuration, enableDisableRuleMap, rulesDirectory); - for (let rule of configuredRules) { - if (rule.isEnabled()) { - const ruleFailures = rule.apply(sourceFile); - for (let ruleFailure of ruleFailures) { - if (!this.containsRule(failures, ruleFailure)) { - failures.push(ruleFailure); - } + public lint(): Linter.LintResult { + const failures: Lint.RuleFailure[] = []; + const sourceFile = Lint.getSourceFile(this.fileName, this.source); + + // walk the code first to find all the intervals where rules are disabled + const rulesWalker = new Lint.EnableDisableRulesWalker(sourceFile, { + disabledIntervals: [], + ruleName: "" + }); + rulesWalker.walk(sourceFile); + const enableDisableRuleMap = rulesWalker.enableDisableRuleMap; + + const rulesDirectory = this.getRelativePath(this.options.rulesDirectory); + const configuration = this.options.configuration.rules; + const configuredRules = Lint.loadRules(configuration, enableDisableRuleMap, rulesDirectory); + for (let rule of configuredRules) { + if (rule.isEnabled()) { + const ruleFailures = rule.apply(sourceFile); + for (let ruleFailure of ruleFailures) { + if (!this.containsRule(failures, ruleFailure)) { + failures.push(ruleFailure); } } } + } - let formatter: Lint.IFormatter; - const formattersDirectory = this.getRelativePath(this.options.formattersDirectory); - - const Formatter = Lint.findFormatter(this.options.formatter, formattersDirectory); - if (Formatter) { - formatter = new Formatter(); - } else { - throw new Error("formatter '" + this.options.formatter + "' not found"); - } + let formatter: Lint.IFormatter; + const formattersDirectory = this.getRelativePath(this.options.formattersDirectory); - const output = formatter.format(failures); - return { - failureCount: failures.length, - failures: failures, - format: this.options.formatter, - output: output - }; + const Formatter = Lint.findFormatter(this.options.formatter, formattersDirectory); + if (Formatter) { + formatter = new Formatter(); + } else { + throw new Error("formatter '" + this.options.formatter + "' not found"); } - private getRelativePath(directory: string): string { - if (directory) { - return path.relative(moduleDirectory, directory); - } + const output = formatter.format(failures); + return { + failureCount: failures.length, + failures: failures, + format: this.options.formatter, + output: output + }; + } - return undefined; + private getRelativePath(directory: string): string { + if (directory) { + return path.relative(moduleDirectory, directory); } - private containsRule(rules: RuleFailure[], rule: RuleFailure) { - return rules.some((r) => r.equals(rule)); - } + return undefined; + } + + private containsRule(rules: Lint.RuleFailure[], rule: Lint.RuleFailure) { + return rules.some((r) => r.equals(rule)); } } -// add the Lint and TypeScript modules to global for pluggable formatters/rules -global.Lint = Lint; -global.ts = ts; +import {findConfiguration as config} from "./configuration"; -// export Lint.Linter as the API interface for this module -module.exports = Lint.Linter; -// also export Lint.Configuration.findConfiguration so implementers can consume -module.exports.findConfiguration = Lint.Configuration.findConfiguration; +namespace Linter { + export var findConfiguration = config; + export interface LintResult { + failureCount: number; + failures: Lint.RuleFailure[]; + format: string; + output: string; + } -declare module "tslint" { - import Linter = Lint.Linter; - export = Linter; + export interface ILinterOptions { + configuration: any; + formatter: string; + formattersDirectory: string; + rulesDirectory: string; + } } + +// export Lint.Linter as the API interface for this module +export = Linter; + diff --git a/test/chaiAssert.ts b/test/chaiAssert.d.ts similarity index 100% rename from test/chaiAssert.ts rename to test/chaiAssert.d.ts diff --git a/test/helper.ts b/test/helper.ts index da39265cc95..5b15eab79e9 100644 --- a/test/helper.ts +++ b/test/helper.ts @@ -14,70 +14,69 @@ * limitations under the License. */ -module Lint.Test { - const fs = require("fs"); - const path = require("path"); +import * as fs from "fs"; +import * as path from "path"; +import * as Lint from "tslint"; - export function getSourceFile(fileName: string): ts.SourceFile { - const relativePath = path.join("test", "files", fileName); - const source = fs.readFileSync(relativePath, "utf8"); +export function getSourceFile(fileName: string): ts.SourceFile { + const relativePath = path.join("test", "files", fileName); + const source = fs.readFileSync(relativePath, "utf8"); - return Lint.getSourceFile(fileName, source); - } + return Lint.getSourceFile(fileName, source); +} - export function getRule(ruleName: string) { - const rulesDirectory = path.join(global.process.cwd(), "build/rules"); - return Lint.findRule(ruleName, rulesDirectory); - } +export function getRule(ruleName: string) { + const rulesDirectory = path.join(global.process.cwd(), "build/rules"); + return Lint.findRule(ruleName, rulesDirectory); +} - export function getFormatter(formatterName: string) { - const formattersDirectory = path.join(global.process.cwd(), "build/formatters"); - return Lint.findFormatter(formatterName, formattersDirectory); - } +export function getFormatter(formatterName: string) { + const formattersDirectory = path.join(global.process.cwd(), "build/formatters"); + return Lint.findFormatter(formatterName, formattersDirectory); +} - export function applyRuleOnFile(fileName: string, Rule: any, ruleValue: any = true): Lint.RuleFailure[] { - const sourceFile = getSourceFile(fileName); - const rule = new Rule("", ruleValue, []); - return rule.apply(sourceFile); - } +export function applyRuleOnFile(fileName: string, Rule: any, ruleValue: any = true): Lint.RuleFailure[] { + const sourceFile = getSourceFile(fileName); + const rule = new Rule("", ruleValue, []); + return rule.apply(sourceFile); +} - // start and end are arrays with the first and second elements - // being (one-indexed) line and character positions respectively - export function createFailure(fileName: string, start: number[], end: number[], failure: string): Lint.RuleFailure { - const sourceFile = getSourceFile(fileName); - const startPosition = sourceFile.getPositionOfLineAndCharacter(start[0] - 1, start[1] - 1); - const endPosition = sourceFile.getPositionOfLineAndCharacter(end[0] - 1, end[1] - 1); +// start and end are arrays with the first and second elements +// being (one-indexed) line and character positions respectively +export function createFailure(fileName: string, start: number[], end: number[], failure: string): Lint.RuleFailure { + const sourceFile = getSourceFile(fileName); + const startPosition = sourceFile.getPositionOfLineAndCharacter(start[0] - 1, start[1] - 1); + const endPosition = sourceFile.getPositionOfLineAndCharacter(end[0] - 1, end[1] - 1); - return new Lint.RuleFailure(sourceFile, startPosition, endPosition, failure, ""); - } + return new Lint.RuleFailure(sourceFile, startPosition, endPosition, failure, ""); +} - // return a partial on createFailure - export function createFailuresOnFile(fileName: string, failure: string) { - return function(start: number[], end: number[]) { - return createFailure(fileName, start, end, failure); - }; - } +// return a partial on createFailure +export function createFailuresOnFile(fileName: string, failure: string) { + return function(start: number[], end: number[]) { + return createFailure(fileName, start, end, failure); + }; +} - // assert on array equality for failures - export function assertFailuresEqual(actualFailures: Lint.RuleFailure[], expectedFailures: Lint.RuleFailure[]) { - assert.equal(actualFailures.length, expectedFailures.length); - actualFailures.forEach((actualFailure, i) => { - const startPosition = JSON.stringify(actualFailure.getStartPosition().toJson()); - const endPosition = JSON.stringify(actualFailure.getEndPosition().toJson()); - assert.isTrue(actualFailure.equals(expectedFailures[i]), - `actual failure at ${startPosition}, ${endPosition} did not match expected failure`); - }); - } +// assert on array equality for failures +export function assertFailuresEqual(actualFailures: Lint.RuleFailure[], expectedFailures: Lint.RuleFailure[]) { + assert.equal(actualFailures.length, expectedFailures.length); + actualFailures.forEach((actualFailure, i) => { + const startPosition = JSON.stringify(actualFailure.getStartPosition().toJson()); + const endPosition = JSON.stringify(actualFailure.getEndPosition().toJson()); + assert.isTrue(actualFailure.equals(expectedFailures[i]), + `actual failure at ${startPosition}, ${endPosition} did not match expected failure`); + }); +} - // assert whether a failure array contains the given failure - export function assertContainsFailure(haystack: Lint.RuleFailure[], needle: Lint.RuleFailure) { - const haystackContainsNeedle = haystack.some((item) => item.equals(needle)); +// assert whether a failure array contains the given failure +export function assertContainsFailure(haystack: Lint.RuleFailure[], needle: Lint.RuleFailure) { + const haystackContainsNeedle = haystack.some((item) => item.equals(needle)); - if (!haystackContainsNeedle) { - const stringifiedNeedle = JSON.stringify(needle.toJson(), null, 2); - const stringifiedHaystack = JSON.stringify(haystack.map((hay) => hay.toJson()), null, 2); + if (!haystackContainsNeedle) { + const stringifiedNeedle = JSON.stringify(needle.toJson(), null, 2); + const stringifiedHaystack = JSON.stringify(haystack.map((hay) => hay.toJson()), null, 2); - assert(false, "expected " + stringifiedNeedle + " within " + stringifiedHaystack); - } + assert(false, "expected " + stringifiedNeedle + " within " + stringifiedHaystack); } } diff --git a/test/tsconfig.json b/test/tsconfig.json index 5885599c073..0563d78bcda 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -5,10 +5,10 @@ "noImplicitAny": true, "sourceMap": false, "target": "es5", - "out": "../build/tslint-tests.js" + "outDir": "../build/tests" }, "filesGlob": [ - "../typings/*.d.ts", + "../typings/tsd.d.ts", "../lib/tslint.d.ts", "./typings/**/*.d.ts", "./references.ts", @@ -20,8 +20,7 @@ "./rules/*.ts" ], "files": [ - "../typings/node.d.ts", - "../typings/typescriptServices.d.ts", + "../typings/tsd.d.ts", "../lib/tslint.d.ts", "./typings/chai/chai.d.ts", "./typings/mocha/mocha.d.ts", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..d89fdb6883c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,70 @@ +{ + "version": "1.6.2", + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": true, + "declaration": true, + "sourceMap": false, + "target": "es5", + "outDir": "./lib" + }, + "files": [ + "./typings/tsd.d.ts", + "./src/tslint.ts", + "./src/tslint-cli.ts", + "./src/rules/alignRule.ts", + "./src/rules/banRule.ts", + "./src/rules/classNameRule.ts", + "./src/rules/commentFormatRule.ts", + "./src/rules/curlyRule.ts", + "./src/rules/eoflineRule.ts", + "./src/rules/forinRule.ts", + "./src/rules/indentRule.ts", + "./src/rules/interfaceNameRule.ts", + "./src/rules/jsdocFormatRule.ts", + "./src/rules/labelPositionRule.ts", + "./src/rules/labelUndefinedRule.ts", + "./src/rules/maxLineLengthRule.ts", + "./src/rules/memberAccessRule.ts", + "./src/rules/memberOrderingRule.ts", + "./src/rules/noAnyRule.ts", + "./src/rules/noArgRule.ts", + "./src/rules/noBitwiseRule.ts", + "./src/rules/noConditionalAssignmentRule.ts", + "./src/rules/noConsecutiveBlankLinesRule.ts", + "./src/rules/noConsoleRule.ts", + "./src/rules/noConstructRule.ts", + "./src/rules/noConstructorVarsRule.ts", + "./src/rules/noDebuggerRule.ts", + "./src/rules/noDuplicateKeyRule.ts", + "./src/rules/noDuplicateVariableRule.ts", + "./src/rules/noEmptyRule.ts", + "./src/rules/noEvalRule.ts", + "./src/rules/noInferrableTypesRule.ts", + "./src/rules/noInternalModuleRule.ts", + "./src/rules/noRequireImportsRule.ts", + "./src/rules/noShadowedVariableRule.ts", + "./src/rules/noStringLiteralRule.ts", + "./src/rules/noSwitchCaseFallThroughRule.ts", + "./src/rules/noTrailingCommaRule.ts", + "./src/rules/noTrailingWhitespaceRule.ts", + "./src/rules/noUnreachableRule.ts", + "./src/rules/noUnusedExpressionRule.ts", + "./src/rules/noUnusedVariableRule.ts", + "./src/rules/noUseBeforeDeclareRule.ts", + "./src/rules/noVarKeywordRule.ts", + "./src/rules/noVarRequiresRule.ts", + "./src/rules/oneLineRule.ts", + "./src/rules/quotemarkRule.ts", + "./src/rules/radixRule.ts", + "./src/rules/semicolonRule.ts", + "./src/rules/sortObjectLiteralKeysRule.ts", + "./src/rules/switchDefaultRule.ts", + "./src/rules/tripleEqualsRule.ts", + "./src/rules/typedefRule.ts", + "./src/rules/typedefWhitespaceRule.ts", + "./src/rules/useStrictRule.ts", + "./src/rules/variableNameRule.ts", + "./src/rules/whitespaceRule.ts" + ] +} diff --git a/tsd.json b/tsd.json new file mode 100644 index 00000000000..d06f754449b --- /dev/null +++ b/tsd.json @@ -0,0 +1,27 @@ +{ + "version": "v4", + "repo": "borisyankov/DefinitelyTyped", + "ref": "master", + "path": "typings", + "bundle": "typings/tsd.d.ts", + "installed": { + "node/node.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + }, + "underscore.string/underscore.string.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + }, + "underscore/underscore.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + }, + "findup-sync/findup-sync.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + }, + "minimatch/minimatch.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + }, + "optimist/optimist.d.ts": { + "commit": "98d3168c2c570352a3a7393788e2ec9fbb08ade6" + } + } +} diff --git a/typings/findup-sync/findup-sync.d.ts b/typings/findup-sync/findup-sync.d.ts new file mode 100644 index 00000000000..f42ca325613 --- /dev/null +++ b/typings/findup-sync/findup-sync.d.ts @@ -0,0 +1,19 @@ +// Type definitions for findup-sync v0.3.0 +// Project: https://github.com/cowboy/node-findup-sync +// Definitions by: Bart van der Schoor , Nathan Brown +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +declare module 'findup-sync' { + import minimatch = require('minimatch'); + + interface IOptions extends minimatch.IOptions { + cwd?: string; + } + + function mod(pattern: string[] | string, opts?: IOptions): string; + namespace mod {} // Literally works around a bug in TS + + export = mod; +} diff --git a/typings/minimatch/minimatch.d.ts b/typings/minimatch/minimatch.d.ts new file mode 100644 index 00000000000..a79c6ff114d --- /dev/null +++ b/typings/minimatch/minimatch.d.ts @@ -0,0 +1,64 @@ +// Type definitions for Minimatch 2.0.8 +// Project: https://github.com/isaacs/minimatch +// Definitions by: vvakame +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module "minimatch" { + + function M(target: string, pattern: string, options?: M.IOptions): boolean; + + module M { + function match(list: string[], pattern: string, options?: IOptions): string[]; + function filter(pattern: string, options?: IOptions): (element: string, indexed: number, array: string[]) => boolean; + function makeRe(pattern: string, options?: IOptions): RegExp; + + var Minimatch: IMinimatchStatic; + + interface IOptions { + debug?: boolean; + nobrace?: boolean; + noglobstar?: boolean; + dot?: boolean; + noext?: boolean; + nocase?: boolean; + nonull?: boolean; + matchBase?: boolean; + nocomment?: boolean; + nonegate?: boolean; + flipNegate?: boolean; + } + + interface IMinimatchStatic { + new (pattern: string, options?: IOptions): IMinimatch; + prototype: IMinimatch; + } + + interface IMinimatch { + pattern: string; + options: IOptions; + /** 2-dimensional array of regexp or string expressions. */ + set: any[][]; // (RegExp | string)[][] + regexp: RegExp; + negate: boolean; + comment: boolean; + empty: boolean; + + makeRe(): RegExp; // regexp or boolean + match(fname: string): boolean; + matchOne(files: string[], pattern: string[], partial: boolean): boolean; + + /** Deprecated. For internal use. */ + debug(): void; + /** Deprecated. For internal use. */ + make(): void; + /** Deprecated. For internal use. */ + parseNegate(): void; + /** Deprecated. For internal use. */ + braceExpand(pattern: string, options: IOptions): void; + /** Deprecated. For internal use. */ + parse(pattern: string, isSub?: boolean): void; + } + } + + export = M; +} diff --git a/typings/node.d.ts b/typings/node/node.d.ts similarity index 58% rename from typings/node.d.ts rename to typings/node/node.d.ts index a62e1f6741a..d7e23cb1e63 100644 --- a/typings/node.d.ts +++ b/typings/node/node.d.ts @@ -1,1296 +1,2077 @@ -// Type definitions for Node.js v0.10.1 -// Project: http://nodejs.org/ -// Definitions by: Microsoft TypeScript , DefinitelyTyped -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -/************************************************ -* * -* Node.js v0.10.1 API * -* * -************************************************/ - -/************************************************ -* * -* GLOBAL * -* * -************************************************/ -declare var process: NodeJS.Process; -declare var global: any; - -declare var __filename: string; -declare var __dirname: string; - -declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearTimeout(timeoutId: NodeJS.Timer): void; -declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; -declare function clearInterval(intervalId: NodeJS.Timer): void; -declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; -declare function clearImmediate(immediateId: any): void; - -declare var require: { - (id: string): any; - resolve(id:string): string; - cache: any; - extensions: any; - main: any; -}; - -declare var module: { - exports: any; - require(id: string): any; - id: string; - filename: string; - loaded: boolean; - parent: any; - children: any[]; -}; - -// Same as module.exports -declare var exports: any; -declare var SlowBuffer: { - new (str: string, encoding?: string): Buffer; - new (size: number): Buffer; - new (array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; -}; - - -// Buffer class -interface Buffer extends NodeBuffer {} -declare var Buffer: { - new (str: string, encoding?: string): Buffer; - new (size: number): Buffer; - new (array: any[]): Buffer; - prototype: Buffer; - isBuffer(obj: any): boolean; - byteLength(string: string, encoding?: string): number; - concat(list: Buffer[], totalLength?: number): Buffer; -}; - -/************************************************ -* * -* GLOBAL INTERFACES * -* * -************************************************/ -declare module NodeJS { - export interface ErrnoException extends Error { - errno?: any; - code?: string; - path?: string; - syscall?: string; - } - - export interface EventEmitter { - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - } - - export interface ReadableStream extends EventEmitter { - readable: boolean; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: ReadableStream): ReadableStream; - } - - export interface WritableStream extends EventEmitter { - writable: boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface ReadWriteStream extends ReadableStream, WritableStream {} - - export interface Process extends EventEmitter { - stdout: WritableStream; - stderr: WritableStream; - stdin: ReadableStream; - argv: string[]; - execPath: string; - abort(): void; - chdir(directory: string): void; - cwd(): string; - env: any; - exit(code?: number): void; - getgid(): number; - setgid(id: number): void; - setgid(id: string): void; - getuid(): number; - setuid(id: number): void; - setuid(id: string): void; - version: string; - versions: { - http_parser: string; - node: string; - v8: string; - ares: string; - uv: string; - zlib: string; - openssl: string; - }; - config: { - target_defaults: { - cflags: any[]; - default_configuration: string; - defines: string[]; - include_dirs: string[]; - libraries: string[]; - }; - variables: { - clang: number; - host_arch: string; - node_install_npm: boolean; - node_install_waf: boolean; - node_prefix: string; - node_shared_openssl: boolean; - node_shared_v8: boolean; - node_shared_zlib: boolean; - node_use_dtrace: boolean; - node_use_etw: boolean; - node_use_openssl: boolean; - target_arch: string; - v8_no_strict_aliasing: number; - v8_use_snapshot: boolean; - visibility: string; - }; - }; - kill(pid: number, signal?: string): void; - pid: number; - title: string; - arch: string; - platform: string; - memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; - nextTick(callback: Function): void; - umask(mask?: number): number; - uptime(): number; - hrtime(time?:number[]): number[]; - - // Worker - send?(message: any, sendHandle?: any): void; - } - - export interface Timer { - ref() : void; - unref() : void; - } -} - -/** - * @deprecated - */ -interface NodeBuffer { - [index: number]: number; - write(string: string, offset?: number, length?: number, encoding?: string): number; - toString(encoding?: string, start?: number, end?: number): string; - toJSON(): any; - length: number; - copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; - slice(start?: number, end?: number): Buffer; - readUInt8(offset: number, noAsset?: boolean): number; - readUInt16LE(offset: number, noAssert?: boolean): number; - readUInt16BE(offset: number, noAssert?: boolean): number; - readUInt32LE(offset: number, noAssert?: boolean): number; - readUInt32BE(offset: number, noAssert?: boolean): number; - readInt8(offset: number, noAssert?: boolean): number; - readInt16LE(offset: number, noAssert?: boolean): number; - readInt16BE(offset: number, noAssert?: boolean): number; - readInt32LE(offset: number, noAssert?: boolean): number; - readInt32BE(offset: number, noAssert?: boolean): number; - readFloatLE(offset: number, noAssert?: boolean): number; - readFloatBE(offset: number, noAssert?: boolean): number; - readDoubleLE(offset: number, noAssert?: boolean): number; - readDoubleBE(offset: number, noAssert?: boolean): number; - writeUInt8(value: number, offset: number, noAssert?: boolean): void; - writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeInt8(value: number, offset: number, noAssert?: boolean): void; - writeInt16LE(value: number, offset: number, noAssert?: boolean): void; - writeInt16BE(value: number, offset: number, noAssert?: boolean): void; - writeInt32LE(value: number, offset: number, noAssert?: boolean): void; - writeInt32BE(value: number, offset: number, noAssert?: boolean): void; - writeFloatLE(value: number, offset: number, noAssert?: boolean): void; - writeFloatBE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; - writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; - fill(value: any, offset?: number, end?: number): void; -} - -/************************************************ -* * -* MODULES * -* * -************************************************/ -declare module "buffer" { - export var INSPECT_MAX_BYTES: number; -} - -declare module "querystring" { - export function stringify(obj: any, sep?: string, eq?: string): string; - export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; - export function escape(): any; - export function unescape(): any; -} - -declare module "events" { - export class EventEmitter implements NodeJS.EventEmitter { - static listenerCount(emitter: EventEmitter, event: string): number; - - addListener(event: string, listener: Function): EventEmitter; - on(event: string, listener: Function): EventEmitter; - once(event: string, listener: Function): EventEmitter; - removeListener(event: string, listener: Function): EventEmitter; - removeAllListeners(event?: string): EventEmitter; - setMaxListeners(n: number): void; - listeners(event: string): Function[]; - emit(event: string, ...args: any[]): boolean; - } -} - -declare module "http" { - import events = require("events"); - import net = require("net"); - import stream = require("stream"); - - export interface Server extends events.EventEmitter { - listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; - listen(path: string, callback?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(cb?: any): Server; - address(): { port: number; family: string; address: string; }; - maxHeadersCount: number; - } - export interface ServerRequest extends events.EventEmitter, stream.Readable { - method: string; - url: string; - headers: any; - trailers: string; - httpVersion: string; - setEncoding(encoding?: string): void; - pause(): void; - resume(): void; - connection: net.Socket; - } - export interface ServerResponse extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - writeContinue(): void; - writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; - writeHead(statusCode: number, headers?: any): void; - statusCode: number; - setHeader(name: string, value: string): void; - sendDate: boolean; - getHeader(name: string): string; - removeHeader(name: string): void; - write(chunk: any, encoding?: string): any; - addTrailers(headers: any): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientRequest extends events.EventEmitter, stream.Writable { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - write(chunk: any, encoding?: string): void; - abort(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - export interface ClientResponse extends events.EventEmitter, stream.Readable { - statusCode: number; - httpVersion: string; - headers: any; - trailers: any; - setEncoding(encoding?: string): void; - pause(): void; - resume(): void; - } - export interface Agent { maxSockets: number; sockets: any; requests: any; } - - export var STATUS_CODES: { - [errorCode: number]: string; - [errorCode: string]: string; - }; - export function createServer(requestListener?: (request: ServerRequest, response: ServerResponse) =>void ): Server; - export function createClient(port?: number, host?: string): any; - export function request(options: any, callback?: Function): ClientRequest; - export function get(options: any, callback?: Function): ClientRequest; - export var globalAgent: Agent; -} - -declare module "cluster" { - import child = require("child_process"); - import events = require("events"); - - export interface ClusterSettings { - exec?: string; - args?: string[]; - silent?: boolean; - } - - export class Worker extends events.EventEmitter { - id: string; - process: child.ChildProcess; - suicide: boolean; - send(message: any, sendHandle?: any): void; - kill(signal?: string): void; - destroy(signal?: string): void; - disconnect(): void; - } - - export var settings: ClusterSettings; - export var isMaster: boolean; - export var isWorker: boolean; - export function setupMaster(settings?: ClusterSettings): void; - export function fork(env?: any): Worker; - export function disconnect(callback?: Function): void; - export var worker: Worker; - export var workers: Worker[]; - - // Event emitter - export function addListener(event: string, listener: Function): void; - export function on(event: string, listener: Function): any; - export function once(event: string, listener: Function): void; - export function removeListener(event: string, listener: Function): void; - export function removeAllListeners(event?: string): void; - export function setMaxListeners(n: number): void; - export function listeners(event: string): Function[]; - export function emit(event: string, ...args: any[]): boolean; -} - -declare module "zlib" { - import stream = require("stream"); - export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } - - export interface Gzip extends stream.Transform { } - export interface Gunzip extends stream.Transform { } - export interface Deflate extends stream.Transform { } - export interface Inflate extends stream.Transform { } - export interface DeflateRaw extends stream.Transform { } - export interface InflateRaw extends stream.Transform { } - export interface Unzip extends stream.Transform { } - - export function createGzip(options?: ZlibOptions): Gzip; - export function createGunzip(options?: ZlibOptions): Gunzip; - export function createDeflate(options?: ZlibOptions): Deflate; - export function createInflate(options?: ZlibOptions): Inflate; - export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; - export function createInflateRaw(options?: ZlibOptions): InflateRaw; - export function createUnzip(options?: ZlibOptions): Unzip; - - export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; - - // Constants - export var Z_NO_FLUSH: number; - export var Z_PARTIAL_FLUSH: number; - export var Z_SYNC_FLUSH: number; - export var Z_FULL_FLUSH: number; - export var Z_FINISH: number; - export var Z_BLOCK: number; - export var Z_TREES: number; - export var Z_OK: number; - export var Z_STREAM_END: number; - export var Z_NEED_DICT: number; - export var Z_ERRNO: number; - export var Z_STREAM_ERROR: number; - export var Z_DATA_ERROR: number; - export var Z_MEM_ERROR: number; - export var Z_BUF_ERROR: number; - export var Z_VERSION_ERROR: number; - export var Z_NO_COMPRESSION: number; - export var Z_BEST_SPEED: number; - export var Z_BEST_COMPRESSION: number; - export var Z_DEFAULT_COMPRESSION: number; - export var Z_FILTERED: number; - export var Z_HUFFMAN_ONLY: number; - export var Z_RLE: number; - export var Z_FIXED: number; - export var Z_DEFAULT_STRATEGY: number; - export var Z_BINARY: number; - export var Z_TEXT: number; - export var Z_ASCII: number; - export var Z_UNKNOWN: number; - export var Z_DEFLATED: number; - export var Z_NULL: number; -} - -declare module "os" { - export function tmpDir(): string; - export function hostname(): string; - export function type(): string; - export function platform(): string; - export function arch(): string; - export function release(): string; - export function uptime(): number; - export function loadavg(): number[]; - export function totalmem(): number; - export function freemem(): number; - export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; - export function networkInterfaces(): any; - export var EOL: string; -} - -declare module "https" { - import tls = require("tls"); - import events = require("events"); - import http = require("http"); - - export interface ServerOptions { - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - crl?: any; - ciphers?: string; - honorCipherOrder?: boolean; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; - SNICallback?: (servername: string) => any; - } - - export interface RequestOptions { - host?: string; - hostname?: string; - port?: number; - path?: string; - method?: string; - headers?: any; - auth?: string; - agent?: any; - pfx?: any; - key?: any; - passphrase?: string; - cert?: any; - ca?: any; - ciphers?: string; - rejectUnauthorized?: boolean; - } - - export interface Agent { - maxSockets: number; - sockets: any; - requests: any; - } - export var Agent: { - new (options?: RequestOptions): Agent; - }; - export interface Server extends tls.Server { } - export function createServer(options: ServerOptions, requestListener?: Function): Server; - export function request(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; - export function get(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; - export var globalAgent: Agent; -} - -declare module "punycode" { - export function decode(string: string): string; - export function encode(string: string): string; - export function toUnicode(domain: string): string; - export function toASCII(domain: string): string; - export var ucs2: ucs2; - interface ucs2 { - decode(string: string): string; - encode(codePoints: number[]): string; - } - export var version: any; -} - -declare module "repl" { - import stream = require("stream"); - import events = require("events"); - - export interface ReplOptions { - prompt?: string; - input?: NodeJS.ReadableStream; - output?: NodeJS.WritableStream; - terminal?: boolean; - eval?: Function; - useColors?: boolean; - useGlobal?: boolean; - ignoreUndefined?: boolean; - writer?: Function; - } - export function start(options: ReplOptions): events.EventEmitter; -} - -declare module "readline" { - import events = require("events"); - import stream = require("stream"); - - export interface ReadLine extends events.EventEmitter { - setPrompt(prompt: string, length: number): void; - prompt(preserveCursor?: boolean): void; - question(query: string, callback: Function): void; - pause(): void; - resume(): void; - close(): void; - write(data: any, key?: any): void; - } - export interface ReadLineOptions { - input: NodeJS.ReadableStream; - output: NodeJS.WritableStream; - completer?: Function; - terminal?: boolean; - } - export function createInterface(options: ReadLineOptions): ReadLine; -} - -declare module "vm" { - export interface Context { } - export interface Script { - runInThisContext(): void; - runInNewContext(sandbox?: Context): void; - } - export function runInThisContext(code: string, filename?: string): void; - export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; - export function runInContext(code: string, context: Context, filename?: string): void; - export function createContext(initSandbox?: Context): Context; - export function createScript(code: string, filename?: string): Script; -} - -declare module "child_process" { - import events = require("events"); - import stream = require("stream"); - - export interface ChildProcess extends events.EventEmitter { - stdin: stream.Writable; - stdout: stream.Readable; - stderr: stream.Readable; - pid: number; - kill(signal?: string): void; - send(message: any, sendHandle: any): void; - disconnect(): void; - } - - export function spawn(command: string, args?: string[], options?: { - cwd?: string; - stdio?: any; - custom?: any; - env?: any; - detached?: boolean; - }): ChildProcess; - export function exec(command: string, options: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function exec(command: string, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function execFile(file: string, args: string[], options: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: string; - killSignal?: string; - }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; - export function fork(modulePath: string, args?: string[], options?: { - cwd?: string; - env?: any; - encoding?: string; - }): ChildProcess; -} - -declare module "url" { - export interface Url { - href: string; - protocol: string; - auth: string; - hostname: string; - port: string; - host: string; - pathname: string; - search: string; - query: string; - slashes: boolean; - hash?: string; - path?: string; - } - - export interface UrlOptions { - protocol?: string; - auth?: string; - hostname?: string; - port?: string; - host?: string; - pathname?: string; - search?: string; - query?: any; - hash?: string; - path?: string; - } - - export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; - export function format(url: UrlOptions): string; - export function resolve(from: string, to: string): string; -} - -declare module "dns" { - export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; - export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; - export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; - export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; -} - -declare module "net" { - import stream = require("stream"); - - export interface Socket extends stream.Duplex { - // Extended base methods - write(buffer: Buffer): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - write(str: string, encoding?: string, fd?: string): boolean; - - connect(port: number, host?: string, connectionListener?: Function): void; - connect(path: string, connectionListener?: Function): void; - bufferSize: number; - setEncoding(encoding?: string): void; - write(data: any, encoding?: string, callback?: Function): void; - destroy(): void; - pause(): void; - resume(): void; - setTimeout(timeout: number, callback?: Function): void; - setNoDelay(noDelay?: boolean): void; - setKeepAlive(enable?: boolean, initialDelay?: number): void; - address(): { port: number; family: string; address: string; }; - remoteAddress: string; - remotePort: number; - bytesRead: number; - bytesWritten: number; - - // Extended base methods - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - end(data?: any, encoding?: string): void; - } - - export var Socket: { - new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; - }; - - export interface Server extends Socket { - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - close(callback?: Function): Server; - address(): { port: number; family: string; address: string; }; - maxConnections: number; - connections: number; - } - export function createServer(connectionListener?: (socket: Socket) =>void ): Server; - export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; - export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function connect(port: number, host?: string, connectionListener?: Function): Socket; - export function connect(path: string, connectionListener?: Function): Socket; - export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; - export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; - export function createConnection(path: string, connectionListener?: Function): Socket; - export function isIP(input: string): number; - export function isIPv4(input: string): boolean; - export function isIPv6(input: string): boolean; -} - -declare module "dgram" { - import events = require("events"); - - export function createSocket(type: string, callback?: Function): Socket; - - interface Socket extends events.EventEmitter { - send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: Function): void; - bind(port: number, address?: string): void; - close(): void; - address: { address: string; family: string; port: number; }; - setBroadcast(flag: boolean): void; - setMulticastTTL(ttl: number): void; - setMulticastLoopback(flag: boolean): void; - addMembership(multicastAddress: string, multicastInterface?: string): void; - dropMembership(multicastAddress: string, multicastInterface?: string): void; - } -} - -declare module "fs" { - import stream = require("stream"); - import events = require("events"); - - interface Stats { - isFile(): boolean; - isDirectory(): boolean; - isBlockDevice(): boolean; - isCharacterDevice(): boolean; - isSymbolicLink(): boolean; - isFIFO(): boolean; - isSocket(): boolean; - dev: number; - ino: number; - mode: number; - nlink: number; - uid: number; - gid: number; - rdev: number; - size: number; - blksize: number; - blocks: number; - atime: Date; - mtime: Date; - ctime: Date; - } - - interface FSWatcher extends events.EventEmitter { - close(): void; - } - - export interface ReadStream extends stream.Readable {} - export interface WriteStream extends stream.Writable {} - - export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function renameSync(oldPath: string, newPath: string): void; - export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function truncateSync(path: string, len?: number): void; - export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function ftruncateSync(fd: number, len?: number): void; - export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chownSync(path: string, uid: number, gid: number): void; - export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchownSync(fd: number, uid: number, gid: number): void; - export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchownSync(path: string, uid: number, gid: number): void; - export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function chmodSync(path: string, mode: number): void; - export function chmodSync(path: string, mode: string): void; - export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fchmodSync(fd: number, mode: number): void; - export function fchmodSync(fd: number, mode: string): void; - export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function lchmodSync(path: string, mode: number): void; - export function lchmodSync(path: string, mode: string): void; - export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; - export function statSync(path: string): Stats; - export function lstatSync(path: string): Stats; - export function fstatSync(fd: number): Stats; - export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function linkSync(srcpath: string, dstpath: string): void; - export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; - export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; - export function readlinkSync(path: string): string; - export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; - export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; - export function realpathSync(path: string, cache?: {[path: string]: string}): string; - export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function unlinkSync(path: string): void; - export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function rmdirSync(path: string): void; - export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function mkdirSync(path: string, mode?: number): void; - export function mkdirSync(path: string, mode?: string): void; - export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; - export function readdirSync(path: string): string[]; - export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function closeSync(fd: number): void; - export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; - export function openSync(path: string, flags: string, mode?: number): number; - export function openSync(path: string, flags: string, mode?: string): number; - export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function utimesSync(path: string, atime: number, mtime: number): void; - export function utimesSync(path: string, atime: Date, mtime: Date): void; - export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function futimesSync(fd: number, atime: number, mtime: number): void; - export function futimesSync(fd: number, atime: Date, mtime: Date): void; - export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; - export function fsyncSync(fd: number): void; - export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; - export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; - export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; - export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; - export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; - export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void; - export function readFileSync(filename: string, encoding: string): string; - export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; - export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; - export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; - export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; - export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; - export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; - export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; - export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; - export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; - export function exists(path: string, callback?: (exists: boolean) => void): void; - export function existsSync(path: string): boolean; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: string; - mode?: number; - bufferSize?: number; - }): ReadStream; - export function createReadStream(path: string, options?: { - flags?: string; - encoding?: string; - fd?: string; - mode?: string; - bufferSize?: number; - }): ReadStream; - export function createWriteStream(path: string, options?: { - flags?: string; - encoding?: string; - string?: string; - }): WriteStream; -} - -declare module "path" { - export function normalize(p: string): string; - export function join(...paths: any[]): string; - export function resolve(...pathSegments: any[]): string; - export function relative(from: string, to: string): string; - export function dirname(p: string): string; - export function basename(p: string, ext?: string): string; - export function extname(p: string): string; - export var sep: string; -} - -declare module "string_decoder" { - export interface NodeStringDecoder { - write(buffer: Buffer): string; - detectIncompleteChar(buffer: Buffer): number; - } - export var StringDecoder: { - new (encoding: string): NodeStringDecoder; - }; -} - -declare module "tls" { - import crypto = require("crypto"); - import net = require("net"); - import stream = require("stream"); - - var CLIENT_RENEG_LIMIT: number; - var CLIENT_RENEG_WINDOW: number; - - export interface TlsOptions { - pfx?: any; //string or buffer - key?: any; //string or buffer - passphrase?: string; - cert?: any; - ca?: any; //string or buffer - crl?: any; //string or string array - ciphers?: string; - honorCipherOrder?: any; - requestCert?: boolean; - rejectUnauthorized?: boolean; - NPNProtocols?: any; //array or Buffer; - SNICallback?: (servername: string) => any; - } - - export interface ConnectionOptions { - host?: string; - port?: number; - socket?: net.Socket; - pfx?: any; //string | Buffer - key?: any; //string | Buffer - passphrase?: string; - cert?: any; //string | Buffer - ca?: any; //Array of string | Buffer - rejectUnauthorized?: boolean; - NPNProtocols?: any; //Array of string | Buffer - servername?: string; - } - - export interface Server extends net.Server { - // Extended base methods - listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; - listen(path: string, listeningListener?: Function): Server; - listen(handle: any, listeningListener?: Function): Server; - - listen(port: number, host?: string, callback?: Function): Server; - close(): Server; - address(): { port: number; family: string; address: string; }; - addContext(hostName: string, credentials: { - key: string; - cert: string; - ca: string; - }): void; - maxConnections: number; - connections: number; - } - - export interface ClearTextStream extends stream.Duplex { - authorized: boolean; - authorizationError: Error; - getPeerCertificate(): any; - getCipher: { - name: string; - version: string; - }; - address: { - port: number; - family: string; - address: string; - }; - remoteAddress: string; - remotePort: number; - } - - export interface SecurePair { - encrypted: any; - cleartext: any; - } - - export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; - export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; - export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; - export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; -} - -declare module "crypto" { - export interface CredentialDetails { - pfx: string; - key: string; - passphrase: string; - cert: string; - ca: any; //string | string array - crl: any; //string | string array - ciphers: string; - } - export interface Credentials { context?: any; } - export function createCredentials(details: CredentialDetails): Credentials; - export function createHash(algorithm: string): Hash; - export function createHmac(algorithm: string, key: string): Hmac; - interface Hash { - update(data: any, input_encoding?: string): Hash; - digest(encoding?: string): string; - } - interface Hmac { - update(data: any, input_encoding?: string): Hmac; - digest(encoding?: string): string; - } - export function createCipher(algorithm: string, password: any): Cipher; - export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; - interface Cipher { - update(data: any, input_encoding?: string, output_encoding?: string): string; - final(output_encoding?: string): string; - setAutoPadding(auto_padding: boolean): void; - createDecipher(algorithm: string, password: any): Decipher; - createDecipheriv(algorithm: string, key: any, iv: any): Decipher; - } - interface Decipher { - update(data: any, input_encoding?: string, output_encoding?: string): void; - final(output_encoding?: string): string; - setAutoPadding(auto_padding: boolean): void; - } - export function createSign(algorithm: string): Signer; - interface Signer { - update(data: any): void; - sign(private_key: string, output_format: string): string; - } - export function createVerify(algorith: string): Verify; - interface Verify { - update(data: any): void; - verify(object: string, signature: string, signature_format?: string): boolean; - } - export function createDiffieHellman(prime_length: number): DiffieHellman; - export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; - interface DiffieHellman { - generateKeys(encoding?: string): string; - computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; - getPrime(encoding?: string): string; - getGenerator(encoding: string): string; - getPublicKey(encoding?: string): string; - getPrivateKey(encoding?: string): string; - setPublicKey(public_key: string, encoding?: string): void; - setPrivateKey(public_key: string, encoding?: string): void; - } - export function getDiffieHellman(group_name: string): DiffieHellman; - export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: string) => any): void; - export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; - export function randomBytes(size: number): Buffer; - export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; - export function pseudoRandomBytes(size: number): Buffer; - export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; -} - -declare module "stream" { - import events = require("events"); - - export interface ReadableOptions { - highWaterMark?: number; - encoding?: string; - objectMode?: boolean; - } - - export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { - readable: boolean; - constructor(opts?: ReadableOptions); - _read(size: number): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - } - - export interface WritableOptions { - highWaterMark?: number; - decodeStrings?: boolean; - } - - export class Writable extends events.EventEmitter implements NodeJS.WritableStream { - writable: boolean; - constructor(opts?: WritableOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface DuplexOptions extends ReadableOptions, WritableOptions { - allowHalfOpen?: boolean; - } - - // Note: Duplex extends both Readable and Writable. - export class Duplex extends Readable implements NodeJS.ReadWriteStream { - writable: boolean; - constructor(opts?: DuplexOptions); - _write(data: Buffer, encoding: string, callback: Function): void; - _write(data: string, encoding: string, callback: Function): void; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export interface TransformOptions extends ReadableOptions, WritableOptions {} - - // Note: Transform lacks the _read and _write methods of Readable/Writable. - export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { - readable: boolean; - writable: boolean; - constructor(opts?: TransformOptions); - _transform(chunk: Buffer, encoding: string, callback: Function): void; - _transform(chunk: string, encoding: string, callback: Function): void; - _flush(callback: Function): void; - read(size?: number): any; - setEncoding(encoding: string): void; - pause(): void; - resume(): void; - pipe(destination: T, options?: { end?: boolean; }): T; - unpipe(destination?: T): void; - unshift(chunk: string): void; - unshift(chunk: Buffer): void; - wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; - push(chunk: any, encoding?: string): boolean; - write(buffer: Buffer, cb?: Function): boolean; - write(str: string, cb?: Function): boolean; - write(str: string, encoding?: string, cb?: Function): boolean; - end(): void; - end(buffer: Buffer, cb?: Function): void; - end(str: string, cb?: Function): void; - end(str: string, encoding?: string, cb?: Function): void; - } - - export class PassThrough extends Transform {} -} - -declare module "util" { - export interface InspectOptions { - showHidden?: boolean; - depth?: number; - colors?: boolean; - customInspect?: boolean; - } - - export function format(format: any, ...param: any[]): string; - export function debug(string: string): void; - export function error(...param: any[]): void; - export function puts(...param: any[]): void; - export function print(...param: any[]): void; - export function log(string: string): void; - export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; - export function inspect(object: any, options: InspectOptions): string; - export function isArray(object: any): boolean; - export function isRegExp(object: any): boolean; - export function isDate(object: any): boolean; - export function isError(object: any): boolean; - export function inherits(constructor: any, superConstructor: any): void; -} - -declare module "assert" { - function internal (value: any, message?: string): void; - module internal { - export class AssertionError implements Error { - name: string; - message: string; - actual: any; - expected: any; - operator: string; - generatedMessage: boolean; - - constructor(options?: {message?: string; actual?: any; expected?: any; - operator?: string; stackStartFunction?: Function}); - } - - export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; - export function ok(value: any, message?: string): void; - export function equal(actual: any, expected: any, message?: string): void; - export function notEqual(actual: any, expected: any, message?: string): void; - export function deepEqual(actual: any, expected: any, message?: string): void; - export function notDeepEqual(acutal: any, expected: any, message?: string): void; - export function strictEqual(actual: any, expected: any, message?: string): void; - export function notStrictEqual(actual: any, expected: any, message?: string): void; - export var throws: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export var doesNotThrow: { - (block: Function, message?: string): void; - (block: Function, error: Function, message?: string): void; - (block: Function, error: RegExp, message?: string): void; - (block: Function, error: (err: any) => boolean, message?: string): void; - }; - - export function ifError(value: any): void; - } - - export = internal; -} - -declare module "tty" { - import net = require("net"); - - export function isatty(fd: number): boolean; - export interface ReadStream extends net.Socket { - isRaw: boolean; - setRawMode(mode: boolean): void; - } - export interface WriteStream extends net.Socket { - columns: number; - rows: number; - } -} - -declare module "domain" { - import events = require("events"); - - export class Domain extends events.EventEmitter { - run(fn: Function): void; - add(emitter: events.EventEmitter): void; - remove(emitter: events.EventEmitter): void; - bind(cb: (err: Error, data: any) => any): any; - intercept(cb: (data: any) => any): any; - dispose(): void; - - addListener(event: string, listener: Function): Domain; - on(event: string, listener: Function): Domain; - once(event: string, listener: Function): Domain; - removeListener(event: string, listener: Function): Domain; - removeAllListeners(event?: string): Domain; - } - - export function create(): Domain; -} \ No newline at end of file +// Type definitions for Node.js v0.12.0 +// Project: http://nodejs.org/ +// Definitions by: Microsoft TypeScript , DefinitelyTyped +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/************************************************ +* * +* Node.js v0.12.0 API * +* * +************************************************/ + +interface Error { + stack?: string; +} + + +// compat for TypeScript 1.5.3 +// if you use with --target es3 or --target es5 and use below definitions, +// use the lib.es6.d.ts that is bundled with TypeScript 1.5.3. +interface MapConstructor {} +interface WeakMapConstructor {} +interface SetConstructor {} +interface WeakSetConstructor {} + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: NodeJS.Global; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +interface NodeRequireFunction { + (id: string): any; +} + +interface NodeRequire extends NodeRequireFunction { + resolve(id:string): string; + cache: any; + extensions: any; + main: any; +} + +declare var require: NodeRequire; + +interface NodeModule { + exports: any; + require: NodeRequireFunction; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +} + +declare var module: NodeModule; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (size: Uint8Array): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +interface Buffer extends NodeBuffer {} + +/** + * Raw data is stored in instances of the Buffer class. + * A Buffer is similar to an array of integers but corresponds to a raw memory allocation outside the V8 heap. A Buffer cannot be resized. + * Valid string encodings: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + */ +declare var Buffer: { + /** + * Allocates a new buffer containing the given {str}. + * + * @param str String to store in buffer. + * @param encoding encoding to use, optional. Default is 'utf8' + */ + new (str: string, encoding?: string): Buffer; + /** + * Allocates a new buffer of {size} octets. + * + * @param size count of octets to allocate. + */ + new (size: number): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: Uint8Array): Buffer; + /** + * Allocates a new buffer containing the given {array} of octets. + * + * @param array The octets to store. + */ + new (array: any[]): Buffer; + prototype: Buffer; + /** + * Returns true if {obj} is a Buffer + * + * @param obj object to test. + */ + isBuffer(obj: any): boolean; + /** + * Returns true if {encoding} is a valid encoding argument. + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex' + * + * @param encoding string to test. + */ + isEncoding(encoding: string): boolean; + /** + * Gives the actual byte length of a string. encoding defaults to 'utf8'. + * This is not the same as String.prototype.length since that returns the number of characters in a string. + * + * @param string string to test. + * @param encoding encoding used to evaluate (defaults to 'utf8') + */ + byteLength(string: string, encoding?: string): number; + /** + * Returns a buffer which is the result of concatenating all the buffers in the list together. + * + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer. + * If the list has exactly one item, then the first item of the list is returned. + * If the list has more than one item, then a new Buffer is created. + * + * @param list An array of Buffer objects to concatenate + * @param totalLength Total length of the buffers when concatenated. + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly. + */ + concat(list: Buffer[], totalLength?: number): Buffer; + /** + * The same as buf1.compare(buf2). + */ + compare(buf1: Buffer, buf2: Buffer): number; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare module NodeJS { + export interface ErrnoException extends Error { + errno?: number; + code?: string; + path?: string; + syscall?: string; + stack?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): string|Buffer; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer|string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream {} + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?:number[]): number[]; + + // Worker + send?(message: any, sendHandle?: any): void; + } + + export interface Global { + Array: typeof Array; + ArrayBuffer: typeof ArrayBuffer; + Boolean: typeof Boolean; + Buffer: typeof Buffer; + DataView: typeof DataView; + Date: typeof Date; + Error: typeof Error; + EvalError: typeof EvalError; + Float32Array: typeof Float32Array; + Float64Array: typeof Float64Array; + Function: typeof Function; + GLOBAL: Global; + Infinity: typeof Infinity; + Int16Array: typeof Int16Array; + Int32Array: typeof Int32Array; + Int8Array: typeof Int8Array; + Intl: typeof Intl; + JSON: typeof JSON; + Map: MapConstructor; + Math: typeof Math; + NaN: typeof NaN; + Number: typeof Number; + Object: typeof Object; + Promise: Function; + RangeError: typeof RangeError; + ReferenceError: typeof ReferenceError; + RegExp: typeof RegExp; + Set: SetConstructor; + String: typeof String; + Symbol: Function; + SyntaxError: typeof SyntaxError; + TypeError: typeof TypeError; + URIError: typeof URIError; + Uint16Array: typeof Uint16Array; + Uint32Array: typeof Uint32Array; + Uint8Array: typeof Uint8Array; + Uint8ClampedArray: Function; + WeakMap: WeakMapConstructor; + WeakSet: WeakSetConstructor; + clearImmediate: (immediateId: any) => void; + clearInterval: (intervalId: NodeJS.Timer) => void; + clearTimeout: (timeoutId: NodeJS.Timer) => void; + console: typeof console; + decodeURI: typeof decodeURI; + decodeURIComponent: typeof decodeURIComponent; + encodeURI: typeof encodeURI; + encodeURIComponent: typeof encodeURIComponent; + escape: (str: string) => string; + eval: typeof eval; + global: Global; + isFinite: typeof isFinite; + isNaN: typeof isNaN; + parseFloat: typeof parseFloat; + parseInt: typeof parseInt; + process: Process; + root: Global; + setImmediate: (callback: (...args: any[]) => void, ...args: any[]) => any; + setInterval: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + setTimeout: (callback: (...args: any[]) => void, ms: number, ...args: any[]) => NodeJS.Timer; + undefined: typeof undefined; + unescape: (str: string) => string; + gc: () => void; + } + + export interface Timer { + ref() : void; + unref() : void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer { + [index: number]: number; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): any; + length: number; + equals(otherBuffer: Buffer): boolean; + compare(otherBuffer: Buffer): number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number; + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number; + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number; + readUInt8(offset: number, noAsset?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): void; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeInt8(value: number, offset: number, noAssert?: boolean): void; + writeInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeFloatLE(value: number, offset: number, noAssert?: boolean): void; + writeFloatBE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; + fill(value: any, offset?: number, end?: number): void; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; +} + +declare module "querystring" { + export function stringify(obj: any, sep?: string, eq?: string): string; + export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; + export function escape(str: string): string; + export function unescape(str: string): string; +} + +declare module "events" { + export class EventEmitter implements NodeJS.EventEmitter { + static listenerCount(emitter: EventEmitter, event: string): number; + + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } +} + +declare module "http" { + import * as events from "events"; + import * as net from "net"; + import * as stream from "stream"; + + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; + listen(port: number, hostname?: string, callback?: Function): Server; + listen(path: string, callback?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(cb?: any): Server; + address(): { port: number; family: string; address: string; }; + maxHeadersCount: number; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ServerRequest extends IncomingMessage { + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + statusMessage: string; + setHeader(name: string, value: string): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface IncomingMessage extends events.EventEmitter, stream.Readable { + httpVersion: string; + headers: any; + rawHeaders: string[]; + trailers: any; + rawTrailers: any; + setTimeout(msecs: number, callback: Function): NodeJS.Timer; + /** + * Only valid for request obtained from http.Server. + */ + method?: string; + /** + * Only valid for request obtained from http.Server. + */ + url?: string; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusCode?: number; + /** + * Only valid for response obtained from http.ClientRequest. + */ + statusMessage?: string; + socket: net.Socket; + } + /** + * @deprecated Use IncomingMessage + */ + export interface ClientResponse extends IncomingMessage { } + + export interface AgentOptions { + /** + * Keep sockets around in a pool to be used by other requests in the future. Default = false + */ + keepAlive?: boolean; + /** + * When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default = 1000. + * Only relevant if keepAlive is set to true. + */ + keepAliveMsecs?: number; + /** + * Maximum number of sockets to allow per host. Default for Node 0.10 is 5, default for Node 0.12 is Infinity + */ + maxSockets?: number; + /** + * Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default = 256. + */ + maxFreeSockets?: number; + } + + export class Agent { + maxSockets: number; + sockets: any; + requests: any; + + constructor(opts?: AgentOptions); + + /** + * Destroy any sockets that are currently in use by the agent. + * It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, + * then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, + * sockets may hang open for quite a long time before the server terminates them. + */ + destroy(): void; + } + + export var METHODS: string[]; + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: IncomingMessage, response: ServerResponse) =>void ): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export function get(options: any, callback?: (res: IncomingMessage) => void): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import * as child from "child_process"; + import * as events from "events"; + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: Worker[]; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module "zlib" { + import * as stream from "stream"; + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateSync(buf: Buffer, options?: ZlibOptions): any; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzipSync(buf: Buffer, options?: ZlibOptions): any; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzipSync(buf: Buffer, options?: ZlibOptions): any; + export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateSync(buf: Buffer, options?: ZlibOptions): any; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRawSync(buf: Buffer, options?: ZlibOptions): any; + export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzipSync(buf: Buffer, options?: ZlibOptions): any; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export function tmpdir(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; + export function networkInterfaces(): any; + export var EOL: string; +} + +declare module "https" { + import * as tls from "tls"; + import * as events from "events"; + import * as http from "http"; + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions { + host?: string; + hostname?: string; + port?: number; + path?: string; + method?: string; + headers?: any; + auth?: string; + agent?: any; + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + } + + export interface Agent { + maxSockets: number; + sockets: any; + requests: any; + } + export var Agent: { + new (options?: RequestOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: http.IncomingMessage) =>void ): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): string; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import * as stream from "stream"; + import * as events from "events"; + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module "readline" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: Function): void; + pause(): void; + resume(): void; + close(): void; + write(data: any, key?: any): void; + } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output: NodeJS.WritableStream; + completer?: Function; + terminal?: boolean; + } + export function createInterface(options: ReadLineOptions): ReadLine; +} + +declare module "vm" { + export interface Context { } + export interface Script { + runInThisContext(): void; + runInNewContext(sandbox?: Context): void; + } + export function runInThisContext(code: string, filename?: string): void; + export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; + export function runInContext(code: string, context: Context, filename?: string): void; + export function createContext(initSandbox?: Context): Context; + export function createScript(code: string, filename?: string): Script; +} + +declare module "child_process" { + import * as events from "events"; + import * as stream from "stream"; + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle?: any): void; + disconnect(): void; + unref(): void; + } + + export function spawn(command: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + custom?: any; + env?: any; + detached?: boolean; + }): ChildProcess; + export function exec(command: string, options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, + callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], + callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: string; + killSignal?: string; + }, callback?: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function fork(modulePath: string, args?: string[], options?: { + cwd?: string; + env?: any; + encoding?: string; + }): ChildProcess; + export function execSync(command: string, options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): ChildProcess; + export function execFileSync(command: string, args?: string[], options?: { + cwd?: string; + input?: string|Buffer; + stdio?: any; + env?: any; + uid?: number; + gid?: number; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + encoding?: string; + }): ChildProcess; +} + +declare module "url" { + export interface Url { + href: string; + protocol: string; + auth: string; + hostname: string; + port: string; + host: string; + pathname: string; + search: string; + query: any; // string | Object + slashes: boolean; + hash?: string; + path?: string; + } + + export interface UrlOptions { + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: any; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; + export function format(url: UrlOptions): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; +} + +declare module "net" { + import * as stream from "stream"; + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + unref(): void; + ref(): void; + + remoteAddress: string; + remoteFamily: string; + remotePort: number; + localAddress: string; + localPort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface Server extends Socket { + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) =>void ): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; + export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import * as events from "events"; + + interface RemoteInfo { + address: string; + port: number; + size: number; + } + + interface AddressInfo { + address: string; + family: string; + port: number; + } + + export function createSocket(type: string, callback?: (msg: Buffer, rinfo: RemoteInfo) => void): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port: number, address?: string, callback?: () => void): void; + close(): void; + address(): AddressInfo; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module "fs" { + import * as stream from "stream"; + import * as events from "events"; + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + birthtime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable { + close(): void; + } + export interface WriteStream extends stream.Writable { + close(): void; + bytesWritten: number; + } + + /** + * Asynchronous rename. + * @param oldPath + * @param newPath + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /** + * Synchronous rename + * @param oldPath + * @param newPath + */ + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; + export function realpathSync(path: string, cache?: { [path: string]: string }): string; + /* + * Asynchronous unlink - deletes the file specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous unlink - deletes the file specified in {path} + * + * @param path + */ + export function unlinkSync(path: string): void; + /* + * Asynchronous rmdir - removes the directory specified in {path} + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous rmdir - removes the directory specified in {path} + * + * @param path + */ + export function rmdirSync(path: string): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Asynchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: number): void; + /* + * Synchronous mkdir - creates the directory specified in {path}. Parameter {mode} defaults to 0777. + * + * @param path + * @param mode + * @param callback No arguments other than a possible exception are given to the completion callback. + */ + export function mkdirSync(path: string, mode?: string): void; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function utimesSync(path: string, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function write(fd: number, data: any, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function write(fd: number, data: any, offset: number, encoding: string, callback?: (err: NodeJS.ErrnoException, written: number, str: string) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFile returns a string; otherwise it returns a Buffer. + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Asynchronous readFile - Asynchronously reads the entire contents of a file. + * + * @param fileName + * @param callback - The callback is passed two arguments (err, data), where data is the contents of the file. + */ + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param encoding + */ + export function readFileSync(filename: string, encoding: string): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + /* + * Synchronous readFile - Synchronously reads the entire contents of a file. + * + * @param fileName + * @param options An object with optional {encoding} and {flag} properties. If {encoding} is specified, readFileSync returns a string; otherwise it returns a Buffer. + */ + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + /** Constant for fs.access(). File is visible to the calling process. */ + export var F_OK: number; + /** Constant for fs.access(). File can be read by the calling process. */ + export var R_OK: number; + /** Constant for fs.access(). File can be written by the calling process. */ + export var W_OK: number; + /** Constant for fs.access(). File can be executed by the calling process. */ + export var X_OK: number; + /** Tests a user's permissions for the file specified by path. */ + export function access(path: string, callback: (err: NodeJS.ErrnoException) => void): void; + export function access(path: string, mode: number, callback: (err: NodeJS.ErrnoException) => void): void; + /** Synchronous version of fs.access. This throws if any accessibility checks fail, and does nothing otherwise. */ + export function accessSync(path: string, mode ?: number): void; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: number; + bufferSize?: number; + }): ReadStream; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: string; + bufferSize?: number; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + mode?: number; + }): WriteStream; +} + +declare module "path" { + + /** + * A parsed path object generated by path.parse() or consumed by path.format(). + */ + export interface ParsedPath { + /** + * The root of the path such as '/' or 'c:\' + */ + root: string; + /** + * The full directory path such as '/home/user/dir' or 'c:\path\dir' + */ + dir: string; + /** + * The file name including extension (if any) such as 'index.html' + */ + base: string; + /** + * The file extension (if any) such as '.html' + */ + ext: string; + /** + * The file name without extension (if any) such as 'index' + */ + name: string; + } + + /** + * Normalize a string path, reducing '..' and '.' parts. + * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used. + * + * @param p string path to normalize. + */ + export function normalize(p: string): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: any[]): string; + /** + * Join all arguments together and normalize the resulting path. + * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown. + * + * @param paths string paths to join. + */ + export function join(...paths: string[]): string; + /** + * The right-most parameter is considered {to}. Other parameters are considered an array of {from}. + * + * Starting from leftmost {from} paramter, resolves {to} to an absolute path. + * + * If {to} isn't already absolute, {from} arguments are prepended in right to left order, until an absolute path is found. If after using all {from} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory. + * + * @param pathSegments string paths to join. Non-string arguments are ignored. + */ + export function resolve(...pathSegments: any[]): string; + /** + * Determines whether {path} is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory. + * + * @param path path to test. + */ + export function isAbsolute(path: string): boolean; + /** + * Solve the relative path from {from} to {to}. + * At times we have two absolute paths, and we need to derive the relative path from one to the other. This is actually the reverse transform of path.resolve. + * + * @param from + * @param to + */ + export function relative(from: string, to: string): string; + /** + * Return the directory name of a path. Similar to the Unix dirname command. + * + * @param p the path to evaluate. + */ + export function dirname(p: string): string; + /** + * Return the last portion of a path. Similar to the Unix basename command. + * Often used to extract the file name from a fully qualified path. + * + * @param p the path to evaluate. + * @param ext optionally, an extension to remove from the result. + */ + export function basename(p: string, ext?: string): string; + /** + * Return the extension of the path, from the last '.' to end of string in the last portion of the path. + * If there is no '.' in the last portion of the path or the first character of it is '.', then it returns an empty string + * + * @param p the path to evaluate. + */ + export function extname(p: string): string; + /** + * The platform-specific file separator. '\\' or '/'. + */ + export var sep: string; + /** + * The platform-specific file delimiter. ';' or ':'. + */ + export var delimiter: string; + /** + * Returns an object from a path string - the opposite of format(). + * + * @param pathString path to evaluate. + */ + export function parse(pathString: string): ParsedPath; + /** + * Returns a path string from an object - the opposite of parse(). + * + * @param pathString path to evaluate. + */ + export function format(pathObject: ParsedPath): string; + + export module posix { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } + + export module win32 { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function isAbsolute(p: string): boolean; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; + export var delimiter: string; + export function parse(p: string): ParsedPath; + export function format(pP: ParsedPath): string; + } +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + detectIncompleteChar(buffer: Buffer): number; + } + export var StringDecoder: { + new (encoding: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import * as crypto from "crypto"; + import * as net from "net"; + import * as stream from "stream"; + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: any; //string | Buffer + key?: any; //string | Buffer + passphrase?: string; + cert?: any; //string | Buffer + ca?: any; //Array of string | Buffer + rejectUnauthorized?: boolean; + NPNProtocols?: any; //Array of string | Buffer + servername?: string; + } + + export interface Server extends net.Server { + // Extended base methods + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + + listen(port: number, host?: string, callback?: Function): Server; + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export interface SecureContextOptions { + pfx?: any; //string | buffer + key?: any; //string | buffer + passphrase?: string; + cert?: any; // string | buffer + ca?: any; // string | buffer + crl?: any; // string | string[] + ciphers?: string; + honorCipherOrder?: boolean; + } + + export interface SecureContext { + context: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; + export function createSecureContext(details: SecureContextOptions): SecureContext; +} + +declare module "crypto" { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: any; //string | string array + crl: any; //string | string array + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + export function createHmac(algorithm: string, key: Buffer): Hmac; + interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + interface Hmac { + update(data: any, input_encoding?: string): Hmac; + digest(encoding: 'buffer'): Buffer; + digest(encoding: string): any; + digest(): Buffer; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + interface Cipher { + update(data: Buffer): Buffer; + update(data: string, input_encoding?: string, output_encoding?: string): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createDecipher(algorithm: string, password: any): Decipher; + export function createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + interface Decipher { + update(data: Buffer): Buffer; + update(data: string, input_encoding?: string, output_encoding?: string): string; + final(): Buffer; + final(output_encoding: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createSign(algorithm: string): Signer; + interface Signer extends NodeJS.WritableStream { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + interface Verify extends NodeJS.WritableStream { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, digest: string, callback: (err: Error, derivedKey: Buffer) => any): void; + export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; + export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number, digest: string) : Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; +} + +declare module "stream" { + import * as events from "events"; + + export interface Stream extends events.EventEmitter { + pipe(destination: T, options?: { end?: boolean; }): T; + } + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(chunk: any, encoding: string, callback: Function): void; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions {} + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: any, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: any): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(chunk: any, cb?: Function): boolean; + write(chunk: any, encoding?: string, cb?: Function): boolean; + end(): void; + end(chunk: any, cb?: Function): void; + end(chunk: any, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform {} +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; + export function debuglog(key:string): (msg:string,...param: any[])=>void; +} + +declare module "assert" { + function internal (value: any, message?: string): void; + module internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: {message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function}); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import * as net from "net"; + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + } +} + +declare module "domain" { + import * as events from "events"; + + export class Domain extends events.EventEmitter { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): Domain; + on(event: string, listener: Function): Domain; + once(event: string, listener: Function): Domain; + removeListener(event: string, listener: Function): Domain; + removeAllListeners(event?: string): Domain; + } + + export function create(): Domain; +} + +declare module "constants" { + export var E2BIG: number; + export var EACCES: number; + export var EADDRINUSE: number; + export var EADDRNOTAVAIL: number; + export var EAFNOSUPPORT: number; + export var EAGAIN: number; + export var EALREADY: number; + export var EBADF: number; + export var EBADMSG: number; + export var EBUSY: number; + export var ECANCELED: number; + export var ECHILD: number; + export var ECONNABORTED: number; + export var ECONNREFUSED: number; + export var ECONNRESET: number; + export var EDEADLK: number; + export var EDESTADDRREQ: number; + export var EDOM: number; + export var EEXIST: number; + export var EFAULT: number; + export var EFBIG: number; + export var EHOSTUNREACH: number; + export var EIDRM: number; + export var EILSEQ: number; + export var EINPROGRESS: number; + export var EINTR: number; + export var EINVAL: number; + export var EIO: number; + export var EISCONN: number; + export var EISDIR: number; + export var ELOOP: number; + export var EMFILE: number; + export var EMLINK: number; + export var EMSGSIZE: number; + export var ENAMETOOLONG: number; + export var ENETDOWN: number; + export var ENETRESET: number; + export var ENETUNREACH: number; + export var ENFILE: number; + export var ENOBUFS: number; + export var ENODATA: number; + export var ENODEV: number; + export var ENOENT: number; + export var ENOEXEC: number; + export var ENOLCK: number; + export var ENOLINK: number; + export var ENOMEM: number; + export var ENOMSG: number; + export var ENOPROTOOPT: number; + export var ENOSPC: number; + export var ENOSR: number; + export var ENOSTR: number; + export var ENOSYS: number; + export var ENOTCONN: number; + export var ENOTDIR: number; + export var ENOTEMPTY: number; + export var ENOTSOCK: number; + export var ENOTSUP: number; + export var ENOTTY: number; + export var ENXIO: number; + export var EOPNOTSUPP: number; + export var EOVERFLOW: number; + export var EPERM: number; + export var EPIPE: number; + export var EPROTO: number; + export var EPROTONOSUPPORT: number; + export var EPROTOTYPE: number; + export var ERANGE: number; + export var EROFS: number; + export var ESPIPE: number; + export var ESRCH: number; + export var ETIME: number; + export var ETIMEDOUT: number; + export var ETXTBSY: number; + export var EWOULDBLOCK: number; + export var EXDEV: number; + export var WSAEINTR: number; + export var WSAEBADF: number; + export var WSAEACCES: number; + export var WSAEFAULT: number; + export var WSAEINVAL: number; + export var WSAEMFILE: number; + export var WSAEWOULDBLOCK: number; + export var WSAEINPROGRESS: number; + export var WSAEALREADY: number; + export var WSAENOTSOCK: number; + export var WSAEDESTADDRREQ: number; + export var WSAEMSGSIZE: number; + export var WSAEPROTOTYPE: number; + export var WSAENOPROTOOPT: number; + export var WSAEPROTONOSUPPORT: number; + export var WSAESOCKTNOSUPPORT: number; + export var WSAEOPNOTSUPP: number; + export var WSAEPFNOSUPPORT: number; + export var WSAEAFNOSUPPORT: number; + export var WSAEADDRINUSE: number; + export var WSAEADDRNOTAVAIL: number; + export var WSAENETDOWN: number; + export var WSAENETUNREACH: number; + export var WSAENETRESET: number; + export var WSAECONNABORTED: number; + export var WSAECONNRESET: number; + export var WSAENOBUFS: number; + export var WSAEISCONN: number; + export var WSAENOTCONN: number; + export var WSAESHUTDOWN: number; + export var WSAETOOMANYREFS: number; + export var WSAETIMEDOUT: number; + export var WSAECONNREFUSED: number; + export var WSAELOOP: number; + export var WSAENAMETOOLONG: number; + export var WSAEHOSTDOWN: number; + export var WSAEHOSTUNREACH: number; + export var WSAENOTEMPTY: number; + export var WSAEPROCLIM: number; + export var WSAEUSERS: number; + export var WSAEDQUOT: number; + export var WSAESTALE: number; + export var WSAEREMOTE: number; + export var WSASYSNOTREADY: number; + export var WSAVERNOTSUPPORTED: number; + export var WSANOTINITIALISED: number; + export var WSAEDISCON: number; + export var WSAENOMORE: number; + export var WSAECANCELLED: number; + export var WSAEINVALIDPROCTABLE: number; + export var WSAEINVALIDPROVIDER: number; + export var WSAEPROVIDERFAILEDINIT: number; + export var WSASYSCALLFAILURE: number; + export var WSASERVICE_NOT_FOUND: number; + export var WSATYPE_NOT_FOUND: number; + export var WSA_E_NO_MORE: number; + export var WSA_E_CANCELLED: number; + export var WSAEREFUSED: number; + export var SIGHUP: number; + export var SIGINT: number; + export var SIGILL: number; + export var SIGABRT: number; + export var SIGFPE: number; + export var SIGKILL: number; + export var SIGSEGV: number; + export var SIGTERM: number; + export var SIGBREAK: number; + export var SIGWINCH: number; + export var SSL_OP_ALL: number; + export var SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION: number; + export var SSL_OP_CIPHER_SERVER_PREFERENCE: number; + export var SSL_OP_CISCO_ANYCONNECT: number; + export var SSL_OP_COOKIE_EXCHANGE: number; + export var SSL_OP_CRYPTOPRO_TLSEXT_BUG: number; + export var SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS: number; + export var SSL_OP_EPHEMERAL_RSA: number; + export var SSL_OP_LEGACY_SERVER_CONNECT: number; + export var SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER: number; + export var SSL_OP_MICROSOFT_SESS_ID_BUG: number; + export var SSL_OP_MSIE_SSLV2_RSA_PADDING: number; + export var SSL_OP_NETSCAPE_CA_DN_BUG: number; + export var SSL_OP_NETSCAPE_CHALLENGE_BUG: number; + export var SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG: number; + export var SSL_OP_NO_COMPRESSION: number; + export var SSL_OP_NO_QUERY_MTU: number; + export var SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION: number; + export var SSL_OP_NO_SSLv2: number; + export var SSL_OP_NO_SSLv3: number; + export var SSL_OP_NO_TICKET: number; + export var SSL_OP_NO_TLSv1: number; + export var SSL_OP_NO_TLSv1_1: number; + export var SSL_OP_NO_TLSv1_2: number; + export var SSL_OP_PKCS1_CHECK_1: number; + export var SSL_OP_PKCS1_CHECK_2: number; + export var SSL_OP_SINGLE_DH_USE: number; + export var SSL_OP_SINGLE_ECDH_USE: number; + export var SSL_OP_SSLEAY_080_CLIENT_DH_BUG: number; + export var SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG: number; + export var SSL_OP_TLS_BLOCK_PADDING_BUG: number; + export var SSL_OP_TLS_D5_BUG: number; + export var SSL_OP_TLS_ROLLBACK_BUG: number; + export var ENGINE_METHOD_DSA: number; + export var ENGINE_METHOD_DH: number; + export var ENGINE_METHOD_RAND: number; + export var ENGINE_METHOD_ECDH: number; + export var ENGINE_METHOD_ECDSA: number; + export var ENGINE_METHOD_CIPHERS: number; + export var ENGINE_METHOD_DIGESTS: number; + export var ENGINE_METHOD_STORE: number; + export var ENGINE_METHOD_PKEY_METHS: number; + export var ENGINE_METHOD_PKEY_ASN1_METHS: number; + export var ENGINE_METHOD_ALL: number; + export var ENGINE_METHOD_NONE: number; + export var DH_CHECK_P_NOT_SAFE_PRIME: number; + export var DH_CHECK_P_NOT_PRIME: number; + export var DH_UNABLE_TO_CHECK_GENERATOR: number; + export var DH_NOT_SUITABLE_GENERATOR: number; + export var NPN_ENABLED: number; + export var RSA_PKCS1_PADDING: number; + export var RSA_SSLV23_PADDING: number; + export var RSA_NO_PADDING: number; + export var RSA_PKCS1_OAEP_PADDING: number; + export var RSA_X931_PADDING: number; + export var RSA_PKCS1_PSS_PADDING: number; + export var POINT_CONVERSION_COMPRESSED: number; + export var POINT_CONVERSION_UNCOMPRESSED: number; + export var POINT_CONVERSION_HYBRID: number; + export var O_RDONLY: number; + export var O_WRONLY: number; + export var O_RDWR: number; + export var S_IFMT: number; + export var S_IFREG: number; + export var S_IFDIR: number; + export var S_IFCHR: number; + export var S_IFLNK: number; + export var O_CREAT: number; + export var O_EXCL: number; + export var O_TRUNC: number; + export var O_APPEND: number; + export var F_OK: number; + export var R_OK: number; + export var W_OK: number; + export var X_OK: number; + export var UV_UDP_REUSEADDR: number; +} diff --git a/typings/optimist/optimist.d.ts b/typings/optimist/optimist.d.ts new file mode 100644 index 00000000000..3a32bc8d6ab --- /dev/null +++ b/typings/optimist/optimist.d.ts @@ -0,0 +1,50 @@ +// Type definitions for optimist +// Project: https://github.com/substack/node-optimist +// Definitions by: Carlos Ballesteros Velasco +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +// Imported from: https://github.com/soywiz/typescript-node-definitions/optimist.d.ts + +declare module "optimist" { + + interface Optimist { + (args: string[]): Optimist + default(name: string, value: any): Optimist; + default(args: Object): Optimist; + + boolean(name: string): Optimist; + boolean(names: string[]): Optimist; + + string(name: string): Optimist; + string(names: string[]): Optimist; + + wrap(columns: number): Optimist; + + help(): void; + showHelp(fn?: Function): void; + + usage(message: string): Optimist; + + demand(key: string): Optimist; + demand(key: number): Optimist; + demand(key: string[]): Optimist; + + alias(key: string, alias: string): Optimist; + + describe(key: string, desc: string): Optimist; + + options(obj: {[key: string]: {alias: string, describe: string, default?: any}}): Optimist; + options(key: string, opt: Object): Optimist; + + check(fn: Function): Optimist; + + parse(args: string[]): Optimist; + + argv: { + _: string[] + } & any; + } + var t: Optimist; + + export = t; +} diff --git a/typings/tsd.d.ts b/typings/tsd.d.ts new file mode 100644 index 00000000000..3fb12c2d580 --- /dev/null +++ b/typings/tsd.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// +/// +/// +/// diff --git a/typings/typescriptServices.d.ts b/typings/typescriptServices.d.ts deleted file mode 100644 index 4ce3cd34cb5..00000000000 --- a/typings/typescriptServices.d.ts +++ /dev/null @@ -1,2143 +0,0 @@ -/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -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 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */ - -declare namespace ts { - interface Map { - [index: string]: T; - } - interface FileMap { - get(fileName: string): T; - set(fileName: string, value: T): void; - contains(fileName: string): boolean; - remove(fileName: string): void; - forEachValue(f: (v: T) => void): void; - clear(): void; - } - interface TextRange { - pos: number; - end: number; - } - const enum SyntaxKind { - Unknown = 0, - EndOfFileToken = 1, - SingleLineCommentTrivia = 2, - MultiLineCommentTrivia = 3, - NewLineTrivia = 4, - WhitespaceTrivia = 5, - ShebangTrivia = 6, - ConflictMarkerTrivia = 7, - NumericLiteral = 8, - StringLiteral = 9, - RegularExpressionLiteral = 10, - NoSubstitutionTemplateLiteral = 11, - TemplateHead = 12, - TemplateMiddle = 13, - TemplateTail = 14, - OpenBraceToken = 15, - CloseBraceToken = 16, - OpenParenToken = 17, - CloseParenToken = 18, - OpenBracketToken = 19, - CloseBracketToken = 20, - DotToken = 21, - DotDotDotToken = 22, - SemicolonToken = 23, - CommaToken = 24, - LessThanToken = 25, - LessThanSlashToken = 26, - GreaterThanToken = 27, - LessThanEqualsToken = 28, - GreaterThanEqualsToken = 29, - EqualsEqualsToken = 30, - ExclamationEqualsToken = 31, - EqualsEqualsEqualsToken = 32, - ExclamationEqualsEqualsToken = 33, - EqualsGreaterThanToken = 34, - PlusToken = 35, - MinusToken = 36, - AsteriskToken = 37, - SlashToken = 38, - PercentToken = 39, - PlusPlusToken = 40, - MinusMinusToken = 41, - LessThanLessThanToken = 42, - GreaterThanGreaterThanToken = 43, - GreaterThanGreaterThanGreaterThanToken = 44, - AmpersandToken = 45, - BarToken = 46, - CaretToken = 47, - ExclamationToken = 48, - TildeToken = 49, - AmpersandAmpersandToken = 50, - BarBarToken = 51, - QuestionToken = 52, - ColonToken = 53, - AtToken = 54, - EqualsToken = 55, - PlusEqualsToken = 56, - MinusEqualsToken = 57, - AsteriskEqualsToken = 58, - SlashEqualsToken = 59, - PercentEqualsToken = 60, - LessThanLessThanEqualsToken = 61, - GreaterThanGreaterThanEqualsToken = 62, - GreaterThanGreaterThanGreaterThanEqualsToken = 63, - AmpersandEqualsToken = 64, - BarEqualsToken = 65, - CaretEqualsToken = 66, - Identifier = 67, - BreakKeyword = 68, - CaseKeyword = 69, - CatchKeyword = 70, - ClassKeyword = 71, - ConstKeyword = 72, - ContinueKeyword = 73, - DebuggerKeyword = 74, - DefaultKeyword = 75, - DeleteKeyword = 76, - DoKeyword = 77, - ElseKeyword = 78, - EnumKeyword = 79, - ExportKeyword = 80, - ExtendsKeyword = 81, - FalseKeyword = 82, - FinallyKeyword = 83, - ForKeyword = 84, - FunctionKeyword = 85, - IfKeyword = 86, - ImportKeyword = 87, - InKeyword = 88, - InstanceOfKeyword = 89, - NewKeyword = 90, - NullKeyword = 91, - ReturnKeyword = 92, - SuperKeyword = 93, - SwitchKeyword = 94, - ThisKeyword = 95, - ThrowKeyword = 96, - TrueKeyword = 97, - TryKeyword = 98, - TypeOfKeyword = 99, - VarKeyword = 100, - VoidKeyword = 101, - WhileKeyword = 102, - WithKeyword = 103, - ImplementsKeyword = 104, - InterfaceKeyword = 105, - LetKeyword = 106, - PackageKeyword = 107, - PrivateKeyword = 108, - ProtectedKeyword = 109, - PublicKeyword = 110, - StaticKeyword = 111, - YieldKeyword = 112, - AbstractKeyword = 113, - AsKeyword = 114, - AnyKeyword = 115, - AsyncKeyword = 116, - AwaitKeyword = 117, - BooleanKeyword = 118, - ConstructorKeyword = 119, - DeclareKeyword = 120, - GetKeyword = 121, - IsKeyword = 122, - ModuleKeyword = 123, - NamespaceKeyword = 124, - RequireKeyword = 125, - NumberKeyword = 126, - SetKeyword = 127, - StringKeyword = 128, - SymbolKeyword = 129, - TypeKeyword = 130, - FromKeyword = 131, - OfKeyword = 132, - QualifiedName = 133, - ComputedPropertyName = 134, - TypeParameter = 135, - Parameter = 136, - Decorator = 137, - PropertySignature = 138, - PropertyDeclaration = 139, - MethodSignature = 140, - MethodDeclaration = 141, - Constructor = 142, - GetAccessor = 143, - SetAccessor = 144, - CallSignature = 145, - ConstructSignature = 146, - IndexSignature = 147, - TypePredicate = 148, - TypeReference = 149, - FunctionType = 150, - ConstructorType = 151, - TypeQuery = 152, - TypeLiteral = 153, - ArrayType = 154, - TupleType = 155, - UnionType = 156, - IntersectionType = 157, - ParenthesizedType = 158, - ObjectBindingPattern = 159, - ArrayBindingPattern = 160, - BindingElement = 161, - ArrayLiteralExpression = 162, - ObjectLiteralExpression = 163, - PropertyAccessExpression = 164, - ElementAccessExpression = 165, - CallExpression = 166, - NewExpression = 167, - TaggedTemplateExpression = 168, - TypeAssertionExpression = 169, - ParenthesizedExpression = 170, - FunctionExpression = 171, - ArrowFunction = 172, - DeleteExpression = 173, - TypeOfExpression = 174, - VoidExpression = 175, - AwaitExpression = 176, - PrefixUnaryExpression = 177, - PostfixUnaryExpression = 178, - BinaryExpression = 179, - ConditionalExpression = 180, - TemplateExpression = 181, - YieldExpression = 182, - SpreadElementExpression = 183, - ClassExpression = 184, - OmittedExpression = 185, - ExpressionWithTypeArguments = 186, - AsExpression = 187, - TemplateSpan = 188, - SemicolonClassElement = 189, - Block = 190, - VariableStatement = 191, - EmptyStatement = 192, - ExpressionStatement = 193, - IfStatement = 194, - DoStatement = 195, - WhileStatement = 196, - ForStatement = 197, - ForInStatement = 198, - ForOfStatement = 199, - ContinueStatement = 200, - BreakStatement = 201, - ReturnStatement = 202, - WithStatement = 203, - SwitchStatement = 204, - LabeledStatement = 205, - ThrowStatement = 206, - TryStatement = 207, - DebuggerStatement = 208, - VariableDeclaration = 209, - VariableDeclarationList = 210, - FunctionDeclaration = 211, - ClassDeclaration = 212, - InterfaceDeclaration = 213, - TypeAliasDeclaration = 214, - EnumDeclaration = 215, - ModuleDeclaration = 216, - ModuleBlock = 217, - CaseBlock = 218, - ImportEqualsDeclaration = 219, - ImportDeclaration = 220, - ImportClause = 221, - NamespaceImport = 222, - NamedImports = 223, - ImportSpecifier = 224, - ExportAssignment = 225, - ExportDeclaration = 226, - NamedExports = 227, - ExportSpecifier = 228, - MissingDeclaration = 229, - ExternalModuleReference = 230, - JsxElement = 231, - JsxSelfClosingElement = 232, - JsxOpeningElement = 233, - JsxText = 234, - JsxClosingElement = 235, - JsxAttribute = 236, - JsxSpreadAttribute = 237, - JsxExpression = 238, - CaseClause = 239, - DefaultClause = 240, - HeritageClause = 241, - CatchClause = 242, - PropertyAssignment = 243, - ShorthandPropertyAssignment = 244, - EnumMember = 245, - SourceFile = 246, - JSDocTypeExpression = 247, - JSDocAllType = 248, - JSDocUnknownType = 249, - JSDocArrayType = 250, - JSDocUnionType = 251, - JSDocTupleType = 252, - JSDocNullableType = 253, - JSDocNonNullableType = 254, - JSDocRecordType = 255, - JSDocRecordMember = 256, - JSDocTypeReference = 257, - JSDocOptionalType = 258, - JSDocFunctionType = 259, - JSDocVariadicType = 260, - JSDocConstructorType = 261, - JSDocThisType = 262, - JSDocComment = 263, - JSDocTag = 264, - JSDocParameterTag = 265, - JSDocReturnTag = 266, - JSDocTypeTag = 267, - JSDocTemplateTag = 268, - SyntaxList = 269, - Count = 270, - FirstAssignment = 55, - LastAssignment = 66, - FirstReservedWord = 68, - LastReservedWord = 103, - FirstKeyword = 68, - LastKeyword = 132, - FirstFutureReservedWord = 104, - LastFutureReservedWord = 112, - FirstTypeNode = 149, - LastTypeNode = 158, - FirstPunctuation = 15, - LastPunctuation = 66, - FirstToken = 0, - LastToken = 132, - FirstTriviaToken = 2, - LastTriviaToken = 7, - FirstLiteralToken = 8, - LastLiteralToken = 11, - FirstTemplateToken = 11, - LastTemplateToken = 14, - FirstBinaryOperator = 25, - LastBinaryOperator = 66, - FirstNode = 133, - } - const enum NodeFlags { - Export = 1, - Ambient = 2, - Public = 16, - Private = 32, - Protected = 64, - Static = 128, - Abstract = 256, - Async = 512, - Default = 1024, - MultiLine = 2048, - Synthetic = 4096, - DeclarationFile = 8192, - Let = 16384, - Const = 32768, - OctalLiteral = 65536, - Namespace = 131072, - ExportContext = 262144, - Modifier = 2035, - AccessibilityModifier = 112, - BlockScoped = 49152, - } - const enum JsxFlags { - None = 0, - IntrinsicNamedElement = 1, - IntrinsicIndexedElement = 2, - ClassElement = 4, - UnknownElement = 8, - IntrinsicElement = 3, - } - interface Node extends TextRange { - kind: SyntaxKind; - flags: NodeFlags; - decorators?: NodeArray; - modifiers?: ModifiersArray; - parent?: Node; - } - interface NodeArray extends Array, TextRange { - hasTrailingComma?: boolean; - } - interface ModifiersArray extends NodeArray { - flags: number; - } - interface Identifier extends PrimaryExpression { - text: string; - originalKeywordKind?: SyntaxKind; - } - interface QualifiedName extends Node { - left: EntityName; - right: Identifier; - } - type EntityName = Identifier | QualifiedName; - type DeclarationName = Identifier | LiteralExpression | ComputedPropertyName | BindingPattern; - interface Declaration extends Node { - _declarationBrand: any; - name?: DeclarationName; - } - interface ComputedPropertyName extends Node { - expression: Expression; - } - interface Decorator extends Node { - expression: LeftHandSideExpression; - } - interface TypeParameterDeclaration extends Declaration { - name: Identifier; - constraint?: TypeNode; - expression?: Expression; - } - interface SignatureDeclaration extends Declaration { - typeParameters?: NodeArray; - parameters: NodeArray; - type?: TypeNode; - } - interface VariableDeclaration extends Declaration { - parent?: VariableDeclarationList; - name: Identifier | BindingPattern; - type?: TypeNode; - initializer?: Expression; - } - interface VariableDeclarationList extends Node { - declarations: NodeArray; - } - interface ParameterDeclaration extends Declaration { - dotDotDotToken?: Node; - name: Identifier | BindingPattern; - questionToken?: Node; - type?: TypeNode; - initializer?: Expression; - } - interface BindingElement extends Declaration { - propertyName?: Identifier; - dotDotDotToken?: Node; - name: Identifier | BindingPattern; - initializer?: Expression; - } - interface PropertyDeclaration extends Declaration, ClassElement { - name: DeclarationName; - questionToken?: Node; - type?: TypeNode; - initializer?: Expression; - } - interface ObjectLiteralElement extends Declaration { - _objectLiteralBrandBrand: any; - } - interface PropertyAssignment extends ObjectLiteralElement { - _propertyAssignmentBrand: any; - name: DeclarationName; - questionToken?: Node; - initializer: Expression; - } - interface ShorthandPropertyAssignment extends ObjectLiteralElement { - name: Identifier; - questionToken?: Node; - } - interface VariableLikeDeclaration extends Declaration { - propertyName?: Identifier; - dotDotDotToken?: Node; - name: DeclarationName; - questionToken?: Node; - type?: TypeNode; - initializer?: Expression; - } - interface BindingPattern extends Node { - elements: NodeArray; - } - /** - * Several node kinds share function-like features such as a signature, - * a name, and a body. These nodes should extend FunctionLikeDeclaration. - * Examples: - * - FunctionDeclaration - * - MethodDeclaration - * - AccessorDeclaration - */ - interface FunctionLikeDeclaration extends SignatureDeclaration { - _functionLikeDeclarationBrand: any; - asteriskToken?: Node; - questionToken?: Node; - body?: Block | Expression; - } - interface FunctionDeclaration extends FunctionLikeDeclaration, Statement { - name?: Identifier; - body?: Block; - } - interface MethodDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { - body?: Block; - } - interface ConstructorDeclaration extends FunctionLikeDeclaration, ClassElement { - body?: Block; - } - interface SemicolonClassElement extends ClassElement { - _semicolonClassElementBrand: any; - } - interface AccessorDeclaration extends FunctionLikeDeclaration, ClassElement, ObjectLiteralElement { - _accessorDeclarationBrand: any; - body: Block; - } - interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement { - _indexSignatureDeclarationBrand: any; - } - interface TypeNode extends Node { - _typeNodeBrand: any; - } - interface FunctionOrConstructorTypeNode extends TypeNode, SignatureDeclaration { - _functionOrConstructorTypeNodeBrand: any; - } - interface TypeReferenceNode extends TypeNode { - typeName: EntityName; - typeArguments?: NodeArray; - } - interface TypePredicateNode extends TypeNode { - parameterName: Identifier; - type: TypeNode; - } - interface TypeQueryNode extends TypeNode { - exprName: EntityName; - } - interface TypeLiteralNode extends TypeNode, Declaration { - members: NodeArray; - } - interface ArrayTypeNode extends TypeNode { - elementType: TypeNode; - } - interface TupleTypeNode extends TypeNode { - elementTypes: NodeArray; - } - interface UnionOrIntersectionTypeNode extends TypeNode { - types: NodeArray; - } - interface UnionTypeNode extends UnionOrIntersectionTypeNode { - } - interface IntersectionTypeNode extends UnionOrIntersectionTypeNode { - } - interface ParenthesizedTypeNode extends TypeNode { - type: TypeNode; - } - interface StringLiteral extends LiteralExpression, TypeNode { - _stringLiteralBrand: any; - } - interface Expression extends Node { - _expressionBrand: any; - contextualType?: Type; - } - interface UnaryExpression extends Expression { - _unaryExpressionBrand: any; - } - interface PrefixUnaryExpression extends UnaryExpression { - operator: SyntaxKind; - operand: UnaryExpression; - } - interface PostfixUnaryExpression extends PostfixExpression { - operand: LeftHandSideExpression; - operator: SyntaxKind; - } - interface PostfixExpression extends UnaryExpression { - _postfixExpressionBrand: any; - } - interface LeftHandSideExpression extends PostfixExpression { - _leftHandSideExpressionBrand: any; - } - interface MemberExpression extends LeftHandSideExpression { - _memberExpressionBrand: any; - } - interface PrimaryExpression extends MemberExpression { - _primaryExpressionBrand: any; - } - interface DeleteExpression extends UnaryExpression { - expression: UnaryExpression; - } - interface TypeOfExpression extends UnaryExpression { - expression: UnaryExpression; - } - interface VoidExpression extends UnaryExpression { - expression: UnaryExpression; - } - interface AwaitExpression extends UnaryExpression { - expression: UnaryExpression; - } - interface YieldExpression extends Expression { - asteriskToken?: Node; - expression?: Expression; - } - interface BinaryExpression extends Expression { - left: Expression; - operatorToken: Node; - right: Expression; - } - interface ConditionalExpression extends Expression { - condition: Expression; - questionToken: Node; - whenTrue: Expression; - colonToken: Node; - whenFalse: Expression; - } - interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclaration { - name?: Identifier; - body: Block | Expression; - } - interface ArrowFunction extends Expression, FunctionLikeDeclaration { - equalsGreaterThanToken: Node; - } - interface LiteralExpression extends PrimaryExpression { - text: string; - isUnterminated?: boolean; - hasExtendedUnicodeEscape?: boolean; - } - interface TemplateExpression extends PrimaryExpression { - head: LiteralExpression; - templateSpans: NodeArray; - } - interface TemplateSpan extends Node { - expression: Expression; - literal: LiteralExpression; - } - interface ParenthesizedExpression extends PrimaryExpression { - expression: Expression; - } - interface ArrayLiteralExpression extends PrimaryExpression { - elements: NodeArray; - } - interface SpreadElementExpression extends Expression { - expression: Expression; - } - interface ObjectLiteralExpression extends PrimaryExpression, Declaration { - properties: NodeArray; - } - interface PropertyAccessExpression extends MemberExpression { - expression: LeftHandSideExpression; - dotToken: Node; - name: Identifier; - } - interface ElementAccessExpression extends MemberExpression { - expression: LeftHandSideExpression; - argumentExpression?: Expression; - } - interface CallExpression extends LeftHandSideExpression { - expression: LeftHandSideExpression; - typeArguments?: NodeArray; - arguments: NodeArray; - } - interface ExpressionWithTypeArguments extends TypeNode { - expression: LeftHandSideExpression; - typeArguments?: NodeArray; - } - interface NewExpression extends CallExpression, PrimaryExpression { - } - interface TaggedTemplateExpression extends MemberExpression { - tag: LeftHandSideExpression; - template: LiteralExpression | TemplateExpression; - } - type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; - interface AsExpression extends Expression { - expression: Expression; - type: TypeNode; - } - interface TypeAssertion extends UnaryExpression { - type: TypeNode; - expression: UnaryExpression; - } - type AssertionExpression = TypeAssertion | AsExpression; - interface JsxElement extends PrimaryExpression { - openingElement: JsxOpeningElement; - children: NodeArray; - closingElement: JsxClosingElement; - } - interface JsxOpeningElement extends Expression { - _openingElementBrand?: any; - tagName: EntityName; - attributes: NodeArray; - } - interface JsxSelfClosingElement extends PrimaryExpression, JsxOpeningElement { - _selfClosingElementBrand?: any; - } - type JsxOpeningLikeElement = JsxSelfClosingElement | JsxOpeningElement; - interface JsxAttribute extends Node { - name: Identifier; - initializer?: Expression; - } - interface JsxSpreadAttribute extends Node { - expression: Expression; - } - interface JsxClosingElement extends Node { - tagName: EntityName; - } - interface JsxExpression extends Expression { - expression?: Expression; - } - interface JsxText extends Node { - _jsxTextExpressionBrand: any; - } - type JsxChild = JsxText | JsxExpression | JsxElement | JsxSelfClosingElement; - interface Statement extends Node { - _statementBrand: any; - } - interface Block extends Statement { - statements: NodeArray; - } - interface VariableStatement extends Statement { - declarationList: VariableDeclarationList; - } - interface ExpressionStatement extends Statement { - expression: Expression; - } - interface IfStatement extends Statement { - expression: Expression; - thenStatement: Statement; - elseStatement?: Statement; - } - interface IterationStatement extends Statement { - statement: Statement; - } - interface DoStatement extends IterationStatement { - expression: Expression; - } - interface WhileStatement extends IterationStatement { - expression: Expression; - } - interface ForStatement extends IterationStatement { - initializer?: VariableDeclarationList | Expression; - condition?: Expression; - incrementor?: Expression; - } - interface ForInStatement extends IterationStatement { - initializer: VariableDeclarationList | Expression; - expression: Expression; - } - interface ForOfStatement extends IterationStatement { - initializer: VariableDeclarationList | Expression; - expression: Expression; - } - interface BreakOrContinueStatement extends Statement { - label?: Identifier; - } - interface ReturnStatement extends Statement { - expression?: Expression; - } - interface WithStatement extends Statement { - expression: Expression; - statement: Statement; - } - interface SwitchStatement extends Statement { - expression: Expression; - caseBlock: CaseBlock; - } - interface CaseBlock extends Node { - clauses: NodeArray; - } - interface CaseClause extends Node { - expression?: Expression; - statements: NodeArray; - } - interface DefaultClause extends Node { - statements: NodeArray; - } - type CaseOrDefaultClause = CaseClause | DefaultClause; - interface LabeledStatement extends Statement { - label: Identifier; - statement: Statement; - } - interface ThrowStatement extends Statement { - expression: Expression; - } - interface TryStatement extends Statement { - tryBlock: Block; - catchClause?: CatchClause; - finallyBlock?: Block; - } - interface CatchClause extends Node { - variableDeclaration: VariableDeclaration; - block: Block; - } - interface ClassLikeDeclaration extends Declaration { - name?: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; - } - interface ClassDeclaration extends ClassLikeDeclaration, Statement { - } - interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression { - } - interface ClassElement extends Declaration { - _classElementBrand: any; - } - interface InterfaceDeclaration extends Declaration, Statement { - name: Identifier; - typeParameters?: NodeArray; - heritageClauses?: NodeArray; - members: NodeArray; - } - interface HeritageClause extends Node { - token: SyntaxKind; - types?: NodeArray; - } - interface TypeAliasDeclaration extends Declaration, Statement { - name: Identifier; - typeParameters?: NodeArray; - type: TypeNode; - } - interface EnumMember extends Declaration { - name: DeclarationName; - initializer?: Expression; - } - interface EnumDeclaration extends Declaration, Statement { - name: Identifier; - members: NodeArray; - } - interface ModuleDeclaration extends Declaration, Statement { - name: Identifier | LiteralExpression; - body: ModuleBlock | ModuleDeclaration; - } - interface ModuleBlock extends Node, Statement { - statements: NodeArray; - } - interface ImportEqualsDeclaration extends Declaration, Statement { - name: Identifier; - moduleReference: EntityName | ExternalModuleReference; - } - interface ExternalModuleReference extends Node { - expression?: Expression; - } - interface ImportDeclaration extends Statement { - importClause?: ImportClause; - moduleSpecifier: Expression; - } - interface ImportClause extends Declaration { - name?: Identifier; - namedBindings?: NamespaceImport | NamedImports; - } - interface NamespaceImport extends Declaration { - name: Identifier; - } - interface ExportDeclaration extends Declaration, Statement { - exportClause?: NamedExports; - moduleSpecifier?: Expression; - } - interface NamedImportsOrExports extends Node { - elements: NodeArray; - } - type NamedImports = NamedImportsOrExports; - type NamedExports = NamedImportsOrExports; - interface ImportOrExportSpecifier extends Declaration { - propertyName?: Identifier; - name: Identifier; - } - type ImportSpecifier = ImportOrExportSpecifier; - type ExportSpecifier = ImportOrExportSpecifier; - interface ExportAssignment extends Declaration, Statement { - isExportEquals?: boolean; - expression: Expression; - } - interface FileReference extends TextRange { - fileName: string; - } - interface CommentRange extends TextRange { - hasTrailingNewLine?: boolean; - kind: SyntaxKind; - } - interface JSDocTypeExpression extends Node { - type: JSDocType; - } - interface JSDocType extends TypeNode { - _jsDocTypeBrand: any; - } - interface JSDocAllType extends JSDocType { - _JSDocAllTypeBrand: any; - } - interface JSDocUnknownType extends JSDocType { - _JSDocUnknownTypeBrand: any; - } - interface JSDocArrayType extends JSDocType { - elementType: JSDocType; - } - interface JSDocUnionType extends JSDocType { - types: NodeArray; - } - interface JSDocTupleType extends JSDocType { - types: NodeArray; - } - interface JSDocNonNullableType extends JSDocType { - type: JSDocType; - } - interface JSDocNullableType extends JSDocType { - type: JSDocType; - } - interface JSDocRecordType extends JSDocType, TypeLiteralNode { - members: NodeArray; - } - interface JSDocTypeReference extends JSDocType { - name: EntityName; - typeArguments: NodeArray; - } - interface JSDocOptionalType extends JSDocType { - type: JSDocType; - } - interface JSDocFunctionType extends JSDocType, SignatureDeclaration { - parameters: NodeArray; - type: JSDocType; - } - interface JSDocVariadicType extends JSDocType { - type: JSDocType; - } - interface JSDocConstructorType extends JSDocType { - type: JSDocType; - } - interface JSDocThisType extends JSDocType { - type: JSDocType; - } - interface JSDocRecordMember extends PropertyDeclaration { - name: Identifier | LiteralExpression; - type?: JSDocType; - } - interface JSDocComment extends Node { - tags: NodeArray; - } - interface JSDocTag extends Node { - atToken: Node; - tagName: Identifier; - } - interface JSDocTemplateTag extends JSDocTag { - typeParameters: NodeArray; - } - interface JSDocReturnTag extends JSDocTag { - typeExpression: JSDocTypeExpression; - } - interface JSDocTypeTag extends JSDocTag { - typeExpression: JSDocTypeExpression; - } - interface JSDocParameterTag extends JSDocTag { - preParameterName?: Identifier; - typeExpression?: JSDocTypeExpression; - postParameterName?: Identifier; - isBracketed: boolean; - } - interface SourceFile extends Declaration { - statements: NodeArray; - endOfFileToken: Node; - fileName: string; - text: string; - amdDependencies: { - path: string; - name: string; - }[]; - moduleName: string; - referencedFiles: FileReference[]; - languageVariant: LanguageVariant; - /** - * lib.d.ts should have a reference comment like - * - * /// - * - * If any other file has this comment, it signals not to include lib.d.ts - * because this containing file is intended to act as a default library. - */ - hasNoDefaultLib: boolean; - languageVersion: ScriptTarget; - } - interface ScriptReferenceHost { - getCompilerOptions(): CompilerOptions; - getSourceFile(fileName: string): SourceFile; - getCurrentDirectory(): string; - } - interface ParseConfigHost extends ModuleResolutionHost { - readDirectory(rootDir: string, extension: string, exclude: string[]): string[]; - } - interface WriteFileCallback { - (fileName: string, data: string, writeByteOrderMark: boolean, onError?: (message: string) => void): void; - } - class OperationCanceledException { - } - interface CancellationToken { - isCancellationRequested(): boolean; - /** @throws OperationCanceledException if isCancellationRequested is true */ - throwIfCancellationRequested(): void; - } - interface Program extends ScriptReferenceHost { - /** - * Get a list of root file names that were passed to a 'createProgram' - */ - getRootFileNames(): string[]; - /** - * Get a list of files in the program - */ - getSourceFiles(): SourceFile[]; - /** - * Emits the JavaScript and declaration files. If targetSourceFile is not specified, then - * the JavaScript and declaration files will be produced for all the files in this program. - * If targetSourceFile is specified, then only the JavaScript and declaration for that - * specific file will be generated. - * - * If writeFile is not specified then the writeFile callback from the compiler host will be - * used for writing the JavaScript and declaration files. Otherwise, the writeFile parameter - * will be invoked when writing the JavaScript and declaration files. - */ - emit(targetSourceFile?: SourceFile, writeFile?: WriteFileCallback, cancellationToken?: CancellationToken): EmitResult; - getOptionsDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; - getGlobalDiagnostics(cancellationToken?: CancellationToken): Diagnostic[]; - getSyntacticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - getSemanticDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - getDeclarationDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - /** - * Gets a type checker that can be used to semantically analyze source fils in the program. - */ - getTypeChecker(): TypeChecker; - } - interface SourceMapSpan { - /** Line number in the .js file. */ - emittedLine: number; - /** Column number in the .js file. */ - emittedColumn: number; - /** Line number in the .ts file. */ - sourceLine: number; - /** Column number in the .ts file. */ - sourceColumn: number; - /** Optional name (index into names array) associated with this span. */ - nameIndex?: number; - /** .ts file (index into sources array) associated with this span */ - sourceIndex: number; - } - interface SourceMapData { - sourceMapFilePath: string; - jsSourceMappingURL: string; - sourceMapFile: string; - sourceMapSourceRoot: string; - sourceMapSources: string[]; - sourceMapSourcesContent?: string[]; - inputSourceFileNames: string[]; - sourceMapNames?: string[]; - sourceMapMappings: string; - sourceMapDecodedMappings: SourceMapSpan[]; - } - /** Return code used by getEmitOutput function to indicate status of the function */ - enum ExitStatus { - Success = 0, - DiagnosticsPresent_OutputsSkipped = 1, - DiagnosticsPresent_OutputsGenerated = 2, - } - interface EmitResult { - emitSkipped: boolean; - diagnostics: Diagnostic[]; - } - interface TypeChecker { - getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; - getDeclaredTypeOfSymbol(symbol: Symbol): Type; - getPropertiesOfType(type: Type): Symbol[]; - getPropertyOfType(type: Type, propertyName: string): Symbol; - getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; - getIndexTypeOfType(type: Type, kind: IndexKind): Type; - getBaseTypes(type: InterfaceType): ObjectType[]; - getReturnTypeOfSignature(signature: Signature): Type; - getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[]; - getSymbolAtLocation(node: Node): Symbol; - getShorthandAssignmentValueSymbol(location: Node): Symbol; - getTypeAtLocation(node: Node): Type; - typeToString(type: Type, enclosingDeclaration?: Node, flags?: TypeFormatFlags): string; - symbolToString(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): string; - getSymbolDisplayBuilder(): SymbolDisplayBuilder; - getFullyQualifiedName(symbol: Symbol): string; - getAugmentedPropertiesOfType(type: Type): Symbol[]; - getRootSymbols(symbol: Symbol): Symbol[]; - getContextualType(node: Expression): Type; - getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature; - getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature; - isImplementationOfOverload(node: FunctionLikeDeclaration): boolean; - isUndefinedSymbol(symbol: Symbol): boolean; - isArgumentsSymbol(symbol: Symbol): boolean; - getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): number; - isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean; - getAliasedSymbol(symbol: Symbol): Symbol; - getExportsOfModule(moduleSymbol: Symbol): Symbol[]; - getJsxElementAttributesType(elementNode: JsxOpeningLikeElement): Type; - getJsxIntrinsicTagNames(): Symbol[]; - isOptionalParameter(node: ParameterDeclaration): boolean; - } - interface SymbolDisplayBuilder { - buildTypeDisplay(type: Type, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void; - buildSignatureDisplay(signatures: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildParameterDisplay(parameter: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplay(tp: TypeParameter, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildTypeParameterDisplayFromSymbol(symbol: Symbol, writer: SymbolWriter, enclosingDeclaraiton?: Node, flags?: TypeFormatFlags): void; - buildDisplayForParametersAndDelimiters(parameters: Symbol[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildDisplayForTypeParametersAndDelimiters(typeParameters: TypeParameter[], writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - buildReturnTypeDisplay(signature: Signature, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags): void; - } - interface SymbolWriter { - writeKeyword(text: string): void; - writeOperator(text: string): void; - writePunctuation(text: string): void; - writeSpace(text: string): void; - writeStringLiteral(text: string): void; - writeParameter(text: string): void; - writeSymbol(text: string, symbol: Symbol): void; - writeLine(): void; - increaseIndent(): void; - decreaseIndent(): void; - clear(): void; - trackSymbol(symbol: Symbol, enclosingDeclaration?: Node, meaning?: SymbolFlags): void; - } - const enum TypeFormatFlags { - None = 0, - WriteArrayAsGenericType = 1, - UseTypeOfFunction = 2, - NoTruncation = 4, - WriteArrowStyleSignature = 8, - WriteOwnNameForAnyLike = 16, - WriteTypeArgumentsOfSignature = 32, - InElementType = 64, - UseFullyQualifiedType = 128, - } - const enum SymbolFormatFlags { - None = 0, - WriteTypeParametersOrArguments = 1, - UseOnlyExternalAliasing = 2, - } - interface TypePredicate { - parameterName: string; - parameterIndex: number; - type: Type; - } - const enum SymbolFlags { - None = 0, - FunctionScopedVariable = 1, - BlockScopedVariable = 2, - Property = 4, - EnumMember = 8, - Function = 16, - Class = 32, - Interface = 64, - ConstEnum = 128, - RegularEnum = 256, - ValueModule = 512, - NamespaceModule = 1024, - TypeLiteral = 2048, - ObjectLiteral = 4096, - Method = 8192, - Constructor = 16384, - GetAccessor = 32768, - SetAccessor = 65536, - Signature = 131072, - TypeParameter = 262144, - TypeAlias = 524288, - ExportValue = 1048576, - ExportType = 2097152, - ExportNamespace = 4194304, - Alias = 8388608, - Instantiated = 16777216, - Merged = 33554432, - Transient = 67108864, - Prototype = 134217728, - SyntheticProperty = 268435456, - Optional = 536870912, - ExportStar = 1073741824, - Enum = 384, - Variable = 3, - Value = 107455, - Type = 793056, - Namespace = 1536, - Module = 1536, - Accessor = 98304, - FunctionScopedVariableExcludes = 107454, - BlockScopedVariableExcludes = 107455, - ParameterExcludes = 107455, - PropertyExcludes = 107455, - EnumMemberExcludes = 107455, - FunctionExcludes = 106927, - ClassExcludes = 899519, - InterfaceExcludes = 792960, - RegularEnumExcludes = 899327, - ConstEnumExcludes = 899967, - ValueModuleExcludes = 106639, - NamespaceModuleExcludes = 0, - MethodExcludes = 99263, - GetAccessorExcludes = 41919, - SetAccessorExcludes = 74687, - TypeParameterExcludes = 530912, - TypeAliasExcludes = 793056, - AliasExcludes = 8388608, - ModuleMember = 8914931, - ExportHasLocal = 944, - HasExports = 1952, - HasMembers = 6240, - BlockScoped = 418, - PropertyOrAccessor = 98308, - Export = 7340032, - } - interface Symbol { - flags: SymbolFlags; - name: string; - declarations?: Declaration[]; - valueDeclaration?: Declaration; - members?: SymbolTable; - exports?: SymbolTable; - } - interface SymbolTable { - [index: string]: Symbol; - } - const enum TypeFlags { - Any = 1, - String = 2, - Number = 4, - Boolean = 8, - Void = 16, - Undefined = 32, - Null = 64, - Enum = 128, - StringLiteral = 256, - TypeParameter = 512, - Class = 1024, - Interface = 2048, - Reference = 4096, - Tuple = 8192, - Union = 16384, - Intersection = 32768, - Anonymous = 65536, - Instantiated = 131072, - ObjectLiteral = 524288, - ESSymbol = 16777216, - StringLike = 258, - NumberLike = 132, - ObjectType = 80896, - UnionOrIntersection = 49152, - StructuredType = 130048, - } - interface Type { - flags: TypeFlags; - symbol?: Symbol; - } - interface StringLiteralType extends Type { - text: string; - } - interface ObjectType extends Type { - } - interface InterfaceType extends ObjectType { - typeParameters: TypeParameter[]; - outerTypeParameters: TypeParameter[]; - localTypeParameters: TypeParameter[]; - } - interface InterfaceTypeWithDeclaredMembers extends InterfaceType { - declaredProperties: Symbol[]; - declaredCallSignatures: Signature[]; - declaredConstructSignatures: Signature[]; - declaredStringIndexType: Type; - declaredNumberIndexType: Type; - } - interface TypeReference extends ObjectType { - target: GenericType; - typeArguments: Type[]; - } - interface GenericType extends InterfaceType, TypeReference { - } - interface TupleType extends ObjectType { - elementTypes: Type[]; - baseArrayType: TypeReference; - } - interface UnionOrIntersectionType extends Type { - types: Type[]; - } - interface UnionType extends UnionOrIntersectionType { - } - interface IntersectionType extends UnionOrIntersectionType { - } - interface TypeParameter extends Type { - constraint: Type; - } - const enum SignatureKind { - Call = 0, - Construct = 1, - } - interface Signature { - declaration: SignatureDeclaration; - typeParameters: TypeParameter[]; - parameters: Symbol[]; - typePredicate?: TypePredicate; - } - const enum IndexKind { - String = 0, - Number = 1, - } - interface DiagnosticMessage { - key: string; - category: DiagnosticCategory; - code: number; - } - /** - * A linked list of formatted diagnostic messages to be used as part of a multiline message. - * It is built from the bottom up, leaving the head to be the "main" diagnostic. - * While it seems that DiagnosticMessageChain is structurally similar to DiagnosticMessage, - * the difference is that messages are all preformatted in DMC. - */ - interface DiagnosticMessageChain { - messageText: string; - category: DiagnosticCategory; - code: number; - next?: DiagnosticMessageChain; - } - interface Diagnostic { - file: SourceFile; - start: number; - length: number; - messageText: string | DiagnosticMessageChain; - category: DiagnosticCategory; - code: number; - } - enum DiagnosticCategory { - Warning = 0, - Error = 1, - Message = 2, - } - const enum ModuleResolutionKind { - Classic = 1, - NodeJs = 2, - } - interface CompilerOptions { - allowNonTsExtensions?: boolean; - charset?: string; - declaration?: boolean; - diagnostics?: boolean; - emitBOM?: boolean; - help?: boolean; - init?: boolean; - inlineSourceMap?: boolean; - inlineSources?: boolean; - jsx?: JsxEmit; - listFiles?: boolean; - locale?: string; - mapRoot?: string; - module?: ModuleKind; - newLine?: NewLineKind; - noEmit?: boolean; - noEmitHelpers?: boolean; - noEmitOnError?: boolean; - noErrorTruncation?: boolean; - noImplicitAny?: boolean; - noLib?: boolean; - noResolve?: boolean; - out?: string; - outFile?: string; - outDir?: string; - preserveConstEnums?: boolean; - project?: string; - removeComments?: boolean; - rootDir?: string; - sourceMap?: boolean; - sourceRoot?: string; - suppressExcessPropertyErrors?: boolean; - suppressImplicitAnyIndexErrors?: boolean; - target?: ScriptTarget; - version?: boolean; - watch?: boolean; - isolatedModules?: boolean; - experimentalDecorators?: boolean; - experimentalAsyncFunctions?: boolean; - emitDecoratorMetadata?: boolean; - moduleResolution?: ModuleResolutionKind; - [option: string]: string | number | boolean; - } - const enum ModuleKind { - None = 0, - CommonJS = 1, - AMD = 2, - UMD = 3, - System = 4, - } - const enum JsxEmit { - None = 0, - Preserve = 1, - React = 2, - } - const enum NewLineKind { - CarriageReturnLineFeed = 0, - LineFeed = 1, - } - interface LineAndCharacter { - line: number; - character: number; - } - const enum ScriptTarget { - ES3 = 0, - ES5 = 1, - ES6 = 2, - Latest = 2, - } - const enum LanguageVariant { - Standard = 0, - JSX = 1, - } - interface ParsedCommandLine { - options: CompilerOptions; - fileNames: string[]; - errors: Diagnostic[]; - } - interface ModuleResolutionHost { - fileExists(fileName: string): boolean; - readFile(fileName: string): string; - } - interface ResolvedModule { - resolvedFileName: string; - isExternalLibraryImport?: boolean; - } - interface ResolvedModuleWithFailedLookupLocations { - resolvedModule: ResolvedModule; - failedLookupLocations: string[]; - } - interface CompilerHost extends ModuleResolutionHost { - getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile; - getCancellationToken?(): CancellationToken; - getDefaultLibFileName(options: CompilerOptions): string; - writeFile: WriteFileCallback; - getCurrentDirectory(): string; - getCanonicalFileName(fileName: string): string; - useCaseSensitiveFileNames(): boolean; - getNewLine(): string; - resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[]; - } - interface TextSpan { - start: number; - length: number; - } - interface TextChangeRange { - span: TextSpan; - newLength: number; - } -} -declare namespace ts { - interface System { - args: string[]; - newLine: string; - useCaseSensitiveFileNames: boolean; - write(s: string): void; - readFile(path: string, encoding?: string): string; - writeFile(path: string, data: string, writeByteOrderMark?: boolean): void; - watchFile?(path: string, callback: (path: string) => void): FileWatcher; - resolvePath(path: string): string; - fileExists(path: string): boolean; - directoryExists(path: string): boolean; - createDirectory(path: string): void; - getExecutingFilePath(): string; - getCurrentDirectory(): string; - readDirectory(path: string, extension?: string, exclude?: string[]): string[]; - getMemoryUsage?(): number; - exit(exitCode?: number): void; - } - interface FileWatcher { - close(): void; - } - var sys: System; -} -declare namespace ts { - interface ErrorCallback { - (message: DiagnosticMessage, length: number): void; - } - interface Scanner { - getStartPos(): number; - getToken(): SyntaxKind; - getTextPos(): number; - getTokenPos(): number; - getTokenText(): string; - getTokenValue(): string; - hasExtendedUnicodeEscape(): boolean; - hasPrecedingLineBreak(): boolean; - isIdentifier(): boolean; - isReservedWord(): boolean; - isUnterminated(): boolean; - reScanGreaterToken(): SyntaxKind; - reScanSlashToken(): SyntaxKind; - reScanTemplateToken(): SyntaxKind; - scanJsxIdentifier(): SyntaxKind; - reScanJsxToken(): SyntaxKind; - scanJsxToken(): SyntaxKind; - scan(): SyntaxKind; - setText(text: string, start?: number, length?: number): void; - setOnError(onError: ErrorCallback): void; - setScriptTarget(scriptTarget: ScriptTarget): void; - setLanguageVariant(variant: LanguageVariant): void; - setTextPos(textPos: number): void; - lookAhead(callback: () => T): T; - tryScan(callback: () => T): T; - } - function tokenToString(t: SyntaxKind): string; - function getPositionOfLineAndCharacter(sourceFile: SourceFile, line: number, character: number): number; - function getLineAndCharacterOfPosition(sourceFile: SourceFile, position: number): LineAndCharacter; - function isWhiteSpace(ch: number): boolean; - function isLineBreak(ch: number): boolean; - function couldStartTrivia(text: string, pos: number): boolean; - function getLeadingCommentRanges(text: string, pos: number): CommentRange[]; - function getTrailingCommentRanges(text: string, pos: number): CommentRange[]; - /** Optionally, get the shebang */ - function getShebang(text: string): string; - function isIdentifierStart(ch: number, languageVersion: ScriptTarget): boolean; - function isIdentifierPart(ch: number, languageVersion: ScriptTarget): boolean; - function createScanner(languageVersion: ScriptTarget, skipTrivia: boolean, languageVariant?: LanguageVariant, text?: string, onError?: ErrorCallback, start?: number, length?: number): Scanner; -} -declare namespace ts { - function getDefaultLibFileName(options: CompilerOptions): string; - function textSpanEnd(span: TextSpan): number; - function textSpanIsEmpty(span: TextSpan): boolean; - function textSpanContainsPosition(span: TextSpan, position: number): boolean; - function textSpanContainsTextSpan(span: TextSpan, other: TextSpan): boolean; - function textSpanOverlapsWith(span: TextSpan, other: TextSpan): boolean; - function textSpanOverlap(span1: TextSpan, span2: TextSpan): TextSpan; - function textSpanIntersectsWithTextSpan(span: TextSpan, other: TextSpan): boolean; - function textSpanIntersectsWith(span: TextSpan, start: number, length: number): boolean; - function decodedTextSpanIntersectsWith(start1: number, length1: number, start2: number, length2: number): boolean; - function textSpanIntersectsWithPosition(span: TextSpan, position: number): boolean; - function textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan; - function createTextSpan(start: number, length: number): TextSpan; - function createTextSpanFromBounds(start: number, end: number): TextSpan; - function textChangeRangeNewSpan(range: TextChangeRange): TextSpan; - function textChangeRangeIsUnchanged(range: TextChangeRange): boolean; - function createTextChangeRange(span: TextSpan, newLength: number): TextChangeRange; - let unchangedTextChangeRange: TextChangeRange; - /** - * Called to merge all the changes that occurred across several versions of a script snapshot - * into a single change. i.e. if a user keeps making successive edits to a script we will - * have a text change from V1 to V2, V2 to V3, ..., Vn. - * - * This function will then merge those changes into a single change range valid between V1 and - * Vn. - */ - function collapseTextChangeRangesAcrossMultipleVersions(changes: TextChangeRange[]): TextChangeRange; - function getTypeParameterOwner(d: Declaration): Declaration; -} -declare namespace ts { - function getNodeConstructor(kind: SyntaxKind): new () => Node; - function createNode(kind: SyntaxKind): Node; - function forEachChild(node: Node, cbNode: (node: Node) => T, cbNodeArray?: (nodes: Node[]) => T): T; - function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes?: boolean): SourceFile; - function updateSourceFile(sourceFile: SourceFile, newText: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; -} -declare namespace ts { - const version: string; - function findConfigFile(searchPath: string): string; - function resolveTripleslashReference(moduleName: string, containingFile: string): string; - function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations; - function nodeModuleNameResolver(moduleName: string, containingFile: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations; - function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations; - function createCompilerHost(options: CompilerOptions, setParentNodes?: boolean): CompilerHost; - function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[]; - function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string; - function createProgram(rootNames: string[], options: CompilerOptions, host?: CompilerHost, oldProgram?: Program): Program; -} -declare namespace ts { - function parseCommandLine(commandLine: string[], readFile?: (path: string) => string): ParsedCommandLine; - /** - * Read tsconfig.json file - * @param fileName The path to the config file - */ - function readConfigFile(fileName: string): { - config?: any; - error?: Diagnostic; - }; - /** - * Parse the text of the tsconfig.json file - * @param fileName The path to the config file - * @param jsonText The text of the config file - */ - function parseConfigFileText(fileName: string, jsonText: string): { - config?: any; - error?: Diagnostic; - }; - /** - * Parse the contents of a config file (tsconfig.json). - * @param json The contents of the config file to parse - * @param basePath A root directory to resolve relative path entries in the config - * file to. e.g. outDir - */ - function parseConfigFile(json: any, host: ParseConfigHost, basePath: string): ParsedCommandLine; -} -declare namespace ts { - /** The version of the language service API */ - let servicesVersion: string; - interface Node { - getSourceFile(): SourceFile; - getChildCount(sourceFile?: SourceFile): number; - getChildAt(index: number, sourceFile?: SourceFile): Node; - getChildren(sourceFile?: SourceFile): Node[]; - getStart(sourceFile?: SourceFile): number; - getFullStart(): number; - getEnd(): number; - getWidth(sourceFile?: SourceFile): number; - getFullWidth(): number; - getLeadingTriviaWidth(sourceFile?: SourceFile): number; - getFullText(sourceFile?: SourceFile): string; - getText(sourceFile?: SourceFile): string; - getFirstToken(sourceFile?: SourceFile): Node; - getLastToken(sourceFile?: SourceFile): Node; - } - interface Symbol { - getFlags(): SymbolFlags; - getName(): string; - getDeclarations(): Declaration[]; - getDocumentationComment(): SymbolDisplayPart[]; - } - interface Type { - getFlags(): TypeFlags; - getSymbol(): Symbol; - getProperties(): Symbol[]; - getProperty(propertyName: string): Symbol; - getApparentProperties(): Symbol[]; - getCallSignatures(): Signature[]; - getConstructSignatures(): Signature[]; - getStringIndexType(): Type; - getNumberIndexType(): Type; - getBaseTypes(): ObjectType[]; - } - interface Signature { - getDeclaration(): SignatureDeclaration; - getTypeParameters(): Type[]; - getParameters(): Symbol[]; - getReturnType(): Type; - getDocumentationComment(): SymbolDisplayPart[]; - } - interface SourceFile { - getLineAndCharacterOfPosition(pos: number): LineAndCharacter; - getLineStarts(): number[]; - getPositionOfLineAndCharacter(line: number, character: number): number; - update(newText: string, textChangeRange: TextChangeRange): SourceFile; - } - /** - * Represents an immutable snapshot of a script at a specified time.Once acquired, the - * snapshot is observably immutable. i.e. the same calls with the same parameters will return - * the same values. - */ - interface IScriptSnapshot { - /** Gets a portion of the script snapshot specified by [start, end). */ - getText(start: number, end: number): string; - /** Gets the length of this script snapshot. */ - getLength(): number; - /** - * Gets the TextChangeRange that describe how the text changed between this text and - * an older version. This information is used by the incremental parser to determine - * what sections of the script need to be re-parsed. 'undefined' can be returned if the - * change range cannot be determined. However, in that case, incremental parsing will - * not happen and the entire document will be re - parsed. - */ - getChangeRange(oldSnapshot: IScriptSnapshot): TextChangeRange; - /** Releases all resources held by this script snapshot */ - dispose?(): void; - } - module ScriptSnapshot { - function fromString(text: string): IScriptSnapshot; - } - interface PreProcessedFileInfo { - referencedFiles: FileReference[]; - importedFiles: FileReference[]; - ambientExternalModules: string[]; - isLibFile: boolean; - } - interface HostCancellationToken { - isCancellationRequested(): boolean; - } - interface LanguageServiceHost { - getCompilationSettings(): CompilerOptions; - getNewLine?(): string; - getProjectVersion?(): string; - getScriptFileNames(): string[]; - getScriptVersion(fileName: string): string; - getScriptSnapshot(fileName: string): IScriptSnapshot; - getLocalizedDiagnosticMessages?(): any; - getCancellationToken?(): HostCancellationToken; - getCurrentDirectory(): string; - getDefaultLibFileName(options: CompilerOptions): string; - log?(s: string): void; - trace?(s: string): void; - error?(s: string): void; - useCaseSensitiveFileNames?(): boolean; - resolveModuleNames?(moduleNames: string[], containingFile: string): ResolvedModule[]; - } - interface LanguageService { - cleanupSemanticCache(): void; - getSyntacticDiagnostics(fileName: string): Diagnostic[]; - getSemanticDiagnostics(fileName: string): Diagnostic[]; - getCompilerOptionsDiagnostics(): Diagnostic[]; - /** - * @deprecated Use getEncodedSyntacticClassifications instead. - */ - getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; - /** - * @deprecated Use getEncodedSemanticClassifications instead. - */ - getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[]; - getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications; - getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications; - getCompletionsAtPosition(fileName: string, position: number): CompletionInfo; - getCompletionEntryDetails(fileName: string, position: number, entryName: string): CompletionEntryDetails; - getQuickInfoAtPosition(fileName: string, position: number): QuickInfo; - getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan; - getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan; - getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems; - getRenameInfo(fileName: string, position: number): RenameInfo; - findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; - getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; - getTypeDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; - getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; - findReferences(fileName: string, position: number): ReferencedSymbol[]; - getDocumentHighlights(fileName: string, position: number, filesToSearch: string[]): DocumentHighlights[]; - /** @deprecated */ - getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[]; - getNavigateToItems(searchValue: string, maxResultCount?: number): NavigateToItem[]; - getNavigationBarItems(fileName: string): NavigationBarItem[]; - getOutliningSpans(fileName: string): OutliningSpan[]; - getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[]; - getBraceMatchingAtPosition(fileName: string, position: number): TextSpan[]; - getIndentationAtPosition(fileName: string, position: number, options: EditorOptions): number; - getFormattingEditsForRange(fileName: string, start: number, end: number, options: FormatCodeOptions): TextChange[]; - getFormattingEditsForDocument(fileName: string, options: FormatCodeOptions): TextChange[]; - getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): TextChange[]; - getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion; - getEmitOutput(fileName: string): EmitOutput; - getProgram(): Program; - getSourceFile(fileName: string): SourceFile; - dispose(): void; - } - interface Classifications { - spans: number[]; - endOfLineState: EndOfLineState; - } - interface ClassifiedSpan { - textSpan: TextSpan; - classificationType: string; - } - interface NavigationBarItem { - text: string; - kind: string; - kindModifiers: string; - spans: TextSpan[]; - childItems: NavigationBarItem[]; - indent: number; - bolded: boolean; - grayed: boolean; - } - interface TodoCommentDescriptor { - text: string; - priority: number; - } - interface TodoComment { - descriptor: TodoCommentDescriptor; - message: string; - position: number; - } - class TextChange { - span: TextSpan; - newText: string; - } - interface TextInsertion { - newText: string; - /** The position in newText the caret should point to after the insertion. */ - caretOffset: number; - } - interface RenameLocation { - textSpan: TextSpan; - fileName: string; - } - interface ReferenceEntry { - textSpan: TextSpan; - fileName: string; - isWriteAccess: boolean; - } - interface DocumentHighlights { - fileName: string; - highlightSpans: HighlightSpan[]; - } - module HighlightSpanKind { - const none: string; - const definition: string; - const reference: string; - const writtenReference: string; - } - interface HighlightSpan { - fileName?: string; - textSpan: TextSpan; - kind: string; - } - interface NavigateToItem { - name: string; - kind: string; - kindModifiers: string; - matchKind: string; - isCaseSensitive: boolean; - fileName: string; - textSpan: TextSpan; - containerName: string; - containerKind: string; - } - interface EditorOptions { - IndentSize: number; - TabSize: number; - NewLineCharacter: string; - ConvertTabsToSpaces: boolean; - } - interface FormatCodeOptions extends EditorOptions { - InsertSpaceAfterCommaDelimiter: boolean; - InsertSpaceAfterSemicolonInForStatements: boolean; - InsertSpaceBeforeAndAfterBinaryOperators: boolean; - InsertSpaceAfterKeywordsInControlFlowStatements: boolean; - InsertSpaceAfterFunctionKeywordForAnonymousFunctions: boolean; - InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: boolean; - InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: boolean; - PlaceOpenBraceOnNewLineForFunctions: boolean; - PlaceOpenBraceOnNewLineForControlBlocks: boolean; - [s: string]: boolean | number | string; - } - interface DefinitionInfo { - fileName: string; - textSpan: TextSpan; - kind: string; - name: string; - containerKind: string; - containerName: string; - } - interface ReferencedSymbol { - definition: DefinitionInfo; - references: ReferenceEntry[]; - } - enum SymbolDisplayPartKind { - aliasName = 0, - className = 1, - enumName = 2, - fieldName = 3, - interfaceName = 4, - keyword = 5, - lineBreak = 6, - numericLiteral = 7, - stringLiteral = 8, - localName = 9, - methodName = 10, - moduleName = 11, - operator = 12, - parameterName = 13, - propertyName = 14, - punctuation = 15, - space = 16, - text = 17, - typeParameterName = 18, - enumMemberName = 19, - functionName = 20, - regularExpressionLiteral = 21, - } - interface SymbolDisplayPart { - text: string; - kind: string; - } - interface QuickInfo { - kind: string; - kindModifiers: string; - textSpan: TextSpan; - displayParts: SymbolDisplayPart[]; - documentation: SymbolDisplayPart[]; - } - interface RenameInfo { - canRename: boolean; - localizedErrorMessage: string; - displayName: string; - fullDisplayName: string; - kind: string; - kindModifiers: string; - triggerSpan: TextSpan; - } - interface SignatureHelpParameter { - name: string; - documentation: SymbolDisplayPart[]; - displayParts: SymbolDisplayPart[]; - isOptional: boolean; - } - /** - * Represents a single signature to show in signature help. - * The id is used for subsequent calls into the language service to ask questions about the - * signature help item in the context of any documents that have been updated. i.e. after - * an edit has happened, while signature help is still active, the host can ask important - * questions like 'what parameter is the user currently contained within?'. - */ - interface SignatureHelpItem { - isVariadic: boolean; - prefixDisplayParts: SymbolDisplayPart[]; - suffixDisplayParts: SymbolDisplayPart[]; - separatorDisplayParts: SymbolDisplayPart[]; - parameters: SignatureHelpParameter[]; - documentation: SymbolDisplayPart[]; - } - /** - * Represents a set of signature help items, and the preferred item that should be selected. - */ - interface SignatureHelpItems { - items: SignatureHelpItem[]; - applicableSpan: TextSpan; - selectedItemIndex: number; - argumentIndex: number; - argumentCount: number; - } - interface CompletionInfo { - isMemberCompletion: boolean; - isNewIdentifierLocation: boolean; - entries: CompletionEntry[]; - } - interface CompletionEntry { - name: string; - kind: string; - kindModifiers: string; - sortText: string; - } - interface CompletionEntryDetails { - name: string; - kind: string; - kindModifiers: string; - displayParts: SymbolDisplayPart[]; - documentation: SymbolDisplayPart[]; - } - interface OutliningSpan { - /** The span of the document to actually collapse. */ - textSpan: TextSpan; - /** The span of the document to display when the user hovers over the collapsed span. */ - hintSpan: TextSpan; - /** The text to display in the editor for the collapsed region. */ - bannerText: string; - /** - * Whether or not this region should be automatically collapsed when - * the 'Collapse to Definitions' command is invoked. - */ - autoCollapse: boolean; - } - interface EmitOutput { - outputFiles: OutputFile[]; - emitSkipped: boolean; - } - const enum OutputFileType { - JavaScript = 0, - SourceMap = 1, - Declaration = 2, - } - interface OutputFile { - name: string; - writeByteOrderMark: boolean; - text: string; - } - const enum EndOfLineState { - None = 0, - InMultiLineCommentTrivia = 1, - InSingleQuoteStringLiteral = 2, - InDoubleQuoteStringLiteral = 3, - InTemplateHeadOrNoSubstitutionTemplate = 4, - InTemplateMiddleOrTail = 5, - InTemplateSubstitutionPosition = 6, - } - enum TokenClass { - Punctuation = 0, - Keyword = 1, - Operator = 2, - Comment = 3, - Whitespace = 4, - Identifier = 5, - NumberLiteral = 6, - StringLiteral = 7, - RegExpLiteral = 8, - } - interface ClassificationResult { - finalLexState: EndOfLineState; - entries: ClassificationInfo[]; - } - interface ClassificationInfo { - length: number; - classification: TokenClass; - } - interface Classifier { - /** - * Gives lexical classifications of tokens on a line without any syntactic context. - * For instance, a token consisting of the text 'string' can be either an identifier - * named 'string' or the keyword 'string', however, because this classifier is not aware, - * it relies on certain heuristics to give acceptable results. For classifications where - * speed trumps accuracy, this function is preferable; however, for true accuracy, the - * syntactic classifier is ideal. In fact, in certain editing scenarios, combining the - * lexical, syntactic, and semantic classifiers may issue the best user experience. - * - * @param text The text of a line to classify. - * @param lexState The state of the lexical classifier at the end of the previous line. - * @param syntacticClassifierAbsent Whether the client is *not* using a syntactic classifier. - * If there is no syntactic classifier (syntacticClassifierAbsent=true), - * certain heuristics may be used in its place; however, if there is a - * syntactic classifier (syntacticClassifierAbsent=false), certain - * classifications which may be incorrectly categorized will be given - * back as Identifiers in order to allow the syntactic classifier to - * subsume the classification. - * @deprecated Use getLexicalClassifications instead. - */ - getClassificationsForLine(text: string, lexState: EndOfLineState, syntacticClassifierAbsent: boolean): ClassificationResult; - getEncodedLexicalClassifications(text: string, endOfLineState: EndOfLineState, syntacticClassifierAbsent: boolean): Classifications; - } - /** - * The document registry represents a store of SourceFile objects that can be shared between - * multiple LanguageService instances. A LanguageService instance holds on the SourceFile (AST) - * of files in the context. - * SourceFile objects account for most of the memory usage by the language service. Sharing - * the same DocumentRegistry instance between different instances of LanguageService allow - * for more efficient memory utilization since all projects will share at least the library - * file (lib.d.ts). - * - * A more advanced use of the document registry is to serialize sourceFile objects to disk - * and re-hydrate them when needed. - * - * To create a default DocumentRegistry, use createDocumentRegistry to create one, and pass it - * to all subsequent createLanguageService calls. - */ - interface DocumentRegistry { - /** - * Request a stored SourceFile with a given fileName and compilationSettings. - * The first call to acquire will call createLanguageServiceSourceFile to generate - * the SourceFile if was not found in the registry. - * - * @param fileName The name of the file requested - * @param compilationSettings Some compilation settings like target affects the - * shape of a the resulting SourceFile. This allows the DocumentRegistry to store - * multiple copies of the same file for different compilation settings. - * @parm scriptSnapshot Text of the file. Only used if the file was not found - * in the registry and a new one was created. - * @parm version Current version of the file. Only used if the file was not found - * in the registry and a new one was created. - */ - acquireDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile; - /** - * Request an updated version of an already existing SourceFile with a given fileName - * and compilationSettings. The update will in-turn call updateLanguageServiceSourceFile - * to get an updated SourceFile. - * - * @param fileName The name of the file requested - * @param compilationSettings Some compilation settings like target affects the - * shape of a the resulting SourceFile. This allows the DocumentRegistry to store - * multiple copies of the same file for different compilation settings. - * @param scriptSnapshot Text of the file. - * @param version Current version of the file. - */ - updateDocument(fileName: string, compilationSettings: CompilerOptions, scriptSnapshot: IScriptSnapshot, version: string): SourceFile; - /** - * Informs the DocumentRegistry that a file is not needed any longer. - * - * Note: It is not allowed to call release on a SourceFile that was not acquired from - * this registry originally. - * - * @param fileName The name of the file to be released - * @param compilationSettings The compilation settings used to acquire the file - */ - releaseDocument(fileName: string, compilationSettings: CompilerOptions): void; - reportStats(): string; - } - module ScriptElementKind { - const unknown: string; - const warning: string; - const keyword: string; - const scriptElement: string; - const moduleElement: string; - const classElement: string; - const localClassElement: string; - const interfaceElement: string; - const typeElement: string; - const enumElement: string; - const variableElement: string; - const localVariableElement: string; - const functionElement: string; - const localFunctionElement: string; - const memberFunctionElement: string; - const memberGetAccessorElement: string; - const memberSetAccessorElement: string; - const memberVariableElement: string; - const constructorImplementationElement: string; - const callSignatureElement: string; - const indexSignatureElement: string; - const constructSignatureElement: string; - const parameterElement: string; - const typeParameterElement: string; - const primitiveType: string; - const label: string; - const alias: string; - const constElement: string; - const letElement: string; - } - module ScriptElementKindModifier { - const none: string; - const publicMemberModifier: string; - const privateMemberModifier: string; - const protectedMemberModifier: string; - const exportedModifier: string; - const ambientModifier: string; - const staticModifier: string; - const abstractModifier: string; - } - class ClassificationTypeNames { - static comment: string; - static identifier: string; - static keyword: string; - static numericLiteral: string; - static operator: string; - static stringLiteral: string; - static whiteSpace: string; - static text: string; - static punctuation: string; - static className: string; - static enumName: string; - static interfaceName: string; - static moduleName: string; - static typeParameterName: string; - static typeAliasName: string; - static parameterName: string; - static docCommentTagName: string; - } - const enum ClassificationType { - comment = 1, - identifier = 2, - keyword = 3, - numericLiteral = 4, - operator = 5, - stringLiteral = 6, - regularExpressionLiteral = 7, - whiteSpace = 8, - text = 9, - punctuation = 10, - className = 11, - enumName = 12, - interfaceName = 13, - moduleName = 14, - typeParameterName = 15, - typeAliasName = 16, - parameterName = 17, - docCommentTagName = 18, - } - interface DisplayPartsSymbolWriter extends SymbolWriter { - displayParts(): SymbolDisplayPart[]; - } - function displayPartsToString(displayParts: SymbolDisplayPart[]): string; - function getDefaultCompilerOptions(): CompilerOptions; - interface TranspileOptions { - compilerOptions?: CompilerOptions; - fileName?: string; - reportDiagnostics?: boolean; - moduleName?: string; - renamedDependencies?: Map; - } - interface TranspileOutput { - outputText: string; - diagnostics?: Diagnostic[]; - sourceMapText?: string; - } - function transpileModule(input: string, transpileOptions: TranspileOptions): TranspileOutput; - function transpile(input: string, compilerOptions?: CompilerOptions, fileName?: string, diagnostics?: Diagnostic[], moduleName?: string): string; - function createLanguageServiceSourceFile(fileName: string, scriptSnapshot: IScriptSnapshot, scriptTarget: ScriptTarget, version: string, setNodeParents: boolean): SourceFile; - let disableIncrementalParsing: boolean; - function updateLanguageServiceSourceFile(sourceFile: SourceFile, scriptSnapshot: IScriptSnapshot, version: string, textChangeRange: TextChangeRange, aggressiveChecks?: boolean): SourceFile; - function createGetCanonicalFileName(useCaseSensitivefileNames: boolean): (fileName: string) => string; - function createDocumentRegistry(useCaseSensitiveFileNames?: boolean): DocumentRegistry; - function preProcessFile(sourceText: string, readImportFiles?: boolean): PreProcessedFileInfo; - function createLanguageService(host: LanguageServiceHost, documentRegistry?: DocumentRegistry): LanguageService; - function createClassifier(): Classifier; - /** - * Get the path of the default library files (lib.d.ts) as distributed with the typescript - * node package. - * The functionality is not supported if the ts module is consumed outside of a node module. - */ - function getDefaultLibFilePath(options: CompilerOptions): string; -} diff --git a/typings/underscore.string/underscore.string.d.ts b/typings/underscore.string/underscore.string.d.ts new file mode 100644 index 00000000000..1b08dcf852d --- /dev/null +++ b/typings/underscore.string/underscore.string.d.ts @@ -0,0 +1,573 @@ +// Type definitions for underscore.string +// Project: https://github.com/epeli/underscore.string +// Definitions by: Ry Racherbaumer +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/// + +interface UnderscoreStatic { + str: UnderscoreStringStatic; + string: UnderscoreStringStatic; +} + +declare var s : UnderscoreStringStatic; + +interface UnderscoreStringStatic extends UnderscoreStringStaticExports { + /** + * Tests if string contains a substring. + * ('foobar', 'ob') => true + * @param str + * @param needle + */ + include(str: string, needle: string): boolean; + + /** + * Tests if string contains a substring. + * ('foobar', 'ob') => true + * @param str + * @param needle + */ + contains(str: string, needle: string): boolean; + + /** + * Return reversed string. + * ('foobar') => 'raboof' + * @param str + */ + reverse(str: string): string; +} + +/** + * Functions exported for mixing with underscore object. + * + * Usage: + * _.mixin(_.string.exports()); + * interface UnderscoreStatic extends UnderscoreStringStaticExports { } + */ +interface UnderscoreStringStaticExports { + + exports(): UnderscoreStringStaticExports; + + /** + * Determine if a string is 'blank.' + * @param str + */ + isBlank(str: string): boolean; + + /** + * Removes all html tags from string. + * @param str + */ + stripTags(str: string): string; + + /** + * Converts first letter of the string to uppercase. + * ('foo Bar') => 'Foo Bar' + * @param str + */ + capitalize(str: string): string; + + /** + * Chop a string into pieces. + * ('whitespace', 3) => ['whi','tes','pac','e'] + * @param str String to chop + * @param step Size of the pieces + */ + chop(str: string, step: number): any[]; + + /** + * Compress some whitespaces to one. + * (' foo bar ') => 'foo bar' + * @param str + */ + clean(str: string): string; + + /** + * Count occurences of a sub string. + * ('Hello world', 'l') => 3 + * @param str + * @param substr + */ + count(str: string, substr: string): number; + + /** + * Convert string to an array of characters. + * ('Hello') => ['H','e','l','l','o'] + * @param str + */ + chars(str: string): any[]; + + /** + * Returns a copy of the string in which all the case-based characters have had their case swapped. + * ('hELLO') => 'Hello' + * @param str + */ + swapCase(str: string): string; + + /** + * Converts HTML special characters to their entity equivalents. + * ('
Blah blah blah
') => '<div>Blah blah blah</div>' + * @param str + */ + escapeHTML(str: string): string; + + /** + * Converts entity characters to HTML equivalents. + * ('<div>Blah blah blah</div>') => '
Blah blah blah
' + * @param str + */ + unescapeHTML(str: string): string; + + /** + * Escape a string for use in a regular expression. + * @param str + */ + escapeRegExp(str: string): string; + + /** + * Splice a string like an array. + * @param str + * @param i + * @param howmany + * @param substr + */ + splice(str: string, i: number, howmany: number, substr?: string): string; + + /** + * Insert a string at index. + * @param str + * @param i + * @param substr + */ + insert(str: string, i: number, substr: string): string; + + /** + * Joins strings together with given separator. + * (' ', 'foo', 'bar') => 'foo bar' + * @param separator + * @param args + */ + join(separator: string, ...args: string[]): string; + + /** + * Split string by newlines character. + * ('Hello\nWorld') => ['Hello', 'World'] + * @param str + */ + lines(str: string): any[]; + + /** + * Checks if string starts with another string. + * ('image.gif', 'image') => true + * @param str + * @param starts + */ + startsWith(str: string, starts: string): boolean; + + /** + * Checks if string ends with another string. + * ('image.gif', 'gif') => true + * @param value + * @param starts + */ + endsWith(value: string, starts: string): boolean; + + /** + * Returns the successor to passed string. + * ('a') => 'b' + * @param str + */ + succ(str: string): string; + + /** + * Capitalize first letter of every word in the string. + * ('my name is epeli') => 'My Name Is Epeli' + * @param str + */ + titleize(str: string): string; + + /** + * Converts underscored or dasherized string to a camelized one. + * ('-moz-transform') => 'MozTransform' + * @param str + */ + camelize(str: string): string; + + /** + * Converts a camelized or dasherized string into an underscored one. + * ('MozTransform') => 'moz_transform' + * @param str + */ + underscored(str: string): string; + + /** + * Converts a underscored or camelized string into an dasherized one. + * ('MozTransform') => '-moz-transform' + * @param str + */ + dasherize(str: string): string; + + /** + * Converts string to camelized class name. + * ('some_class_name') => 'SomeClassName' + * @param str + */ + classify(str: string): string; + + /** + * Converts an underscored, camelized, or dasherized string into a humanized one. + * Also removes beginning and ending whitespace, and removes the postfix '_id'. + * (' capitalize dash-CamelCase_underscore trim ') => 'Capitalize dash camel case underscore trim' + * @param str + */ + humanize(str: string): string; + + /** + * Trims defined characters from begining and ending of the string. + * Defaults to whitespace characters. + * (' foobar ') => 'foobar' + * ('_-foobar-_', '_-') => 'foobar' + * @param str + * @param characters + */ + trim(str: string, characters?: string): string; + + /** + * Trims defined characters from begining and ending of the string. + * Defaults to whitespace characters. + * (' foobar ') => 'foobar' + * ('_-foobar-_', '_-') => 'foobar' + * @param str + * @param characters + */ + strip(str: string, characters?: string): string; + + /** + * Left trim. Similar to trim, but only for left side. + * @param str + * @param characters + */ + ltrim(str: string, characters?: string): string; + + /** + * Left trim. Similar to trim, but only for left side. + * @param str + * @param characters + */ + lstrip(str: string, characters?: string): string; + + /** + * Right trim. Similar to trim, but only for right side. + * @param str + * @param characters + */ + rtrim(str: string, characters?: string): string; + + /** + * Right trim. Similar to trim, but only for right side. + * @param str + * @param characters + */ + rstrip(str: string, characters?: string): string; + + /** + * Truncate string to specified length. + * ('Hello world').truncate(5) => 'Hello...' + * ('Hello').truncate(10) => 'Hello' + * @param str + * @param length + * @param truncateStr + */ + truncate(str: string, length: number, truncateStr?: string): string; + + /** + * Elegant version of truncate. + * Makes sure the pruned string does not exceed the original length. + * Avoid half-chopped words when truncating. + * ('Hello, cruel world', 15) => 'Hello, cruel...' + * @param str + * @param length + * @param pruneStr + */ + prune(str: string, length: number, pruneStr?: string): string; + + /** + * Split string by delimiter (String or RegExp). + * /\s+/ by default. + * (' I love you ') => ['I','love','you'] + * ('I_love_you', '_') => ['I','love','you'] + * @param str + * @param delimiter + */ + words(str: string): string[]; + + /** + * Split string by delimiter (String or RegExp). + * /\s+/ by default. + * (' I love you ') => ['I','love','you'] + * ('I_love_you', '_') => ['I','love','you'] + * @param str + * @param delimiter + */ + words(str: string, delimiter: string): string[]; + + /** + * Split string by delimiter (String or RegExp). + * /\s+/ by default. + * (' I love you ') => ['I','love','you'] + * ('I_love_you', '_') => ['I','love','you'] + * @param str + * @param delimiter + */ + words(str: string, delimiter: RegExp): string[]; + + /** + * Pads a string with characters until the total string length is equal to the passed length parameter. + * By default, pads on the left with the space char (' '). + * padStr is truncated to a single character if necessary. + * ('1', 8) => ' 1' + * ('1', 8, '0') => '00000001' + * ('1', 8, '0', 'right') => '10000000' + * ('1', 8, '0', 'both') => '00001000' + * ('1', 8, 'bleepblorp', 'both') => 'bbbb1bbb' + * @param str + * @param length + * @param padStr + * @param type + */ + pad(str: string, length: number, padStr?:string, type?: string): string; + + /** + * Left-pad a string. + * Alias for pad(str, length, padStr, 'left') + * ('1', 8, '0') => '00000001' + * @param str + * @param length + * @param padStr + */ + lpad(str: string, length: number, padStr?: string): string; + + /** + * Left-pad a string. + * Alias for pad(str, length, padStr, 'left') + * ('1', 8, '0') => '00000001' + * @param str + * @param length + * @param padStr + */ + rjust(str: string, length: number, padStr?: string): string; + + /** + * Right-pad a string. + * Alias for pad(str, length, padStr, 'right') + * ('1', 8, '0') => '10000000' + * @param str + * @param length + * @param padStr + */ + rpad(str: string, length: number, padStr?: string): string; + + /** + * Right-pad a string. + * Alias for pad(str, length, padStr, 'right') + * ('1', 8, '0') => '10000000' + * @param str + * @param length + * @param padStr + */ + ljust(str: string, length: number, padStr?: string): string; + + /** + * Left/right-pad a string. + * Alias for pad(str, length, padStr, 'both') + * ('1', 8, '0') => '00001000' + * @param str + * @param length + * @param padStr + */ + lrpad(str: string, length: number, padStr?: string): string; + + /** + * Left/right-pad a string. + * Alias for pad(str, length, padStr, 'both') + * ('1', 8, '0') => '00001000' + * @param str + * @param length + * @param padStr + */ + center(str: string, length: number, padStr?: string): string; + + /** + * C like string formatting. + * _.sprintf('%.1f', 1.17) => '1.2' + * @param format + * @param args + */ + sprintf(format: string, ...args: any[]): string; + + /** + * Parse string to number. + * Returns NaN if string can't be parsed to number. + * ('2.556').toNumber() => 3 + * ('2.556').toNumber(1) => 2.6 + * @param str + * @param decimals + */ + toNumber(str: string, decimals?: number): number; + + /** + * Formats the numbers. + * (1000, 2) => '1,000.00' + * (123456789.123, 5, '.', ',') => '123,456,789.12300' + * @param number + * @param dec + * @param dsep + * @param tsep + */ + numberFormat(number: number, dec?: number, dsep?: string, tsep?: string): string; + + /** + * Searches a string from left to right for a pattern. + * Returns a substring consisting of the characters in the string that are to the right of the pattern. + * If no match found, returns entire string. + * ('This_is_a_test_string').strRight('_') => 'is_a_test_string' + * @param str + * @param sep + */ + strRight(str: string, sep: string): string; + + /** + * Searches a string from right to left for a pattern. + * Returns a substring consisting of the characters in the string that are to the right of the pattern. + * If no match found, returns entire string. + * ('This_is_a_test_string').strRightBack('_') => 'string' + * @param str + * @param sep + */ + strRightBack(str: string, sep: string): string; + + /** + * Searches a string from left to right for a pattern. + * Returns a substring consisting of the characters in the string that are to the left of the pattern. + * If no match found, returns entire string. + * ('This_is_a_test_string').strLeft('_') => 'This' + * @param str + * @param sep + */ + strLeft(str: string, sep: string): string; + + /** + * Searches a string from right to left for a pattern. + * Returns a substring consisting of the characters in the string that are to the left of the pattern. + * If no match found, returns entire string. + * ('This_is_a_test_string').strLeftBack('_') => 'This_is_a_test' + * @param str + * @param sep + */ + strLeftBack(str: string, sep: string): string; + + /** + * Join an array into a human readable sentence. + * (['jQuery', 'Mootools', 'Prototype']) => 'jQuery, Mootools and Prototype' + * (['jQuery', 'Mootools', 'Prototype'], ', ', ' unt ') => 'jQuery, Mootools unt Prototype' + * @param array + * @param separator + * @param lastSeparator + * @param serial + */ + toSentence(array: any[], separator?: string, lastSeparator?: string, serial?: boolean): string; + + /** + * The same as toSentence, but uses ', ' as default for lastSeparator. + * @param array + * @param separator + * @param lastSeparator + */ + toSentenceSerial(array: any[], separator?: string, lastSeparator?: string): string; + + /** + * Transform text into a URL slug. Replaces whitespaces, accentuated, and special characters with a dash. + * ('Un éléphant à l'orée du bois') => 'un-elephant-a-loree-du-bois' + * @param str + */ + slugify(str: string): string; + + /** + * Surround a string with another string. + * ('foo', 'ab') => 'abfooab' + * @param str + * @param wrapper + */ + surround(str: string, wrapper: string): string; + + /** + * Quotes a string. + * quoteChar defaults to " + * ('foo') => '"foo"' + * @param str + */ + quote(str: string, quoteChar?: string): string; + + /** + * Quotes a string. + * quoteChar defaults to " + * ('foo') => '"foo"' + * @param str + */ + q(str: string, quoteChar?: string): string; + + /** + * Unquotes a string. + * quoteChar defaults to " + * ('"foo"') => 'foo' + * ("'foo'", "'") => 'foo' + * @param str + */ + unquote(str: string, quoteChar?: string): string; + + /** + * Repeat a string with an optional separator. + * ('foo', 3) => 'foofoofoo' + * ('foo', 3, 'bar') => 'foobarfoobarfoo' + * @param value + * @param count + * @param separator + */ + repeat(value: string, count: number, separator?:string): string; + + /** + * Naturally sort strings like humans would do. + * Caution: this function is charset dependent. + * @param str1 + * @param str2 + */ + naturalCmp(str1: string, str2: string): number; + + /** + * Calculates Levenshtein distance between two strings. + * ('kitten', 'kittah') => 2 + * @param str1 + * @param str2 + */ + levenshtein(str1: string, str2: string): number; + + /** + * Turn strings that can be commonly considered as booleans to real booleans. + * Such as "true", "false", "1" and "0". This function is case insensitive. + * ('true') => true + * ('FALSE') => false + * ('random') => undefined + * ('truthy', ['truthy'], ['falsy']) => true + * ('true only at start', [/^true/]) => true + * @param str + * @param trueValues + * @param falseValues + */ + toBoolean(str: string, trueValues?: any[], falseValues?: any[]): boolean; + +} +declare module 'underscore.string' { + var underscoreString: UnderscoreStringStatic; + export = underscoreString; +} +// TODO interface UnderscoreString extends Underscore diff --git a/typings/underscore/underscore.d.ts b/typings/underscore/underscore.d.ts new file mode 100644 index 00000000000..7dea66a84ac --- /dev/null +++ b/typings/underscore/underscore.d.ts @@ -0,0 +1,3413 @@ +// Type definitions for Underscore 1.7.0 +// Project: http://underscorejs.org/ +// Definitions by: Boris Yankov , Josh Baldwin +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +declare module _ { + /** + * underscore.js _.throttle options. + **/ + interface ThrottleSettings { + + /** + * If you'd like to disable the leading-edge call, pass this as false. + **/ + leading?: boolean; + + /** + * If you'd like to disable the execution on the trailing-edge, pass false. + **/ + trailing?: boolean; + } + + /** + * underscore.js template settings, set templateSettings or pass as an argument + * to 'template()' to override defaults. + **/ + interface TemplateSettings { + /** + * Default value is '/<%([\s\S]+?)%>/g'. + **/ + evaluate?: RegExp; + + /** + * Default value is '/<%=([\s\S]+?)%>/g'. + **/ + interpolate?: RegExp; + + /** + * Default value is '/<%-([\s\S]+?)%>/g'. + **/ + escape?: RegExp; + } + + interface Collection { } + + // Common interface between Arrays and jQuery objects + interface List extends Collection { + [index: number]: T; + length: number; + } + + interface Dictionary extends Collection { + [index: string]: T; + } + + interface ListIterator { + (value: T, index: number, list: List): TResult; + } + + interface ObjectIterator { + (element: T, key: string, list: Dictionary): TResult; + } + + interface MemoIterator { + (prev: TResult, curr: T, index: number, list: List): TResult; + } + + interface MemoObjectIterator { + (prev: TResult, curr: T, key: string, list: Dictionary): TResult; + } +} + +interface UnderscoreStatic { + /** + * Underscore OOP Wrapper, all Underscore functions that take an object + * as the first parameter can be invoked through this function. + * @param key First argument to Underscore object functions. + **/ + (value: Array): Underscore; + (value: T): Underscore; + + /* ************* + * Collections * + ************* */ + + /** + * Iterates over a list of elements, yielding each in turn to an iterator function. The iterator is + * bound to the context object, if one is passed. Each invocation of iterator is called with three + * arguments: (element, index, list). If list is a JavaScript object, iterator's arguments will be + * (value, key, object). Delegates to the native forEach function if it exists. + * @param list Iterates over this list of elements. + * @param iterator Iterator function for each element `list`. + * @param context 'this' object in `iterator`, optional. + **/ + each( + list: _.List, + iterator: _.ListIterator, + context?: any): _.List; + + /** + * @see _.each + * @param object Iterates over properties of this object. + * @param iterator Iterator function for each property on `object`. + * @param context 'this' object in `iterator`, optional. + **/ + each( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): _.Dictionary; + + /** + * @see _.each + **/ + forEach( + list: _.List, + iterator: _.ListIterator, + context?: any): _.List; + + /** + * @see _.each + **/ + forEach( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): _.Dictionary; + + /** + * Produces a new array of values by mapping each value in list through a transformation function + * (iterator). If the native map method exists, it will be used instead. If list is a JavaScript + * object, iterator's arguments will be (value, key, object). + * @param list Maps the elements of this array. + * @param iterator Map iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return The mapped array result. + **/ + map( + list: _.List, + iterator: _.ListIterator, + context?: any): TResult[]; + + /** + * @see _.map + * @param object Maps the properties of this object. + * @param iterator Map iterator function for each property on `object`. + * @param context `this` object in `iterator`, optional. + * @return The mapped object result. + **/ + map( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): TResult[]; + + /** + * @see _.map + **/ + collect( + list: _.List, + iterator: _.ListIterator, + context?: any): TResult[]; + + /** + * @see _.map + **/ + collect( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): TResult[]; + + /** + * Also known as inject and foldl, reduce boils down a list of values into a single value. + * Memo is the initial state of the reduction, and each successive step of it should be + * returned by iterator. The iterator is passed four arguments: the memo, then the value + * and index (or key) of the iteration, and finally a reference to the entire list. + * @param list Reduces the elements of this array. + * @param iterator Reduce iterator function for each element in `list`. + * @param memo Initial reduce state. + * @param context `this` object in `iterator`, optional. + * @return Reduced object result. + **/ + reduce( + list: _.Collection, + iterator: _.MemoIterator, + memo?: TResult, + context?: any): TResult; + + reduce( + list: _.Dictionary, + iterator: _.MemoObjectIterator, + memo?: TResult, + context?: any): TResult; + + /** + * @see _.reduce + **/ + inject( + list: _.Collection, + iterator: _.MemoIterator, + memo?: TResult, + context?: any): TResult; + + /** + * @see _.reduce + **/ + foldl( + list: _.Collection, + iterator: _.MemoIterator, + memo?: TResult, + context?: any): TResult; + + /** + * The right-associative version of reduce. Delegates to the JavaScript 1.8 version of + * reduceRight, if it exists. `foldr` is not as useful in JavaScript as it would be in a + * language with lazy evaluation. + * @param list Reduces the elements of this array. + * @param iterator Reduce iterator function for each element in `list`. + * @param memo Initial reduce state. + * @param context `this` object in `iterator`, optional. + * @return Reduced object result. + **/ + reduceRight( + list: _.Collection, + iterator: _.MemoIterator, + memo?: TResult, + context?: any): TResult; + + /** + * @see _.reduceRight + **/ + foldr( + list: _.Collection, + iterator: _.MemoIterator, + memo?: TResult, + context?: any): TResult; + + /** + * Looks through each value in the list, returning the first one that passes a truth + * test (iterator). The function returns as soon as it finds an acceptable element, + * and doesn't traverse the entire list. + * @param list Searches for a value in this list. + * @param iterator Search iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return The first acceptable found element in `list`, if nothing is found undefined/null is returned. + **/ + find( + list: _.List, + iterator: _.ListIterator, + context?: any): T; + + /** + * @see _.find + **/ + find( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): T; + + /** + * @see _.find + **/ + detect( + list: _.List, + iterator: _.ListIterator, + context?: any): T; + + /** + * @see _.find + **/ + detect( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): T; + + /** + * Looks through each value in the list, returning the index of the first one that passes a truth + * test (iterator). The function returns as soon as it finds an acceptable element, + * and doesn't traverse the entire list. + * @param list Searches for a value in this list. + * @param iterator Search iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return The index of the first acceptable found element in `list`, if nothing is found -1 is returned. + **/ + findIndex( + list: _.List, + iterator: _.ListIterator, + context?: any): number; + + + /** + * Looks through each value in the list, returning an array of all the values that pass a truth + * test (iterator). Delegates to the native filter method, if it exists. + * @param list Filter elements out of this list. + * @param iterator Filter iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return The filtered list of elements. + **/ + filter( + list: _.List, + iterator: _.ListIterator, + context?: any): T[]; + + /** + * @see _.filter + **/ + filter( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): T[]; + + /** + * @see _.filter + **/ + select( + list: _.List, + iterator: _.ListIterator, + context?: any): T[]; + + /** + * @see _.filter + **/ + select( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): T[]; + + /** + * Looks through each value in the list, returning an array of all the values that contain all + * of the key-value pairs listed in properties. + * @param list List to match elements again `properties`. + * @param properties The properties to check for on each element within `list`. + * @return The elements within `list` that contain the required `properties`. + **/ + where( + list: _.List, + properties: U): T[]; + + /** + * Looks through the list and returns the first value that matches all of the key-value pairs listed in properties. + * @param list Search through this list's elements for the first object with all `properties`. + * @param properties Properties to look for on the elements within `list`. + * @return The first element in `list` that has all `properties`. + **/ + findWhere( + list: _.List, + properties: U): T; + + /** + * Returns the values in list without the elements that the truth test (iterator) passes. + * The opposite of filter. + * Return all the elements for which a truth test fails. + * @param list Reject elements within this list. + * @param iterator Reject iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return The rejected list of elements. + **/ + reject( + list: _.List, + iterator: _.ListIterator, + context?: any): T[]; + + /** + * @see _.reject + **/ + reject( + object: _.Dictionary, + iterator: _.ObjectIterator, + context?: any): T[]; + + /** + * Returns true if all of the values in the list pass the iterator truth test. Delegates to the + * native method every, if present. + * @param list Truth test against all elements within this list. + * @param iterator Trust test iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return True if all elements passed the truth test, otherwise false. + **/ + every( + list: _.List, + iterator?: _.ListIterator, + context?: any): boolean; + + /** + * @see _.every + **/ + every( + list: _.Dictionary, + iterator?: _.ObjectIterator, + context?: any): boolean; + + /** + * @see _.every + **/ + all( + list: _.List, + iterator?: _.ListIterator, + context?: any): boolean; + + /** + * @see _.every + **/ + all( + list: _.Dictionary, + iterator?: _.ObjectIterator, + context?: any): boolean; + + /** + * Returns true if any of the values in the list pass the iterator truth test. Short-circuits and + * stops traversing the list if a true element is found. Delegates to the native method some, if present. + * @param list Truth test against all elements within this list. + * @param iterator Trust test iterator function for each element in `list`. + * @param context `this` object in `iterator`, optional. + * @return True if any elements passed the truth test, otherwise false. + **/ + some( + list: _.List, + iterator?: _.ListIterator, + context?: any): boolean; + + /** + * @see _.some + **/ + some( + object: _.Dictionary, + iterator?: _.ObjectIterator, + context?: any): boolean; + + /** + * @see _.some + **/ + any( + list: _.List, + iterator?: _.ListIterator, + context?: any): boolean; + + /** + * @see _.some + **/ + any( + object: _.Dictionary, + iterator?: _.ObjectIterator, + context?: any): boolean; + + /** + * Returns true if the value is present in the list. Uses indexOf internally, + * if list is an Array. + * @param list Checks each element to see if `value` is present. + * @param value The value to check for within `list`. + * @return True if `value` is present in `list`, otherwise false. + **/ + contains( + list: _.List, + value: T): boolean; + + /** + * @see _.contains + **/ + contains( + object: _.Dictionary, + value: T): boolean; + + /** + * @see _.contains + **/ + include( + list: _.Collection, + value: T): boolean; + + /** + * @see _.contains + **/ + include( + object: _.Dictionary, + value: T): boolean; + + /** + * Calls the method named by methodName on each value in the list. Any extra arguments passed to + * invoke will be forwarded on to the method invocation. + * @param list The element's in this list will each have the method `methodName` invoked. + * @param methodName The method's name to call on each element within `list`. + * @param arguments Additional arguments to pass to the method `methodName`. + **/ + invoke( + list: _.List, + methodName: string, + ...arguments: any[]): any; + + /** + * A convenient version of what is perhaps the most common use-case for map: extracting a list of + * property values. + * @param list The list to pluck elements out of that have the property `propertyName`. + * @param propertyName The property to look for on each element within `list`. + * @return The list of elements within `list` that have the property `propertyName`. + **/ + pluck( + list: _.List, + propertyName: string): any[]; + + /** + * Returns the maximum value in list. + * @param list Finds the maximum value in this list. + * @return Maximum value in `list`. + **/ + max(list: _.List): number; + + /** + * Returns the maximum value in list. If iterator is passed, it will be used on each value to generate + * the criterion by which the value is ranked. + * @param list Finds the maximum value in this list. + * @param iterator Compares each element in `list` to find the maximum value. + * @param context `this` object in `iterator`, optional. + * @return The maximum element within `list`. + **/ + max( + list: _.List, + iterator?: _.ListIterator, + context?: any): T; + + /** + * Returns the minimum value in list. + * @param list Finds the minimum value in this list. + * @return Minimum value in `list`. + **/ + min(list: _.List): number; + + /** + * Returns the minimum value in list. If iterator is passed, it will be used on each value to generate + * the criterion by which the value is ranked. + * @param list Finds the minimum value in this list. + * @param iterator Compares each element in `list` to find the minimum value. + * @param context `this` object in `iterator`, optional. + * @return The minimum element within `list`. + **/ + min( + list: _.List, + iterator?: _.ListIterator, + context?: any): T; + + /** + * Returns a sorted copy of list, ranked in ascending order by the results of running each value + * through iterator. Iterator may also be the string name of the property to sort by (eg. length). + * @param list Sorts this list. + * @param iterator Sort iterator for each element within `list`. + * @param context `this` object in `iterator`, optional. + * @return A sorted copy of `list`. + **/ + sortBy( + list: _.List, + iterator?: _.ListIterator, + context?: any): T[]; + + /** + * @see _.sortBy + * @param iterator Sort iterator for each element within `list`. + **/ + sortBy( + list: _.List, + iterator: string, + context?: any): T[]; + + /** + * Splits a collection into sets, grouped by the result of running each value through iterator. + * If iterator is a string instead of a function, groups by the property named by iterator on + * each of the values. + * @param list Groups this list. + * @param iterator Group iterator for each element within `list`, return the key to group the element by. + * @param context `this` object in `iterator`, optional. + * @return An object with the group names as properties where each property contains the grouped elements from `list`. + **/ + groupBy( + list: _.List, + iterator?: _.ListIterator, + context?: any): _.Dictionary; + + /** + * @see _.groupBy + * @param iterator Property on each object to group them by. + **/ + groupBy( + list: _.List, + iterator: string, + context?: any): _.Dictionary; + + /** + * Given a `list`, and an `iterator` function that returns a key for each element in the list (or a property name), + * returns an object with an index of each item. Just like _.groupBy, but for when you know your keys are unique. + **/ + indexBy( + list: _.List, + iterator: _.ListIterator, + context?: any): _.Dictionary; + + /** + * @see _.indexBy + * @param iterator Property on each object to index them by. + **/ + indexBy( + list: _.List, + iterator: string, + context?: any): _.Dictionary; + + /** + * Sorts a list into groups and returns a count for the number of objects in each group. Similar + * to groupBy, but instead of returning a list of values, returns a count for the number of values + * in that group. + * @param list Group elements in this list and then count the number of elements in each group. + * @param iterator Group iterator for each element within `list`, return the key to group the element by. + * @param context `this` object in `iterator`, optional. + * @return An object with the group names as properties where each property contains the number of elements in that group. + **/ + countBy( + list: _.List, + iterator?: _.ListIterator, + context?: any): _.Dictionary; + + /** + * @see _.countBy + * @param iterator Function name + **/ + countBy( + list: _.List, + iterator: string, + context?: any): _.Dictionary; + + /** + * Returns a shuffled copy of the list, using a version of the Fisher-Yates shuffle. + * @param list List to shuffle. + * @return Shuffled copy of `list`. + **/ + shuffle(list: _.Collection): T[]; + + /** + * Produce a random sample from the `list`. Pass a number to return `n` random elements from the list. Otherwise a single random item will be returned. + * @param list List to sample. + * @return Random sample of `n` elements in `list`. + **/ + sample(list: _.Collection, n: number): T[]; + + /** + * @see _.sample + **/ + sample(list: _.Collection): T; + + /** + * Converts the list (anything that can be iterated over), into a real Array. Useful for transmuting + * the arguments object. + * @param list object to transform into an array. + * @return `list` as an array. + **/ + toArray(list: _.Collection): T[]; + + /** + * Return the number of values in the list. + * @param list Count the number of values/elements in this list. + * @return Number of values in `list`. + **/ + size(list: _.Collection): number; + + /** + * Split array into two arrays: + * one whose elements all satisfy predicate and one whose elements all do not satisfy predicate. + * @param array Array to split in two. + * @param iterator Filter iterator function for each element in `array`. + * @param context `this` object in `iterator`, optional. + * @return Array where Array[0] are the elements in `array` that satisfies the predicate, and Array[1] the elements that did not. + **/ + partition( + array: Array, + iterator: _.ListIterator, + context?: any): T[][]; + + /********* + * Arrays * + **********/ + + /** + * Returns the first element of an array. Passing n will return the first n elements of the array. + * @param array Retrieves the first element of this array. + * @return Returns the first element of `array`. + **/ + first(array: _.List): T; + + /** + * @see _.first + * @param n Return more than one element from `array`. + **/ + first( + array: _.List, + n: number): T[]; + + /** + * @see _.first + **/ + head(array: _.List): T; + + /** + * @see _.first + **/ + head( + array: _.List, + n: number): T[]; + + /** + * @see _.first + **/ + take(array: _.List): T; + + /** + * @see _.first + **/ + take( + array: _.List, + n: number): T[]; + + /** + * Returns everything but the last entry of the array. Especially useful on the arguments object. + * Pass n to exclude the last n elements from the result. + * @param array Retrieve all elements except the last `n`. + * @param n Leaves this many elements behind, optional. + * @return Returns everything but the last `n` elements of `array`. + **/ + initial( + array: _.List, + n?: number): T[]; + + /** + * Returns the last element of an array. Passing n will return the last n elements of the array. + * @param array Retrieves the last element of this array. + * @return Returns the last element of `array`. + **/ + last(array: _.List): T; + + /** + * @see _.last + * @param n Return more than one element from `array`. + **/ + last( + array: _.List, + n: number): T[]; + + /** + * Returns the rest of the elements in an array. Pass an index to return the values of the array + * from that index onward. + * @param array The array to retrieve all but the first `index` elements. + * @param n The index to start retrieving elements forward from, optional, default = 1. + * @return Returns the elements of `array` from `index` to the end of `array`. + **/ + rest( + array: _.List, + n?: number): T[]; + + /** + * @see _.rest + **/ + tail( + array: _.List, + n?: number): T[]; + + /** + * @see _.rest + **/ + drop( + array: _.List, + n?: number): T[]; + + /** + * Returns a copy of the array with all falsy values removed. In JavaScript, false, null, 0, "", + * undefined and NaN are all falsy. + * @param array Array to compact. + * @return Copy of `array` without false values. + **/ + compact(array: _.List): T[]; + + /** + * Flattens a nested array (the nesting can be to any depth). If you pass shallow, the array will + * only be flattened a single level. + * @param array The array to flatten. + * @param shallow If true then only flatten one level, optional, default = false. + * @return `array` flattened. + **/ + flatten( + array: _.List, + shallow?: boolean): any[]; + + /** + * Returns a copy of the array with all instances of the values removed. + * @param array The array to remove `values` from. + * @param values The values to remove from `array`. + * @return Copy of `array` without `values`. + **/ + without( + array: _.List, + ...values: T[]): T[]; + + /** + * Computes the union of the passed-in arrays: the list of unique items, in order, that are + * present in one or more of the arrays. + * @param arrays Array of arrays to compute the union of. + * @return The union of elements within `arrays`. + **/ + union(...arrays: _.List[]): T[]; + + /** + * Computes the list of values that are the intersection of all the arrays. Each value in the result + * is present in each of the arrays. + * @param arrays Array of arrays to compute the intersection of. + * @return The intersection of elements within `arrays`. + **/ + intersection(...arrays: _.List[]): T[]; + + /** + * Similar to without, but returns the values from array that are not present in the other arrays. + * @param array Keeps values that are within `others`. + * @param others The values to keep within `array`. + * @return Copy of `array` with only `others` values. + **/ + difference( + array: _.List, + ...others: _.List[]): T[]; + + /** + * Produces a duplicate-free version of the array, using === to test object equality. If you know in + * advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If + * you want to compute unique items based on a transformation, pass an iterator function. + * @param array Array to remove duplicates from. + * @param isSorted True if `array` is already sorted, optional, default = false. + * @param iterator Transform the elements of `array` before comparisons for uniqueness. + * @param context 'this' object in `iterator`, optional. + * @return Copy of `array` where all elements are unique. + **/ + uniq( + array: _.List, + isSorted?: boolean, + iterator?: _.ListIterator, + context?: any): T[]; + + /** + * @see _.uniq + **/ + uniq( + array: _.List, + iterator?: _.ListIterator, + context?: any): T[]; + + /** + * @see _.uniq + **/ + unique( + array: _.List, + iterator?: _.ListIterator, + context?: any): T[]; + + /** + * @see _.uniq + **/ + unique( + array: _.List, + isSorted?: boolean, + iterator?: _.ListIterator, + context?: any): T[]; + + + /** + * Merges together the values of each of the arrays with the values at the corresponding position. + * Useful when you have separate data sources that are coordinated through matching array indexes. + * If you're working with a matrix of nested arrays, zip.apply can transpose the matrix in a similar fashion. + * @param arrays The arrays to merge/zip. + * @return Zipped version of `arrays`. + **/ + zip(...arrays: any[][]): any[][]; + + /** + * @see _.zip + **/ + zip(...arrays: any[]): any[]; + + /** + * Converts arrays into objects. Pass either a single list of [key, value] pairs, or a + * list of keys, and a list of values. + * @param keys Key array. + * @param values Value array. + * @return An object containing the `keys` as properties and `values` as the property values. + **/ + object( + keys: _.List, + values: _.List): TResult; + + /** + * Converts arrays into objects. Pass either a single list of [key, value] pairs, or a + * list of keys, and a list of values. + * @param keyValuePairs Array of [key, value] pairs. + * @return An object containing the `keys` as properties and `values` as the property values. + **/ + object(...keyValuePairs: any[][]): TResult; + + /** + * @see _.object + **/ + object( + list: _.List, + values?: any): TResult; + + /** + * Returns the index at which value can be found in the array, or -1 if value is not present in the array. + * Uses the native indexOf function unless it's missing. If you're working with a large array, and you know + * that the array is already sorted, pass true for isSorted to use a faster binary search ... or, pass a number + * as the third argument in order to look for the first matching value in the array after the given index. + * @param array The array to search for the index of `value`. + * @param value The value to search for within `array`. + * @param isSorted True if the array is already sorted, optional, default = false. + * @return The index of `value` within `array`. + **/ + indexOf( + array: _.List, + value: T, + isSorted?: boolean): number; + + /** + * @see _indexof + **/ + indexOf( + array: _.List, + value: T, + startFrom: number): number; + + /** + * Returns the index of the last occurrence of value in the array, or -1 if value is not present. Uses the + * native lastIndexOf function if possible. Pass fromIndex to start your search at a given index. + * @param array The array to search for the last index of `value`. + * @param value The value to search for within `array`. + * @param from The starting index for the search, optional. + * @return The index of the last occurrence of `value` within `array`. + **/ + lastIndexOf( + array: _.List, + value: T, + from?: number): number; + + /** + * Uses a binary search to determine the index at which the value should be inserted into the list in order + * to maintain the list's sorted order. If an iterator is passed, it will be used to compute the sort ranking + * of each value, including the value you pass. + * @param list The sorted list. + * @param value The value to determine its index within `list`. + * @param iterator Iterator to compute the sort ranking of each value, optional. + * @return The index where `value` should be inserted into `list`. + **/ + sortedIndex( + list: _.List, + value: T, + iterator?: (x: T) => TSort, context?: any): number; + + /** + * A function to create flexibly-numbered lists of integers, handy for each and map loops. start, if omitted, + * defaults to 0; step defaults to 1. Returns a list of integers from start to stop, incremented (or decremented) + * by step, exclusive. + * @param start Start here. + * @param stop Stop here. + * @param step The number to count up by each iteration, optional, default = 1. + * @return Array of numbers from `start` to `stop` with increments of `step`. + **/ + + range( + start: number, + stop: number, + step?: number): number[]; + + /** + * @see _.range + * @param stop Stop here. + * @return Array of numbers from 0 to `stop` with increments of 1. + * @note If start is not specified the implementation will never pull the step (step = arguments[2] || 0) + **/ + range(stop: number): number[]; + + /************* + * Functions * + *************/ + + /** + * Bind a function to an object, meaning that whenever the function is called, the value of this will + * be the object. Optionally, bind arguments to the function to pre-fill them, also known as partial application. + * @param func The function to bind `this` to `object`. + * @param context The `this` pointer whenever `fn` is called. + * @param arguments Additional arguments to pass to `fn` when called. + * @return `fn` with `this` bound to `object`. + **/ + bind( + func: Function, + context: any, + ...arguments: any[]): () => any; + + /** + * Binds a number of methods on the object, specified by methodNames, to be run in the context of that object + * whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, + * which would otherwise be invoked with a fairly useless this. If no methodNames are provided, all of the + * object's function properties will be bound to it. + * @param object The object to bind the methods `methodName` to. + * @param methodNames The methods to bind to `object`, optional and if not provided all of `object`'s + * methods are bound. + **/ + bindAll( + object: any, + ...methodNames: string[]): any; + + /** + * Partially apply a function by filling in any number of its arguments, without changing its dynamic this value. + * A close cousin of bind. You may pass _ in your list of arguments to specify an argument that should not be + * pre-filled, but left open to supply at call-time. + * @param fn Function to partially fill in arguments. + * @param arguments The partial arguments. + * @return `fn` with partially filled in arguments. + **/ + partial( + fn: Function, + ...arguments: any[]): Function; + + /** + * Memoizes a given function by caching the computed result. Useful for speeding up slow-running computations. + * If passed an optional hashFunction, it will be used to compute the hash key for storing the result, based + * on the arguments to the original function. The default hashFunction just uses the first argument to the + * memoized function as the key. + * @param fn Computationally expensive function that will now memoized results. + * @param hashFn Hash function for storing the result of `fn`. + * @return Memoized version of `fn`. + **/ + memoize( + fn: Function, + hashFn?: (...args: any[]) => string): Function; + + /** + * Much like setTimeout, invokes function after wait milliseconds. If you pass the optional arguments, + * they will be forwarded on to the function when it is invoked. + * @param func Function to delay `waitMS` amount of ms. + * @param wait The amount of milliseconds to delay `fn`. + * @arguments Additional arguments to pass to `fn`. + **/ + delay( + func: Function, + wait: number, + ...arguments: any[]): any; + + /** + * @see _delay + **/ + delay( + func: Function, + ...arguments: any[]): any; + + /** + * Defers invoking the function until the current call stack has cleared, similar to using setTimeout + * with a delay of 0. Useful for performing expensive computations or HTML rendering in chunks without + * blocking the UI thread from updating. If you pass the optional arguments, they will be forwarded on + * to the function when it is invoked. + * @param fn The function to defer. + * @param arguments Additional arguments to pass to `fn`. + **/ + defer( + fn: Function, + ...arguments: any[]): void; + + /** + * Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, + * will only actually call the original function at most once per every wait milliseconds. Useful for + * rate-limiting events that occur faster than you can keep up with. + * By default, throttle will execute the function as soon as you call it for the first time, and, + * if you call it again any number of times during the wait period, as soon as that period is over. + * If you'd like to disable the leading-edge call, pass {leading: false}, and if you'd like to disable + * the execution on the trailing-edge, pass {trailing: false}. + * @param func Function to throttle `waitMS` ms. + * @param wait The number of milliseconds to wait before `fn` can be invoked again. + * @param options Allows for disabling execution of the throttled function on either the leading or trailing edge. + * @return `fn` with a throttle of `wait`. + **/ + throttle( + func: T, + wait: number, + options?: _.ThrottleSettings): T; + + /** + * Creates and returns a new debounced version of the passed function that will postpone its execution + * until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing + * behavior that should only happen after the input has stopped arriving. For example: rendering a preview + * of a Markdown comment, recalculating a layout after the window has stopped being resized, and so on. + * + * Pass true for the immediate parameter to cause debounce to trigger the function on the leading instead + * of the trailing edge of the wait interval. Useful in circumstances like preventing accidental double + *-clicks on a "submit" button from firing a second time. + * @param fn Function to debounce `waitMS` ms. + * @param wait The number of milliseconds to wait before `fn` can be invoked again. + * @param immediate True if `fn` should be invoked on the leading edge of `waitMS` instead of the trailing edge. + * @return Debounced version of `fn` that waits `wait` ms when invoked. + **/ + debounce( + fn: T, + wait: number, + immediate?: boolean): T; + + /** + * Creates a version of the function that can only be called one time. Repeated calls to the modified + * function will have no effect, returning the value from the original call. Useful for initialization + * functions, instead of having to set a boolean flag and then check it later. + * @param fn Function to only execute once. + * @return Copy of `fn` that can only be invoked once. + **/ + once(fn: T): T; + + /** + * Creates a version of the function that will only be run after first being called count times. Useful + * for grouping asynchronous responses, where you want to be sure that all the async calls have finished, + * before proceeding. + * @param number count Number of times to be called before actually executing. + * @param Function fn The function to defer execution `count` times. + * @return Copy of `fn` that will not execute until it is invoked `count` times. + **/ + after( + count: number, + fn: Function): Function; + + /** + * Creates a version of the function that can be called no more than count times. The result of + * the last function call is memoized and returned when count has been reached. + * @param number count The maxmimum number of times the function can be called. + * @param Function fn The function to limit the number of times it can be called. + * @return Copy of `fn` that can only be called `count` times. + **/ + before( + count: number, + fn: Function): Function; + + /** + * Wraps the first function inside of the wrapper function, passing it as the first argument. This allows + * the wrapper to execute code before and after the function runs, adjust the arguments, and execute it + * conditionally. + * @param fn Function to wrap. + * @param wrapper The function that will wrap `fn`. + * @return Wrapped version of `fn. + **/ + wrap( + fn: Function, + wrapper: (fn: Function, ...args: any[]) => any): Function; + + /** + * Returns a negated version of the pass-in predicate. + * @param Function predicate + * @return boolean + **/ + negate(predicate: Function): boolean; + + /** + * Returns the composition of a list of functions, where each function consumes the return value of the + * function that follows. In math terms, composing the functions f(), g(), and h() produces f(g(h())). + * @param functions List of functions to compose. + * @return Composition of `functions`. + **/ + compose(...functions: Function[]): Function; + + /********** + * Objects * + ***********/ + + /** + * Retrieve all the names of the object's properties. + * @param object Retrieve the key or property names from this object. + * @return List of all the property names on `object`. + **/ + keys(object: any): string[]; + + /** + * Return all of the values of the object's properties. + * @param object Retrieve the values of all the properties on this object. + * @return List of all the values on `object`. + **/ + values(object: any): any[]; + + /** + * Like map, but for objects. Transform the value of each property in turn. + * @param object The object to transform + * @param iteratee The function that transforms property values + * @param context The optional context (value of `this`) to bind to + * @return a new _.Dictionary of property values + */ + mapObject(object: _.Dictionary, iteratee: (val: T, key: string, object: _.Dictionary) => U, context?: any): _.Dictionary; + + /** + * Like map, but for objects. Transform the value of each property in turn. + * @param object The object to transform + * @param iteratee The function that tranforms property values + * @param context The optional context (value of `this`) to bind to + */ + mapObject(object: any, iteratee: (val: any, key: string, object: any) => T, context?: any): _.Dictionary; + + /** + * Like map, but for objects. Retrieves a property from each entry in the object, as if by _.property + * @param object The object to transform + * @param iteratee The property name to retrieve + * @param context The optional context (value of `this`) to bind to + */ + mapObject(object: any, iteratee: string, context?: any): _.Dictionary; + + /** + * Convert an object into a list of [key, value] pairs. + * @param object Convert this object to a list of [key, value] pairs. + * @return List of [key, value] pairs on `object`. + **/ + pairs(object: any): any[][]; + + /** + * Returns a copy of the object where the keys have become the values and the values the keys. + * For this to work, all of your object's values should be unique and string serializable. + * @param object Object to invert key/value pairs. + * @return An inverted key/value paired version of `object`. + **/ + invert(object: any): any; + + /** + * Returns a sorted list of the names of every method in an object - that is to say, + * the name of every function property of the object. + * @param object Object to pluck all function property names from. + * @return List of all the function names on `object`. + **/ + functions(object: any): string[]; + + /** + * @see _functions + **/ + methods(object: any): string[]; + + /** + * Copy all of the properties in the source objects over to the destination object, and return + * the destination object. It's in-order, so the last source will override properties of the + * same name in previous arguments. + * @param destination Object to extend all the properties from `sources`. + * @param sources Extends `destination` with all properties from these source objects. + * @return `destination` extended with all the properties from the `sources` objects. + **/ + extend( + destination: any, + ...sources: any[]): any; + + /** + * Like extend, but only copies own properties over to the destination object. (alias: assign) + */ + extendOwn( + destination: any, + ...source: any[]): any; + + /** + * Like extend, but only copies own properties over to the destination object. (alias: extendOwn) + */ + assign( + destination: any, + ...source: any[]): any; + + /** + * Return a copy of the object, filtered to only have values for the whitelisted keys + * (or array of valid keys). + * @param object Object to strip unwanted key/value pairs. + * @keys The key/value pairs to keep on `object`. + * @return Copy of `object` with only the `keys` properties. + **/ + pick( + object: any, + ...keys: any[]): any; + + /** + * @see _.pick + **/ + pick( + object: any, + fn: (value: any, key: any, object: any) => any): any; + + /** + * Return a copy of the object, filtered to omit the blacklisted keys (or array of keys). + * @param object Object to strip unwanted key/value pairs. + * @param keys The key/value pairs to remove on `object`. + * @return Copy of `object` without the `keys` properties. + **/ + omit( + object: any, + ...keys: string[]): any; + + /** + * @see _.omit + **/ + omit( + object: any, + keys: string[]): any; + + /** + * @see _.omit + **/ + omit( + object: any, + iteratee: Function): any; + + /** + * Fill in null and undefined properties in object with values from the defaults objects, + * and return the object. As soon as the property is filled, further defaults will have no effect. + * @param object Fill this object with default values. + * @param defaults The default values to add to `object`. + * @return `object` with added `defaults` values. + **/ + defaults( + object: any, + ...defaults: any[]): any; + + /** + * Create a shallow-copied clone of the object. + * Any nested objects or arrays will be copied by reference, not duplicated. + * @param object Object to clone. + * @return Copy of `object`. + **/ + clone(object: T): T; + + /** + * Invokes interceptor with the object, and then returns object. The primary purpose of this method + * is to "tap into" a method chain, in order to perform operations on intermediate results within the chain. + * @param object Argument to `interceptor`. + * @param intercepter The function to modify `object` before continuing the method chain. + * @return Modified `object`. + **/ + tap(object: T, intercepter: Function): T; + + /** + * Does the object contain the given key? Identical to object.hasOwnProperty(key), but uses a safe + * reference to the hasOwnProperty function, in case it's been overridden accidentally. + * @param object Object to check for `key`. + * @param key The key to check for on `object`. + * @return True if `key` is a property on `object`, otherwise false. + **/ + has(object: any, key: string): boolean; + + /** + * Returns a predicate function that will tell you if a passed in object contains all of the key/value properties present in attrs. + * @param attrs Object with key values pair + * @return Predicate function + **/ + matches(attrs: T): _.ListIterator; + + /** + * Returns a function that will itself return the key property of any passed-in object. + * @param key Property of the object. + * @return Function which accept an object an returns the value of key in that object. + **/ + property(key: string): (object: Object) => any; + + /** + * Performs an optimized deep comparison between the two objects, + * to determine if they should be considered equal. + * @param object Compare to `other`. + * @param other Compare to `object`. + * @return True if `object` is equal to `other`. + **/ + isEqual(object: any, other: any): boolean; + + /** + * Returns true if object contains no values. + * @param object Check if this object has no properties or values. + * @return True if `object` is empty. + **/ + isEmpty(object: any): boolean; + + /** + * Returns true if object is a DOM element. + * @param object Check if this object is a DOM element. + * @return True if `object` is a DOM element, otherwise false. + **/ + isElement(object: any): boolean; + + /** + * Returns true if object is an Array. + * @param object Check if this object is an Array. + * @return True if `object` is an Array, otherwise false. + **/ + isArray(object: any): boolean; + + /** + * Returns true if value is an Object. Note that JavaScript arrays and functions are objects, + * while (normal) strings and numbers are not. + * @param object Check if this object is an Object. + * @return True of `object` is an Object, otherwise false. + **/ + isObject(object: any): boolean; + + /** + * Returns true if object is an Arguments object. + * @param object Check if this object is an Arguments object. + * @return True if `object` is an Arguments object, otherwise false. + **/ + isArguments(object: any): boolean; + + /** + * Returns true if object is a Function. + * @param object Check if this object is a Function. + * @return True if `object` is a Function, otherwise false. + **/ + isFunction(object: any): boolean; + + /** + * Returns true if object is a String. + * @param object Check if this object is a String. + * @return True if `object` is a String, otherwise false. + **/ + isString(object: any): boolean; + + /** + * Returns true if object is a Number (including NaN). + * @param object Check if this object is a Number. + * @return True if `object` is a Number, otherwise false. + **/ + isNumber(object: any): boolean; + + /** + * Returns true if object is a finite Number. + * @param object Check if this object is a finite Number. + * @return True if `object` is a finite Number. + **/ + isFinite(object: any): boolean; + + /** + * Returns true if object is either true or false. + * @param object Check if this object is a bool. + * @return True if `object` is a bool, otherwise false. + **/ + isBoolean(object: any): boolean; + + /** + * Returns true if object is a Date. + * @param object Check if this object is a Date. + * @return True if `object` is a Date, otherwise false. + **/ + isDate(object: any): boolean; + + /** + * Returns true if object is a RegExp. + * @param object Check if this object is a RegExp. + * @return True if `object` is a RegExp, otherwise false. + **/ + isRegExp(object: any): boolean; + + /** + * Returns true if object is NaN. + * Note: this is not the same as the native isNaN function, + * which will also return true if the variable is undefined. + * @param object Check if this object is NaN. + * @return True if `object` is NaN, otherwise false. + **/ + isNaN(object: any): boolean; + + /** + * Returns true if the value of object is null. + * @param object Check if this object is null. + * @return True if `object` is null, otherwise false. + **/ + isNull(object: any): boolean; + + /** + * Returns true if value is undefined. + * @param object Check if this object is undefined. + * @return True if `object` is undefined, otherwise false. + **/ + isUndefined(value: any): boolean; + + /* ********* + * Utility * + ********** */ + + /** + * Give control of the "_" variable back to its previous owner. + * Returns a reference to the Underscore object. + * @return Underscore object reference. + **/ + noConflict(): any; + + /** + * Returns the same value that is used as the argument. In math: f(x) = x + * This function looks useless, but is used throughout Underscore as a default iterator. + * @param value Identity of this object. + * @return `value`. + **/ + identity(value: T): T; + + /** + * Creates a function that returns the same value that is used as the argument of _.constant + * @param value Identity of this object. + * @return Function that return value. + **/ + constant(value: T): () => T; + + /** + * Returns undefined irrespective of the arguments passed to it. Useful as the default + * for optional callback arguments. + * Note there is no way to indicate a 'undefined' return, so it is currently typed as void. + * @return undefined + **/ + noop(): void; + + /** + * Invokes the given iterator function n times. + * Each invocation of iterator is called with an index argument + * @param n Number of times to invoke `iterator`. + * @param iterator Function iterator to invoke `n` times. + * @param context `this` object in `iterator`, optional. + **/ + times(n: number, iterator: (n: number) => TResult, context?: any): TResult[]; + + /** + * Returns a random integer between min and max, inclusive. If you only pass one argument, + * it will return a number between 0 and that number. + * @param max The maximum random number. + * @return A random number between 0 and `max`. + **/ + random(max: number): number; + + /** + * @see _.random + * @param min The minimum random number. + * @return A random number between `min` and `max`. + **/ + random(min: number, max: number): number; + + /** + * Allows you to extend Underscore with your own utility functions. Pass a hash of + * {name: function} definitions to have your functions added to the Underscore object, + * as well as the OOP wrapper. + * @param object Mixin object containing key/function pairs to add to the Underscore object. + **/ + mixin(object: any): void; + + /** + * A mostly-internal function to generate callbacks that can be applied to each element + * in a collection, returning the desired result -- either identity, an arbitrary callback, + * a property matcher, or a propetery accessor. + * @param string|Function|Object value The value to iterate over, usually the key. + * @param any context + * @param number argCount + * @return Callback that can be applied to each element in a collection. + **/ + iteratee(value: string): Function; + iteratee(value: Function, context?: any, argCount?: number): Function; + iteratee(value: Object): Function; + + /** + * Generate a globally-unique id for client-side models or DOM elements that need one. + * If prefix is passed, the id will be appended to it. Without prefix, returns an integer. + * @param prefix A prefix string to start the unique ID with. + * @return Unique string ID beginning with `prefix`. + **/ + uniqueId(prefix: string): string; + + /** + * @see _.uniqueId + **/ + uniqueId(): number; + + /** + * Escapes a string for insertion into HTML, replacing &, <, >, ", ', and / characters. + * @param str Raw string to escape. + * @return `str` HTML escaped. + **/ + escape(str: string): string; + + /** + * The opposite of escape, replaces &, <, >, ", and ' with their unescaped counterparts. + * @param str HTML escaped string. + * @return `str` Raw string. + **/ + unescape(str: string): string; + + /** + * If the value of the named property is a function then invoke it; otherwise, return it. + * @param object Object to maybe invoke function `property` on. + * @param property The function by name to invoke on `object`. + * @return The result of invoking the function `property` on `object. + **/ + result(object: any, property: string): any; + + /** + * Compiles JavaScript templates into functions that can be evaluated for rendering. Useful + * for rendering complicated bits of HTML from JSON data sources. Template functions can both + * interpolate variables, using <%= ... %>, as well as execute arbitrary JavaScript code, with + * <% ... %>. If you wish to interpolate a value, and have it be HTML-escaped, use <%- ... %> When + * you evaluate a template function, pass in a data object that has properties corresponding to + * the template's free variables. If you're writing a one-off, you can pass the data object as + * the second parameter to template in order to render immediately instead of returning a template + * function. The settings argument should be a hash containing any _.templateSettings that should + * be overridden. + * @param templateString Underscore HTML template. + * @param data Data to use when compiling `templateString`. + * @param settings Settings to use while compiling. + * @return Returns the compiled Underscore HTML template. + **/ + template(templateString: string, settings?: _.TemplateSettings): (...data: any[]) => string; + + /** + * By default, Underscore uses ERB-style template delimiters, change the + * following template settings to use alternative delimiters. + **/ + templateSettings: _.TemplateSettings; + + /** + * Returns an integer timestamp for the current time, using the fastest method available in the runtime. Useful for implementing timing/animation functions. + **/ + now(): number; + + /* ********** + * Chaining * + *********** */ + + /** + * Returns a wrapped object. Calling methods on this object will continue to return wrapped objects + * until value() is used. + * @param obj Object to chain. + * @return Wrapped `obj`. + **/ + chain(obj: T[]): _Chain; + chain(obj: T): _Chain; +} + +interface Underscore { + + /* ************* + * Collections * + ************* */ + + /** + * Wrapped type `any[]`. + * @see _.each + **/ + each(iterator: _.ListIterator, context?: any): T[]; + + /** + * @see _.each + **/ + each(iterator: _.ObjectIterator, context?: any): T[]; + + /** + * @see _.each + **/ + forEach(iterator: _.ListIterator, context?: any): T[]; + + /** + * @see _.each + **/ + forEach(iterator: _.ObjectIterator, context?: any): T[]; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ListIterator, context?: any): TResult[]; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ObjectIterator, context?: any): TResult[]; + + /** + * @see _.map + **/ + collect(iterator: _.ListIterator, context?: any): TResult[]; + + /** + * @see _.map + **/ + collect(iterator: _.ObjectIterator, context?: any): TResult[]; + + /** + * Wrapped type `any[]`. + * @see _.reduce + **/ + reduce(iterator: _.MemoIterator, memo?: TResult, context?: any): TResult; + + /** + * @see _.reduce + **/ + inject(iterator: _.MemoIterator, memo?: TResult, context?: any): TResult; + + /** + * @see _.reduce + **/ + foldl(iterator: _.MemoIterator, memo?: TResult, context?: any): TResult; + + /** + * Wrapped type `any[]`. + * @see _.reduceRight + **/ + reduceRight(iterator: _.MemoIterator, memo?: TResult, context?: any): TResult; + + /** + * @see _.reduceRight + **/ + foldr(iterator: _.MemoIterator, memo?: TResult, context?: any): TResult; + + /** + * Wrapped type `any[]`. + * @see _.find + **/ + find(iterator: _.ListIterator, context?: any): T; + + /** + * @see _.find + **/ + detect(iterator: _.ListIterator, context?: any): T; + + /** + * Wrapped type `any[]`. + * @see _.filter + **/ + filter(iterator: _.ListIterator, context?: any): T[]; + + /** + * @see _.filter + **/ + select(iterator: _.ListIterator, context?: any): T[]; + + /** + * Wrapped type `any[]`. + * @see _.where + **/ + where(properties: U): T[]; + + /** + * Wrapped type `any[]`. + * @see _.findWhere + **/ + findWhere(properties: U): T; + + /** + * Wrapped type `any[]`. + * @see _.reject + **/ + reject(iterator: _.ListIterator, context?: any): T[]; + + /** + * Wrapped type `any[]`. + * @see _.all + **/ + all(iterator?: _.ListIterator, context?: any): boolean; + + /** + * @see _.all + **/ + every(iterator?: _.ListIterator, context?: any): boolean; + + /** + * Wrapped type `any[]`. + * @see _.any + **/ + any(iterator?: _.ListIterator, context?: any): boolean; + + /** + * @see _.any + **/ + some(iterator?: _.ListIterator, context?: any): boolean; + + /** + * Wrapped type `any[]`. + * @see _.contains + **/ + contains(value: T): boolean; + + /** + * Alias for 'contains'. + * @see contains + **/ + include(value: T): boolean; + + /** + * Wrapped type `any[]`. + * @see _.invoke + **/ + invoke(methodName: string, ...arguments: any[]): any; + + /** + * Wrapped type `any[]`. + * @see _.pluck + **/ + pluck(propertyName: string): any[]; + + /** + * Wrapped type `number[]`. + * @see _.max + **/ + max(): number; + + /** + * Wrapped type `any[]`. + * @see _.max + **/ + max(iterator: _.ListIterator, context?: any): T; + + /** + * Wrapped type `any[]`. + * @see _.max + **/ + max(iterator?: _.ListIterator, context?: any): T; + + /** + * Wrapped type `number[]`. + * @see _.min + **/ + min(): number; + + /** + * Wrapped type `any[]`. + * @see _.min + **/ + min(iterator: _.ListIterator, context?: any): T; + + /** + * Wrapped type `any[]`. + * @see _.min + **/ + min(iterator?: _.ListIterator, context?: any): T; + + /** + * Wrapped type `any[]`. + * @see _.sortBy + **/ + sortBy(iterator?: _.ListIterator, context?: any): T[]; + + /** + * Wrapped type `any[]`. + * @see _.sortBy + **/ + sortBy(iterator: string, context?: any): T[]; + + /** + * Wrapped type `any[]`. + * @see _.groupBy + **/ + groupBy(iterator?: _.ListIterator, context?: any): _.Dictionary<_.List>; + + /** + * Wrapped type `any[]`. + * @see _.groupBy + **/ + groupBy(iterator: string, context?: any): _.Dictionary; + + /** + * Wrapped type `any[]`. + * @see _.indexBy + **/ + indexBy(iterator: _.ListIterator, context?: any): _.Dictionary; + + /** + * Wrapped type `any[]`. + * @see _.indexBy + **/ + indexBy(iterator: string, context?: any): _.Dictionary; + + /** + * Wrapped type `any[]`. + * @see _.countBy + **/ + countBy(iterator?: _.ListIterator, context?: any): _.Dictionary; + + /** + * Wrapped type `any[]`. + * @see _.countBy + **/ + countBy(iterator: string, context?: any): _.Dictionary; + + /** + * Wrapped type `any[]`. + * @see _.shuffle + **/ + shuffle(): T[]; + + /** + * Wrapped type `any[]`. + * @see _.sample + **/ + sample(n: number): T[]; + + /** + * @see _.sample + **/ + sample(): T; + + /** + * Wrapped type `any`. + * @see _.toArray + **/ + toArray(): T[]; + + /** + * Wrapped type `any`. + * @see _.size + **/ + size(): number; + + /********* + * Arrays * + **********/ + + /** + * Wrapped type `any[]`. + * @see _.first + **/ + first(): T; + + /** + * Wrapped type `any[]`. + * @see _.first + **/ + first(n: number): T[]; + + /** + * @see _.first + **/ + head(): T; + + /** + * @see _.first + **/ + head(n: number): T[]; + + /** + * @see _.first + **/ + take(): T; + + /** + * @see _.first + **/ + take(n: number): T[]; + + /** + * Wrapped type `any[]`. + * @see _.initial + **/ + initial(n?: number): T[]; + + /** + * Wrapped type `any[]`. + * @see _.last + **/ + last(): T; + + /** + * Wrapped type `any[]`. + * @see _.last + **/ + last(n: number): T[]; + + /** + * Wrapped type `any[]`. + * @see _.rest + **/ + rest(n?: number): T[]; + + /** + * @see _.rest + **/ + tail(n?: number): T[]; + + /** + * @see _.rest + **/ + drop(n?: number): T[]; + + /** + * Wrapped type `any[]`. + * @see _.compact + **/ + compact(): T[]; + + /** + * Wrapped type `any`. + * @see _.flatten + **/ + flatten(shallow?: boolean): any[]; + + /** + * Wrapped type `any[]`. + * @see _.without + **/ + without(...values: T[]): T[]; + + /** + * Wrapped type `any[]`. + * @see _.partition + **/ + partition(iterator: _.ListIterator, context?: any): T[][]; + + /** + * Wrapped type `any[][]`. + * @see _.union + **/ + union(...arrays: _.List[]): T[]; + + /** + * Wrapped type `any[][]`. + * @see _.intersection + **/ + intersection(...arrays: _.List[]): T[]; + + /** + * Wrapped type `any[]`. + * @see _.difference + **/ + difference(...others: _.List[]): T[]; + + /** + * Wrapped type `any[]`. + * @see _.uniq + **/ + uniq(isSorted?: boolean, iterator?: _.ListIterator): T[]; + + /** + * Wrapped type `any[]`. + * @see _.uniq + **/ + uniq(iterator?: _.ListIterator, context?: any): T[]; + + /** + * @see _.uniq + **/ + unique(isSorted?: boolean, iterator?: _.ListIterator): T[]; + + /** + * @see _.uniq + **/ + unique(iterator?: _.ListIterator, context?: any): T[]; + + /** + * Wrapped type `any[][]`. + * @see _.zip + **/ + zip(...arrays: any[][]): any[][]; + + /** + * Wrapped type `any[][]`. + * @see _.object + **/ + object(...keyValuePairs: any[][]): any; + + /** + * @see _.object + **/ + object(values?: any): any; + + /** + * Wrapped type `any[]`. + * @see _.indexOf + **/ + indexOf(value: T, isSorted?: boolean): number; + + /** + * @see _.indexOf + **/ + indexOf(value: T, startFrom: number): number; + + /** + * Wrapped type `any[]`. + * @see _.lastIndexOf + **/ + lastIndexOf(value: T, from?: number): number; + + /** + * Wrapped type `any[]`. + * @see _.sortedIndex + **/ + sortedIndex(value: T, iterator?: (x: T) => any, context?: any): number; + + /** + * Wrapped type `number`. + * @see _.range + **/ + range(stop: number, step?: number): number[]; + + /** + * Wrapped type `number`. + * @see _.range + **/ + range(): number[]; + + /* *********** + * Functions * + ************ */ + + /** + * Wrapped type `Function`. + * @see _.bind + **/ + bind(object: any, ...arguments: any[]): Function; + + /** + * Wrapped type `object`. + * @see _.bindAll + **/ + bindAll(...methodNames: string[]): any; + + /** + * Wrapped type `Function`. + * @see _.partial + **/ + partial(...arguments: any[]): Function; + + /** + * Wrapped type `Function`. + * @see _.memoize + **/ + memoize(hashFn?: (n: any) => string): Function; + + /** + * Wrapped type `Function`. + * @see _.defer + **/ + defer(...arguments: any[]): void; + + /** + * Wrapped type `Function`. + * @see _.delay + **/ + delay(wait: number, ...arguments: any[]): any; + + /** + * @see _.delay + **/ + delay(...arguments: any[]): any; + + /** + * Wrapped type `Function`. + * @see _.throttle + **/ + throttle(wait: number, options?: _.ThrottleSettings): Function; + + /** + * Wrapped type `Function`. + * @see _.debounce + **/ + debounce(wait: number, immediate?: boolean): Function; + + /** + * Wrapped type `Function`. + * @see _.once + **/ + once(): Function; + + /** + * Wrapped type `number`. + * @see _.after + **/ + after(fn: Function): Function; + + /** + * Wrapped type `number`. + * @see _.before + **/ + before(fn: Function): Function; + + /** + * Wrapped type `Function`. + * @see _.wrap + **/ + wrap(wrapper: Function): () => Function; + + /** + * Wrapped type `Function`. + * @see _.negate + **/ + negate(): boolean; + + /** + * Wrapped type `Function[]`. + * @see _.compose + **/ + compose(...functions: Function[]): Function; + + /********* * + * Objects * + ********** */ + + /** + * Wrapped type `object`. + * @see _.keys + **/ + keys(): string[]; + + /** + * Wrapped type `object`. + * @see _.values + **/ + values(): T[]; + + /** + * Wrapped type `object`. + * @see _.pairs + **/ + pairs(): any[][]; + + /** + * Wrapped type `object`. + * @see _.invert + **/ + invert(): any; + + /** + * Wrapped type `object`. + * @see _.functions + **/ + functions(): string[]; + + /** + * @see _.functions + **/ + methods(): string[]; + + /** + * Wrapped type `object`. + * @see _.extend + **/ + extend(...sources: any[]): any; + + /** + * Wrapped type `object`. + * @see _.pick + **/ + pick(...keys: any[]): any; + pick(keys: any[]): any; + pick(fn: (value: any, key: any, object: any) => any): any; + + /** + * Wrapped type `object`. + * @see _.omit + **/ + omit(...keys: string[]): any; + omit(keys: string[]): any; + omit(fn: Function): any; + + /** + * Wrapped type `object`. + * @see _.defaults + **/ + defaults(...defaults: any[]): any; + + /** + * Wrapped type `any[]`. + * @see _.clone + **/ + clone(): T; + + /** + * Wrapped type `object`. + * @see _.tap + **/ + tap(interceptor: (...as: any[]) => any): any; + + /** + * Wrapped type `object`. + * @see _.has + **/ + has(key: string): boolean; + + /** + * Wrapped type `any[]`. + * @see _.matches + **/ + matches(): _.ListIterator; + + /** + * Wrapped type `string`. + * @see _.property + **/ + property(): (object: Object) => any; + + /** + * Wrapped type `object`. + * @see _.isEqual + **/ + isEqual(other: any): boolean; + + /** + * Wrapped type `object`. + * @see _.isEmpty + **/ + isEmpty(): boolean; + + /** + * Wrapped type `object`. + * @see _.isElement + **/ + isElement(): boolean; + + /** + * Wrapped type `object`. + * @see _.isArray + **/ + isArray(): boolean; + + /** + * Wrapped type `object`. + * @see _.isObject + **/ + isObject(): boolean; + + /** + * Wrapped type `object`. + * @see _.isArguments + **/ + isArguments(): boolean; + + /** + * Wrapped type `object`. + * @see _.isFunction + **/ + isFunction(): boolean; + + /** + * Wrapped type `object`. + * @see _.isString + **/ + isString(): boolean; + + /** + * Wrapped type `object`. + * @see _.isNumber + **/ + isNumber(): boolean; + + /** + * Wrapped type `object`. + * @see _.isFinite + **/ + isFinite(): boolean; + + /** + * Wrapped type `object`. + * @see _.isBoolean + **/ + isBoolean(): boolean; + + /** + * Wrapped type `object`. + * @see _.isDate + **/ + isDate(): boolean; + + /** + * Wrapped type `object`. + * @see _.isRegExp + **/ + isRegExp(): boolean; + + /** + * Wrapped type `object`. + * @see _.isNaN + **/ + isNaN(): boolean; + + /** + * Wrapped type `object`. + * @see _.isNull + **/ + isNull(): boolean; + + /** + * Wrapped type `object`. + * @see _.isUndefined + **/ + isUndefined(): boolean; + + /********* * + * Utility * + ********** */ + + /** + * Wrapped type `any`. + * @see _.identity + **/ + identity(): any; + + /** + * Wrapped type `any`. + * @see _.constant + **/ + constant(): () => T; + + /** + * Wrapped type `any`. + * @see _.noop + **/ + noop(): void; + + /** + * Wrapped type `number`. + * @see _.times + **/ + times(iterator: (n: number) => TResult, context?: any): TResult[]; + + /** + * Wrapped type `number`. + * @see _.random + **/ + random(): number; + /** + * Wrapped type `number`. + * @see _.random + **/ + random(max: number): number; + + /** + * Wrapped type `object`. + * @see _.mixin + **/ + mixin(): void; + + /** + * Wrapped type `string|Function|Object`. + * @see _.iteratee + **/ + iteratee(context?: any, argCount?: number): Function; + + /** + * Wrapped type `string`. + * @see _.uniqueId + **/ + uniqueId(): string; + + /** + * Wrapped type `string`. + * @see _.escape + **/ + escape(): string; + + /** + * Wrapped type `string`. + * @see _.unescape + **/ + unescape(): string; + + /** + * Wrapped type `object`. + * @see _.result + **/ + result(property: string): any; + + /** + * Wrapped type `string`. + * @see _.template + **/ + template(settings?: _.TemplateSettings): (...data: any[]) => string; + + /********** * + * Chaining * + *********** */ + + /** + * Wrapped type `any`. + * @see _.chain + **/ + chain(): _Chain; + + /** + * Wrapped type `any`. + * Extracts the value of a wrapped object. + * @return Value of the wrapped object. + **/ + value(): TResult; +} + +interface _Chain { + + /* ************* + * Collections * + ************* */ + + /** + * Wrapped type `any[]`. + * @see _.each + **/ + each(iterator: _.ListIterator, context?: any): _Chain; + + /** + * @see _.each + **/ + each(iterator: _.ObjectIterator, context?: any): _Chain; + + /** + * @see _.each + **/ + forEach(iterator: _.ListIterator, context?: any): _Chain; + + /** + * @see _.each + **/ + forEach(iterator: _.ObjectIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ListIterator, context?: any): _ChainOfArrays; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ObjectIterator, context?: any): _ChainOfArrays; + + /** + * Wrapped type `any[]`. + * @see _.map + **/ + map(iterator: _.ObjectIterator, context?: any): _Chain; + + /** + * @see _.map + **/ + collect(iterator: _.ListIterator, context?: any): _Chain; + + /** + * @see _.map + **/ + collect(iterator: _.ObjectIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.reduce + **/ + reduce(iterator: _.MemoIterator, memo?: TResult, context?: any): _ChainSingle; + + /** + * @see _.reduce + **/ + inject(iterator: _.MemoIterator, memo?: TResult, context?: any): _ChainSingle; + + /** + * @see _.reduce + **/ + foldl(iterator: _.MemoIterator, memo?: TResult, context?: any): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.reduceRight + **/ + reduceRight(iterator: _.MemoIterator, memo?: TResult, context?: any): _ChainSingle; + + /** + * @see _.reduceRight + **/ + foldr(iterator: _.MemoIterator, memo?: TResult, context?: any): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.find + **/ + find(iterator: _.ListIterator, context?: any): _ChainSingle; + + /** + * @see _.find + **/ + detect(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.filter + **/ + filter(iterator: _.ListIterator, context?: any): _Chain; + + /** + * @see _.filter + **/ + select(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.where + **/ + where(properties: U): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.findWhere + **/ + findWhere(properties: U): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.reject + **/ + reject(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.all + **/ + all(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * @see _.all + **/ + every(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.any + **/ + any(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * @see _.any + **/ + some(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.contains + **/ + contains(value: T): _Chain; + + /** + * Alias for 'contains'. + * @see contains + **/ + include(value: T): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.invoke + **/ + invoke(methodName: string, ...arguments: any[]): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.pluck + **/ + pluck(propertyName: string): _Chain; + + /** + * Wrapped type `number[]`. + * @see _.max + **/ + max(): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.max + **/ + max(iterator: _.ListIterator, context?: any): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.max + **/ + max(iterator?: _.ListIterator, context?: any): _ChainSingle; + + /** + * Wrapped type `number[]`. + * @see _.min + **/ + min(): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.min + **/ + min(iterator: _.ListIterator, context?: any): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.min + **/ + min(iterator?: _.ListIterator, context?: any): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.sortBy + **/ + sortBy(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.sortBy + **/ + sortBy(iterator: string, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.groupBy + **/ + groupBy(iterator?: _.ListIterator, context?: any): _ChainOfArrays; + + /** + * Wrapped type `any[]`. + * @see _.groupBy + **/ + groupBy(iterator: string, context?: any): _ChainOfArrays; + + /** + * Wrapped type `any[]`. + * @see _.indexBy + **/ + indexBy(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.indexBy + **/ + indexBy(iterator: string, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.countBy + **/ + countBy(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.countBy + **/ + countBy(iterator: string, context?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.shuffle + **/ + shuffle(): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.sample + **/ + sample(n: number): _Chain; + + /** + * @see _.sample + **/ + sample(): _Chain; + + /** + * Wrapped type `any`. + * @see _.toArray + **/ + toArray(): _Chain; + + /** + * Wrapped type `any`. + * @see _.size + **/ + size(): _Chain; + + /********* + * Arrays * + **********/ + + /** + * Wrapped type `any[]`. + * @see _.first + **/ + first(): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.first + **/ + first(n: number): _Chain; + + /** + * @see _.first + **/ + head(): _Chain; + + /** + * @see _.first + **/ + head(n: number): _Chain; + + /** + * @see _.first + **/ + take(): _Chain; + + /** + * @see _.first + **/ + take(n: number): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.initial + **/ + initial(n?: number): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.last + **/ + last(): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.last + **/ + last(n: number): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.rest + **/ + rest(n?: number): _Chain; + + /** + * @see _.rest + **/ + tail(n?: number): _Chain; + + /** + * @see _.rest + **/ + drop(n?: number): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.compact + **/ + compact(): _Chain; + + /** + * Wrapped type `any`. + * @see _.flatten + **/ + flatten(shallow?: boolean): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.without + **/ + without(...values: T[]): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.partition + **/ + partition(iterator: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[][]`. + * @see _.union + **/ + union(...arrays: _.List[]): _Chain; + + /** + * Wrapped type `any[][]`. + * @see _.intersection + **/ + intersection(...arrays: _.List[]): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.difference + **/ + difference(...others: _.List[]): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.uniq + **/ + uniq(isSorted?: boolean, iterator?: _.ListIterator): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.uniq + **/ + uniq(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * @see _.uniq + **/ + unique(isSorted?: boolean, iterator?: _.ListIterator): _Chain; + + /** + * @see _.uniq + **/ + unique(iterator?: _.ListIterator, context?: any): _Chain; + + /** + * Wrapped type `any[][]`. + * @see _.zip + **/ + zip(...arrays: any[][]): _Chain; + + /** + * Wrapped type `any[][]`. + * @see _.object + **/ + object(...keyValuePairs: any[][]): _Chain; + + /** + * @see _.object + **/ + object(values?: any): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.indexOf + **/ + indexOf(value: T, isSorted?: boolean): _ChainSingle; + + /** + * @see _.indexOf + **/ + indexOf(value: T, startFrom: number): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.lastIndexOf + **/ + lastIndexOf(value: T, from?: number): _ChainSingle; + + /** + * Wrapped type `any[]`. + * @see _.sortedIndex + **/ + sortedIndex(value: T, iterator?: (x: T) => any, context?: any): _Chain; + + /** + * Wrapped type `number`. + * @see _.range + **/ + range(stop: number, step?: number): _Chain; + + /** + * Wrapped type `number`. + * @see _.range + **/ + range(): _Chain; + + /* *********** + * Functions * + ************ */ + + /** + * Wrapped type `Function`. + * @see _.bind + **/ + bind(object: any, ...arguments: any[]): _Chain; + + /** + * Wrapped type `object`. + * @see _.bindAll + **/ + bindAll(...methodNames: string[]): _Chain; + + /** + * Wrapped type `Function`. + * @see _.partial + **/ + partial(...arguments: any[]): _Chain; + + /** + * Wrapped type `Function`. + * @see _.memoize + **/ + memoize(hashFn?: (n: any) => string): _Chain; + + /** + * Wrapped type `Function`. + * @see _.defer + **/ + defer(...arguments: any[]): _Chain; + + /** + * Wrapped type `Function`. + * @see _.delay + **/ + delay(wait: number, ...arguments: any[]): _Chain; + + /** + * @see _.delay + **/ + delay(...arguments: any[]): _Chain; + + /** + * Wrapped type `Function`. + * @see _.throttle + **/ + throttle(wait: number, options?: _.ThrottleSettings): _Chain; + + /** + * Wrapped type `Function`. + * @see _.debounce + **/ + debounce(wait: number, immediate?: boolean): _Chain; + + /** + * Wrapped type `Function`. + * @see _.once + **/ + once(): _Chain; + + /** + * Wrapped type `number`. + * @see _.after + **/ + after(func: Function): _Chain; + + /** + * Wrapped type `number`. + * @see _.before + **/ + before(fn: Function): _Chain; + + /** + * Wrapped type `Function`. + * @see _.wrap + **/ + wrap(wrapper: Function): () => _Chain; + + /** + * Wrapped type `Function`. + * @see _.negate + **/ + negate(): _Chain; + + /** + * Wrapped type `Function[]`. + * @see _.compose + **/ + compose(...functions: Function[]): _Chain; + + /********* * + * Objects * + ********** */ + + /** + * Wrapped type `object`. + * @see _.keys + **/ + keys(): _Chain; + + /** + * Wrapped type `object`. + * @see _.values + **/ + values(): _Chain; + + /** + * Wrapped type `object`. + * @see _.pairs + **/ + pairs(): _Chain; + + /** + * Wrapped type `object`. + * @see _.invert + **/ + invert(): _Chain; + + /** + * Wrapped type `object`. + * @see _.functions + **/ + functions(): _Chain; + + /** + * @see _.functions + **/ + methods(): _Chain; + + /** + * Wrapped type `object`. + * @see _.extend + **/ + extend(...sources: any[]): _Chain; + + /** + * Wrapped type `object`. + * @see _.pick + **/ + pick(...keys: any[]): _Chain; + pick(keys: any[]): _Chain; + pick(fn: (value: any, key: any, object: any) => any): _Chain; + + /** + * Wrapped type `object`. + * @see _.omit + **/ + omit(...keys: string[]): _Chain; + omit(keys: string[]): _Chain; + omit(iteratee: Function): _Chain; + + /** + * Wrapped type `object`. + * @see _.defaults + **/ + defaults(...defaults: any[]): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.clone + **/ + clone(): _Chain; + + /** + * Wrapped type `object`. + * @see _.tap + **/ + tap(interceptor: (...as: any[]) => any): _Chain; + + /** + * Wrapped type `object`. + * @see _.has + **/ + has(key: string): _Chain; + + /** + * Wrapped type `any[]`. + * @see _.matches + **/ + matches(): _Chain; + + /** + * Wrapped type `string`. + * @see _.property + **/ + property(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isEqual + **/ + isEqual(other: any): _Chain; + + /** + * Wrapped type `object`. + * @see _.isEmpty + **/ + isEmpty(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isElement + **/ + isElement(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isArray + **/ + isArray(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isObject + **/ + isObject(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isArguments + **/ + isArguments(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isFunction + **/ + isFunction(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isString + **/ + isString(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isNumber + **/ + isNumber(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isFinite + **/ + isFinite(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isBoolean + **/ + isBoolean(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isDate + **/ + isDate(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isRegExp + **/ + isRegExp(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isNaN + **/ + isNaN(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isNull + **/ + isNull(): _Chain; + + /** + * Wrapped type `object`. + * @see _.isUndefined + **/ + isUndefined(): _Chain; + + /********* * + * Utility * + ********** */ + + /** + * Wrapped type `any`. + * @see _.identity + **/ + identity(): _Chain; + + /** + * Wrapped type `any`. + * @see _.constant + **/ + constant(): _Chain; + + /** + * Wrapped type `any`. + * @see _.noop + **/ + noop(): _Chain; + + /** + * Wrapped type `number`. + * @see _.times + **/ + times(iterator: (n: number) => TResult, context?: any): _Chain; + + /** + * Wrapped type `number`. + * @see _.random + **/ + random(): _Chain; + /** + * Wrapped type `number`. + * @see _.random + **/ + random(max: number): _Chain; + + /** + * Wrapped type `object`. + * @see _.mixin + **/ + mixin(): _Chain; + + /** + * Wrapped type `string|Function|Object`. + * @see _.iteratee + **/ + iteratee(context?: any, argCount?: number): _Chain; + + /** + * Wrapped type `string`. + * @see _.uniqueId + **/ + uniqueId(): _Chain; + + /** + * Wrapped type `string`. + * @see _.escape + **/ + escape(): _Chain; + + /** + * Wrapped type `string`. + * @see _.unescape + **/ + unescape(): _Chain; + + /** + * Wrapped type `object`. + * @see _.result + **/ + result(property: string): _Chain; + + /** + * Wrapped type `string`. + * @see _.template + **/ + template(settings?: _.TemplateSettings): (...data: any[]) => _Chain; + + /************* * + * Array proxy * + ************** */ + + /** + * Returns a new array comprised of the array on which it is called + * joined with the array(s) and/or value(s) provided as arguments. + * @param arr Arrays and/or values to concatenate into a new array. See the discussion below for details. + * @return A new array comprised of the array on which it is called + **/ + concat(...arr: Array): _Chain; + + /** + * Join all elements of an array into a string. + * @param separator Optional. Specifies a string to separate each element of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma. + * @return The string conversions of all array elements joined into one string. + **/ + join(separator?: any): _ChainSingle; + + /** + * Removes the last element from an array and returns that element. + * @return Returns the popped element. + **/ + pop(): _ChainSingle; + + /** + * Adds one or more elements to the end of an array and returns the new length of the array. + * @param item The elements to add to the end of the array. + * @return The array with the element added to the end. + **/ + push(...item: Array): _Chain; + + /** + * Reverses an array in place. The first array element becomes the last and the last becomes the first. + * @return The reversed array. + **/ + reverse(): _Chain; + + /** + * Removes the first element from an array and returns that element. This method changes the length of the array. + * @return The shifted element. + **/ + shift(): _ChainSingle; + + /** + * Returns a shallow copy of a portion of an array into a new array object. + * @param start Zero-based index at which to begin extraction. + * @param end Optional. Zero-based index at which to end extraction. slice extracts up to but not including end. + * @return A shallow copy of a portion of an array into a new array object. + **/ + slice(start: number, end?: number): _Chain; + + /** + * Sorts the elements of an array in place and returns the array. The sort is not necessarily stable. The default sort order is according to string Unicode code points. + * @param compareFn Optional. Specifies a function that defines the sort order. If omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element. + * @return The sorted array. + **/ + sort(compareFn: (a: T, b: T) => boolean): _Chain; + + /** + * Changes the content of an array by removing existing elements and/or adding new elements. + * @param index Index at which to start changing the array. If greater than the length of the array, actual starting index will be set to the length of the array. If negative, will begin that many elements from the end. + * @param quantity An integer indicating the number of old array elements to remove. If deleteCount is 0, no elements are removed. In this case, you should specify at least one new element. If deleteCount is greater than the number of elements left in the array starting at index, then all of the elements through the end of the array will be deleted. + * @param items The element to add to the array. If you don't specify any elements, splice will only remove elements from the array. + * @return An array containing the deleted elements. If only one element is removed, an array of one element is returned. If no elements are removed, an empty array is returned. + **/ + splice(index: number, quantity: number, ...items: Array): _Chain; + + /** + * A string representing the specified array and its elements. + * @return A string representing the specified array and its elements. + **/ + toString(): _ChainSingle; + + /** + * Adds one or more elements to the beginning of an array and returns the new length of the array. + * @param items The elements to add to the front of the array. + * @return The array with the element added to the beginning. + **/ + unshift(...items: Array): _Chain; + + /********** * + * Chaining * + *********** */ + + /** + * Wrapped type `any`. + * @see _.chain + **/ + chain(): _Chain; + + /** + * Wrapped type `any`. + * @see _.value + **/ + value(): T[]; +} +interface _ChainSingle { + value(): T; +} +interface _ChainOfArrays extends _Chain { + flatten(): _Chain; +} + +declare var _: UnderscoreStatic; + +declare module "underscore" { + export = _; +}