Browse Source

The Boo forms designer now supports partial classes.

VB and Boo templates now use partial classes for the forms designer.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1033 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 20 years ago
parent
commit
4816d086ef
  1. 2
      data/templates/file/CSharp/CSharp.Forms.UserControl.xft
  2. 43
      data/templates/file/VBNet/VBNet.Forms.Form.xft
  3. 42
      data/templates/file/VBNet/VBNet.Forms.UserControl.xft
  4. 43
      data/templates/project/VBNet/ControlLibrary.xpt
  5. 49
      data/templates/project/VBNet/FormsProject.xpt
  6. 100
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerLoader.cs
  7. 27
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/Form.xft
  8. 29
      src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/FormsProject.xpt
  9. 27
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs
  10. 7
      src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs
  11. 6
      src/Main/Base/Project/Src/Dom/Implementations/CompoundClass.cs
  12. 15
      src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs

2
data/templates/file/CSharp/CSharp.Forms.UserControl.xft

@ -61,7 +61,7 @@ namespace ${StandardNamespace} @@ -61,7 +61,7 @@ namespace ${StandardNamespace}
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)

43
data/templates/file/VBNet/VBNet.Forms.Form.xft

@ -24,33 +24,52 @@ @@ -24,33 +24,52 @@
<Files>
<File name="${FullName}" language="VBNET"><![CDATA[${StandardHeader.VBNET}
Public Class ${ClassName}
Inherits System.Windows.Forms.Form
Public Partial Class ${ClassName}
Public Sub New()
'
' The Me.InitializeComponent call is required for Windows Forms designer support.
'
Me.InitializeComponent
Me.InitializeComponent()
'
' TODO : Add constructor code after InitializeComponents
'
End Sub
End Class
]]></File>
<File name="${Path}/${FileNameWithoutExtension}.Designer.vb" dependentUpon="${FileName}" language="VBNET"><![CDATA[${StandardHeader.VBNET}
Partial Class ${ClassName}
Inherits System.Windows.Forms.Form
''' <summary>
''' Designer variable used to keep track of non-visual components.
''' </summary>
Private components As System.ComponentModel.IContainer
''' <summary>
''' Disposes resources used by the form.
''' </summary>
''' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region " Windows Forms Designer generated code "
' This method is required for Windows Forms designer support.
' Do not change the method contents inside the source code editor. The Forms designer might
' not be able to load this method if it was changed manually.
''' <summary>
''' This method is required for Windows Forms designer support.
''' Do not change the method contents inside the source code editor. The Forms designer might
''' not be able to load this method if it was changed manually.
''' </summary>
Private Sub InitializeComponent()
'
'${ClassName}
'
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Name = "${ClassName}"
Me.Text = "${ClassName}"
End Sub
#End Region
End Class
]]></File>
</Files>

42
data/templates/file/VBNet/VBNet.Forms.UserControl.xft

@ -22,29 +22,51 @@ @@ -22,29 +22,51 @@
-->
<Files>
<File name="${FullName}" language="VBNET"><![CDATA[${StandardHeader.VBNET}
Public Class ${ClassName}
Inherits System.Windows.Forms.UserControl
Public Partial Class ${ClassName}
Public Sub New()
' Must be called for initialization
' The Me.InitializeComponent call is required for Windows Forms designer support.
Me.InitializeComponent()
'
' TODO : Add constructor code after InitializeComponents
'
End Sub
End Class
]]></File>
<File name="${Path}/${FileNameWithoutExtension}.Designer.vb" dependentUpon="${FileName}" language="VBNET"><![CDATA[${StandardHeader.VBNET}
Partial Class ${ClassName}
Inherits System.Windows.Forms.UserControl
''' <summary>
''' Designer variable used to keep track of non-visual components.
''' </summary>
Private components As System.ComponentModel.IContainer
''' <summary>
''' Disposes resources used by the control.
''' </summary>
''' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region " Windows Forms Designer generated code "
' This method is required for Windows Forms designer support.
' Do not change the method contents inside the source code editor. The Forms designer might
' not be able to load this method if it was changed manually.
''' <summary>
''' This method is required for Windows Forms designer support.
''' Do not change the method contents inside the source code editor. The Forms designer might
''' not be able to load this method if it was changed manually.
''' </summary>
Private Sub InitializeComponent()
'
'${ClassName}
'
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Name = "${ClassName}"
End Sub
#End Region
End Class
]]></File>
</Files>

43
data/templates/project/VBNet/ControlLibrary.xpt

@ -45,28 +45,51 @@ @@ -45,28 +45,51 @@
<Files>
<File name="UserControl1.vb"><![CDATA[${StandardHeader.VBNET}
Public Class UserControl1
Inherits System.Windows.Forms.UserControl
Public Partial Class UserControl1
Public Sub New()
' Must be called for initialization
Me.InitializeComponent
' The Me.InitializeComponent call is required for Windows Forms designer support.
Me.InitializeComponent()
'
' TODO : Add constructor code after InitializeComponents
'
End Sub
End Class
]]></File>
<File name="UserControl1.Designer.vb" dependentUpon="UserControl1.vb"><![CDATA[${StandardHeader.VBNET}
Partial Class UserControl1
Inherits System.Windows.Forms.UserControl
''' <summary>
''' Designer variable used to keep track of non-visual components.
''' </summary>
Private components As System.ComponentModel.IContainer
''' <summary>
''' Disposes resources used by the control.
''' </summary>
''' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
#Region " Windows Forms Designer generated code "
' This method is required for Windows Forms designer support.
' Do not change the method contents inside the source code editor. The Forms designer might
' not be able to load this method if it was changed manually.
''' <summary>
''' This method is required for Windows Forms designer support.
''' Do not change the method contents inside the source code editor. The Forms designer might
''' not be able to load this method if it was changed manually.
''' </summary>
Private Sub InitializeComponent()
'
'UserControl1
'
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.Name = "UserControl1"
End Sub
#End Region
End Class
]]></File>
<File name="AssemblyInfo.vb">

49
data/templates/project/VBNet/FormsProject.xpt

@ -45,34 +45,53 @@ @@ -45,34 +45,53 @@
<Files>
<File name="MainForm.vb">
<![CDATA[${StandardHeader.VBNET}
Public Class MainForm
Inherits System.Windows.Forms.Form
Public Partial Class MainForm
Public Sub New()
'
' The Me.InitializeComponent call is required for Windows Forms designer support.
'
Me.InitializeComponent
Me.InitializeComponent()
'
' TODO : Add constructor code after InitializeComponents
'
End Sub
End Class
]]></File>
<File name="MainForm.Designer.vb" dependentUpon="MainForm.vb">
<![CDATA[${StandardHeader.VBNET}
Partial Class MainForm
Inherits System.Windows.Forms.Form
''' <summary>
''' Designer variable used to keep track of non-visual components.
''' </summary>
Private components As System.ComponentModel.IContainer
#Region " Windows Forms Designer generated code "
' This method is required for Windows Forms designer support.
' Do not change the method contents inside the source code editor. The Forms designer might
' not be able to load this method if it was changed manually.
''' <summary>
''' Disposes resources used by the form.
''' </summary>
''' <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
Protected Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If components IsNot Nothing Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
''' <summary>
''' This method is required for Windows Forms designer support.
''' Do not change the method contents inside the source code editor. The Forms designer might
''' not be able to load this method if it was changed manually.
''' </summary>
Private Sub InitializeComponent()
'
'Form1
'MainForm
'
Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Name = "MainForm"
Me.Text = "MainForm"
Me.Text = "${ProjectName}"
End Sub
#End Region
End Class
]]></File>
<File name="Program.vb">

100
src/AddIns/BackendBindings/Boo/BooBinding/Project/Src/Designer/BooDesignerLoader.cs

@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.ComponentModel.Design;
@ -18,6 +18,7 @@ using System.Windows.Forms; @@ -18,6 +18,7 @@ using System.Windows.Forms;
using System.Windows.Forms.Design;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.TextEditor;
using ICSharpCode.TextEditor.Document;
@ -86,7 +87,7 @@ namespace Grunwald.BooBinding.Designer @@ -86,7 +87,7 @@ namespace Grunwald.BooBinding.Designer
base.BeginLoad(host);
}
protected override void OnEndLoad(bool successful, ICollection errors)
protected override void OnEndLoad(bool successful, System.Collections.ICollection errors)
{
this.loading = false;
base.OnEndLoad(successful, errors);
@ -109,38 +110,89 @@ namespace Grunwald.BooBinding.Designer @@ -109,38 +110,89 @@ namespace Grunwald.BooBinding.Designer
CodeCompileUnit ParseForm()
{
lastTextContent = TextContent;
ParseInformation parseInfo = ParserService.GetParseInformation(textEditorControl.FileName);
// ensure that there are no syntax errors in the file:
Module mainModule = Parse(textEditorControl.FileName, lastTextContent);
IClass formClass;
List<IClass> parts = NRefactoryDesignerLoader.FindFormClassParts(parseInfo, out formClass);
IMethod initMethod = FormsDesignerSecondaryDisplayBinding.GetInitializeComponents(formClass);
if (initMethod == null)
throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded.");
Module module = new Module();
module.Namespace = new NamespaceDeclaration(formClass.Namespace);
ClassDefinition cld = new ClassDefinition();
cld.Name = formClass.Name;
module.Members.Add(cld);
if (formClass.BaseClass == null)
throw new FormsDesignerLoadException("formClass.BaseClass returned null.");
cld.BaseTypes.Add(new SimpleTypeReference(formClass.BaseClass.FullyQualifiedName));
foreach (IField f in formClass.Fields) {
if (f.ReturnType.IsDefaultReturnType) {
Field field = new Field();
field.Name = f.Name;
field.Type = new SimpleTypeReference(f.ReturnType.FullyQualifiedName);
cld.Members.Add(field);
}
}
string fileName = initMethod.DeclaringType.CompilationUnit.FileName;
Module parsedModule;
if (FileUtility.IsEqualFileName(fileName, textEditorControl.FileName))
parsedModule = mainModule;
else
parsedModule = Parse(fileName, ParserService.GetParseableFileContent(fileName));
// Now find InitializeComponent in parsed module and put it into our new module
foreach (TypeMember m in parsedModule.Members) {
TypeDefinition td = m as TypeDefinition;
if (td == null)
continue;
foreach (TypeMember m2 in td.Members) {
Method method = m2 as Method;
if (method != null
&& FormsDesignerSecondaryDisplayBinding.IsInitializeComponentsMethodName(method.Name)
&& method.Parameters.Count == 0)
{
cld.Members.Add(method);
Console.WriteLine(module.ToCodeString());
CodeDomVisitor visitor = new CodeDomVisitor(parseInfo.MostRecentCompilationUnit.ProjectContent);
module.Accept(visitor);
// output generated CodeDOM to the console :
ICSharpCode.NRefactory.Parser.CodeDOMVerboseOutputGenerator outputGenerator = new ICSharpCode.NRefactory.Parser.CodeDOMVerboseOutputGenerator();
outputGenerator.GenerateCodeFromMember(visitor.OutputCompileUnit.Namespaces[0].Types[0], Console.Out, null);
provider.GenerateCodeFromCompileUnit(visitor.OutputCompileUnit, Console.Out, null);
return visitor.OutputCompileUnit;
}
}
}
throw new FormsDesignerLoadException("Could not find InitializeComponent in parsed module.");
}
Module Parse(string fileName, string fileContent)
{
BooParsingStep step = new BooParsingStep();
StringBuilder errors = new StringBuilder();
Module module = BooParser.ParseModule(4, new CompileUnit(), textEditorControl.FileName,
new StringReader(lastTextContent),
new StringReader(fileContent),
delegate(antlr.RecognitionException e) {
errors.AppendLine(e.ToString());
});
if (errors.Length > 0) {
throw new FormsDesignerLoadException(errors.ToString());
throw new FormsDesignerLoadException("Syntax errors in " + fileName + ":\r\n" + errors.ToString());
}
// Try to fix the type names to fully qualified ones
ParseInformation parseInfo = ParserService.GetParseInformation(textEditorControl.FileName);
/*
bool foundInitMethod = false;
//FixTypeNames(p.CompilationUnit, parseInfo.BestCompilationUnit, ref foundInitMethod);
if (!foundInitMethod)
throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded.");
*/
CodeDomVisitor visitor = new CodeDomVisitor(parseInfo.MostRecentCompilationUnit.ProjectContent);
module.Accept(visitor);
// output generated CodeDOM to the console :
ICSharpCode.NRefactory.Parser.CodeDOMVerboseOutputGenerator outputGenerator = new ICSharpCode.NRefactory.Parser.CodeDOMVerboseOutputGenerator();
outputGenerator.GenerateCodeFromMember(visitor.OutputCompileUnit.Namespaces[0].Types[0], Console.Out, null);
provider.GenerateCodeFromCompileUnit(visitor.OutputCompileUnit, Console.Out, null);
return visitor.OutputCompileUnit;
return module;
}
protected override void Write(CodeCompileUnit unit)

27
src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/Form.xft

@ -28,26 +28,33 @@ import System.Collections @@ -28,26 +28,33 @@ import System.Collections
import System.Drawing
import System.Windows.Forms
class MainForm(System.Windows.Forms.Form):
"""Description of MainForm."""
partial class ${ClassName}:
"""Description of ${ClassName}."""
def constructor():
// The InitializeComponent() call is required for Windows Forms designer support.
InitializeComponent()
// TODO: Add constructor code after the InitializeComponent() call.
]]></File>
<File name="${Path}/${FileNameWithoutExtension}.Designer.boo" language="Boo"><![CDATA[namespace ${StandardNamespace}
partial class ${ClassName}(System.Windows.Forms.Form):
private components as System.ComponentModel.IContainer = null
protected override def Dispose(disposing as bool):
if disposing:
if components is not null:
components.Dispose()
super(disposing)
#region Windows Forms Designer generated code
// This method is required for Windows Forms designer support.
// Do not change the method contents inside the source code editor. The Forms designer might
// not be able to load this method if it was changed manually.
def InitializeComponent():
// Form1
// ${ClassName}
self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
self.ClientSize = System.Drawing.Size(292, 266)
self.Text = 'MainForm'
self.Name = 'MainForm'
#endregion
self.Text = '${ClassName}'
self.Name = '${ClassName}'
]]></File>
</Files>

29
src/AddIns/BackendBindings/Boo/BooBinding/Project/Templates/FormsProject.xpt

@ -36,29 +36,36 @@ import System.Collections @@ -36,29 +36,36 @@ import System.Collections
import System.Drawing
import System.Windows.Forms
class MainForm(System.Windows.Forms.Form):
"""Description of MainForm."""
partial class MainForm:
def constructor():
// The InitializeComponent() call is required for Windows Forms designer support.
InitializeComponent()
// TODO: Add constructor code after the InitializeComponent() call.
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(false)
Application.Run(MainForm())
]]></File>
<File name="MainForm.Designer.boo" dependentUpon="MainForm.boo"><![CDATA[namespace ${StandardNamespace}
partial class MainForm(System.Windows.Forms.Form):
private components as System.ComponentModel.IContainer = null
protected override def Dispose(disposing as bool):
if disposing:
if components is not null:
components.Dispose()
super(disposing)
#region Windows Forms Designer generated code
// This method is required for Windows Forms designer support.
// Do not change the method contents inside the source code editor. The Forms designer might
// not be able to load this method if it was changed manually.
def InitializeComponent():
// Form1
// MainForm
self.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
self.ClientSize = System.Drawing.Size(292, 266)
self.Text = 'MainForm'
self.Name = 'MainForm'
#endregion
Application.EnableVisualStyles()
Application.Run(MainForm())
]]></File>
<File name="AssemblyInfo.boo">

27
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/DesignerLoader/NRefactoryDesignerLoader.cs

@ -131,22 +131,15 @@ namespace ICSharpCode.FormsDesigner @@ -131,22 +131,15 @@ namespace ICSharpCode.FormsDesigner
string lastTextContent;
protected override CodeCompileUnit Parse()
public static List<IClass> FindFormClassParts(ParseInformation parseInfo, out IClass formClass)
{
LoggingService.Debug("NRefactoryDesignerLoader.Parse()");
#if DEBUG
if ((Control.ModifierKeys & (Keys.Alt | Keys.Control)) == (Keys.Alt | Keys.Control)) {
System.Diagnostics.Debugger.Break();
}
#endif
lastTextContent = TextContent;
ParseInformation parseInfo = ParserService.GetParseInformation(textEditorControl.FileName);
IClass formClass = null;
formClass = null;
foreach (IClass c in parseInfo.BestCompilationUnit.Classes) {
if (FormsDesignerSecondaryDisplayBinding.BaseClassIsFormOrControl(c)) {
formClass = c;
@ -154,7 +147,7 @@ namespace ICSharpCode.FormsDesigner @@ -154,7 +147,7 @@ namespace ICSharpCode.FormsDesigner
}
}
if (formClass == null)
throw new FormsDesignerLoadException("No class derived from Form or Control was found.");
throw new FormsDesignerLoadException("No class derived from Form or UserControl was found.");
// Initialize designer for formClass
formClass = formClass.DefaultReturnType.GetUnderlyingClass();
@ -165,6 +158,20 @@ namespace ICSharpCode.FormsDesigner @@ -165,6 +158,20 @@ namespace ICSharpCode.FormsDesigner
parts = new List<IClass>();
parts.Add(formClass);
}
return parts;
}
protected override CodeCompileUnit Parse()
{
LoggingService.Debug("NRefactoryDesignerLoader.Parse()");
lastTextContent = TextContent;
ParseInformation parseInfo = ParserService.GetParseInformation(textEditorControl.FileName);
IClass formClass;
List<IClass> parts = FindFormClassParts(parseInfo, out formClass);
List<KeyValuePair<string, CompilationUnit>> compilationUnits = new List<KeyValuePair<string, CompilationUnit>>();
bool foundInitMethod = false;
foreach (IClass part in parts) {

7
src/AddIns/DisplayBindings/FormsDesigner/Project/Src/SecondaryDisplayBinding.cs

@ -30,13 +30,18 @@ namespace ICSharpCode.FormsDesigner @@ -30,13 +30,18 @@ namespace ICSharpCode.FormsDesigner
}
}
public static bool IsInitializeComponentsMethodName(string name)
{
return name == "InitializeComponents" || name == "InitializeComponent";
}
public static IMethod GetInitializeComponents(IClass c)
{
c = c.DefaultReturnType.GetUnderlyingClass();
if (c == null)
return null;
foreach (IMethod method in c.Methods) {
if ((method.Name == "InitializeComponents" || method.Name == "InitializeComponent") && method.Parameters.Count == 0) {
if (IsInitializeComponentsMethodName(method.Name) && method.Parameters.Count == 0) {
return method;
}
}

6
src/Main/Base/Project/Src/Dom/Implementations/CompoundClass.cs

@ -56,7 +56,11 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -56,7 +56,11 @@ namespace ICSharpCode.SharpDevelop.Dom
this.Attributes.Clear();
foreach (IClass part in parts) {
modifier |= part.Modifiers;
this.BaseTypes.AddRange(part.BaseTypes);
foreach (IReturnType rt in part.BaseTypes) {
if (!rt.IsDefaultReturnType || rt.FullyQualifiedName != "System.Object") {
this.BaseTypes.Add(rt);
}
}
foreach (ITypeParameter typeParam in part.TypeParameters) {
this.TypeParameters.Add(typeParam);
}

15
src/Main/Base/Project/Src/Dom/Implementations/SearchClassReturnType.cs

@ -91,10 +91,23 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -91,10 +91,23 @@ namespace ICSharpCode.SharpDevelop.Dom
static SearchClassReturnType()
{
cache = new Dictionary<SearchClassReturnType, IReturnType>();
cache = new Dictionary<SearchClassReturnType, IReturnType>(new ReferenceComparer());
ParserService.ParserUpdateStepFinished += OnParserUpdateStepFinished;
}
class ReferenceComparer : IEqualityComparer<SearchClassReturnType>
{
public bool Equals(SearchClassReturnType x, SearchClassReturnType y)
{
return x == y; // don't use x.Equals(y) - Equals might cause a FullyQualifiedName lookup on its own
}
public int GetHashCode(SearchClassReturnType obj)
{
return obj.GetHashCode();
}
}
static void OnParserUpdateStepFinished(object sender, ParserUpdateStepEventArgs e)
{
if (e.Updated) {

Loading…
Cancel
Save