mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
fix(59304): Convert to ESM uses template strings instead of string literals (#59306)
This commit is contained in:
parent
66a762f59d
commit
bf39eccee6
@ -10,10 +10,12 @@ import {
|
||||
factory,
|
||||
first,
|
||||
getAllowSyntheticDefaultImports,
|
||||
getQuotePreference,
|
||||
getTokenAtPosition,
|
||||
Identifier,
|
||||
ImportSpecifier,
|
||||
isIdentifier,
|
||||
isNoSubstitutionTemplateLiteral,
|
||||
isObjectBindingPattern,
|
||||
isRequireCall,
|
||||
isVariableDeclaration,
|
||||
@ -21,10 +23,12 @@ import {
|
||||
NamedImports,
|
||||
ObjectBindingPattern,
|
||||
Program,
|
||||
QuotePreference,
|
||||
SourceFile,
|
||||
StringLiteralLike,
|
||||
textChanges,
|
||||
tryCast,
|
||||
UserPreferences,
|
||||
VariableStatement,
|
||||
} from "../_namespaces/ts.js";
|
||||
|
||||
@ -33,7 +37,7 @@ const errorCodes = [Diagnostics.require_call_may_be_converted_to_an_import.code]
|
||||
registerCodeFix({
|
||||
errorCodes,
|
||||
getCodeActions(context) {
|
||||
const info = getInfo(context.sourceFile, context.program, context.span.start);
|
||||
const info = getInfo(context.sourceFile, context.program, context.span.start, context.preferences);
|
||||
if (!info) {
|
||||
return undefined;
|
||||
}
|
||||
@ -43,7 +47,7 @@ registerCodeFix({
|
||||
fixIds: [fixId],
|
||||
getAllCodeActions: context =>
|
||||
codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const info = getInfo(diag.file, context.program, diag.start);
|
||||
const info = getInfo(diag.file, context.program, diag.start, context.preferences);
|
||||
if (info) {
|
||||
doChange(changes, context.sourceFile, info);
|
||||
}
|
||||
@ -51,13 +55,13 @@ registerCodeFix({
|
||||
});
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, info: Info) {
|
||||
const { allowSyntheticDefaults, defaultImportName, namedImports, statement, required } = info;
|
||||
const { allowSyntheticDefaults, defaultImportName, namedImports, statement, moduleSpecifier } = info;
|
||||
changes.replaceNode(
|
||||
sourceFile,
|
||||
statement,
|
||||
defaultImportName && !allowSyntheticDefaults
|
||||
? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(required))
|
||||
: factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports), required, /*attributes*/ undefined),
|
||||
? factory.createImportEqualsDeclaration(/*modifiers*/ undefined, /*isTypeOnly*/ false, defaultImportName, factory.createExternalModuleReference(moduleSpecifier))
|
||||
: factory.createImportDeclaration(/*modifiers*/ undefined, factory.createImportClause(/*isTypeOnly*/ false, defaultImportName, namedImports), moduleSpecifier, /*attributes*/ undefined),
|
||||
);
|
||||
}
|
||||
|
||||
@ -66,25 +70,27 @@ interface Info {
|
||||
readonly defaultImportName: Identifier | undefined;
|
||||
readonly namedImports: NamedImports | undefined;
|
||||
readonly statement: VariableStatement;
|
||||
readonly required: StringLiteralLike;
|
||||
readonly moduleSpecifier: StringLiteralLike;
|
||||
}
|
||||
|
||||
function getInfo(sourceFile: SourceFile, program: Program, pos: number): Info | undefined {
|
||||
function getInfo(sourceFile: SourceFile, program: Program, pos: number, preferences: UserPreferences): Info | undefined {
|
||||
const { parent } = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isRequireCall(parent, /*requireStringLiteralLikeArgument*/ true)) {
|
||||
Debug.failBadSyntaxKind(parent);
|
||||
}
|
||||
|
||||
const decl = cast(parent.parent, isVariableDeclaration);
|
||||
const quotePreference = getQuotePreference(sourceFile, preferences);
|
||||
const defaultImportName = tryCast(decl.name, isIdentifier);
|
||||
const namedImports = isObjectBindingPattern(decl.name) ? tryCreateNamedImportsFromObjectBindingPattern(decl.name) : undefined;
|
||||
if (defaultImportName || namedImports) {
|
||||
const moduleSpecifier = first(parent.arguments);
|
||||
return {
|
||||
allowSyntheticDefaults: getAllowSyntheticDefaultImports(program.getCompilerOptions()),
|
||||
defaultImportName,
|
||||
namedImports,
|
||||
statement: cast(decl.parent.parent, isVariableStatement),
|
||||
required: first(parent.arguments),
|
||||
moduleSpecifier: isNoSubstitutionTemplateLiteral(moduleSpecifier) ? factory.createStringLiteral(moduleSpecifier.text, quotePreference === QuotePreference.Single) : moduleSpecifier,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
10
tests/cases/fourslash/codeFixRequireInTs4.ts
Normal file
10
tests/cases/fourslash/codeFixRequireInTs4.ts
Normal file
@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////const foo = require(`foo`);
|
||||
|
||||
verify.codeFix({
|
||||
description: ts.Diagnostics.Convert_require_to_import.message,
|
||||
newFileContent: 'import foo = require("foo");',
|
||||
});
|
||||
|
||||
8
tests/cases/fourslash/codeFixRequireInTs5.ts
Normal file
8
tests/cases/fourslash/codeFixRequireInTs5.ts
Normal file
@ -0,0 +1,8 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /a.ts
|
||||
////const a = 1;
|
||||
////const b = 2;
|
||||
////const foo = require(`foo${a}${b}`);
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
Loading…
x
Reference in New Issue
Block a user