packages/deriver/tests/Integration/SessionContractTest.php
1<?php
2
3declare (strict_types=1);
4
5namespace Tests\Integration;
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\EvaluatorConfig;
12use Deriver\Deriver\Evaluator\Evidence\Frontier;
13use Deriver\Deriver\Evaluator\Execution\Completion\Reachability;
14use Deriver\Deriver\Evaluator\Execution\EvaluatorConfig as ExecutionEvaluatorConfig;
15use Deriver\Deriver\Evaluator\Index\DefinitionIndex;
16use Deriver\Deriver\Evaluator\Request\Budget;
17use Deriver\Deriver\Evaluator\Request\EntryPoint;
18use Deriver\Deriver\Evaluator\Request\QueryScope;
19use Deriver\Deriver\Evaluator\Request\ReturnQuery;
20use Deriver\Deriver\Evaluator\Request\ValueQuery;
21use Deriver\Deriver\Evaluator\TargetProfile;
22use Deriver\Deriver\Evaluator\Term;
23use Deriver\Deriver\Execution\QueryExecution;
24use Deriver\Deriver\Lowerer\Declaration\Index;
25use Deriver\Deriver\Lowerer\Graph\ExpressionRef;
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\Selection\CallObservations;
34use Deriver\Deriver\SnapshotIdentity;
35use Deriver\Deriver\Sources\Path;
36use Deriver\Deriver\Sources\Source;
37use Deriver\Deriver\Sources\Sources;
38use Deriver\Exception\InvalidInputException;
39use Deriver\Exception\ParserException;
40use PHPUnit\Framework\Attributes\CoversNothing;
41use PHPUnit\Framework\Attributes\Small;
42use PHPUnit\Framework\TestCase;
43
44#[CoversNothing]
45#[Small]
46final class SessionContractTest extends TestCase
47{
48 public function testQueryIdentityIncludesArgumentsScopeAndBudget(): void
49 {
50 $input = new Sources([new Source('fixture.php', '<?php function target($x){return $x;}')]);
51 $configuration = new DeriverConfig();
52 $contributions = new Contributions();
53 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
54 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
55 $contributions1 = $providers->contributions;
56 $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);
57 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
58 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
59 $snapshotId = $identity->id;
60 $input1 = $providers->input;
61 $parser = new Parser(new ParserConfig($target->version));
62 $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($input1, false));
63 $program = new Index($snapshotId, $trees);
64 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
65 $one = $session->derive(new ReturnQuery('target', QueryScope::fromEntrypoints([new EntryPoint('target', [Term::constant(1)])])));
66 $two = $session->derive(new ReturnQuery('target', QueryScope::fromEntrypoints([new EntryPoint('target', [Term::constant(2)])])));
67 $small = $session->derive(new ReturnQuery('target', budget: new Budget(transfers: 1)));
68 self::assertNotSame($one->reference->id, $two->reference->id);
69 self::assertNotSame($one->reference->id, $small->reference->id);
70 self::assertSame(1, $one->normalOutcomes[0]->values['return']->native());
71 self::assertSame(2, $two->normalOutcomes[0]->values['return']->native());
72 }
73 public function testRepeatedQueriesPerformTheSameLogicalWork(): void
74 {
75 $input = new Sources([new Source('fixture.php', '<?php function target(){return 42;}function unrelated(){return 100;}')]);
76 $configuration = new DeriverConfig();
77 $contributions = new Contributions();
78 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
79 $providers = new ProviderExpansion($input, 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 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
84 $snapshotId = $identity->id;
85 $input1 = $providers->input;
86 $parser = new Parser(new ParserConfig($target->version));
87 $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($input1, false));
88 $program = new Index($snapshotId, $trees);
89 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
90 $first = $session->derive(new ReturnQuery('target'));
91 $session->derive(new ReturnQuery('unrelated'));
92 $repeated = $session->derive(new ReturnQuery('target'));
93 self::assertNotSame($first, $repeated);
94 self::assertEquals($first->normalOutcomes, $repeated->normalOutcomes);
95 self::assertSame(1, $repeated->statistics->graphs);
96 self::assertSame($first->statistics->transfers, $repeated->statistics->transfers);
97 }
98 public function testCallSelectionDoesNotCompileUnrelatedFunctions(): void
99 {
100 $input = new Sources([new Source('fixture.php', '<?php function selected(){observe(42);}function unrelated(){return 100;}')]);
101 $configuration = new DeriverConfig();
102 $contributions = new Contributions();
103 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
104 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
105 $contributions1 = $providers->contributions;
106 $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);
107 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
108 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
109 $snapshotId = $identity->id;
110 $input1 = $providers->input;
111 $parser = new Parser(new ParserConfig($target->version));
112 $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($input1, false));
113 $program = new Index($snapshotId, $trees);
114 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
115 $site = (new CallObservations($session->program, $session->evaluators))->find('observe')[0];
116 $result = $session->derive(new ValueQuery($site->argument(0)));
117 self::assertSame(42, $result->normalOutcomes[0]->values['value']->native());
118 self::assertSame(1, $result->statistics->graphs);
119 }
120 public function testFabricatedRegistersAreInvalidInsteadOfUnreachable(): void
121 {
122 $input = new Sources([new Source('fixture.php', '<?php function target(){observe(42);}')]);
123 $configuration = new DeriverConfig();
124 $contributions = new Contributions();
125 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
126 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
127 $contributions1 = $providers->contributions;
128 $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);
129 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
130 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
131 $snapshotId = $identity->id;
132 $input1 = $providers->input;
133 $parser = new Parser(new ParserConfig($target->version));
134 $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($input1, false));
135 $program = new Index($snapshotId, $trees);
136 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
137 $site = (new CallObservations($session->program, $session->evaluators))->find('observe')[0];
138 $this->expectException(InvalidInputException::class);
139 $session->derive(new ValueQuery(new ExpressionRef($site->argument(0)->source, $site->callable, 'missing-register')));
140 }
141 public function testProvenUnreachableObservationHasNoResidualSuccess(): void
142 {
143 $input = new Sources([new Source('fixture.php', '<?php function target(){if(false){observe(42);}}')]);
144 $configuration = new DeriverConfig();
145 $contributions = new Contributions();
146 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
147 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
148 $contributions1 = $providers->contributions;
149 $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);
150 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
151 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
152 $snapshotId = $identity->id;
153 $input1 = $providers->input;
154 $parser = new Parser(new ParserConfig($target->version));
155 $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($input1, false));
156 $program = new Index($snapshotId, $trees);
157 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
158 $result = $session->derive(new ValueQuery((new CallObservations($session->program, $session->evaluators))->find('observe')[0]->argument(0)));
159 self::assertSame(Reachability::Unreachable, $result->reachability);
160 self::assertSame([], $result->normalOutcomes);
161 self::assertSame([], $result->frontiers);
162 }
163 public function testMalformedSourceRaisesParserException(): void
164 {
165 $this->expectException(ParserException::class);
166 $prepared1Input = new Sources([new Source('good.php', '<?php function target(){return 42;}'), new Source('bad.php', '<?php function broken(')]);
167 $prepared1Configuration = new DeriverConfig();
168 $prepared1Contributions = new Contributions();
169 $prepared1Target = new TargetProfile($prepared1Configuration->phpVersion, $prepared1Configuration->integerBits, $prepared1Configuration->floatPrecision);
170 $prepared1Providers = new ProviderExpansion($prepared1Input, array_map(Term::fromNative(...), $prepared1Configuration->environment), $prepared1Contributions);
171 $contributions = $prepared1Providers->contributions;
172 $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);
173 $prepared1Settings = new EvaluatorConfig($prepared1Target, $prepared1Providers->environment, $prepared1Configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $prepared1Configuration->evaluators));
174 $prepared1Identity = new SnapshotIdentity($prepared1Providers->input, $prepared1Settings, $prepared1Evaluators, $prepared1Providers->manifest);
175 $snapshotId = $prepared1Identity->id;
176 $input = $prepared1Providers->input;
177 $parser = new Parser(new ParserConfig($prepared1Target->version));
178 $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));
179 $prepared1Program = new Index($snapshotId, $trees);
180 $prepared1Snapshot = $prepared1Identity->snapshot(array_map(Frontier::fromDiagnostic(...), $prepared1Program->diagnostics()));
181 }
182 public function testFileOrderDoesNotChangeSnapshotOrSemanticResult(): void
183 {
184 $a = new Source('a.php', '<?php function target(){return helper();}');
185 $b = new Source('b.php', '<?php function helper(){return 42;}');
186 $prepared2Input = new Sources([$a, $b]);
187 $prepared2Configuration = new DeriverConfig();
188 $prepared2Contributions = new Contributions();
189 $prepared2Target = new TargetProfile($prepared2Configuration->phpVersion, $prepared2Configuration->integerBits, $prepared2Configuration->floatPrecision);
190 $prepared2Providers = new ProviderExpansion($prepared2Input, array_map(Term::fromNative(...), $prepared2Configuration->environment), $prepared2Contributions);
191 $contributions = $prepared2Providers->contributions;
192 $prepared2Evaluators = new Evaluators(new TargetProfile($prepared2Configuration->phpVersion, $prepared2Configuration->integerBits, $prepared2Configuration->floatPrecision), new Registrations($contributions->evaluators, $contributions->providers, $contributions->domains, $contributions->intrinsics, $contributions->stateSlots), $prepared2Configuration->standardEvaluators);
193 $prepared2Settings = new EvaluatorConfig($prepared2Target, $prepared2Providers->environment, $prepared2Configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $prepared2Configuration->evaluators));
194 $prepared2Identity = new SnapshotIdentity($prepared2Providers->input, $prepared2Settings, $prepared2Evaluators, $prepared2Providers->manifest);
195 $snapshotId = $prepared2Identity->id;
196 $input = $prepared2Providers->input;
197 $parser = new Parser(new ParserConfig($prepared2Target->version));
198 $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));
199 $prepared2Program = new Index($snapshotId, $trees);
200 $prepared2Snapshot = $prepared2Identity->snapshot(array_map(Frontier::fromDiagnostic(...), $prepared2Program->diagnostics()));
201 $first = new CandidateQuery(new DefinitionIndex($prepared2Program), $prepared2Settings, $prepared2Evaluators, $prepared2Snapshot);
202 $prepared3Input = new Sources([$b, $a]);
203 $prepared3Configuration = new DeriverConfig();
204 $prepared3Contributions = new Contributions();
205 $prepared3Target = new TargetProfile($prepared3Configuration->phpVersion, $prepared3Configuration->integerBits, $prepared3Configuration->floatPrecision);
206 $prepared3Providers = new ProviderExpansion($prepared3Input, array_map(Term::fromNative(...), $prepared3Configuration->environment), $prepared3Contributions);
207 $contributions1 = $prepared3Providers->contributions;
208 $prepared3Evaluators = new Evaluators(new TargetProfile($prepared3Configuration->phpVersion, $prepared3Configuration->integerBits, $prepared3Configuration->floatPrecision), new Registrations($contributions1->evaluators, $contributions1->providers, $contributions1->domains, $contributions1->intrinsics, $contributions1->stateSlots), $prepared3Configuration->standardEvaluators);
209 $prepared3Settings = new EvaluatorConfig($prepared3Target, $prepared3Providers->environment, $prepared3Configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $prepared3Configuration->evaluators));
210 $prepared3Identity = new SnapshotIdentity($prepared3Providers->input, $prepared3Settings, $prepared3Evaluators, $prepared3Providers->manifest);
211 $snapshotId1 = $prepared3Identity->id;
212 $input1 = $prepared3Providers->input;
213 $parser1 = new Parser(new ParserConfig($prepared3Target->version));
214 $trees1 = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser1->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input1, false));
215 $prepared3Program = new Index($snapshotId1, $trees1);
216 $prepared3Snapshot = $prepared3Identity->snapshot(array_map(Frontier::fromDiagnostic(...), $prepared3Program->diagnostics()));
217 $second = new CandidateQuery(new DefinitionIndex($prepared3Program), $prepared3Settings, $prepared3Evaluators, $prepared3Snapshot);
218 $one = $first->derive(new ReturnQuery('target'));
219 $two = $second->derive(new ReturnQuery('target'));
220 self::assertSame($prepared2Snapshot->id, $prepared3Snapshot->id);
221 self::assertSame($one->reference->id, $two->reference->id);
222 self::assertEquals(iterator_to_array($one, false), iterator_to_array($two, false));
223 }
224 public function testSourceCaptureDoesNotExecuteTopLevelCode(): void
225 {
226 $input = new Sources([new Source('fixture.php', '<?php throw new RuntimeException("Never execute this file");exit(99);function target(){return 42;}')]);
227 $configuration = new DeriverConfig();
228 $contributions = new Contributions();
229 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
230 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
231 $contributions1 = $providers->contributions;
232 $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);
233 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
234 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
235 $snapshotId = $identity->id;
236 $input1 = $providers->input;
237 $parser = new Parser(new ParserConfig($target->version));
238 $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($input1, false));
239 $program = new Index($snapshotId, $trees);
240 $session = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
241 $result = $session->derive(new ReturnQuery('target'));
242 self::assertSame(42, $result->normalOutcomes[0]->values['return']->native());
243 self::assertSame([], $result->frontiers);
244 }
245 public function testSourceChangesInvalidateResults(): void
246 {
247 $input = new Sources([new Source('fixture.php', '<?php function target(){return 1;}')]);
248 $configuration = new DeriverConfig();
249 $contributions = new Contributions();
250 $target = new TargetProfile($configuration->phpVersion, $configuration->integerBits, $configuration->floatPrecision);
251 $providers = new ProviderExpansion($input, array_map(Term::fromNative(...), $configuration->environment), $contributions);
252 $contributions1 = $providers->contributions;
253 $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);
254 $settings = new EvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration->evaluators));
255 $identity = new SnapshotIdentity($providers->input, $settings, $evaluators, $providers->manifest);
256 $snapshotId = $identity->id;
257 $input1 = $providers->input;
258 $parser = new Parser(new ParserConfig($target->version));
259 $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($input1, false));
260 $program = new Index($snapshotId, $trees);
261 $first = new QueryExecution($program, new ExecutionEvaluatorConfig($target, $providers->environment, $configuration->standardEvaluators), $evaluators, $identity->snapshot(array_map(Frontier::fromDiagnostic(...), $program->diagnostics())));
262 $input2 = new Sources([new Source('fixture.php', '<?php function target(){return 2;}')]);
263 $configuration1 = new DeriverConfig();
264 $contributions2 = new Contributions();
265 $target1 = new TargetProfile($configuration1->phpVersion, $configuration1->integerBits, $configuration1->floatPrecision);
266 $providers1 = new ProviderExpansion($input2, array_map(Term::fromNative(...), $configuration1->environment), $contributions2);
267 $contributions3 = $providers1->contributions;
268 $evaluators1 = new Evaluators(new TargetProfile($configuration1->phpVersion, $configuration1->integerBits, $configuration1->floatPrecision), new Registrations($contributions3->evaluators, $contributions3->providers, $contributions3->domains, $contributions3->intrinsics, $contributions3->stateSlots), $configuration1->standardEvaluators);
269 $settings1 = new EvaluatorConfig($target1, $providers1->environment, $configuration1->standardEvaluators, array_map((new MicroEvaluatorConversion())->convert(...), $configuration1->evaluators));
270 $identity1 = new SnapshotIdentity($providers1->input, $settings1, $evaluators1, $providers1->manifest);
271 $snapshotId1 = $identity1->id;
272 $input3 = $providers1->input;
273 $parser1 = new Parser(new ParserConfig($target1->version));
274 $trees1 = array_map(static fn (Source $source1): File => (new Resolver())->resolve($parser1->parse(new Source(Path::normalize($source1->path), $source1->contents, $source1->declarationsOnly))), iterator_to_array($input3, false));
275 $program1 = new Index($snapshotId1, $trees1);
276 $second = new QueryExecution($program1, new ExecutionEvaluatorConfig($target1, $providers1->environment, $configuration1->standardEvaluators), $evaluators1, $identity1->snapshot(array_map(Frontier::fromDiagnostic(...), $program1->diagnostics())));
277 self::assertNotSame($first->snapshot->id, $second->snapshot->id);
278 self::assertSame(2, $second->derive(new ReturnQuery('target'))->normalOutcomes[0]->values['return']->native());
279 }
280}
281