protected override CodeCompileUnit Parse () { ICSharpCode.NRefactory.IParser parser = ICSharpCode.NRefactory.ParserFactory.CreateParser (_designerFile); parser.Parse (); CodeDomVisitor visitor = new CodeDomVisitor (); visitor.VisitCompilationUnit (parser.CompilationUnit, null); return visitor.codeCompileUnit; }
public TemplateMemberGenerator(CodeGenerationContext context) { Context = context; if (!String.IsNullOrEmpty(context.Model.MemberTemplateFile)) { string templateFile = context.Model.MemberTemplateFile; if (!Path.IsPathRooted(templateFile)) templateFile = Helper.FindFile(context.ModelFilePath, templateFile); if (templateFile == null || !File.Exists(templateFile)) throw new FileNotFoundException("Template file not found", context.Model.MemberTemplateFile); SupportedLanguage language; if (templateFile.EndsWith(".cs", StringComparison.InvariantCultureIgnoreCase)) language = SupportedLanguage.CSharp; else if (templateFile.EndsWith(".vb", StringComparison.InvariantCultureIgnoreCase)) language = SupportedLanguage.VBNet; else throw new Exception("Only .cs and .vb files are supported for MemberTemplateFile."); using (StreamReader reader = new StreamReader(templateFile)) { IParser parser = ParserFactory.CreateParser(language, reader); parser.Parse(); if (parser.Errors.Count > 0) throw new Exception("Error detected parsing MemberTemplateFile."); CodeDomVisitor visit = new CodeDomVisitor(); visit.VisitCompilationUnit(parser.CompilationUnit, null); // Remove Unsed Namespaces for (int i = visit.codeCompileUnit.Namespaces.Count - 1; i >= 0; i--) { if (visit.codeCompileUnit.Namespaces[i].Types.Count == 0) { visit.codeCompileUnit.Namespaces.RemoveAt(i); } } TemplateCompileUnit = visit.codeCompileUnit; } } }
// The .Designer partial file produced by Visual Studio and SharpDevelop // does not specify the inherited type. The type is specified in the // non-designer generated file.E.g: // // partial Form1 - in Form1.Designer.cs // partial Form1 : Form - in Form1.cs // private CodeCompileUnit MergeParse (string fileName, string codeBehindFileName) { CodeCompileUnit mergedUnit = null; // parse codebehind IParser codeBehindParser = ICSharpCode.NRefactory.ParserFactory.CreateParser (codeBehindFileName); codeBehindParser.Parse (); // get the first valid typedeclaration name CodeDomVisitor visitor = new CodeDomVisitor (); visitor.VisitCompilationUnit (codeBehindParser.CompilationUnit, null); mergedUnit = visitor.codeCompileUnit; string codeBehindNamespaceName = null; CodeTypeDeclaration codeBehindType = GetFirstValidType (visitor.codeCompileUnit, out codeBehindNamespaceName); if (codeBehindType == null) throw new InvalidOperationException ("No class with an InitializeComponent method found"); // parse file without the method bodies IParser fileParser = ICSharpCode.NRefactory.ParserFactory.CreateParser (fileName); fileParser.ParseMethodBodies = false; fileParser.Parse (); // match declaration name from codebehind and get the type visitor = new CodeDomVisitor (); visitor.VisitCompilationUnit (fileParser.CompilationUnit, null); foreach (CodeNamespace namesp in visitor.codeCompileUnit.Namespaces) { if (namesp.Name == codeBehindNamespaceName) { foreach (CodeTypeDeclaration declaration in namesp.Types) { if (declaration.Name == codeBehindType.Name) { foreach (CodeTypeReference baseType in declaration.BaseTypes) codeBehindType.BaseTypes.Add (baseType); } } } } fileParser.Dispose (); codeBehindParser.Dispose (); return mergedUnit; }
// Steps to load the designer: // - Parse main file // - Find other files containing parts of the form // - Parse all files and look for fields (for controls) and InitializeComponents method // - Create CodeDom objects for fields and InitializeComponents statements // - If debug build and Ctrl pressed, output CodeDom to console // - Return CodeDom objects to the .NET designer protected override CodeCompileUnit Parse() { LoggingService.Debug("NRefactoryDesignerLoader.Parse()"); lastTextContent = this.Generator.ViewContent.DesignerCodeFileContent; ParseInformation parseInfo = ParserService.GetParseInformation(this.Generator.ViewContent.DesignerCodeFile.FileName); IClass formClass; bool isFirstClassInFile; IList<IClass> parts = FindFormClassParts(parseInfo, out formClass, out isFirstClassInFile); const string missingReferenceMessage = "Your project is missing a reference to '${Name}' - please add it using 'Project > Add Reference'."; if (formClass.ProjectContent.GetClass("System.Drawing.Point", 0) == null) { throw new FormsDesignerLoadException(StringParser.Parse(missingReferenceMessage, new StringTagPair("Name", "System.Drawing"))); } if (formClass.ProjectContent.GetClass("System.Windows.Forms.Form", 0) == null) { throw new FormsDesignerLoadException(StringParser.Parse(missingReferenceMessage, new StringTagPair("Name" , "System.Windows.Forms"))); } List<KeyValuePair<string, CompilationUnit>> compilationUnits = new List<KeyValuePair<string, CompilationUnit>>(); bool foundInitMethod = false; foreach (IClass part in parts) { string fileName = part.CompilationUnit.FileName; if (fileName == null) continue; bool found = false; foreach (KeyValuePair<string, CompilationUnit> entry in compilationUnits) { if (FileUtility.IsEqualFileName(fileName, entry.Key)) { found = true; break; } } if (found) continue; ITextBuffer fileContent; if (FileUtility.IsEqualFileName(fileName, this.Generator.ViewContent.PrimaryFileName)) { fileContent = this.Generator.ViewContent.PrimaryFileContent; } else if (FileUtility.IsEqualFileName(fileName, this.Generator.ViewContent.DesignerCodeFile.FileName)) { fileContent = new StringTextBuffer(this.Generator.ViewContent.DesignerCodeFileContent); } else { fileContent = ParserService.GetParseableFileContent(fileName); } ICSharpCode.NRefactory.IParser p = ICSharpCode.NRefactory.ParserFactory.CreateParser(language, fileContent.CreateReader()); p.Parse(); if (p.Errors.Count > 0) { throw new FormsDesignerLoadException("Syntax errors in " + fileName + ":\r\n" + p.Errors.ErrorOutput); } // Try to fix the type names to fully qualified ones FixTypeNames(p.CompilationUnit, part.CompilationUnit, ref foundInitMethod); compilationUnits.Add(new KeyValuePair<string, CompilationUnit>(fileName, p.CompilationUnit)); } if (!foundInitMethod) throw new FormsDesignerLoadException("The InitializeComponent method was not found. Designer cannot be loaded."); CompilationUnit combinedCu = new CompilationUnit(); NamespaceDeclaration nsDecl = new NamespaceDeclaration(formClass.Namespace); combinedCu.AddChild(nsDecl); TypeDeclaration formDecl = new TypeDeclaration(Modifiers.Public, null); nsDecl.AddChild(formDecl); formDecl.Name = formClass.Name; foreach (KeyValuePair<string, CompilationUnit> entry in compilationUnits) { foreach (object o in entry.Value.Children) { TypeDeclaration td = o as TypeDeclaration; if (td != null && td.Name == formDecl.Name) { foreach (INode node in td.Children) formDecl.AddChild(node); formDecl.BaseTypes.AddRange(td.BaseTypes); } if (o is NamespaceDeclaration) { foreach (object o2 in ((NamespaceDeclaration)o).Children) { td = o2 as TypeDeclaration; if (td != null && td.Name == formDecl.Name) { foreach (INode node in td.Children) formDecl.AddChild(node); formDecl.BaseTypes.AddRange(td.BaseTypes); } } } } } CodeDomVisitor visitor = new CodeDomVisitor(); visitor.EnvironmentInformationProvider = new ICSharpCode.SharpDevelop.Dom.NRefactoryResolver.NRefactoryInformationProvider(formClass.ProjectContent); visitor.VisitCompilationUnit(combinedCu, null); // output generated CodeDOM to the console : #if DEBUG if ((Control.ModifierKeys & Keys.Control) == Keys.Control) { CodeDomVerboseOutputGenerator outputGenerator = new CodeDomVerboseOutputGenerator(); outputGenerator.GenerateCodeFromMember(visitor.codeCompileUnit.Namespaces[0].Types[0], Console.Out, null); this.CodeDomProvider.GenerateCodeFromCompileUnit(visitor.codeCompileUnit, Console.Out, null); } #endif LoggingService.Debug("NRefactoryDesignerLoader.Parse() finished"); if (!isFirstClassInFile) { MessageService.ShowWarning("The form must be the first class in the file in order for form resources be compiled correctly.\n" + "Please move other classes below the form class definition or move them to other files."); } return visitor.codeCompileUnit; }