| 405 | } |
| 406 | |
| 407 | function removeJSXAttribute(loc: {start: number; end: number}): void { |
| 408 | if (!s) return |
| 409 | // Walk backward from the value to find attribute name |
| 410 | let i = loc.start - 1 |
| 411 | // Skip the `=` |
| 412 | if (i >= 0 && code[i] === '=') i-- |
| 413 | // Walk backward through attribute name |
| 414 | while (i >= 0 && /[a-zA-Z0-9_$]/.test(code[i])) i-- |
| 415 | const attrStart = i + 1 |
| 416 | |
| 417 | const attrEnd = loc.end |
| 418 | |
| 419 | // Remove leading whitespace/newline before attribute name. |
| 420 | // We intentionally do NOT consume trailing whitespace so that when attributes |
| 421 | // are on the same line the space before the next attribute is preserved. |
| 422 | // e.g. `<FM description="x" defaultMessage="y" />` → `<FM defaultMessage="y" />` |
| 423 | let k = attrStart - 1 |
| 424 | while (k >= 0 && (code[k] === ' ' || code[k] === '\t')) k-- |
| 425 | // Also include the preceding newline for multi-line JSX so the whole line is removed. |
| 426 | if (k >= 0 && code[k] === '\n') k-- |
| 427 | if (k >= 0 && code[k] === '\r') k-- |
| 428 | const removeStart = k + 1 |
| 429 | |
| 430 | s.remove(removeStart, attrEnd) |
| 431 | } |
| 432 | |
| 433 | function getCalleeName(node: any): string | undefined { |
| 434 | if (node.type === 'Identifier') return node.name |