diff --git a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerGenerator.cs b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerGenerator.cs index b603fc8632..fc39e644be 100644 --- a/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerGenerator.cs +++ b/src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerGenerator.cs @@ -9,6 +9,7 @@ using System; using System.ComponentModel; using System.Text; using System.Reflection; +using System.CodeDom; using ICSharpCode.Core; using ICSharpCode.SharpDevelop.Dom; using ICSharpCode.FormDesigner; @@ -17,9 +18,11 @@ namespace Grunwald.BooBinding.Designer { public class BooDesignerGenerator : AbstractDesignerGenerator { - protected override string GenerateFieldDeclaration(Type fieldType, string name) + protected override string GenerateFieldDeclaration(CodeDOMGenerator domGenerator, CodeMemberField field) { - return "private " + name + " as " + fieldType; + // TODO: add support for modifiers + // (or implement code generation for fields in the Boo CodeDomProvider) + return "private " + field.Name + " as " + field.Type.BaseType; } protected override System.CodeDom.Compiler.CodeDomProvider CreateCodeProvider() diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/AbstractDesignerGenerator.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/AbstractDesignerGenerator.cs index 820ceaf723..4780809f76 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/AbstractDesignerGenerator.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/AbstractDesignerGenerator.cs @@ -8,6 +8,7 @@ using System; using System.IO; using System.Collections; +using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Reflection; @@ -35,8 +36,6 @@ namespace ICSharpCode.FormDesigner CodeDomProvider provider; - public const string NonVisualComponentContainerName = "components"; - public CodeDomProvider CodeDomProvider { get { if (this.provider == null) { @@ -49,31 +48,26 @@ namespace ICSharpCode.FormDesigner public void Attach(FormDesignerViewContent viewContent) { this.viewContent = viewContent; - IComponentChangeService componentChangeService = (IComponentChangeService)viewContent.DesignSurface.GetService(typeof(IComponentChangeService)); - componentChangeService.ComponentAdded += new ComponentEventHandler(ComponentAdded); - componentChangeService.ComponentRename += new ComponentRenameEventHandler(ComponentRenamed); - componentChangeService.ComponentRemoving += new ComponentEventHandler(ComponentRemoved); } public void Detach() { - IComponentChangeService componentChangeService = (IComponentChangeService)viewContent.DesignSurface.GetService(typeof(IComponentChangeService)); - componentChangeService.ComponentAdded -= new ComponentEventHandler(ComponentAdded); - componentChangeService.ComponentRename -= new ComponentRenameEventHandler(ComponentRenamed); - componentChangeService.ComponentRemoving -= new ComponentEventHandler(ComponentRemoved); this.viewContent = null; } - void ComponentRemoved(object sender, ComponentEventArgs e) + /// + /// Removes the field declaration with the specified name from the source file. + /// + void RemoveField(string fieldName) { try { + LoggingService.Info("Remove field declaration: "+fieldName); Reparse(); - foreach (IField field in c.Fields) { - if (field.Name == e.Component.Site.Name) { - int startOffset = document.PositionToOffset(new Point(0, field.Region.BeginLine - 1)); - int endOffset = document.PositionToOffset(new Point(0, field.Region.EndLine)); - document.Remove(startOffset, endOffset - startOffset); - } + IField field = GetField(c, fieldName); + if (field != null) { + int startOffset = document.PositionToOffset(new Point(0, field.Region.BeginLine - 1)); + int endOffset = document.PositionToOffset(new Point(0, field.Region.EndLine)); + document.Remove(startOffset, endOffset - startOffset); } SaveDocument(); } catch (Exception ex) { @@ -81,7 +75,12 @@ namespace ICSharpCode.FormDesigner } } - protected abstract string GenerateFieldDeclaration(Type fieldType, string name); + protected virtual string GenerateFieldDeclaration(CodeDOMGenerator domGenerator, CodeMemberField field) + { + StringWriter writer = new StringWriter(); + domGenerator.ConvertContentDefinition(field, writer); + return writer.ToString().Trim(); + } /// /// Contains the tabs in front of the InitializeComponents declaration. @@ -89,33 +88,24 @@ namespace ICSharpCode.FormDesigner /// protected string tabs; - void ComponentAdded(object sender, ComponentEventArgs e) - { - try { - Reparse(); - int endOffset = document.PositionToOffset(new Point(0, initializeComponents.BodyRegion.EndLine)); - document.Insert(endOffset, tabs + GenerateFieldDeclaration(e.Component.GetType(), e.Component.Site.Name) + Environment.NewLine); - if (CodeDOMGenerator.IsNonVisualComponent(viewContent.Host, e.Component)) { - if (!IsNonVisualComponentContainerDefined) { - document.Insert(endOffset, tabs + GenerateFieldDeclaration(typeof(Container), NonVisualComponentContainerName) + Environment.NewLine); - } - } - SaveDocument(); - } catch (Exception ex) { - MessageService.ShowError(ex); - } - } - - void ComponentRenamed(object sender, ComponentRenameEventArgs e) + /// + /// Adds the declaration for the specified field to the source file + /// or replaces the already present declaration for a field with the same name. + /// + /// The CodeDOMGenerator used to generate the field declaration. + /// The CodeDom field to be added or replaced. + void AddOrReplaceField(CodeDOMGenerator domGenerator, CodeMemberField newField) { try { Reparse(); - foreach (IField field in c.Fields) { - if (field.Name == e.OldName) { - int startOffset = document.PositionToOffset(new Point(0, field.Region.BeginLine - 1)); - int endOffset = document.PositionToOffset(new Point(0, field.Region.EndLine)); - document.Replace(startOffset, endOffset - startOffset, tabs + GenerateFieldDeclaration(e.Component.GetType(), e.NewName) + Environment.NewLine); - } + IField oldField = GetField(c, newField.Name); + if (oldField != null) { + int startOffset = document.PositionToOffset(new Point(0, oldField.Region.BeginLine - 1)); + int endOffset = document.PositionToOffset(new Point(0, oldField.Region.EndLine)); + document.Replace(startOffset, endOffset - startOffset, tabs + GenerateFieldDeclaration(domGenerator, newField) + Environment.NewLine); + } else { + int endOffset = document.PositionToOffset(new Point(0, initializeComponents.BodyRegion.EndLine)); + document.Insert(endOffset, tabs + GenerateFieldDeclaration(domGenerator, newField) + Environment.NewLine); } SaveDocument(); } catch (Exception ex) { @@ -166,6 +156,64 @@ namespace ICSharpCode.FormDesigner document.Replace(startOffset, endOffset - startOffset, statements); SaveDocument(); + + // apply changes the designer made to field declarations + // first loop looks for added and changed fields + foreach (CodeTypeMember m in formClass.Members) { + if (m is CodeMemberField) { + CodeMemberField newField = (CodeMemberField)m; + IField oldField = GetField(c, newField.Name); + if (oldField == null || FieldChanged(oldField, newField)) { + AddOrReplaceField(domGenerator, newField); + } + } + } + + // second loop looks for removed fields + List removedFields = new List(); + foreach (IField field in c.Fields) { + bool found = false; + foreach (CodeTypeMember m in formClass.Members) { + if (m is CodeMemberField && m.Name == field.Name) { + found = true; + break; + } + } + if (!found) { + removedFields.Add(field.Name); + } + } + // removing fields is done in two steps because + // we must not modify the c.Fields collection while it is enumerated + removedFields.ForEach(RemoveField); + + } + + /// + /// Compares the SharpDevelop.Dom field declaration oldField to + /// the CodeDom field declaration newField. + /// + /// true, if the fields are different in type or modifiers, otherwise false. + bool FieldChanged(IField oldField, CodeMemberField newField) + { + // compare types + if (oldField.ReturnType.FullyQualifiedName != newField.Type.BaseType) { + return true; + } + + // compare modifiers + ModifierEnum[] sdModifiers = new ModifierEnum[] {ModifierEnum.Private, ModifierEnum.Protected, ModifierEnum.ProtectedAndInternal, ModifierEnum.Internal, ModifierEnum.Public}; + MemberAttributes[] cdModifiers = new MemberAttributes[] {MemberAttributes.Private, MemberAttributes.Family, MemberAttributes.FamilyOrAssembly, MemberAttributes.Assembly, MemberAttributes.Public}; + + ModifierEnum oldModifiers = oldField.Modifiers & ModifierEnum.VisibilityMask; + MemberAttributes newModifiers = newField.Attributes & MemberAttributes.AccessMask; + for (int i = 0; i < sdModifiers.Length; i++) { + if ((oldModifiers == sdModifiers[i]) ^ (newModifiers == cdModifiers[i])) { + return true; + } + } + + return false; } IDocument document; @@ -321,13 +369,6 @@ namespace ICSharpCode.FormDesigner return compatibleMethods; } - bool IsNonVisualComponentContainerDefined - { - get { - return GetField(c, NonVisualComponentContainerName) != null; - } - } - IField GetField(IClass c, string name) { foreach (IField field in c.Fields) { diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CSharpDesignerGenerator.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CSharpDesignerGenerator.cs index 8bef948c3a..a607a16b10 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CSharpDesignerGenerator.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CSharpDesignerGenerator.cs @@ -17,11 +17,6 @@ namespace ICSharpCode.FormDesigner { public class CSharpDesignerGenerator : AbstractDesignerGenerator { - protected override string GenerateFieldDeclaration(Type fieldType, string name) - { - return "private " + fieldType + " " + name + ";"; - } - protected override DomRegion GetReplaceRegion(ICSharpCode.TextEditor.Document.IDocument document, IMethod method) { DomRegion r = method.BodyRegion; diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CodeDOMGenerator.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CodeDOMGenerator.cs index 9344cf73b3..9d49c2ef56 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CodeDOMGenerator.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/CodeDOMGenerator.cs @@ -66,10 +66,21 @@ namespace ICSharpCode.FormDesigner } - public static bool IsNonVisualComponent(IDesignerHost host, IComponent component) + public void ConvertContentDefinition(CodeMemberField field, TextWriter writer) { - IDesigner designer = host.GetDesigner(component); - return !(designer is ControlDesigner); + LoggingService.Info("Generate field declaration for: "+field.Name); + + CodeGeneratorOptions options = codeDOMGeneratorUtility.CreateCodeGeneratorOptions; + options.IndentString = indentation; + try { + codeProvider.GenerateCodeFromMember(field, writer, options); + } catch (Exception e) { + codeProvider.GenerateCodeFromStatement(new CodeCommentStatement("TODO: Error while generating statement : " + e.Message), + writer, + options); + LoggingService.Error(e); + } + } } diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/VBNetDesignerGenerator.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/VBNetDesignerGenerator.cs index ec54910989..f54ae46a99 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/VBNetDesignerGenerator.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerGenerator/VBNetDesignerGenerator.cs @@ -16,11 +16,6 @@ namespace ICSharpCode.FormDesigner { public class VBNetDesignerGenerator : AbstractDesignerGenerator { - protected override string GenerateFieldDeclaration(Type fieldType, string name) - { - return "Private " + name + " As " + fieldType; - } - protected override System.CodeDom.Compiler.CodeDomProvider CreateCodeProvider() { return new Microsoft.VisualBasic.VBCodeProvider(); diff --git a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs index e0385b57f8..e670e56cdf 100644 --- a/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs +++ b/src/AddIns/DisplayBindings/FormDesigner/Project/Src/FormDesigner/DesignerLoader/NRefactoryDesignerLoader.cs @@ -301,6 +301,12 @@ namespace ICSharpCode.FormDesigner protected override void Write(CodeCompileUnit unit) { LoggingService.Info("DesignerLoader.Write called"); + // output generated CodeDOM to the console : + #if DEBUG + if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { + this.CodeDomProvider.GenerateCodeFromCompileUnit(unit, Console.Out, null); + } + #endif generator.MergeFormChanges(unit); } diff --git a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs index 00980e2e98..3305c71f3c 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs @@ -117,18 +117,8 @@ namespace ICSharpCode.NRefactory.Parser if ((modifier & Modifier.Abstract) != 0) attr |= MemberAttributes.Abstract; -// if ((modifier & Modifier.None) != 0) -// attr |= MemberAttributes.AccessMask; - if ((modifier & Modifier.Internal) != 0) - attr |= MemberAttributes.Assembly; if ((modifier & Modifier.Const) != 0) attr |= MemberAttributes.Const; - if ((modifier & Modifier.Protected) != 0) - attr |= MemberAttributes.Family; - if ((modifier & Modifier.Protected) != 0 && (modifier & Modifier.Internal) != 0) - attr |= MemberAttributes.FamilyAndAssembly; -// if ((modifier & Modifier.None) != 0) -// attr |= MemberAttributes.FamilyOrAssembly; if ((modifier & Modifier.Sealed) != 0) attr |= MemberAttributes.Final; if ((modifier & Modifier.New) != 0) @@ -137,17 +127,20 @@ namespace ICSharpCode.NRefactory.Parser attr |= MemberAttributes.Overloaded; if ((modifier & Modifier.Override) != 0) attr |= MemberAttributes.Override; + if ((modifier & Modifier.Static) != 0) + attr |= MemberAttributes.Static; + if ((modifier & Modifier.Private) != 0) attr |= MemberAttributes.Private; - if ((modifier & Modifier.Public) != 0) + else if ((modifier & Modifier.Public) != 0) attr |= MemberAttributes.Public; -// if ((modifier & Modifier.None) != 0) -// attr |= MemberAttributes.ScopeMask; - if ((modifier & Modifier.Static) != 0) - attr |= MemberAttributes.Static; -// if ((modifier & Modifier.None) != 0) -// attr |= MemberAttributes.VTableMask; - + else if ((modifier & Modifier.Internal) != 0 && (modifier & Modifier.Protected) != 0) + attr |= MemberAttributes.FamilyOrAssembly; + else if ((modifier & Modifier.Internal) != 0) + attr |= MemberAttributes.Assembly; + else if ((modifier & Modifier.Protected) != 0) + attr |= MemberAttributes.Family; + return attr; }