示例#1
0
        //FIXME: can we display some kind of "loading" message while it loads?
        async Task <QuickInfoItem> CreateNuGetQuickInfo(ITextSnapshot snapshot, MSBuildRootDocument doc, MSBuildResolveResult rr, CancellationToken token)
        {
            IPackageInfo info      = null;
            var          packageId = (string)rr.Reference;

            try {
                var frameworkId = doc.GetTargetFrameworkNuGetSearchParameter();

                //FIXME: can we use the correct version here?
                var infos = await provider.PackageSearchManager.SearchPackageInfo(packageId, null, frameworkId).ToTask(token);

                //prefer non-local results as they will have more metadata
                info = infos
                       .FirstOrDefault(p => p.SourceKind != ProjectFileTools.NuGetSearch.Feeds.FeedKind.Local)
                       ?? infos.FirstOrDefault();
            }
            catch (Exception ex) when(!(ex is OperationCanceledException && token.IsCancellationRequested))
            {
                LoggingService.LogError("Error loading package description", ex);
            }

            var span = snapshot.CreateTrackingSpan(rr.ReferenceOffset, rr.ReferenceLength, SpanTrackingMode.EdgeInclusive);

            return(new QuickInfoItem(span, provider.DisplayElementFactory.GetPackageInfoTooltip(packageId, info, FeedKind.NuGet)));
        }
示例#2
0
 static IEnumerable <NavigationSegment> CreateNavigationSegments(MSBuildRootDocument doc, List <MSBuildNavigationResult> results)
 {
     foreach (var result in results)
     {
         yield return(new NavigationSegment(result.Offset, result.Length, () => Navigate(result, doc)));
     }
 }
        protected override Task <MSBuildParseResult> StartParseAsync(
            ITextSnapshot2 snapshot, MSBuildParseResult previousParse,
            ITextSnapshot2 previousSnapshot, CancellationToken token)
        {
            if (runtimeInformation == null)
            {
                EnsureInitialized();
            }

            return(Task.Run(() => {
                var oldDoc = previousParse?.MSBuildDocument;

                var filepath = TryGetFilePath();

                MSBuildRootDocument doc = MSBuildRootDocument.Empty;
                try {
                    doc = MSBuildRootDocument.Parse(snapshot.GetTextSource(filepath), oldDoc, schemaProvider, runtimeInformation, taskMetadataBuilder, token);
                } catch (Exception ex) {
                    LoggingService.LogError("Unhandled error in MSBuild parser", ex);
                    doc = MSBuildRootDocument.Empty;
                }

                return new MSBuildParseResult(doc, doc.XDocument, doc.Errors);
            }));
        }
        public static IReadOnlyList <BaseInfo> GetFilenameCompletions(
            MSBuildValueKind kind, MSBuildRootDocument doc,
            ExpressionNode triggerExpression, int triggerLength)
        {
            bool includeFiles = false;

            switch (kind)
            {
            case MSBuildValueKind.File:
            case MSBuildValueKind.ProjectFile:
                includeFiles = true;
                break;

            case MSBuildValueKind.FileOrFolder:
                includeFiles = true;
                break;

            case MSBuildValueKind.Folder:
            case MSBuildValueKind.FolderWithSlash:
                break;

            default:
                return(null);
            }

            var basePaths = EvaluateExpressionAsPaths(triggerExpression, doc, triggerLength + 1).ToList();

            return(basePaths.Count == 0 ? null : GetPathCompletions(doc.Filename, basePaths, includeFiles));
        }
示例#5
0
        async Task <List <CompletionItem> > GetPackageVersionCompletions(MSBuildRootDocument doc, MSBuildResolveResult rr, CancellationToken token)
        {
            if (rr == null)
            {
                return(null);
            }

            var packageId = rr.Element.Attributes.FirstOrDefault(a => a.Name.Name == "Include")?.Value;

            if (string.IsNullOrEmpty(packageId))
            {
                return(null);
            }

            var tfm = doc.GetTargetFrameworkNuGetSearchParameter();

            var results = await provider.PackageSearchManager.SearchPackageVersions(packageId.ToLower(), tfm).ToTask(token);

            //FIXME should we deduplicate?
            var items = new List <CompletionItem> ();

            foreach (var result in results)
            {
                items.Add(CreateNuGetCompletionItem(result, XmlCompletionItemKind.AttributeValue));
            }

            return(items);
        }
示例#6
0
        async Task <CompletionContext> GetPackageVersionCompletions(MSBuildRootDocument doc, MSBuildResolveResult rr)
        {
            var packageId = rr.XElement.Attributes.FirstOrDefault(a => a.Name.Name == "Include")?.Value;

            if (string.IsNullOrEmpty(packageId))
            {
                return(null);
            }

            var tfm    = doc.GetTargetFrameworkNuGetSearchParameter();
            var search = provider.PackageSearchManager.SearchPackageVersions(packageId.ToLower(), tfm);
            var tcs    = new TaskCompletionSource <object> ();

            search.Updated += (s, e) => { if (search.RemainingFeeds.Count == 0)
                                          {
                                              tcs.TrySetResult(null);
                                          }
            };
            await tcs.Task;

            //FIXME should we deduplicate?
            var items = new List <CompletionItem> ();

            foreach (var result in search.Results)
            {
                items.Add(CreateNuGetVersionCompletionItem(result.Item1, result.Item2));
            }

            return(CreateCompletionContext(items));
        }
示例#7
0
        static void AssertImportsExist(MSBuildRootDocument rootDoc, params string[] filenames)
        {
            var collected = new Dictionary <string, Import> (StringComparer.OrdinalIgnoreCase);

            foreach (var f in filenames)
            {
                collected.Add(f, null);
            }

            foreach (var import in GetAllImports(rootDoc))
            {
                if (import.IsResolved)
                {
                    var name = Path.GetFileName(import.Filename);
                    if (collected.ContainsKey(name))
                    {
                        collected[name] = import;
                    }
                }
            }

            foreach (var kvp in collected)
            {
                Assert.NotNull(kvp.Value, "Missing import {0}", kvp.Key);
            }
        }
        public static IReadOnlyList <BaseInfo> GetValueCompletions(
            MSBuildValueKind kind,
            MSBuildRootDocument doc,
            MSBuildResolveResult rr          = null,
            ExpressionNode triggerExpression = null)
        {
            var simple = kind.GetSimpleValues(true);

            if (simple != null)
            {
                return(simple);
            }

            switch (kind)
            {
            case MSBuildValueKind.TaskOutputParameterName:
                return(doc.GetTaskParameters(rr.ParentName).Where(p => p.IsOutput).ToList());

            case MSBuildValueKind.TargetName:
                return(doc.GetTargets().ToList());

            case MSBuildValueKind.PropertyName:
                return(doc.GetProperties(true).ToList());

            case MSBuildValueKind.ItemName:
                return(doc.GetItems().ToList());

            case MSBuildValueKind.TargetFramework:
                return(FrameworkInfoProvider.Instance.GetFrameworksWithShortNames().ToList());

            case MSBuildValueKind.TargetFrameworkIdentifier:
                return(FrameworkInfoProvider.Instance.GetFrameworkIdentifiers().ToList());

            case MSBuildValueKind.TargetFrameworkVersion:
                return(doc.Frameworks.Select(f => f.Framework).Distinct().SelectMany(
                           id => FrameworkInfoProvider.Instance.GetFrameworkVersions(id)
                           ).Distinct().ToList());

            case MSBuildValueKind.TargetFrameworkProfile:
                return(doc.Frameworks.SelectMany(
                           tfm => FrameworkInfoProvider.Instance.GetFrameworkProfiles(tfm.Framework, tfm.Version)
                           ).Distinct().ToList());

            case MSBuildValueKind.Configuration:
                return(doc.GetConfigurations().Select(c => new ConstantInfo(c, "")).ToList());

            case MSBuildValueKind.Platform:
                return(doc.GetPlatforms().Select(c => new ConstantInfo(c, "")).ToList());
            }

            var fileCompletions = GetFilenameCompletions(kind, doc, triggerExpression, 0, rr);

            if (fileCompletions != null)
            {
                return(fileCompletions);
            }

            return(null);
        }
示例#9
0
        void Update(MSBuildRootDocument doc)
        {
            store.Clear();
            var shorten = GetDisplayElementFactory().CreateFilenameShortener(doc.RuntimeInformation);

            AddNode(store.AddNode(), doc, shorten);
            ExpandAll();
        }
示例#10
0
        public static async Task <object> GetInfoTooltipElement(MSBuildRootDocument doc, BaseInfo info, MSBuildResolveResult rr, CancellationToken token)
        {
            object nameElement = GetNameElement(info);

            if (nameElement == null)
            {
                return(null);
            }

            var imageElement = GetImageElement(info);

            if (imageElement != null)
            {
                nameElement = new ContainerElement(
                    ContainerElementStyle.Wrapped | ContainerElementStyle.VerticalPadding,
                    imageElement, nameElement
                    );
            }

            var elements = new List <object> {
                nameElement
            };

            switch (info.Description.DisplayElement)
            {
            case ISymbol symbol:
                await AddSymbolDescriptionElements(symbol, elements.Add, token);

                break;

            case object obj:
                elements.Add(obj);
                break;

            default:
                var descStr = DescriptionFormatter.GetDescription(info, doc, rr);
                if (!string.IsNullOrEmpty(descStr))
                {
                    elements.Add(
                        new ClassifiedTextElement(
                            new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, descStr)
                            )
                        );
                }
                break;
            }

            var seenIn = GetSeenInElement(info, doc);

            if (seenIn != null)
            {
                elements.Add(seenIn);
            }

            return(elements.Count == 1
                                ? elements[0]
                                : new ContainerElement(ContainerElementStyle.Stacked | ContainerElementStyle.VerticalPadding, elements));
        }
示例#11
0
        static MSBuildRootDocument ParseDoc(string contents, string filename = "myfile.csproj")
        {
            var runtimeInfo    = new MSBuildEnvironmentRuntimeInformation();
            var textSource     = new StringTextSource(contents);
            var schemaProvider = new MSBuildSchemaProvider();
            var taskBuilder    = new NoopTaskMetadataBuilder();

            return(MSBuildRootDocument.Parse(textSource, filename, null, schemaProvider, runtimeInfo, taskBuilder, default));
        }
示例#12
0
        CompletionItem CreateCompletionItem(BaseInfo info, MSBuildRootDocument doc, MSBuildResolveResult rr)
        {
            var image = DisplayElementFactory.GetImageElement(info);
            var item  = new CompletionItem(info.Name, this, image);

            item.AddDocumentationProvider(this);
            item.Properties.AddProperty(typeof(BaseInfo), info);
            return(item);
        }
示例#13
0
        protected void VerifyDiagnostics(string source, ICollection <MSBuildAnalyzer> analyzers, bool includeCoreDiagnostics, params MSBuildDiagnostic[] expectedDiagnostics)
        {
            var token = CancellationToken.None;

            var(env, _) = MSBuildTestEnvironment.EnsureInitialized();
            var host = env.GetEditorHost();

            var doc = MSBuildRootDocument.Parse(
                new StringTextSource(source),
                "FakeProject.csproj",
                null,
                host.GetService <MSBuildSchemaProvider> (),
                host.GetService <IRuntimeInformation> (),
                host.GetService <ITaskMetadataBuilder> (),
                token);

            var analyzerDriver = new MSBuildAnalyzerDriver();

            if (analyzers != null && analyzers.Count > 0)
            {
                analyzerDriver.AddAnalyzers(analyzers);
            }
            else if (!includeCoreDiagnostics)
            {
                throw new ArgumentException("Analyzers can only be null or empty if core diagnostics are included", nameof(analyzers));
            }

            var actualDiagnostics = analyzerDriver.Analyze(doc, includeCoreDiagnostics, token);

            foreach (var expectedDiag in expectedDiagnostics)
            {
                bool found = false;
                for (int i = 0; i < actualDiagnostics.Count; i++)
                {
                    var actualDiag = actualDiagnostics[i];
                    // todo: compare properties
                    if (actualDiag.Descriptor == expectedDiag.Descriptor && actualDiag.Span.Equals(expectedDiag.Span))
                    {
                        found = true;
                        actualDiagnostics.RemoveAt(i);
                        break;
                    }
                }
                if (!found)
                {
                    Assert.Fail($"Did not find expected diagnostic {expectedDiag.Descriptor.Id}@{expectedDiag.Span.Start}-{expectedDiag.Span.End}");
                }
            }

            if (actualDiagnostics.Count > 0)
            {
                var diag = actualDiagnostics[0];
                Assert.Fail($"Found unexpected diagnostic {diag.Descriptor.Id}@{diag.Span.Start}-{diag.Span.End}");
            }
        }
示例#14
0
        public TaskMetadataBuilder(MSBuildRootDocument rootDoc)
        {
            this.rootDoc = rootDoc;
            binPath      = rootDoc.RuntimeInformation.GetBinPath();

            foreach (var project in Ide.IdeApp.Workspace.GetAllProjects())
            {
                var outName = project.GetOutputFileName(project.ParentSolution.DefaultConfigurationSelector);
                projectMap[Path.GetFileNameWithoutExtension(outName)] = project;
            }
        }
        public List <MSBuildDiagnostic> Analyze(MSBuildRootDocument doc, CancellationToken token)
        {
            var session = new MSBuildAnalysisSession(context, doc, token);
            var visitor = new MSBuildAnalyzerVisitor(session);

            visitor.Run(doc, token: token);

            session.AddCoreDiagnostics(doc.Diagnostics);

            return(session.Diagnostics);
        }
        public MSBuildCompletionData(BaseInfo info, MSBuildRootDocument doc, MSBuildResolveResult rr, DataType type)
            : base(info.Name, info.Description, type)
        {
            this.info = info;
            this.doc  = doc;
            this.rr   = rr;

            if (info is FileOrFolderInfo f)
            {
                Icon = f.IsFolder? Stock.ClosedFolder : Stock.GenericFile;
            }
        }
示例#17
0
        async Task <object> GetPackageDocumentationAsync(MSBuildRootDocument doc, string packageId, FeedKind feedKind, CancellationToken token)
        {
            var tfm          = doc.GetTargetFrameworkNuGetSearchParameter();
            var packageInfos = await provider.PackageSearchManager.SearchPackageInfo(packageId, null, tfm).ToTask(token);

            var packageInfo = packageInfos.FirstOrDefault(p => p.SourceKind == feedKind) ?? packageInfos.FirstOrDefault();

            if (packageInfo != null)
            {
                return(provider.DisplayElementFactory.GetPackageInfoTooltip(packageId, packageInfo, feedKind));
            }
            return(null);
        }
        public List <MSBuildDiagnostic> Analyze(MSBuildRootDocument doc, bool includeFilteredCoreDiagnostics, CancellationToken token)
        {
            var session = new MSBuildAnalysisSession(context, doc, token);

            AnalyzeElement(doc.ProjectElement, session, token);

            if (includeFilteredCoreDiagnostics)
            {
                session.AddCoreDiagnostics(doc.Diagnostics);
            }

            return(session.Diagnostics);
        }
示例#19
0
        //FIXME: SDK version completion
        //FIXME: enumerate SDKs from NuGet
        Task <List <CompletionItem> > GetSdkCompletions(MSBuildRootDocument doc, CancellationToken token)
        {
            return(Task.Run(() => {
                var items = new List <CompletionItem> ();
                var sdks = new HashSet <string> ();

                foreach (var sdk in doc.RuntimeInformation.GetRegisteredSdks())
                {
                    if (sdks.Add(sdk.Name))
                    {
                        items.Add(CreateSdkCompletionItem(sdk));
                    }
                }

                //FIXME we should be able to cache these
                var sdksPath = doc.RuntimeInformation.SdksPath;
                if (sdksPath != null)
                {
                    AddSdksFromDir(sdksPath);
                }

                var dotNetSdkPath = doc.RuntimeInformation.GetSdkPath(("Microsoft.NET.Sdk", null, null), null, null);
                if (dotNetSdkPath != null)
                {
                    dotNetSdkPath = Path.GetDirectoryName(Path.GetDirectoryName(dotNetSdkPath));
                    if (sdksPath == null || Path.GetFullPath(dotNetSdkPath) != Path.GetFullPath(sdksPath))
                    {
                        AddSdksFromDir(dotNetSdkPath);
                    }
                }

                void AddSdksFromDir(string sdkDir)
                {
                    if (!Directory.Exists(sdkDir))
                    {
                        return;
                    }
                    foreach (var dir in Directory.GetDirectories(sdkDir))
                    {
                        string name = Path.GetFileName(dir);
                        var targetsFileExists = File.Exists(Path.Combine(dir, "Sdk", "Sdk.targets"));
                        if (targetsFileExists && sdks.Add(name))
                        {
                            items.Add(CreateSdkCompletionItem(new SdkInfo(name, null, Path.Combine(dir, name))));
                        }
                    }
                }

                return items;
            }, token));
        }
        public TaskMetadataBuilder(MSBuildRootDocument rootDoc)
        {
            this.rootDoc = rootDoc;
            binPath      = rootDoc.RuntimeInformation.GetBinPath();

            var metadataServiceType = typeof(Workspace).Assembly.GetType("Microsoft.CodeAnalysis.Host.IMetadataService");

            getReferenceMethod = metadataServiceType.GetMethod("GetReference", BF.Instance | BF.NonPublic | BF.Public);
            var services       = Ide.TypeSystem.TypeSystemService.Workspace.Services;
            var getServiceMeth = services.GetType().GetMethod("GetService", BF.Instance | BF.NonPublic | BF.Public);

            getServiceMeth  = getServiceMeth.MakeGenericMethod(metadataServiceType);
            metadataService = getServiceMeth.Invoke(services, null);
        }
        public ContainerElement GetSeenInElement(BaseInfo info, MSBuildRootDocument doc)
        {
            var seenIn = doc.GetFilesSeenIn(info).ToList();

            if (seenIn.Count == 0)
            {
                return(null);
            }

            Func <string, (string prefix, string remaining)?> shorten = null;

            var elements = new List <ClassifiedTextElement> ();

            int count = 0;

            foreach (var s in seenIn)
            {
                if (count == 5)
                {
                    elements.Add(new ClassifiedTextElement(new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, "[more in Find References]")));
                    break;
                }
                count++;

                //factor out some common prefixes into variables
                //we do this instead of using the original string, as the result is simpler
                //and easier to understand
                shorten = shorten ?? CreateFilenameShortener(doc.RuntimeInformation);
                var replacement = shorten(s);
                if (!replacement.HasValue)
                {
                    elements.Add(new ClassifiedTextElement(new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, s)));
                    continue;
                }

                elements.Add(new ClassifiedTextElement(
                                 new ClassifiedTextRun(PredefinedClassificationTypeNames.SymbolReference, replacement.Value.prefix),
                                 new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, replacement.Value.remaining, () => OpenFile(s), s)
                                 ));
            }

            if (elements.Count == 0)
            {
                return(null);
            }

            elements.Insert(0, new ClassifiedTextElement(new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, "Seen in:")));
            return(new ContainerElement(ContainerElementStyle.Stacked, elements));
        }
示例#22
0
        public static IReadOnlyList <ISymbol> GetFilenameCompletions(
            MSBuildValueKind kind, MSBuildRootDocument doc,
            ExpressionNode triggerExpression, int triggerLength, MSBuildResolveResult rr = null)
        {
            bool includeFiles = false;

            switch (kind)
            {
            case MSBuildValueKind.File:
            case MSBuildValueKind.ProjectFile:
                includeFiles = true;
                break;

            case MSBuildValueKind.FileOrFolder:
                includeFiles = true;
                break;

            case MSBuildValueKind.Folder:
            case MSBuildValueKind.FolderWithSlash:
                break;

            default:
                return(null);
            }

            string baseDir = null;

            if (rr.AttributeSyntax != null && rr.AttributeSyntax.SyntaxKind == MSBuildSyntaxKind.Import_Project)
            {
                if (rr.Element != null)
                {
                    var sdkAtt = rr.Element.Attributes.Get("Sdk", true)?.Value;
                    if (!string.IsNullOrEmpty(sdkAtt) && Microsoft.Build.Framework.SdkReference.TryParse(sdkAtt, out var sdkRef))
                    {
                        var sdkInfo = doc.RuntimeInformation.ResolveSdk(
                            (sdkRef.Name, sdkRef.Version, sdkRef.MinimumVersion), doc.Filename, null);
                        if (sdkInfo != null)
                        {
                            baseDir = sdkInfo.Path;
                        }
                    }
                }
            }

            var basePaths = EvaluateExpressionAsPaths(triggerExpression, doc, triggerLength + 1, baseDir).ToList();

            return(basePaths.Count == 0 ? null : GetPathCompletions(basePaths, includeFiles));
        }
示例#23
0
        Task <ICompletionDataList> GetPackageVersionCompletions(MSBuildRootDocument doc, MSBuildResolveResult rr, int startIdx, int triggerLength)
        {
            var name = rr.XElement.Attributes.FirstOrDefault(a => a.Name.FullName == "Include")?.Value;

            if (string.IsNullOrEmpty(name))
            {
                return(null);
            }
            return(Task.FromResult <ICompletionDataList> (
                       new PackageVersionSearchCompletionDataList(PackageSearchManager, doc.GetTargetFrameworkNuGetSearchParameter(), name)
            {
                TriggerWordStart = startIdx,
                TriggerWordLength = triggerLength
            }
                       ));
        }
示例#24
0
        internal MSBuildRefactoringContext(
            MSBuildRootDocument document,
            TextSpan selectedSpan,
            Action <MSBuildAction> reportRefactoring,
            CancellationToken cancellationToken)
        {
            this.reportRefactoring = reportRefactoring;
            Document     = document;
            XDocument    = document.XDocument;
            SelectedSpan = selectedSpan;

            var xobj = document.XDocument.FindAtOrBeforeOffset(SelectedSpan.Start);

            if (xobj.Span.Contains(SelectedSpan.Start) || xobj is XElement el && el.OuterSpan.Contains(SelectedSpan.Start))
            {
                XObject = xobj;
            }
示例#25
0
        public static void Navigate(MSBuildNavigationResult result, MSBuildRootDocument doc)
        {
            try {
                switch (result.Kind)
                {
                case MSBuildReferenceKind.None:
                    NavigatePaths(result.Paths);
                    break;

                case MSBuildReferenceKind.Target:
                    FindReferences(() => new MSBuildTargetDefinitionCollector(result.Name), doc);
                    break;
                }
            } catch (Exception ex) {
                LoggingService.LogError("MSBuild navigation failed", ex);
            }
        }
示例#26
0
 Task <CompletionContext> GetPackageNameCompletions(MSBuildRootDocument doc, int startIdx, int triggerLength)
 {
     /*
      * string name = ((IXmlParserContext)Tracker.Engine).KeywordBuilder.ToString ();
      * if (string.IsNullOrWhiteSpace (name)) {
      *      return null;
      * }
      *
      * return Task.FromResult<ICompletionDataList> (
      *      new PackageNameSearchCompletionDataList (name, PackageSearchManager, doc.GetTargetFrameworkNuGetSearchParameter ()) {
      *              TriggerWordStart = startIdx,
      *              TriggerWordLength = triggerLength
      *      }
      * );
      */
     return(Task.FromResult(CompletionContext.Empty));
 }
示例#27
0
        Task <ICompletionDataList> GetPackageNameCompletions(MSBuildRootDocument doc, int startIdx, int triggerLength)
        {
            string name = ((IXmlParserContext)Tracker.Engine).KeywordBuilder.ToString();

            if (string.IsNullOrWhiteSpace(name))
            {
                return(null);
            }

            return(Task.FromResult <ICompletionDataList> (
                       new PackageNameSearchCompletionDataList(name, PackageSearchManager, doc.GetTargetFrameworkNuGetSearchParameter())
            {
                TriggerWordStart = startIdx,
                TriggerWordLength = triggerLength
            }
                       ));
        }
示例#28
0
        public TaskMetadataBuilder(MSBuildRootDocument rootDoc)
        {
            this.rootDoc = rootDoc;
            binPath      = rootDoc.RuntimeInformation.GetBinPath();

            if (Ide.IdeApp.IsRunning)
            {
                try {
                    foreach (var project in Ide.IdeApp.Workspace.GetAllProjects())
                    {
                        var outName = project.GetOutputFileName(project.ParentSolution.DefaultConfigurationSelector);
                        projectMap [Path.GetFileNameWithoutExtension(outName)] = project;
                    }
                } catch (Exception ex) {
                    LoggingService.LogError("Error reading open projects", ex);
                }
            }
        }
示例#29
0
        public static TooltipInformation CreateTooltipInformation(MSBuildRootDocument doc, BaseInfo info, MSBuildResolveResult rr)
        {
            var formatter  = new DescriptionMarkupFormatter(doc);
            var nameMarkup = formatter.GetNameMarkup(info);

            if (nameMarkup.IsEmpty)
            {
                return(null);
            }

            var desc = DescriptionFormatter.GetDescription(info, doc, rr);

            return(new TooltipInformation {
                SignatureMarkup = nameMarkup.AsMarkup(),
                SummaryMarkup = desc.AsMarkup(),
                FooterMarkup = formatter.GetSeenInMarkup(info).AsMarkup()
            });
        }
        public MSBuildCompletionData(BaseInfo info, MSBuildRootDocument doc, MSBuildResolveResult rr, DataType type)
            : base(info.Name, null, type)
        {
            this.info = info;
            this.doc  = doc;
            this.rr   = rr;

            if (info is FileOrFolderInfo f)
            {
                Icon = f.IsFolder? Stock.ClosedFolder : Stock.GenericFile;
            }

            // deprioritize private values
            if (info.Name[0] == '_')
            {
                priorityGroup = -int.MaxValue;
            }
        }