Merge pull request #18929 from amcasey/ExtractVoidNever

Stop extracting void and never constants
This commit is contained in:
Andrew Casey 2017-10-04 10:33:05 -07:00 committed by GitHub
commit d03d237b3b
2 changed files with 28 additions and 3 deletions

View File

@ -222,9 +222,21 @@ const f = () => {
testExtractConstant("extractConstant_ArrowFunction_Expression",
`const f = () => [#|2 + 1|];`);
testExtractConstantFailed("extractConstant_Void", `
function f(): void { }
[#|f();|]`);
testExtractConstantFailed("extractConstant_Never", `
function f(): never { }
[#|f();|]`);
});
function testExtractConstant(caption: string, text: string) {
testExtractSymbol(caption, text, "extractConstant", Diagnostics.Extract_constant);
}
function testExtractConstantFailed(caption: string, text: string) {
testExtractSymbolFailed(caption, text, Diagnostics.Extract_constant);
}
}

View File

@ -127,6 +127,7 @@ namespace ts.refactor.extractSymbol {
export const CannotExtractSuper: DiagnosticMessage = createMessage("Cannot extract super call.");
export const CannotExtractEmpty: DiagnosticMessage = createMessage("Cannot extract empty range.");
export const ExpressionExpected: DiagnosticMessage = createMessage("expression expected.");
export const UselessConstantType: DiagnosticMessage = createMessage("No reason to extract constant of type.");
export const StatementOrExpressionExpected: DiagnosticMessage = createMessage("Statement or expression expected.");
export const CannotExtractRangeContainingConditionalBreakOrContinueStatements: DiagnosticMessage = createMessage("Cannot extract range containing conditional break or continue statements.");
export const CannotExtractRangeContainingConditionalReturnStatement: DiagnosticMessage = createMessage("Cannot extract range containing conditional return statement.");
@ -1278,11 +1279,23 @@ namespace ts.refactor.extractSymbol {
const constantErrorsPerScope: Diagnostic[][] = [];
const visibleDeclarationsInExtractedRange: Symbol[] = [];
const expressionDiagnostic =
isReadonlyArray(targetRange.range) && !(targetRange.range.length === 1 && isExpressionStatement(targetRange.range[0]))
? ((start, end) => createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected))(first(targetRange.range).getStart(), last(targetRange.range).end)
const expression = !isReadonlyArray(targetRange.range)
? targetRange.range
: targetRange.range.length === 1 && isExpressionStatement(targetRange.range[0])
? (targetRange.range[0] as ExpressionStatement).expression
: undefined;
let expressionDiagnostic: Diagnostic | undefined = undefined;
if (expression === undefined) {
const statements = targetRange.range as ReadonlyArray<Statement>;
const start = first(statements).getStart();
const end = last(statements).end;
expressionDiagnostic = createFileDiagnostic(sourceFile, start, end - start, Messages.ExpressionExpected);
}
else if (checker.getTypeAtLocation(expression).flags & (TypeFlags.Void | TypeFlags.Never)) {
expressionDiagnostic = createDiagnosticForNode(expression, Messages.UselessConstantType);
}
// initialize results
for (const scope of scopes) {
usagesPerScope.push({ usages: createMap<UsageEntry>(), typeParameterUsages: createMap<TypeParameter>(), substitutions: createMap<() => Expression>() });