コード例 #1
0
        public override async Task <CompletionContext> GetCompletionContextAsync(IAsyncCompletionSession session, CompletionTrigger trigger, SnapshotPoint triggerLocation, SnapshotSpan applicableToSpan, CancellationToken token)
        {
            var context = await GetSessionContext(session, triggerLocation, token);

            var rr    = context.rr;
            var doc   = context.doc;
            var spine = context.spine;

            if (rr?.LanguageElement != null)
            {
                if (ExpressionCompletion.IsPossibleExpressionCompletionContext(spine))
                {
                    string expression   = GetAttributeOrElementValueToCaret(spine, triggerLocation);
                    var    triggerState = ExpressionCompletion.GetTriggerState(
                        expression,
                        trigger.Character,
                        rr.IsCondition(),
                        out int triggerLength,
                        out ExpressionNode triggerExpression,
                        out var listKind,
                        out IReadOnlyList <ExpressionNode> comparandVariables
                        );
                    if (triggerState != ExpressionCompletion.TriggerState.None)
                    {
                        var info = rr.GetElementOrAttributeValueInfo(doc);
                        if (info != null && info.ValueKind != MSBuildValueKind.Nothing)
                        {
                            return(await GetExpressionCompletionsAsync(info, triggerState, listKind, triggerLength, triggerExpression, comparandVariables, rr, triggerLocation, doc, token));
                        }
                    }
                }
            }

            return(await base.GetCompletionContextAsync(session, trigger, triggerLocation, applicableToSpan, token));
        }
コード例 #2
0
        public override CompletionStartData InitializeCompletion(CompletionTrigger trigger, SnapshotPoint triggerLocation, CancellationToken token)
        {
            //we don't care need a real document here we're doing very basic resolution for triggering
            var spine = GetSpineParser(triggerLocation);
            var rr    = MSBuildResolver.Resolve(spine, triggerLocation.Snapshot.GetTextSource(), MSBuildRootDocument.Empty, null);

            if (rr?.LanguageElement != null)
            {
                if (ExpressionCompletion.IsPossibleExpressionCompletionContext(spine))
                {
                    string expression   = GetAttributeOrElementValueToCaret(spine, triggerLocation);
                    var    triggerState = ExpressionCompletion.GetTriggerState(
                        expression,
                        trigger.Character,
                        rr.IsCondition(),
                        out int triggerLength,
                        out ExpressionNode triggerExpression,
                        out var listKind,
                        out IReadOnlyList <ExpressionNode> comparandVariables
                        );
                    if (triggerState != ExpressionCompletion.TriggerState.None)
                    {
                        return(new CompletionStartData(CompletionParticipation.ProvidesItems, new SnapshotSpan(triggerLocation.Snapshot, triggerLocation.Position - triggerLength, triggerLength)));
                    }
                }
            }

            return(base.InitializeCompletion(trigger, triggerLocation, token));
        }
コード例 #3
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);
        }
コード例 #4
0
        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);
        }