Browse Source
Fixed BOO-511 (#develop should not display boo's "generated" module classes). git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@582 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
17 changed files with 1080 additions and 602 deletions
@ -0,0 +1,59 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.Reflection; |
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.FormDesigner; |
||||||
|
|
||||||
|
namespace Grunwald.BooBinding.Designer |
||||||
|
{ |
||||||
|
public class BooDesignerGenerator : AbstractDesignerGenerator |
||||||
|
{ |
||||||
|
protected override string GenerateFieldDeclaration(Type fieldType, string name) |
||||||
|
{ |
||||||
|
return "private " + name + " as " + fieldType; |
||||||
|
} |
||||||
|
|
||||||
|
protected override System.CodeDom.Compiler.CodeDomProvider CreateCodeProvider() |
||||||
|
{ |
||||||
|
return new Boo.Lang.CodeDom.BooCodeProvider(); |
||||||
|
} |
||||||
|
|
||||||
|
protected override string CreateEventHandler(EventDescriptor edesc, string eventMethodName, string body) |
||||||
|
{ |
||||||
|
if (string.IsNullOrEmpty(body)) body = "\tpass"; |
||||||
|
string param = GenerateParams(edesc); |
||||||
|
return "private def " + eventMethodName + "(" + param + "):\n" + |
||||||
|
body + |
||||||
|
"\n"; |
||||||
|
} |
||||||
|
|
||||||
|
protected static string GenerateParams(EventDescriptor edesc) |
||||||
|
{ |
||||||
|
Type type = edesc.EventType; |
||||||
|
MethodInfo mInfo = type.GetMethod("Invoke"); |
||||||
|
string param = ""; |
||||||
|
|
||||||
|
for (int i = 0; i < mInfo.GetParameters().Length; ++i) { |
||||||
|
ParameterInfo pInfo = mInfo.GetParameters()[i]; |
||||||
|
|
||||||
|
param += pInfo.Name; |
||||||
|
param += " as "; |
||||||
|
|
||||||
|
string typeStr = pInfo.ParameterType.ToString(); |
||||||
|
typeStr = BooAmbience.Instance.GetIntrinsicTypeName(typeStr); |
||||||
|
param += typeStr; |
||||||
|
if (i + 1 < mInfo.GetParameters().Length) { |
||||||
|
param += ", "; |
||||||
|
} |
||||||
|
} |
||||||
|
return param; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,141 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Drawing; |
||||||
|
using System.IO; |
||||||
|
using System.ComponentModel.Design; |
||||||
|
using System.CodeDom; |
||||||
|
using System.CodeDom.Compiler; |
||||||
|
using System.ComponentModel.Design.Serialization; |
||||||
|
using System.Text; |
||||||
|
using System.Windows.Forms; |
||||||
|
using System.Windows.Forms.Design; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.TextEditor; |
||||||
|
using ICSharpCode.TextEditor.Document; |
||||||
|
|
||||||
|
using ICSharpCode.FormDesigner; |
||||||
|
using ICSharpCode.FormDesigner.Services; |
||||||
|
using Boo.Lang.Parser; |
||||||
|
using Boo.Lang.Compiler.Ast; |
||||||
|
|
||||||
|
namespace Grunwald.BooBinding.Designer |
||||||
|
{ |
||||||
|
public class BooDesignerLoader : CodeDomDesignerLoader |
||||||
|
{ |
||||||
|
bool loading = true; |
||||||
|
IDesignerLoaderHost designerLoaderHost = null; |
||||||
|
ITypeResolutionService typeResolutionService = null; |
||||||
|
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider(); |
||||||
|
|
||||||
|
TextEditorControl textEditorControl; |
||||||
|
|
||||||
|
public string TextContent { |
||||||
|
get { |
||||||
|
return textEditorControl.Document.TextContent; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override bool Loading { |
||||||
|
get { |
||||||
|
return loading; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IDesignerLoaderHost DesignerLoaderHost { |
||||||
|
get { |
||||||
|
return designerLoaderHost; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override CodeDomProvider CodeDomProvider { |
||||||
|
get { |
||||||
|
return provider; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override ITypeResolutionService TypeResolutionService { |
||||||
|
get { |
||||||
|
return typeResolutionService; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected override bool IsReloadNeeded() |
||||||
|
{ |
||||||
|
return base.IsReloadNeeded() || TextContent != lastTextContent; |
||||||
|
} |
||||||
|
|
||||||
|
public BooDesignerLoader(TextEditorControl textEditorControl) |
||||||
|
{ |
||||||
|
this.textEditorControl = textEditorControl; |
||||||
|
} |
||||||
|
|
||||||
|
public override void BeginLoad(IDesignerLoaderHost host) |
||||||
|
{ |
||||||
|
this.loading = true; |
||||||
|
typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService)); |
||||||
|
base.BeginLoad(host); |
||||||
|
} |
||||||
|
|
||||||
|
protected override void OnEndLoad(bool successful, ICollection errors) |
||||||
|
{ |
||||||
|
this.loading = false; |
||||||
|
base.OnEndLoad(successful, errors); |
||||||
|
} |
||||||
|
|
||||||
|
string lastTextContent; |
||||||
|
|
||||||
|
protected override CodeCompileUnit Parse() |
||||||
|
{ |
||||||
|
LoggingService.Debug("BooDesignerLoader.Parse()"); |
||||||
|
|
||||||
|
lastTextContent = TextContent; |
||||||
|
BooParsingStep step = new BooParsingStep(); |
||||||
|
|
||||||
|
StringBuilder errors = new StringBuilder(); |
||||||
|
Module module = BooParser.ParseModule(4, new CompileUnit(), "BooDesignerLoaderModule", |
||||||
|
new StringReader(lastTextContent), |
||||||
|
delegate(antlr.RecognitionException e) { |
||||||
|
errors.AppendLine(e.ToString()); |
||||||
|
}); |
||||||
|
|
||||||
|
if (errors.Length > 0) { |
||||||
|
throw new FormDesignerLoadException(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 FormDesignerLoadException("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); |
||||||
|
|
||||||
|
LoggingService.Debug("BooDesignerLoader.Parse() finished"); |
||||||
|
return visitor.OutputCompileUnit; |
||||||
|
} |
||||||
|
|
||||||
|
protected override void Write(CodeCompileUnit unit) |
||||||
|
{ |
||||||
|
LoggingService.Info("BooDesignerLoader.Write called"); |
||||||
|
provider.GenerateCodeFromCompileUnit(unit, Console.Out, null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,410 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.CodeDom; |
||||||
|
using System.Text; |
||||||
|
using Boo.Lang.Compiler; |
||||||
|
using Boo.Lang.Compiler.Ast; |
||||||
|
using Boo.Lang.Compiler.Ast.Visitors; |
||||||
|
using Boo.Lang.Parser; |
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
|
||||||
|
namespace Grunwald.BooBinding.Designer |
||||||
|
{ |
||||||
|
/// <summary>
|
||||||
|
/// The CodeDomVisitor is able to convert from the Boo AST to System.CodeDom
|
||||||
|
/// It makes use of the SharpDevelop parser service to get necessary additional
|
||||||
|
/// information about the types.
|
||||||
|
/// </summary>
|
||||||
|
public class CodeDomVisitor : DepthFirstVisitor |
||||||
|
{ |
||||||
|
CodeCompileUnit _compileUnit = new CodeCompileUnit(); |
||||||
|
|
||||||
|
public CodeCompileUnit OutputCompileUnit { |
||||||
|
get { |
||||||
|
return _compileUnit; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
IProjectContent pc; |
||||||
|
|
||||||
|
public CodeDomVisitor(IProjectContent pc) |
||||||
|
{ |
||||||
|
this.pc = pc; |
||||||
|
} |
||||||
|
|
||||||
|
CodeNamespace _namespace; |
||||||
|
CodeTypeDeclaration _class; |
||||||
|
CodeStatementCollection _statements; |
||||||
|
CodeExpression _expression; |
||||||
|
|
||||||
|
MemberAttributes ConvModifiers(TypeMember member) |
||||||
|
{ |
||||||
|
if (member is Field) |
||||||
|
return ConvModifiers(member.Modifiers, MemberAttributes.Family); |
||||||
|
else |
||||||
|
return ConvModifiers(member.Modifiers, MemberAttributes.Public); |
||||||
|
} |
||||||
|
|
||||||
|
MemberAttributes ConvModifiers(TypeMemberModifiers modifier, MemberAttributes defaultAttr) |
||||||
|
{ |
||||||
|
MemberAttributes attr = 0; |
||||||
|
if ((modifier & TypeMemberModifiers.Abstract) == TypeMemberModifiers.Abstract) |
||||||
|
attr |= MemberAttributes.Abstract; |
||||||
|
if ((modifier & TypeMemberModifiers.Final) == TypeMemberModifiers.Final) |
||||||
|
attr |= MemberAttributes.Const; |
||||||
|
if ((modifier & TypeMemberModifiers.Internal) == TypeMemberModifiers.Internal) |
||||||
|
attr |= MemberAttributes.Assembly; |
||||||
|
if ((modifier & TypeMemberModifiers.Override) == TypeMemberModifiers.Override) |
||||||
|
attr |= MemberAttributes.Override; |
||||||
|
if ((modifier & TypeMemberModifiers.Private) == TypeMemberModifiers.Private) |
||||||
|
attr |= MemberAttributes.Private; |
||||||
|
if ((modifier & TypeMemberModifiers.Protected) == TypeMemberModifiers.Protected) |
||||||
|
attr |= MemberAttributes.Family; |
||||||
|
if ((modifier & TypeMemberModifiers.Public) == TypeMemberModifiers.Public) |
||||||
|
attr |= MemberAttributes.Public; |
||||||
|
if ((modifier & TypeMemberModifiers.Static) == TypeMemberModifiers.Static) |
||||||
|
attr |= MemberAttributes.Static; |
||||||
|
if ((modifier & TypeMemberModifiers.Virtual) != TypeMemberModifiers.Virtual) |
||||||
|
attr |= MemberAttributes.Final; |
||||||
|
if (attr == 0) |
||||||
|
return defaultAttr; |
||||||
|
else |
||||||
|
return attr; |
||||||
|
} |
||||||
|
|
||||||
|
CodeTypeReference ConvTypeRef(TypeReference tr) |
||||||
|
{ |
||||||
|
if (tr == null) return null; |
||||||
|
string name = tr.ToString(); |
||||||
|
if (BooAmbience.ReverseTypeConversionTable.ContainsKey(name)) |
||||||
|
name = BooAmbience.ReverseTypeConversionTable[name]; |
||||||
|
return new CodeTypeReference(name); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnCompileUnit(CompileUnit node) |
||||||
|
{ |
||||||
|
foreach (Module m in node.Modules) |
||||||
|
m.Accept(this); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnModule(Module node) |
||||||
|
{ |
||||||
|
if (node.Namespace == null) { |
||||||
|
_namespace = new CodeNamespace("Global"); |
||||||
|
_compileUnit.Namespaces.Add(_namespace); |
||||||
|
} else { |
||||||
|
node.Namespace.Accept(this); |
||||||
|
} |
||||||
|
foreach (Import i in node.Imports) |
||||||
|
i.Accept(this); |
||||||
|
foreach (TypeMember m in node.Members) |
||||||
|
m.Accept(this); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnNamespaceDeclaration(NamespaceDeclaration node) |
||||||
|
{ |
||||||
|
_namespace = new CodeNamespace(node.Name); |
||||||
|
_compileUnit.Namespaces.Add(_namespace); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnImport(Import node) |
||||||
|
{ |
||||||
|
_namespace.Imports.Add(new CodeNamespaceImport(node.Namespace)); |
||||||
|
} |
||||||
|
|
||||||
|
CodeTypeDeclaration ConvertTypeDefinition(TypeDefinition node) |
||||||
|
{ |
||||||
|
CodeTypeDeclaration oldClass = _class; |
||||||
|
CodeTypeDeclaration newClass = new CodeTypeDeclaration(node.Name); |
||||||
|
_class = newClass; |
||||||
|
|
||||||
|
foreach (TypeReference b in node.BaseTypes) |
||||||
|
newClass.BaseTypes.Add(ConvTypeRef(b)); |
||||||
|
|
||||||
|
foreach (TypeMember member in node.Members) |
||||||
|
member.Accept(this); |
||||||
|
|
||||||
|
if (oldClass == null) |
||||||
|
_namespace.Types.Add(newClass); |
||||||
|
else |
||||||
|
oldClass.Members.Add(newClass); |
||||||
|
_class = oldClass; |
||||||
|
return newClass; |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnClassDefinition(ClassDefinition node) |
||||||
|
{ |
||||||
|
ConvertTypeDefinition(node).IsClass = true; |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnStructDefinition(StructDefinition node) |
||||||
|
{ |
||||||
|
ConvertTypeDefinition(node).IsStruct = true; |
||||||
|
} |
||||||
|
public override void OnInterfaceDefinition(InterfaceDefinition node) |
||||||
|
{ |
||||||
|
ConvertTypeDefinition(node).IsInterface = true; |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnField(Field node) |
||||||
|
{ |
||||||
|
CodeMemberField field = new CodeMemberField(ConvTypeRef(node.Type), node.Name); |
||||||
|
field.Attributes = ConvModifiers(node); |
||||||
|
if (node.Initializer != null) { |
||||||
|
_expression = null; |
||||||
|
//Visit(node.Initializer);
|
||||||
|
field.InitExpression = _expression; |
||||||
|
} |
||||||
|
_class.Members.Add(field); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnConstructor(Boo.Lang.Compiler.Ast.Constructor node) |
||||||
|
{ |
||||||
|
ConvertMethod(node, new CodeConstructor()); |
||||||
|
} |
||||||
|
public override void OnMethod(Method node) |
||||||
|
{ |
||||||
|
CodeMemberMethod cmm = new CodeMemberMethod(); |
||||||
|
cmm.Name = node.Name; |
||||||
|
cmm.ReturnType = ConvTypeRef(node.ReturnType); |
||||||
|
ConvertMethod(node, cmm); |
||||||
|
} |
||||||
|
public override void OnDestructor(Boo.Lang.Compiler.Ast.Destructor node) |
||||||
|
{ |
||||||
|
CodeMemberMethod cmm = new CodeMemberMethod(); |
||||||
|
cmm.Name = "Finalize"; |
||||||
|
ConvertMethod(node, cmm); |
||||||
|
} |
||||||
|
void ConvertMethod(Method node, CodeMemberMethod method) |
||||||
|
{ |
||||||
|
method.Attributes = ConvModifiers(node); |
||||||
|
if (node.Parameters != null) { |
||||||
|
foreach (ParameterDeclaration p in node.Parameters) |
||||||
|
method.Parameters.Add(new CodeParameterDeclarationExpression(ConvTypeRef(p.Type), p.Name)); |
||||||
|
} |
||||||
|
_statements = method.Statements; |
||||||
|
|
||||||
|
if (node.Body != null) |
||||||
|
node.Body.Accept(this); |
||||||
|
|
||||||
|
_class.Members.Add(method); |
||||||
|
} |
||||||
|
public override void OnBinaryExpression(BinaryExpression node) |
||||||
|
{ |
||||||
|
BinaryOperatorType op = node.Operator; |
||||||
|
if (op == BinaryOperatorType.Assign) { |
||||||
|
_expression = null; |
||||||
|
node.Left.Accept(this); |
||||||
|
CodeExpression left = _expression; |
||||||
|
_expression = null; |
||||||
|
node.Right.Accept(this); |
||||||
|
if (left != null && _expression != null) |
||||||
|
_statements.Add(new CodeAssignStatement(left, _expression)); |
||||||
|
_expression = null; |
||||||
|
} |
||||||
|
} |
||||||
|
public override void OnBlock(Block node) |
||||||
|
{ |
||||||
|
foreach (Statement n in node.Statements) |
||||||
|
n.Accept(this); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnExpressionStatement(ExpressionStatement node) |
||||||
|
{ |
||||||
|
_expression = null; |
||||||
|
node.Expression.Accept(this); |
||||||
|
if (_expression != null) |
||||||
|
_statements.Add(new CodeExpressionStatement(_expression)); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnGotoStatement(GotoStatement node) |
||||||
|
{ |
||||||
|
_statements.Add(new CodeGotoStatement(node.Label.Name)); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnNullLiteralExpression(NullLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(null); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnBoolLiteralExpression(BoolLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(node.Value); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnStringLiteralExpression(StringLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(node.Value); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnCharLiteralExpression(CharLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(node.Value); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnIntegerLiteralExpression(IntegerLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(node.Value); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnDoubleLiteralExpression(DoubleLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodePrimitiveExpression(node.Value); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnMemberReferenceExpression(MemberReferenceExpression node) |
||||||
|
{ |
||||||
|
_expression = null; |
||||||
|
node.Target.Accept(this); |
||||||
|
if (_expression != null) { |
||||||
|
if (_expression is CodeTypeReferenceExpression) { |
||||||
|
string baseName = ((CodeTypeReferenceExpression)_expression).Type.BaseType; |
||||||
|
_expression = CreateMemberExpression(_expression, baseName, node.Name, true); |
||||||
|
} else { |
||||||
|
_expression = CreateMemberExpression(_expression, node.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnReferenceExpression(ReferenceExpression node) |
||||||
|
{ |
||||||
|
if (pc.GetClass(node.Name) != null) |
||||||
|
_expression = new CodeTypeReferenceExpression(node.Name); |
||||||
|
else if (pc.NamespaceExists(node.Name)) |
||||||
|
_expression = new CodeTypeReferenceExpression(node.Name); |
||||||
|
else |
||||||
|
_expression = CreateMemberExpression(new CodeThisReferenceExpression(), node.Name); |
||||||
|
} |
||||||
|
|
||||||
|
CodeExpression CreateMemberExpression(CodeExpression expr, string name) |
||||||
|
{ |
||||||
|
if (expr is CodeTypeReferenceExpression) { |
||||||
|
string typeRef = ((CodeTypeReferenceExpression)_expression).Type.BaseType; |
||||||
|
return CreateMemberExpression(expr, typeRef, name, true); |
||||||
|
} else if (expr is CodeThisReferenceExpression) { |
||||||
|
string typeRef = _namespace.Name + "." + _class.Name; |
||||||
|
return CreateMemberExpression(expr, typeRef, name, false); |
||||||
|
} else if (expr is CodeFieldReferenceExpression || expr is CodePropertyReferenceExpression) { |
||||||
|
if (_fieldReferenceType == null) |
||||||
|
return new CodePropertyReferenceExpression(expr, name); |
||||||
|
return CreateMemberExpression(expr, _fieldReferenceType.FullyQualifiedName, name, false); |
||||||
|
} else { |
||||||
|
_fieldReferenceType = null; |
||||||
|
return new CodePropertyReferenceExpression(expr, name); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
IReturnType _fieldReferenceType; |
||||||
|
|
||||||
|
CodeExpression CreateMemberExpression(CodeExpression target, string parentName, string name, bool isStatic) |
||||||
|
{ |
||||||
|
_fieldReferenceType = null; |
||||||
|
|
||||||
|
string combinedName = parentName + "." + name; |
||||||
|
if (pc.GetClass(combinedName) != null) |
||||||
|
return new CodeTypeReferenceExpression(combinedName); |
||||||
|
else if (pc.NamespaceExists(combinedName)) |
||||||
|
return new CodeTypeReferenceExpression(combinedName); |
||||||
|
|
||||||
|
GetClassReturnType rt = new GetClassReturnType(pc, parentName, 0); |
||||||
|
foreach (IProperty prop in rt.GetProperties()) { |
||||||
|
if (prop.IsStatic == isStatic && prop.Name == name) { |
||||||
|
_fieldReferenceType = prop.ReturnType; |
||||||
|
return new CodePropertyReferenceExpression(target, name); |
||||||
|
} |
||||||
|
} |
||||||
|
foreach (IEvent ev in rt.GetEvents()) { |
||||||
|
if (ev.IsStatic == isStatic && ev.Name == name) { |
||||||
|
_fieldReferenceType = ev.ReturnType; |
||||||
|
return new CodeEventReferenceExpression(target, name); |
||||||
|
} |
||||||
|
} |
||||||
|
foreach (IMethod me in rt.GetMethods()) { |
||||||
|
if (me.IsStatic == isStatic && me.Name == name) { |
||||||
|
_fieldReferenceType = me.ReturnType; |
||||||
|
return new CodeMethodReferenceExpression(target, name); |
||||||
|
} |
||||||
|
} |
||||||
|
foreach (IField field in rt.GetFields()) { |
||||||
|
if (field.IsStatic == isStatic && field.Name == name) { |
||||||
|
_fieldReferenceType = field.ReturnType; |
||||||
|
return new CodeFieldReferenceExpression(target, name); |
||||||
|
} |
||||||
|
} |
||||||
|
// unknown member, guess:
|
||||||
|
if (char.IsUpper(name, 0)) |
||||||
|
return new CodePropertyReferenceExpression(target, name); |
||||||
|
else |
||||||
|
return new CodeFieldReferenceExpression(target, name); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnAstLiteralExpression(AstLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodeObjectCreateExpression(node.Node.GetType()); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnMethodInvocationExpression(MethodInvocationExpression node) |
||||||
|
{ |
||||||
|
_expression = null; |
||||||
|
node.Target.Accept(this); |
||||||
|
if (_expression != null) { |
||||||
|
CodeMethodInvokeExpression cmie; |
||||||
|
CodeObjectCreateExpression coce; |
||||||
|
|
||||||
|
if (_expression is CodeTypeReferenceExpression) { |
||||||
|
coce = new CodeObjectCreateExpression(((CodeTypeReferenceExpression)_expression).Type); |
||||||
|
ConvertExpressions(coce.Parameters, node.Arguments); |
||||||
|
_expression = coce; |
||||||
|
} else if (_expression is CodeMethodReferenceExpression) { |
||||||
|
cmie = new CodeMethodInvokeExpression((CodeMethodReferenceExpression)_expression); |
||||||
|
ConvertExpressions(cmie.Parameters, node.Arguments); |
||||||
|
_expression = cmie; |
||||||
|
} else if (_expression is CodeFieldReferenceExpression) { |
||||||
|
// when a type is unknown, a MemberReferenceExpression is translated into a CodeFieldReferenceExpression
|
||||||
|
CodeFieldReferenceExpression cfre = (CodeFieldReferenceExpression)_expression; |
||||||
|
cmie = new CodeMethodInvokeExpression(cfre.TargetObject, cfre.FieldName); |
||||||
|
ConvertExpressions(cmie.Parameters, node.Arguments); |
||||||
|
_expression = cmie; |
||||||
|
} else { |
||||||
|
_expression = null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary>Converts a list of expressions to CodeDom expressions.</summary>
|
||||||
|
void ConvertExpressions(CodeExpressionCollection args, ExpressionCollection expressions) |
||||||
|
{ |
||||||
|
foreach (Expression e in expressions) { |
||||||
|
_expression = null; |
||||||
|
e.Accept(this); |
||||||
|
args.Add(_expression); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnReturnStatement(ReturnStatement node) |
||||||
|
{ |
||||||
|
_expression = null; |
||||||
|
if (node.Expression != null) |
||||||
|
node.Expression.Accept(this); |
||||||
|
_statements.Add(new CodeMethodReturnStatement(_expression)); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnSelfLiteralExpression(SelfLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodeThisReferenceExpression(); |
||||||
|
} |
||||||
|
|
||||||
|
public override void OnSuperLiteralExpression(SuperLiteralExpression node) |
||||||
|
{ |
||||||
|
_expression = new CodeBaseReferenceExpression(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
using ICSharpCode.SharpDevelop.Gui; |
||||||
|
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.FormDesigner; |
||||||
|
using ICSharpCode.TextEditor; |
||||||
|
|
||||||
|
namespace Grunwald.BooBinding.Designer |
||||||
|
{ |
||||||
|
public class FormDesignerDisplayBinding : ISecondaryDisplayBinding |
||||||
|
{ |
||||||
|
public bool CanAttachTo(IViewContent viewContent) |
||||||
|
{ |
||||||
|
if (viewContent is ITextEditorControlProvider) { |
||||||
|
ITextEditorControlProvider textAreaControlProvider = (ITextEditorControlProvider)viewContent; |
||||||
|
string fileExtension = String.Empty; |
||||||
|
string fileName = viewContent.IsUntitled ? viewContent.UntitledName : viewContent.FileName; |
||||||
|
if (fileName == null) |
||||||
|
return false; |
||||||
|
if (Path.GetExtension(fileName).Equals(".boo", StringComparison.InvariantCultureIgnoreCase)) { |
||||||
|
ParseInformation info = ParserService.ParseFile(fileName, textAreaControlProvider.TextEditorControl.Document.TextContent, false, true); |
||||||
|
if (FormDesignerSecondaryDisplayBinding.IsDesignable(info)) |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public ISecondaryViewContent[] CreateSecondaryViewContent(IViewContent viewContent) |
||||||
|
{ |
||||||
|
IDesignerLoaderProvider loader = new BooDesignerLoaderProvider(((ITextEditorControlProvider)viewContent).TextEditorControl); |
||||||
|
IDesignerGenerator generator = new BooDesignerGenerator(); |
||||||
|
return new ISecondaryViewContent[] { new FormDesignerViewContent(viewContent, loader, generator) }; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class BooDesignerLoaderProvider : IDesignerLoaderProvider |
||||||
|
{ |
||||||
|
TextEditorControl textEditorControl; |
||||||
|
|
||||||
|
public BooDesignerLoaderProvider(TextEditorControl textEditorControl) |
||||||
|
{ |
||||||
|
this.textEditorControl = textEditorControl; |
||||||
|
} |
||||||
|
|
||||||
|
public System.ComponentModel.Design.Serialization.DesignerLoader CreateLoader() |
||||||
|
{ |
||||||
|
return new BooDesignerLoader(textEditorControl); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,249 @@ |
|||||||
|
// <file>
|
||||||
|
// <copyright see="prj:///doc/copyright.txt">2002-2005 AlphaSierraPapa</copyright>
|
||||||
|
// <license see="prj:///doc/license.txt">GNU General Public License</license>
|
||||||
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||||
|
// <version>$Revision$</version>
|
||||||
|
// </file>
|
||||||
|
|
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
using System.Collections; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Drawing; |
||||||
|
using System.Reflection; |
||||||
|
using System.ComponentModel; |
||||||
|
using System.ComponentModel.Design; |
||||||
|
|
||||||
|
using ICSharpCode.SharpDevelop.Gui; |
||||||
|
using ICSharpCode.SharpDevelop.Dom; |
||||||
|
using ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor; |
||||||
|
|
||||||
|
using ICSharpCode.Core; |
||||||
|
|
||||||
|
namespace ICSharpCode.FormDesigner |
||||||
|
{ |
||||||
|
public abstract class AbstractDesignerGenerator : IDesignerGenerator |
||||||
|
{ |
||||||
|
IClass c; |
||||||
|
IMethod initializeComponents; |
||||||
|
|
||||||
|
FormDesignerViewContent viewContent; |
||||||
|
bool failedDesignerInitialize = false; |
||||||
|
|
||||||
|
public const string NonVisualComponentContainerName = "components"; |
||||||
|
|
||||||
|
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) |
||||||
|
{ |
||||||
|
try { |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
foreach (IField field in c.Fields) { |
||||||
|
if (field.Name == e.Component.Site.Name) { |
||||||
|
int startOffset = viewContent.Document.PositionToOffset(new Point(0, field.Region.BeginLine - 1)); |
||||||
|
int endOffset = viewContent.Document.PositionToOffset(new Point(0, field.Region.EndLine)); |
||||||
|
viewContent.Document.Remove(startOffset, endOffset - startOffset); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception ex) { |
||||||
|
MessageService.ShowError(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract string GenerateFieldDeclaration(Type fieldType, string name); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the tabs in front of the InitializeComponents declaration.
|
||||||
|
/// Used to indent the fields and generated statements.
|
||||||
|
/// </summary>
|
||||||
|
protected string tabs; |
||||||
|
|
||||||
|
void ComponentAdded(object sender, ComponentEventArgs e) |
||||||
|
{ |
||||||
|
try { |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
int endOffset = viewContent.Document.PositionToOffset(new Point(0, initializeComponents.BodyRegion.EndLine)); |
||||||
|
viewContent.Document.Insert(endOffset, tabs + GenerateFieldDeclaration(e.Component.GetType(), e.Component.Site.Name) + Environment.NewLine); |
||||||
|
if (CodeDOMGenerator.IsNonVisualComponent(viewContent.Host, e.Component)) { |
||||||
|
if (!IsNonVisualComponentContainerDefined) { |
||||||
|
viewContent.Document.Insert(endOffset, tabs + GenerateFieldDeclaration(typeof(Container), NonVisualComponentContainerName) + Environment.NewLine); |
||||||
|
} |
||||||
|
} |
||||||
|
} catch (Exception ex) { |
||||||
|
MessageService.ShowError(ex); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void ComponentRenamed(object sender, ComponentRenameEventArgs e) |
||||||
|
{ |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
foreach (IField field in c.Fields) { |
||||||
|
if (field.Name == e.OldName) { |
||||||
|
int startOffset = viewContent.Document.PositionToOffset(new Point(0, field.Region.BeginLine - 1)); |
||||||
|
int endOffset = viewContent.Document.PositionToOffset(new Point(0, field.Region.EndLine)); |
||||||
|
viewContent.Document.Replace(startOffset, endOffset - startOffset, tabs + GenerateFieldDeclaration(e.Component.GetType(), e.NewName) + Environment.NewLine); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract System.CodeDom.Compiler.CodeDomProvider CreateCodeProvider(); |
||||||
|
|
||||||
|
public void MergeFormChanges() |
||||||
|
{ |
||||||
|
if (tabs == null) Reparse(viewContent.Document.TextContent); |
||||||
|
|
||||||
|
// generate file and get initialize components string
|
||||||
|
StringWriter writer = new StringWriter(); |
||||||
|
new CodeDOMGenerator(viewContent.Host, CreateCodeProvider(), tabs + '\t').ConvertContentDefinition(writer); |
||||||
|
string statements = writer.ToString(); |
||||||
|
|
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
|
||||||
|
int startOffset = viewContent.Document.PositionToOffset(new Point(0, initializeComponents.BodyRegion.BeginLine + 1)); |
||||||
|
int endOffset = viewContent.Document.PositionToOffset(new Point(0, initializeComponents.BodyRegion.EndLine - 1)); |
||||||
|
|
||||||
|
viewContent.Document.Replace(startOffset, endOffset - startOffset, statements); |
||||||
|
} |
||||||
|
|
||||||
|
protected void Reparse(string content) |
||||||
|
{ |
||||||
|
// get new initialize components
|
||||||
|
ParseInformation info = ParserService.ParseFile(viewContent.TextEditorControl.FileName, content, false, true); |
||||||
|
ICompilationUnit cu = (ICompilationUnit)info.BestCompilationUnit; |
||||||
|
foreach (IClass c in cu.Classes) { |
||||||
|
if (FormDesignerSecondaryDisplayBinding.BaseClassIsFormOrControl(c)) { |
||||||
|
initializeComponents = FormDesignerSecondaryDisplayBinding.GetInitializeComponents(c); |
||||||
|
if (initializeComponents != null) { |
||||||
|
using (StringReader r = new StringReader(content)) { |
||||||
|
int count = initializeComponents.Region.BeginLine; |
||||||
|
for (int i = 1; i < count; i++) |
||||||
|
r.ReadLine(); |
||||||
|
string line = r.ReadLine(); |
||||||
|
tabs = line.Substring(0, line.Length - line.TrimStart().Length); |
||||||
|
} |
||||||
|
this.c = c; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
protected abstract string CreateEventHandler(EventDescriptor edesc, string eventMethodName, string body); |
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If found return true and int as position
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="component"></param>
|
||||||
|
/// <param name="edesc"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool InsertComponentEvent(IComponent component, EventDescriptor edesc, string eventMethodName, string body, out int position) |
||||||
|
{ |
||||||
|
if (this.failedDesignerInitialize) { |
||||||
|
position = 0; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
|
||||||
|
foreach (IMethod method in c.Methods) { |
||||||
|
if (method.Name == eventMethodName) { |
||||||
|
position = method.Region.BeginLine + 1; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
MergeFormChanges(); |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
|
||||||
|
position = c.Region.EndLine + 1; |
||||||
|
|
||||||
|
int offset = viewContent.Document.GetLineSegment(c.Region.EndLine - 1).Offset; |
||||||
|
|
||||||
|
viewContent.Document.Insert(offset, CreateEventHandler(edesc, eventMethodName, body)); |
||||||
|
viewContent.Document.FormattingStrategy.IndentLines(viewContent.TextEditorControl.ActiveTextAreaControl.TextArea, c.Region.EndLine - 1, c.Region.EndLine + 3); |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public ICollection GetCompatibleMethods(EventDescriptor edesc) |
||||||
|
{ |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
ArrayList compatibleMethods = new ArrayList(); |
||||||
|
MethodInfo methodInfo = edesc.EventType.GetMethod("Invoke"); |
||||||
|
foreach (IMethod method in c.Methods) { |
||||||
|
if (method.Parameters.Count == methodInfo.GetParameters().Length) { |
||||||
|
bool found = true; |
||||||
|
for (int i = 0; i < methodInfo.GetParameters().Length; ++i) { |
||||||
|
ParameterInfo pInfo = methodInfo.GetParameters()[i]; |
||||||
|
IParameter p = method.Parameters[i]; |
||||||
|
if (p.ReturnType.FullyQualifiedName != pInfo.ParameterType.ToString()) { |
||||||
|
found = false; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (found) { |
||||||
|
compatibleMethods.Add(method.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return compatibleMethods; |
||||||
|
} |
||||||
|
|
||||||
|
public ICollection GetCompatibleMethods(EventInfo edesc) |
||||||
|
{ |
||||||
|
Reparse(viewContent.Document.TextContent); |
||||||
|
ArrayList compatibleMethods = new ArrayList(); |
||||||
|
MethodInfo methodInfo = edesc.GetAddMethod(); |
||||||
|
ParameterInfo pInfo = methodInfo.GetParameters()[0]; |
||||||
|
string eventName = pInfo.ParameterType.ToString().Replace("EventHandler", "EventArgs"); |
||||||
|
|
||||||
|
foreach (IMethod method in c.Methods) { |
||||||
|
if (method.Parameters.Count == 2) { |
||||||
|
bool found = true; |
||||||
|
|
||||||
|
IParameter p = method.Parameters[1]; |
||||||
|
if (p.ReturnType.FullyQualifiedName != eventName) { |
||||||
|
found = false; |
||||||
|
} |
||||||
|
if (found) { |
||||||
|
compatibleMethods.Add(method.Name); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return compatibleMethods; |
||||||
|
} |
||||||
|
|
||||||
|
bool IsNonVisualComponentContainerDefined |
||||||
|
{ |
||||||
|
get { |
||||||
|
return GetField(c, NonVisualComponentContainerName) != null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
IField GetField(IClass c, string name) |
||||||
|
{ |
||||||
|
foreach (IField field in c.Fields) { |
||||||
|
if (field.Name == name) { |
||||||
|
return field; |
||||||
|
} |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue