Add assert comments in CodeFixes and Refactors (#33016)

* Add comments to assert calls

* Add comments to assert calls in codefixes

* So linty
This commit is contained in:
Ryan Cavanaugh
2019-08-21 14:22:17 -07:00
committed by GitHub
parent f6155f89da
commit 016884d48c
18 changed files with 78 additions and 78 deletions

View File

@@ -14,7 +14,7 @@ namespace ts.codefix {
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
const token = getTokenAtPosition(sourceFile, pos);
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)));
const assertion = Debug.assertDefined(findAncestor(token, (n): n is AsExpression | TypeAssertion => isAsExpression(n) || isTypeAssertion(n)), "Expected to find an assertion expression");
const replacement = isAsExpression(assertion)
? createAsExpression(assertion.expression, createKeywordTypeNode(SyntaxKind.UnknownKeyword))
: createTypeAssertion(createKeywordTypeNode(SyntaxKind.UnknownKeyword), assertion.expression);

View File

@@ -60,8 +60,8 @@ namespace ts.codefix {
}
}
else {
const jsdocType = Debug.assertDefined(getJSDocType(decl)); // If not defined, shouldn't have been an error to fix
Debug.assert(!decl.type); // If defined, shouldn't have been an error to fix.
const jsdocType = Debug.assertDefined(getJSDocType(decl), "A JSDocType for this declaration should exist"); // If not defined, shouldn't have been an error to fix
Debug.assert(!decl.type, "The JSDocType decl should have a type"); // If defined, shouldn't have been an error to fix.
changes.tryInsertTypeAnnotation(sourceFile, decl, transformJSDocType(jsdocType));
}
}

View File

@@ -178,7 +178,7 @@ namespace ts.codefix {
// `const a = require("b").c` --> `import { c as a } from "./b";
return [makeSingleImport(name.text, propertyName, moduleSpecifier, quotePreference)];
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Convert to ES6 module got invalid syntax form ${(name as BindingName).kind}`);
}
}
@@ -238,7 +238,7 @@ namespace ts.codefix {
case SyntaxKind.MethodDeclaration:
return !isIdentifier(prop.name) ? undefined : functionExpressionToDeclaration(prop.name.text, [createToken(SyntaxKind.ExportKeyword)], prop);
default:
Debug.assertNever(prop);
Debug.assertNever(prop, `Convert to ES6 got invalid prop kind ${(prop as ObjectLiteralElementLike).kind}`);
}
});
return statements && [statements, false];
@@ -375,7 +375,7 @@ namespace ts.codefix {
case SyntaxKind.Identifier:
return convertSingleIdentifierImport(file, name, moduleSpecifier, changes, checker, identifiers, quotePreference);
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Convert to ES6 module got invalid name kind ${(name as BindingName).kind}`);
}
}
@@ -399,7 +399,7 @@ namespace ts.codefix {
const { parent } = use;
if (isPropertyAccessExpression(parent)) {
const { expression, name: { text: propertyName } } = parent;
Debug.assert(expression === use); // Else shouldn't have been in `collectIdentifiers`
Debug.assert(expression === use, "Didn't expect expression === use"); // Else shouldn't have been in `collectIdentifiers`
let idName = namedBindingsNames.get(propertyName);
if (idName === undefined) {
idName = makeUniqueName(propertyName, identifiers);

View File

@@ -19,8 +19,8 @@ namespace ts.codefix {
function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode {
const token = getTokenAtPosition(sourceFile, pos);
Debug.assert(token.kind === SyntaxKind.ImportKeyword);
Debug.assert(token.parent.kind === SyntaxKind.ImportType);
Debug.assert(token.kind === SyntaxKind.ImportKeyword, "This token should be an ImportKeyword");
Debug.assert(token.parent.kind === SyntaxKind.ImportType, "Token parent should be an ImportType");
return <ImportTypeNode>token.parent;
}

View File

@@ -28,7 +28,7 @@ namespace ts.codefix {
});
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos)));
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos)), "There should be a containing class");
}
function symbolPointsToNonPrivateMember (symbol: Symbol) {

View File

@@ -17,7 +17,7 @@ namespace ts.codefix {
function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration {
const token = getTokenAtPosition(sourceFile, pos);
Debug.assert(token.kind === SyntaxKind.ConstructorKeyword);
Debug.assert(token.kind === SyntaxKind.ConstructorKeyword, "token should be at the constructor keyword");
return token.parent as ConstructorDeclaration;
}

View File

@@ -36,12 +36,12 @@ namespace ts.codefix {
let suggestion: string | undefined;
if (isPropertyAccessExpression(node.parent) && node.parent.name === node) {
Debug.assert(node.kind === SyntaxKind.Identifier);
Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (property access)");
const containingType = checker.getTypeAtLocation(node.parent.expression);
suggestion = checker.getSuggestionForNonexistentProperty(node as Identifier, containingType);
}
else if (isImportSpecifier(node.parent) && node.parent.name === node) {
Debug.assert(node.kind === SyntaxKind.Identifier);
Debug.assert(node.kind === SyntaxKind.Identifier, "Expected an identifier for spelling (import)");
const importDeclaration = findAncestor(node, isImportDeclaration)!;
const resolvedSourceFile = getResolvedSourceFileFromImportDeclaration(sourceFile, context, importDeclaration);
if (resolvedSourceFile && resolvedSourceFile.symbol) {

View File

@@ -15,7 +15,7 @@ namespace ts.codefix {
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number, length: number): void {
const token = getTokenAtPosition(sourceFile, start);
const statement = findAncestor(token, isStatement)!;
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile), "token and statement should start at the same point");
const container = (isBlock(statement.parent) ? statement.parent : statement).parent;
if (!isBlock(statement.parent) || statement === first(statement.parent.statements)) {
@@ -40,7 +40,7 @@ namespace ts.codefix {
if (isBlock(statement.parent)) {
const end = start + length;
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end));
const lastStatement = Debug.assertDefined(lastWhere(sliceAfter(statement.parent.statements, statement), s => s.pos < end), "Some statement should be last");
changes.deleteNodeRange(sourceFile, statement, lastStatement);
}
else {

View File

@@ -117,7 +117,7 @@ namespace ts.codefix {
}
function deleteTypeParameters(changes: textChanges.ChangeTracker, sourceFile: SourceFile, token: Node): void {
changes.delete(sourceFile, Debug.assertDefined(cast(token.parent, isDeclarationWithTypeParameterChildren).typeParameters));
changes.delete(sourceFile, Debug.assertDefined(cast(token.parent, isDeclarationWithTypeParameterChildren).typeParameters, "The type parameter to delete should exist"));
}
// Sometimes the diagnostic span is an entire ImportDeclaration, so we should remove the whole thing.
@@ -231,7 +231,7 @@ namespace ts.codefix {
// Can't remove a non-last parameter in a callback. Can remove a parameter in code-fix-all if future parameters are also unused.
const { parameters } = parent;
const index = parameters.indexOf(p);
Debug.assert(index !== -1);
Debug.assert(index !== -1, "The parameter should already be in the list");
return isFixAll
? parameters.slice(index + 1).every(p => p.name.kind === SyntaxKind.Identifier && !p.symbol.isReferenced)
: index === parameters.length - 1;

View File

@@ -87,7 +87,7 @@ namespace ts.codefix {
ambient ? undefined : createStubbedMethodBody(preferences)));
}
else {
Debug.assertNode(accessor, isSetAccessorDeclaration);
Debug.assertNode(accessor, isSetAccessorDeclaration, "The counterpart to a getter should be a setter");
const parameter = getSetAccessorValueParameter(accessor);
const parameterName = parameter && isIdentifier(parameter.name) ? idText(parameter.name) : undefined;
out(createSetAccessor(
@@ -115,7 +115,7 @@ namespace ts.codefix {
}
if (declarations.length === 1) {
Debug.assert(signatures.length === 1);
Debug.assert(signatures.length === 1, "One declaration implies one signature");
const signature = signatures[0];
outputMethod(signature, modifiers, name, ambient ? undefined : createStubbedMethodBody(preferences));
break;
@@ -132,7 +132,7 @@ namespace ts.codefix {
outputMethod(signature, modifiers, name, createStubbedMethodBody(preferences));
}
else {
Debug.assert(declarations.length === signatures.length);
Debug.assert(declarations.length === signatures.length, "Declarations and signatures should match count");
out(createMethodImplementingSignatures(signatures, name, optional, modifiers, preferences));
}
}

View File

@@ -57,7 +57,7 @@ namespace ts.codefix {
pushIfUnique(entry.namedImports, symbolName);
}
else {
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add to Existing) Default import should be missing or match symbolName");
entry.defaultImport = symbolName;
}
break;
@@ -70,7 +70,7 @@ namespace ts.codefix {
}
switch (importKind) {
case ImportKind.Default:
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName);
Debug.assert(entry.defaultImport === undefined || entry.defaultImport === symbolName, "(Add new) Default import should be missing or match symbolName");
entry.defaultImport = symbolName;
break;
case ImportKind.Named:
@@ -78,14 +78,14 @@ namespace ts.codefix {
break;
case ImportKind.Equals:
case ImportKind.Namespace:
Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName);
Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName");
entry.namespaceLikeImport = { importKind, name: symbolName };
break;
}
break;
}
default:
Debug.assertNever(fix);
Debug.assertNever(fix, `fix wasn't never - got kind ${(fix as ImportFix).kind}`);
}
});
@@ -165,7 +165,7 @@ namespace ts.codefix {
preferences: UserPreferences,
): { readonly moduleSpecifier: string, readonly codeAction: CodeAction } {
const exportInfos = getAllReExportingModules(sourceFile, exportedSymbol, moduleSymbol, symbolName, sourceFile, program.getCompilerOptions(), program.getTypeChecker(), program.getSourceFiles());
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol));
Debug.assert(exportInfos.some(info => info.moduleSymbol === moduleSymbol), "Some exportInfo should match the specified moduleSymbol");
// We sort the best codefixes first, so taking `first` is best for completions.
const moduleSpecifier = first(getNewImportInfos(program, sourceFile, position, exportInfos, host, preferences)).moduleSpecifier;
const fix = first(getFixForImport(exportInfos, symbolName, position, program, sourceFile, host, preferences));
@@ -288,7 +288,7 @@ namespace ts.codefix {
moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap)
.map((moduleSpecifier): FixAddNewImport | FixUseImportType =>
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position) } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind }));
exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position, "position should be defined") } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind }));
// Sort to keep the shortest paths first
return sort(choicesForEachExportingModule, (a, b) => a.moduleSpecifier.length - b.moduleSpecifier.length);
}
@@ -369,7 +369,7 @@ namespace ts.codefix {
// Fall back to the `import * as ns` style import.
return ImportKind.Namespace;
default:
return Debug.assertNever(moduleKind);
return Debug.assertNever(moduleKind, `Unexpected moduleKind ${moduleKind}`);
}
}
@@ -382,7 +382,7 @@ namespace ts.codefix {
? checker.getJsxNamespace(sourceFile)
: symbolToken.text;
// "default" is a keyword and not a legal identifier for the import, so we don't expect it here
Debug.assert(symbolName !== InternalSymbolName.Default);
Debug.assert(symbolName !== InternalSymbolName.Default, "'default' isn't a legal identifier and couldn't occur here");
const fixes = arrayFrom(flatMapIterator(getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, checker, program).entries(), ([_, exportInfos]) =>
getFixForImport(exportInfos, symbolName, symbolToken.getStart(sourceFile), program, sourceFile, host, preferences)));
@@ -468,7 +468,7 @@ namespace ts.codefix {
if (defaultExport.flags & SymbolFlags.Alias) {
const aliased = checker.getImmediateAliasedSymbol(defaultExport);
return aliased && getDefaultExportInfoWorker(aliased, Debug.assertDefined(aliased.parent), checker, compilerOptions);
return aliased && getDefaultExportInfoWorker(aliased, Debug.assertDefined(aliased.parent, "Alias targets of default exports must have a parent"), checker, compilerOptions);
}
if (defaultExport.escapedName !== InternalSymbolName.Default &&
@@ -486,7 +486,7 @@ namespace ts.codefix {
}
}
else if (isExportSpecifier(declaration)) {
Debug.assert(declaration.name.text === InternalSymbolName.Default);
Debug.assert(declaration.name.text === InternalSymbolName.Default, "Expected the specifier to be a default export");
return declaration.propertyName && declaration.propertyName.text;
}
});
@@ -521,13 +521,13 @@ namespace ts.codefix {
return [importKind === ImportKind.Default ? Diagnostics.Import_default_0_from_module_1 : Diagnostics.Import_0_from_module_1, symbolName, moduleSpecifier];
}
default:
return Debug.assertNever(fix);
return Debug.assertNever(fix, `Unexpected fix kind ${(fix as ImportFix).kind}`);
}
}
function doAddExistingFix(changes: textChanges.ChangeTracker, sourceFile: SourceFile, clause: ImportClause, defaultImport: string | undefined, namedImports: ReadonlyArray<string>): void {
if (defaultImport) {
Debug.assert(!clause.name);
Debug.assert(!clause.name, "Default imports can't have names");
changes.insertNodeAt(sourceFile, clause.getStart(sourceFile), createIdentifier(defaultImport), { suffix: ", " });
}
@@ -545,7 +545,7 @@ namespace ts.codefix {
changes.replaceNode(sourceFile, clause.namedBindings, namedImports);
}
else {
changes.insertNodeAfter(sourceFile, Debug.assertDefined(clause.name), namedImports);
changes.insertNodeAfter(sourceFile, Debug.assertDefined(clause.name, "Named import specifiers must have names"), namedImports);
}
}
}

View File

@@ -211,7 +211,7 @@ namespace ts.codefix {
declaration: p,
type: isIdentifier(p.name) ? inferTypeForVariableFromUsage(p.name, program, cancellationToken) : program.getTypeChecker().getAnyType()
}));
Debug.assert(containingFunction.parameters.length === parameterInferences.length);
Debug.assert(containingFunction.parameters.length === parameterInferences.length, "Parameter count and inference count should match");
if (isInJSFile(containingFunction)) {
annotateJSDocParameters(changes, sourceFile, parameterInferences, program, host);
@@ -741,7 +741,7 @@ namespace ts.codefix {
for (const i of inferences) {
for (const { high, low } of priorities) {
if (high(i)) {
Debug.assert(!low(i));
Debug.assert(!low(i), "Priority can't have both low and high");
toRemove.push(low);
}
}

View File

@@ -12,8 +12,8 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault);
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, Debug.assertDefined(getInfo(context)), t, context.cancellationToken));
Debug.assert(actionName === actionNameDefaultToNamed || actionName === actionNameNamedToDefault, "Unexpected action name");
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, Debug.assertDefined(getInfo(context), "context must have info"), t, context.cancellationToken));
return { edits, renameFilename: undefined, renameLocation: undefined };
},
});
@@ -63,7 +63,7 @@ namespace ts.refactor {
}
const decl = first(vs.declarationList.declarations);
if (!decl.initializer) return undefined;
Debug.assert(!wasDefault);
Debug.assert(!wasDefault, "Can't have a default flag here");
return isIdentifier(decl.name) ? { exportNode: vs, exportName: decl.name, wasDefault, exportingModuleSymbol } : undefined;
}
default:
@@ -78,10 +78,10 @@ namespace ts.refactor {
function changeExport(exportingSourceFile: SourceFile, { wasDefault, exportNode, exportName }: Info, changes: textChanges.ChangeTracker, checker: TypeChecker): void {
if (wasDefault) {
changes.delete(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword)));
changes.delete(exportingSourceFile, Debug.assertDefined(findModifier(exportNode, SyntaxKind.DefaultKeyword), "Should find a default keyword in modifier list"));
}
else {
const exportKeyword = Debug.assertDefined(findModifier(exportNode, SyntaxKind.ExportKeyword));
const exportKeyword = Debug.assertDefined(findModifier(exportNode, SyntaxKind.ExportKeyword), "Should find an export keyword in modifier list");
switch (exportNode.kind) {
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.ClassDeclaration:
@@ -92,7 +92,7 @@ namespace ts.refactor {
// If 'x' isn't used in this file, `export const x = 0;` --> `export default 0;`
if (!FindAllReferences.Core.isSymbolReferencedInFile(exportName, checker, exportingSourceFile)) {
// We checked in `getInfo` that an initializer exists.
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer)));
changes.replaceNode(exportingSourceFile, exportNode, createExportDefault(Debug.assertDefined(first(exportNode.declarationList.declarations).initializer, "Initializer was previously known to be present")));
break;
}
// falls through
@@ -104,14 +104,14 @@ namespace ts.refactor {
changes.insertNodeAfter(exportingSourceFile, exportNode, createExportDefault(createIdentifier(exportName.text)));
break;
default:
Debug.assertNever(exportNode);
Debug.assertNever(exportNode, `Unexpected exportNode kind ${(exportNode as ExportToConvert).kind}`);
}
}
}
function changeImports(program: Program, { wasDefault, exportName, exportingModuleSymbol }: Info, changes: textChanges.ChangeTracker, cancellationToken: CancellationToken | undefined): void {
const checker = program.getTypeChecker();
const exportSymbol = Debug.assertDefined(checker.getSymbolAtLocation(exportName));
const exportSymbol = Debug.assertDefined(checker.getSymbolAtLocation(exportName), "Export name should resolve to a symbol");
FindAllReferences.Core.eachExportReference(program.getSourceFiles(), checker, cancellationToken, exportSymbol, exportingModuleSymbol, exportName.text, wasDefault, ref => {
const importingSourceFile = ref.getSourceFile();
if (wasDefault) {
@@ -139,7 +139,7 @@ namespace ts.refactor {
}
case SyntaxKind.ImportClause: {
const clause = parent as ImportClause;
Debug.assert(clause.name === ref);
Debug.assert(clause.name === ref, "Import clause name should match provided ref");
const spec = makeImportSpecifier(exportName, ref.text);
const { namedBindings } = clause;
if (!namedBindings) {
@@ -194,7 +194,7 @@ namespace ts.refactor {
break;
}
default:
Debug.assertNever(parent);
Debug.assertNever(parent, `Unexpected parent kind ${(parent as Node).kind}`);
}
}

View File

@@ -12,8 +12,8 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: actionName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace);
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, Debug.assertDefined(getImportToConvert(context))));
Debug.assert(actionName === actionNameNamespaceToNamed || actionName === actionNameNamedToNamespace, "Unexpected action name");
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, t, Debug.assertDefined(getImportToConvert(context), "Context must provide an import to convert")));
return { edits, renameFilename: undefined, renameLocation: undefined };
}
});
@@ -55,7 +55,7 @@ namespace ts.refactor {
if (checker.resolveName(exportName, id, SymbolFlags.All, /*excludeGlobals*/ true)) {
conflictingNames.set(exportName, true);
}
Debug.assert(parent.expression === id);
Debug.assert(parent.expression === id, "Parent expression should match id");
nodesToReplace.push(parent);
}
});

View File

@@ -24,7 +24,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
}
function getEditsForAction(context: RefactorContext, actionName: string): RefactorEditInfo | undefined {
Debug.assert(actionName === refactorName);
Debug.assert(actionName === refactorName, "Unexpected action name");
const { file, startPosition, program, cancellationToken, host } = context;
const functionDeclaration = getFunctionDeclarationAtPosition(file, startPosition, program.getTypeChecker());
if (!functionDeclaration || !cancellationToken) return undefined;
@@ -563,7 +563,7 @@ namespace ts.refactor.convertParamsToDestructuredObject {
if (functionDeclaration.name) return [functionDeclaration.name, functionDeclaration.parent.name];
return [functionDeclaration.parent.name];
default:
return Debug.assertNever(functionDeclaration);
return Debug.assertNever(functionDeclaration, `Unexpected function declaration kind ${(functionDeclaration as ValidFunctionDeclaration).kind}`);
}
}

View File

@@ -335,10 +335,10 @@ namespace ts.refactor.extractSymbol {
}
// We believe it's true because the node is from the (unmodified) tree.
Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
Debug.assert(nodeToCheck.pos <= nodeToCheck.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (1)");
// For understanding how skipTrivia functioned:
Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
Debug.assert(!positionIsSynthesized(nodeToCheck.pos), "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809 (2)");
if (!isStatement(nodeToCheck) && !(isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) {
return [createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)];
@@ -681,7 +681,7 @@ namespace ts.refactor.extractSymbol {
case SyntaxKind.SetAccessor:
return `'set ${scope.name.getText()}'`;
default:
throw Debug.assertNever(scope);
throw Debug.assertNever(scope, `Unexpected scope kind ${(scope as FunctionLikeDeclaration).kind}`);
}
}
function getDescriptionForClassLikeDeclaration(scope: ClassLikeDeclaration): string {
@@ -837,8 +837,8 @@ namespace ts.refactor.extractSymbol {
// No need to mix declarations and writes.
// How could any variables be exposed if there's a return statement?
Debug.assert(!returnValueProperty);
Debug.assert(!(range.facts & RangeFacts.HasReturn));
Debug.assert(!returnValueProperty, "Expected no returnValueProperty");
Debug.assert(!(range.facts & RangeFacts.HasReturn), "Expected RangeFacts.HasReturn flag to be unset");
if (exposedVariableDeclarations.length === 1) {
// Declaring exactly one variable: let x = newFunction();
@@ -928,7 +928,7 @@ namespace ts.refactor.extractSymbol {
if (assignments.length === 1) {
// We would only have introduced a return value property if there had been
// other assignments to make.
Debug.assert(!returnValueProperty);
Debug.assert(!returnValueProperty, "Shouldn't have returnValueProperty here");
newNodes.push(createStatement(createAssignment(assignments[0].name, call)));
@@ -1016,7 +1016,7 @@ namespace ts.refactor.extractSymbol {
const changeTracker = textChanges.ChangeTracker.fromContext(context);
if (isClassLike(scope)) {
Debug.assert(!isJS); // See CannotExtractToJSClass
Debug.assert(!isJS, "Cannot extract to a JS class"); // See CannotExtractToJSClass
const modifiers: Modifier[] = [];
modifiers.push(createToken(SyntaxKind.PrivateKeyword));
if (rangeFacts & RangeFacts.InStaticRegion) {
@@ -1255,7 +1255,7 @@ namespace ts.refactor.extractSymbol {
function getNodeToInsertPropertyBefore(maxPos: number, scope: ClassLikeDeclaration): ClassElement {
const members = scope.members;
Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one.
Debug.assert(members.length > 0, "Found no members"); // There must be at least one child, since we extracted from one.
let prevMember: ClassElement | undefined;
let allProperties = true;
@@ -1301,12 +1301,12 @@ namespace ts.refactor.extractSymbol {
if (!prevStatement && isCaseClause(curr)) {
// We must have been in the expression of the case clause.
Debug.assert(isSwitchStatement(curr.parent.parent));
Debug.assert(isSwitchStatement(curr.parent.parent), "Grandparent isn't a switch statement");
return curr.parent.parent;
}
// There must be at least one statement since we started in one.
return Debug.assertDefined(prevStatement);
return Debug.assertDefined(prevStatement, "prevStatement failed to get set");
}
Debug.assert(curr !== scope, "Didn't encounter a block-like before encountering scope");
@@ -1476,7 +1476,7 @@ namespace ts.refactor.extractSymbol {
// If we didn't get through all the scopes, then there were some that weren't in our
// parent chain (impossible at time of writing). A conservative solution would be to
// copy allTypeParameterUsages into all remaining scopes.
Debug.assert(i === scopes.length);
Debug.assert(i === scopes.length, "Should have iterated all scopes");
}
// If there are any declarations in the extracted block that are used in the same enclosing
@@ -1512,7 +1512,7 @@ namespace ts.refactor.extractSymbol {
});
// If an expression was extracted, then there shouldn't have been any variable declarations.
Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0);
Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0, "No variable declarations expected if something was extracted");
if (hasWrite && !isReadonlyArray(targetRange.range)) {
const diag = createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression);

View File

@@ -19,10 +19,10 @@ namespace ts.refactor {
}];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef);
Debug.assert(actionName === extractToTypeAlias || actionName === extractToTypeDef, "Unexpected action name");
const { file } = context;
const info = Debug.assertDefined(getRangeToExtract(context));
Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS);
const info = Debug.assertDefined(getRangeToExtract(context), "Expected to find a range to extract");
Debug.assert(actionName === extractToTypeAlias && !info.isJS || actionName === extractToTypeDef && info.isJS, "Invalid actionName/JS combo");
const name = getUniqueName("NewType", file);
const edits = textChanges.ChangeTracker.with(context, changes => info.isJS ?
@@ -47,7 +47,7 @@ namespace ts.refactor {
if (!selection || !isTypeNode(selection)) return undefined;
const checker = context.program.getTypeChecker();
const firstStatement = Debug.assertDefined(isJS ? findAncestor(selection, isStatementAndHasJSDoc) : findAncestor(selection, isStatement));
const firstStatement = Debug.assertDefined(isJS ? findAncestor(selection, isStatementAndHasJSDoc) : findAncestor(selection, isStatement), "Should find a statement");
const typeParameters = collectTypeParameters(checker, selection, firstStatement, file);
if (!typeParameters) return undefined;

View File

@@ -8,7 +8,7 @@ namespace ts.refactor {
return [{ name: refactorName, description, actions: [{ name: refactorName, description }] }];
},
getEditsForAction(context, actionName): RefactorEditInfo {
Debug.assert(actionName === refactorName);
Debug.assert(actionName === refactorName, "Wrong refactor invoked");
const statements = Debug.assertDefined(getStatementsToMove(context));
const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences));
return { edits, renameFilename: undefined, renameLocation: undefined };
@@ -184,7 +184,7 @@ namespace ts.refactor {
case SyntaxKind.VariableDeclaration:
return tryCast(node.name, isIdentifier);
default:
return Debug.assertNever(node);
return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`);
}
}
@@ -232,7 +232,7 @@ namespace ts.refactor {
case SyntaxKind.VariableDeclaration:
return createVariableDeclaration(newNamespaceId, /*type*/ undefined, createRequireCall(newModuleString));
default:
return Debug.assertNever(node);
return Debug.assertNever(node, `Unexpected node kind ${(node as SupportedImport).kind}`);
}
}
@@ -290,7 +290,7 @@ namespace ts.refactor {
return makeImportIfNecessary(defaultImport, specifiers, path, quotePreference);
}
else {
Debug.assert(!defaultImport); // If there's a default export, it should have been an es6 module.
Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module.
const bindingElements = imports.map(i => createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i));
return bindingElements.length
? makeVariableStatement(createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(createLiteral(path)))
@@ -332,7 +332,7 @@ namespace ts.refactor {
deleteUnusedImportsInVariableDeclaration(sourceFile, importDecl, changes, isUnused);
break;
default:
Debug.assertNever(importDecl);
Debug.assertNever(importDecl, `Unexpected import decl kind ${(importDecl as SupportedImport).kind}`);
}
}
function deleteUnusedImportsInDeclaration(sourceFile: SourceFile, importDecl: ImportDeclaration, changes: textChanges.ChangeTracker, isUnused: (name: Identifier) => boolean): void {
@@ -472,7 +472,7 @@ namespace ts.refactor {
for (const statement of toMove) {
forEachTopLevelDeclaration(statement, decl => {
movedSymbols.add(Debug.assertDefined(isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol));
movedSymbols.add(Debug.assertDefined(isExpressionStatement(decl) ? checker.getSymbolAtLocation(decl.expression.left) : decl.symbol, "Need a symbol here"));
});
}
for (const statement of toMove) {
@@ -565,7 +565,7 @@ namespace ts.refactor {
return name ? makeVariableStatement(name, i.type, createRequireCall(moduleSpecifier), i.parent.flags) : undefined;
}
default:
return Debug.assertNever(i);
return Debug.assertNever(i, `Unexpected import kind ${(i as SupportedImport).kind}`);
}
}
function filterNamedBindings(namedBindings: NamedImportBindings, keep: (name: Identifier) => boolean): NamedImportBindings | undefined {
@@ -654,7 +654,7 @@ namespace ts.refactor {
}
function isTopLevelDeclarationStatement(node: Node): node is TopLevelDeclarationStatement {
Debug.assert(isSourceFile(node.parent));
Debug.assert(isSourceFile(node.parent), "Node parent should be a SourceFile");
return isNonVariableTopLevelDeclaration(node) || isVariableStatement(node);
}
@@ -703,7 +703,7 @@ namespace ts.refactor {
case SyntaxKind.ObjectBindingPattern:
return firstDefined(name.elements, em => isOmittedExpression(em) ? undefined : forEachTopLevelDeclarationInBindingName(em.name, cb));
default:
return Debug.assertNever(name);
return Debug.assertNever(name, `Unexpected name kind ${(name as BindingName).kind}`);
}
}
@@ -768,7 +768,7 @@ namespace ts.refactor {
case SyntaxKind.ExpressionStatement:
return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
default:
return Debug.assertNever(d);
return Debug.assertNever(d, `Unexpected declaration kind ${(d as DeclarationStatement).kind}`);
}
}
function addCommonjsExport(decl: TopLevelDeclarationStatement): ReadonlyArray<Statement> | undefined {
@@ -788,9 +788,9 @@ namespace ts.refactor {
case SyntaxKind.ImportEqualsDeclaration:
return emptyArray;
case SyntaxKind.ExpressionStatement:
return Debug.fail(); // Shouldn't try to add 'export' keyword to `exports.x = ...`
return Debug.fail("Can't export an ExpressionStatement"); // Shouldn't try to add 'export' keyword to `exports.x = ...`
default:
return Debug.assertNever(decl);
return Debug.assertNever(decl, `Unexpected decl kind ${(decl as TopLevelDeclarationStatement).kind}`);
}
}