1/* @internal */ 2namespace ts.codefix { 3 const fixId = "fixIncorrectNamedTupleSyntax"; 4 const errorCodes = [ 5 Diagnostics.A_labeled_tuple_element_is_declared_as_optional_with_a_question_mark_after_the_name_and_before_the_colon_rather_than_after_the_type.code, 6 Diagnostics.A_labeled_tuple_element_is_declared_as_rest_with_a_before_the_name_rather_than_before_the_type.code 7 ]; 8 9 registerCodeFix({ 10 errorCodes, 11 getCodeActions: context => { 12 const { sourceFile, span } = context; 13 const namedTupleMember = getNamedTupleMember(sourceFile, span.start); 14 const changes = textChanges.ChangeTracker.with(context, t => doChange(t, sourceFile, namedTupleMember)); 15 return [createCodeFixAction(fixId, changes, Diagnostics.Move_labeled_tuple_element_modifiers_to_labels, fixId, Diagnostics.Move_labeled_tuple_element_modifiers_to_labels)]; 16 }, 17 fixIds: [fixId] 18 }); 19 20 function getNamedTupleMember(sourceFile: SourceFile, pos: number) { 21 const token = getTokenAtPosition(sourceFile, pos); 22 return findAncestor(token, t => t.kind === SyntaxKind.NamedTupleMember) as NamedTupleMember | undefined; 23 } 24 function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, namedTupleMember?: NamedTupleMember) { 25 if (!namedTupleMember) { 26 return; 27 } 28 let unwrappedType = namedTupleMember.type; 29 let sawOptional = false; 30 let sawRest = false; 31 while (unwrappedType.kind === SyntaxKind.OptionalType || unwrappedType.kind === SyntaxKind.RestType || unwrappedType.kind === SyntaxKind.ParenthesizedType) { 32 if (unwrappedType.kind === SyntaxKind.OptionalType) { 33 sawOptional = true; 34 } 35 else if (unwrappedType.kind === SyntaxKind.RestType) { 36 sawRest = true; 37 } 38 unwrappedType = (unwrappedType as OptionalTypeNode | RestTypeNode | ParenthesizedTypeNode).type; 39 } 40 const updated = factory.updateNamedTupleMember( 41 namedTupleMember, 42 namedTupleMember.dotDotDotToken || (sawRest ? factory.createToken(SyntaxKind.DotDotDotToken) : undefined), 43 namedTupleMember.name, 44 namedTupleMember.questionToken || (sawOptional ? factory.createToken(SyntaxKind.QuestionToken) : undefined), 45 unwrappedType 46 ); 47 if (updated === namedTupleMember) { 48 return; 49 } 50 changes.replaceNode(sourceFile, namedTupleMember, updated); 51 } 52} 53