@openrewrite/rewrite 8.96.4 → 8.96.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/execution.d.ts +2 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +4 -0
- package/dist/execution.js.map +1 -1
- package/dist/heavyweight.d.ts +8 -0
- package/dist/heavyweight.d.ts.map +1 -0
- package/dist/heavyweight.js +45 -0
- package/dist/heavyweight.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/java/visitor.d.ts.map +1 -1
- package/dist/java/visitor.js +16 -2
- package/dist/java/visitor.js.map +1 -1
- package/dist/javascript/add-import.d.ts +2 -1
- package/dist/javascript/add-import.d.ts.map +1 -1
- package/dist/javascript/add-import.js +14 -2
- package/dist/javascript/add-import.js.map +1 -1
- package/dist/javascript/amd.d.ts.map +1 -1
- package/dist/javascript/amd.js +2 -1
- package/dist/javascript/amd.js.map +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js +1 -1
- package/dist/javascript/cleanup/add-parse-int-radix.js.map +1 -1
- package/dist/javascript/format/format.d.ts +10 -0
- package/dist/javascript/format/format.d.ts.map +1 -1
- package/dist/javascript/format/format.js +10 -2
- package/dist/javascript/format/format.js.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.d.ts.map +1 -1
- package/dist/javascript/format/tabs-and-indents-visitor.js +4 -0
- package/dist/javascript/format/tabs-and-indents-visitor.js.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.d.ts.map +1 -1
- package/dist/javascript/format/whitespace-reconciler.js +4 -0
- package/dist/javascript/format/whitespace-reconciler.js.map +1 -1
- package/dist/javascript/node-resolution-result.d.ts.map +1 -1
- package/dist/javascript/node-resolution-result.js +2 -0
- package/dist/javascript/node-resolution-result.js.map +1 -1
- package/dist/javascript/parser-utils.d.ts.map +1 -1
- package/dist/javascript/parser-utils.js +9 -6
- package/dist/javascript/parser-utils.js.map +1 -1
- package/dist/javascript/templating/engine.d.ts.map +1 -1
- package/dist/javascript/templating/engine.js +11 -6
- package/dist/javascript/templating/engine.js.map +1 -1
- package/dist/javascript/templating/pattern.d.ts.map +1 -1
- package/dist/javascript/templating/pattern.js +8 -0
- package/dist/javascript/templating/pattern.js.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -1
- package/dist/javascript/templating/placeholder-replacement.js +15 -0
- package/dist/javascript/templating/placeholder-replacement.js.map +1 -1
- package/dist/javascript/visitor.d.ts.map +1 -1
- package/dist/javascript/visitor.js +21 -0
- package/dist/javascript/visitor.js.map +1 -1
- package/dist/recipe.d.ts +5 -0
- package/dist/recipe.d.ts.map +1 -1
- package/dist/recipe.js +5 -0
- package/dist/recipe.js.map +1 -1
- package/dist/rewrite-javascript-version.txt +1 -1
- package/dist/run.d.ts +7 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +40 -2
- package/dist/run.js.map +1 -1
- package/dist/test/accumulator-contents.d.ts +15 -0
- package/dist/test/accumulator-contents.d.ts.map +1 -0
- package/dist/test/accumulator-contents.js +185 -0
- package/dist/test/accumulator-contents.js.map +1 -0
- package/dist/test/empty-sources.d.ts +14 -0
- package/dist/test/empty-sources.d.ts.map +1 -0
- package/dist/test/empty-sources.js +98 -0
- package/dist/test/empty-sources.js.map +1 -0
- package/dist/test/formatting-scope.d.ts +18 -0
- package/dist/test/formatting-scope.d.ts.map +1 -0
- package/dist/test/formatting-scope.js +244 -0
- package/dist/test/formatting-scope.js.map +1 -0
- package/dist/test/probes.d.ts +25 -0
- package/dist/test/probes.d.ts.map +1 -0
- package/dist/test/probes.js +189 -0
- package/dist/test/probes.js.map +1 -0
- package/dist/test/rewrite-test.d.ts +27 -0
- package/dist/test/rewrite-test.d.ts.map +1 -1
- package/dist/test/rewrite-test.js +191 -21
- package/dist/test/rewrite-test.js.map +1 -1
- package/dist/test/tree-shapes.d.ts +15 -0
- package/dist/test/tree-shapes.d.ts.map +1 -0
- package/dist/test/tree-shapes.js +288 -0
- package/dist/test/tree-shapes.js.map +1 -0
- package/dist/test/unparsed-sources.d.ts +17 -0
- package/dist/test/unparsed-sources.d.ts.map +1 -0
- package/dist/test/unparsed-sources.js +113 -0
- package/dist/test/unparsed-sources.js.map +1 -0
- package/dist/tree.d.ts.map +1 -1
- package/dist/tree.js +2 -0
- package/dist/tree.js.map +1 -1
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +2 -0
- package/dist/visitor.js.map +1 -1
- package/package.json +1 -1
- package/src/execution.ts +6 -0
- package/src/heavyweight.ts +42 -0
- package/src/index.ts +1 -0
- package/src/java/visitor.ts +16 -2
- package/src/javascript/add-import.ts +11 -2
- package/src/javascript/amd.ts +4 -2
- package/src/javascript/cleanup/add-parse-int-radix.ts +2 -2
- package/src/javascript/format/format.ts +18 -0
- package/src/javascript/format/tabs-and-indents-visitor.ts +4 -0
- package/src/javascript/format/whitespace-reconciler.ts +4 -0
- package/src/javascript/node-resolution-result.ts +3 -0
- package/src/javascript/parser-utils.ts +10 -6
- package/src/javascript/templating/engine.ts +11 -6
- package/src/javascript/templating/pattern.ts +10 -0
- package/src/javascript/templating/placeholder-replacement.ts +16 -0
- package/src/javascript/visitor.ts +30 -0
- package/src/recipe.ts +5 -0
- package/src/run.ts +30 -2
- package/src/test/accumulator-contents.ts +194 -0
- package/src/test/empty-sources.ts +99 -0
- package/src/test/formatting-scope.ts +231 -0
- package/src/test/probes.ts +156 -0
- package/src/test/rewrite-test.ts +177 -24
- package/src/test/tree-shapes.ts +332 -0
- package/src/test/unparsed-sources.ts +138 -0
- package/src/tree.ts +3 -0
- package/src/visitor.ts +3 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AccumulatorContents = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright 2025 the original author or authors.
|
|
6
|
+
* <p>
|
|
7
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
* <p>
|
|
11
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
12
|
+
* <p>
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
const util_1 = require("util");
|
|
20
|
+
const recipe_1 = require("../recipe");
|
|
21
|
+
const tree_1 = require("../tree");
|
|
22
|
+
const heavyweight_1 = require("../heavyweight");
|
|
23
|
+
const java_1 = require("../java");
|
|
24
|
+
const probes_1 = require("./probes");
|
|
25
|
+
/** Beyond this many objects in one accumulator the walk stops descending. */
|
|
26
|
+
const MAX_OBJECTS = 100000;
|
|
27
|
+
const MAX_PATHS = 5;
|
|
28
|
+
/**
|
|
29
|
+
* Finds the heavyweight objects that ScanningRecipe accumulators keep, which are trees and the types
|
|
30
|
+
* registerHeavyweight registers. An accumulator lives from the first source file scanned until the cycle ends. The
|
|
31
|
+
* walk reads data properties and built-in collections, and runs no code of the recipe's own.
|
|
32
|
+
*/
|
|
33
|
+
class AccumulatorContents {
|
|
34
|
+
constructor() {
|
|
35
|
+
/** What each recipe's accumulator keeps, by recipe name and then by the shape of the path to it. */
|
|
36
|
+
this.findings = new Map();
|
|
37
|
+
this.listener = (accumulators, phase) => {
|
|
38
|
+
const walked = new Set();
|
|
39
|
+
for (const [recipe, acc] of accumulators) {
|
|
40
|
+
if (acc !== null && typeof acc === "object" && !walked.has(acc)) {
|
|
41
|
+
walked.add(acc);
|
|
42
|
+
try {
|
|
43
|
+
this.walk(recipe.name, acc, phase);
|
|
44
|
+
}
|
|
45
|
+
catch (_a) {
|
|
46
|
+
// an accumulator the walk can't read is left alone
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
assertNoneFound() {
|
|
53
|
+
if (this.findings.size === 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const lines = ["A ScanningRecipe's accumulator should keep the values the recipe needs, such as package " +
|
|
57
|
+
"names, versions, paths and ids, and no heavyweight objects, such as trees, cursors, visitors, execution " +
|
|
58
|
+
"contexts and dependency models:"];
|
|
59
|
+
for (const [recipe, found] of this.findings) {
|
|
60
|
+
lines.push(` ${recipe} keeps`);
|
|
61
|
+
const shown = [...found.values()].slice(0, MAX_PATHS);
|
|
62
|
+
lines.push(...shown.map(f => ` ${f.path} -> ${f.what}, ${f.phase}`));
|
|
63
|
+
if (found.size > MAX_PATHS) {
|
|
64
|
+
lines.push(` and ${found.size - MAX_PATHS} more`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
lines.push("An accumulator stays in memory from the first source file scanned until the cycle ends, so " +
|
|
68
|
+
"what it keeps for each source file adds up over a large repository. A NodeResolutionResult can reach " +
|
|
69
|
+
"the model of a whole dependency tree, while small markers such as NodeRuntime are fine to keep. A " +
|
|
70
|
+
"recipe that must keep a heavyweight object opts out with spec.checkLightweightAccumulators = false.");
|
|
71
|
+
throw new Error(lines.join("\n"));
|
|
72
|
+
}
|
|
73
|
+
/** Breadth first, so that the path to what the accumulator keeps is a short one. */
|
|
74
|
+
walk(recipe, acc, phase) {
|
|
75
|
+
const visited = new Set();
|
|
76
|
+
const queue = [];
|
|
77
|
+
let budget = MAX_OBJECTS;
|
|
78
|
+
const visit = (value, parent, step) => {
|
|
79
|
+
if (!walks(value)) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const what = heavyweight(value);
|
|
83
|
+
if (what) {
|
|
84
|
+
const path = pathOf({ value, parent, step });
|
|
85
|
+
let found = this.findings.get(recipe);
|
|
86
|
+
if (!found) {
|
|
87
|
+
this.findings.set(recipe, found = new Map());
|
|
88
|
+
}
|
|
89
|
+
const shape = `${path.replace(/\[[^\]]*]/g, "[]")} -> ${what}`;
|
|
90
|
+
if (!found.has(shape)) {
|
|
91
|
+
found.set(shape, { path, what, phase });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (budget > 0 && !visited.has(value)) {
|
|
95
|
+
budget--;
|
|
96
|
+
visited.add(value);
|
|
97
|
+
queue.push({ value, parent, step });
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
visit(acc, undefined, "acc");
|
|
101
|
+
for (let i = 0; i < queue.length; i++) {
|
|
102
|
+
const node = queue[i];
|
|
103
|
+
const value = node.value;
|
|
104
|
+
if (util_1.types.isMap(value)) {
|
|
105
|
+
Map.prototype.forEach.call(value, (v, k) => {
|
|
106
|
+
if (walks(k) || walks(v)) {
|
|
107
|
+
visit(k, node, `[${key(k)}]`);
|
|
108
|
+
visit(v, node, `[${key(k)}]`);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
else if (util_1.types.isSet(value)) {
|
|
113
|
+
let index = 0;
|
|
114
|
+
Set.prototype.forEach.call(value, (v) => visit(v, node, `[${index++}]`));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// data properties only, since a getter is code of the recipe's own
|
|
118
|
+
const array = Array.isArray(value);
|
|
119
|
+
for (const name of Reflect.ownKeys(value)) {
|
|
120
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, name);
|
|
121
|
+
if (descriptor && "value" in descriptor && !(array && name === "length")) {
|
|
122
|
+
visit(descriptor.value, node, step(name, array));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.AccumulatorContents = AccumulatorContents;
|
|
130
|
+
/** Whether the walk looks at a value at all, which it doesn't for primitives and for what refers to no tree. */
|
|
131
|
+
function walks(value) {
|
|
132
|
+
return value !== null && typeof value === "object" && !util_1.types.isProxy(value) && !util_1.types.isPromise(value) &&
|
|
133
|
+
!util_1.types.isWeakMap(value) && !util_1.types.isWeakSet(value) && !util_1.types.isAnyArrayBuffer(value) &&
|
|
134
|
+
!util_1.types.isArrayBufferView(value) && !util_1.types.isDate(value) && !util_1.types.isRegExp(value) &&
|
|
135
|
+
!util_1.types.isBoxedPrimitive(value) &&
|
|
136
|
+
// a recipe lives for the whole run anyway, and type attribution refers to no tree
|
|
137
|
+
!(value instanceof recipe_1.Recipe) && !java_1.Type.isType(value);
|
|
138
|
+
}
|
|
139
|
+
/** How to name what the accumulator keeps, when it is a heavyweight object. */
|
|
140
|
+
function heavyweight(value) {
|
|
141
|
+
const type = (0, heavyweight_1.heavyweightType)(value);
|
|
142
|
+
if (type === undefined) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
else if (typeof type === "function") {
|
|
146
|
+
return type.name || "an object of an anonymous class";
|
|
147
|
+
}
|
|
148
|
+
return (0, tree_1.isSourceFile)(value) ? `${(0, probes_1.typeName)(type)} ${value.sourcePath}` : (0, probes_1.typeName)(type);
|
|
149
|
+
}
|
|
150
|
+
function pathOf(node) {
|
|
151
|
+
const steps = [];
|
|
152
|
+
for (let n = node; n; n = n.parent) {
|
|
153
|
+
steps.push(n.step);
|
|
154
|
+
}
|
|
155
|
+
return steps.reverse().join("");
|
|
156
|
+
}
|
|
157
|
+
function step(name, array) {
|
|
158
|
+
if (typeof name === "symbol") {
|
|
159
|
+
return `[${name.toString()}]`;
|
|
160
|
+
}
|
|
161
|
+
return array && /^\d+$/.test(name) ? `[${name}]` :
|
|
162
|
+
/^[A-Za-z_$][\w$]*$/.test(name) ? `.${name}` : `[${JSON.stringify(name)}]`;
|
|
163
|
+
}
|
|
164
|
+
/** A map key as the path shows it, without calling code of the recipe's own. */
|
|
165
|
+
function key(k) {
|
|
166
|
+
var _a, _b;
|
|
167
|
+
let shown;
|
|
168
|
+
if (k === null || typeof k !== "object") {
|
|
169
|
+
shown = typeof k === "symbol" ? k.toString() : String(k);
|
|
170
|
+
}
|
|
171
|
+
else if ((0, tree_1.isSourceFile)(k)) {
|
|
172
|
+
shown = k.sourcePath;
|
|
173
|
+
}
|
|
174
|
+
else if (k instanceof recipe_1.Recipe) {
|
|
175
|
+
shown = k.name;
|
|
176
|
+
}
|
|
177
|
+
else if (typeof k.kind === "string") {
|
|
178
|
+
shown = (0, probes_1.typeName)(k.kind);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
shown = ((_b = (_a = Object.getPrototypeOf(k)) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) || "Object";
|
|
182
|
+
}
|
|
183
|
+
return shown.length > 60 ? `${shown.substring(0, 60)}...` : shown;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=accumulator-contents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accumulator-contents.js","sourceRoot":"","sources":["../../src/test/accumulator-contents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SourceSpec } from "./rewrite-test";
|
|
2
|
+
import { Recipe } from "../recipe";
|
|
3
|
+
import { ExecutionContext } from "../execution";
|
|
4
|
+
import { SourceFile } from "../tree";
|
|
5
|
+
import { Result } from "../run";
|
|
6
|
+
/** Runs the recipe on an empty file of each kind it changed, and fails the test if the recipe throws there. */
|
|
7
|
+
export declare class EmptySources {
|
|
8
|
+
private readonly recipe;
|
|
9
|
+
private readonly changed;
|
|
10
|
+
constructor(recipe: Recipe, results: Result[]);
|
|
11
|
+
assertNoneThrow(parsed: [SourceSpec<any>, SourceFile][], parseCtx: ExecutionContext, recipeCtx: ExecutionContext, cycles: number): Promise<void>;
|
|
12
|
+
private message;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=empty-sources.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-sources.d.ts","sourceRoot":"","sources":["../../src/test/empty-sources.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AACnC,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAI9B,+GAA+G;AAC/G,qBAAa,YAAY;IAGT,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAEb,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE;IAIxD,eAAe,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EACnE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBjF,OAAO,CAAC,OAAO;CAmBlB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
3
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
4
|
+
var m = o[Symbol.asyncIterator], i;
|
|
5
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
6
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
7
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.EmptySources = void 0;
|
|
11
|
+
const print_1 = require("../print");
|
|
12
|
+
const probes_1 = require("./probes");
|
|
13
|
+
/** Runs the recipe on an empty file of each kind it changed, and fails the test if the recipe throws there. */
|
|
14
|
+
class EmptySources {
|
|
15
|
+
constructor(recipe, results) {
|
|
16
|
+
this.recipe = recipe;
|
|
17
|
+
this.changed = new Set(results.filter(r => r.before && r.after !== r.before).map(r => r.before));
|
|
18
|
+
}
|
|
19
|
+
async assertNoneThrow(parsed, parseCtx, recipeCtx, cycles) {
|
|
20
|
+
const kinds = new Set();
|
|
21
|
+
for (const [spec, before] of parsed) {
|
|
22
|
+
const probe = `empty ${before.kind} ${spec.ext}`;
|
|
23
|
+
if (!this.changed.has(before) || kinds.has(probe)) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
kinds.add(probe);
|
|
27
|
+
await (0, probes_1.probeOnce)(this.recipe, probe, async () => {
|
|
28
|
+
const empty = await parseEmpty(before, spec, parseCtx);
|
|
29
|
+
const thrown = empty ? await (0, probes_1.thrownBy)(this.recipe, [empty], recipeCtx, cycles) : undefined;
|
|
30
|
+
if (empty && thrown) {
|
|
31
|
+
throw new Error(this.message(empty, thrown.error));
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
message(empty, thrown) {
|
|
37
|
+
return [
|
|
38
|
+
"Check for the structure the recipe edits before using it, so that it handles an empty file or leaves " +
|
|
39
|
+
"it unchanged instead of throwing.",
|
|
40
|
+
`${this.recipe.name} threw when run on an empty ${(0, probes_1.typeName)(empty.kind)} at ${empty.sourcePath}` +
|
|
41
|
+
`${(0, probes_1.withMarkersOf)(empty.markers.markers)}:`,
|
|
42
|
+
(0, probes_1.describeThrown)(thrown, " "),
|
|
43
|
+
"The test gives the recipe only files that contain what it edits, but repositories also hold empty " +
|
|
44
|
+
"files and files without that block, such as an empty index.ts, a placeholder tsconfig.json or an " +
|
|
45
|
+
"empty .eslintrc.yml.",
|
|
46
|
+
" - return the tree unchanged when what the visitor assumes is absent: check the kind before a cast " +
|
|
47
|
+
"(`document.value.kind === Json.Kind.Object`), the length before an index (`cu.statements.length > 0`) " +
|
|
48
|
+
"and undefined before a dereference (`documents.documents[0]?.block`)",
|
|
49
|
+
" - if the recipe adds what is missing, build that content correctly for an empty file too",
|
|
50
|
+
" - don't catch the exception to make this pass",
|
|
51
|
+
"Then add a test with an empty source, such as typescript(\"\"), json(\"\") or yaml(\"\"), that states the " +
|
|
52
|
+
"intended result."
|
|
53
|
+
].join("\n");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.EmptySources = EmptySources;
|
|
57
|
+
/**
|
|
58
|
+
* An empty file at the source's path, with the markers that describe the source's project, or undefined for a kind of
|
|
59
|
+
* file that can't be empty.
|
|
60
|
+
*/
|
|
61
|
+
async function parseEmpty(before, spec, parseCtx) {
|
|
62
|
+
var _a, e_1, _b, _c;
|
|
63
|
+
// a file its parser resolves a project from, such as a package.json, can't be empty
|
|
64
|
+
if (before.markers.markers.some(m => m.kind.endsWith("ResolutionResult"))) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
let empty;
|
|
68
|
+
try {
|
|
69
|
+
const parsed = [];
|
|
70
|
+
try {
|
|
71
|
+
for (var _d = true, _e = __asyncValues(spec.parser(parseCtx).parse({ text: "", sourcePath: before.sourcePath })), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
|
|
72
|
+
_c = _f.value;
|
|
73
|
+
_d = false;
|
|
74
|
+
const sourceFile = _c;
|
|
75
|
+
parsed.push(sourceFile);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
79
|
+
finally {
|
|
80
|
+
try {
|
|
81
|
+
if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
|
|
82
|
+
}
|
|
83
|
+
finally { if (e_1) throw e_1.error; }
|
|
84
|
+
}
|
|
85
|
+
// some kinds of file can't be empty
|
|
86
|
+
if (parsed.length !== 1 || parsed[0].kind !== before.kind || await print_1.TreePrinters.print(parsed[0]) !== "") {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
empty = parsed[0];
|
|
90
|
+
}
|
|
91
|
+
catch (_g) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const present = new Set(empty.markers.markers.map(m => m.kind));
|
|
95
|
+
const added = before.markers.markers.filter(m => !present.has(m.kind));
|
|
96
|
+
return Object.assign(Object.assign({}, empty), { markers: Object.assign(Object.assign({}, empty.markers), { markers: [...empty.markers.markers, ...added] }) });
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=empty-sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"empty-sources.js","sourceRoot":"","sources":["../../src/test/empty-sources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Recipe } from "../recipe";
|
|
2
|
+
import { Cursor, Tree } from "../tree";
|
|
3
|
+
import { Result } from "../run";
|
|
4
|
+
import type { FormattingListener } from "../javascript/format";
|
|
5
|
+
/**
|
|
6
|
+
* Finds recipes that auto-format a whole source file or class that existed before the run. Test inputs are usually
|
|
7
|
+
* formatted already, so the reformatting this causes on real code rarely shows in an expected output.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FormattingScope implements FormattingListener {
|
|
10
|
+
private readonly recipe;
|
|
11
|
+
private readonly requests;
|
|
12
|
+
private readonly requested;
|
|
13
|
+
constructor(recipe: Recipe);
|
|
14
|
+
onFormat(tree: Tree, stopAfter: Tree | undefined, cursor: Cursor | undefined): void;
|
|
15
|
+
assertFormattedOnlyWhatChanged(results: Result[]): Promise<void>;
|
|
16
|
+
private message;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=formatting-scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting-scope.d.ts","sourceRoot":"","sources":["../../src/test/formatting-scope.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAC,MAAM,EAA4B,IAAI,EAAC,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAC,MAAM,EAAC,MAAM,QAAQ,CAAC;AAK9B,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AAQ7D;;;GAGG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IAI1C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmB;gBAEhB,MAAM,EAAE,MAAM;IAG3C,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAY7E,8BAA8B,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BtE,OAAO,CAAC,OAAO;CAqBlB"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FormattingScope = void 0;
|
|
37
|
+
/*
|
|
38
|
+
* Copyright 2025 the original author or authors.
|
|
39
|
+
* <p>
|
|
40
|
+
* Licensed under the Moderne Source Available License (the "License");
|
|
41
|
+
* you may not use this file except in compliance with the License.
|
|
42
|
+
* You may obtain a copy of the License at
|
|
43
|
+
* <p>
|
|
44
|
+
* https://docs.moderne.io/licensing/moderne-source-available-license
|
|
45
|
+
* <p>
|
|
46
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
47
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
48
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
49
|
+
* See the License for the specific language governing permissions and
|
|
50
|
+
* limitations under the License.
|
|
51
|
+
*/
|
|
52
|
+
const path = __importStar(require("path"));
|
|
53
|
+
const tree_1 = require("../tree");
|
|
54
|
+
const print_1 = require("../print");
|
|
55
|
+
const java_1 = require("../java");
|
|
56
|
+
const javascript_1 = require("../javascript");
|
|
57
|
+
/**
|
|
58
|
+
* Finds recipes that auto-format a whole source file or class that existed before the run. Test inputs are usually
|
|
59
|
+
* formatted already, so the reformatting this causes on real code rarely shows in an expected output.
|
|
60
|
+
*/
|
|
61
|
+
class FormattingScope {
|
|
62
|
+
constructor(recipe) {
|
|
63
|
+
this.recipe = recipe;
|
|
64
|
+
this.requests = [];
|
|
65
|
+
this.requested = new Set();
|
|
66
|
+
}
|
|
67
|
+
onFormat(tree, stopAfter, cursor) {
|
|
68
|
+
var _a;
|
|
69
|
+
if (stopAfter || !isWhole(tree) || this.requested.has(tree)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
this.requested.add(tree);
|
|
73
|
+
const sourceFile = (0, tree_1.isSourceFile)(tree) ? tree : cursor === null || cursor === void 0 ? void 0 : cursor.firstEnclosing(tree_1.isSourceFile);
|
|
74
|
+
const site = sourceFile && callSite((_a = new Error().stack) !== null && _a !== void 0 ? _a : "");
|
|
75
|
+
if (sourceFile && site) {
|
|
76
|
+
this.requests.push({ tree, sourceFile: sourceFile.id, callSite: site });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async assertFormattedOnlyWhatChanged(results) {
|
|
80
|
+
if (this.requests.length === 0 || await isFormatter(this.recipe)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const treesByFile = new Map();
|
|
84
|
+
const found = new Map();
|
|
85
|
+
for (const request of this.requests) {
|
|
86
|
+
const result = results.find(r => { var _a; return ((_a = r.before) === null || _a === void 0 ? void 0 : _a.id) === request.sourceFile && r.after && r.after !== r.before; });
|
|
87
|
+
if (!result || await onlyWhitespaceChanged(result)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const before = result.before;
|
|
91
|
+
let trees = treesByFile.get(before.id);
|
|
92
|
+
if (!trees) {
|
|
93
|
+
treesByFile.set(before.id, trees = await treesById(before));
|
|
94
|
+
}
|
|
95
|
+
const original = trees.get(request.tree.id);
|
|
96
|
+
if (original && !await holdsNoneOfItsChildren(original, request.tree)) {
|
|
97
|
+
let targets = found.get(request.callSite);
|
|
98
|
+
if (!targets) {
|
|
99
|
+
found.set(request.callSite, targets = new Set());
|
|
100
|
+
}
|
|
101
|
+
targets.add(`${describe(request.tree)} of ${before.sourcePath}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (found.size > 0) {
|
|
105
|
+
throw new Error(this.message(found));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
message(found) {
|
|
109
|
+
return [
|
|
110
|
+
"Format only what the recipe changed, not the whole class or file around it. These calls of " +
|
|
111
|
+
`${this.recipe.name} auto-formatted a whole file or class that existed before the run, with no stopAfter:`,
|
|
112
|
+
...[...found].flatMap(([site, targets]) => [` ${site}`, ...[...targets].map(target => ` ${target}`)]),
|
|
113
|
+
"That rewrites the whitespace of code the recipe did not change. Test inputs are usually formatted " +
|
|
114
|
+
"already, so expected outputs rarely show it, but on real code the diff will carry unrelated " +
|
|
115
|
+
"reformatting. Instead:",
|
|
116
|
+
" - format the element you created or replaced: maybeAutoFormat(original, changed, ctx) on that " +
|
|
117
|
+
"element, or autoFormat(newElement, ctx, undefined, cursor) with a cursor on its parent",
|
|
118
|
+
" - when a new element only formats right inside its container, format a copy of the container that " +
|
|
119
|
+
"holds just the new element, and add the formatted element to the original",
|
|
120
|
+
" - after changing a declaration's decorators or modifiers, stop after its header: " +
|
|
121
|
+
"maybeAutoFormat(c, updated, ctx, updated.name, this.cursor.parent)",
|
|
122
|
+
" - when you remove an element, give its prefix to the element that takes its place",
|
|
123
|
+
" - re-indent statements you moved with autoIndent(..) rather than autoFormat",
|
|
124
|
+
" - a template already formats what it inserts, so drop the extra call",
|
|
125
|
+
"Recipes named with a `format` segment, such as org.openrewrite.javascript.format.auto-format, are exempt. " +
|
|
126
|
+
"Any other recipe whose purpose is formatting opts out with spec.checkMinimalFormatting = false."
|
|
127
|
+
].join("\n");
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
exports.FormattingScope = FormattingScope;
|
|
131
|
+
/** A source file or a class. */
|
|
132
|
+
function isWhole(tree) {
|
|
133
|
+
return (0, tree_1.isSourceFile)(tree) || tree.kind === java_1.J.Kind.ClassDeclaration;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The code that asked for the format, from the stack of the request, or undefined when that is a formatter, a
|
|
137
|
+
* template, or the scheduler running a recipe whose own visitor is a formatter.
|
|
138
|
+
*/
|
|
139
|
+
function callSite(stack) {
|
|
140
|
+
const frames = stack.split("\n").map(line => line.trim()).filter(line => line.startsWith("at "))
|
|
141
|
+
.map(line => {
|
|
142
|
+
var _a, _b;
|
|
143
|
+
const m = /^at (?:async )?(?:(.*?) \((.*)\)|(.*))$/.exec(line);
|
|
144
|
+
return { fn: (_a = m[1]) !== null && _a !== void 0 ? _a : "", location: ((_b = m[2]) !== null && _b !== void 0 ? _b : m[3]).split(process.cwd() + path.sep).join("") };
|
|
145
|
+
});
|
|
146
|
+
// the listener, the formatter and the helpers that run it
|
|
147
|
+
let i = frames.findIndex(f => /\.visit$/.test(f.fn) && inFormat(f));
|
|
148
|
+
if (i < 0) {
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
let helper;
|
|
152
|
+
for (i++; i < frames.length && inFormat(frames[i]) && /^(maybeAutoFormat|autoFormat)$/.test(frames[i].fn); i++) {
|
|
153
|
+
helper = frames[i].fn;
|
|
154
|
+
}
|
|
155
|
+
// a precondition and a scanning recipe's editor hand the tree on to the visitor they wrap, after an await
|
|
156
|
+
while (i < frames.length && (isWrapper(frames[i]) || frames[i].location.startsWith("node:"))) {
|
|
157
|
+
i++;
|
|
158
|
+
}
|
|
159
|
+
const caller = frames[i];
|
|
160
|
+
if (!caller) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
else if (/(^|[\\/])(src|dist)[\\/]visitor\.[jt]s:/.test(caller.location)) {
|
|
164
|
+
// the visitor that asked is gone from the stack by the time its after-visitors run
|
|
165
|
+
return "A visitor's afterVisit.push(new AutoformatVisitor()) ran on";
|
|
166
|
+
}
|
|
167
|
+
else if (inFormat(caller) || /[\\/]templating[\\/]/.test(caller.location) ||
|
|
168
|
+
/(^|[\\/])(src|dist)[\\/]run\.[jt]s:/.test(caller.location)) {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
return `${caller.fn || "<anonymous>"} (${caller.location}) ${helper ? `called ${helper} on` : "ran an AutoformatVisitor on"}`;
|
|
172
|
+
}
|
|
173
|
+
function inFormat(frame) {
|
|
174
|
+
return /[\\/]format[\\/]/.test(frame.location);
|
|
175
|
+
}
|
|
176
|
+
/** The visit of a precondition or of a scanning recipe's editor, which runs the visitor it wraps. */
|
|
177
|
+
function isWrapper(frame) {
|
|
178
|
+
return /\.visit$/.test(frame.fn) && /(^|[\\/])(src|dist)[\\/](preconditions|recipe)\.[jt]s:/.test(frame.location);
|
|
179
|
+
}
|
|
180
|
+
/** A formatting recipe may format whole files, and so may the recipes run alongside it. */
|
|
181
|
+
async function isFormatter(recipe) {
|
|
182
|
+
if (/(^|\.)format\./.test(recipe.name)) {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
for (const child of await recipe.recipeList()) {
|
|
186
|
+
if (await isFormatter(child)) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
async function onlyWhitespaceChanged(result) {
|
|
193
|
+
const [before, after] = [await print_1.TreePrinters.print(result.before), await print_1.TreePrinters.print(result.after)];
|
|
194
|
+
return before.replace(/\s+/g, "") === after.replace(/\s+/g, "");
|
|
195
|
+
}
|
|
196
|
+
async function treesById(sourceFile) {
|
|
197
|
+
const trees = new Map();
|
|
198
|
+
await new class extends javascript_1.JavaScriptVisitor {
|
|
199
|
+
async preVisit(tree) {
|
|
200
|
+
trees.set(tree.id, tree);
|
|
201
|
+
return tree;
|
|
202
|
+
}
|
|
203
|
+
}().visit(sourceFile, undefined);
|
|
204
|
+
return trees;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* A tree formatted with none of the children it had reformats no existing code below it: a class with its body
|
|
208
|
+
* emptied to be put back afterwards, or a copy of a container holding only a new element. A tree that had no children
|
|
209
|
+
* to begin with would format them on real code.
|
|
210
|
+
*/
|
|
211
|
+
async function holdsNoneOfItsChildren(original, formatted) {
|
|
212
|
+
const children = await childrenOf(original);
|
|
213
|
+
if (children.size === 0) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
for (const child of await childrenOf(formatted)) {
|
|
217
|
+
if (children.has(child)) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
/** The members of a class's body, or the trees directly below any other tree. */
|
|
224
|
+
async function childrenOf(tree) {
|
|
225
|
+
if (tree.kind === java_1.J.Kind.ClassDeclaration) {
|
|
226
|
+
return new Set(tree.body.statements.map(s => s.element.id));
|
|
227
|
+
}
|
|
228
|
+
const children = new Set();
|
|
229
|
+
await new class extends javascript_1.JavaScriptVisitor {
|
|
230
|
+
async preVisit(t) {
|
|
231
|
+
if (t !== tree) {
|
|
232
|
+
children.add(t.id);
|
|
233
|
+
this.stopAfterPreVisit();
|
|
234
|
+
}
|
|
235
|
+
return t;
|
|
236
|
+
}
|
|
237
|
+
}().visit(tree, undefined);
|
|
238
|
+
return children;
|
|
239
|
+
}
|
|
240
|
+
/** Reads as "all" or "class `A`". */
|
|
241
|
+
function describe(tree) {
|
|
242
|
+
return (0, tree_1.isSourceFile)(tree) ? "all" : `class \`${tree.name.simpleName}\``;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=formatting-scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatting-scope.js","sourceRoot":"","sources":["../../src/test/formatting-scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Recipe } from "../recipe";
|
|
2
|
+
import { ExecutionContext } from "../execution";
|
|
3
|
+
import { SourceFile } from "../tree";
|
|
4
|
+
import { Marker } from "../markers";
|
|
5
|
+
/**
|
|
6
|
+
* Runs `run`, a probe of the recipe on what `probe` names, unless this process ran that probe before or the recipe's
|
|
7
|
+
* probes have taken the time cap, and charges the recipe the time it takes.
|
|
8
|
+
*/
|
|
9
|
+
export declare function probeOnce(recipe: Recipe, probe: string, run: () => Promise<void>): Promise<void>;
|
|
10
|
+
/** Adds `ms` to the time the recipe's probes have taken in this process. */
|
|
11
|
+
export declare function charge(recipe: Recipe, ms: number): Promise<void>;
|
|
12
|
+
/** The error the recipe threw when run on `sources` for up to `cycles` cycles, if it threw. */
|
|
13
|
+
export declare function thrownBy(recipe: Recipe, sources: SourceFile[], recipeCtx: ExecutionContext, cycles: number): Promise<{
|
|
14
|
+
error: unknown;
|
|
15
|
+
} | undefined>;
|
|
16
|
+
/**
|
|
17
|
+
* The error the recipe threw, with the first line of its message and the first frame of its stack, and when that
|
|
18
|
+
* frame is in a dependency, the first frame that isn't.
|
|
19
|
+
*/
|
|
20
|
+
export declare function describeThrown(thrown: unknown, indent: string): string;
|
|
21
|
+
/** Reads as " with the markers of the test's source (Autodetect, PrettierStyle)", or as nothing. */
|
|
22
|
+
export declare function withMarkersOf(markers: Marker[]): string;
|
|
23
|
+
/** Reads as "PlainText" or "JS.CompilationUnit". */
|
|
24
|
+
export declare function typeName(kind: string): string;
|
|
25
|
+
//# sourceMappingURL=probes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"probes.d.ts","sourceRoot":"","sources":["../../src/test/probes.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC;AACjC,OAAO,EAAC,gBAAgB,EAAC,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAC,UAAU,EAAC,MAAM,SAAS,CAAC;AAInC,OAAO,EAAC,MAAM,EAAC,MAAM,YAAY,CAAC;AAiBlC;;;GAGG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBtG;AAED,4EAA4E;AAC5E,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtE;AA4BD,+FAA+F;AAC/F,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAClE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,CAqBtF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBtE;AAED,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAGvD;AAED,oDAAoD;AACpD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C"}
|