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

Function expandReplacement

src/MagicString.ts:61–137  ·  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

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