mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
fix(49001): handle missing imports in addMissingMember QF (#49009)
This commit is contained in:
parent
c1c3ebcadf
commit
69214c0e56
@ -459,6 +459,7 @@ namespace ts.codefix {
|
||||
const importAdder = createImportAdder(context.sourceFile, context.program, context.preferences, context.host);
|
||||
const functionDeclaration = createSignatureDeclarationFromCallExpression(SyntaxKind.FunctionDeclaration, context, importAdder, info.call, idText(info.token), info.modifierFlags, info.parentDeclaration) as FunctionDeclaration;
|
||||
changes.insertNodeAtEndOfScope(info.sourceFile, info.parentDeclaration, functionDeclaration);
|
||||
importAdder.writeFixes(changes);
|
||||
}
|
||||
|
||||
function addJsxAttributes(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: JsxAttributesInfo) {
|
||||
@ -468,7 +469,7 @@ namespace ts.codefix {
|
||||
const jsxAttributesNode = info.parentDeclaration.attributes;
|
||||
const hasSpreadAttribute = some(jsxAttributesNode.properties, isJsxSpreadAttribute);
|
||||
const attrs = map(info.attributes, attr => {
|
||||
const value = tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeOfSymbol(attr));
|
||||
const value = tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeOfSymbol(attr), info.parentDeclaration);
|
||||
const name = factory.createIdentifier(attr.name);
|
||||
const jsxAttribute = factory.createJsxAttribute(name, factory.createJsxExpression(/*dotDotDotToken*/ undefined, value));
|
||||
// formattingScanner requires the Identifier to have a context for scanning attributes with "-" (data-foo).
|
||||
@ -478,6 +479,7 @@ namespace ts.codefix {
|
||||
const jsxAttributes = factory.createJsxAttributes(hasSpreadAttribute ? [...attrs, ...jsxAttributesNode.properties] : [...jsxAttributesNode.properties, ...attrs]);
|
||||
const options = { prefix: jsxAttributesNode.pos === jsxAttributesNode.end ? " " : undefined };
|
||||
changes.replaceNode(context.sourceFile, jsxAttributesNode, jsxAttributes, options);
|
||||
importAdder.writeFixes(changes);
|
||||
}
|
||||
|
||||
function addObjectLiteralProperties(changes: textChanges.ChangeTracker, context: CodeFixContextBase, info: ObjectLiteralInfo) {
|
||||
@ -486,7 +488,7 @@ namespace ts.codefix {
|
||||
const target = getEmitScriptTarget(context.program.getCompilerOptions());
|
||||
const checker = context.program.getTypeChecker();
|
||||
const props = map(info.properties, prop => {
|
||||
const initializer = tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeOfSymbol(prop));
|
||||
const initializer = tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeOfSymbol(prop), info.parentDeclaration);
|
||||
return factory.createPropertyAssignment(createPropertyNameNodeForIdentifierOrLiteral(prop.name, target, quotePreference === QuotePreference.Single), initializer);
|
||||
});
|
||||
const options = {
|
||||
@ -495,9 +497,10 @@ namespace ts.codefix {
|
||||
indentation: info.indentation
|
||||
};
|
||||
changes.replaceNode(context.sourceFile, info.parentDeclaration, factory.createObjectLiteralExpression([...info.parentDeclaration.properties, ...props], /*multiLine*/ true), options);
|
||||
importAdder.writeFixes(changes);
|
||||
}
|
||||
|
||||
function tryGetValueFromType(context: CodeFixContextBase, checker: TypeChecker, importAdder: ImportAdder, quotePreference: QuotePreference, type: Type): Expression {
|
||||
function tryGetValueFromType(context: CodeFixContextBase, checker: TypeChecker, importAdder: ImportAdder, quotePreference: QuotePreference, type: Type, enclosingDeclaration: Node | undefined): Expression {
|
||||
if (type.flags & TypeFlags.AnyOrUnknown) {
|
||||
return createUndefined();
|
||||
}
|
||||
@ -534,7 +537,7 @@ namespace ts.codefix {
|
||||
return factory.createNull();
|
||||
}
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
const expression = firstDefined((type as UnionType).types, t => tryGetValueFromType(context, checker, importAdder, quotePreference, t));
|
||||
const expression = firstDefined((type as UnionType).types, t => tryGetValueFromType(context, checker, importAdder, quotePreference, t, enclosingDeclaration));
|
||||
return expression ?? createUndefined();
|
||||
}
|
||||
if (checker.isArrayLikeType(type)) {
|
||||
@ -542,7 +545,7 @@ namespace ts.codefix {
|
||||
}
|
||||
if (isObjectLiteralType(type)) {
|
||||
const props = map(checker.getPropertiesOfType(type), prop => {
|
||||
const initializer = prop.valueDeclaration ? tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeAtLocation(prop.valueDeclaration)) : createUndefined();
|
||||
const initializer = prop.valueDeclaration ? tryGetValueFromType(context, checker, importAdder, quotePreference, checker.getTypeAtLocation(prop.valueDeclaration), enclosingDeclaration) : createUndefined();
|
||||
return factory.createPropertyAssignment(prop.name, initializer);
|
||||
});
|
||||
return factory.createObjectLiteralExpression(props, /*multiLine*/ true);
|
||||
@ -555,7 +558,7 @@ namespace ts.codefix {
|
||||
if (signature === undefined) return createUndefined();
|
||||
|
||||
const func = createSignatureDeclarationFromSignature(SyntaxKind.FunctionExpression, context, quotePreference, signature[0],
|
||||
createStubbedBody(Diagnostics.Function_not_implemented.message, quotePreference), /*name*/ undefined, /*modifiers*/ undefined, /*optional*/ undefined, /*enclosingDeclaration*/ undefined, importAdder) as FunctionExpression | undefined;
|
||||
createStubbedBody(Diagnostics.Function_not_implemented.message, quotePreference), /*name*/ undefined, /*modifiers*/ undefined, /*optional*/ undefined, /*enclosingDeclaration*/ enclosingDeclaration, importAdder) as FunctionExpression | undefined;
|
||||
return func ?? createUndefined();
|
||||
}
|
||||
if (getObjectFlags(type) & ObjectFlags.Class) {
|
||||
|
||||
29
tests/cases/fourslash/codeFixAddMissingProperties21.ts
Normal file
29
tests/cases/fourslash/codeFixAddMissingProperties21.ts
Normal file
@ -0,0 +1,29 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @filename: /a.ts
|
||||
////export type A = { x: string };
|
||||
|
||||
// @filename: /b.ts
|
||||
////import { A } from "./a";
|
||||
////export type Foo = { x: string };
|
||||
////export interface B {
|
||||
//// b(a: A): Foo;
|
||||
////}
|
||||
|
||||
// @filename: /c.ts
|
||||
////import { B } from "./b";
|
||||
////const b: B = {};
|
||||
|
||||
goTo.file("/c.ts");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: ts.Diagnostics.Add_missing_properties.message,
|
||||
newFileContent:
|
||||
`import { A } from "./a";
|
||||
import { B, Foo } from "./b";
|
||||
const b: B = {
|
||||
b: function(a: A): Foo {
|
||||
throw new Error("Function not implemented.");
|
||||
}
|
||||
};`,
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user