packages/deriver/tests/Unit/Deriver/Evaluator/EvaluatorTest.php
1<?php
2
3declare (strict_types=1);
4
5namespace Tests\Unit\Deriver\Evaluator;
6
7use Deriver\Deriver\Contributions;
8use Deriver\Deriver\DeriverConfig;
9use Deriver\Deriver\Evaluator\Call\Evaluators;
10use Deriver\Deriver\Evaluator\Call\Registrations;
11use Deriver\Deriver\Evaluator\Enumeration\Choices;
12use Deriver\Deriver\Evaluator\Evaluator;
13use Deriver\Deriver\Evaluator\EvaluatorConfig;
14use Deriver\Deriver\Evaluator\Evidence\Frontier;
15use Deriver\Deriver\Evaluator\Index\DefinitionIndex;
16use Deriver\Deriver\Evaluator\Request\Budget;
17use Deriver\Deriver\Evaluator\Request\ReturnQuery;
18use Deriver\Deriver\Evaluator\Scope\Context;
19use Deriver\Deriver\Evaluator\Scope\Frame;
20use Deriver\Deriver\Evaluator\Target;
21use Deriver\Deriver\Evaluator\TargetKind;
22use Deriver\Deriver\Evaluator\TargetProfile;
23use Deriver\Deriver\Evaluator\Term;
24use Deriver\Deriver\Evaluator\TermKind;
25use Deriver\Deriver\Lowerer\Declaration\Index;
26use Deriver\Deriver\MicroEvaluatorConversion;
27use Deriver\Deriver\Parser\Node\File;
28use Deriver\Deriver\Parser\Parser;
29use Deriver\Deriver\Parser\ParserConfig;
30use Deriver\Deriver\Providers\ProviderExpansion;
31use Deriver\Deriver\Publication\CandidateQuery;
32use Deriver\Deriver\Resolver\Resolver;
33use Deriver\Deriver\SnapshotIdentity;
34use Deriver\Deriver\Sources\Path;
35use Deriver\Deriver\Sources\Source;
36use Deriver\Deriver\Sources\Sources;
37use PHPUnit\Framework\Attributes\CoversNothing;
38use PHPUnit\Framework\TestCase;
39
40#[CoversNothing]
41final class EvaluatorTest extends TestCase
42{
43 public function testValueSharesImmutableDependencyNodes(): void
44 {
45 $source = 'function target($x){return $x+2;}';
46 $configuration = new DeriverConfig();
47 $budget = new Budget();
48 $contributions = new Contributions();
49 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
50 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
51 $contributions1 = $providers->contributions;
52 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
53 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
54 $snapshotId = 'test';
55 $input = $providers->input;
56 $parser = new Parser(new ParserConfig($target->version));
57 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
58 $program = new Index($snapshotId, $trees);
59 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
60 $symbol = 'target';
61 $graph = $e->context->index->graph($symbol);
62 self::assertNotNull($graph);
63 $f = new Frame($graph, 'source:' . $symbol);
64 $operation = 'binary';
65 $instruction = array_values(array_filter($f->graph->definitions, static fn ($instruction): bool => $instruction->operation === $operation))[0] ?? null;
66 $i = $instruction;
67 self::assertNotNull($i);
68 $a = $e->value($f, $i->result, 20);
69 self::assertSame($a, $e->value($f, $i->result, 10));
70 self::assertGreaterThan(0, $e->context->sharedNodeHits);
71 }
72 public function testInstructionKeepsTheOperatorWithAnUnknownOperand(): void
73 {
74 $source = 'function target($x){return $x+2;}';
75 $configuration = new DeriverConfig();
76 $budget = new Budget();
77 $contributions = new Contributions();
78 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
79 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
80 $contributions1 = $providers->contributions;
81 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
82 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
83 $snapshotId = 'test';
84 $input = $providers->input;
85 $parser = new Parser(new ParserConfig($target->version));
86 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
87 $program = new Index($snapshotId, $trees);
88 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
89 $symbol = 'target';
90 $graph = $e->context->index->graph($symbol);
91 self::assertNotNull($graph);
92 $f = new Frame($graph, 'source:' . $symbol);
93 $operation = 'binary';
94 $instruction = array_values(array_filter($f->graph->definitions, static fn ($instruction): bool => $instruction->operation === $operation))[0] ?? null;
95 self::assertNotNull($instruction);
96 $v = $e->instruction($f, $instruction, 20);
97 self::assertSame('+', $v->literal);
98 self::assertSame(TermKind::Reference, $v->operands[0]->kind);
99 }
100 public function testReturnsIgnoresUnrelatedCalls(): void
101 {
102 $source = 'function target(){unrelated();return 12;}';
103 $configuration = new DeriverConfig();
104 $budget = new Budget();
105 $contributions = new Contributions();
106 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
107 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
108 $contributions1 = $providers->contributions;
109 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
110 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
111 $snapshotId = 'test';
112 $input = $providers->input;
113 $parser = new Parser(new ParserConfig($target->version));
114 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
115 $program = new Index($snapshotId, $trees);
116 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
117 $symbol = 'target';
118 $graph = $e->context->index->graph($symbol);
119 self::assertNotNull($graph);
120 $f = new Frame($graph, 'source:' . $symbol);
121 self::assertSame(12, $e->returns($f, 20)->native());
122 self::assertSame(0, $e->context->bodyExpansions);
123 }
124 public function testPhiPrunesAKnownCondition(): void
125 {
126 $source = 'function target(){return true ? 3 : external();}';
127 $configuration = new DeriverConfig();
128 $budget = new Budget();
129 $contributions = new Contributions();
130 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
131 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
132 $contributions1 = $providers->contributions;
133 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
134 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
135 $snapshotId = 'test';
136 $input = $providers->input;
137 $parser = new Parser(new ParserConfig($target->version));
138 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
139 $program = new Index($snapshotId, $trees);
140 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
141 $symbol = 'target';
142 $graph = $e->context->index->graph($symbol);
143 self::assertNotNull($graph);
144 $f = new Frame($graph, 'source:' . $symbol);
145 $operation = 'phi';
146 $instruction = array_values(array_filter($f->graph->definitions, static fn ($instruction): bool => $instruction->operation === $operation))[0] ?? null;
147 self::assertNotNull($instruction);
148 $v = $e->phi($f, $instruction, 20);
149 self::assertSame(3, iterator_to_array((new Choices())->alternatives($v), false)[0][0]->native());
150 self::assertSame(0, $e->context->bodyExpansions);
151 }
152 public function testOperationUsesTheOrdinaryArithmeticRules(): void
153 {
154 $source = 'function target($x){return $x+2;}';
155 $configuration = new DeriverConfig();
156 $budget = new Budget();
157 $contributions = new Contributions();
158 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
159 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
160 $contributions1 = $providers->contributions;
161 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
162 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
163 $snapshotId = 'test';
164 $input = $providers->input;
165 $parser = new Parser(new ParserConfig($target->version));
166 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
167 $program = new Index($snapshotId, $trees);
168 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
169 self::assertSame(12, $e->operation('binary', '+', [Term::constant(5), Term::constant(7)])->native());
170 }
171 public function testReduceRetainsUnsupportedOperands(): void
172 {
173 $source = 'function target($x){return $x+2;}';
174 $configuration = new DeriverConfig();
175 $budget = new Budget();
176 $contributions = new Contributions();
177 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
178 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
179 $contributions1 = $providers->contributions;
180 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
181 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
182 $snapshotId = 'test';
183 $input = $providers->input;
184 $parser = new Parser(new ParserConfig($target->version));
185 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
186 $program = new Index($snapshotId, $trees);
187 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
188 $known = Term::constant(5);
189 $v = $e->reduce('not-supported', '', [$known]);
190 self::assertSame([$known], $v->operands);
191 self::assertSame('UNSUPPORTED_OPERATION', $v->attributes['reason']);
192 }
193 public function testElementRespectsNumericStringKeys(): void
194 {
195 $source = 'function target($x){return $x+2;}';
196 $configuration = new DeriverConfig();
197 $budget = new Budget();
198 $contributions = new Contributions();
199 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
200 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
201 $contributions1 = $providers->contributions;
202 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
203 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
204 $snapshotId = 'test';
205 $input = $providers->input;
206 $parser = new Parser(new ParserConfig($target->version));
207 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
208 $program = new Index($snapshotId, $trees);
209 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
210 self::assertSame(3, $e->element(Term::array([-1 => Term::constant(3)]), Term::constant('-1'))->native());
211 }
212 public function testIntrinsicSimplifiesKnownLibraryInputs(): void
213 {
214 $source = 'function target($x){return $x+2;}';
215 $configuration = new DeriverConfig();
216 $budget = new Budget();
217 $contributions = new Contributions();
218 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
219 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
220 $contributions1 = $providers->contributions;
221 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
222 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
223 $snapshotId = 'test';
224 $input = $providers->input;
225 $parser = new Parser(new ParserConfig($target->version));
226 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
227 $program = new Index($snapshotId, $trees);
228 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
229 self::assertSame(3, $e->intrinsic('strlen', [Term::constant('abc')])->native());
230 }
231 public function testConstantKeepsMissingConstantIdentity(): void
232 {
233 $source = 'function target(){return UNKNOWN_NAME;}';
234 $configuration = new DeriverConfig();
235 $budget = new Budget();
236 $contributions = new Contributions();
237 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
238 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
239 $contributions1 = $providers->contributions;
240 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
241 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
242 $snapshotId = 'test';
243 $input = $providers->input;
244 $parser = new Parser(new ParserConfig($target->version));
245 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
246 $program = new Index($snapshotId, $trees);
247 $e = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
248 $symbol = 'target';
249 $graph = $e->context->index->graph($symbol);
250 self::assertNotNull($graph);
251 $f = new Frame($graph, 'source:' . $symbol);
252 $operation = 'constant-fetch';
253 $instruction = array_values(array_filter($f->graph->definitions, static fn ($instruction): bool => $instruction->operation === $operation))[0] ?? null;
254 self::assertNotNull($instruction);
255 $v = $e->constant($f, $instruction, 20);
256 self::assertSame('UNKNOWN_NAME', $v->literal);
257 self::assertSame('MISSING_CONSTANT', $v->attributes['reason']);
258 }
259 public function testExpressionUsesTheSameCallbackAndCastRules(): void
260 {
261 $source = 'function target(){return "v".call_user_func(fn($x)=>$x+1,2);}';
262 $configuration = new DeriverConfig();
263 $budget = new Budget();
264 $contributions = new Contributions();
265 $prepared2Input = new Sources([new Source('candidate.php', '<?php ' . $source)]);
266 $prepared2Configuration = $configuration;
267 $prepared2Contributions = $contributions;
268 $prepared2Target = new TargetProfile($prepared2Configuration->phpVersion, $prepared2Configuration->integerBits, $prepared2Configuration->floatPrecision);
269 $prepared2Providers = new ProviderExpansion($prepared2Input, array_map(Term::fromNative(...), $prepared2Configuration->environment), $prepared2Contributions);
270 $contributions1 = $prepared2Providers->contributions;
271 $prepared2Evaluators = new Evaluators(new TargetProfile($prepared2Configuration->phpVersion, $prepared2Configuration->integerBits, $prepared2Configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $prepared2Configuration->standardEvaluators);
272 $prepared2Settings = new EvaluatorConfig($prepared2Target, $prepared2Providers->environment, $prepared2Configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $prepared2Configuration->evaluators));
273 $prepared2Identity = new SnapshotIdentity($prepared2Providers->input, $prepared2Settings, $prepared2Evaluators, $prepared2Providers->manifest);
274 $snapshotId = $prepared2Identity->id;
275 $input = $prepared2Providers->input;
276 $parser = new Parser(new ParserConfig($prepared2Target->version));
277 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
278 $prepared2Program = new Index($snapshotId, $trees);
279 $prepared2Snapshot = $prepared2Identity->snapshot(array_map(Frontier::fromDiagnostic(...), $prepared2Program->diagnostics()));
280 self::assertSame('v3', (new CandidateQuery(new DefinitionIndex($prepared2Program), $prepared2Settings, $prepared2Evaluators, $prepared2Snapshot))->derive(new ReturnQuery('target', budget: $budget))[0]->result);
281 }
282 public function testBoundedKeepsTheSameEvidenceWhenReused(): void
283 {
284 $prepared1Input = new Sources([new Source('candidate.php', '<?php ' . 'function target(){return external(1);}')]);
285 $prepared1Configuration = new DeriverConfig();
286 $prepared1Contributions = new Contributions();
287 $prepared1Target = new TargetProfile($prepared1Configuration->phpVersion, $prepared1Configuration->integerBits, $prepared1Configuration->floatPrecision);
288 $prepared1Providers = new ProviderExpansion($prepared1Input, array_map(Term::fromNative(...), $prepared1Configuration->environment), $prepared1Contributions);
289 $contributions = $prepared1Providers->contributions;
290 $prepared1Evaluators = new Evaluators(new TargetProfile($prepared1Configuration->phpVersion, $prepared1Configuration->integerBits, $prepared1Configuration->floatPrecision), new Registrations($contributions->evaluators, $contributions->providers, $contributions->domains, $contributions->intrinsics, $contributions->stateSlots), $prepared1Configuration->standardEvaluators);
291 $prepared1Settings = new EvaluatorConfig($prepared1Target, $prepared1Providers->environment, $prepared1Configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $prepared1Configuration->evaluators));
292 $prepared1Identity = new SnapshotIdentity($prepared1Providers->input, $prepared1Settings, $prepared1Evaluators, $prepared1Providers->manifest);
293 $snapshotId = $prepared1Identity->id;
294 $input = $prepared1Providers->input;
295 $parser = new Parser(new ParserConfig($prepared1Target->version));
296 $trees = array_map(static fn (Source $source): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source->path), $source->contents, $source->declarationsOnly))), iterator_to_array($input, false));
297 $prepared1Program = new Index($snapshotId, $trees);
298 $prepared1Snapshot = $prepared1Identity->snapshot(array_map(Frontier::fromDiagnostic(...), $prepared1Program->diagnostics()));
299 $session = new CandidateQuery(new DefinitionIndex($prepared1Program), $prepared1Settings, $prepared1Evaluators, $prepared1Snapshot);
300 $query = new ReturnQuery('target');
301 $first = $session->derive($query);
302 $second = $session->derive($query);
303 self::assertEquals(iterator_to_array($first), iterator_to_array($second));
304 }
305 public function testEvaluateSelectsTheRequestedReturn(): void
306 {
307 $source = 'function target(){return 42;}';
308 $configuration = new DeriverConfig();
309 $budget = new Budget();
310 $contributions = new Contributions();
311 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
312 $providers = new ProviderExpansion(new Sources([new Source('candidate.php', '<?php ' . $source)]), array_map(Term::fromNative(...), $configuration->environment), $contributions);
313 $contributions1 = $providers->contributions;
314 $evaluators = new Evaluators(new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $configuration->standardEvaluators);
315 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
316 $snapshotId = 'test';
317 $input = $providers->input;
318 $parser = new Parser(new ParserConfig($target->version));
319 $trees = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input, false));
320 $program = new Index($snapshotId, $trees);
321 $engine = new Evaluator(new Context(new DefinitionIndex($program), $settings, $evaluators, $budget));
322 $result = $engine->evaluate(new Target('target', TargetKind::Return, 'return'));
323 self::assertSame(42, $result->operands['return']->native());
324 }
325}
326