Ejemplo n.º 1
0
        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);
        }