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;
		}
		static CodeCompileUnit ParseInternal (TextReader codeStream)
		{
			IParser parser = ParserFactory.CreateParser (
				SupportedLanguage.CSharp,
				codeStream);
			parser.ParseMethodBodies = true;
			parser.Parse ();
			
			if (parser.Errors.Count > 0)
				throw new ArgumentException (parser.Errors.ErrorOutput);
			
			CodeDomVisitor cdv = new CodeDomVisitor (); // new CodeDomVisitor (parser.Lexer.SpecialTracker.CurrentSpecials);
			parser.CompilationUnit.AcceptVisitor (cdv, null);
			
			parser.Dispose ();
			
			CodeCompileUnit ccu = cdv.codeCompileUnit;
			
			//C# parser seems to insist on putting imports in the "Global" namespace; fix it up
			for (int i = 0; i < ccu.Namespaces.Count; i++) {
				CodeNamespace global = ccu.Namespaces [i];
				if ((global.Name == "Global") && (global.Types.Count == 0)) {
					global.Name = "";
					ccu.Namespaces.RemoveAt (i);
					ccu.Namespaces.Insert (0, global);
					
					//clear out repeat imports...
					for (int j = 1; j < ccu.Namespaces.Count; j++) {
						CodeNamespace cn = ccu.Namespaces [j];
						
						//why can't we remove imports? will have to collect ones to keep
						//then clear and refill
						CodeNamespaceImportCollection imps = new CodeNamespaceImportCollection ();
						
						for (int m = 0; m < cn.Imports.Count; m++) {
							bool found = false;
							
							for (int n = 0; n < global.Imports.Count; n++)
								if (global.Imports [n] == cn.Imports [m])
									found = true;
						
							if (!found)
								imps.Add (cn.Imports [m]);
						}
						
						cn.Imports.Clear ();
						
						foreach (CodeNamespaceImport imp in imps)
							cn.Imports.Add (imp);
					}
					
					break;
				}
			}
			return ccu;
		}
        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;
                }
            }
        }
			static void AddAttributes (AbstractMember member, IEnumerable<ICSharpCode.NRefactory.Ast.AttributeSection> attributes)
			{
				CodeDomVisitor domVisitor = new CodeDomVisitor ();
				foreach (ICSharpCode.NRefactory.Ast.AttributeSection attributeSection in attributes) {
					foreach (ICSharpCode.NRefactory.Ast.Attribute attribute in attributeSection.Attributes) {
						DomAttribute domAttribute = new DomAttribute ();
						domAttribute.Name = attribute.Name;
						domAttribute.Region = ConvertRegion (attribute.StartLocation, attribute.EndLocation);
						domAttribute.AttributeType = new DomReturnType (attribute.Name);
						member.Add (domAttribute);
						foreach (ICSharpCode.NRefactory.Ast.Expression exp in attribute.PositionalArguments)
							domAttribute.AddPositionalArgument ((CodeExpression)exp.AcceptVisitor (domVisitor, null));
						foreach (ICSharpCode.NRefactory.Ast.NamedArgumentExpression nexp in attribute.NamedArguments)
							domAttribute.AddNamedArgument (nexp.Name, (CodeExpression)nexp.Expression.AcceptVisitor (domVisitor, null));
					}
				}
			}
示例#5
0
		// 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;
		}