.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / tslint / lib / rules / strictTypePredicatesRule.js
diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/tslint/lib/rules/strictTypePredicatesRule.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/tslint/lib/rules/strictTypePredicatesRule.js
new file mode 100644 (file)
index 0000000..84fe62f
--- /dev/null
@@ -0,0 +1,247 @@
+"use strict";
+/**
+ * @license
+ * Copyright 2017 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.
+ */
+Object.defineProperty(exports, "__esModule", { value: true });
+var tslib_1 = require("tslib");
+var tsutils_1 = require("tsutils");
+var ts = require("typescript");
+var error_1 = require("../error");
+var Lint = require("../index");
+// tslint:disable:no-bitwise
+var Rule = /** @class */ (function (_super) {
+    tslib_1.__extends(Rule, _super);
+    function Rule() {
+        return _super !== null && _super.apply(this, arguments) || this;
+    }
+    Rule.FAILURE_STRING = function (value) {
+        return "Expression is always " + value + ".";
+    };
+    Rule.FAILURE_STRICT_PREFER_STRICT_EQUALS = function (value, isPositive) {
+        return "Use '" + (isPositive ? "===" : "!==") + " " + value + "' instead.";
+    };
+    Rule.prototype.applyWithProgram = function (sourceFile, program) {
+        if (!Lint.isStrictNullChecksEnabled(program.getCompilerOptions())) {
+            error_1.showWarningOnce("strict-type-predicates does not work without --strictNullChecks");
+            return [];
+        }
+        return this.applyWithFunction(sourceFile, walk, undefined, program.getTypeChecker());
+    };
+    /* tslint:disable:object-literal-sort-keys */
+    Rule.metadata = {
+        ruleName: "strict-type-predicates",
+        description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n            Warns for type predicates that are always true or always false.\n            Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n            (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n            Does not yet work for 'instanceof'.\n            Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions.\n\n            This rule requires `strictNullChecks` to work properly."], ["\n            Warns for type predicates that are always true or always false.\n            Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n            (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n            Does not yet work for 'instanceof'.\n            Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions.\n\n            This rule requires \\`strictNullChecks\\` to work properly."]))),
+        optionsDescription: "Not configurable.",
+        options: null,
+        optionExamples: [true],
+        type: "functionality",
+        typescriptOnly: true,
+        requiresTypeInfo: true,
+    };
+    /* tslint:enable:object-literal-sort-keys */
+    Rule.FAILURE_STRING_BAD_TYPEOF = "Bad comparison for 'typeof'.";
+    return Rule;
+}(Lint.Rules.TypedRule));
+exports.Rule = Rule;
+function walk(ctx, checker) {
+    return ts.forEachChild(ctx.sourceFile, function cb(node) {
+        if (tsutils_1.isBinaryExpression(node)) {
+            var equals = Lint.getEqualsKind(node.operatorToken);
+            if (equals !== undefined) {
+                checkEquals(node, equals);
+            }
+        }
+        return ts.forEachChild(node, cb);
+    });
+    function checkEquals(node, _a) {
+        var isStrict = _a.isStrict, isPositive = _a.isPositive;
+        var exprPred = getTypePredicate(node, isStrict);
+        if (exprPred === undefined) {
+            return;
+        }
+        if (exprPred.kind === 2 /* TypeofTypo */) {
+            fail(Rule.FAILURE_STRING_BAD_TYPEOF);
+            return;
+        }
+        var exprType = checker.getTypeAtLocation(exprPred.expression);
+        // TODO: could use checker.getBaseConstraintOfType to help with type parameters, but it's not publicly exposed.
+        if (tsutils_1.isTypeFlagSet(exprType, ts.TypeFlags.Any | ts.TypeFlags.TypeParameter | ts.TypeFlags.Unknown)) {
+            return;
+        }
+        switch (exprPred.kind) {
+            case 0 /* Plain */: {
+                var predicate = exprPred.predicate, isNullOrUndefined = exprPred.isNullOrUndefined;
+                var value = getConstantBoolean(exprType, predicate);
+                // 'null'/'undefined' are the only two values *not* assignable to '{}'.
+                if (value !== undefined && (isNullOrUndefined || !isEmptyType(checker, exprType))) {
+                    fail(Rule.FAILURE_STRING(value === isPositive));
+                }
+                break;
+            }
+            case 1 /* NonStructNullUndefined */: {
+                var result = testNonStrictNullUndefined(exprType);
+                if (result !== undefined) {
+                    fail(typeof result === "boolean"
+                        ? Rule.FAILURE_STRING(result === isPositive)
+                        : Rule.FAILURE_STRICT_PREFER_STRICT_EQUALS(result, isPositive));
+                }
+            }
+        }
+        function fail(failure) {
+            ctx.addFailureAtNode(node, failure);
+        }
+    }
+}
+/** Detects a type predicate given `left === right`. */
+function getTypePredicate(node, isStrictEquals) {
+    var left = node.left, right = node.right;
+    var lr = getTypePredicateOneWay(left, right, isStrictEquals);
+    return lr !== undefined ? lr : getTypePredicateOneWay(right, left, isStrictEquals);
+}
+/** Only gets the type predicate if the expression is on the left. */
+function getTypePredicateOneWay(left, right, isStrictEquals) {
+    switch (right.kind) {
+        case ts.SyntaxKind.TypeOfExpression:
+            var expression = right.expression;
+            if (!tsutils_1.isLiteralExpression(left)) {
+                if ((tsutils_1.isIdentifier(left) && left.text === "undefined") ||
+                    left.kind === ts.SyntaxKind.NullKeyword ||
+                    left.kind === ts.SyntaxKind.TrueKeyword ||
+                    left.kind === ts.SyntaxKind.FalseKeyword) {
+                    return { kind: 2 /* TypeofTypo */ };
+                }
+                return undefined;
+            }
+            var predicate = getTypePredicateForKind(left.text);
+            return predicate === undefined
+                ? { kind: 2 /* TypeofTypo */ }
+                : {
+                    expression: expression,
+                    isNullOrUndefined: left.text === "undefined",
+                    kind: 0 /* Plain */,
+                    predicate: predicate,
+                };
+        case ts.SyntaxKind.NullKeyword:
+            return nullOrUndefined(ts.TypeFlags.Null);
+        case ts.SyntaxKind.Identifier:
+            if (right.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) {
+                return nullOrUndefined(undefinedFlags);
+            }
+            return undefined;
+        default:
+            return undefined;
+    }
+    function nullOrUndefined(flags) {
+        return isStrictEquals
+            ? {
+                expression: left,
+                isNullOrUndefined: true,
+                kind: 0 /* Plain */,
+                predicate: flagPredicate(flags),
+            }
+            : { kind: 1 /* NonStructNullUndefined */, expression: left };
+    }
+}
+function isEmptyType(checker, type) {
+    return checker.typeToString(type) === "{}";
+}
+var undefinedFlags = ts.TypeFlags.Undefined | ts.TypeFlags.Void;
+function getTypePredicateForKind(kind) {
+    switch (kind) {
+        case "undefined":
+            return flagPredicate(undefinedFlags);
+        case "boolean":
+            return flagPredicate(ts.TypeFlags.BooleanLike);
+        case "number":
+            return flagPredicate(ts.TypeFlags.NumberLike);
+        case "string":
+            return flagPredicate(ts.TypeFlags.StringLike);
+        case "symbol":
+            return flagPredicate(ts.TypeFlags.ESSymbol);
+        case "function":
+            return isFunction;
+        case "object":
+            // It's an object if it's not any of the above.
+            var allFlags_1 = ts.TypeFlags.Undefined |
+                ts.TypeFlags.Void |
+                ts.TypeFlags.BooleanLike |
+                ts.TypeFlags.NumberLike |
+                ts.TypeFlags.StringLike |
+                ts.TypeFlags.ESSymbol;
+            return function (type) { return !tsutils_1.isTypeFlagSet(type, allFlags_1) && !isFunction(type); };
+        default:
+            return undefined;
+    }
+}
+function flagPredicate(testedFlag) {
+    return function (type) { return tsutils_1.isTypeFlagSet(type, testedFlag); };
+}
+function isFunction(t) {
+    if (t.getConstructSignatures().length !== 0 || t.getCallSignatures().length !== 0) {
+        return true;
+    }
+    var symbol = t.getSymbol();
+    return symbol !== undefined && symbol.getName() === "Function";
+}
+/** Returns a boolean value if that should always be the result of a type predicate. */
+function getConstantBoolean(type, predicate) {
+    var anyTrue = false;
+    var anyFalse = false;
+    for (var _i = 0, _a = unionParts(type); _i < _a.length; _i++) {
+        var ty = _a[_i];
+        if (predicate(ty)) {
+            anyTrue = true;
+        }
+        else {
+            anyFalse = true;
+        }
+        if (anyTrue && anyFalse) {
+            return undefined;
+        }
+    }
+    return anyTrue;
+}
+/** Returns bool for always/never true, or a string to recommend strict equality. */
+function testNonStrictNullUndefined(type) {
+    var anyNull = false;
+    var anyUndefined = false;
+    var anyOther = false;
+    for (var _i = 0, _a = unionParts(type); _i < _a.length; _i++) {
+        var ty = _a[_i];
+        if (tsutils_1.isTypeFlagSet(ty, ts.TypeFlags.Null)) {
+            anyNull = true;
+        }
+        else if (tsutils_1.isTypeFlagSet(ty, undefinedFlags)) {
+            anyUndefined = true;
+        }
+        else {
+            anyOther = true;
+        }
+    }
+    return !anyOther
+        ? true
+        : anyNull && anyUndefined
+            ? undefined
+            : anyNull
+                ? "null"
+                : anyUndefined
+                    ? "undefined"
+                    : false;
+}
+function unionParts(type) {
+    return tsutils_1.isUnionType(type) ? type.types : [type];
+}
+var templateObject_1;