private static bool RewriteSyntax(IResourceTypeProvider resourceTypeProvider, Workspace workspace, Uri entryUri, Func <SemanticModel, SyntaxRewriteVisitor> rewriteVisitorBuilder)
        {
            var hasChanges         = false;
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), workspace, entryUri);
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            foreach (var(fileUri, syntaxTree) in workspace.GetActiveSyntaxTrees())
            {
                var entryFile  = syntaxTreeGrouping.EntryPoint;
                var entryModel = compilation.GetEntrypointSemanticModel();

                var newProgramSyntax = rewriteVisitorBuilder(compilation.GetSemanticModel(syntaxTree)).Rewrite(syntaxTree.ProgramSyntax);

                if (!object.ReferenceEquals(syntaxTree.ProgramSyntax, newProgramSyntax))
                {
                    hasChanges = true;
                    var newSyntaxTree = new SyntaxTree(fileUri, ImmutableArray <int> .Empty, newProgramSyntax);
                    workspace.UpsertSyntaxTrees(newSyntaxTree.AsEnumerable());

                    syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), workspace, entryUri);
                    compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);
                }
            }

            return(hasChanges);
        }
Exemple #2
0
        public CompilationContext Create(IReadOnlyWorkspace workspace, DocumentUri documentUri)
        {
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(fileResolver, workspace, documentUri.ToUri());
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            return(new CompilationContext(compilation));
        }
Exemple #3
0
        private void BuildManyFilesToStdOut(IDiagnosticLogger logger, string[] bicepPaths)
        {
            using var writer = new JsonTextWriter(this.outputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            if (bicepPaths.Length > 1)
            {
                writer.WriteStartArray();
            }
            foreach (var bicepPath in bicepPaths)
            {
                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                var success = LogDiagnosticsAndCheckSuccess(logger, compilation);
                if (success)
                {
                    var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

                    emitter.Emit(writer);
                }
            }
            if (bicepPaths.Length > 1)
            {
                writer.WriteEndArray();
            }
        }
Exemple #4
0
        public static Compilation CopyFilesAndCreateCompilation(this DataSet dataSet, TestContext testContext, out string outputDirectory)
        {
            outputDirectory = dataSet.SaveFilesToTestDirectory(testContext, dataSet.Name);
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), Path.Combine(outputDirectory, DataSet.TestFileMain));

            return(new Compilation(TestResourceTypeProvider.Create(), syntaxTreeGrouping));
        }
Exemple #5
0
        public void ValidBicepTextWriter_TemplateEmiterTemplateHashCheck(DataSet dataSet)
        {
            var          outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext, dataSet.Name);
            var          bicepFilePath   = Path.Combine(outputDirectory, DataSet.TestFileMain);
            MemoryStream memoryStream    = new MemoryStream();

            // emitting the template should be successful
            var result = this.EmitTemplate(SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), memoryStream, ThisAssembly.AssemblyFileVersion);

            result.Diagnostics.Should().BeEmptyOrContainDeprecatedDiagnosticOnly();
            result.Status.Should().Be(EmitStatus.Succeeded);

            var actual   = JToken.ReadFrom(new JsonTextReader(new StreamReader(new MemoryStream(memoryStream.ToArray()))));
            var compiled = JToken.Parse(dataSet.Compiled !);

            // TemplateHash should not be the same with difference assembly versions
            actual.SelectToken("metadata._generator.templateHash") !.ToString().Should().NotBe(
                compiled.SelectToken("metadata._generator.templateHash") !.ToString()
                );
            actual.SelectToken("metadata._generator.version") !.ToString().Should().Be(ThisAssembly.AssemblyFileVersion);

            // Aside from the different metadata, the templates should be the same
            ((JObject)actual).Remove("metadata");
            ((JObject)compiled).Remove("metadata");

            var compiledFilePath = FileHelper.SaveResultFile(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled), actual.ToString(Formatting.Indented));

            actual.Should().EqualWithJsonDiffOutput(
                TestContext,
                compiled,
                expectedLocation: DataSet.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #6
0
        public int Decompile(ILogger logger, DecompileArguments arguments)
        {
            logger.LogWarning(
                "WARNING: Decompilation is a best-effort process, as there is no guaranteed mapping from ARM JSON to Bicep.\n" +
                "You may need to fix warnings and errors in the generated bicep file(s), or decompilation may fail entirely if an accurate conversion is not possible.\n" +
                "If you would like to report any issues or inaccurate conversions, please see https://github.com/Azure/bicep/issues.");

            var diagnosticLogger = new BicepDiagnosticLogger(logger);
            var jsonPath         = PathHelper.ResolvePath(arguments.InputFile);

            try
            {
                var(bicepUri, filesToSave) = TemplateDecompiler.DecompileFileWithModules(resourceTypeProvider, new FileResolver(), PathHelper.FilePathToFileUrl(jsonPath));
                foreach (var(fileUri, bicepOutput) in filesToSave)
                {
                    File.WriteAllText(fileUri.LocalPath, bicepOutput);
                }

                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), bicepUri);
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                return(LogDiagnosticsAndCheckSuccess(diagnosticLogger, compilation) ? 0 : 1);
            }
            catch (Exception exception)
            {
                this.errorWriter.WriteLine($"{jsonPath}: Decompilation failed with fatal error \"{exception.Message}\"");
                return(1);
            }
        }
Exemple #7
0
        private int DecompileToStdout(IDiagnosticLogger logger, string jsonPath)
        {
            var tempOutputPath = Path.ChangeExtension(Path.GetTempFileName(), "bicep");

            try
            {
                var(_, filesToSave) = TemplateDecompiler.DecompileFileWithModules(resourceTypeProvider, new FileResolver(), PathHelper.FilePathToFileUrl(jsonPath));
                foreach (var(_, bicepOutput) in filesToSave)
                {
                    this.outputWriter.Write(bicepOutput);
                    File.WriteAllText(tempOutputPath, bicepOutput);
                }

                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(tempOutputPath));
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                return(LogDiagnosticsAndCheckSuccess(logger, compilation) ? 0 : 1);
            }
            catch (Exception exception)
            {
                this.errorWriter.WriteLine($"{jsonPath}: Decompilation failed with fatal error \"{exception.Message}\"");
                return(1);
            } finally
            {
                if (File.Exists(tempOutputPath))
                {
                    File.Delete(tempOutputPath);
                }
            }
        }
        public static Compilation CopyFilesAndCreateCompilation(this DataSet dataSet, TestContext testContext, out string outputDirectory, out Uri fileUri)
        {
            outputDirectory = dataSet.SaveFilesToTestDirectory(testContext);
            fileUri         = PathHelper.FilePathToFileUrl(Path.Combine(outputDirectory, DataSet.TestFileMain));
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(BicepTestConstants.FileResolver, new Workspace(), fileUri);

            return(new Compilation(AzResourceTypeProvider.CreateWithAzTypes(), syntaxTreeGrouping));
        }
Exemple #9
0
        public static Compilation CopyFilesAndCreateCompilation(this DataSet dataSet, TestContext testContext, out string outputDirectory)
        {
            outputDirectory = dataSet.SaveFilesToTestDirectory(testContext, dataSet.Name);
            var fileUri            = PathHelper.FilePathToFileUrl(Path.Combine(outputDirectory, DataSet.TestFileMain));
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), fileUri);

            return(new Compilation(new AzResourceTypeProvider(TypeLoader), syntaxTreeGrouping));
        }
Exemple #10
0
        public static SyntaxTreeGrouping CreateForFiles(IReadOnlyDictionary <Uri, string> files, Uri entryFileUri)
        {
            var workspace   = new Workspace();
            var syntaxTrees = files.Select(kvp => SyntaxTree.Create(kvp.Key, kvp.Value));

            workspace.UpsertSyntaxTrees(syntaxTrees);

            return(SyntaxTreeGroupingBuilder.Build(new FileResolver(), workspace, entryFileUri));
        }
Exemple #11
0
        private static Compilation GetCompilation(string text)
        {
            var fileName     = "/main.bicep";
            var fileResolver = new InMemoryFileResolver(new Dictionary <string, string> {
                [fileName] = text
            }, filePath => "Modules are not supported in the Bicep Playground");
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(fileResolver, fileName);

            return(new Compilation(resourceTypeProvider, syntaxTreeGrouping));
        }
Exemple #12
0
        private static Compilation GetCompilation(string fileContents)
        {
            var fileUri    = new Uri("inmemory:///main.bicep");
            var workspace  = new Workspace();
            var syntaxTree = SyntaxTree.Create(fileUri, fileContents);

            workspace.UpsertSyntaxTrees(syntaxTree.AsEnumerable());

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), workspace, fileUri);

            return(new Compilation(resourceTypeProvider, syntaxTreeGrouping));
        }
Exemple #13
0
        public Compilation Compile(string inputPath)
        {
            var inputUri = PathHelper.FilePathToFileUrl(inputPath);

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(this.fileResolver, this.workspace, inputUri);

            var compilation = new Compilation(this.invocationContext.ResourceTypeProvider, syntaxTreeGrouping);

            LogDiagnostics(compilation);

            return(compilation);
        }
        public void InvalidBicep_TemplateEmiterShouldNotProduceAnyTemplate(DataSet dataSet)
        {
            var    outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext, dataSet.Name);
            var    bicepFilePath   = Path.Combine(outputDirectory, DataSet.TestFileMain);
            string filePath        = FileHelper.GetResultFilePath(this.TestContext, $"{dataSet.Name}_Compiled_Original.json");

            // emitting the template should fail
            var result = this.EmitTemplate(SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), filePath);

            result.Status.Should().Be(EmitStatus.Failed);
            result.Diagnostics.Should().NotBeEmpty();
        }
Exemple #15
0
        private void BuildToFile(IDiagnosticLogger logger, string bicepPath, string outputPath)
        {
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            var success = LogDiagnosticsAndCheckSuccess(logger, compilation);

            if (success)
            {
                var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), this.assemblyFileVersion);

                using var outputStream = CreateFileStream(outputPath);
                emitter.Emit(outputStream);
            }
        }
Exemple #16
0
        public void ExampleIsValid(ExampleData example)
        {
            // save all the files in the containing directory to disk so that we can test module resolution
            var parentStream    = Path.GetDirectoryName(example.BicepStreamName) !.Replace('\\', '/');
            var outputDirectory = FileHelper.SaveEmbeddedResourcesWithPathPrefix(TestContext, typeof(ExamplesTests).Assembly, example.OutputFolderName, parentStream);
            var bicepFileName   = Path.Combine(outputDirectory, Path.GetFileName(example.BicepStreamName));
            var jsonFileName    = Path.Combine(outputDirectory, Path.GetFileName(example.JsonStreamName));

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFileName));
            var compilation        = new Compilation(new AzResourceTypeProvider(), syntaxTreeGrouping);
            var emitter            = new TemplateEmitter(compilation.GetEntrypointSemanticModel());

            // group assertion failures using AssertionScope, rather than reporting the first failure
            using (new AssertionScope())
            {
                foreach (var(syntaxTree, diagnostics) in compilation.GetAllDiagnosticsBySyntaxTree())
                {
                    var nonPermittedDiagnostics = diagnostics.Where(x => !IsPermittedMissingTypeDiagnostic(x));

                    nonPermittedDiagnostics.Should().BeEmpty($"\"{syntaxTree.FileUri.LocalPath}\" should not have warnings or errors");
                }

                var exampleExists = File.Exists(jsonFileName);
                exampleExists.Should().BeTrue($"Generated example \"{jsonFileName}\" should be checked in");

                using var stream = new MemoryStream();
                var result = emitter.Emit(stream);

                result.Status.Should().Be(EmitStatus.Succeeded);

                if (result.Status == EmitStatus.Succeeded)
                {
                    stream.Position = 0;
                    var generated = new StreamReader(stream).ReadToEnd();

                    var actual = JToken.Parse(generated);
                    File.WriteAllText(jsonFileName + ".actual", generated);

                    actual.Should().EqualWithJsonDiffOutput(
                        TestContext,
                        exampleExists ? JToken.Parse(File.ReadAllText(jsonFileName)) : new JObject(),
                        example.JsonStreamName,
                        jsonFileName + ".actual");
                }
            }
        }
Exemple #17
0
        private static IEnumerable <string> GetAllDiagnostics(string bicepFilePath)
        {
            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath));
            var compilation        = new Compilation(TestTypeHelper.CreateEmptyProvider(), syntaxTreeGrouping);

            var output = new List <string>();

            foreach (var(syntaxTree, diagnostics) in compilation.GetAllDiagnosticsBySyntaxTree())
            {
                foreach (var diagnostic in diagnostics)
                {
                    var(line, character) = TextCoordinateConverter.GetPosition(syntaxTree.LineStarts, diagnostic.Span.Position);
                    output.Add($"{syntaxTree.FileUri.LocalPath}({line + 1},{character + 1}) : {diagnostic.Level} {diagnostic.Code}: {diagnostic.Message}");
                }
            }

            return(output);
        }
Exemple #18
0
        private void BuildToStdout(IDiagnosticLogger logger, string bicepPath)
        {
            using var writer = new JsonTextWriter(this.outputWriter)
                  {
                      Formatting = Formatting.Indented
                  };

            var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepPath));
            var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

            var success = LogDiagnosticsAndCheckSuccess(logger, compilation);

            if (success)
            {
                var emitter = new TemplateEmitter(compilation.GetEntrypointSemanticModel(), this.assemblyFileVersion);

                emitter.Emit(writer);
            }
        }
        public void ValidBicep_TemplateEmiterShouldProduceExpectedTemplate(DataSet dataSet)
        {
            var outputDirectory  = dataSet.SaveFilesToTestDirectory(TestContext, dataSet.Name);
            var bicepFilePath    = Path.Combine(outputDirectory, DataSet.TestFileMain);
            var compiledFilePath = FileHelper.GetResultFilePath(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled));

            // emitting the template should be successful
            var result = this.EmitTemplate(SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), compiledFilePath);

            result.Status.Should().Be(EmitStatus.Succeeded);
            result.Diagnostics.Should().BeEmpty();

            var actual = JToken.Parse(File.ReadAllText(compiledFilePath));

            actual.Should().EqualWithJsonDiffOutput(
                JToken.Parse(dataSet.Compiled !),
                expectedLocation: OutputHelper.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #20
0
        public void Decompiler_generates_expected_bicep_files_with_diagnostics(ExampleData example)
        {
            // save all the files in the containing directory to disk so that we can test module resolution
            var parentStream    = Path.GetDirectoryName(example.BicepStreamName) !.Replace('\\', '/');
            var outputDirectory = FileHelper.SaveEmbeddedResourcesWithPathPrefix(TestContext, typeof(DecompilationTests).Assembly, parentStream);
            var bicepFileName   = Path.Combine(outputDirectory, Path.GetFileName(example.BicepStreamName));
            var jsonFileName    = Path.Combine(outputDirectory, Path.GetFileName(example.JsonStreamName));
            var typeProvider    = AzResourceTypeProvider.CreateWithAzTypes();

            var(bicepUri, filesToSave) = TemplateDecompiler.DecompileFileWithModules(typeProvider, new FileResolver(), PathHelper.FilePathToFileUrl(jsonFileName));

            var syntaxTrees = filesToSave.Select(kvp => SyntaxTree.Create(kvp.Key, kvp.Value));
            var workspace   = new Workspace();

            workspace.UpsertSyntaxTrees(syntaxTrees);

            var syntaxTreeGrouping      = SyntaxTreeGroupingBuilder.Build(new FileResolver(), workspace, bicepUri);
            var compilation             = new Compilation(typeProvider, syntaxTreeGrouping);
            var diagnosticsBySyntaxTree = compilation.GetAllDiagnosticsBySyntaxTree();

            using (new AssertionScope())
            {
                foreach (var syntaxTree in syntaxTreeGrouping.SyntaxTrees)
                {
                    var exampleExists = File.Exists(syntaxTree.FileUri.LocalPath);
                    exampleExists.Should().BeTrue($"Generated example \"{syntaxTree.FileUri.LocalPath}\" should be checked in");

                    var diagnostics = diagnosticsBySyntaxTree[syntaxTree];
                    var bicepOutput = filesToSave[syntaxTree.FileUri];

                    var sourceTextWithDiags = OutputHelper.AddDiagsToSourceText(bicepOutput, Environment.NewLine, diagnostics, diag => OutputHelper.GetDiagLoggingString(bicepOutput, outputDirectory, diag));
                    File.WriteAllText(syntaxTree.FileUri.LocalPath + ".actual", sourceTextWithDiags);

                    sourceTextWithDiags.Should().EqualWithLineByLineDiffOutput(
                        TestContext,
                        exampleExists ? File.ReadAllText(syntaxTree.FileUri.LocalPath) : "",
                        expectedLocation: Path.Combine("src", "Bicep.Decompiler.IntegrationTests", parentStream, Path.GetRelativePath(outputDirectory, syntaxTree.FileUri.LocalPath)),
                        actualLocation: syntaxTree.FileUri.LocalPath + ".actual");
                }
            }
        }
Exemple #21
0
        private bool DecompileSingleFile(IDiagnosticLogger logger, string filePath)
        {
            try
            {
                var(bicepUri, filesToSave) = TemplateDecompiler.DecompileFileWithModules(resourceTypeProvider, new FileResolver(), PathHelper.FilePathToFileUrl(filePath));
                foreach (var(fileUri, bicepOutput) in filesToSave)
                {
                    File.WriteAllText(fileUri.LocalPath, bicepOutput);
                }

                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), bicepUri);
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                return(LogDiagnosticsAndCheckSuccess(logger, compilation));
            }
            catch (Exception exception)
            {
                this.errorWriter.WriteLine($"{filePath}: Decompilation failed with fatal error \"{exception.Message}\"");
                return(false);
            }
        }
        public void ValidBicepTextWriter_TemplateEmiterShouldProduceExpectedTemplate(DataSet dataSet)
        {
            var          outputDirectory = dataSet.SaveFilesToTestDirectory(TestContext, dataSet.Name);
            var          bicepFilePath   = Path.Combine(outputDirectory, DataSet.TestFileMain);
            MemoryStream memoryStream    = new MemoryStream();

            // emitting the template should be successful
            var result = this.EmitTemplate(SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(bicepFilePath)), memoryStream);

            result.Diagnostics.Should().BeEmpty();
            result.Status.Should().Be(EmitStatus.Succeeded);

            // normalizing the formatting in case there are differences in indentation
            // this way the diff between actual and expected will be clean
            var actual           = JToken.ReadFrom(new JsonTextReader(new StreamReader(new MemoryStream(memoryStream.ToArray()))));
            var compiledFilePath = FileHelper.SaveResultFile(this.TestContext, Path.Combine(dataSet.Name, DataSet.TestFileMainCompiled), actual.ToString(Formatting.Indented));

            actual.Should().EqualWithJsonDiffOutput(
                JToken.Parse(dataSet.Compiled !),
                expectedLocation: OutputHelper.GetBaselineUpdatePath(dataSet, DataSet.TestFileMainCompiled),
                actualLocation: compiledFilePath);
        }
Exemple #23
0
        private int DecompileToFile(IDiagnosticLogger logger, string jsonPath, string outputPath)
        {
            try
            {
                var(_, filesToSave) = TemplateDecompiler.DecompileFileWithModules(resourceTypeProvider, new FileResolver(), PathHelper.FilePathToFileUrl(jsonPath));
                foreach (var(_, bicepOutput) in filesToSave)
                {
                    File.WriteAllText(outputPath, bicepOutput);
                }

                var outputPathToCheck  = Path.GetFullPath(outputPath);
                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(outputPathToCheck));
                var compilation        = new Compilation(resourceTypeProvider, syntaxTreeGrouping);

                return(LogDiagnosticsAndCheckSuccess(logger, compilation) ? 0 : 1);
            }
            catch (Exception exception)
            {
                this.errorWriter.WriteLine($"{jsonPath}: Decompilation failed with fatal error \"{exception.Message}\"");
                return(1);
            }
        }
Exemple #24
0
        public async Task ValidateSnippetCompletionAfterPlaceholderReplacements(CompletionData completionData)
        {
            string pathPrefix = $"Completions/SnippetTemplates/{completionData.Prefix}";

            var outputDirectory = FileHelper.SaveEmbeddedResourcesWithPathPrefix(TestContext, typeof(CompletionTests).Assembly, pathPrefix);

            var bicepFileName       = Path.Combine(outputDirectory, "main.bicep");
            var bicepSourceFileName = Path.Combine("src", "Bicep.LangServer.IntegrationTests", pathPrefix, Path.GetRelativePath(outputDirectory, bicepFileName));

            File.Exists(bicepFileName).Should().BeTrue($"Snippet placeholder file \"{bicepSourceFileName}\" should be checked in");
            var bicepContents = await File.ReadAllTextAsync(bicepFileName);

            // Request the expected completion from the server, and ensure it is unique + valid
            var completionText = await RequestSnippetCompletion(bicepFileName, completionData, bicepContents);

            // Replace all the placeholders with values from the placeholder file
            var replacementContents = SnippetCompletionTestHelper.GetSnippetTextAfterPlaceholderReplacements(completionText, bicepContents);

            using (new AssertionScope())
            {
                var combinedFileName       = Path.Combine(outputDirectory, "main.combined.bicep");
                var combinedSourceFileName = Path.Combine("src", "Bicep.LangServer.IntegrationTests", pathPrefix, Path.GetRelativePath(outputDirectory, combinedFileName));
                File.Exists(combinedFileName).Should().BeTrue($"Combined snippet file \"{combinedSourceFileName}\" should be checked in");

                var syntaxTreeGrouping = SyntaxTreeGroupingBuilder.Build(new FileResolver(), new Workspace(), PathHelper.FilePathToFileUrl(combinedFileName));
                var compilation        = new Compilation(TypeProvider, syntaxTreeGrouping);
                var diagnostics        = compilation.GetEntrypointSemanticModel().GetAllDiagnostics();

                var sourceTextWithDiags = OutputHelper.AddDiagsToSourceText(replacementContents, Environment.NewLine, diagnostics, diag => OutputHelper.GetDiagLoggingString(replacementContents, outputDirectory, diag));
                File.WriteAllText(combinedFileName + ".actual", sourceTextWithDiags);

                sourceTextWithDiags.Should().EqualWithLineByLineDiffOutput(
                    TestContext,
                    File.Exists(combinedFileName) ? (await File.ReadAllTextAsync(combinedFileName)) : string.Empty,
                    expectedLocation: combinedSourceFileName,
                    actualLocation: combinedFileName + ".actual");
            }
        }
Exemple #25
0
        public static SyntaxTreeGrouping CreateForFiles(IReadOnlyDictionary <string, string> files, string entryFileName)
        {
            var fileResolver = new InMemoryFileResolver(files);

            return(SyntaxTreeGroupingBuilder.Build(fileResolver, entryFileName));
        }