Example #1
0
        public async Task TestSpec2SpecMapGeneratedByTypeChecker(SimpleGraph file2file)
        {
            var helper    = new WorkspaceEvaluationHelper(TestOutputDirectory, null, forTesting: true);
            var repo      = GenerateFullWorkspaceRepo(helper, file2file);
            var workspace = await helper.ParseAsync(repo);

            var semanticModel = helper.Typecheck(workspace);

            Func <int, AbsolutePath> specIdxToSpecPath = (specIdx) => SpecIdxToSpecPath(repo, specIdx);
            var relevantSpecPaths = file2file.Nodes.Select(specIdxToSpecPath).ToList();
            Func <RoaringBitSet, IEnumerable <AbsolutePath> > materializeRelevant = (bitSet) =>
            {
                bitSet.MaterializeSetIfNeeded(string.Empty, (s, i) => workspace.GetAllSourceFiles()[i].GetAbsolutePath(helper.PathTable));
                return(bitSet.MaterializedSetOfPaths.Intersect(relevantSpecPaths));
            };

            // test the spec2spec map generated by TypeChecker
            XAssert.All(
                file2file.Nodes,
                specIdx =>
            {
                var specSourceFile       = workspace.GetSourceFile(SpecIdxToSpecPath(repo, specIdx));
                var computedDependencies = materializeRelevant(semanticModel.GetFileDependenciesOf(specSourceFile));
                var computedDependents   = materializeRelevant(semanticModel.GetFileDependentFilesOf(specSourceFile));
                var expectedDependents   = file2file.OutgoingEdges(specIdx).Select(e => specIdxToSpecPath(e.Dest));
                var expectedDependencies = file2file.IncomingEdges(specIdx).Select(e => specIdxToSpecPath(e.Src));

                XAssert.SetEqual(expectedDependencies, computedDependents);
                XAssert.SetEqual(expectedDependents, computedDependencies);
            });
        }
Example #2
0
        private async Task DoPartialEvalTest(SimpleGraph file2file, int[] changed,
                                             int[] expectedDownstream, int[] expectedUpstream, int[] expectedIndirectUpstream, int[] expectedAffected)
        {
            ComputeAndCheckSpecStates(file2file, changed, expectedDownstream, expectedUpstream, expectedIndirectUpstream, expectedAffected);

            // helpers
            var helper = new WorkspaceEvaluationHelper(TestOutputDirectory, null, forTesting: true);
            var repo   = GenerateFullWorkspaceRepo(helper, file2file);
            Func <int, AbsolutePath> specIdxToSpecPath = (specIdx) => SpecIdxToSpecPath(repo, specIdx);

            // create workspace and semantic model
            var workspace = await helper.ParseAsync(repo);

            var semanticModel = helper.Typecheck(workspace);

            var changedWithDownstream      = changed.Union(expectedDownstream).ToArray();
            var changedWithDownstreamPaths = changedWithDownstream.Select(specIdxToSpecPath).ToArray();

            // test workspace 'closure of dependent files' computation
            var specDepProvider       = new WorkspaceBasedSpecDependencyProvider(workspace, helper.PathTable);
            var dependentPathsClosure = specDepProvider.ComputeReflectiveClosureOfDependentFiles(changed.Select(specIdxToSpecPath));

            XAssert.SetEqual(changedWithDownstreamPaths.ToStrings(helper.PathTable), dependentPathsClosure.ToStrings(helper.PathTable));

            // test workspace 'closure of dependency files' computation
            var dependencyPathsClosure = specDepProvider
                                         .ComputeReflectiveClosureOfDependencyFiles(changedWithDownstreamPaths)
                                         .Intersect(file2file.Nodes.Select(specIdxToSpecPath)); // this leaves only spec files from TestModule, i.e., filters out prelude files etc.
            var expectedAffectedPaths = expectedAffected.Select(specIdxToSpecPath);

            XAssert.SetEqual(expectedAffectedPaths.ToStrings(helper.PathTable), dependencyPathsClosure.ToStrings(helper.PathTable));

            // full evaluation
            var interpreter = await helper.ConvertAsync(workspace, oldPipGraph : null);

            var pipGraph = await helper.EvaluateAsync(workspace, interpreter);

            AssertPipGraphContent(pipGraph, file2file, helper.StringTable);

            // partial evaluation
            var helper2     = new WorkspaceEvaluationHelper(TestOutputDirectory, helper.FrontEndContext, forTesting: true);
            var partialRepo = GenerateWorkspaceRepo(helper2, file2file, expectedAffected);
            var pipGraph2   = await helper2.EvaluateWithGraphPatchingAsync(
                repo : partialRepo,
                oldPipGraph : pipGraph,
                changedSpecs : changedWithDownstreamPaths,
                specsToIgnore : expectedUpstream.Union(expectedIndirectUpstream).Select(specIdxToSpecPath));

            // assert we still get the full graph
            AssertPipGraphContent(pipGraph2, file2file, helper2.StringTable);
        }
Example #3
0
        private ModuleRepository GenerateWorkspaceRepo(WorkspaceEvaluationHelper helper, SimpleGraph file2file, int[] selectedFiles)
        {
            XAssert.IsTrue(file2file.IsDAG(), "Must be a DAG");
            var specs = selectedFiles
                        .Select(i =>
            {
                var specsToImport = file2file.OutgoingEdges(i).Select(e => e.Dest).ToList();
                var specContent   = GenerateSpec(i, specsToImport);
                return(new ModuleRepository.NameContentPair(GetSpecName(i), specContent));
            })
                        .Concat(new[]
            {
                new ModuleRepository.NameContentPair(HelperSpecName, GetHelperSpecContent()),
                new ModuleRepository.NameContentPair(Qualifier, GetSpecWithDefaultQualifierContent()),
            })
                        .ToArray();

            return(helper.NewModuleRepoWithPrelude().AddContent(TestModule, specs));
        }
Example #4
0
        public async Task TestSimple()
        {
            const string Spec0 = "import {Transformer} from 'Sdk.Transformers';\r\nexport const x = Transformer.copyFile(f`src-x.txt`, Context.getNewOutputDirectory('test').combine('dest-x.txt'));";
            const string Spec1 = "import {Transformer} from 'Sdk.Transformers';\r\nexport const y = Transformer.copyFile(f`src-y.txt`, Context.getNewOutputDirectory('test').combine('dest-y.txt'));";

            var helperFull = new WorkspaceEvaluationHelper(TestOutputDirectory, context: null, forTesting: true);
            var testModule = ModuleDescriptor.CreateForTesting("MyModule1");

            // evaluate full
            var repo     = helperFull.NewModuleRepoWithPrelude().AddContent(testModule, Spec0, Spec1);
            var pipGraph = await helperFull.EvaluateAsync(repo);

            var fullGraphPipCounts = new Dictionary <PipType, int>
            {
                [PipType.CopyFile] = 2,
            };

            AssertPipGraphCounts(pipGraph, fullGraphPipCounts);

            // evaluate partial without patching --> result is a smaller graph
            {
                var helperPartial = new WorkspaceEvaluationHelper(TestOutputDirectory, context: helperFull.FrontEndContext, forTesting: true);
                var partialRepo   = helperPartial.NewModuleRepoWithPrelude().AddContent(testModule, Spec0);
                var newPipGraph   = await helperPartial.EvaluateAsync(partialRepo);

                AssertPipGraphCounts(newPipGraph, new Dictionary <PipType, int>
                {
                    [PipType.CopyFile] = 1,
                });
            }

            // evaluate partial with patching --> same as full graph
            {
                // NOTE: must start with previous PathTable, because some paths from the old build might not be seen in the partial workspace
                var helperPartial = new WorkspaceEvaluationHelper(TestOutputDirectory, context: helperFull.FrontEndContext, forTesting: true);
                var partialRepo   = helperPartial.NewModuleRepoWithPrelude().AddContent(testModule, Spec0);
                var changedSpecs  = new[] { repo.GetPathToModuleAndSpec(testModule, 0) };
                var newPipGraph   = await helperPartial.EvaluateWithGraphPatchingAsync(partialRepo, oldPipGraph : pipGraph, changedSpecs : changedSpecs, specsToIgnore : null);

                AssertPipGraphCounts(newPipGraph, fullGraphPipCounts);
            }
        }
Example #5
0
 private ModuleRepository GenerateFullWorkspaceRepo(WorkspaceEvaluationHelper helper, SimpleGraph file2file)
 {
     return(GenerateWorkspaceRepo(helper, file2file, selectedFiles: file2file.Nodes.ToArray()));
 }