mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-10 01:43:59 -05:00
Merge branch 'master' into libReference
This commit is contained in:
@@ -8,7 +8,7 @@ function endsWith(s: string, suffix: string) {
|
||||
}
|
||||
|
||||
function isStringEnum(declaration: ts.EnumDeclaration) {
|
||||
return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
|
||||
return declaration.members.length && declaration.members.every(m => !!m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
|
||||
}
|
||||
|
||||
class DeclarationsWalker {
|
||||
@@ -30,7 +30,7 @@ class DeclarationsWalker {
|
||||
text += "\ndeclare namespace ts {\n";
|
||||
text += " // these types are empty stubs for types from services and should not be used directly\n"
|
||||
for (const type of walker.removedTypes) {
|
||||
text += ` export type ${type.symbol.name} = never;\n`;
|
||||
text += ` export type ${type.symbol!.name} = never;\n`;
|
||||
}
|
||||
text += "}"
|
||||
}
|
||||
@@ -130,7 +130,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
|
||||
function getInitialDtsFileForProtocol() {
|
||||
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
|
||||
|
||||
let protocolDts: string;
|
||||
let protocolDts: string | undefined;
|
||||
program.emit(program.getSourceFile(protocolTs), (file, content) => {
|
||||
if (endsWith(file, ".d.ts")) {
|
||||
protocolDts = content;
|
||||
@@ -162,7 +162,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
|
||||
let protocolDts = getInitialDtsFileForProtocol();
|
||||
const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
|
||||
|
||||
const protocolFile = program.getSourceFile("protocol.d.ts");
|
||||
const protocolFile = program.getSourceFile("protocol.d.ts")!;
|
||||
const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
|
||||
if (extraDeclarations) {
|
||||
protocolDts += extraDeclarations;
|
||||
|
||||
@@ -56,13 +56,13 @@ function updateTsFile(tsFilePath: string, tsFileContents: string, majorMinor: st
|
||||
const majorMinorRgx = /export const versionMajorMinor = "(\d+\.\d+)"/;
|
||||
const majorMinorMatch = majorMinorRgx.exec(tsFileContents);
|
||||
assert(majorMinorMatch !== null, `The file seems to no longer have a string matching '${majorMinorRgx}'.`);
|
||||
const parsedMajorMinor = majorMinorMatch[1];
|
||||
const parsedMajorMinor = majorMinorMatch![1];
|
||||
assert(parsedMajorMinor === majorMinor, `versionMajorMinor does not match. ${tsFilePath}: '${parsedMajorMinor}'; package.json: '${majorMinor}'`);
|
||||
|
||||
const versionRgx = /export const version = `\$\{versionMajorMinor\}\.(\d)(-dev)?`;/;
|
||||
const patchMatch = versionRgx.exec(tsFileContents);
|
||||
assert(patchMatch !== null, "The file seems to no longer have a string matching " + versionRgx.toString());
|
||||
const parsedPatch = patchMatch[1];
|
||||
const parsedPatch = patchMatch![1];
|
||||
if (parsedPatch !== patch) {
|
||||
throw new Error(`patch does not match. ${tsFilePath}: '${parsedPatch}; package.json: '${patch}'`);
|
||||
}
|
||||
@@ -74,7 +74,7 @@ function parsePackageJsonVersion(versionString: string): { majorMinor: string, p
|
||||
const versionRgx = /(\d+\.\d+)\.(\d+)($|\-)/;
|
||||
const match = versionString.match(versionRgx);
|
||||
assert(match !== null, "package.json 'version' should match " + versionRgx.toString());
|
||||
return { majorMinor: match[1], patch: match[2] };
|
||||
return { majorMinor: match![1], patch: match![2] };
|
||||
}
|
||||
|
||||
/** e.g. 0-dev.20170707 */
|
||||
|
||||
@@ -19,7 +19,7 @@ const userName = process.env.GH_USERNAME;
|
||||
const reviewers = ["weswigham", "sandersn", "mhegazy"]
|
||||
const now = new Date();
|
||||
const branchName = `user-update-${now.getFullYear()}${padNum(now.getMonth())}${padNum(now.getDay())}`;
|
||||
const remoteUrl = `https://github.com/${userName}/TypeScript.git`;
|
||||
const remoteUrl = `https://${process.argv[2]}@github.com/${userName}/TypeScript.git`;
|
||||
runSequence([
|
||||
["git", ["checkout", "."]], // reset any changes
|
||||
["node", ["./node_modules/jake/bin/cli.js", "baseline-accept"]], // accept baselines
|
||||
@@ -27,7 +27,7 @@ runSequence([
|
||||
["git", ["add", "."]], // Add all changes
|
||||
["git", ["commit", "-m", `"Update user baselines"`]], // Commit all changes
|
||||
["git", ["remote", "add", "fork", remoteUrl]], // Add the remote fork
|
||||
["git", ["push", "--set-upstream", "fork", branchName]] // push the branch
|
||||
["git", ["push", "--set-upstream", "fork", branchName, "-f"]] // push the branch
|
||||
]);
|
||||
|
||||
const gh = new Octokit();
|
||||
@@ -44,6 +44,7 @@ gh.pullRequests.create({
|
||||
base: "master",
|
||||
body:
|
||||
`Please review the diff and merge if no changes are unexpected.
|
||||
You can view the build log [here](https://typescript.visualstudio.com/TypeScript/_build/index?buildId=${process.env.BUILD_BUILDID}&_a=summary).
|
||||
|
||||
cc ${reviewers.map(r => "@" + r).join(" ")}`,
|
||||
}).then(r => {
|
||||
|
||||
@@ -22,7 +22,7 @@ function main(): void {
|
||||
}
|
||||
|
||||
const inputFilePath = sys.args[0].replace(/\\/g, "/");
|
||||
const inputStr = sys.readFile(inputFilePath);
|
||||
const inputStr = sys.readFile(inputFilePath)!;
|
||||
|
||||
const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ function walk(ctx: Lint.WalkContext<void>, checkCatch: boolean, checkElse: boole
|
||||
return;
|
||||
}
|
||||
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile);
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile);
|
||||
const tryClosingBrace = tryBlock.getLastToken(sourceFile)!;
|
||||
const catchKeyword = catchClause.getFirstToken(sourceFile)!;
|
||||
const tryClosingBraceLoc = sourceFile.getLineAndCharacterOfPosition(tryClosingBrace.getEnd());
|
||||
const catchKeywordLoc = sourceFile.getLineAndCharacterOfPosition(catchKeyword.getStart(sourceFile));
|
||||
if (tryClosingBraceLoc.line === catchKeywordLoc.line) {
|
||||
|
||||
@@ -28,7 +28,7 @@ function walk(ctx: Lint.WalkContext<void>): void {
|
||||
}
|
||||
|
||||
function check(node: ts.UnaryExpression): void {
|
||||
if (!isAllowedLocation(node.parent!)) {
|
||||
if (!isAllowedLocation(node.parent)) {
|
||||
ctx.addFailureAtNode(node, Rule.POSTFIX_FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ function isAllowedLocation(node: ts.Node): boolean {
|
||||
// Can be in a comma operator in a for statement (`for (let a = 0, b = 10; a < b; a++, b--)`)
|
||||
case ts.SyntaxKind.BinaryExpression:
|
||||
return (node as ts.BinaryExpression).operatorToken.kind === ts.SyntaxKind.CommaToken &&
|
||||
node.parent!.kind === ts.SyntaxKind.ForStatement;
|
||||
node.parent.kind === ts.SyntaxKind.ForStatement;
|
||||
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016 Palantir Technologies, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as ts from "typescript";
|
||||
import * as Lint from "tslint";
|
||||
|
||||
export class Rule extends Lint.Rules.TypedRule {
|
||||
/* tslint:disable:object-literal-sort-keys */
|
||||
public static metadata: Lint.IRuleMetadata = {
|
||||
ruleName: "no-unnecessary-type-assertion",
|
||||
description: "Warns if a type assertion does not change the type of an expression.",
|
||||
options: {
|
||||
type: "list",
|
||||
listType: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
},
|
||||
},
|
||||
optionsDescription: "A list of whitelisted assertion types to ignore",
|
||||
type: "typescript",
|
||||
hasFix: true,
|
||||
typescriptOnly: true,
|
||||
requiresTypeInfo: true,
|
||||
};
|
||||
/* tslint:enable:object-literal-sort-keys */
|
||||
|
||||
public static FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression.";
|
||||
|
||||
public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.ruleName, this.ruleArguments, program.getTypeChecker()));
|
||||
}
|
||||
}
|
||||
|
||||
class Walker extends Lint.AbstractWalker<string[]> {
|
||||
constructor(sourceFile: ts.SourceFile, ruleName: string, options: string[], private readonly checker: ts.TypeChecker) {
|
||||
super(sourceFile, ruleName, options);
|
||||
}
|
||||
|
||||
public walk(sourceFile: ts.SourceFile) {
|
||||
const cb = (node: ts.Node): void => {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.TypeAssertionExpression:
|
||||
case ts.SyntaxKind.AsExpression:
|
||||
this.verifyCast(node as ts.TypeAssertion | ts.AsExpression);
|
||||
}
|
||||
|
||||
return ts.forEachChild(node, cb);
|
||||
};
|
||||
|
||||
return ts.forEachChild(sourceFile, cb);
|
||||
}
|
||||
|
||||
private verifyCast(node: ts.TypeAssertion | ts.NonNullExpression | ts.AsExpression) {
|
||||
if (ts.isAssertionExpression(node) && this.options.indexOf(node.type.getText(this.sourceFile)) !== -1) {
|
||||
return;
|
||||
}
|
||||
const castType = this.checker.getTypeAtLocation(node);
|
||||
if (castType === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.kind !== ts.SyntaxKind.NonNullExpression &&
|
||||
(castType.flags & ts.TypeFlags.Literal ||
|
||||
castType.flags & ts.TypeFlags.Object &&
|
||||
(castType as ts.ObjectType).objectFlags & ts.ObjectFlags.Tuple) ||
|
||||
// Sometimes tuple types don't have ObjectFlags.Tuple set, like when
|
||||
// they're being matched against an inferred type. So, in addition,
|
||||
// check if any properties are numbers, which implies that this is
|
||||
// likely a tuple type.
|
||||
(castType.getProperties().some((symbol) => !isNaN(Number(symbol.name))))) {
|
||||
|
||||
// It's not always safe to remove a cast to a literal type or tuple
|
||||
// type, as those types are sometimes widened without the cast.
|
||||
return;
|
||||
}
|
||||
|
||||
const uncastType = this.checker.getTypeAtLocation(node.expression);
|
||||
if (uncastType === castType) {
|
||||
this.addFailureAtNode(node, Rule.FAILURE_STRING, node.kind === ts.SyntaxKind.TypeAssertionExpression
|
||||
? Lint.Replacement.deleteFromTo(node.getStart(), node.expression.getStart())
|
||||
: Lint.Replacement.deleteFromTo(node.expression.getEnd(), node.getEnd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user