void AddMember (XElement element)
		{
			string id;
			if (element.IsRunatServer () && !string.IsNullOrEmpty (id = element.GetId ())) {
				
				if (Members.ContainsKey (id)) {
					Errors.Add (new Error (
						ErrorType.Error,
						GettextCatalog.GetString ("Tag ID must be unique within the document: '{0}'.", id),
						element.Region
					)
					);
				} else {
					string controlType = element.Attributes.GetValue (new XName ("type"), true);
					var type = docRefMan.GetType (element.Name.Prefix, element.Name.Name, controlType);
	
					if (type == null) {
						Errors.Add (
							new Error (
								ErrorType.Error,
								GettextCatalog.GetString ("The tag type '{0}{1}{2}' has not been registered.", 
						                          element.Name.Prefix, 
						                          element.Name.HasPrefix ? string.Empty : ":", 
						                          element.Name.Name),
								element.Region
							)
						);
					} else
						Members [id] = new CodeBehindMember (id, type, element.Region.Begin);
				}

			}
			foreach (XElement child in element.Nodes.OfType<XElement> ())
				AddMember (child);
		}
		public XmlMultipleClosingTagCompletionData (XElement finalEl, XElement[] intermediateElements)
		{
			name = finalEl.Name.FullName;
			description = GettextCatalog.GetString ("Closing tag for '{0}', also closing all intermediate tags", name);
			name = string.Format ("/{0}>...", name);
			this.intEls = intermediateElements;
			this.finalEl = finalEl;
		}
		static string GetTypeAttributeValue (XElement el)
		{
			var typeAtt = el.Attributes.Get (new XName ("type"), true);
			if (typeAtt == null || string.IsNullOrEmpty (typeAtt.Value)) {
				return null;
			}
			return typeAtt.Value;
		}
		public override SchemaElement GetChild (XElement element)
		{
			var node = info.GetAllowedNodeTypes ().FirstOrDefault (n => n.NodeName == element.Name.FullName);
			if (node != null) {
				return new ExtensionNodeElement (proj, extensionPoint, node);
			}

			return null;
		}
		public virtual void GetElementCompletions (CompletionDataList list, XElement element)
		{
			if (children == null) {
				return;
			}

			foreach (var c in children) {
				list.Add (c.Key, null, c.Value.Description);
			}
		}
		public RazorOutlineNode (XElement el)
		{
			Name = el.Name.FullName;
			string id = el.GetId ();
			if (!string.IsNullOrEmpty (id))
				Name = "<" + Name + "#" + id + ">";
			else
				Name = "<" + Name + ">";

			Location = el.Region;
		}
		protected SchemaElement GetSchemaItem (IEnumerable<XObject> path, out XElement el)
		{
			el = null;
			SchemaElement item = schema;
			foreach (var val in path) {
				el = val as XElement;
				if (el == null)
					break;
				item = item.GetChild (el);
			}
			return item;
		}
		public override void GetElementCompletions (CompletionDataList list, XElement element)
		{
			var type = GetTypeAttributeValue (element);

			if (type == "StringTable") {
				list.Add (localeItem.Name, null, localeItem.Description);
			}
		}
		public virtual SchemaElement GetChild (XElement element)
		{
			SchemaElement child;
			if (children != null && children.TryGetValue (element.Name.FullName, out child)) {
				return child;
			}
			return null;
		}
		public override void GetElementCompletions (CompletionDataList list, XElement element)
		{
			foreach (ExtensionNodeType n in info.GetAllowedNodeTypes ()) {
				list.Add (n.NodeName, null, n.Description);
			}
		}
		ExtensionPoint GetExtensionPoint (XElement element)
		{
			if (element == null) {
				return null;
			}

			var pathAtt = element.Attributes.Get (new XName ("path"), true);
			if (pathAtt == null || pathAtt.Value == null) {
				return null;
			}

			return GetExtensionPoint (pathAtt.Value);
		}
Beispiel #12
0
		public override bool KeyPress(Gdk.Key key, char keyChar, Gdk.ModifierType modifier)
		{
			var buffer = EditableBuffer;
			if (CompletionWindowManager.IsVisible)
			{
				// do some things to minimize keystrokes with code completion
				if (keyChar == '=')
				{
					// we're in an attribute completion, so automatically add the quote and show completions (if available)
					var ret = base.KeyPress(key, keyChar, modifier);
					if (!ret)
					{
						base.KeyPress((Gdk.Key)0, '"', Gdk.ModifierType.None);
						buffer.InsertText(buffer.CursorPosition, "\"");
						buffer.CursorPosition--;
					}
					return ret;
				}
				if (key == Gdk.Key.Return 
					&& modifier == Gdk.ModifierType.None
					&& isParameterValueCompletion)
				{
					// finish completion
					base.KeyPress(key, keyChar, modifier);
					// if double quote already exists, skip it!
					if (buffer.GetCharAt(buffer.CursorPosition) == '"')
					{
						buffer.CursorPosition++;
						return false;
					}
					// no double quote yet, so add it
					return base.KeyPress((Gdk.Key)0, '"', Gdk.ModifierType.None);
				}
				if (keyChar == '"' || keyChar == '\'')
				{
					// finish completion with double quote
					base.KeyPress(Gdk.Key.Return, '\0', Gdk.ModifierType.None);
					// if double quote already exists, skip it!
					if (buffer.GetCharAt(buffer.CursorPosition) == keyChar)
					{
						buffer.CursorPosition++;
						return false;
					}
					return base.KeyPress(key, keyChar, modifier);
				}
			}
			if (keyChar == '>')
			{
				// finish completion first
				if (CompletionWindowManager.IsVisible)
					base.KeyPress(Gdk.Key.Return, '\0', Gdk.ModifierType.None);

				// add self-closing tag if there is no content for the control
				if (!HasContentAtCurrentElement())
				{
					base.KeyPress((Gdk.Key)0, '/', Gdk.ModifierType.None);
					//buffer.InsertText(buffer.CursorPosition++, "/");
					return base.KeyPress(key, keyChar, modifier);
				}
			}
			if (keyChar == '"' || keyChar == '\'')
			{
				// if double quote already exists, skip it!
				if (buffer.GetCharAt(buffer.CursorPosition) == keyChar)
				{
					buffer.CursorPosition++;
					return false;
				}
			}
			if (keyChar == '.')
			{
				var result = base.KeyPress(key, keyChar, modifier);
				// provide completions for <Control.Property> elements
				var completionContext = CompletionWidget.CurrentCodeCompletionContext;
				var offset = completionContext.TriggerOffset - 1;
				var ch = CompletionWidget.GetChar(offset);
				while (ch != '\0' && (XmlConvert.IsNCNameChar(ch) || ch == ':') && offset > 0)
				{
					offset--;
					ch = CompletionWidget.GetChar(offset);
				}
				if (ch != '\0' && ch != '<')
					return result;
				offset++;
				var len = completionContext.TriggerOffset - offset;
				var name = Editor.GetTextAt(offset, len);
				try
				{
					XmlConvert.VerifyName(name);
				}
				catch (XmlException)
				{
					// not a valid xml name
					return result;
				}

				var xobject = Tracker.Engine.Nodes.Peek(1) as IAttributedXObject;
				if (xobject == null)
				{
					string prefix = null;
					var nsidx = name.IndexOf(':');
					if (nsidx > 0)
					{
						prefix = name.Substring(0, nsidx);
						name = name.Substring(nsidx + 1);
					}
					name = name.TrimEnd('.');
					xobject = new XElement(Tracker.Engine.Location, new XName(prefix, name));
				}
				
				var attributeDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				if (xobject.Attributes != null)
				{
					foreach (XAttribute current in xobject.Attributes)
					{
						attributeDictionary[current.Name.FullName] = current.Value ?? string.Empty;
					}
				}
				var completions = GetAttributeCompletions(xobject, attributeDictionary, XmlCompletionData.DataType.XmlElement, true);

				if (completions != null)
				{
					ShowCompletion(completions);
					return false;
				}
			}
			return base.KeyPress(key, keyChar, modifier);
		}
Beispiel #13
0
		protected virtual void Close (XElement element, IXmlParserContext context, TextLocation location)
		{
			//have already checked that element is not null, i.e. top of stack is our element
			if (element.IsClosed)
				context.Nodes.Pop ();

			element.End (location);
			if (context.BuildTree) {
				XContainer container = element.IsClosed? 
					  (XContainer) context.Nodes.Peek ()
					: (XContainer) context.Nodes.Peek (1);
										
				container.AddChildNode (element);
			}
		}
		protected SchemaElement GetSchemaItem (out XElement el)
		{
			return GetSchemaItem (GetCurrentPath (), out el);
		}
		public override SchemaElement GetChild (XElement element)
		{
			var ep = GetExtensionPoint (element.Parent as XElement);
			if (ep == null) {
				return null;
			}

			var node = ep.NodeSet.GetAllowedNodeTypes ().FirstOrDefault (n => n.NodeName == element.Name.FullName);
			if (node != null) {
				return new ExtensionNodeElement (project, ep, node);
			}

			return null;
		}
		public override void GetElementCompletions (CompletionDataList list, XElement element)
		{
			var ep = GetExtensionPoint (element);
			if (ep == null) {
				return;
			}

			foreach (ExtensionNodeType n in ep.NodeSet.GetAllowedNodeTypes ()) {
				list.Add (n.NodeName, null, n.Description);
			}
		}
		public override SchemaElement GetChild (XElement element)
		{
			var type = GetTypeAttributeValue (element);

			if (type == "StringTable") {
				if (element.Name.FullName == localeItem.Name) {
					return localeItem;
				}
			}

			return null;
		}
Beispiel #18
0
		public override XmlParserState PushChar (char c, IXmlParserContext context, ref string rollback)
		{
			XElement element = context.Nodes.Peek () as XElement;
			
			if (element == null || element.IsComplete) {
				element = new XElement (context.LocationMinus (2)); // 2 == < + current char
				context.Nodes.Push (element);
			}
			
			if (c == '<') {
				if (element.IsNamed) {
					context.LogError ("Unexpected '<' in tag '" + element.Name.FullName + "'.");
					Close (element, context, context.LocationMinus (1));
				} else {
					context.LogError ("Unexpected '<' in unnamed tag.");
				}
				
				rollback = string.Empty;
				return Parent;
			}
			
			Debug.Assert (!element.IsComplete);
			
			if (element.IsClosed && c != '>') {
				if (char.IsWhiteSpace (c)) {
					context.LogWarning ("Unexpected whitespace after '/' in self-closing tag.");
					return null;
				}
				context.LogError ("Unexpected character '" + c + "' after '/' in self-closing tag.");
				context.Nodes.Pop ();
				return Parent;
			}
			
			//if tag closed
			if (c == '>') {
				if (context.StateTag == MAYBE_SELF_CLOSING) {
					element.Close (element);
				}
				if (!element.IsNamed) {
					context.LogError ("Tag closed prematurely.");
				} else {
					Close (element, context, context.Location);
				}
				return Parent;
			}

			if (c == '/') {
				context.StateTag = MAYBE_SELF_CLOSING;
				return null;
			}

			if (context.StateTag == ATTEMPT_RECOVERY) {
				if (XmlChar.IsWhitespace (c)) {
					context.StateTag = RECOVERY_FOUND_WHITESPACE;
				}
				return null;
			}

			if (context.StateTag == RECOVERY_FOUND_WHITESPACE) {
				if (!XmlChar.IsFirstNameChar (c))
					return null;
			}

			context.StateTag = OK;

			if (!element.IsNamed && XmlChar.IsFirstNameChar (c)) {
				rollback = string.Empty;
				return NameState;
			}

			if (context.CurrentStateLength > 1 && XmlChar.IsFirstNameChar (c)) {
				rollback = string.Empty;
				return AttributeState;
			}
			
			if (XmlChar.IsWhitespace (c))
				return null;

			context.LogError ("Unexpected character '" + c + "' in tag.", context.LocationMinus (1));
			context.StateTag = ATTEMPT_RECOVERY;
			return null;
		}
		void Populate (XElement el, MSBuildElement parent)
		{
			if (el.Name.Prefix != null)
				return;

			var name = el.Name.Name;
			var msel = MSBuildElement.Get (name, parent);
			if (msel == null || !msel.IsSpecial) {
				foreach (var child in el.Nodes.OfType<XElement> ())
					Populate (child, msel);
				return;
			}

			switch (parent.ChildType) {
			case "Item":
				HashSet<string> item;
				if (!items.TryGetValue (name, out item))
					items [name] = item = new HashSet<string> ();
				foreach (var metadata in el.Nodes.OfType<XElement> ())
					if (!metadata.Name.HasPrefix)
						item.Add (metadata.Name.Name);
				break;
			case "Property":
				properties.Add (name);
				break;
			case "Import":
				var import = el.Attributes [xnProject];
				if (import != null && string.IsNullOrEmpty (import.Value))
					imports.Add (import.Value);
				break;
			case "Task":
				HashSet<string> task;
				if (!tasks.TryGetValue (name, out task))
					tasks [name] = task = new HashSet<string> ();
				foreach (var att in el.Attributes)
					if (!att.Name.HasPrefix)
						task.Add (att.Name.Name);
				break;
			case "Parameter":
				//TODO: Parameters
				break;
			}
		}
Beispiel #20
0
		public override bool KeyPress(KeyDescriptor descriptor)
		{
			var buffer = Editor;
			var keyChar = descriptor.KeyChar;
			var key = descriptor.SpecialKey;
			var modifier = descriptor.ModifierKeys;
			if (CompletionWindowManager.IsVisible)
			{
				// do some things to minimize keystrokes with code completion
				if (keyChar == '=')
				{
					// we're in an attribute completion, so automatically add the quote and show completions (if available)
					var ret = base.KeyPress(descriptor);
					if (!ret)
					{
						base.KeyPress(KeyDescriptor.FromGtk((Gdk.Key)0, '"', Gdk.ModifierType.None));
						buffer.InsertText(buffer.CaretOffset, "\"");
						buffer.CaretOffset--;
					}
					return ret;
				}
				if (key == SpecialKey.Return
					&& modifier == ModifierKeys.None
					&& isParameterValueCompletion)
				{
					// finish completion
					base.KeyPress(descriptor);
					// if double quote already exists, skip it!
					if (buffer.GetCharAt(buffer.CaretOffset) == '"')
					{
						buffer.CaretOffset++;
						return false;
					}
					// no double quote yet, so add it
					return base.KeyPress(KeyDescriptor.FromGtk((Gdk.Key)0, '"', Gdk.ModifierType.None));
				}
				if (keyChar == '"' || keyChar == '\'')
				{
					// finish completion with double quote
					base.KeyPress(KeyDescriptor.FromGtk(Gdk.Key.Return, '\0', Gdk.ModifierType.None));
					// if double quote already exists, skip it!
					if (buffer.GetCharAt(buffer.CaretOffset) == keyChar)
					{
						buffer.CaretOffset++;
						return false;
					}
					return base.KeyPress(descriptor);
				}
			}
			if (keyChar == '>')
			{
				// finish completion first
				if (CompletionWindowManager.IsVisible)
					base.KeyPress(KeyDescriptor.FromGtk(Gdk.Key.Return, '\0', Gdk.ModifierType.None));

				// add self-closing tag if there is no content for the control
				if (!HasContentAtCurrentElement())
				{
					base.KeyPress(KeyDescriptor.FromGtk((Gdk.Key)0, '/', Gdk.ModifierType.None));
					//buffer.InsertText(buffer.CursorPosition++, "/");
					return base.KeyPress(descriptor);
				}
			}
			if (keyChar == '"' || keyChar == '\'')
			{
				// if double quote already exists, skip it!
				if (buffer.GetCharAt(buffer.CaretOffset) == keyChar)
				{
					buffer.CaretOffset++;
					return false;
				}
			}
			if (keyChar == '.' || ((key == SpecialKey.Return || key == SpecialKey.Tab) && CompletionWindowManager.IsVisible))
			{
				// provide completions for <Control.Property> elements
				var isNewCompletion = keyChar == '.' && !CompletionWindowManager.IsVisible;
				var completionContext = CurrentCompletionContext;

				var result = base.KeyPress(descriptor);

				if (isNewCompletion) completionContext = CurrentCompletionContext;
				var offset = completionContext.TriggerOffset - 1;

				// using reflection here as these have been made internal as of XS 6.0.  Why? who knows.  Alternative? reflection of course.
				var completionWidget = GetType().GetProperty("CompletionWidget", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(this);
				var getCharMethod = completionWidget?.GetType()?.GetMethod("GetChar", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
				if (getCharMethod != null)
				{
					Func<int, char> getChar = (arg) =>
					{
						return (char)getCharMethod.Invoke(completionWidget, new object[] { arg });
					};

					var ch = getChar(offset);
					while (ch != '\0' && (XmlConvert.IsNCNameChar(ch) || ch == ':') && offset > 0)
					{
						offset--;
						ch = getChar(offset);
					}
					if (ch != '\0' && ch != '<')
						return result;
				}
				offset++;
				var end = isNewCompletion ? completionContext.TriggerOffset - 1 : buffer.CaretOffset;

				var name = Editor.GetTextAt(offset, end - offset);

				if (!isNewCompletion && !name.EndsWith(".", StringComparison.Ordinal))
					return result;

				try
				{
					XmlConvert.VerifyName(name);
				}
				catch (XmlException)
				{
					// not a valid xml name, so just return
					return result;
				}

				var xobject = Tracker.Engine.Nodes.Peek(1) as IAttributedXObject;
				if (xobject == null)
				{
					string prefix = null;
					var nsidx = name.IndexOf(':');
					if (nsidx > 0)
					{
						prefix = name.Substring(0, nsidx);
						name = name.Substring(nsidx + 1);
					}
					name = name.TrimEnd('.');
					xobject = new XElement(Tracker.Engine.Location, new XName(prefix, name));
				}

				var attributeDictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				if (xobject.Attributes != null)
				{
					foreach (XAttribute current in xobject.Attributes)
					{
						attributeDictionary[current.Name.FullName] = current.Value ?? string.Empty;
					}
				}
				var task = GetAttributeCompletions(xobject, attributeDictionary, CancellationToken.None, XmlCompletionData.DataType.XmlElement, true);

				task.ContinueWith(t =>
				{
					// need to show completion within the main task scheduler, otherwise it doesn't show
					var completions = t.Result;
					if (completions != null)
					{
						ShowCompletion(completions, 0, '.');
					}
				}, Runtime.MainTaskScheduler);
				return false;
			}
			return base.KeyPress (descriptor);
		}