예제 #1
0
        IList <ICompletionItem> CreatePropertyPathCompletion(XamlCompletionContext context)
        {
            bool  isExplicit;
            IType typeName = GetType(context, out isExplicit);
            IList <ICompletionItem> list = new List <ICompletionItem>();

            string value = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset + 1, context.RawAttributeValue.Length)) : "";

            if (value.EndsWithAny(']', ')'))
            {
                return(list);
            }

            var segments = PropertyPathParser.Parse(value).ToList();

            int  completionStart;
            bool isAtDot = false;

            IType propertyPathType = ResolvePropertyPath(segments, context, typeName, out completionStart);

            if (completionStart < segments.Count)
            {
                PropertyPathSegment seg = segments[completionStart];
                switch (seg.Kind)
                {
                case SegmentKind.ControlChar:
                    if (seg.Content == ".")
                    {
                        AddAttributes(propertyPathType, list, false);
                        isAtDot = true;
                    }
                    break;

                case SegmentKind.AttachedProperty:
                    AddAttributes(seg.Resolve(context, propertyPathType), list, false);
                    isAtDot = seg.Content.Contains(".");
                    break;

                case SegmentKind.PropertyOrType:
                    AddAttributes(propertyPathType, list, false);
                    isAtDot = true;
                    break;
                }
            }
            else if (typeName != null)
            {
                AddAttributes(typeName, list, false);
            }

            if (!isAtDot)
            {
                foreach (var item in GetAllTypes(context))
                {
                    list.Add(item);
                }
            }

            return(list);
        }
예제 #2
0
        public static IType Resolve(this PropertyPathSegment segment, XamlCompletionContext context, IType previousType)
        {
            if (segment.Kind == SegmentKind.SourceTraversal)
            {
                return(previousType);
            }
            if (segment.Kind == SegmentKind.ControlChar)
            {
                return(previousType);
            }

            string content = segment.Content;

            if (segment.Kind == SegmentKind.AttachedProperty && content.StartsWith("(", StringComparison.Ordinal))
            {
                content = content.TrimStart('(');
                if (content.Contains("."))
                {
                    content = content.Remove(content.IndexOf('.'));
                }
            }

            ICompilation compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
            XamlResolver resolver    = new XamlResolver(compilation);

            ResolveResult rr   = resolver.ResolveExpression(content, context);
            IType         type = rr.Type;

            if (previousType != null)
            {
                IMember member = previousType.GetMemberByName(content);
                if (member != null)
                {
                    type = member.ReturnType;
                }
            }
            else if (rr is MemberResolveResult)
            {
                MemberResolveResult mrr = rr as MemberResolveResult;
                if (mrr.Member != null)
                {
                    type = mrr.Member.ReturnType;
                }
            }
            return(type);
        }
예제 #3
0
        static IType ResolvePropertyPath(IList <PropertyPathSegment> segments, XamlCompletionContext context, IType parentType, out int lastIndex)
        {
            IType type = parentType;

            for (lastIndex = 0; lastIndex < segments.Count - 1; lastIndex++)
            {
                PropertyPathSegment segment = segments[lastIndex];
                switch (segment.Kind)
                {
                case SegmentKind.AttachedProperty:
                    // do we need to take account of previous results?
                    type = segment.Resolve(context, null);
                    break;

                case SegmentKind.ControlChar:
                    if (segment.Content == "[" || segment.Content == "(" || segment.Content == "/")
                    {
                        return(null);
                    }
                    return(type);

                case SegmentKind.PropertyOrType:
                    type = segment.Resolve(context, type);
                    break;

                case SegmentKind.Indexer:
                    if (type != null)
                    {
                        IProperty prop = type.GetProperties(p => p.IsIndexer).FirstOrDefault();
                        if (prop != null)
                        {
                            type = prop.ReturnType;
                        }
                    }
                    break;

                case SegmentKind.SourceTraversal:
                    // ignore
                    return(null);
                }
            }

            return(type);
        }