Skip to content

Commit d03d237

Browse files
authored
Merge pull request microsoft#18929 from amcasey/ExtractVoidNever
Stop extracting void and never constants
2 parents 6617819 + 443812a commit d03d237

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/harness/unittests/extractConstants.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,21 @@ const f = () => {
222222

223223
testExtractConstant("extractConstant_ArrowFunction_Expression",
224224
`const f = () => [#|2 + 1|];`);
225+
226+
testExtractConstantFailed("extractConstant_Void", `
227+
function f(): void { }
228+
[#|f();|]`);
229+
230+
testExtractConstantFailed("extractConstant_Never", `
231+
function f(): never { }
232+
[#|f();|]`);
225233
});
226234

227235
function testExtractConstant(caption: string, text: string) {
228236
testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant);
229237
}
238+
239+
function testExtractConstantFailed(caption: string, text: string) {
240+
testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant);
241+
}
230242
}

src/services/refactors/extractSymbol.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ namespace ts.refactor.extractSymbol {
127127
export const CannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call.");
128128
export const CannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range.");
129129
export const ExpressionExpected: DiagnosticMessage = createMessage("expression expected.");
130+
export const UselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type.");
130131
export const StatementOrExpressionExpected: DiagnosticMessage = createMessage("Statement or expression expected.");
131132
export const CannotExtractRangeContainingConditionalBreakOrContinueStatements: DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements.");
132133
export const CannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement.");
@@ -1278,11 +1279,23 @@ namespace ts.refactor.extractSymbol {
12781279
const constantErrorsPerScope: Diagnostic[][] = [];
12791280
const visibleDeclarationsInExtractedRange: Symbol[] = [];
12801281

1281-
const expressionDiagnostic =
1282-
isReadonlyArray(targetRange.range) && !(targetRange.range.length === 1 && isExpressionStatement(targetRange.range[0]))
1283-
? ((start, end) => createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected))(first(targetRange.range).getStart(), last(targetRange.range).end)
1282+
const expression = !isReadonlyArray(targetRange.range)
1283+
? targetRange.range
1284+
: targetRange.range.length === 1 && isExpressionStatement(targetRange.range[0])
1285+
? (targetRange.range[0] as ExpressionStatement).expression
12841286
: undefined;
12851287

1288+
let expressionDiagnostic: Diagnostic | undefined = undefined;
1289+
if (expression === undefined) {
1290+
const statements = targetRange.range as ReadonlyArray<Statement>;
1291+
const start = first(statements).getStart();
1292+
const end = last(statements).end;
1293+
expressionDiagnostic = createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected);
1294+
}
1295+
else if (checker.getTypeAtLocation(expression).flags & (TypeFlags.Void | TypeFlags.Never)) {
1296+
expressionDiagnostic = createDiagnosticForNode(expression, Messages.UselessConstantType);
1297+
}
1298+
12861299
// initialize results
12871300
for (const scope of scopes) {
12881301
usagesPerScope.push({ usages: createMap<UsageEntry>(), typeParameterUsages: createMap<TypeParameter>(), substitutions: createMap<() => Expression>() });

0 commit comments

Comments
 (0)