mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Fix semicolon removal before comments
This commit is contained in:
@@ -317,63 +317,6 @@ namespace ts.formatting {
|
||||
rule("OptionalSemicolon", anyToken, anyTokenIncludingEOF, [isOptionEnabled("insertTrailingSemicolon"), isSemicolonInsertionContext], RuleAction.TrailingSemicolon),
|
||||
];
|
||||
|
||||
function isSemicolonDeletionContext(context: FormattingContext): boolean {
|
||||
if (context.TokensAreOnSameLine()) {
|
||||
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
|
||||
&& context.nextTokenSpan.kind !== SyntaxKind.OpenBracketToken
|
||||
&& context.nextTokenSpan.kind !== SyntaxKind.OpenParenToken
|
||||
&& 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;
|
||||
}
|
||||
|
||||
function isSemicolonInsertionContext(context: FormattingContext): boolean {
|
||||
const contextAncestor = findAncestor(context.currentTokenParent, ancestor => {
|
||||
if (ancestor.end !== context.currentTokenSpan.end) {
|
||||
return "quit";
|
||||
}
|
||||
return syntaxMayBeASICandidate(ancestor.kind);
|
||||
});
|
||||
|
||||
return !!contextAncestor && isASICandidate(contextAncestor);
|
||||
}
|
||||
|
||||
// These rules are lower in priority than user-configurable. Rules earlier in this list have priority over rules later in the list.
|
||||
const lowPriorityCommonRules = [
|
||||
// Space after keyword but not before ; or : or ?
|
||||
@@ -833,4 +776,65 @@ namespace ts.formatting {
|
||||
function isNonNullAssertionContext(context: FormattingContext): boolean {
|
||||
return context.contextNode.kind === SyntaxKind.NonNullExpression;
|
||||
}
|
||||
|
||||
function isSemicolonDeletionContext(context: FormattingContext): boolean {
|
||||
if (context.TokensAreOnSameLine()) {
|
||||
return context.nextTokenSpan.kind === SyntaxKind.CloseBraceToken
|
||||
|| context.nextTokenSpan.kind === SyntaxKind.EndOfFileToken;
|
||||
}
|
||||
|
||||
const nextToken = isTrivia(context.nextTokenSpan.kind)
|
||||
? context.nextTokenParent.getChildAt(0)
|
||||
: context.nextTokenSpan;
|
||||
|
||||
if (nextToken.kind === SyntaxKind.SemicolonClassElement ||
|
||||
nextToken.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
|
||||
&& nextToken.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
|
||||
&& nextToken.kind !== SyntaxKind.OpenBracketToken
|
||||
&& nextToken.kind !== SyntaxKind.OpenParenToken
|
||||
&& nextToken.kind !== SyntaxKind.PlusToken
|
||||
&& nextToken.kind !== SyntaxKind.MinusToken
|
||||
&& nextToken.kind !== SyntaxKind.SlashToken
|
||||
&& nextToken.kind !== SyntaxKind.RegularExpressionLiteral
|
||||
&& nextToken.kind !== SyntaxKind.CommaToken
|
||||
&& nextToken.kind !== SyntaxKind.TemplateExpression
|
||||
&& nextToken.kind !== SyntaxKind.TemplateHead
|
||||
&& nextToken.kind !== SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
&& nextToken.kind !== SyntaxKind.DotToken;
|
||||
}
|
||||
|
||||
function isSemicolonInsertionContext(context: FormattingContext): boolean {
|
||||
const contextAncestor = findAncestor(context.currentTokenParent, ancestor => {
|
||||
if (ancestor.end !== context.currentTokenSpan.end) {
|
||||
return "quit";
|
||||
}
|
||||
return syntaxMayBeASICandidate(ancestor.kind);
|
||||
});
|
||||
|
||||
return !!contextAncestor && isASICandidate(contextAncestor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace ts.formatting {
|
||||
function getRuleActionExclusion(ruleAction: RuleAction): RuleAction {
|
||||
let mask: RuleAction = 0;
|
||||
if (ruleAction & RuleAction.Ignore) {
|
||||
return -1;
|
||||
mask |= RuleAction.TriviaAction;
|
||||
}
|
||||
if (ruleAction & RuleAction.TriviaAction) {
|
||||
mask |= RuleAction.TriviaAction;
|
||||
|
||||
@@ -758,7 +758,7 @@ namespace ts {
|
||||
insertSpaceBeforeFunctionParenthesis: false,
|
||||
placeOpenBraceOnNewLineForFunctions: false,
|
||||
placeOpenBraceOnNewLineForControlBlocks: false,
|
||||
// insertTrailingSemicolon: true,
|
||||
// insertTrailingSemicolon: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////interface I {
|
||||
//// a: string;
|
||||
//// /** @internal */
|
||||
//// b: string;
|
||||
////}
|
||||
|
||||
format.setFormatOptions({ ...format.copyFormatOptions(), insertTrailingSemicolon: false });
|
||||
format.document();
|
||||
verify.currentFileContentIs(`interface I {
|
||||
a: string
|
||||
/** @internal */
|
||||
b: string
|
||||
}`);
|
||||
Reference in New Issue
Block a user