Fix some edge cases of semicolon deletion

This commit is contained in:
Andrew Branch committed 2019-09-11 10:35:52 -07:00
1 parent 7cae3cdbd1
commit e27bc9646a
9 files changed
+81 -18

No files matched your search

+7 -3
View File
@@ -1147,7 +1147,11 @@ namespace ts.formatting {
function recordDelete(start: number, len: number) {
if (len) {
edits.push(createTextChangeFromStartLength(start, len, ""));
const newEdit = createTextChangeFromStartLength(start, len, "");
const lastEdit = lastOrUndefined(edits);
if (!lastEdit || !textSpansEqual(lastEdit.span, newEdit.span) || lastEdit.newText !== newEdit.newText) {
edits.push(newEdit);
}
}
}
@@ -1157,7 +1161,7 @@ namespace ts.formatting {
}
}
function recordInsertionOnce(start: number, text: string) {
function recordInsert(start: number, text: string) {
if (text) {
const newEdit = createTextChangeFromStartLength(start, 0, text);
const lastEdit = lastOrUndefined(edits);
@@ -1216,7 +1220,7 @@ namespace ts.formatting {
}
break;
case RuleAction.TrailingSemicolon:
recordInsertionOnce(previousRange.end, ";");
recordInsert(previousRange.end, ";");
}
return LineAction.None;
}
+31 -1
View File
@@ -319,8 +319,34 @@ namespace ts.formatting {
function isSemicolonDeletionContext(context: FormattingContext): boolean {
if (context.TokensAreOnSameLine()) {
return context.nextTokenSpan.kind === SyntaxKind.CloseBraceToken;
return context.nextTokenSpan.kind === SyntaxKind.CloseBraceToken
|| context.nextTokenSpan.kind === SyntaxKind.EndOfFileToken;
}
if (context.nextTokenSpan.kind === SyntaxKind.SemicolonClassElement ||
context.nextTokenSpan.kind === SyntaxKind.SemicolonToken
) {
return false;
}
if (context.contextNode.kind === SyntaxKind.InterfaceDeclaration ||
context.contextNode.kind === SyntaxKind.TypeAliasDeclaration
) {
// Can’t remove semicolon after `foo`; it would parse as a
// method declaration:
// interface I {
// foo;
// (): void
// }
return !(isPropertySignature(context.currentTokenParent)
&& !context.currentTokenParent.type
&& context.nextTokenSpan.kind === SyntaxKind.OpenParenToken);
}
if (isPropertyDeclaration(context.currentTokenParent)) {
return !context.currentTokenParent.initializer;
}
return context.currentTokenParent.kind !== SyntaxKind.ForStatement
&& context.currentTokenParent.kind !== SyntaxKind.EmptyStatement
&& context.currentTokenParent.kind !== SyntaxKind.SemicolonClassElement
@@ -329,7 +355,11 @@ namespace ts.formatting {
&& context.nextTokenSpan.kind !== SyntaxKind.PlusToken
&& context.nextTokenSpan.kind !== SyntaxKind.MinusToken
&& context.nextTokenSpan.kind !== SyntaxKind.SlashToken
&& context.nextTokenSpan.kind !== SyntaxKind.RegularExpressionLiteral
&& context.nextTokenSpan.kind !== SyntaxKind.CommaToken
&& context.nextTokenSpan.kind !== SyntaxKind.TemplateExpression
&& context.nextTokenSpan.kind !== SyntaxKind.TemplateHead
&& context.nextTokenSpan.kind !== SyntaxKind.NoSubstitutionTemplateLiteral
&& context.nextTokenSpan.kind !== SyntaxKind.DotToken;
}
@@ -1,6 +1,6 @@
/// <reference path="fourslash.ts" />
////;(function f() { })();
////; (function f() { })();
////const a = 3;
////+ 4;
////const b = 3
@@ -8,6 +8,9 @@
////const c = 3 +
////4;
////class C {
//// prop;
//// ["p"];
//// zero: void;
//// ["one"] = {};
//// ["two"];
//// ;
@@ -21,28 +24,54 @@
////;
////[];
/////** blah */[0];
////interface I {
//// new;
//// ();
//// foo;
//// ();
////}
////type T = {
//// new;
//// ();
//// foo;
//// ();
////}
format.setFormatOptions({ ...format.copyFormatOptions(), insertTrailingSemicolon: false });
format.document();
verify.currentFileContentIs(`;(function f() { })()
verify.currentFileContentIs(`; (function f() { })()
const a = 3;
+ 4
const b = 3
+ 4
+ 4
const c = 3 +
4
4
class C {
prop
["p"]
zero: void
["one"] = {};
["two"];
;
}
a;
\`b\`;
\`b\`
b;
(3);
(3)
4;
/ regex /;
/ regex /;
;
[];
/** blah */[0]`);
/** blah */[0]
interface I {
new;
()
foo;
()
}
type T = {
new;
()
foo;
()
}`);