1/* @internal */ 2namespace ts.codefix { 3 const fixIdExpression = "fixInvalidJsxCharacters_expression"; 4 const fixIdHtmlEntity = "fixInvalidJsxCharacters_htmlEntity"; 5 6 const errorCodes = [ 7 Diagnostics.Unexpected_token_Did_you_mean_or_gt.code, 8 Diagnostics.Unexpected_token_Did_you_mean_or_rbrace.code 9 ]; 10 11 registerCodeFix({ 12 errorCodes, 13 fixIds: [fixIdExpression, fixIdHtmlEntity], 14 getCodeActions(context) { 15 const { sourceFile, preferences, span } = context; 16 const changeToExpression = textChanges.ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ false)); 17 const changeToHtmlEntity = textChanges.ChangeTracker.with(context, t => doChange(t, preferences, sourceFile, span.start, /* useHtmlEntity */ true)); 18 19 return [ 20 createCodeFixAction(fixIdExpression, changeToExpression, Diagnostics.Wrap_invalid_character_in_an_expression_container, fixIdExpression, Diagnostics.Wrap_all_invalid_characters_in_an_expression_container), 21 createCodeFixAction(fixIdHtmlEntity, changeToHtmlEntity, Diagnostics.Convert_invalid_character_to_its_html_entity_code, fixIdHtmlEntity, Diagnostics.Convert_all_invalid_characters_to_HTML_entity_code) 22 ]; 23 }, 24 getAllCodeActions(context) { 25 return codeFixAll(context, errorCodes, (changes, diagnostic) => doChange(changes, context.preferences, diagnostic.file, diagnostic.start, context.fixId === fixIdHtmlEntity)); 26 } 27 }); 28 29 const htmlEntity = { 30 ">": ">", 31 "}": "}", 32 }; 33 34 function isValidCharacter(character: string): character is keyof typeof htmlEntity { 35 return hasProperty(htmlEntity, character); 36 } 37 38 function doChange(changes: textChanges.ChangeTracker, preferences: UserPreferences, sourceFile: SourceFile, start: number, useHtmlEntity: boolean) { 39 const character = sourceFile.getText()[start]; 40 // sanity check 41 if (!isValidCharacter(character)) { 42 return; 43 } 44 45 const replacement = useHtmlEntity ? htmlEntity[character] : `{${quote(sourceFile, preferences, character)}}`; 46 changes.replaceRangeWithText(sourceFile, { pos: start, end: start + 1 }, replacement); 47 } 48} 49