Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/services/codefixes/convertToEs6Module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ namespace ts.codefix {
changes.replaceNodeWithNodes(sourceFile, statement, newNodes);
}
else {
changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right), { useNonAdjustedEndPosition: true });
changes.replaceNode(sourceFile, statement, convertExportsDotXEquals(text, right));
}
}

Expand Down
25 changes: 5 additions & 20 deletions src/services/codefixes/disableJsDiagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace ts.codefix {
fixId: undefined,
}];

if (isValidSuppressLocation(sourceFile, span.start)) {
if (isValidLocationToAddComment(sourceFile, span.start)) {
fixes.unshift({
description: getLocaleSpecificMessage(Diagnostics.Ignore_this_error_message),
changes: textChanges.ChangeTracker.with(context, t => makeChange(t, sourceFile, span.start)),
Expand All @@ -41,37 +41,22 @@ namespace ts.codefix {
getAllCodeActions: context => {
const seenLines = createMap<true>();
return codeFixAll(context, errorCodes, (changes, diag) => {
if (isValidSuppressLocation(diag.file!, diag.start!)) {
if (isValidLocationToAddComment(diag.file!, diag.start!)) {
makeChange(changes, diag.file!, diag.start!, seenLines);
}
});
},
});

function isValidSuppressLocation(sourceFile: SourceFile, position: number) {
export function isValidLocationToAddComment(sourceFile: SourceFile, position: number) {
return !isInComment(sourceFile, position) && !isInString(sourceFile, position) && !isInTemplateString(sourceFile, position);
}

function makeChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, seenLines?: Map<true>) {
const { line: lineNumber } = getLineAndCharacterOfPosition(sourceFile, position);

// Only need to add `// @ts-ignore` for a line once.
if (seenLines && !addToSeen(seenLines, lineNumber)) {
return;
if (!seenLines || addToSeen(seenLines, lineNumber)) {
changes.insertCommentBeforeLine(sourceFile, lineNumber, position, " @ts-ignore");
}

const lineStartPosition = getStartPositionOfLine(lineNumber, sourceFile);
const startPosition = getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition);

// First try to see if we can put the '// @ts-ignore' on the previous line.
// We need to make sure that we are not in the middle of a string literal or a comment.
// If so, we do not want to separate the node from its comment if we can.
// Otherwise, add an extra new line immediately before the error span.
const insertAtLineStart = isValidSuppressLocation(sourceFile, startPosition);

const token = getTouchingToken(sourceFile, insertAtLineStart ? startPosition : position, /*includeJsDocComment*/ false);
const clone = setStartsOnNewLine(getSynthesizedDeepClone(token), true);
addSyntheticLeadingComment(clone, SyntaxKind.SingleLineCommentTrivia, " @ts-ignore");
changes.replaceNode(sourceFile, token, clone, { preserveLeadingWhitespace: true, prefix: insertAtLineStart ? undefined : changes.newLineCharacter });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace ts.codefix {
}

function doChanges(changes: textChanges.ChangeTracker, sourceFile: SourceFile, extendsToken: Node, heritageClauses: ReadonlyArray<HeritageClause>): void {
changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword), textChanges.useNonAdjustedPositions);
changes.replaceNode(sourceFile, extendsToken, createToken(SyntaxKind.ImplementsKeyword));

// If there is already an implements clause, replace the implements keyword with a comma.
if (heritageClauses.length === 2 &&
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/fixForgottenThisPropertyAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ namespace ts.codefix {
}
// TODO (https://github.com/Microsoft/TypeScript/issues/21246): use shared helper
suppressLeadingAndTrailingTrivia(token);
changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token), textChanges.useNonAdjustedPositions);
changes.replaceNode(sourceFile, token, createPropertyAccess(createThis(), token));
}
}
3 changes: 1 addition & 2 deletions src/services/codefixes/fixInvalidImportSyntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ namespace ts.codefix {
}

function createAction(context: CodeFixContext, sourceFile: SourceFile, node: Node, replacement: Node): CodeAction {
// TODO: GH#21246 Should be able to use `replaceNode`, but be sure to preserve comments (see `codeFixCalledES2015Import11.ts`)
const changes = textChanges.ChangeTracker.with(context, t => t.replaceRange(sourceFile, { pos: node.getStart(), end: node.end }, replacement));
const changes = textChanges.ChangeTracker.with(context, t => t.replaceNode(sourceFile, node, replacement));
return {
description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Replace_import_with_0), [changes[0].textChanges[0].newText]),
changes,
Expand Down
27 changes: 12 additions & 15 deletions src/services/codefixes/fixStrictClassInitialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,24 @@ namespace ts.codefix {
const propertyDeclaration = getPropertyDeclaration(context.sourceFile, context.span.start);
if (!propertyDeclaration) return;

const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options);
const result = [
getActionForAddMissingUndefinedType(context, propertyDeclaration),
getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration, newLineCharacter)
getActionForAddMissingDefiniteAssignmentAssertion(context, propertyDeclaration)
];

append(result, getActionForAddMissingInitializer(context, propertyDeclaration, newLineCharacter));
append(result, getActionForAddMissingInitializer(context, propertyDeclaration));

return result;
},
fixIds: [fixIdAddDefiniteAssignmentAssertions, fixIdAddUndefinedType, fixIdAddInitializer],
getAllCodeActions: context => {
const newLineCharacter = getNewLineOrDefaultFromHost(context.host, context.formatContext.options);

return codeFixAll(context, errorCodes, (changes, diag) => {
const propertyDeclaration = getPropertyDeclaration(diag.file, diag.start);
if (!propertyDeclaration) return;

switch (context.fixId) {
case fixIdAddDefiniteAssignmentAssertions:
addDefiniteAssignmentAssertion(changes, diag.file, propertyDeclaration, newLineCharacter);
addDefiniteAssignmentAssertion(changes, diag.file, propertyDeclaration);
break;
case fixIdAddUndefinedType:
addUndefinedType(changes, diag.file, propertyDeclaration);
Expand All @@ -40,7 +37,7 @@ namespace ts.codefix {
const initializer = getInitializer(checker, propertyDeclaration);
if (!initializer) return;

addInitializer(changes, diag.file, propertyDeclaration, initializer, newLineCharacter);
addInitializer(changes, diag.file, propertyDeclaration, initializer);
break;
default:
Debug.fail(JSON.stringify(context.fixId));
Expand All @@ -54,13 +51,13 @@ namespace ts.codefix {
return isIdentifier(token) ? cast(token.parent, isPropertyDeclaration) : undefined;
}

function getActionForAddMissingDefiniteAssignmentAssertion (context: CodeFixContext, propertyDeclaration: PropertyDeclaration, newLineCharacter: string): CodeFixAction {
function getActionForAddMissingDefiniteAssignmentAssertion (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction {
const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_definite_assignment_assertion_to_property_0), [propertyDeclaration.getText()]);
const changes = textChanges.ChangeTracker.with(context, t => addDefiniteAssignmentAssertion(t, context.sourceFile, propertyDeclaration, newLineCharacter));
const changes = textChanges.ChangeTracker.with(context, t => addDefiniteAssignmentAssertion(t, context.sourceFile, propertyDeclaration));
return { description, changes, fixId: fixIdAddDefiniteAssignmentAssertions };
}

function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, newLineCharacter: string): void {
function addDefiniteAssignmentAssertion(changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration): void {
const property = updateProperty(
propertyDeclaration,
propertyDeclaration.decorators,
Expand All @@ -70,7 +67,7 @@ namespace ts.codefix {
propertyDeclaration.type,
propertyDeclaration.initializer
);
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property, { suffix: newLineCharacter });
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
}

function getActionForAddMissingUndefinedType (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction {
Expand All @@ -85,17 +82,17 @@ namespace ts.codefix {
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration.type, createUnionTypeNode(types));
}

function getActionForAddMissingInitializer (context: CodeFixContext, propertyDeclaration: PropertyDeclaration, newLineCharacter: string): CodeFixAction | undefined {
function getActionForAddMissingInitializer (context: CodeFixContext, propertyDeclaration: PropertyDeclaration): CodeFixAction | undefined {
const checker = context.program.getTypeChecker();
const initializer = getInitializer(checker, propertyDeclaration);
if (!initializer) return undefined;

const description = formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Add_initializer_to_property_0), [propertyDeclaration.name.getText()]);
const changes = textChanges.ChangeTracker.with(context, t => addInitializer(t, context.sourceFile, propertyDeclaration, initializer, newLineCharacter));
const changes = textChanges.ChangeTracker.with(context, t => addInitializer(t, context.sourceFile, propertyDeclaration, initializer));
return { description, changes, fixId: fixIdAddInitializer };
}

function addInitializer (changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression, newLineCharacter: string): void {
function addInitializer (changeTracker: textChanges.ChangeTracker, propertyDeclarationSourceFile: SourceFile, propertyDeclaration: PropertyDeclaration, initializer: Expression): void {
const property = updateProperty(
propertyDeclaration,
propertyDeclaration.decorators,
Expand All @@ -105,7 +102,7 @@ namespace ts.codefix {
propertyDeclaration.type,
initializer
);
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property, { suffix: newLineCharacter });
changeTracker.replaceNode(propertyDeclarationSourceFile, propertyDeclaration, property);
}

function getInitializer(checker: TypeChecker, propertyDeclaration: PropertyDeclaration): Expression | undefined {
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/fixUnusedIdentifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ namespace ts.codefix {
// and trailing trivia will remain.
suppressLeadingAndTrailingTrivia(newFunction);

changes.replaceNode(sourceFile, oldFunction, newFunction, textChanges.useNonAdjustedPositions);
changes.replaceNode(sourceFile, oldFunction, newFunction);
}
else {
changes.deleteNodeInList(sourceFile, parent);
Expand Down
2 changes: 1 addition & 1 deletion src/services/codefixes/useDefaultImport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ namespace ts.codefix {
}

function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info): void {
changes.replaceNode(sourceFile, info.importNode, makeImportDeclaration(info.name, /*namedImports*/ undefined, info.moduleSpecifier), textChanges.useNonAdjustedPositions);
changes.replaceNode(sourceFile, info.importNode, makeImportDeclaration(info.name, /*namedImports*/ undefined, info.moduleSpecifier));
}
}
8 changes: 4 additions & 4 deletions src/services/refactors/extractSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ namespace ts.refactor.extractSymbol {
changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, /*blankLineBetween*/ true);

// Consume
changeTracker.replaceNode(context.file, node, localReference, textChanges.useNonAdjustedPositions);
changeTracker.replaceNode(context.file, node, localReference);
}
else {
const newVariableDeclaration = createVariableDeclaration(localNameText, variableType, initializer);
Expand All @@ -1070,15 +1070,15 @@ namespace ts.refactor.extractSymbol {

// Consume
const localReference = createIdentifier(localNameText);
changeTracker.replaceNode(context.file, node, localReference, textChanges.useNonAdjustedPositions);
changeTracker.replaceNode(context.file, node, localReference);
}
else if (node.parent.kind === SyntaxKind.ExpressionStatement && scope === findAncestor(node, isScope)) {
// If the parent is an expression statement and the target scope is the immediately enclosing one,
// replace the statement with the declaration.
const newVariableStatement = createVariableStatement(
/*modifiers*/ undefined,
createVariableDeclarationList([newVariableDeclaration], NodeFlags.Const));
changeTracker.replaceNode(context.file, node.parent, newVariableStatement, textChanges.useNonAdjustedPositions);
changeTracker.replaceNode(context.file, node.parent, newVariableStatement);
}
else {
const newVariableStatement = createVariableStatement(
Expand All @@ -1101,7 +1101,7 @@ namespace ts.refactor.extractSymbol {
}
else {
const localReference = createIdentifier(localNameText);
changeTracker.replaceNode(context.file, node, localReference, textChanges.useNonAdjustedPositions);
changeTracker.replaceNode(context.file, node, localReference);
}
}
}
Expand Down
Loading