//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))); }
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)); }
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); }
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)); }
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); }
void Update(MSBuildRootDocument doc) { store.Clear(); var shorten = GetDisplayElementFactory().CreateFilenameShortener(doc.RuntimeInformation); AddNode(store.AddNode(), doc, shorten); ExpandAll(); }
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)); }
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)); }
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); }
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}"); } }
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; } }
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); }
//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)); }
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)); }
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 } )); }
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; }
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); } }
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)); }
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 } )); }
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); } } }
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; } }