Browse Source

Merge branch 'master' of github.com:icsharpcode/SharpDevelop

pull/490/head
Peter Forstmeier 11 years ago
parent
commit
ee249e03be
  1. 20
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs
  2. 14
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs
  3. 60
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs
  4. 11
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs
  5. 2
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs
  6. 101
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs
  7. 2
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs
  8. 11
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs
  9. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs
  10. 2
      src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

20
src/AddIns/BackendBindings/CSharpBinding/Project/Src/FormattingStrategy/CSharpFormattingOptionsContainer.cs

@ -127,7 +127,6 @@ namespace CSharpBinding.FormattingStrategy @@ -127,7 +127,6 @@ namespace CSharpBinding.FormattingStrategy
if ((e.PropertyName == "Parent") || (e.PropertyName == null)) {
// All properties might have changed -> update everything
cachedOptions = CreateCachedOptions();
OnPropertyChanged(e.PropertyName);
} else {
// Some other property has changed, check if we have our own value for it
if (!activeOptions.Contains(e.PropertyName)) {
@ -136,7 +135,6 @@ namespace CSharpBinding.FormattingStrategy @@ -136,7 +135,6 @@ namespace CSharpBinding.FormattingStrategy
if (propertyInfo != null) {
var val = GetEffectiveOption(e.PropertyName);
propertyInfo.SetValue(cachedOptions, val);
OnPropertyChanged(e.PropertyName);
}
}
}
@ -265,14 +263,16 @@ namespace CSharpBinding.FormattingStrategy @@ -265,14 +263,16 @@ namespace CSharpBinding.FormattingStrategy
if (parentProperties == null)
throw new ArgumentNullException("parentProperties");
Properties formatProperties = parentProperties.NestedProperties("CSharpFormatting");
if (formatProperties != null) {
foreach (var key in formatProperties.Keys) {
try {
object val = formatProperties.Get(key, (object) null);
SetOption(key, val);
} catch (Exception) {
// Silently ignore loading error, then this property will be "as parent" automatically
if (parentProperties.Contains("CSharpFormatting")) {
Properties formatProperties = parentProperties.NestedProperties("CSharpFormatting");
if (formatProperties != null) {
foreach (var key in formatProperties.Keys) {
try {
object val = formatProperties.Get(key, (object)null);
SetOption(key, val);
} catch (Exception) {
// Silently ignore loading error, then this property will be "as parent" automatically
}
}
}
}

14
src/AddIns/BackendBindings/CSharpBinding/Project/Src/OptionPanels/CSharpFormattingOptionPanel.xaml.cs

@ -64,6 +64,7 @@ namespace CSharpBinding.OptionPanels @@ -64,6 +64,7 @@ namespace CSharpBinding.OptionPanels
internal partial class CSharpFormattingOptionPanel : OptionPanel
{
readonly CSharpFormattingOptionsPersistence persistenceHelper;
bool isDirty;
public CSharpFormattingOptionPanel(CSharpFormattingOptionsPersistence persistenceHelper, bool allowPresets)
{
@ -71,6 +72,7 @@ namespace CSharpBinding.OptionPanels @@ -71,6 +72,7 @@ namespace CSharpBinding.OptionPanels
throw new ArgumentNullException("persistenceHelper");
this.persistenceHelper = persistenceHelper;
this.isDirty = false;
InitializeComponent();
formattingEditor.AllowPresets = allowPresets;
@ -79,12 +81,20 @@ namespace CSharpBinding.OptionPanels @@ -79,12 +81,20 @@ namespace CSharpBinding.OptionPanels
public override void LoadOptions()
{
base.LoadOptions();
formattingEditor.OptionsContainer = persistenceHelper.StartEditing();
formattingEditor.OptionsContainer = persistenceHelper.StartEditing();
formattingEditor.OptionsContainer.PropertyChanged += ContainerPropertyChanged;
}
void ContainerPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
isDirty = true;
}
public override bool SaveOptions()
{
return persistenceHelper.Save() && base.SaveOptions();
// Only save container, if some option really has changed
formattingEditor.OptionsContainer.PropertyChanged -= ContainerPropertyChanged;
return (!isDirty || persistenceHelper.Save()) && base.SaveOptions();
}
}
}

60
src/AddIns/BackendBindings/XamlBinding/XamlBinding/CompletionDataGenerator.cs

@ -122,15 +122,26 @@ namespace ICSharpCode.XamlBinding @@ -122,15 +122,26 @@ namespace ICSharpCode.XamlBinding
{
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;
var items = GetClassesFromContext(context);
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);
@ -172,6 +183,8 @@ namespace ICSharpCode.XamlBinding @@ -172,6 +183,8 @@ namespace ICSharpCode.XamlBinding
.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))
@ -198,15 +211,6 @@ namespace ICSharpCode.XamlBinding @@ -198,15 +211,6 @@ namespace ICSharpCode.XamlBinding
// result.Add(new XamlCodeCompletionItem(itemClass, last.Prefix));
// }
var xamlItems = XamlConst.XamlNamespaceAttributes.AsEnumerable();
if (XamlConst.EnableXaml2009)
xamlItems = XamlConst.XamlBuiltInTypes.Concat(xamlItems);
foreach (string item in xamlItems) {
result.Add(new XamlCompletionItem(context.XamlNamespacePrefix + ":" + item));
}
return result;
}
@ -266,8 +270,11 @@ namespace ICSharpCode.XamlBinding @@ -266,8 +270,11 @@ namespace ICSharpCode.XamlBinding
string xamlPrefix = context.XamlNamespacePrefix;
string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":";
if (lastElement.Prefix == context.XamlNamespacePrefix && XamlConst.IsBuiltin(lastElement.LocalName))
return EmptyList<ICompletionItem>.Instance;
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)
@ -279,16 +286,9 @@ namespace ICSharpCode.XamlBinding @@ -279,16 +286,9 @@ namespace ICSharpCode.XamlBinding
}
AddAttachedProperties(type.GetDefinition(), list);
} else {
if (type.Kind == TypeKind.Unknown) {
list.Add(new XamlCompletionItem(xKey + "Uid"));
} else {
if (type.Kind != TypeKind.Unknown) {
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))
);
}
}
@ -384,11 +384,11 @@ namespace ICSharpCode.XamlBinding @@ -384,11 +384,11 @@ namespace ICSharpCode.XamlBinding
ITextEditor editor = context.Editor;
compilation = SD.ParserService.GetCompilationForFile(editor.FileName);
string xamlPrefix = context.XamlNamespacePrefix;
string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":";
if (type.Name == typeof(System.Nullable<>).Name) {
string nullExtensionName = "Null";
if (!string.IsNullOrEmpty(context.XamlNamespacePrefix))
nullExtensionName = context.XamlNamespacePrefix + ":" + nullExtensionName;
yield return new XamlCompletionItem("{" + nullExtensionName + "}");
yield return new XamlCompletionItem("{" + xKey + "Null}");
type = type.TypeArguments.FirstOrDefault();
if (type == null) yield break;
}
@ -397,6 +397,18 @@ namespace ICSharpCode.XamlBinding @@ -397,6 +397,18 @@ namespace ICSharpCode.XamlBinding
if (definition == null) yield break;
definition.IsCollectionType();
switch (definition.KnownTypeCode) {
case KnownTypeCode.Array:
case KnownTypeCode.ICollection:
case KnownTypeCode.ICollectionOfT:
case KnownTypeCode.IEnumerable:
case KnownTypeCode.IEnumerableOfT:
yield return new XamlCompletionItem("{" + xKey + "Array}");
break;
}
switch (definition.Kind) {
case TypeKind.Class:
IType typeName;

11
src/AddIns/BackendBindings/XamlBinding/XamlBinding/Extensions.cs

@ -398,6 +398,17 @@ namespace ICSharpCode.XamlBinding @@ -398,6 +398,17 @@ namespace ICSharpCode.XamlBinding
return thisValue.GetAllBaseTypeDefinitions().Any(t => t.FullName == "System.Collections.IList");
}
public static bool Implements(this IType thisValue, IType interfaceType)
{
if (thisValue == null)
throw new ArgumentNullException("thisValue");
if (interfaceType == null)
throw new ArgumentNullException("interfaceType");
if (interfaceType.Kind != TypeKind.Interface)
throw new ArgumentException("must be TypeKind.Interface", "interfaceType");
return thisValue.GetAllBaseTypes().Any(t => t.Equals(interfaceType));
}
public static bool HasAttached(this ITypeDefinition thisValue, bool lookForProperties, bool lookForEvents)
{
if (!lookForProperties && !lookForEvents)

2
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlCompletionItemList.cs

@ -83,7 +83,7 @@ namespace ICSharpCode.XamlBinding @@ -83,7 +83,7 @@ namespace ICSharpCode.XamlBinding
XamlCompletionItem cItem = item as XamlCompletionItem;
if (xamlContext.Description == XamlContextDescription.InTag) {
if (cItem.Entity.SymbolKind == SymbolKind.Property || cItem.Entity.SymbolKind == SymbolKind.Event) {
if (cItem.Entity == null || cItem.Entity.SymbolKind == SymbolKind.Property || cItem.Entity.SymbolKind == SymbolKind.Event) {
context.Editor.Document.Insert(context.EndOffset, "=\"\"");
context.CompletionCharHandled = context.CompletionChar == '=';
context.Editor.Caret.Offset--;

101
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlConst.cs

@ -20,6 +20,11 @@ using System; @@ -20,6 +20,11 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Xml.Serialization;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Semantics;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.XamlBinding
{
@ -28,33 +33,22 @@ namespace ICSharpCode.XamlBinding @@ -28,33 +33,22 @@ namespace ICSharpCode.XamlBinding
/// </summary>
public static class XamlConst
{
public const bool EnableXaml2009 = true;
// [XAML 2009]
public static readonly List<string> XamlBuiltInTypes = new List<string> {
"Object", "Boolean", "Char", "String", "Decimal", "Single", "Double",
"Int16", "Int32", "Int64", "TimeSpan", "Uri", "Byte", "Array", "List", "Dictionary",
// This is no built in type, but a markup extension
"Reference"
};
public static readonly ReadOnlyCollection<string> XamlNamespaceAttributes = new List<string> {
"Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid", "Key"
}.AsReadOnly();
public static readonly ReadOnlyCollection<string> RootOnlyElements = new List<string> {
"Class", "ClassModifier", "Subclass"
}.AsReadOnly();
public static readonly ReadOnlyCollection<string> ChildOnlyElements = new List<string> {
"FieldModifier"
"Class", "ClassModifier", "FieldModifier", "Name", "Subclass", "TypeArguments", "Uid", "Key", "Shared"
}.AsReadOnly();
/// <summary>
/// values: http://schemas.microsoft.com/winfx/2006/xaml/presentation,
/// http://schemas.microsoft.com/netfx/2007/xaml/presentation
/// </summary>
public static readonly string[] WpfXamlNamespaces = new[] {
public static readonly string[] WpfXamlNamespaces = {
"http://schemas.microsoft.com/winfx/2006/xaml/presentation",
"http://schemas.microsoft.com/netfx/2007/xaml/presentation"
};
@ -88,11 +82,86 @@ namespace ICSharpCode.XamlBinding @@ -88,11 +82,86 @@ namespace ICSharpCode.XamlBinding
}
/// <summary>
/// Returns true if the given attribute is allowed in the current element.
/// Returns the list of allow XAML2009 completion items.
/// </summary>
public static bool IsAttributeAllowed(bool inRoot, string localName)
public static IEnumerable<string> GetAllowedItems(XamlCompletionContext context)
{
return inRoot ? !ChildOnlyElements.Contains(localName) : !RootOnlyElements.Contains(localName);
string xamlPrefix = context.XamlNamespacePrefix;
string xKey = string.IsNullOrEmpty(xamlPrefix) ? "" : xamlPrefix + ":";
var compilation = SD.ParserService.GetCompilationForFile(context.Editor.FileName);
var resolver = new XamlAstResolver(compilation, context.ParseInformation);
// TODO : add support for x:Key as attribute element (XAML 2009 only)
switch (context.Description) {
case XamlContextDescription.AtTag:
if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Members", StringComparison.OrdinalIgnoreCase)) {
yield return xKey + "Member";
yield return xKey + "Property";
} else if (context.ParentElement == context.RootElement && context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) {
yield return xKey + "Code";
yield return xKey + "Members";
} else {
if (context.ParentElement != null && string.Equals(context.ParentElement.Name, xKey + "Code", StringComparison.OrdinalIgnoreCase))
yield break;
yield return xKey + "Array";
yield return xKey + "Boolean";
yield return xKey + "Byte";
yield return xKey + "Char";
yield return xKey + "Decimal";
yield return xKey + "Dictionary";
yield return xKey + "Double";
yield return xKey + "Int16";
yield return xKey + "Int32";
yield return xKey + "Int64";
yield return xKey + "List";
yield return xKey + "Object";
yield return xKey + "Reference";
yield return xKey + "Single";
yield return xKey + "String";
yield return xKey + "TimeSpan";
yield return xKey + "Uri";
if (context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase)))
yield return xKey + "Members";
}
break;
case XamlContextDescription.InTag:
yield return xKey + "Uid";
if (context.InRoot) {
yield return xKey + "Class";
yield return xKey + "ClassModifier";
yield return xKey + "Subclass";
yield return xKey + "Name";
} else {
var resourceDictionaryType = compilation.FindType(typeof(ResourceDictionary));
if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Array", StringComparison.OrdinalIgnoreCase)) {
yield return "Type";
} else if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Member", StringComparison.OrdinalIgnoreCase)) {
yield return "Name";
} else if (context.ActiveElement != null && string.Equals(context.ActiveElement.Name, xKey + "Property", StringComparison.OrdinalIgnoreCase)) {
yield return "Name";
yield return "Type";
} else if (context.RootElement.Attributes.Any(attr => string.Equals(attr.Name, xKey + "Class", StringComparison.OrdinalIgnoreCase))) {
yield return xKey + "FieldModifier";
yield return xKey + "Name";
} else {
yield return xKey + "Name";
}
if (context.ParentElement != null) {
var rr = resolver.ResolveElement(context.ParentElement);
if (rr != null) {
if (rr.Type.Equals(resourceDictionaryType)) {
yield return xKey + "Key";
yield return xKey + "Shared";
} else if (rr.Type.TypeParameterCount > 0) {
yield return xKey + "TypeArguments";
}
}
}
}
break;
}
yield break;
}
}
}

2
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContext.cs

@ -94,6 +94,7 @@ namespace ICSharpCode.XamlBinding @@ -94,6 +94,7 @@ namespace ICSharpCode.XamlBinding
{
public AXmlElement ActiveElement { get; set; }
public AXmlElement ParentElement { get; set; }
public AXmlElement RootElement { get; set; }
public ReadOnlyCollection<AXmlElement> Ancestors { get; set; }
public AXmlAttribute Attribute { get; set; }
public AttributeValue AttributeValue { get; set; }
@ -131,6 +132,7 @@ namespace ICSharpCode.XamlBinding @@ -131,6 +132,7 @@ namespace ICSharpCode.XamlBinding
this.AttributeValue = context.AttributeValue;
this.Description = context.Description;
this.ParentElement = context.ParentElement;
this.RootElement = context.RootElement;
this.ParseInformation = context.ParseInformation;
this.RawAttributeValue = context.RawAttributeValue;
this.ValueStartOffset = context.ValueStartOffset;

11
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlContextResolver.cs

@ -59,6 +59,7 @@ namespace ICSharpCode.XamlBinding @@ -59,6 +59,7 @@ namespace ICSharpCode.XamlBinding
string xamlNamespacePrefix = string.Empty;
var item = currentData;
AXmlElement root = null;
while (item != document) {
if (item is AXmlElement) {
@ -78,8 +79,11 @@ namespace ICSharpCode.XamlBinding @@ -78,8 +79,11 @@ namespace ICSharpCode.XamlBinding
xamlNamespacePrefix = attr.LocalName;
}
if (!wasAXmlElement && item.Parent is AXmlDocument)
isRoot = true;
if (element.Parent is AXmlDocument) {
root = element;
if (!wasAXmlElement)
isRoot = true;
}
wasAXmlElement = true;
}
@ -91,7 +95,7 @@ namespace ICSharpCode.XamlBinding @@ -91,7 +95,7 @@ namespace ICSharpCode.XamlBinding
AXmlElement active = null;
AXmlElement parent = null;
if (currentData is AXmlAttribute) {
AXmlAttribute a = currentData as AXmlAttribute;
int valueStartOffset = a.ValueSegment.Offset + 1;
@ -140,6 +144,7 @@ namespace ICSharpCode.XamlBinding @@ -140,6 +144,7 @@ namespace ICSharpCode.XamlBinding
Description = description,
ActiveElement = active,
ParentElement = parent,
RootElement = root,
Ancestors = ancestors.AsReadOnly(),
Attribute = xAttribute,
InRoot = isRoot,

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignPanelHitTestResult.cs

@ -24,7 +24,7 @@ using ICSharpCode.WpfDesign.Adorners; @@ -24,7 +24,7 @@ using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// Describes the result of a <see cref="IDesignPanel.HitTest(Point, bool, bool)"/> call.
/// Describes the result of a <see cref="IDesignPanel.HitTest(Point, bool, bool, HitTestType)"/> call.
/// </summary>
public struct DesignPanelHitTestResult : IEquatable<DesignPanelHitTestResult>
{

2
src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

@ -430,7 +430,7 @@ namespace ICSharpCode.Core @@ -430,7 +430,7 @@ namespace ICSharpCode.Core
if (result == null) {
result = new Properties(this);
dict[key] = result;
result.MakeDirty();
isNewContainer = true;
}
}
if (isNewContainer)

Loading…
Cancel
Save