MCPcopy Create free account
hub / github.com/Effect-TS/effect / transform

Function transform

packages/tools/doctest/src/Transform.ts:142–208  ·  view source on GitHub ↗
(source: string, file: string, line: number)

Source from the content-addressed store, hash-verified

140 * @since 4.0.0
141 */
142export const transform = (source: string, file: string, line: number): string => {
143 if (!source.includes("// =>")) return source
144
145 const parsed = parseSync(file, source, { lang: "ts" })
146 const parseError = parsed.errors[0]
147 if (parseError !== undefined) {
148 fail(source, parseError.labels[0]?.start ?? 0, file, line, `invalid doctest source: ${parseError.message}`)
149 }
150
151 const markers = parsed.comments.flatMap((comment) => {
152 if (comment.type !== "Line") return []
153 const match = markerPattern.exec(comment.value)
154 return match === null ? [] : [{ comment, expected: match[1].trim() }]
155 })
156 if (markers.length === 0) return source
157
158 const { candidates, names } = collect(parsed.program)
159 let index = 0
160 while (names.has(`${helper}${index}`)) index++
161 const alias = `${helper}${index}`
162 const output = new RolldownMagicString(source)
163
164 for (const { comment, expected } of markers) {
165 parseExpected(expected, source, comment.start, file, line)
166 const { node, parent } = assertionTarget(source, candidates, comment, file, line)
167
168 if (node.type === "ExpressionStatement") {
169 if (node.directive !== null) {
170 fail(source, comment.start, file, line, "doctest assertions cannot target directives")
171 }
172 const expression = isNode(node.expression)
173 ? node.expression
174 : fail(source, comment.start, file, line, "doctest assertion has no expression")
175 output.overwrite(
176 expression.start,
177 comment.end,
178 `${alias}(${source.slice(expression.start, expression.end)}, ${expected})`
179 )
180 continue
181 }
182
183 if (node.type === "VariableDeclaration" && parent?.type !== "ExportNamedDeclaration") {
184 const declarations = node.declarations
185 const declaration = Array.isArray(declarations) && declarations.length === 1 ? declarations[0] : undefined
186 const id = isNode(declaration) && isNode(declaration.id) ? declaration.id : undefined
187 if (
188 node.kind === "const" && node.declare === false && isNode(declaration?.init) &&
189 id?.type === "Identifier" && typeof id.name === "string"
190 ) {
191 const indentation = source.slice(source.lastIndexOf("\n", node.start - 1) + 1, node.start)
192 output.overwrite(node.end, comment.end, `\n${indentation}${alias}(${id.name}, ${expected})`)
193 continue
194 }
195 }
196
197 fail(
198 source,
199 comment.start,

Callers 2

Transform.test.tsFile · 0.90
loadFunction · 0.90

Calls 8

parseExpectedFunction · 0.85
assertionTargetFunction · 0.85
isNodeFunction · 0.85
execMethod · 0.80
failFunction · 0.70
collectFunction · 0.70
toStringMethod · 0.65
hasMethod · 0.45

Tested by

no test coverage detected