public static IEnumerable <BaseInfo> GetElementCompletions(this MSBuildResolveResult rr, IEnumerable <IMSBuildSchema> schemas) { if (rr?.LanguageElement == null) { yield return(MSBuildLanguageElement.Get("Project")); yield break; } if (rr.LanguageElement.Children == null) { yield break; } foreach (var c in rr.LanguageElement.Children) { if (c.IsAbstract) { var abstractChildren = GetAbstractChildren(schemas, rr.LanguageElement.AbstractChild.Kind, rr.ElementName); if (abstractChildren != null) { foreach (var child in abstractChildren) { yield return(child); } } } else { yield return(c); } } }
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); }
public bool FindReferences(ITextBuffer buffer, MSBuildResolveResult resolveResult) { if (!MSBuildReferenceCollector.CanCreate(resolveResult)) { return(false); } FindReferencesAsync(buffer, resolveResult); return(true); }
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); }
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; } }
public static IEnumerable <BaseInfo> GetAttributeCompletions(this MSBuildResolveResult rr, IEnumerable <IMSBuildSchema> schemas, MSBuildToolsVersion tv) { bool isInTarget = false; if (rr.LanguageElement.Kind == MSBuildKind.Item) { isInTarget = rr.LanguageElement.IsInTarget(rr.XElement); } foreach (var att in rr.LanguageElement.Attributes) { var spat = schemas.SpecializeAttribute(att, rr.ElementName); if (!spat.IsAbstract) { if (rr.LanguageElement.Kind == MSBuildKind.Item) { if (isInTarget) { if (spat.Name == "Update") { continue; } } else { if (spat.Name == "KeepMetadata" || spat.Name == "RemoveMetadata" || spat.Name == "KeepDuplicates") { continue; } } } yield return(spat); } } if (rr.LanguageElement.Kind == MSBuildKind.Item && tv.IsAtLeast(MSBuildToolsVersion.V15_0)) { foreach (var item in schemas.GetMetadata(rr.ElementName, false)) { yield return(item); } } if (rr.LanguageElement.Kind == MSBuildKind.Task) { foreach (var parameter in schemas.GetTaskParameters(rr.ElementName)) { yield return(parameter); } } }
async void FindReferencesAsync(ITextBuffer buffer, MSBuildResolveResult reference) { var referenceName = reference.GetReferenceName(); var searchCtx = Presenter.StartSearch($"'{referenceName}' references", referenceName, true); try { await FindReferences(searchCtx, a => MSBuildReferenceCollector.Create(reference, Resolver.FunctionTypeProvider, a), buffer); } catch (Exception ex) when(!(ex is OperationCanceledException && searchCtx.CancellationToken.IsCancellationRequested)) { LoggingService.LogError($"Error in find references", ex); } await searchCtx.OnCompletedAsync(); }
public static ValueInfo GetElementOrAttributeValueInfo(this MSBuildResolveResult rr, IEnumerable <IMSBuildSchema> schemas) { if (rr.LanguageElement == null) { return(null); } if (rr.AttributeName != null) { return(schemas.GetAttributeInfo(rr.LanguageAttribute, rr.ElementName, rr.AttributeName)); } return(schemas.GetElementInfo(rr.LanguageElement, rr.ParentName, rr.ElementName)); }
public static ITypedSymbol GetElementOrAttributeValueInfo(this MSBuildResolveResult rr, IEnumerable <IMSBuildSchema> schemas) { if (rr.ElementSyntax == null) { return(null); } if (rr.AttributeName != null) { return(schemas.GetAttributeInfo(rr.AttributeSyntax, rr.ElementName, rr.AttributeName)); } return(schemas.GetElementInfo(rr.ElementSyntax, rr.ParentName, rr.ElementName)); }
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)); }
//FIXME: improve logic for determining where metadata is permitted bool IsMetadataAllowed(ExpressionNode triggerExpression, MSBuildResolveResult rr) { //if any a parent node is an item transform or function, metadata is allowed if (triggerExpression != null) { var node = triggerExpression.Find(triggerExpression.Length); while (node != null) { if (node is ExpressionItemTransform || node is ExpressionItemFunctionInvocation) { return(true); } node = node.Parent; } } if (rr.AttributeSyntax != null) { switch (rr.AttributeSyntax.SyntaxKind) { // metadata attributes on items can refer to other metadata on the items case MSBuildSyntaxKind.Item_Metadata: // task params can refer to metadata in batched items case MSBuildSyntaxKind.Task_Parameter: // target inputs and outputs can use metadata from each other's items case MSBuildSyntaxKind.Target_Inputs: case MSBuildSyntaxKind.Target_Outputs: return(true); //conditions on metadata elements can refer to metadata on the items case MSBuildSyntaxKind.Metadata_Condition: return(true); } } if (rr.ElementSyntax != null) { switch (rr.ElementSyntax.SyntaxKind) { // metadata elements can refer to other metadata in the items case MSBuildSyntaxKind.Metadata: return(true); } } return(false); }
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; } }
public static BaseInfo GetResolvedReference(this MSBuildResolveResult rr, MSBuildRootDocument doc) { switch (rr.ReferenceKind) { case MSBuildReferenceKind.Item: return(doc.GetItem((string)rr.Reference)); case MSBuildReferenceKind.Metadata: var m = rr.ReferenceAsMetadata; return(doc.GetMetadata(m.itemName, m.metaName, true)); case MSBuildReferenceKind.Property: return(doc.GetProperty((string)rr.Reference)); case MSBuildReferenceKind.Task: return(doc.GetTask((string)rr.Reference)); case MSBuildReferenceKind.Target: return(doc.GetTarget((string)rr.Reference)); case MSBuildReferenceKind.Keyword: return((BaseInfo)rr.Reference); case MSBuildReferenceKind.KnownValue: return((BaseInfo)rr.Reference); case MSBuildReferenceKind.TargetFramework: return(ResolveFramework((string)rr.Reference)); case MSBuildReferenceKind.TargetFrameworkIdentifier: return(BestGuessResolveFrameworkIdentifier((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkVersion: return(BestGuessResolveFrameworkVersion((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkProfile: return(BestGuessResolveFrameworkProfile((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TaskParameter: var p = rr.ReferenceAsTaskParameter; return(doc.GetTaskParameter(p.taskName, p.paramName)); } return(null); }
public MSBuildCompletionData(BaseInfo info, MSBuildRootDocument doc, MSBuildResolveResult rr, DataType type) : base(info.Name, null, type) { switch (info) { case FunctionInfo fi: { foreach (var overload in fi.Overloads) { AddOverload(new MSBuildCompletionData(overload, doc, rr, type)); } //FIXME: can we resolve the msbuild / .net property terminology overloading? Icon = fi.IsProperty? Stock.Property : Stock.Method; break; } case PropertyInfo _: Icon = Stock.Property; break; case FileOrFolderInfo f: Icon = f.IsFolder ? Stock.ClosedFolder : Stock.GenericFile; break; case ClassInfo _: Icon = Stock.Class; break; } this.info = info; this.doc = doc; this.rr = rr; // deprioritize private values if (info.Name[0] == '_') { priorityGroup = -int.MaxValue; } }
async Task <CompletionContext> GetExpressionCompletionsAsync( IAsyncCompletionSession session, ValueInfo info, TriggerState triggerState, ListKind listKind, int triggerLength, ExpressionNode triggerExpression, IReadOnlyList <ExpressionNode> comparandVariables, MSBuildResolveResult rr, SnapshotPoint triggerLocation, MSBuildRootDocument doc, CancellationToken token) { var kind = info.InferValueKindIfUnknown(); if (!ValidateListPermitted(listKind, kind)) { return(CompletionContext.Empty); } bool allowExpressions = kind.AllowExpressions(); kind = kind.GetScalarType(); if (kind == MSBuildValueKind.Data || kind == MSBuildValueKind.Nothing) { return(CompletionContext.Empty); } bool isValue = triggerState == TriggerState.Value; var items = new List <CompletionItem> (); if (comparandVariables != null && isValue) { foreach (var ci in ExpressionCompletion.GetComparandCompletions(doc, comparandVariables)) { items.Add(CreateCompletionItem(ci, XmlCompletionItemKind.AttributeValue)); } } if (isValue) { switch (kind) { case MSBuildValueKind.NuGetID: if (triggerExpression is ExpressionText t) { var packageNameItems = await GetPackageNameCompletions(session, doc, t.Value, token); if (packageNameItems != null) { items.AddRange(packageNameItems); } } break; case MSBuildValueKind.NuGetVersion: { var packageVersionItems = await GetPackageVersionCompletions(doc, rr, token); if (packageVersionItems != null) { items.AddRange(packageVersionItems); } break; } case MSBuildValueKind.Sdk: case MSBuildValueKind.SdkWithVersion: { var sdkItems = await GetSdkCompletions(doc, token); if (sdkItems != null) { items.AddRange(sdkItems); } break; } case MSBuildValueKind.Guid: items.Add(CreateSpecialItem("New GUID", "Inserts a new GUID", KnownImages.Add, MSBuildSpecialCommitKind.NewGuid)); break; case MSBuildValueKind.Lcid: items.AddRange(GetLcidCompletions()); break; } } //TODO: better metadata support IEnumerable <BaseInfo> cinfos; if (info.CustomType != null && info.CustomType.Values.Count > 0 && isValue) { cinfos = info.CustomType.Values; } else { //FIXME: can we avoid awaiting this unless we actually need to resolve a function? need to propagate async downwards await provider.FunctionTypeProvider.EnsureInitialized(token); cinfos = ExpressionCompletion.GetCompletionInfos(rr, triggerState, kind, triggerExpression, triggerLength, doc, provider.FunctionTypeProvider); } if (cinfos != null) { foreach (var ci in cinfos) { items.Add(CreateCompletionItem(ci, XmlCompletionItemKind.AttributeValue)); } } if ((allowExpressions && isValue) || triggerState == TriggerState.BareFunctionArgumentValue) { items.Add(CreateSpecialItem("$(", "Property reference", KnownImages.MSBuildProperty, MSBuildSpecialCommitKind.PropertyReference)); } if (allowExpressions && isValue) { items.Add(CreateSpecialItem("@(", "Item reference", KnownImages.MSBuildItem, MSBuildSpecialCommitKind.ItemReference)); if (IsMetadataAllowed(triggerExpression, rr)) { items.Add(CreateSpecialItem("%(", "Metadata reference", KnownImages.MSBuildItem, MSBuildSpecialCommitKind.MetadataReference)); } } if (items.Count > 0) { return(CreateCompletionContext(items)); } return(CompletionContext.Empty); }
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); }
public static string GetDescription(BaseInfo info, MSBuildDocument doc, MSBuildResolveResult rr) { if (doc == null) { return(info.Description.Text); } //construct a customized version of the include/exclude/etc attribute if appropriate if (info is MSBuildLanguageAttribute att) { switch (att.Name.ToLower()) { case "include": case "exclude": case "remove": case "update": var item = doc.GetSchemas().GetItem(rr.ElementName); if (item != null && !string.IsNullOrEmpty(item.IncludeDescription)) { switch (item.ValueKind) { case MSBuildValueKind.File: case MSBuildValueKind.Folder: case MSBuildValueKind.FolderWithSlash: case MSBuildValueKind.FileOrFolder: return(GetDesc($"Item.{att.Name}.ParameterizedFiles")); default: if (!item.ValueKind.AllowLists()) { return(GetDesc($"Item.{att.Name}.ParameterizedSingle")); } return(GetDesc($"Item.{att.Name}.Parameterized")); } } string GetDesc(string id) => string.Format( ElementDescriptions.ResourceManager.GetString(id, ElementDescriptions.Culture), item.IncludeDescription); break; } } if (info.Description.IsEmpty) { switch (info) { case PropertyInfo prop: if (info.Name.EndsWith("DependsOn", StringComparison.OrdinalIgnoreCase)) { var targetName = info.Name.Substring(0, info.Name.Length - "DependsOn".Length); return($"The targets that the {targetName} target depends on"); } break; case FrameworkInfo fxi: return(FrameworkInfoProvider.GetDescription(fxi.Reference)); } } return(info.Description.Text); }
/// <summary> /// Gets a resolved reference from the document. The schema may be stale, in which case it returns false. /// </summary> public bool GetResolvedReference(ITextBuffer buffer, SnapshotPoint position, out MSBuildRootDocument doc, out MSBuildResolveResult rr) { // grab the field into a local to make this thread safe var cached = this.cached; // if the cached result is up to date, return it if (cached.Position == position) { doc = cached.Doc; rr = cached.Result; return(true); } var parser = ParserProvider.GetParser(buffer); var lastResult = parser.LastOutput; // if it's still at the same position and the last result is the same stale version, there's no point trying again if (cached.Position == position && lastResult.MSBuildDocument == cached.Doc) { doc = cached.Doc; rr = cached.Result; return(false); } // actually do the work cached.Doc = doc = lastResult.MSBuildDocument; cached.Result = rr = MSBuildResolver.Resolve( parser.XmlParser.GetSpineParser(position), position.Snapshot.GetTextSource(), doc, FunctionTypeProvider); cached.Position = position; this.cached = cached; return(lastResult.Snapshot == position.Snapshot); }
Task <ICompletionDataList> HandleExpressionCompletion(MSBuildResolveResult rr, CancellationToken token) { var doc = GetDocument(); if (!ExpressionCompletion.IsPossibleExpressionCompletionContext(Tracker.Engine)) { return(null); } string expression = GetAttributeOrElementTextToCaret(); var triggerState = ExpressionCompletion.GetTriggerState( expression, rr.IsCondition(), out int triggerLength, out ExpressionNode triggerExpression, out IReadOnlyList <ExpressionNode> comparandVariables ); if (triggerState == ExpressionCompletion.TriggerState.None) { return(null); } var info = rr.GetElementOrAttributeValueInfo(doc); if (info == null) { return(null); } var kind = MSBuildCompletionExtensions.InferValueKindIfUnknown(info); if (!ExpressionCompletion.ValidateListPermitted(ref triggerState, kind)) { return(null); } bool allowExpressions = kind.AllowExpressions(); kind = kind.GetScalarType(); if (kind == MSBuildValueKind.Data || kind == MSBuildValueKind.Nothing) { return(null); } var list = new CompletionDataList { TriggerWordLength = triggerLength, AutoSelect = false }; if (comparandVariables != null && triggerState == ExpressionCompletion.TriggerState.Value) { foreach (var ci in ExpressionCompletion.GetComparandCompletions(doc, comparandVariables)) { list.Add(new MSBuildCompletionData(ci, doc, rr, XmlCompletionData.DataType.XmlAttributeValue)); } } if (triggerState == ExpressionCompletion.TriggerState.Value) { switch (kind) { case MSBuildValueKind.NuGetID: return(GetPackageNameCompletions(doc, Editor.CaretOffset - triggerLength, triggerLength)); case MSBuildValueKind.NuGetVersion: return(GetPackageVersionCompletions(doc, rr, Editor.CaretOffset - triggerLength, triggerLength)); case MSBuildValueKind.Sdk: case MSBuildValueKind.SdkWithVersion: return(GetSdkCompletions(triggerLength, token)); case MSBuildValueKind.Guid: list.Add(new GenerateGuidCompletionData()); break; case MSBuildValueKind.Lcid: foreach (var culture in System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures)) { string name = culture.Name; string id = culture.LCID.ToString(); string display = culture.DisplayName; //insert multiple versions for matching on both the name and the number list.Add(new CompletionData(id, null, display)); list.Add(new CompletionData(display, null, id, id)); } break; } } //TODO: better metadata support IEnumerable <BaseInfo> cinfos; if (info.Values != null && info.Values.Count > 0 && triggerState == ExpressionCompletion.TriggerState.Value) { cinfos = info.Values; } else { cinfos = ExpressionCompletion.GetCompletionInfos(rr, triggerState, kind, triggerExpression, triggerLength, doc); } if (cinfos != null) { foreach (var ci in cinfos) { list.Add(new MSBuildCompletionData(ci, doc, rr, XmlCompletionData.DataType.XmlAttributeValue)); } } if (allowExpressions && triggerState == ExpressionCompletion.TriggerState.Value) { list.Add(new CompletionDataWithSkipCharAndRetrigger("$(", "md-variable", "Property value reference", "$(|)", ')')); list.Add(new CompletionDataWithSkipCharAndRetrigger("@(", "md-variable", "Item list reference", "@(|)", ')')); } if (list.Count > 0) { return(Task.FromResult <ICompletionDataList> (list)); } return(null); }
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 } )); }
public static BaseInfo GetResolvedReference(this MSBuildResolveResult rr, MSBuildRootDocument doc) { switch (rr.ReferenceKind) { case MSBuildReferenceKind.Item: return(doc.GetItem((string)rr.Reference)); case MSBuildReferenceKind.Metadata: var m = rr.ReferenceAsMetadata; if (Builtins.Metadata.TryGetValue(m.metaName, out var builtinMeta)) { return(builtinMeta); } return(doc.GetMetadata(m.itemName, m.metaName, true)); case MSBuildReferenceKind.Property: var propName = (string)rr.Reference; if (Builtins.Properties.TryGetValue(propName, out var builtinProp)) { return(builtinProp); } return(doc.GetProperty(propName)); case MSBuildReferenceKind.Task: return(doc.GetTask((string)rr.Reference)); case MSBuildReferenceKind.Target: return(doc.GetTarget((string)rr.Reference)); case MSBuildReferenceKind.Keyword: return((BaseInfo)rr.Reference); case MSBuildReferenceKind.KnownValue: return((BaseInfo)rr.Reference); case MSBuildReferenceKind.TargetFramework: return(ResolveFramework((string)rr.Reference)); case MSBuildReferenceKind.TargetFrameworkIdentifier: return(BestGuessResolveFrameworkIdentifier((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkVersion: return(BestGuessResolveFrameworkVersion((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkProfile: return(BestGuessResolveFrameworkProfile((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TaskParameter: var p = rr.ReferenceAsTaskParameter; return(doc.GetTaskParameter(p.taskName, p.paramName)); case MSBuildReferenceKind.ItemFunction: //FIXME: attempt overload resolution return(FunctionCompletion.GetItemFunctionInfo((string)rr.Reference)); case MSBuildReferenceKind.StaticPropertyFunction: //FIXME: attempt overload resolution (string className, string name) = ((string, string))rr.Reference; return(FunctionCompletion.GetStaticPropertyFunctionInfo(className, name)); case MSBuildReferenceKind.PropertyFunction: //FIXME: attempt overload resolution (MSBuildValueKind kind, string funcName) = ((MSBuildValueKind, string))rr.Reference; return(FunctionCompletion.GetPropertyFunctionInfo(kind, funcName)); case MSBuildReferenceKind.ClassName: return(FunctionCompletion.GetClassInfo((string)rr.Reference)); case MSBuildReferenceKind.Enum: return(FunctionCompletion.GetEnumInfo((string)rr.Reference)); } return(null); }
//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))); }
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)); }
public static IEnumerable <ISymbol> 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 ConstantSymbol(c, "", MSBuildValueKind.Configuration)).ToList()); case MSBuildValueKind.Platform: return(doc.GetPlatforms().Select(c => new ConstantSymbol(c, "", MSBuildValueKind.Platform)).ToList()); case MSBuildValueKind.Condition: //FIXME: relax this a bit if (triggerExpression != null && triggerExpression is ExpressionText t && t.Length == 0) { return(Builtins.ConditionFunctions.Values); } break; } var fileCompletions = GetFilenameCompletions(kind, doc, triggerExpression, 0, rr); if (fileCompletions != null) { return(fileCompletions); } return(null); }
public async Task <object> GetInfoTooltipElement(ITextBuffer buffer, MSBuildRootDocument doc, ISymbol 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 IRoslynSymbol 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(FormatDescriptionText(descStr))); } break; } if (info is VariableInfo vi && !string.IsNullOrEmpty(vi.DefaultValue)) { elements.Add( new ClassifiedTextElement( new ClassifiedTextRun(PredefinedClassificationTypeNames.NaturalLanguage, $"Default value: "), new ClassifiedTextRun(PredefinedClassificationTypeNames.String, vi.DefaultValue) ) ); } var seenIn = GetSeenInElement(buffer, rr, info, doc); if (seenIn != null) { elements.Add(seenIn); } var deprecationMessage = GetDeprecationMessage(info); if (deprecationMessage != null) { elements.Add(deprecationMessage); } return(elements.Count == 1 ? elements[0] : new ContainerElement(ContainerElementStyle.Stacked | ContainerElementStyle.VerticalPadding, elements)); }
ContainerElement GetSeenInElement(ITextBuffer buffer, MSBuildResolveResult rr, ISymbol 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, "["), new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, "more in Find References", () => { NavigationService.FindReferences(buffer, rr); }), new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, "]") )); break; } count++; // collapse any .. segments string path = System.IO.Path.GetFullPath(s); //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 ??= CreateFilenameShortener(doc.RuntimeInformation); var replacement = shorten(path); if (!replacement.HasValue) { elements.Add( new ClassifiedTextElement( new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, path, () => OpenFile(path), path) ) ); continue; } elements.Add(new ClassifiedTextElement( new ClassifiedTextRun(PredefinedClassificationTypeNames.SymbolReference, replacement.Value.prefix), new ClassifiedTextRun(PredefinedClassificationTypeNames.Other, replacement.Value.remaining, () => OpenFile(path), path) )); } 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 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 static ISymbol GetResolvedReference(this MSBuildResolveResult rr, MSBuildRootDocument doc, IFunctionTypeProvider functionTypeProvider) { switch (rr.ReferenceKind) { case MSBuildReferenceKind.Item: return(doc.GetItem((string)rr.Reference)); case MSBuildReferenceKind.Metadata: var m = rr.ReferenceAsMetadata; return(doc.GetMetadata(m.itemName, m.metaName, true)); case MSBuildReferenceKind.Property: return(doc.GetProperty((string)rr.Reference, true)); case MSBuildReferenceKind.Task: return(doc.GetTask((string)rr.Reference)); case MSBuildReferenceKind.Target: return(doc.GetTarget((string)rr.Reference)); case MSBuildReferenceKind.Keyword: return((ISymbol)rr.Reference); case MSBuildReferenceKind.KnownValue: return((ISymbol)rr.Reference); case MSBuildReferenceKind.TargetFramework: return(ResolveFramework((string)rr.Reference)); case MSBuildReferenceKind.TargetFrameworkIdentifier: return(BestGuessResolveFrameworkIdentifier((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkVersion: return(BestGuessResolveFrameworkVersion((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TargetFrameworkProfile: return(BestGuessResolveFrameworkProfile((string)rr.Reference, doc.Frameworks)); case MSBuildReferenceKind.TaskParameter: var p = rr.ReferenceAsTaskParameter; return(doc.GetTaskParameter(p.taskName, p.paramName)); case MSBuildReferenceKind.ItemFunction: //FIXME: attempt overload resolution return(functionTypeProvider.GetItemFunctionInfo((string)rr.Reference)); case MSBuildReferenceKind.StaticPropertyFunction: //FIXME: attempt overload resolution (string className, string name) = ((string, string))rr.Reference; return(functionTypeProvider.GetStaticPropertyFunctionInfo(className, name)); case MSBuildReferenceKind.PropertyFunction: //FIXME: attempt overload resolution (MSBuildValueKind kind, string funcName) = ((MSBuildValueKind, string))rr.Reference; return(functionTypeProvider.GetPropertyFunctionInfo(kind, funcName)); case MSBuildReferenceKind.ClassName: return(functionTypeProvider.GetClassInfo((string)rr.Reference)); case MSBuildReferenceKind.Enum: return(functionTypeProvider.GetEnumInfo((string)rr.Reference)); case MSBuildReferenceKind.ConditionFunction: if (Builtins.ConditionFunctions.TryGetValue((string)rr.Reference, out var conditionFunctionName)) { return(conditionFunctionName); } return(null); } return(null); }