Exemplo n.º 1
0
        private bool RewriteSyntax(Workspace workspace, Uri entryUri, Func <SemanticModel, SyntaxRewriteVisitor> rewriteVisitorBuilder)
        {
            var hasChanges         = false;
            var dispatcher         = new ModuleDispatcher(this.registryProvider);
            var configuration      = configurationManager.GetBuiltInConfiguration(disableAnalyzers: true);
            var linterAnalyzer     = new LinterAnalyzer(configuration);
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri, configuration);
            var compilation        = new Compilation(this.features, namespaceProvider, sourceFileGrouping, configuration, linterAnalyzer);

            // force enumeration here with .ToImmutableArray() as we're going to be modifying the sourceFileGrouping collection as we iterate
            var fileUris = sourceFileGrouping.SourceFiles.Select(x => x.FileUri).ToImmutableArray();

            foreach (var fileUri in fileUris)
            {
                if (sourceFileGrouping.SourceFiles.FirstOrDefault(x => x.FileUri == fileUri) is not BicepFile bicepFile)
                {
                    throw new InvalidOperationException($"Failed to find a bicep source file for URI {fileUri}.");
                }

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

                if (!object.ReferenceEquals(bicepFile.ProgramSyntax, newProgramSyntax))
                {
                    hasChanges = true;
                    var newFile = SourceFileFactory.CreateBicepFile(fileUri, newProgramSyntax.ToText());
                    workspace.UpsertSourceFile(newFile);

                    sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, entryUri, configuration);
                    compilation        = new Compilation(this.features, namespaceProvider, sourceFileGrouping, configuration, linterAnalyzer);
                }
            }

            return(hasChanges);
        }
Exemplo n.º 2
0
        public async Task Overlapping_tokens_are_not_returned(DataSet dataSet)
        {
            var uri       = DocumentUri.From($"/{dataSet.Name}");
            var bicepFile = SourceFileFactory.CreateBicepFile(uri.ToUri(), dataSet.Bicep);

            using var helper = await LanguageServerHelper.StartServerWithTextAsync(TestContext, dataSet.Bicep, uri);

            var client = helper.Client;

            var semanticTokens = await client.TextDocument.RequestSemanticTokens(new SemanticTokensParams
            {
                TextDocument = new TextDocumentIdentifier(uri),
            });

            var tokenSpans = CalculateTokenTextSpans(bicepFile.LineStarts, semanticTokens !.Data).ToArray();

            for (var i = 1; i < tokenSpans.Length; i++)
            {
                var currentSpan = tokenSpans[i];
                var prevSpan    = tokenSpans[i - 1];

                if (TextSpan.AreOverlapping(prevSpan, currentSpan))
                {
                    using (new AssertionScope()
                           .WithAnnotations(bicepFile, "overlapping tokens", new[] { prevSpan, currentSpan }, _ => "here", x => x.ToRange(bicepFile.LineStarts)))
                    {
                        TextSpan.AreOverlapping(prevSpan, currentSpan).Should().BeFalse();
                    }
                }
            }
        }
Exemplo n.º 3
0
        public async Task VerifyNestedResourceCompletionReturnsCustomSnippetWithoutParentInformation()
        {
            string fileWithCursors = @"resource automationAccount 'Microsoft.Automation/automationAccounts@2019-06-01' = {
  name: 'name'
  location: resourceGroup().location

  |
}";

            var(file, cursors) = ParserHelper.GetFileWithCursors(fileWithCursors);
            var bicepFile = SourceFileFactory.CreateBicepFile(new Uri("file:///path/to/main.bicep"), file);
            var client    = await IntegrationTestHelper.StartServerWithTextAsync(TestContext, file, bicepFile.FileUri, resourceTypeProvider : TypeProvider);

            var completionLists = await RequestCompletions(client, bicepFile, cursors);

            completionLists.Count().Should().Be(1);

            var snippetCompletion = completionLists.First() !.Items.Where(x => x.Kind == CompletionItemKind.Snippet && x.Label == "res-automation-cred");

            snippetCompletion.Should().SatisfyRespectively(
                c =>
            {
                c.Label.Should().Be("res-automation-cred");
                c.Detail.Should().Be("Automation Credential");
                c.InsertTextFormat.Should().Be(InsertTextFormat.Snippet);
                c.TextEdit?.TextEdit?.NewText?.Should().BeEquivalentToIgnoringNewlines(@"resource ${2:automationCredential} 'credentials@2019-06-01' = {
  name: ${3:'name'}
  properties: {
    userName: ${4:'userName'}
    password: ${5:'password'}
    description: ${6:'description'}
  }
}");
            });
        }
Exemplo n.º 4
0
        private async Task <string> RequestSnippetCompletion(string bicepFileName, CompletionData completionData, string placeholderFile, int cursor)
        {
            var documentUri = DocumentUri.FromFileSystemPath(bicepFileName);
            var bicepFile   = SourceFileFactory.CreateBicepFile(documentUri.ToUri(), placeholderFile);

            var client = await IntegrationTestHelper.StartServerWithTextAsync(
                this.TestContext,
                placeholderFile,
                documentUri,
                null,
                TypeProvider);

            var completions = await client.RequestCompletion(new CompletionParams
            {
                TextDocument = documentUri,
                Position     = TextCoordinateConverter.GetPosition(bicepFile.LineStarts, cursor),
            });

            var matchingSnippets = completions.Where(x => x.Kind == CompletionItemKind.Snippet && x.Label == completionData.Prefix);

            matchingSnippets.Should().HaveCount(1);
            var completion = matchingSnippets.First();

            completion.TextEdit.Should().NotBeNull();
            completion.TextEdit !.TextEdit !.Range.Should().Be(new TextSpan(cursor, 0).ToRange(bicepFile.LineStarts));
            completion.TextEdit.TextEdit.NewText.Should().NotBeNullOrWhiteSpace();

            return(completion.TextEdit.TextEdit.NewText);
        }
Exemplo n.º 5
0
 public void UpsertCompilation(DocumentUri documentUri, int?version, string fileContents, string?languageId = null)
 {
     if (this.ShouldUpsertCompilation(documentUri, languageId))
     {
         var newFile = SourceFileFactory.CreateSourceFile(documentUri.ToUri(), fileContents);
         UpsertCompilationInternal(documentUri, version, newFile);
     }
 }
Exemplo n.º 6
0
        public static SourceFileGrouping CreateForFiles(IReadOnlyDictionary <Uri, string> fileContentsByUri, Uri entryFileUri, IFileResolver fileResolver)
        {
            var workspace   = new Workspace();
            var sourceFiles = fileContentsByUri.Select(kvp => SourceFileFactory.CreateSourceFile(kvp.Key, kvp.Value));

            workspace.UpsertSourceFiles(sourceFiles);

            return(SourceFileGroupingBuilder.Build(fileResolver, new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver)), workspace, entryFileUri));
        }
Exemplo n.º 7
0
        private static async Task RunDefinitionScenarioTest(TestContext testContext, string fileWithCursors, Action <List <LocationOrLocationLinks> > assertAction)
        {
            var(file, cursors) = ParserHelper.GetFileWithCursors(fileWithCursors);
            var bicepFile = SourceFileFactory.CreateBicepFile(new Uri("file:///path/to/main.bicep"), file);

            var client = await IntegrationTestHelper.StartServerWithTextAsync(testContext, file, bicepFile.FileUri, creationOptions : new LanguageServer.Server.CreationOptions(NamespaceProvider: BuiltInTestTypes.Create()));

            var results = await RequestDefinitions(client, bicepFile, cursors);

            assertAction(results);
        }
Exemplo n.º 8
0
        public static (BicepFile bicepFile, bool hasChanges) Rewrite(Compilation prevCompilation, BicepFile bicepFile, Func <SemanticModel, SyntaxRewriteVisitor> rewriteVisitorBuilder)
        {
            var semanticModel    = new SemanticModel(prevCompilation, bicepFile, prevCompilation.SourceFileGrouping.FileResolver, prevCompilation.Configuration);
            var newProgramSyntax = rewriteVisitorBuilder(semanticModel).Rewrite(bicepFile.ProgramSyntax);

            if (object.ReferenceEquals(bicepFile.ProgramSyntax, newProgramSyntax))
            {
                return(bicepFile, false);
            }

            bicepFile = SourceFileFactory.CreateBicepFile(bicepFile.FileUri, newProgramSyntax.ToTextPreserveFormatting());
            return(bicepFile, true);
        }
Exemplo n.º 9
0
        private static Compilation GetCompilation(string fileContents)
        {
            var fileUri    = new Uri("inmemory:///main.bicep");
            var workspace  = new Workspace();
            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri, fileContents);

            workspace.UpsertSourceFile(sourceFile);

            var fileResolver       = new FileResolver();
            var dispatcher         = new ModuleDispatcher(new EmptyModuleRegistryProvider());
            var sourceFileGrouping = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, fileUri);

            return(new Compilation(resourceTypeProvider, sourceFileGrouping));
        }
Exemplo n.º 10
0
        public async Task VerifyNestedResourceBodyCompletionReturnsSnippets()
        {
            string fileWithCursors = @"resource automationAccount 'Microsoft.Automation/automationAccounts@2019-06-01' = {
  name: 'name'
  location: resourceGroup().location

  resource automationCredential 'credentials@2019-06-01' = |
}";

            var(file, cursors) = ParserHelper.GetFileWithCursors(fileWithCursors);
            var bicepFile = SourceFileFactory.CreateBicepFile(new Uri("file:///path/to/main.bicep"), file);
            var client    = await IntegrationTestHelper.StartServerWithTextAsync(TestContext, file, bicepFile.FileUri, resourceTypeProvider : TypeProvider);

            var completionLists = await RequestCompletions(client, bicepFile, cursors);

            completionLists.Count().Should().Be(1);

            var snippetCompletions = completionLists.First() !.Items.Where(x => x.Kind == CompletionItemKind.Snippet);

            snippetCompletions.Should().SatisfyRespectively(
                c =>
            {
                c.Label.Should().Be("{}");
            },
                c =>
            {
                c.Label.Should().Be("snippet");
            },
                c =>
            {
                c.Label.Should().Be("required-properties");
            },
                c =>
            {
                c.Label.Should().Be("if");
            },
                c =>
            {
                c.Label.Should().Be("for");
            },
                c =>
            {
                c.Label.Should().Be("for-indexed");
            },
                c =>
            {
                c.Label.Should().Be("for-filtered");
            });
        }
Exemplo n.º 11
0
        private static Compilation GetCompilation(string fileContents)
        {
            var fileUri    = new Uri("inmemory:///main.bicep");
            var workspace  = new Workspace();
            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri, fileContents);

            workspace.UpsertSourceFile(sourceFile);

            var fileResolver         = new FileResolver();
            var dispatcher           = new ModuleDispatcher(new EmptyModuleRegistryProvider());
            var configurationManager = new ConfigurationManager(new IOFileSystem());
            var configuration        = configurationManager.GetBuiltInConfiguration();
            var sourceFileGrouping   = SourceFileGroupingBuilder.Build(fileResolver, dispatcher, workspace, fileUri, configuration);

            return(new Compilation(namespaceProvider, sourceFileGrouping, configuration));
        }
Exemplo n.º 12
0
        public (Uri, ImmutableDictionary <Uri, string>) Decompile(string inputPath, string outputPath)
        {
            inputPath = PathHelper.ResolvePath(inputPath);
            Uri inputUri = PathHelper.FilePathToFileUrl(inputPath);

            Uri outputUri = PathHelper.FilePathToFileUrl(outputPath);

            var decompilation = TemplateDecompiler.DecompileFileWithModules(invocationContext.ResourceTypeProvider, new FileResolver(), inputUri, outputUri);

            foreach (var(fileUri, bicepOutput) in decompilation.filesToSave)
            {
                workspace.UpsertSourceFile(SourceFileFactory.CreateBicepFile(fileUri, bicepOutput));
            }

            _ = Compile(decompilation.entrypointUri.AbsolutePath); // to verify success we recompile and check for syntax errors.

            return(decompilation);
        }
Exemplo n.º 13
0
        public async Task VerifyResourceBodyCompletionWithoutExistingKeywordIncludesCustomSnippet()
        {
            string text = @"resource aksCluster 'Microsoft.ContainerService/managedClusters@2021-03-01' = ";

            var bicepFile = SourceFileFactory.CreateBicepFile(new Uri("file:///main.bicep"), text);

            using var client = await IntegrationTestHelper.StartServerWithTextAsync(this.TestContext, text, bicepFile.FileUri, resourceTypeProvider : TypeProvider);

            var completions = await client.RequestCompletion(new CompletionParams
            {
                TextDocument = new TextDocumentIdentifier(bicepFile.FileUri),
                Position     = TextCoordinateConverter.GetPosition(bicepFile.LineStarts, text.Length),
            });

            completions.Should().SatisfyRespectively(
                c =>
            {
                c.Label.Should().Be("{}");
            },
                c =>
            {
                c.Label.Should().Be("snippet");
            },
                c =>
            {
                c.Label.Should().Be("required-properties");
            },
                c =>
            {
                c.Label.Should().Be("if");
            },
                c =>
            {
                c.Label.Should().Be("for");
            },
                c =>
            {
                c.Label.Should().Be("for-indexed");
            },
                c =>
            {
                c.Label.Should().Be("for-filtered");
            });
        }
Exemplo n.º 14
0
        public async Task <(Uri, ImmutableDictionary <Uri, string>)> DecompileAsync(string inputPath, string outputPath)
        {
            inputPath = PathHelper.ResolvePath(inputPath);
            Uri inputUri = PathHelper.FilePathToFileUrl(inputPath);

            Uri outputUri = PathHelper.FilePathToFileUrl(outputPath);

            var decompilation = decompiler.DecompileFileWithModules(inputUri, outputUri);

            foreach (var(fileUri, bicepOutput) in decompilation.filesToSave)
            {
                workspace.UpsertSourceFile(SourceFileFactory.CreateBicepFile(fileUri, bicepOutput));
            }

            // to verify success we recompile and check for syntax errors.
            await CompileAsync(decompilation.entrypointUri.AbsolutePath, skipRestore : true);

            return(decompilation);
        }
        public static SourceFileGrouping CreateForFiles(IReadOnlyDictionary <Uri, string> fileContentsByUri, Uri entryFileUri, IFileResolver fileResolver, RootConfiguration configuration, IFeatureProvider?features = null)
        {
            features ??= BicepTestConstants.Features;
            var workspace   = new Workspace();
            var sourceFiles = fileContentsByUri.Select(kvp => SourceFileFactory.CreateSourceFile(kvp.Key, kvp.Value));

            workspace.UpsertSourceFiles(sourceFiles);

            return(SourceFileGroupingBuilder.Build(
                       fileResolver,
                       new ModuleDispatcher(
                           new DefaultModuleRegistryProvider(
                               fileResolver,
                               BicepTestConstants.ClientFactory,
                               BicepTestConstants.TemplateSpecRepositoryFactory,
                               features)),
                       workspace,
                       entryFileUri,
                       configuration));
        }
Exemplo n.º 16
0
        public void Create_ShouldReturnValidCompilation()
        {
            var fileUri      = DocumentUri.Parse($"/{DataSets.Parameters_LF.Name}.bicep");
            var fileResolver = CreateFileResolver(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver));

            var provider = new BicepCompilationProvider(TestTypeHelper.CreateEmptyProvider(), fileResolver, dispatcher);

            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var workspace  = new Workspace();

            workspace.UpsertSourceFile(sourceFile);
            var context = provider.Create(workspace, fileUri, ImmutableDictionary <ISourceFile, ISemanticModel> .Empty);

            context.Compilation.Should().NotBeNull();
            // TODO: remove Where when the support of modifiers is dropped.
            context.Compilation.GetEntrypointSemanticModel().GetAllDiagnostics(new ConfigHelper().GetDisabledLinterConfig()).Should().BeEmpty();
            context.LineStarts.Should().NotBeEmpty();
            context.LineStarts[0].Should().Be(0);
        }
Exemplo n.º 17
0
        public void Create_ShouldReturnValidCompilation()
        {
            var fileUri      = DocumentUri.Parse($"/{DataSets.Parameters_LF.Name}.bicep");
            var fileResolver = CreateFileResolver(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var dispatcher   = new ModuleDispatcher(new DefaultModuleRegistryProvider(fileResolver, BicepTestConstants.ClientFactory, BicepTestConstants.TemplateSpecRepositoryFactory, BicepTestConstants.Features));

            var provider = new BicepCompilationProvider(BicepTestConstants.Features, TestTypeHelper.CreateWithAzTypes(), fileResolver, dispatcher);

            var sourceFile = SourceFileFactory.CreateSourceFile(fileUri.ToUri(), DataSets.Parameters_LF.Bicep);
            var workspace  = new Workspace();

            workspace.UpsertSourceFile(sourceFile);
            var configuration = BicepTestConstants.BuiltInConfigurationWithAnalyzersDisabled;
            var context       = provider.Create(workspace, fileUri, ImmutableDictionary <ISourceFile, ISemanticModel> .Empty, configuration, new LinterAnalyzer(configuration));

            context.Compilation.Should().NotBeNull();
            // TODO: remove Where when the support of modifiers is dropped.
            context.Compilation.GetEntrypointSemanticModel().GetAllDiagnostics().Should().BeEmpty();
            context.LineStarts.Should().NotBeEmpty();
            context.LineStarts[0].Should().Be(0);
        }
Exemplo n.º 18
0
        public Interpreter(bool is_interactive, DebuggerConfiguration config,
                           DebuggerOptions options)
        {
            this.config         = config;
            this.is_interactive = is_interactive;
            this.is_script      = options.IsScript;
            this.parser         = new ExpressionParser(this);
            this.session        = new DebuggerSession(config, options, "main", parser);
            this.engine         = new DebuggerEngine(this);

            parser.Session = session;

            source_factory = new SourceFileFactory();

            interrupt_event = new ManualResetEvent(false);
            process_event   = new ManualResetEvent(false);

            styles = new Hashtable();
            styles.Add("cli", new StyleCLI(this));
            styles.Add("emacs", new StyleEmacs(this));
            current_style = (StyleBase)styles ["cli"];
        }
Exemplo n.º 19
0
        public void UpsertCompilation(DocumentUri documentUri, int?version, string fileContents, string?languageId = null)
        {
            if (this.ShouldUpsertCompilation(documentUri, languageId))
            {
                var newFile      = SourceFileFactory.CreateSourceFile(documentUri.ToUri(), fileContents);
                var firstChanges = workspace.UpsertSourceFile(newFile);
                var removedFiles = firstChanges.removed;

                var modelLookup = new Dictionary <ISourceFile, ISemanticModel>();
                if (newFile is BicepFile)
                {
                    // Do not update compilation if it is an ARM template file, since it cannot be an entrypoint.
                    UpdateCompilationInternal(documentUri, version, modelLookup, removedFiles);
                }

                foreach (var(entrypointUri, context) in activeContexts)
                {
                    if (removedFiles.Any(x => context.Compilation.SourceFileGrouping.SourceFiles.Contains(x)))
                    {
                        UpdateCompilationInternal(entrypointUri, null, modelLookup, removedFiles);
                    }
                }
            }
        }
Exemplo n.º 20
0
        private static ModuleDeclarationSyntax CreateModule(string reference)
        {
            var file = SourceFileFactory.CreateBicepFile(new System.Uri("untitled://hello"), $"module foo '{reference}' = {{}}");

            return(file.ProgramSyntax.Declarations.OfType <ModuleDeclarationSyntax>().Single());
        }
Exemplo n.º 21
0
        public async Task VerifyResourceBodyCompletionWithDiscriminatedObjectTypeContainsRequiredPropertiesSnippet()
        {
            string text      = @"resource deploymentScripts 'Microsoft.Resources/deploymentScripts@2020-10-01'=";
            var    bicepFile = SourceFileFactory.CreateBicepFile(new Uri("file:///main.bicep"), text);

            using var client = await IntegrationTestHelper.StartServerWithTextAsync(this.TestContext, text, bicepFile.FileUri, resourceTypeProvider : TypeProvider);

            var completions = await client.RequestCompletion(new CompletionParams
            {
                TextDocument = new TextDocumentIdentifier(bicepFile.FileUri),
                Position     = TextCoordinateConverter.GetPosition(bicepFile.LineStarts, text.Length),
            });

            completions.Should().SatisfyRespectively(
                c =>
            {
                c.Label.Should().Be("{}");
            },
                c =>
            {
                c.InsertTextFormat.Should().Be(InsertTextFormat.Snippet);
                c.Label.Should().Be("required-properties-AzureCLI");
                c.Detail.Should().Be("Required properties");
                c.TextEdit?.TextEdit?.NewText?.Should().BeEquivalentToIgnoringNewlines(@"{
	name: $1
	location: $2
	kind: 'AzureCLI'
	properties: {
		azCliVersion: $3
		retentionInterval: $4
	}
}$0");
            },
                c =>
            {
                c.Label.Should().Be("required-properties-AzurePowerShell");
                c.Detail.Should().Be("Required properties");
                c.TextEdit?.TextEdit?.NewText?.Should().BeEquivalentToIgnoringNewlines(@"{
	name: $1
	location: $2
	kind: 'AzurePowerShell'
	properties: {
		azPowerShellVersion: $3
		retentionInterval: $4
	}
}$0");
            },
                c =>
            {
                c.Label.Should().Be("if");
            },
                c =>
            {
                c.Label.Should().Be("for");
            },
                c =>
            {
                c.Label.Should().Be("for-indexed");
            },
                c =>
            {
                c.Label.Should().Be("for-filtered");
            });
        }
Exemplo n.º 22
0
 public LicenseTask()
 {
     _licenseFactory    = new LicenseFactory(new FileReader());
     _sourceFileFactory = new SourceFileFactory(new FileReader(), new FileWriter(), _licenseFactory);
 }
Exemplo n.º 23
0
        public (Uri entrypointUri, ImmutableDictionary <Uri, string> filesToSave) DecompileFileWithModules(Uri entryJsonUri, Uri entryBicepUri)
        {
            var workspace      = new Workspace();
            var decompileQueue = new Queue <(Uri, Uri)>();

            decompileQueue.Enqueue((entryJsonUri, entryBicepUri));

            while (decompileQueue.Count > 0)
            {
                var(jsonUri, bicepUri) = decompileQueue.Dequeue();

                if (PathHelper.HasBicepExtension(jsonUri))
                {
                    throw new InvalidOperationException($"Cannot decompile the file with .bicep extension: {jsonUri}.");
                }

                if (workspace.TryGetSourceFile(bicepUri, out _))
                {
                    continue;
                }

                if (!fileResolver.TryRead(jsonUri, out var jsonInput, out _))
                {
                    throw new InvalidOperationException($"Failed to read {jsonUri}");
                }

                var(program, jsonTemplateUrisByModule) = TemplateConverter.DecompileTemplate(workspace, fileResolver, bicepUri, jsonInput);
                var bicepFile = SourceFileFactory.CreateBicepFile(bicepUri, program.ToText());
                workspace.UpsertSourceFile(bicepFile);

                foreach (var module in program.Children.OfType <ModuleDeclarationSyntax>())
                {
                    var moduleRelativePath = SyntaxHelper.TryGetModulePath(module, out _);
                    if (moduleRelativePath == null ||
                        !LocalModuleReference.Validate(moduleRelativePath, out _) ||
                        !Uri.TryCreate(bicepUri, moduleRelativePath, out var moduleUri))
                    {
                        // Do our best, but keep going if we fail to resolve a module file
                        continue;
                    }

                    if (!workspace.TryGetSourceFile(moduleUri, out _) && jsonTemplateUrisByModule.TryGetValue(module, out var linkedTemplateUri))
                    {
                        decompileQueue.Enqueue((linkedTemplateUri, moduleUri));
                    }
                }
            }

            RewriteSyntax(workspace, entryBicepUri, semanticModel => new ParentChildResourceNameRewriter(semanticModel));
            RewriteSyntax(workspace, entryBicepUri, semanticModel => new DependsOnRemovalRewriter(semanticModel));
            RewriteSyntax(workspace, entryBicepUri, semanticModel => new ForExpressionSimplifierRewriter(semanticModel));
            for (var i = 0; i < 5; i++)
            {
                // This is a little weird. If there are casing issues nested inside casing issues (e.g. in an object), then the inner casing issue will have no type information
                // available, as the compilation will not have associated a type with it (since there was no match on the outer object). So we need to correct the outer issue first,
                // and then move to the inner one. We need to recompute the entire compilation to do this. It feels simpler to just do this in passes over the file, rather than on demand.
                if (!RewriteSyntax(workspace, entryBicepUri, semanticModel => new TypeCasingFixerRewriter(semanticModel)))
                {
                    break;
                }
            }

            return(entryBicepUri, PrintFiles(workspace));
        }