MCPcopy Create free account
hub / github.com/Rich-Harris/magic-string / expandReplacement

Function expandReplacement

src/MagicString.ts:62–138  ·  view source on GitHub ↗

* Expands the `$` substitution patterns that `String.prototype.replace` accepts * in a string replacement. * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter * * `captures` holds the capture groups in order, so `ca

(
  replacement: string,
  matched: string,
  position: number,
  str: string,
  captures: (string | undefined)[],
  namedCaptures: Record<string, string | undefined> | undefined,
)

Source from the content-addressed store, hash-verified

60 * value, where there are no groups of either kind.
61 */
62function expandReplacement(
63 replacement: string,
64 matched: string,
65 position: number,
66 str: string,
67 captures: (string | undefined)[],
68 namedCaptures: Record<string, string | undefined> | undefined,
69): string {
70 if (!replacement.includes('$'))
71 return replacement
72
73 let result = ''
74 let index = 0
75
76 while (index < replacement.length) {
77 const dollar = replacement.indexOf('$', index)
78 if (dollar === -1) {
79 result += replacement.slice(index)
80 break
81 }
82
83 result += replacement.slice(index, dollar)
84
85 const char = replacement[dollar + 1]
86 // a `$` that introduces nothing recognisable stands for itself, so consume
87 // only the `$` and reconsider what follows as text
88 let expansion = '$'
89 let consumed = 1
90
91 if (char === '$') {
92 consumed = 2
93 }
94 else if (char === '&') {
95 expansion = matched
96 consumed = 2
97 }
98 else if (char === '`') {
99 expansion = str.slice(0, position)
100 consumed = 2
101 }
102 else if (char === '\'') {
103 expansion = str.slice(position + matched.length)
104 consumed = 2
105 }
106 else if (char === '<' && namedCaptures !== undefined) {
107 const close = replacement.indexOf('>', dollar + 2)
108 if (close !== -1) {
109 // an unknown group name expands to nothing rather than staying literal
110 expansion = namedCaptures[replacement.slice(dollar + 2, close)] ?? ''
111 consumed = close + 1 - dollar
112 }
113 }
114 else if (char >= '0' && char <= '9') {
115 const second = replacement[dollar + 2]
116 const double = second >= '0' && second <= '9' ? Number(char + second) : Number.NaN
117 const single = Number(char)
118
119 // `$nn` only wins over `$n` when it names a group that exists, so `$12`

Callers 3

getReplacementMethod · 0.85
_replaceStringMethod · 0.85
_replaceAllStringMethod · 0.85

Calls 1

sliceMethod · 0.45

Tested by

no test coverage detected