mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
fix(49151): format type parameters/arguments (#49165)
Before, the formatter did not consider these constructs as comma separated lists in general, leading to wrong indentation of '>' after the list.
This commit is contained in:
parent
bf5acb5c4d
commit
44b9745942
@ -617,7 +617,6 @@ namespace ts.formatting {
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
case SyntaxKind.JsxClosingElement:
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@ -835,7 +834,7 @@ namespace ts.formatting {
|
||||
const listEndToken = getCloseTokenForOpenToken(listStartToken);
|
||||
if (listEndToken !== SyntaxKind.Unknown && formattingScanner.isOnToken() && formattingScanner.getStartPos() < originalRange.end) {
|
||||
let tokenInfo: TokenInfo | undefined = formattingScanner.readTokenInfo(parent);
|
||||
if (tokenInfo.token.kind === SyntaxKind.CommaToken && isCallLikeExpression(parent)) {
|
||||
if (tokenInfo.token.kind === SyntaxKind.CommaToken) {
|
||||
// consume the comma
|
||||
consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent);
|
||||
tokenInfo = formattingScanner.isOnToken() ? formattingScanner.readTokenInfo(parent) : undefined;
|
||||
@ -1311,6 +1310,12 @@ namespace ts.formatting {
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.MethodSignature:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
case SyntaxKind.CallSignature:
|
||||
case SyntaxKind.ConstructSignature:
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
case SyntaxKind.GetAccessor:
|
||||
case SyntaxKind.SetAccessor:
|
||||
if ((node as FunctionDeclaration).typeParameters === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
@ -1327,7 +1332,19 @@ namespace ts.formatting {
|
||||
return SyntaxKind.OpenParenToken;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
case SyntaxKind.ClassExpression:
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
if ((node as ClassDeclaration).typeParameters === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.TypeReference:
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.TypeQuery:
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
case SyntaxKind.ImportType:
|
||||
if ((node as TypeReferenceNode).typeArguments === list) {
|
||||
return SyntaxKind.LessThanToken;
|
||||
}
|
||||
|
||||
140
tests/cases/fourslash/genericsFormattingMultiline.ts
Normal file
140
tests/cases/fourslash/genericsFormattingMultiline.ts
Normal file
@ -0,0 +1,140 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////
|
||||
//// class Foo <
|
||||
//// T1 extends unknown,
|
||||
//// T2
|
||||
//// > {
|
||||
//// public method <
|
||||
//// T3,
|
||||
//// > (a: T1, b: Array <
|
||||
//// string
|
||||
//// > ): Map <
|
||||
//// T1 ,
|
||||
//// Array < T3 >
|
||||
//// > { throw new Error(); }
|
||||
//// }
|
||||
////
|
||||
//// interface IFoo<
|
||||
//// T,
|
||||
//// > {
|
||||
//// new < T
|
||||
//// > ( a: T);
|
||||
//// op?<
|
||||
//// T,
|
||||
//// M
|
||||
//// > (a: T, b : M );
|
||||
//// <
|
||||
//// T,
|
||||
//// >(x: T): T;
|
||||
//// }
|
||||
////
|
||||
//// type foo<
|
||||
//// T
|
||||
//// > = Foo <
|
||||
//// number, Array < number > > ;
|
||||
////
|
||||
//// function bar <
|
||||
//// T, U extends T
|
||||
//// > () {
|
||||
//// return class <
|
||||
//// T2,
|
||||
//// > {
|
||||
//// }
|
||||
//// }
|
||||
////
|
||||
//// bar<
|
||||
//// string,
|
||||
//// "s"
|
||||
//// > ();
|
||||
////
|
||||
//// declare const func: <
|
||||
//// T extends number[],
|
||||
//// > (x: T) => new <
|
||||
//// U
|
||||
//// > () => U;
|
||||
////
|
||||
//// class A < T > extends bar <
|
||||
//// T,number
|
||||
//// >( ) < T
|
||||
//// > {
|
||||
//// }
|
||||
////
|
||||
//// function s<T, U>(x: TemplateStringsArray, ...args: any[]) { return x.join(); }
|
||||
////
|
||||
//// const t = s<
|
||||
//// number ,
|
||||
//// string[] & ArrayLike<any>
|
||||
//// >`abc${1}def` ;
|
||||
////
|
||||
|
||||
|
||||
format.document();
|
||||
|
||||
verify.currentFileContentIs(`
|
||||
class Foo<
|
||||
T1 extends unknown,
|
||||
T2
|
||||
> {
|
||||
public method<
|
||||
T3,
|
||||
>(a: T1, b: Array<
|
||||
string
|
||||
>): Map<
|
||||
T1,
|
||||
Array<T3>
|
||||
> { throw new Error(); }
|
||||
}
|
||||
|
||||
interface IFoo<
|
||||
T,
|
||||
> {
|
||||
new <T
|
||||
>(a: T);
|
||||
op?<
|
||||
T,
|
||||
M
|
||||
>(a: T, b: M);
|
||||
<
|
||||
T,
|
||||
>(x: T): T;
|
||||
}
|
||||
|
||||
type foo<
|
||||
T
|
||||
> = Foo<
|
||||
number, Array<number>>;
|
||||
|
||||
function bar<
|
||||
T, U extends T
|
||||
>() {
|
||||
return class <
|
||||
T2,
|
||||
> {
|
||||
}
|
||||
}
|
||||
|
||||
bar<
|
||||
string,
|
||||
"s"
|
||||
>();
|
||||
|
||||
declare const func: <
|
||||
T extends number[],
|
||||
> (x: T) => new <
|
||||
U
|
||||
> () => U;
|
||||
|
||||
class A<T> extends bar<
|
||||
T, number
|
||||
>()<T
|
||||
> {
|
||||
}
|
||||
|
||||
function s<T, U>(x: TemplateStringsArray, ...args: any[]) { return x.join(); }
|
||||
|
||||
const t = s<
|
||||
number,
|
||||
string[] & ArrayLike<any>
|
||||
>\`abc\${1}def\`;
|
||||
`);
|
||||
Loading…
x
Reference in New Issue
Block a user