You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.5 KiB
208 lines
6.5 KiB
// <file> |
|
// <copyright see="prj:///doc/copyright.txt"/> |
|
// <license see="prj:///doc/license.txt"/> |
|
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/> |
|
// <version>$Revision$</version> |
|
// </file> |
|
|
|
using System; |
|
using System.Collections.Generic; |
|
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.SharpDevelop.Dom; |
|
using ICSharpCode.TextEditor; |
|
using ICSharpCode.TextEditor.Document; |
|
|
|
using ICSharpCode.FormsDesigner; |
|
using ICSharpCode.FormsDesigner.Services; |
|
using Boo.Lang.Parser; |
|
using Boo.Lang.Compiler.Ast; |
|
|
|
namespace Grunwald.BooBinding.Designer |
|
{ |
|
public class BooDesignerLoader : CodeDomDesignerLoader |
|
{ |
|
bool loading = true; |
|
IDesignerLoaderHost designerLoaderHost = null; |
|
IDesignerGenerator generator; |
|
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, IDesignerGenerator generator) |
|
{ |
|
this.textEditorControl = textEditorControl; |
|
this.generator = generator; |
|
} |
|
|
|
public override void BeginLoad(IDesignerLoaderHost host) |
|
{ |
|
this.loading = true; |
|
typeResolutionService = (ITypeResolutionService)host.GetService(typeof(ITypeResolutionService)); |
|
base.BeginLoad(host); |
|
} |
|
|
|
protected override void OnEndLoad(bool successful, System.Collections.ICollection errors) |
|
{ |
|
this.loading = false; |
|
base.OnEndLoad(successful, errors); |
|
} |
|
|
|
string lastTextContent; |
|
|
|
protected override CodeCompileUnit Parse() |
|
{ |
|
LoggingService.Debug("BooDesignerLoader.Parse()"); |
|
try { |
|
CodeCompileUnit ccu = ParseForm(); |
|
LoggingService.Debug("BooDesignerLoader.Parse() finished"); |
|
return ccu; |
|
} catch (Boo.Lang.Compiler.CompilerError ex) { |
|
throw new FormsDesignerLoadException(ex.ToString(true)); |
|
} |
|
} |
|
|
|
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(), fileName, |
|
new StringReader(fileContent), |
|
delegate(antlr.RecognitionException e) { |
|
errors.AppendLine(e.ToString()); |
|
}); |
|
|
|
if (errors.Length > 0) { |
|
throw new FormsDesignerLoadException("Syntax errors in " + fileName + ":\r\n" + errors.ToString()); |
|
} |
|
return module; |
|
} |
|
|
|
protected override void Write(CodeCompileUnit unit) |
|
{ |
|
LoggingService.Info("BooDesignerLoader.Write called"); |
|
try { |
|
generator.MergeFormChanges(unit); |
|
} catch (Exception ex) { |
|
MessageService.ShowError(ex); |
|
} |
|
} |
|
} |
|
}
|
|
|