コード例 #1
0
        public async Task LocalModuleReferenceShouldThrow()
        {
            var dispatcher = StrictMock.Of <IModuleDispatcher>();

            DiagnosticBuilder.ErrorBuilderDelegate?failureBuilder = null;

            const string ModuleRefStr = "./hello.bicep";
            var          localRef     = LocalModuleReference.TryParse(ModuleRefStr, out _);

            localRef.Should().NotBeNull();

            dispatcher.Setup(m => m.TryGetModuleReference(ModuleRefStr, It.IsAny <RootConfiguration>(), out failureBuilder)).Returns(localRef);

            var resolver = StrictMock.Of <IFileResolver>();

            var handler = new BicepRegistryCacheRequestHandler(dispatcher.Object, resolver.Object, ConfigurationManager);

            var @params = new BicepRegistryCacheParams("/foo/bar/main.bicep", ModuleRefStr);

            (await FluentActions
             .Awaiting(() => handler.Handle(@params, default))
             .Should()
             .ThrowAsync <InvalidOperationException>())
            .WithMessage($"The specified module reference '{ModuleRefStr}' refers to a local module which is not supported by textDocument/bicepCache requests.");
        }
コード例 #2
0
        private static LocalModuleReference Parse(string package)
        {
            var parsed = LocalModuleReference.TryParse(package, out var failureBuilder);

            parsed.Should().NotBeNull();
            failureBuilder.Should().BeNull();
            return(parsed !);
        }
コード例 #3
0
        private static Uri?GetFileUriWithDiagnostics(IBinder binder, IFileResolver fileResolver, IDiagnosticWriter diagnostics, string filePath, SyntaxBase filePathArgument)
        {
            if (!LocalModuleReference.Validate(filePath, out var validateFilePathFailureBuilder))
            {
                diagnostics.Write(validateFilePathFailureBuilder.Invoke(DiagnosticBuilder.ForPosition(filePathArgument)));
                return(null);
            }

            var fileUri = fileResolver.TryResolveFilePath(binder.FileSymbol.FileUri, filePath);

            if (fileUri is null)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(filePathArgument).FilePathCouldNotBeResolved(filePath, binder.FileSymbol.FileUri.LocalPath));
                return(null);
            }

            if (!fileUri.IsFile)
            {
                diagnostics.Write(DiagnosticBuilder.ForPosition(filePathArgument).UnableToLoadNonFileUri(fileUri));
                return(null);
            }
            return(fileUri);
        }
コード例 #4
0
 public ModuleReference?TryParseModuleReference(string reference, out DiagnosticBuilder.ErrorBuilderDelegate?failureBuilder) => LocalModuleReference.TryParse(reference, out failureBuilder);
コード例 #5
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));
        }