Skip to content

Commit 16d90f0

Browse files
committed
refactor and handle comment
1 parent af9552e commit 16d90f0

11 files changed

+84
-55
lines changed

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5561,7 +5561,7 @@
55615561
"category": "Message",
55625562
"code": 95109
55635563
},
5564-
"Wrap this object literal with parentheses": {
5564+
"Wrap the following body with parentheses which should be an object literal": {
55655565
"category": "Message",
55665566
"code": 95110
55675567
},

src/compiler/factoryPublic.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2042,6 +2042,25 @@ namespace ts {
20422042
: node;
20432043
}
20442044

2045+
export function updateFunctionLikeBody(declaration: FunctionLikeDeclaration, body: Block): FunctionLikeDeclaration {
2046+
switch (declaration.kind) {
2047+
case SyntaxKind.FunctionDeclaration:
2048+
return createFunctionDeclaration(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
2049+
case SyntaxKind.MethodDeclaration:
2050+
return createMethod(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.questionToken, declaration.typeParameters, declaration.parameters, declaration.type, body);
2051+
case SyntaxKind.GetAccessor:
2052+
return createGetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, declaration.type, body);
2053+
case SyntaxKind.SetAccessor:
2054+
return createSetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, body);
2055+
case SyntaxKind.Constructor:
2056+
return createConstructor(declaration.decorators, declaration.modifiers, declaration.parameters, body);
2057+
case SyntaxKind.FunctionExpression:
2058+
return createFunctionExpression(declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
2059+
case SyntaxKind.ArrowFunction:
2060+
return createArrowFunction(declaration.modifiers, declaration.typeParameters, declaration.parameters, declaration.type, declaration.equalsGreaterThanToken, body);
2061+
}
2062+
}
2063+
20452064
export function createClassDeclaration(
20462065
decorators: readonly Decorator[] | undefined,
20472066
modifiers: readonly Modifier[] | undefined,

src/services/codefixes/returnValueCorrect.ts

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ namespace ts.codefix {
1010
Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code
1111
];
1212

13-
enum FixKind {
13+
enum ProblemKind {
1414
MissingReturnStatement,
1515
MissingParentheses
1616
}
1717

1818
interface MissingReturnInfo {
19-
kind: FixKind.MissingReturnStatement;
19+
kind: ProblemKind.MissingReturnStatement;
2020
declaration: FunctionLikeDeclaration;
2121
expression: Expression;
2222
statement: Statement;
2323
}
2424

2525
interface MissingParenInfo {
26-
kind: FixKind.MissingParentheses;
26+
kind: ProblemKind.MissingParentheses;
2727
declaration: ArrowFunction;
2828
expression: Expression;
2929
statement: Statement;
@@ -39,7 +39,7 @@ namespace ts.codefix {
3939
const info = getInfo(program.getTypeChecker(), sourceFile, start, errorCode);
4040
if (!info) return undefined;
4141

42-
if (info.kind === FixKind.MissingReturnStatement) {
42+
if (info.kind === ProblemKind.MissingReturnStatement) {
4343
return append(
4444
[getActionForfixAddReturnStatement(context, info.expression, info.statement)],
4545
isArrowFunction(info.declaration) ? getActionForfixRemoveBlockBodyBrace(context, info.declaration, info.expression): undefined);
@@ -70,33 +70,14 @@ namespace ts.codefix {
7070
}),
7171
});
7272

73-
function updateFunctionLikeBody(declaration: FunctionLikeDeclaration, body: Block): FunctionLikeDeclaration {
74-
switch (declaration.kind) {
75-
case SyntaxKind.FunctionDeclaration:
76-
return createFunctionDeclaration(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
77-
case SyntaxKind.MethodDeclaration:
78-
return createMethod(declaration.decorators, declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.questionToken, declaration.typeParameters, declaration.parameters, declaration.type, body);
79-
case SyntaxKind.GetAccessor:
80-
return createGetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, declaration.type, body);
81-
case SyntaxKind.SetAccessor:
82-
return createSetAccessor(declaration.decorators, declaration.modifiers, declaration.name, declaration.parameters, body);
83-
case SyntaxKind.Constructor:
84-
return createConstructor(declaration.decorators, declaration.modifiers, declaration.parameters, body);
85-
case SyntaxKind.FunctionExpression:
86-
return createFunctionExpression(declaration.modifiers, declaration.asteriskToken, declaration.name, declaration.typeParameters, declaration.parameters, declaration.type, body);
87-
case SyntaxKind.ArrowFunction:
88-
return createArrowFunction(declaration.modifiers, declaration.typeParameters, declaration.parameters, declaration.type, declaration.equalsGreaterThanToken, body);
89-
}
90-
}
91-
9273
function getFixInfo(checker: TypeChecker, declaration: FunctionLikeDeclaration, expectType: Type, isFunctionType: boolean): Info | undefined {
9374
if (!declaration.body || !isBlock(declaration.body) || length(declaration.body.statements) !== 1) return undefined;
9475

9576
const firstStatement = first(declaration.body.statements);
9677
if (isExpressionStatement(firstStatement) && checkFixedAssignableTo(checker, declaration, firstStatement.expression, expectType, isFunctionType)) {
9778
return {
9879
declaration,
99-
kind: FixKind.MissingReturnStatement,
80+
kind: ProblemKind.MissingReturnStatement,
10081
expression: firstStatement.expression,
10182
statement: firstStatement
10283
};
@@ -106,12 +87,12 @@ namespace ts.codefix {
10687
if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) {
10788
return isArrowFunction(declaration) ? {
10889
declaration,
109-
kind: FixKind.MissingParentheses,
90+
kind: ProblemKind.MissingParentheses,
11091
expression: node,
11192
statement: firstStatement
11293
} : {
11394
declaration,
114-
kind: FixKind.MissingReturnStatement,
95+
kind: ProblemKind.MissingReturnStatement,
11596
expression: node,
11697
statement: firstStatement
11798
};
@@ -124,7 +105,7 @@ namespace ts.codefix {
124105
if (checkFixedAssignableTo(checker, declaration, node, expectType, isFunctionType)) {
125106
return {
126107
declaration,
127-
kind: FixKind.MissingReturnStatement,
108+
kind: ProblemKind.MissingReturnStatement,
128109
expression: node,
129110
statement: firstStatement
130111
};
@@ -183,11 +164,16 @@ namespace ts.codefix {
183164
}
184165

185166
function addReturnStatement(changes: textChanges.ChangeTracker, sourceFile: SourceFile, expression: Expression, statement: Statement) {
167+
suppressLeadingAndTrailingTrivia(expression);
186168
changes.replaceNode(sourceFile, statement, createReturn(expression));
187169
}
188170

189171
function removeBlockBodyBrace(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression, withParen: boolean) {
190-
changes.replaceNode(sourceFile, declaration.body, (withParen || needsParentheses(expression)) ? createParen(expression) : expression);
172+
const newBody = (withParen || needsParentheses(expression)) ? createParen(expression) : expression;
173+
suppressLeadingAndTrailingTrivia(expression);
174+
copyComments(expression, newBody);
175+
176+
changes.replaceNode(sourceFile, declaration.body, newBody);
191177
}
192178

193179
function wrapBlockWithParen(changes: textChanges.ChangeTracker, sourceFile: SourceFile, declaration: ArrowFunction, expression: Expression) {
@@ -206,6 +192,6 @@ namespace ts.codefix {
206192

207193
function getActionForfixWrapTheBlockWithParen(context: CodeFixContext, declaration: ArrowFunction, expression: Expression) {
208194
const changes = textChanges.ChangeTracker.with(context, t => wrapBlockWithParen(t, context.sourceFile, declaration, expression));
209-
return createCodeFixAction(fixId, changes, Diagnostics.Wrap_this_object_literal_with_parentheses, fixIdWrapTheBlockWithParen, Diagnostics.Wrap_all_object_literal_with_parentheses);
195+
return createCodeFixAction(fixId, changes, Diagnostics.Wrap_the_following_body_with_parentheses_which_should_be_an_object_literal, fixIdWrapTheBlockWithParen, Diagnostics.Wrap_all_object_literal_with_parentheses);
210196
}
211197
}

src/services/refactors/convertParamsToDestructuredObject.ts

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -491,27 +491,6 @@ namespace ts.refactor.convertParamsToDestructuredObject {
491491
}
492492
}
493493

494-
function copyComments(sourceNode: Node, targetNode: Node) {
495-
const sourceFile = sourceNode.getSourceFile();
496-
const text = sourceFile.text;
497-
if (hasLeadingLineBreak(sourceNode, text)) {
498-
copyLeadingComments(sourceNode, targetNode, sourceFile);
499-
}
500-
else {
501-
copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile);
502-
}
503-
copyTrailingComments(sourceNode, targetNode, sourceFile);
504-
}
505-
506-
function hasLeadingLineBreak(node: Node, text: string) {
507-
const start = node.getFullStart();
508-
const end = node.getStart();
509-
for (let i = start; i < end; i++) {
510-
if (text.charCodeAt(i) === CharacterCodes.lineFeed) return true;
511-
}
512-
return false;
513-
}
514-
515494
function getParameterName(paramDeclaration: ValidParameterDeclaration) {
516495
return getTextOfIdentifierOrLiteral(paramDeclaration.name);
517496
}

src/services/utilities.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2250,6 +2250,27 @@ namespace ts {
22502250
addEmitFlagsRecursively(node, EmitFlags.NoTrailingComments, getLastChild);
22512251
}
22522252

2253+
export function copyComments(sourceNode: Node, targetNode: Node) {
2254+
const sourceFile = sourceNode.getSourceFile();
2255+
const text = sourceFile.text;
2256+
if (hasLeadingLineBreak(sourceNode, text)) {
2257+
copyLeadingComments(sourceNode, targetNode, sourceFile);
2258+
}
2259+
else {
2260+
copyTrailingAsLeadingComments(sourceNode, targetNode, sourceFile);
2261+
}
2262+
copyTrailingComments(sourceNode, targetNode, sourceFile);
2263+
}
2264+
2265+
function hasLeadingLineBreak(node: Node, text: string) {
2266+
const start = node.getFullStart();
2267+
const end = node.getStart();
2268+
for (let i = start; i < end; i++) {
2269+
if (text.charCodeAt(i) === CharacterCodes.lineFeed) return true;
2270+
}
2271+
return false;
2272+
}
2273+
22532274
function addEmitFlagsRecursively(node: Node, flag: EmitFlags, getChild: (n: Node) => Node | undefined) {
22542275
addEmitFlags(node, flag);
22552276
const child = getChild(node);

tests/cases/fourslash/codeFixCorrectReturnValue14.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
//// }
99

1010
verify.codeFixAvailable([
11-
{ description: 'Wrap this object literal with parentheses' },
11+
{ description: 'Wrap the following body with parentheses which should be an object literal' },
1212
{ description: 'Remove unused label' },
1313
]);

tests/cases/fourslash/codeFixCorrectReturnValue15.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
//// Foo(() => { bar: '1' })
88

99
verify.codeFixAvailable([
10-
{ description: 'Wrap this object literal with parentheses' },
10+
{ description: 'Wrap the following body with parentheses which should be an object literal' },
1111
{ description: 'Remove unused label' },
1212
]);

tests/cases/fourslash/codeFixCorrectReturnValue16.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88
//// Foo(() => { bar: '1' })
99

1010
verify.codeFixAvailable([
11-
{ description: 'Wrap this object literal with parentheses' },
11+
{ description: 'Wrap the following body with parentheses which should be an object literal' },
1212
{ description: 'Remove unused label' },
1313
]);

tests/cases/fourslash/codeFixCorrectReturnValue19.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//// var x = <Comp t={() => { bar: '1' }} />;
1515

1616
verify.codeFixAvailable([
17-
{ description: 'Wrap this object literal with parentheses' },
17+
{ description: 'Wrap the following body with parentheses which should be an object literal' },
1818
{ description: `Infer type of 'props' from usage` },
1919
{ description: 'Remove unused label' },
2020
]);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
//// function Foo (a: () => number) { a() }
4+
//// Foo(() => { /* leading */ 1 /* trailing */ })
5+
6+
verify.codeFix({
7+
description: "Add a return statement",
8+
index: 0,
9+
newFileContent:
10+
`function Foo (a: () => number) { a() }
11+
Foo(() => { /* leading */ return 1 /* trailing */ })`
12+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
//// function Foo (a: () => number) { a() }
4+
//// Foo(() => { /* leading */ 1 /* trailing */ })
5+
6+
verify.codeFix({
7+
description: "Remove block body braces",
8+
index: 1,
9+
newFileContent:
10+
`function Foo (a: () => number) { a() }
11+
Foo(() => /* leading */ 1 /* trailing */)`
12+
})

0 commit comments

Comments
 (0)