예제 #1
0
        private Uri?TryGetNormalizedModulePath(Uri parentFileUri, ModuleDeclarationSyntax moduleDeclarationSyntax, out DiagnosticBuilder.ErrorBuilderDelegate?failureBuilder)
        {
            var pathName = SyntaxHelper.TryGetModulePath(moduleDeclarationSyntax, out var getModulePathFailureBuilder);

            if (pathName == null)
            {
                failureBuilder = getModulePathFailureBuilder;
                return(null);
            }

            if (!ValidateModulePath(pathName, out var validateModulePathFailureBuilder))
            {
                failureBuilder = validateModulePathFailureBuilder;
                return(null);
            }

            var moduleUri = fileResolver.TryResolveModulePath(parentFileUri, pathName);

            if (moduleUri == null)
            {
                failureBuilder = x => x.ModulePathCouldNotBeResolved(pathName, parentFileUri.LocalPath);
                return(null);
            }

            failureBuilder = null;
            return(moduleUri);
        }
예제 #2
0
        private string?TryGetNormalizedModulePath(string parentFileName, ModuleDeclarationSyntax moduleDeclarationSyntax, out DiagnosticBuilder.ErrorBuilderDelegate?failureBuilder)
        {
            var pathName = SyntaxHelper.TryGetModulePath(moduleDeclarationSyntax, out var getModulePathFailureBuilder);

            if (pathName == null)
            {
                failureBuilder = getModulePathFailureBuilder;
                return(null);
            }

            if (pathName.Contains('\\'))
            {
                // enforce '/' rather than '\' for module paths for cross-platform compatibility
                failureBuilder = x => x.ModulePathBackslashUnsupported();
                return(null);
            }

            var fullPath = fileResolver.TryResolveModulePath(parentFileName, pathName);

            if (fullPath == null)
            {
                failureBuilder = x => x.ModulePathCouldNotBeResolved(pathName, parentFileName);
                return(null);
            }

            failureBuilder = null;
            return(fullPath);
        }
예제 #3
0
        private IEnumerable <CompletionItem> GetModulePathCompletions(SemanticModel model, BicepCompletionContext context)
        {
            if (!context.Kind.HasFlag(BicepCompletionContextKind.ModulePath))
            {
                return(Enumerable.Empty <CompletionItem>());
            }

            // To provide intellisense before the quotes are typed
            if (context.EnclosingDeclaration is not ModuleDeclarationSyntax declarationSyntax ||
                declarationSyntax.Path is not StringSyntax stringSyntax ||
                stringSyntax.TryGetLiteralValue() is not string entered)
            {
                entered = "";
            }

            // These should only fail if we're not able to resolve cwd path or the entered string
            if (FileResolver.TryResolveModulePath(model.SyntaxTree.FileUri, ".") is not {
            } cwdUri ||
                FileResolver.TryResolveModulePath(cwdUri, entered) is not {
            } query)
            {
                return(Enumerable.Empty <CompletionItem>());
            }

            var files = Enumerable.Empty <Uri>();
            var dirs  = Enumerable.Empty <Uri>();


            // technically bicep files do not have to follow the bicep extension, so
            // we are not enforcing *.bicep get files command
            if (FileResolver.TryDirExists(query))
            {
                files = FileResolver.GetFiles(query, string.Empty);
                dirs  = FileResolver.GetDirectories(query, string.Empty);
            }
            else if (FileResolver.TryResolveModulePath(query, ".") is {} queryParent)
            {
                files = FileResolver.GetFiles(queryParent, "");
                dirs  = FileResolver.GetDirectories(queryParent, "");
            }
            // "./" will not be preserved when making relative Uris. We have to go and manually add it.
            // Prioritize .bicep files higher than other files.
            var fileItems = files
                            .Where(file => file != model.SyntaxTree.FileUri)
                            .Where(file => file.Segments.Last().EndsWith(LanguageServerConstants.LanguageFileExtension))
                            .Select(file => CreateModulePathCompletion(
                                        file.Segments.Last(),
                                        (entered.StartsWith("./") ? "./" : "") + cwdUri.MakeRelativeUri(file).ToString(),
                                        context.ReplacementRange,
                                        CompletionItemKind.File,
                                        file.Segments.Last().EndsWith(LanguageServerConstants.LanguageId) ? CompletionPriority.High : CompletionPriority.Medium))
                            .ToList();

            var dirItems = dirs
                           .Select(dir => CreateModulePathCompletion(
                                       dir.Segments.Last(),
                                       (entered.StartsWith("./") ? "./" : "") + cwdUri.MakeRelativeUri(dir).ToString(),
                                       context.ReplacementRange,
                                       CompletionItemKind.Folder,
                                       CompletionPriority.Medium)
                                   .WithCommand(new Command {
                Name = EditorCommands.RequestCompletions
            }))
                           .ToList();

            return(fileItems.Concat(dirItems));
        }