mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
format on open curly
This commit is contained in:
1 parent
47c1563649
commit
4c40c42f56
5 files changed
+54
-36
No files matched your search
@@ -97,11 +97,23 @@ namespace ts.formatting {
|
||||
}
|
||||
|
||||
export function formatOnSemicolon(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
|
||||
return formatOutermostParent(position, SyntaxKind.SemicolonToken, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnSemicolon);
|
||||
const outermostParent = findOutermostParentWithinListLevelFromPosition(position, SyntaxKind.SemicolonToken, sourceFile);
|
||||
return formatOutermostParent(outermostParent, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnSemicolon);
|
||||
}
|
||||
|
||||
export function formatOnOpeningCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
|
||||
const openingCurly = findPrecedingTokenOfKind(position, SyntaxKind.FirstPunctuation, sourceFile);
|
||||
const block = openingCurly && openingCurly.parent;
|
||||
if (!(block && isBlock(block))) {
|
||||
return [];
|
||||
}
|
||||
const outermostParent = findOutermostParentWithinListLevel(block);
|
||||
return formatOutermostParent(outermostParent, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnOpeningCurlyBrace);
|
||||
}
|
||||
|
||||
export function formatOnClosingCurly(position: number, sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
|
||||
return formatOutermostParent(position, SyntaxKind.CloseBraceToken, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnClosingCurlyBrace);
|
||||
const outermostParent = findOutermostParentWithinListLevelFromPosition(position, SyntaxKind.CloseBraceToken, sourceFile);
|
||||
return formatOutermostParent(outermostParent, sourceFile, options, rulesProvider, FormattingRequestKind.FormatOnClosingCurlyBrace);
|
||||
}
|
||||
|
||||
export function formatDocument(sourceFile: SourceFile, rulesProvider: RulesProvider, options: FormatCodeSettings): TextChange[] {
|
||||
@@ -121,44 +133,55 @@ namespace ts.formatting {
|
||||
return formatSpan(span, sourceFile, options, rulesProvider, FormattingRequestKind.FormatSelection);
|
||||
}
|
||||
|
||||
function formatOutermostParent(position: number, expectedLastToken: SyntaxKind, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] {
|
||||
const parent = findOutermostParent(position, expectedLastToken, sourceFile);
|
||||
function formatOutermostParent(parent: Node | undefined, sourceFile: SourceFile, options: FormatCodeSettings, rulesProvider: RulesProvider, requestKind: FormattingRequestKind): TextChange[] {
|
||||
if (!parent) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const span = {
|
||||
pos: getLineStartPositionForPosition(parent.getStart(sourceFile), sourceFile),
|
||||
end: parent.end
|
||||
};
|
||||
|
||||
return formatSpan(span, sourceFile, options, rulesProvider, requestKind);
|
||||
}
|
||||
|
||||
function findOutermostParent(position: number, expectedTokenKind: SyntaxKind, sourceFile: SourceFile): Node {
|
||||
function findPrecedingTokenOfKind(position: number, expectedTokenKind: SyntaxKind, sourceFile: SourceFile): Node | undefined {
|
||||
const precedingToken = findPrecedingToken(position, sourceFile);
|
||||
|
||||
// when it is claimed that trigger character was typed at given position
|
||||
// we verify that there is a token with a matching kind whose end is equal to position (because the character was just typed).
|
||||
// If this condition is not hold - then trigger character was typed in some other context,
|
||||
// i.e.in comment and thus should not trigger autoformatting
|
||||
if (!precedingToken ||
|
||||
precedingToken.kind !== expectedTokenKind ||
|
||||
position !== precedingToken.getEnd()) {
|
||||
return undefined;
|
||||
}
|
||||
return precedingToken && precedingToken.kind === expectedTokenKind && position === precedingToken.getEnd() ?
|
||||
precedingToken :
|
||||
undefined;
|
||||
}
|
||||
|
||||
// walk up and search for the parent node that ends at the same position with precedingToken.
|
||||
// for cases like this
|
||||
//
|
||||
// let x = 1;
|
||||
// while (true) {
|
||||
// }
|
||||
// after typing close curly in while statement we want to reformat just the while statement.
|
||||
// However if we just walk upwards searching for the parent that has the same end value -
|
||||
// we'll end up with the whole source file. isListElement allows to stop on the list element level
|
||||
let current = precedingToken;
|
||||
/**
|
||||
* Validating `expectedLastToken` ensures the token was typed in the context we expect (eg: not a comment).
|
||||
* @param expectedLastToken The last token constituting the desired parent node.
|
||||
*/
|
||||
function findOutermostParentWithinListLevelFromPosition(position: number, expectedLastToken: SyntaxKind, sourceFile: SourceFile) {
|
||||
const precedingToken = findPrecedingTokenOfKind(position, expectedLastToken, sourceFile);
|
||||
return precedingToken && findOutermostParentWithinListLevel(precedingToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the outermost parent within the same list level as the token at position.
|
||||
*
|
||||
* Consider typing the following
|
||||
* ```
|
||||
* let x = 1;
|
||||
* while (true) {
|
||||
* }
|
||||
* ```
|
||||
* Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
|
||||
* variable declaration.
|
||||
*/
|
||||
function findOutermostParentWithinListLevel(token: Node): Node {
|
||||
// If we walk upwards searching for the parent that has the same end value, we'll end up with the whole source file.
|
||||
// `isListElement` allows to stop on the list element level.
|
||||
let current = token;
|
||||
while (current &&
|
||||
current.parent &&
|
||||
current.parent.end === precedingToken.end &&
|
||||
current.parent.end === token.end &&
|
||||
!isListElement(current.parent, current)) {
|
||||
current = current.parent;
|
||||
}
|
||||
|
||||
@@ -47,14 +47,6 @@ namespace ts.formatting {
|
||||
return this.contextNodeAllOnSameLine;
|
||||
}
|
||||
|
||||
public NextNodeAllOnSameLine(): boolean {
|
||||
if (this.nextNodeAllOnSameLine === undefined) {
|
||||
this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent);
|
||||
}
|
||||
|
||||
return this.nextNodeAllOnSameLine;
|
||||
}
|
||||
|
||||
public TokensAreOnSameLine(): boolean {
|
||||
if (this.tokensAreOnSameLine === undefined) {
|
||||
const startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line;
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace ts.formatting {
|
||||
FormatSelection,
|
||||
FormatOnEnter,
|
||||
FormatOnSemicolon,
|
||||
FormatOnOpeningCurlyBrace,
|
||||
FormatOnClosingCurlyBrace
|
||||
}
|
||||
}
|
||||
@@ -671,7 +671,7 @@ namespace ts.formatting {
|
||||
|
||||
// This check is done before an open brace in a control construct, a function, or a typescript block declaration
|
||||
static IsBeforeMultilineBlockContext(context: FormattingContext): boolean {
|
||||
return Rules.IsBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine());
|
||||
return Rules.IsBeforeBlockContext(context) && !(context.NextNodeBlockIsOnOneLine());
|
||||
}
|
||||
|
||||
static IsMultilineBlockContext(context: FormattingContext): boolean {
|
||||
|
||||
@@ -1763,8 +1763,10 @@ namespace ts {
|
||||
function getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions | FormatCodeSettings): TextChange[] {
|
||||
const sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName);
|
||||
const settings = toEditorSettings(options);
|
||||
|
||||
if (key === "}") {
|
||||
if (key === "{") {
|
||||
return formatting.formatOnOpeningCurly(position, sourceFile, getRuleProvider(settings), settings);
|
||||
}
|
||||
else if (key === "}") {
|
||||
return formatting.formatOnClosingCurly(position, sourceFile, getRuleProvider(settings), settings);
|
||||
}
|
||||
else if (key === ";") {
|
||||
|
||||
Reference in new issue
Block a user