• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* @internal */
2namespace ts.codefix {
3    const errorCodes = [
4        Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property.code,
5        Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor.code,
6    ];
7    const fixId = "fixPropertyOverrideAccessor";
8    registerCodeFix({
9        errorCodes,
10        getCodeActions(context) {
11            const edits = doChange(context.sourceFile, context.span.start, context.span.length, context.errorCode, context);
12            if (edits) {
13                return [createCodeFixAction(fixId, edits, Diagnostics.Generate_get_and_set_accessors, fixId, Diagnostics.Generate_get_and_set_accessors_for_all_overriding_properties)];
14            }
15        },
16        fixIds: [fixId],
17
18        getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => {
19            const edits = doChange(diag.file, diag.start, diag.length, diag.code, context);
20            if (edits) {
21                for (const edit of edits) {
22                    changes.pushRaw(context.sourceFile, edit);
23                }
24            }
25        }),
26    });
27
28    function doChange(file: SourceFile, start: number, length: number, code: number, context: CodeFixContext | CodeFixAllContext) {
29        let startPosition: number;
30        let endPosition: number;
31        if (code === Diagnostics._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property.code) {
32            startPosition = start;
33            endPosition = start + length;
34        }
35        else if (code === Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor.code) {
36            const checker = context.program.getTypeChecker();
37            const node = getTokenAtPosition(file, start).parent;
38            Debug.assert(isAccessor(node), "error span of fixPropertyOverrideAccessor should only be on an accessor");
39            const containingClass = node.parent;
40            Debug.assert(isClassLike(containingClass), "erroneous accessors should only be inside classes");
41            const base = singleOrUndefined(getAllSupers(containingClass, checker));
42            if (!base) return [];
43
44            const name = unescapeLeadingUnderscores(getTextOfPropertyName(node.name));
45            const baseProp = checker.getPropertyOfType(checker.getTypeAtLocation(base), name);
46            if (!baseProp || !baseProp.valueDeclaration) return [];
47
48            startPosition = baseProp.valueDeclaration.pos;
49            endPosition = baseProp.valueDeclaration.end;
50            file = getSourceFileOfNode(baseProp.valueDeclaration);
51        }
52        else {
53            Debug.fail("fixPropertyOverrideAccessor codefix got unexpected error code " + code);
54        }
55        return generateAccessorFromProperty(file, context.program, startPosition, endPosition, context, Diagnostics.Generate_get_and_set_accessors.message);
56    }
57}
58