Apply formatting

This commit is contained in:
copilot-swe-agent[bot] 2025-07-25 18:11:09 +00:00
parent 963e16736e
commit 16955325a0

View File

@ -11,8 +11,8 @@ import {
CancellationToken,
canHaveDecorators,
canUsePropertyAccess,
CaseBlock,
CaseClause,
CaseBlock,
CaseClause,
cast,
CharacterCodes,
ClassElement,
@ -45,11 +45,11 @@ import {
createSortedArray,
createTextSpanFromBounds,
createTextSpanFromNode,
createTextSpanFromRange,
Debug,
Declaration,
DefaultClause,
createTextSpanFromRange,
Debug,
Declaration,
Decorator,
DefaultClause,
Diagnostics,
diagnosticToString,
displayPart,
@ -351,13 +351,13 @@ import {
skipAlias,
SnippetKind,
some,
SortedArray,
SourceFile,
SpreadAssignment,
startsWith,
stringToToken,
stripQuotes,
SwitchStatement,
SortedArray,
SourceFile,
SpreadAssignment,
startsWith,
stringToToken,
stripQuotes,
SwitchStatement,
Symbol,
SymbolDisplay,
SymbolDisplayPart,
@ -1267,88 +1267,88 @@ function keywordFiltersFromSyntaxKind(keywordCompletion: TokenSyntaxKind): Keywo
}
}
function getOptionalReplacementSpan(location: Node | undefined) {
// StringLiteralLike locations are handled separately in stringCompletions.ts
return location?.kind === SyntaxKind.Identifier ? createTextSpanFromNode(location) : undefined;
}
function shouldPrioritizeCaseAndDefaultKeywords(contextToken: Node | undefined, position: number): boolean {
if (!contextToken) return false;
// Check if we're in a switch statement context
const switchStatement = findAncestor(contextToken, node =>
node.kind === SyntaxKind.SwitchStatement ? true :
isFunctionLikeDeclaration(node) || isClassLike(node) ? "quit" :
false
) as SwitchStatement | undefined;
if (!switchStatement) return false;
const sourceFile = contextToken.getSourceFile();
const { line: currentLine, character: currentColumn } = getLineAndCharacterOfPosition(sourceFile, position);
// Case 1: Cursor is directly inside the switch block
// switch (thing) {
// /*cursor*/
// }
if (contextToken.parent === switchStatement.caseBlock) {
return true;
}
// Case 2: Cursor is at the same column as a case/default keyword but on a different line,
// with at least one statement in the previous clause that meets certain conditions
const caseBlock = switchStatement.caseBlock;
if (!caseBlock) return false;
// Find the last case/default clause before the cursor position
let lastClause: CaseClause | DefaultClause | undefined;
for (const clause of caseBlock.clauses) {
if (clause.pos >= position) break;
lastClause = clause;
}
if (!lastClause) return false;
// Check if cursor is at the same column as the last clause's keyword
const clauseKeywordPos = lastClause.kind === SyntaxKind.CaseClause ?
lastClause.getFirstToken(sourceFile)!.getStart(sourceFile) :
lastClause.getFirstToken(sourceFile)!.getStart(sourceFile);
const { line: clauseLine, character: clauseColumn } = getLineAndCharacterOfPosition(sourceFile, clauseKeywordPos);
if (currentLine === clauseLine || currentColumn !== clauseColumn) {
return false;
}
// Check if there's at least one statement in the clause
if (!lastClause.statements || lastClause.statements.length === 0) {
return false;
}
const lastStatement = lastClause.statements[lastClause.statements.length - 1];
// Get position of the last statement
const { line: stmtLine, character: stmtColumn } = getLineAndCharacterOfPosition(sourceFile, lastStatement.getStart(sourceFile));
// Check if it's a jump statement
const isJumpStatement = isBreakOrContinueStatement(lastStatement) ||
lastStatement.kind === SyntaxKind.ReturnStatement ||
lastStatement.kind === SyntaxKind.ThrowStatement;
if (isJumpStatement) {
// For jump statements: prioritize if on same line as case, or on different line with different indentation
if (stmtLine === clauseLine || (stmtLine !== clauseLine && stmtColumn !== clauseColumn)) {
return true;
}
} else {
// For non-jump statements: prioritize only if on different line and different column
if (stmtLine !== clauseLine && stmtColumn !== clauseColumn) {
return true;
}
}
return false;
}
function getOptionalReplacementSpan(location: Node | undefined) {
// StringLiteralLike locations are handled separately in stringCompletions.ts
return location?.kind === SyntaxKind.Identifier ? createTextSpanFromNode(location) : undefined;
}
function shouldPrioritizeCaseAndDefaultKeywords(contextToken: Node | undefined, position: number): boolean {
if (!contextToken) return false;
// Check if we're in a switch statement context
const switchStatement = findAncestor(contextToken, node =>
node.kind === SyntaxKind.SwitchStatement ? true :
isFunctionLikeDeclaration(node) || isClassLike(node) ? "quit" :
false) as SwitchStatement | undefined;
if (!switchStatement) return false;
const sourceFile = contextToken.getSourceFile();
const { line: currentLine, character: currentColumn } = getLineAndCharacterOfPosition(sourceFile, position);
// Case 1: Cursor is directly inside the switch block
// switch (thing) {
// /*cursor*/
// }
if (contextToken.parent === switchStatement.caseBlock) {
return true;
}
// Case 2: Cursor is at the same column as a case/default keyword but on a different line,
// with at least one statement in the previous clause that meets certain conditions
const caseBlock = switchStatement.caseBlock;
if (!caseBlock) return false;
// Find the last case/default clause before the cursor position
let lastClause: CaseClause | DefaultClause | undefined;
for (const clause of caseBlock.clauses) {
if (clause.pos >= position) break;
lastClause = clause;
}
if (!lastClause) return false;
// Check if cursor is at the same column as the last clause's keyword
const clauseKeywordPos = lastClause.kind === SyntaxKind.CaseClause ?
lastClause.getFirstToken(sourceFile)!.getStart(sourceFile) :
lastClause.getFirstToken(sourceFile)!.getStart(sourceFile);
const { line: clauseLine, character: clauseColumn } = getLineAndCharacterOfPosition(sourceFile, clauseKeywordPos);
if (currentLine === clauseLine || currentColumn !== clauseColumn) {
return false;
}
// Check if there's at least one statement in the clause
if (!lastClause.statements || lastClause.statements.length === 0) {
return false;
}
const lastStatement = lastClause.statements[lastClause.statements.length - 1];
// Get position of the last statement
const { line: stmtLine, character: stmtColumn } = getLineAndCharacterOfPosition(sourceFile, lastStatement.getStart(sourceFile));
// Check if it's a jump statement
const isJumpStatement = isBreakOrContinueStatement(lastStatement) ||
lastStatement.kind === SyntaxKind.ReturnStatement ||
lastStatement.kind === SyntaxKind.ThrowStatement;
if (isJumpStatement) {
// For jump statements: prioritize if on same line as case, or on different line with different indentation
if (stmtLine === clauseLine || (stmtLine !== clauseLine && stmtColumn !== clauseColumn)) {
return true;
}
}
else {
// For non-jump statements: prioritize only if on different line and different column
if (stmtLine !== clauseLine && stmtColumn !== clauseColumn) {
return true;
}
}
return false;
}
function completionInfoFromData(
sourceFile: SourceFile,
host: LanguageServiceHost,
@ -1448,22 +1448,22 @@ function completionInfoFromData(
includeSymbol,
);
if (keywordFilters !== KeywordCompletionFilters.None) {
const shouldPrioritizeCaseDefault = shouldPrioritizeCaseAndDefaultKeywords(contextToken, position);
for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) {
if (
isTypeOnlyLocation && isTypeKeyword(stringToToken(keywordEntry.name)!) ||
!isTypeOnlyLocation && isContextualKeywordInAutoImportableExpressionSpace(keywordEntry.name) ||
!uniqueNames.has(keywordEntry.name)
) {
uniqueNames.add(keywordEntry.name);
// Create a modified keyword entry with prioritized sort text for case/default in switch contexts
const modifiedKeywordEntry = shouldPrioritizeCaseDefault && (keywordEntry.name === "case" || keywordEntry.name === "default")
? { ...keywordEntry, sortText: SortText.LocalDeclarationPriority }
: keywordEntry;
insertSorted(entries, modifiedKeywordEntry, compareCompletionEntries, /*equalityComparer*/ undefined, /*allowDuplicates*/ true);
}
}
if (keywordFilters !== KeywordCompletionFilters.None) {
const shouldPrioritizeCaseDefault = shouldPrioritizeCaseAndDefaultKeywords(contextToken, position);
for (const keywordEntry of getKeywordCompletions(keywordFilters, !insideJsDocTagTypeExpression && isSourceFileJS(sourceFile))) {
if (
isTypeOnlyLocation && isTypeKeyword(stringToToken(keywordEntry.name)!) ||
!isTypeOnlyLocation && isContextualKeywordInAutoImportableExpressionSpace(keywordEntry.name) ||
!uniqueNames.has(keywordEntry.name)
) {
uniqueNames.add(keywordEntry.name);
// Create a modified keyword entry with prioritized sort text for case/default in switch contexts
const modifiedKeywordEntry = shouldPrioritizeCaseDefault && (keywordEntry.name === "case" || keywordEntry.name === "default")
? { ...keywordEntry, sortText: SortText.LocalDeclarationPriority }
: keywordEntry;
insertSorted(entries, modifiedKeywordEntry, compareCompletionEntries, /*equalityComparer*/ undefined, /*allowDuplicates*/ true);
}
}
}
for (const keywordEntry of getContextualKeywords(contextToken, position)) {
@ -4897,23 +4897,23 @@ function getCompletionData(
return undefined;
}
function tryGetFunctionLikeBodyCompletionContainer(contextToken: Node): FunctionLikeDeclaration | undefined {
if (contextToken) {
let prev: Node;
const container = findAncestor(contextToken.parent, (node: Node) => {
if (isClassLike(node)) {
return "quit";
}
if (isFunctionLikeDeclaration(node) && prev === node.body) {
return true;
}
prev = node;
return false;
});
return container && container as FunctionLikeDeclaration;
}
}
function tryGetFunctionLikeBodyCompletionContainer(contextToken: Node): FunctionLikeDeclaration | undefined {
if (contextToken) {
let prev: Node;
const container = findAncestor(contextToken.parent, (node: Node) => {
if (isClassLike(node)) {
return "quit";
}
if (isFunctionLikeDeclaration(node) && prev === node.body) {
return true;
}
prev = node;
return false;
});
return container && container as FunctionLikeDeclaration;
}
}
function tryGetContainingJsxElement(contextToken: Node): JsxOpeningLikeElement | undefined {
if (contextToken) {
const parent = contextToken.parent;