コード例 #1
0
        IType GetType(XamlContext context, out bool isExplicit)
        {
            string         targetTypeValue = Utils.LookForTargetTypeValue(context, out isExplicit, "Trigger", "Setter");
            AttributeValue value           = MarkupExtensionParser.ParseValue(targetTypeValue ?? string.Empty);
            XamlResolver   resolver        = new XamlResolver(compilation);

            return(resolver.ResolveAttributeValue(context, value).Type);
        }
コード例 #2
0
        public bool CtrlSpace(ITextEditor editor)
        {
            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            resolver    = new XamlResolver(compilation);

            XamlCompletionContext context = XamlContextResolver.ResolveCompletionContext(editor, ' ');

            context.Forced = true;
            return(CtrlSpace(editor, context));
        }
コード例 #3
0
        IList <ICompletionItem> CreateAttributeList(XamlCompletionContext context, bool includeEvents)
        {
            if (context.ParseInformation == null)
            {
                return(EmptyList <ICompletionItem> .Instance);
            }
            AXmlElement     lastElement = context.ActiveElement;
            IUnresolvedFile file        = context.ParseInformation.UnresolvedFile;
            XamlResolver    resolver    = new XamlResolver(compilation);
            IType           type        = resolver.ResolveType(lastElement.Namespace, lastElement.LocalName.Trim('.'));

            var list = new List <ICompletionItem>();

            string xamlPrefix = context.XamlNamespacePrefix;
            string xKey       = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":";

            if (lastElement.Prefix == context.XamlNamespacePrefix && XamlConst.IsBuiltin(lastElement.LocalName))
            {
                return(EmptyList <ICompletionItem> .Instance);
            }

            if (lastElement.LocalName.EndsWith(".", StringComparison.OrdinalIgnoreCase) || context.PressedKey == '.')
            {
                if (type.Kind == TypeKind.Unknown)
                {
                    return(EmptyList <ICompletionItem> .Instance);
                }

                if (context.ParentElement != null &&
                    context.ParentElement.LocalName.StartsWith(lastElement.LocalName.TrimEnd('.'), StringComparison.OrdinalIgnoreCase))
                {
                    AddAttributes(type, list, includeEvents);
                }
                AddAttachedProperties(type.GetDefinition(), list);
            }
            else
            {
                if (type.Kind == TypeKind.Unknown)
                {
                    list.Add(new XamlCompletionItem(xKey + "Uid"));
                }
                else
                {
                    AddAttributes(type, list, includeEvents);
                    list.AddRange(GetListOfAttached(context, null, includeEvents, true));
                    list.AddRange(
                        XamlConst.XamlNamespaceAttributes
                        .Where(localName => XamlConst.IsAttributeAllowed(context.InRoot, localName))
                        .Select(item => new XamlCompletionItem(xKey + item))
                        );
                }
            }

            return(list);
        }
コード例 #4
0
        static void DoTriggerCompletion(XamlCompletionContext context, XamlCompletionItemList completionList)
        {
            bool           isExplicit;
            AttributeValue value = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, "Trigger") ?? string.Empty);

            IReturnType typeName       = null;
            string      typeNameString = null;

            if (!value.IsString)
            {
                typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context);
                typeName       = CompletionDataHelper.ResolveType(typeNameString, context);
            }
            else
            {
                typeNameString = value.StringValue;
                typeName       = CompletionDataHelper.ResolveType(value.StringValue, context);
            }

            if (typeName != null)
            {
                switch (context.Attribute.Name)
                {
                case "Value":
                    AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? "");
                    if (!propType.IsString)
                    {
                        break;
                    }

                    string name = propType.StringValue;

                    if (!name.Contains("."))
                    {
                        name = typeNameString + "." + name;
                    }

                    context.Description = XamlContextDescription.AtTag;

                    var member = XamlResolver.Resolve(name, context) as MemberResolveResult;

                    if (member == null || member.ResolvedMember == null)
                    {
                        break;
                    }

                    completionList.Items.AddRange(
                        CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty)
                        );
                    break;
                }
            }
        }
コード例 #5
0
        bool DoStaticExtensionCompletion(XamlCompletionItemList list, XamlCompletionContext context)
        {
            AttributeValue selItem = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset)
                                     .PositionalArguments.LastOrDefault();
            var resolver = new XamlResolver(compilation);

            if (context.PressedKey == '.')
            {
                if (selItem != null && selItem.IsString)
                {
                    var rr = resolver.ResolveAttributeValue(selItem.StringValue, context) as TypeResolveResult;
                    if (rr != null)
                    {
                        list.Items.AddRange(MemberCompletion(context, rr.Type, string.Empty));
                    }
                    return(false);
                }
            }
            else
            {
                if (selItem != null && selItem.IsString)
                {
                    int    index = selItem.StringValue.IndexOf('.');
                    string s     = (index > -1) ? selItem.StringValue.Substring(0, index) : selItem.StringValue;
                    var    rr    = resolver.ResolveAttributeValue(s, context) as TypeResolveResult;
                    if (rr != null && rr.Type.Kind != TypeKind.Unknown)
                    {
                        list.Items.AddRange(MemberCompletion(context, rr.Type, (index == -1) ? "." : string.Empty));

                        list.PreselectionLength = (index > -1) ? selItem.StringValue.Length - index - 1 : 0;

                        return(false);
                    }
                    else
                    {
                        DoStaticTypeCompletion(selItem, list, context);
                    }
                }
                else
                {
                    DoStaticTypeCompletion(selItem, list, context);
                }
            }

            return(true);
        }
コード例 #6
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);
        }
コード例 #7
0
        public IEnumerable <IInsightItem> CreateMarkupExtensionInsight(XamlCompletionContext context)
        {
            var markup   = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
            var resolver = new XamlResolver(compilation);
            var type     = (resolver.ResolveExpression(markup.ExtensionType, context) ?? resolver.ResolveExpression(markup.ExtensionType + "Extension", context)).Type;

            if (type != null)
            {
                var ctors = type
                            .GetMethods(m => m.IsPublic && m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count)
                            .OrderBy(m => m.Parameters.Count);

                foreach (var ctor in ctors)
                {
                    yield return(new MarkupExtensionInsightItem(ctor));
                }
            }
        }
コード例 #8
0
        public ICompletionItemList CreateMarkupExtensionCompletion(XamlCompletionContext context)
        {
            var list = new XamlCompletionItemList(context);

            compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
            string visibleValue = context.RawAttributeValue.Substring(0, Utils.MinMax(context.ValueStartOffset, 0, context.RawAttributeValue.Length));

            if (context.PressedKey == '=')
            {
                visibleValue += "=";
            }
            var markup   = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
            var resolver = new XamlResolver(compilation);
            var type     = resolver.ResolveExpression(markup.ExtensionType, context).Type;

            if (type.Kind == TypeKind.Unknown)
            {
                type = resolver.ResolveExpression(markup.ExtensionType + "Extension", context).Type;
            }

            if (type.Kind == TypeKind.Unknown)
            {
                list.Items.AddRange(CreateListOfMarkupExtensions(context));
                list.PreselectionLength = markup.ExtensionType.Length;
            }
            else
            {
                if (markup.NamedArguments.Count == 0)
                {
                    if (DoPositionalArgsCompletion(list, context, markup, type))
                    {
                        DoNamedArgsCompletion(list, context, type, markup);
                    }
                }
                else
                {
                    DoNamedArgsCompletion(list, context, type, markup);
                }
            }

            list.SortItems();

            return(list);
        }
コード例 #9
0
        public static MemberResolveResult ResolveMember(string expression, XamlCompletionContext context)
        {
            if (context.ParseInformation == null || string.IsNullOrEmpty(context.Editor.Document.Text))
            {
                return(null);
            }

            var expressionResult = new ExpressionResult(expression, context);

            XamlResolver resolver = new XamlResolver();

            resolver.resolveExpression = expression;
            resolver.caretLine         = expressionResult.Region.BeginLine;
            resolver.caretColumn       = expressionResult.Region.BeginColumn;
            resolver.callingClass      = context.ParseInformation.CompilationUnit.GetInnermostClass(resolver.caretLine, resolver.caretColumn);
            resolver.context           = context;

            return(resolver.ResolveNamedAttribute(expression));
        }
コード例 #10
0
            void Process()
            {
                try {
                    List <Highlight> results = new List <Highlight>();

                    foreach (HighlightingInfo info in GetInfo())
                    {
                        IMember member = null;

                        // Commented out because task doesn't come with cancellation support in .NET 4.0 Beta 2
                        // (use CancellationToken instead)
                        // I didn't have to remove any call to task.Cancel(), so apparently this was dead code.
                        //if (task.IsCancellationRequested) {
                        //	task.AcknowledgeCancellation();
                        //	return;
                        //}
                        // TODO: implement cancellation support

                        if (!info.Token.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase))
                        {
                            MemberResolveResult rr = XamlResolver.Resolve(info.Token, info.Context) as MemberResolveResult;
                            member = (rr != null) ? rr.ResolvedMember : null;
                        }

                        results.Add(new Highlight()
                        {
                            Member = member, Info = info
                        });
                    }

                    lock (this)
                        this.results = results;

                    WorkbenchSingleton.SafeThreadAsyncCall(InvokeRedraw);
                } catch (Exception e) {
                    WorkbenchSingleton.SafeThreadAsyncCall(() => MessageService.ShowException(e));
                }
            }
コード例 #11
0
        void DoNamedArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, IType type, MarkupExtensionInfo markup)
        {
            if (markup.NamedArguments.Count > 0 && !context.Editor.GetWordBeforeCaret().StartsWith(",", StringComparison.OrdinalIgnoreCase))
            {
                int lastStart = markup.NamedArguments.Max(i => i.Value.StartOffset);
                var item      = markup.NamedArguments.First(p => p.Value.StartOffset == lastStart);

                if (context.RawAttributeValue.EndsWith("=", StringComparison.OrdinalIgnoreCase) ||
                    (item.Value.IsString && item.Value.StringValue.EndsWith(context.Editor.GetWordBeforeCaretExtended(), StringComparison.Ordinal)))
                {
                    var resolver            = new XamlResolver(compilation);
                    MemberResolveResult mrr = resolver.ResolveAttributeValue(item.Key, context) as MemberResolveResult;
                    if (mrr != null && mrr.Member != null && mrr.Member.ReturnType != null)
                    {
                        IType memberType = mrr.Member.ReturnType;
                        list.Items.AddRange(MemberCompletion(context, memberType, string.Empty));
                    }
                    return;
                }
            }

            list.Items.AddRange(type.GetProperties().Where(p => p.CanSet && p.IsPublic).Select(p => new XamlCompletionItem(p.Name + "=", p)));
        }
コード例 #12
0
		IType GetType(XamlContext context, out bool isExplicit)
		{
			string targetTypeValue = Utils.LookForTargetTypeValue(context, out isExplicit, "Trigger", "Setter");
			AttributeValue value = MarkupExtensionParser.ParseValue(targetTypeValue ?? string.Empty);
			XamlResolver resolver = new XamlResolver(compilation);
			return resolver.ResolveAttributeValue(context, value).Type;
		}
コード例 #13
0
		bool DoStaticExtensionCompletion(XamlCompletionItemList list, XamlCompletionContext context)
		{
			AttributeValue selItem = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset)
				.PositionalArguments.LastOrDefault();
			var resolver = new XamlResolver(compilation);
			if (context.PressedKey == '.') {
				if (selItem != null && selItem.IsString) {
					var rr = resolver.ResolveAttributeValue(selItem.StringValue, context) as TypeResolveResult;
					if (rr != null)
						list.Items.AddRange(MemberCompletion(context, rr.Type, string.Empty));
					return false;
				}
			} else {
				if (selItem != null && selItem.IsString) {
					int index = selItem.StringValue.IndexOf('.');
					string s = (index > -1) ? selItem.StringValue.Substring(0, index) : selItem.StringValue;
					var rr = resolver.ResolveAttributeValue(s, context) as TypeResolveResult;
					if (rr != null && rr.Type.Kind != TypeKind.Unknown) {
						list.Items.AddRange(MemberCompletion(context, rr.Type, (index == -1) ? "." : string.Empty));
						
						list.PreselectionLength = (index > -1) ? selItem.StringValue.Length - index - 1 : 0;
						
						return false;
					} else
						DoStaticTypeCompletion(selItem, list, context);
				} else {
					DoStaticTypeCompletion(selItem, list, context);
				}
			}
			
			return true;
		}
コード例 #14
0
		public XamlCompletionItemList CreateListForContext(XamlCompletionContext context)
		{
			XamlCompletionItemList list = new XamlCompletionItemList(context);
			
			ITextEditor editor = context.Editor;
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);
			
			switch (context.Description) {
				case XamlContextDescription.None:
					if (context.Forced) {
						list.Items.AddRange(standardElements);
						list.Items.AddRange(CreateElementList(context, false));
						AddClosingTagCompletion(context, list, resolver);
					}
					break;
				case XamlContextDescription.AtTag:
					if ((editor.Caret.Offset > 0 && editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.') || context.PressedKey == '.') {
						list.Items.AddRange(CreateAttributeList(context, false));
					} else {
						list.Items.AddRange(standardElements);
						list.Items.AddRange(CreateElementList(context, false));
						AddClosingTagCompletion(context, list, resolver);
					}
					break;
				case XamlContextDescription.InTag:
					string word = editor.GetWordBeforeCaretExtended();
					
					if (context.PressedKey == '.' || word.Contains(".")) {
						int pos = word.IndexOf(':');
						
						string element = word.Substring(pos + 1, word.Length - pos - 1);
						string className = word;
						int propertyStart = element.IndexOf('.');
						if (propertyStart != -1) {
							element = element.Substring(0, propertyStart).TrimEnd('.');
							className = className.Substring(0, propertyStart + pos + 1).TrimEnd('.');
						}
						
						int caretOffset = editor.Caret.Offset;
						int offset = editor.Document.LastIndexOf(className, caretOffset - word.Length, word.Length, StringComparison.OrdinalIgnoreCase);
						TextLocation loc = editor.Document.GetLocation(offset);
						
						XamlFullParseInformation info = context.ParseInformation;
						XamlResolver nameResolver = new XamlResolver(compilation);
						TypeResolveResult trr = nameResolver.ResolveExpression(className, context) as TypeResolveResult;
						ITypeDefinition typeClass = trr != null ? trr.Type.GetDefinition() : null;
						
						if (typeClass != null && typeClass.HasAttached(true, true))
							list.Items.AddRange(GetListOfAttached(context, typeClass, true, true));
					} else {
						list.Items.AddRange(CreateAttributeList(context, true));
						list.Items.AddRange(standardAttributes);
					}
					break;
				case XamlContextDescription.InAttributeValue:
					new XamlCodeCompletionBinding().CtrlSpace(editor);
					break;
			}
			
			list.SortItems();
			
			return list;
		}
コード例 #15
0
		void DoNamedArgsCompletion(XamlCompletionItemList list, XamlCompletionContext context, IType type, MarkupExtensionInfo markup)
		{
			if (markup.NamedArguments.Count > 0 && !context.Editor.GetWordBeforeCaret().StartsWith(",", StringComparison.OrdinalIgnoreCase)) {
				int lastStart = markup.NamedArguments.Max(i => i.Value.StartOffset);
				var item = markup.NamedArguments.First(p => p.Value.StartOffset == lastStart);
				
				if (context.RawAttributeValue.EndsWith("=", StringComparison.OrdinalIgnoreCase) ||
				    (item.Value.IsString && item.Value.StringValue.EndsWith(context.Editor.GetWordBeforeCaretExtended(), StringComparison.Ordinal))) {
					var resolver = new XamlResolver(compilation);
					MemberResolveResult mrr = resolver.ResolveAttributeValue(item.Key, context) as MemberResolveResult;
					if (mrr != null && mrr.Member != null && mrr.Member.ReturnType != null) {
						IType memberType = mrr.Member.ReturnType;
						list.Items.AddRange(MemberCompletion(context, memberType, string.Empty));
					}
					return;
				}
			}
			
			list.Items.AddRange(type.GetProperties().Where(p => p.CanSet && p.IsPublic).Select(p => new XamlCompletionItem(p.Name + "=", p)));
		}
コード例 #16
0
		public ICompletionItemList CreateMarkupExtensionCompletion(XamlCompletionContext context)
		{
			var list = new XamlCompletionItemList(context);
			compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
			string visibleValue = context.RawAttributeValue.Substring(0, Utils.MinMax(context.ValueStartOffset, 0, context.RawAttributeValue.Length));
			if (context.PressedKey == '=')
				visibleValue += "=";
			var markup = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
			var resolver = new XamlResolver(compilation);
			var type = resolver.ResolveExpression(markup.ExtensionType, context).Type;
			if (type.Kind == TypeKind.Unknown)
				type = resolver.ResolveExpression(markup.ExtensionType + "Extension", context).Type;
			
			if (type.Kind == TypeKind.Unknown) {
				list.Items.AddRange(CreateListOfMarkupExtensions(context));
				list.PreselectionLength = markup.ExtensionType.Length;
			} else {
				if (markup.NamedArguments.Count == 0) {
					if (DoPositionalArgsCompletion(list, context, markup, type))
						DoNamedArgsCompletion(list, context, type, markup);
				} else
					DoNamedArgsCompletion(list, context, type, markup);
			}
			
			list.SortItems();
			
			return list;
		}
コード例 #17
0
		public IEnumerable<IInsightItem> CreateMarkupExtensionInsight(XamlCompletionContext context)
		{
			var markup = Utils.GetMarkupExtensionAtPosition(context.AttributeValue.ExtensionValue, context.ValueStartOffset);
			var resolver = new XamlResolver(compilation);
			var type = (resolver.ResolveExpression(markup.ExtensionType, context) ?? resolver.ResolveExpression(markup.ExtensionType + "Extension", context)).Type;
			
			if (type != null) {
				var ctors = type
					.GetMethods(m => m.IsPublic && m.IsConstructor && m.Parameters.Count >= markup.PositionalArguments.Count)
					.OrderBy(m => m.Parameters.Count);
				
				foreach (var ctor in ctors)
					yield return new MarkupExtensionInsightItem(ctor);
			}
		}
コード例 #18
0
        public XamlCompletionItemList CreateListForContext(XamlCompletionContext context)
        {
            XamlCompletionItemList list = new XamlCompletionItemList(context);

            ITextEditor editor = context.Editor;

            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            XamlAstResolver resolver = new XamlAstResolver(compilation, context.ParseInformation);

            switch (context.Description)
            {
            case XamlContextDescription.None:
                if (context.Forced)
                {
                    list.Items.AddRange(standardElements);
                    list.Items.AddRange(CreateElementList(context, false));
                    AddClosingTagCompletion(context, list, resolver);
                }
                break;

            case XamlContextDescription.AtTag:
                if ((editor.Caret.Offset > 0 && editor.Document.GetCharAt(editor.Caret.Offset - 1) == '.') || context.PressedKey == '.')
                {
                    list.Items.AddRange(CreateAttributeList(context, false));
                }
                else
                {
                    list.Items.AddRange(standardElements);
                    list.Items.AddRange(CreateElementList(context, false));
                    AddClosingTagCompletion(context, list, resolver);
                }
                break;

            case XamlContextDescription.InTag:
                string word = editor.GetWordBeforeCaretExtended();

                if (context.PressedKey == '.' || word.Contains("."))
                {
                    int pos = word.IndexOf(':');

                    string element       = word.Substring(pos + 1, word.Length - pos - 1);
                    string className     = word;
                    int    propertyStart = element.IndexOf('.');
                    if (propertyStart != -1)
                    {
                        element   = element.Substring(0, propertyStart).TrimEnd('.');
                        className = className.Substring(0, propertyStart + pos + 1).TrimEnd('.');
                    }

                    int          caretOffset = editor.Caret.Offset;
                    int          offset      = editor.Document.LastIndexOf(className, caretOffset - word.Length, word.Length, StringComparison.OrdinalIgnoreCase);
                    TextLocation loc         = editor.Document.GetLocation(offset);

                    XamlFullParseInformation info         = context.ParseInformation;
                    XamlResolver             nameResolver = new XamlResolver(compilation);
                    TypeResolveResult        trr          = nameResolver.ResolveExpression(className, context) as TypeResolveResult;
                    ITypeDefinition          typeClass    = trr != null?trr.Type.GetDefinition() : null;

                    if (typeClass != null && typeClass.HasAttached(true, true))
                    {
                        list.Items.AddRange(GetListOfAttached(context, typeClass, true, true));
                    }
                }
                else
                {
                    list.Items.AddRange(CreateAttributeList(context, true));
                    list.Items.AddRange(standardAttributes);
                }
                break;

            case XamlContextDescription.InAttributeValue:
                new XamlCodeCompletionBinding().CtrlSpace(editor);
                break;
            }

            list.SortItems();

            return(list);
        }
コード例 #19
0
		public IList<ICompletionItem> CreateElementList(XamlCompletionContext context, bool includeAbstract)
		{
			if (context.ParseInformation == null)
				return EmptyList<ICompletionItem>.Instance;
			
			List<ICompletionItem> result = new List<ICompletionItem>();
			AXmlElement last = context.ParentElement;
			ITextEditor editor = context.Editor;
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			IUnresolvedFile file = context.ParseInformation.UnresolvedFile;
			
			foreach (string item in XamlConst.GetAllowedItems(context)) {
				result.Add(new XamlCompletionItem(item));
			}
			
			IType rt = null;

			if (last != null) {
				if (string.Equals(last.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase)) {
					if (string.Equals(last.LocalName, "Members", StringComparison.OrdinalIgnoreCase))
						return result;
					if (string.Equals(last.LocalName, "Code", StringComparison.OrdinalIgnoreCase))
						return result;
				}
				// If we have an element that is not a property or an incomplete
				// definition => interpret element as a type.
				XamlResolver resolver = new XamlResolver(compilation);
				int dotIndex = last.LocalName.IndexOf(".", StringComparison.Ordinal) + 1;
				if (dotIndex < 1 || dotIndex == last.LocalName.Length) {
					rt = resolver.ResolveType(last.Namespace, last.LocalName.Trim('.'));
					string contentPropertyName = GetContentPropertyName(rt.GetDefinition());
					// If the type has a content property specified, use its type for completion.
					if (!string.IsNullOrEmpty(contentPropertyName)) {
						IProperty p = rt.GetProperties(m => m.Name == contentPropertyName).FirstOrDefault();
						if (p != null) {
							rt = p.ReturnType;
						}
					}
				} else {
					string typeName = last.LocalName.Substring(0, dotIndex - 1);
					string memberName = last.LocalName.Substring(dotIndex);
					rt = resolver.ResolveType(last.Namespace, typeName);
					IMember member = rt.GetMembers(m => m.Name == memberName).FirstOrDefault();
					if (member != null) {
						rt = member.ReturnType;
					}
				}
			}
			
			bool parentAdded = false;
			var utd = file.GetInnermostTypeDefinition(editor.Caret.Location);
			ITypeDefinition currentTypeDef = null;
			if (utd != null) {
				currentTypeDef = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
			}
			MemberLookup memberLookup = new MemberLookup(currentTypeDef, compilation.MainAssembly);
			
			IList<ITypeDefinition> possibleTypesInCollection = EmptyList<ITypeDefinition>.Instance;
			if (rt != null && Extensions.IsListType(rt)) {
				possibleTypesInCollection = rt.GetMethods(m => m.Parameters.Count == 1 && "Add".Equals(m.Name, StringComparison.Ordinal))
					.Select(m => m.Parameters[0].Type.GetDefinition())
					.Where(t => t != null)
					.ToList();
			}
			
			var items = GetClassesFromContext(context);
			
			foreach (var ns in items) {
				foreach (ITypeDefinition td in ns.Value) {
					if (td.Kind != TypeKind.Class && (!includeAbstract || td.Kind != TypeKind.Interface))
						continue;
					if (td.IsStatic || (!includeAbstract && td.IsAbstract) || td.IsDerivedFrom(KnownTypeCode.Attribute))
						continue;
					if (td.Kind == TypeKind.Class && !td.GetConstructors().Any(m => memberLookup.IsAccessible(m, false)))
						continue;
					if (possibleTypesInCollection.Count > 0 && !possibleTypesInCollection.Any(td.IsDerivedFrom))
						continue;
					string fullName = td.Name;
					if (!string.IsNullOrEmpty(ns.Key))
						fullName = ns.Key + ":" + fullName;
					XamlCompletionItem item = new XamlCompletionItem(fullName, td);
					parentAdded = parentAdded || (last != null && item.Text == last.Name);
					result.Add(item);
				}
			}
			
			// TODO reimplement this if it is really necessary.
//			if (!parentAdded && last != null && !last.Name.Contains(".")) {
//				IClass itemClass = cu.CreateType(last.Namespace, last.LocalName.Trim('.')).GetUnderlyingClass();
//				if (itemClass != null)
//					result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix));
//			}
			
			return result;
		}
コード例 #20
0
        static void DoSetterAndEventSetterCompletion(XamlCompletionContext context, XamlCompletionItemList completionList)
        {
            bool           isExplicit;
            string         element = context.ParentElement.Name.EndsWith("Trigger") ? "Trigger" : context.ParentElement.Name;
            AttributeValue value   = MarkupExtensionParser.ParseValue(CompletionDataHelper.LookForTargetTypeValue(context, out isExplicit, element) ?? string.Empty);

            IReturnType typeName       = null;
            string      typeNameString = null;

            if (!value.IsString)
            {
                typeNameString = CompletionDataHelper.GetTypeNameFromTypeExtension(value.ExtensionValue, context);
                typeName       = CompletionDataHelper.ResolveType(typeNameString, context);
            }
            else
            {
                typeNameString = value.StringValue;
                typeName       = CompletionDataHelper.ResolveType(value.StringValue, context);
            }

            if (typeName != null)
            {
                switch (context.Attribute.Name)
                {
                case "Value":
                    AttributeValue propType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Property") ?? "");

                    if (!propType.IsString)
                    {
                        break;
                    }

                    context.Description = XamlContextDescription.AtTag;

                    string name = propType.StringValue;

                    if (!name.Contains("."))
                    {
                        name = typeNameString + "." + name;
                    }

                    var member = XamlResolver.Resolve(name, context) as MemberResolveResult;

                    if (member == null || member.ResolvedMember == null)
                    {
                        break;
                    }

                    completionList.Items.AddRange(
                        CompletionDataHelper.MemberCompletion(context, member.ResolvedMember.ReturnType, string.Empty)
                        );
                    break;

                case "Property":
                    completionList.Items.AddRange(
                        typeName.GetProperties()
                        .Where(p => p.IsPublic && p.CanSet)
                        .Select(prop => new XamlCodeCompletionItem(prop))
                        );
                    break;

                case "Event":
                    completionList.Items.AddRange(
                        typeName.GetEvents()
                        .Where(e => e.IsPublic)
                        .Select(evt => new XamlCodeCompletionItem(evt))
                        );
                    break;

                case "Handler":
                    var            loc3    = context.Editor.Document.OffsetToPosition(XmlParser.GetActiveElementStartIndex(context.Editor.Document.Text, context.Editor.Caret.Offset));
                    AttributeValue evtType = MarkupExtensionParser.ParseValue(context.ActiveElement.GetAttributeValue("Event") ?? "");
                    if (!evtType.IsString)
                    {
                        break;
                    }

                    string evtName = evtType.StringValue;

                    if (!evtName.Contains("."))
                    {
                        evtName = typeNameString + "." + evtName;
                    }

                    var evtMember = XamlResolver.Resolve(evtName, context) as MemberResolveResult;

                    if (evtMember == null || evtMember.ResolvedMember == null || !(evtMember.ResolvedMember is IEvent) || evtMember.ResolvedMember.ReturnType == null)
                    {
                        break;
                    }

                    IClass c = (evtMember.ResolvedMember as IEvent).ReturnType.GetUnderlyingClass();

                    if (c == null)
                    {
                        break;
                    }

                    IMethod invoker = c.Methods.FirstOrDefault(m => m.Name == "Invoke");

                    if (invoker == null)
                    {
                        break;
                    }

                    completionList.Items.AddRange(
                        CompletionDataHelper.AddMatchingEventHandlers(context, invoker).Add(new NewEventCompletionItem(evtMember.ResolvedMember as IEvent, typeName.Name))
                        );
                    break;
                }
            }
        }
コード例 #21
0
        public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
        {
            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            resolver    = new XamlResolver(compilation);

            XamlCompletionContext  context = XamlContextResolver.ResolveCompletionContext(editor, ch);
            XamlCompletionItemList list;

            if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
            {
                return(CodeCompletionKeyPressResult.None);
            }

            switch (ch)
            {
            case '<':
                context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description;
                list = generator.CreateListForContext(context);
                editor.ShowCompletionWindow(list);
                return(CodeCompletionKeyPressResult.Completed);

            case '>':
                return(CodeCompletionKeyPressResult.None);

            case '\'':
            case '"':
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset))
                {
                    // count all " or ' chars before the next > char
                    int  search         = editor.Caret.Offset + 1;
                    int  endMarkerCount = 1;
                    char curCh          = editor.Document.GetCharAt(search);
                    while (search < editor.Document.TextLength - 1 && curCh != '>')
                    {
                        if (curCh == ch)
                        {
                            endMarkerCount++;
                        }
                        search++;
                        curCh = editor.Document.GetCharAt(search);
                    }
                    // if the count is odd we need to add an additional " or ' char
                    if (endMarkerCount % 2 != 0)
                    {
                        editor.Document.Insert(editor.Caret.Offset, ch.ToString());
                        editor.Caret.Offset--;
                        CtrlSpace(editor);
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                }
                break;

            case '{':                     // starting point for Markup Extension Completion
                if (context.Attribute != null &&
                    XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) &&
                    !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2))
                {
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    editor.Document.Insert(editor.Caret.Offset, "{}");
                    editor.Caret.Offset--;

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case '.':
                switch (context.Description)
                {
                case XamlContextDescription.AtTag:
                case XamlContextDescription.InTag:
                    if (context.ActiveElement != null)
                    {
                        list = generator.CreateListForContext(context);
                        editor.ShowCompletionWindow(list);
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                    break;

                case XamlContextDescription.InMarkupExtension:
                    if (DoMarkupExtensionCompletion(context))
                    {
                        return(CodeCompletionKeyPressResult.Completed);
                    }
                    break;

                case XamlContextDescription.InAttributeValue:
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    editor.Document.Insert(editor.Caret.Offset, ".");

                    this.CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case '(':
            case '[':
                if (context.Description == XamlContextDescription.InAttributeValue)
                {
                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    if (ch == '(')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "()");
                    }
                    if (ch == '[')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "[]");
                    }
                    editor.Caret.Offset--;

                    CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                break;

            case ':':
                if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null)
                {
                    if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase))
                    {
                        list = generator.CreateListForContext(context);
                        list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
                        editor.ShowCompletionWindow(list);
                        return(CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion);
                    }
                }
                break;

            case '/':                     // ignore '/' when trying to type '/>'
                return(CodeCompletionKeyPressResult.None);

            case '=':
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset))
                {
                    int searchOffset = editor.Caret.Offset;

                    if (editor.SelectionLength != 0)
                    {
                        editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
                    }

                    while (searchOffset < editor.Document.TextLength - 1)
                    {
                        searchOffset++;
                        if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
                        {
                            break;
                        }
                    }

                    if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"')
                    {
                        editor.Document.Insert(editor.Caret.Offset, "=\"\"");
                        editor.Caret.Offset--;
                    }
                    else
                    {
                        editor.Document.Insert(editor.Caret.Offset, "=");
                        editor.Caret.Offset++;
                    }

                    CtrlSpace(editor);
                    return(CodeCompletionKeyPressResult.EatKey);
                }
                else
                {
                    DoMarkupExtensionCompletion(context);
                    return(CodeCompletionKeyPressResult.Completed);
                }

            default:
                if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch))
                {
                    string starter = editor.GetWordBeforeCaretExtended();
                    if (!string.IsNullOrEmpty(starter))
                    {
                        return(CodeCompletionKeyPressResult.None);
                    }
                    string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty;

                    if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase))
                    {
                        return(CtrlSpace(editor, context)
                                                                ? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion
                                                                : CodeCompletionKeyPressResult.None);
                    }
                    return(CodeCompletionKeyPressResult.None);
                }
                break;
            }

            return(CodeCompletionKeyPressResult.None);
        }
コード例 #22
0
        public bool CtrlSpace(ITextEditor editor)
        {
            XamlCompletionContext context = CompletionDataHelper.ResolveCompletionContext(editor, ' ');

            context.Forced = trackForced;

            if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
            {
                return(false);
            }

            if (context.ActiveElement != null)
            {
                if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset) && context.Description != XamlContextDescription.InAttributeValue)
                {
                    XamlCompletionItemList list = CompletionDataHelper.CreateListForContext(context);
                    string starter = editor.GetWordBeforeCaretExtended().TrimStart('/');
                    if (context.Description != XamlContextDescription.None && !string.IsNullOrEmpty(starter))
                    {
                        if (starter.Contains("."))
                        {
                            list.PreselectionLength = starter.Length - starter.IndexOf('.') - 1;
                        }
                        else
                        {
                            list.PreselectionLength = starter.Length;
                        }
                    }
                    editor.ShowCompletionWindow(list);
                    return(true);
                }
                else
                {
                    // DO NOT USE CompletionDataHelper.CreateListForContext here!!! results in endless recursion!!!!
                    if (context.Attribute != null)
                    {
                        if (!DoMarkupExtensionCompletion(context))
                        {
                            var completionList = new XamlCompletionItemList(context);
                            completionList.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;

                            if ((context.ActiveElement.Name == "Setter" || context.ActiveElement.Name == "EventSetter") &&
                                (context.Attribute.Name == "Property" || context.Attribute.Name == "Value"))
                            {
                                DoSetterAndEventSetterCompletion(context, completionList);
                            }
                            else if ((context.ActiveElement.Name.EndsWith("Trigger") || context.ActiveElement.Name == "Condition") && context.Attribute.Name == "Value")
                            {
                                DoTriggerCompletion(context, completionList);
                            }
                            else
                            {
                                if (context.Attribute.Name == "xml:space")
                                {
                                    completionList.Items.AddRange(new[] { new SpecialCompletionItem("preserve"),
                                                                          new SpecialCompletionItem("default") });
                                }

                                var mrr = XamlResolver.Resolve(context.Attribute.Name, context) as MemberResolveResult;
                                if (mrr != null && mrr.ResolvedType != null)
                                {
                                    completionList.Items.AddRange(CompletionDataHelper.MemberCompletion(context, mrr.ResolvedType, string.Empty));
                                    editor.ShowInsightWindow(CompletionDataHelper.MemberInsight(mrr));
                                    if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.PropertyPath")
                                    {
                                        string start = editor.GetWordBeforeCaretExtended();
                                        int    index = start.LastIndexOfAny(PropertyPathTokenizer.ControlChars);
                                        if (index + 1 < start.Length)
                                        {
                                            start = start.Substring(index + 1);
                                        }
                                        else
                                        {
                                            start = "";
                                        }
                                        completionList.PreselectionLength = start.Length;
                                    }
                                    else if (mrr.ResolvedType.FullyQualifiedName == "System.Windows.Media.FontFamily")
                                    {
                                        string text      = context.ValueStartOffset > -1 ? context.RawAttributeValue.Substring(0, Math.Min(context.ValueStartOffset, context.RawAttributeValue.Length)) : "";
                                        int    lastComma = text.LastIndexOf(',');
                                        completionList.PreselectionLength = lastComma == -1 ? context.ValueStartOffset : context.ValueStartOffset - lastComma - 1;
                                    }
                                }
                            }

                            completionList.SortItems();

                            if (context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
                                context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase))
                            {
                                completionList.Items.AddRange(CompletionDataHelper.CreateListForXmlnsCompletion(context.ProjectContent));
                            }

                            ICompletionListWindow window = editor.ShowCompletionWindow(completionList);

                            if ((context.Attribute.Prefix.Equals("xmlns", StringComparison.OrdinalIgnoreCase) ||
                                 context.Attribute.Name.Equals("xmlns", StringComparison.OrdinalIgnoreCase)) && window != null)
                            {
                                window.Width = 400;
                            }

                            return(completionList.Items.Any());
                        }
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #23
0
		public static MemberResolveResult ResolveMember(string expression, XamlCompletionContext context)
		{
			if (context.ParseInformation == null || string.IsNullOrEmpty(context.Editor.Document.Text))
				return null;
			
			var expressionResult = new ExpressionResult(expression, context);
			
			XamlResolver resolver = new XamlResolver();
			resolver.resolveExpression = expression;
			resolver.caretLine = expressionResult.Region.BeginLine;
			resolver.caretColumn = expressionResult.Region.BeginColumn;
			resolver.callingClass = context.ParseInformation.CompilationUnit.GetInnermostClass(resolver.caretLine, resolver.caretColumn);
			resolver.context = context;
			
			return resolver.ResolveNamedAttribute(expression);
		}
コード例 #24
0
        public IList <ICompletionItem> CreateElementList(XamlCompletionContext context, bool includeAbstract)
        {
            if (context.ParseInformation == null)
            {
                return(EmptyList <ICompletionItem> .Instance);
            }

            List <ICompletionItem> result = new List <ICompletionItem>();
            AXmlElement            last   = context.ParentElement;
            ITextEditor            editor = context.Editor;

            compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
            IUnresolvedFile file = context.ParseInformation.UnresolvedFile;

            foreach (string item in XamlConst.GetAllowedItems(context))
            {
                result.Add(new XamlCompletionItem(item));
            }

            IType rt = null;

            if (last != null)
            {
                if (string.Equals(last.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    if (string.Equals(last.LocalName, "Members", StringComparison.OrdinalIgnoreCase))
                    {
                        return(result);
                    }
                    if (string.Equals(last.LocalName, "Code", StringComparison.OrdinalIgnoreCase))
                    {
                        return(result);
                    }
                }
                // If we have an element that is not a property or an incomplete
                // definition => interpret element as a type.
                XamlResolver resolver = new XamlResolver(compilation);
                int          dotIndex = last.LocalName.IndexOf(".", StringComparison.Ordinal) + 1;
                if (dotIndex < 1 || dotIndex == last.LocalName.Length)
                {
                    rt = resolver.ResolveType(last.Namespace, last.LocalName.Trim('.'));
                    string contentPropertyName = GetContentPropertyName(rt.GetDefinition());
                    // If the type has a content property specified, use its type for completion.
                    if (!string.IsNullOrEmpty(contentPropertyName))
                    {
                        IProperty p = rt.GetProperties(m => m.Name == contentPropertyName).FirstOrDefault();
                        if (p != null)
                        {
                            rt = p.ReturnType;
                        }
                    }
                }
                else
                {
                    string typeName   = last.LocalName.Substring(0, dotIndex - 1);
                    string memberName = last.LocalName.Substring(dotIndex);
                    rt = resolver.ResolveType(last.Namespace, typeName);
                    IMember member = rt.GetMembers(m => m.Name == memberName).FirstOrDefault();
                    if (member != null)
                    {
                        rt = member.ReturnType;
                    }
                }
            }

            bool            parentAdded    = false;
            var             utd            = file.GetInnermostTypeDefinition(editor.Caret.Location);
            ITypeDefinition currentTypeDef = null;

            if (utd != null)
            {
                currentTypeDef = utd.Resolve(new SimpleTypeResolveContext(compilation.MainAssembly)).GetDefinition();
            }
            MemberLookup memberLookup = new MemberLookup(currentTypeDef, compilation.MainAssembly);

            IList <ITypeDefinition> possibleTypesInCollection = EmptyList <ITypeDefinition> .Instance;

            if (rt != null && Extensions.IsListType(rt))
            {
                possibleTypesInCollection = rt.GetMethods(m => m.Parameters.Count == 1 && "Add".Equals(m.Name, StringComparison.Ordinal))
                                            .Select(m => m.Parameters[0].Type.GetDefinition())
                                            .Where(t => t != null)
                                            .ToList();
            }

            var items = GetClassesFromContext(context);

            foreach (var ns in items)
            {
                foreach (ITypeDefinition td in ns.Value)
                {
                    if (td.Kind != TypeKind.Class && (!includeAbstract || td.Kind != TypeKind.Interface))
                    {
                        continue;
                    }
                    if (td.IsStatic || (!includeAbstract && td.IsAbstract) || td.IsDerivedFrom(KnownTypeCode.Attribute))
                    {
                        continue;
                    }
                    if (td.Kind == TypeKind.Class && !td.GetConstructors().Any(m => memberLookup.IsAccessible(m, false)))
                    {
                        continue;
                    }
                    if (possibleTypesInCollection.Count > 0 && !possibleTypesInCollection.Any(td.IsDerivedFrom))
                    {
                        continue;
                    }
                    string fullName = td.Name;
                    if (!string.IsNullOrEmpty(ns.Key))
                    {
                        fullName = ns.Key + ":" + fullName;
                    }
                    XamlCompletionItem item = new XamlCompletionItem(fullName, td);
                    parentAdded = parentAdded || (last != null && item.Text == last.Name);
                    result.Add(item);
                }
            }

            // TODO reimplement this if it is really necessary.
//			if (!parentAdded && last != null && !last.Name.Contains(".")) {
//				IClass itemClass = cu.CreateType(last.Namespace, last.LocalName.Trim('.')).GetUnderlyingClass();
//				if (itemClass != null)
//					result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix));
//			}

            return(result);
        }
コード例 #25
0
		public bool CtrlSpace(ITextEditor editor)
		{
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			resolver = new XamlResolver(compilation);
			
			XamlCompletionContext context = XamlContextResolver.ResolveCompletionContext(editor, ' ');
			context.Forced = true;
			return CtrlSpace(editor, context);
		}
コード例 #26
0
		public CodeCompletionKeyPressResult HandleKeyPress(ITextEditor editor, char ch)
		{
			compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
			resolver = new XamlResolver(compilation);
			
			XamlCompletionContext context = XamlContextResolver.ResolveCompletionContext(editor, ch);
			XamlCompletionItemList list;
			
			if (context.Description == XamlContextDescription.InComment || context.Description == XamlContextDescription.InCData)
				return CodeCompletionKeyPressResult.None;
			
			switch (ch) {
				case '<':
					context.Description = (context.Description == XamlContextDescription.None) ? XamlContextDescription.AtTag : context.Description;
					list = generator.CreateListForContext(context);
					editor.ShowCompletionWindow(list);
					return CodeCompletionKeyPressResult.Completed;
				case '>':
					return CodeCompletionKeyPressResult.None;
				case '\'':
				case '"':
					if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
						// count all " or ' chars before the next > char
						int search = editor.Caret.Offset + 1;
						int endMarkerCount = 1;
						char curCh = editor.Document.GetCharAt(search);
						while (search < editor.Document.TextLength - 1 && curCh != '>') {
							if (curCh == ch)
								endMarkerCount++;
							search++;
							curCh = editor.Document.GetCharAt(search);
						}
						// if the count is odd we need to add an additional " or ' char
						if (endMarkerCount % 2 != 0) {
							editor.Document.Insert(editor.Caret.Offset, ch.ToString());
							editor.Caret.Offset--;
							CtrlSpace(editor);
							return CodeCompletionKeyPressResult.Completed;
						}
					}
					break;
				case '{': // starting point for Markup Extension Completion
					if (context.Attribute != null
					    && XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)
					    && !(context.RawAttributeValue.StartsWith("{}", StringComparison.OrdinalIgnoreCase) && context.RawAttributeValue.Length != 2)) {
						
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						editor.Document.Insert(editor.Caret.Offset, "{}");
						editor.Caret.Offset--;
						
						this.CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case '.':
					switch (context.Description) {
						case XamlContextDescription.AtTag:
						case XamlContextDescription.InTag:
							if (context.ActiveElement != null) {
								list = generator.CreateListForContext(context);
								editor.ShowCompletionWindow(list);
								return CodeCompletionKeyPressResult.Completed;
							}
							break;
						case XamlContextDescription.InMarkupExtension:
							if (DoMarkupExtensionCompletion(context))
								return CodeCompletionKeyPressResult.Completed;
							break;
						case XamlContextDescription.InAttributeValue:
							if (editor.SelectionLength != 0)
								editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
							
							editor.Document.Insert(editor.Caret.Offset, ".");
							
							this.CtrlSpace(editor);
							return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case '(':
				case '[':
					if (context.Description == XamlContextDescription.InAttributeValue) {
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						if (ch == '(')
							editor.Document.Insert(editor.Caret.Offset, "()");
						if (ch == '[')
							editor.Document.Insert(editor.Caret.Offset, "[]");
						editor.Caret.Offset--;
						
						CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					}
					break;
				case ':':
					if (context.ActiveElement != null && XmlParser.GetQualifiedAttributeNameAtIndex(editor.Document.Text, editor.Caret.Offset) == null) {
						if (context.Attribute != null && !context.Attribute.Name.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) {
							list = generator.CreateListForContext(context);
							list.PreselectionLength = editor.GetWordBeforeCaretExtended().Length;
							editor.ShowCompletionWindow(list);
							return CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion;
						}
					}
					break;
				case '/': // ignore '/' when trying to type '/>'
					return CodeCompletionKeyPressResult.None;
				case '=':
					if (!XmlParser.IsInsideAttributeValue(editor.Document.Text, editor.Caret.Offset)) {
						int searchOffset = editor.Caret.Offset;
						
						if (editor.SelectionLength != 0)
							editor.Document.Remove(editor.SelectionStart, editor.SelectionLength);
						
						while (searchOffset < editor.Document.TextLength - 1) {
							searchOffset++;
							if (!char.IsWhiteSpace(editor.Document.GetCharAt(searchOffset)))
								break;
						}
						
						if (searchOffset >= editor.Document.TextLength || editor.Document.GetCharAt(searchOffset) != '"') {
							editor.Document.Insert(editor.Caret.Offset, "=\"\"");
							editor.Caret.Offset--;
						} else {
							editor.Document.Insert(editor.Caret.Offset, "=");
							editor.Caret.Offset++;
						}
						
						CtrlSpace(editor);
						return CodeCompletionKeyPressResult.EatKey;
					} else {
						DoMarkupExtensionCompletion(context);
						return CodeCompletionKeyPressResult.Completed;
					}
				default:
					if (context.Description != XamlContextDescription.None && !char.IsWhiteSpace(ch)) {
						string starter = editor.GetWordBeforeCaretExtended();
						if (!string.IsNullOrEmpty(starter))
							return CodeCompletionKeyPressResult.None;
						string attributeName = (context.Attribute != null) ? context.Attribute.Name : string.Empty;
						
						if (!attributeName.StartsWith("xmlns", StringComparison.OrdinalIgnoreCase)) {
							return CtrlSpace(editor, context)
								? CodeCompletionKeyPressResult.CompletedIncludeKeyInCompletion
								: CodeCompletionKeyPressResult.None;
						}
						return CodeCompletionKeyPressResult.None;
					}
					break;
			}
			
			return CodeCompletionKeyPressResult.None;
		}
コード例 #27
0
		IList<ICompletionItem> CreateAttributeList(XamlCompletionContext context, bool includeEvents)
		{
			if (context.ParseInformation == null)
				return EmptyList<ICompletionItem>.Instance;
			AXmlElement lastElement = context.ActiveElement;
			IUnresolvedFile file = context.ParseInformation.UnresolvedFile;
			XamlResolver resolver = new XamlResolver(compilation);
			IType type = resolver.ResolveType(lastElement.Namespace, lastElement.LocalName.Trim('.'));
			
			var list = new List<ICompletionItem>();
			
			string xamlPrefix = context.XamlNamespacePrefix;
			string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":";
			
			if (context.Description == XamlContextDescription.InTag)
				list.AddRange(XamlConst.GetAllowedItems(context).Select(item => new XamlCompletionItem(item)));
			
			if (string.Equals(lastElement.Prefix, context.XamlNamespacePrefix, StringComparison.OrdinalIgnoreCase) && XamlConst.IsBuiltin(lastElement.LocalName))
				return list;
			
			if (lastElement.LocalName.EndsWith(".", StringComparison.OrdinalIgnoreCase) || context.PressedKey == '.') {
				if (type.Kind == TypeKind.Unknown)
					return EmptyList<ICompletionItem>.Instance;
				
				if (context.ParentElement != null
				    && context.ParentElement.LocalName.StartsWith(lastElement.LocalName.TrimEnd('.'), StringComparison.OrdinalIgnoreCase)) {
					AddAttributes(type, list, includeEvents);
				}
				AddAttachedProperties(type.GetDefinition(), list);
			} else {
				if (type.Kind != TypeKind.Unknown) {
					AddAttributes(type, list, includeEvents);
					list.AddRange(GetListOfAttached(context, null, includeEvents, true));
				}
			}
			
			return list;
		}