private static Symbol SymbolFromRoslynSymbol(int offset, Microsoft.CodeAnalysis.SemanticModel semanticModel, Microsoft.CodeAnalysis.ISymbol symbol)
        {
            var result = new Symbol();

            if (symbol is Microsoft.CodeAnalysis.IMethodSymbol methodSymbol)
            {
                result.IsVariadic = methodSymbol.Parameters.LastOrDefault()?.IsParams ?? false;
                result.Kind       = CursorKind.CXXMethod;

                result.Arguments = new List <ParameterSymbol>();

                foreach (var parameter in methodSymbol.Parameters)
                {
                    var argument = new ParameterSymbol();
                    argument.Name = parameter.Name;

                    var info = CheckForStaticExtension.GetReturnType(parameter);

                    if (info.HasValue)
                    {
                        argument.TypeDescription = info.Value.name;
                        argument.IsBuiltInType   = info.Value.inbuilt;
                    }

                    result.Arguments.Add(argument);
                }
            }

            result.Name = symbol.Name;

            var returnTypeInfo = CheckForStaticExtension.GetReturnType(symbol);

            if (returnTypeInfo.HasValue)
            {
                result.ResultType    = returnTypeInfo.Value.name;
                result.IsBuiltInType = returnTypeInfo.Value.inbuilt;
            }

            result.TypeDescription = symbol.Kind == Microsoft.CodeAnalysis.SymbolKind.NamedType ? symbol.ToDisplayString() : symbol.ToMinimalDisplayString(semanticModel, offset);
            var xmlDocumentation = symbol.GetDocumentationCommentXml();

            var docComment = DocumentationComment.From(xmlDocumentation, Environment.NewLine);

            result.BriefComment = docComment.SummaryText;

            return(result);
        }
        public async Task <CodeCompletionResults> CodeCompleteAtAsync(int index, int line, int column, IEnumerable <UnsavedFile> unsavedFiles, char previousChar, string filter)
        {
            if (_editor.SourceFile is MetaDataFile)
            {
                return(null);
            }

            var result = new CodeCompletionResults();

            var dataAssociation = GetAssociatedData(_editor);

            var workspace     = RoslynWorkspace.GetWorkspace(dataAssociation.Solution);
            var document      = workspace.GetDocument(_editor.SourceFile);
            var semanticModel = await document.GetSemanticModelAsync();

            var completionService = CompletionService.GetService(document);
            var data = await completionService.GetCompletionsAsync(document, index);

            if (data != null)
            {
                var recommendedSymbols = await Microsoft.CodeAnalysis.Recommendations.Recommender.GetRecommendedSymbolsAtPositionAsync(semanticModel, index, workspace);

                foreach (var completion in data.Items)
                {
                    var insertionText = completion.DisplayText;

                    if (completion.Properties.ContainsKey("InsertionText"))
                    {
                        insertionText = completion.Properties["InsertionText"];
                    }

                    var selectionBehavior = Languages.CompletionItemSelectionBehavior.Default;
                    int priority          = 0;

                    if (completion.Rules.SelectionBehavior != Microsoft.CodeAnalysis.Completion.CompletionItemSelectionBehavior.Default)
                    {
                        selectionBehavior = (Languages.CompletionItemSelectionBehavior)completion.Rules.SelectionBehavior;
                        priority          = completion.Rules.MatchPriority;
                    }

                    if (completion.Properties.ContainsKey("Provider") && completion.Properties["Provider"] == "Microsoft.CodeAnalysis.CSharp.Completion.Providers.SymbolCompletionProvider")
                    {
                        var symbols = recommendedSymbols.Where(x => x.Name == completion.Properties["SymbolName"] && (int)x.Kind == int.Parse(completion.Properties["SymbolKind"])).Distinct();

                        if (symbols != null && symbols.Any())
                        {
                            foreach (var symbol in symbols)
                            {
                                if (symbol != null)
                                {
                                    var newCompletion = new CodeCompletionData(symbol.Name, completion.FilterText, insertionText, null, selectionBehavior, priority);

                                    if (completion.Properties.ContainsKey("SymbolKind"))
                                    {
                                        newCompletion.Kind = FromOmniSharpKind(completion.Properties["SymbolKind"]);
                                    }

                                    var xmlDocumentation = symbol.GetDocumentationCommentXml();

                                    if (xmlDocumentation != string.Empty)
                                    {
                                        var docComment = DocumentationComment.From(xmlDocumentation, Environment.NewLine);
                                        newCompletion.BriefComment = docComment.SummaryText;
                                    }

                                    result.Completions.Add(newCompletion);
                                }
                            }
                        }
                    }
                    else
                    {
                        var newCompletion = new CodeCompletionData(completion.DisplayText, completion.FilterText, insertionText, null, selectionBehavior, priority);

                        if (completion.Properties.ContainsKey("SymbolKind"))
                        {
                            newCompletion.Kind = FromOmniSharpKind(completion.Properties["SymbolKind"]);
                        }

                        result.Completions.Add(newCompletion);
                    }
                }

                result.Contexts = Languages.CompletionContext.AnyType;
            }

            return(result);
        }