void GenerateInternal (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			var dnp = file.Project as DotNetProject;
			if (dnp == null || dnp.LanguageName != "C#") {
				var msg = "Razor templates are only supported in C# projects";
				result.Errors.Add (new CompilerError (file.Name, -1, -1, null, msg));
				monitor.Log.WriteLine (msg);
				return;
			}

			var host = PreprocessedRazorHost.Create (file.FilePath);

			var defaultOutputName = file.FilePath.ChangeExtension (".cs");

			var ns = GetNamespaceHint (file, defaultOutputName);
			host.DefaultNamespace = ns;

			CompilerErrorCollection errors;
			var code = host.GenerateCode (out errors);
			result.Errors.AddRange (errors);

			var writer = new MonoDevelop.DesignerSupport.CodeBehindWriter ();
			writer.WriteFile (defaultOutputName, code);
			writer.WriteOpenFiles ();

			result.GeneratedFilePath = defaultOutputName;

			foreach (var err in result.Errors) {
				monitor.Log.WriteLine (err.ToString ());
			}
		}
		static void GenerateInternal (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			if (file.Project.SupportedLanguages.All (l => l != "C#")) {
				const string msg = "Razor templates are only supported in C# projects";
				result.Errors.Add (new CompilerError (file.Name, -1, -1, null, msg));
				monitor.Log.WriteLine (msg);
				return;
			}

			var host = new PreprocessedRazorHost (file.FilePath);

			var defaultOutputName = file.FilePath.ChangeExtension (".cs");

			var ns = CustomToolService.GetFileNamespace (file, defaultOutputName);
			host.DefaultNamespace = ns;

			CompilerErrorCollection errors;
			var code = host.GenerateCode (out errors);
			result.Errors.AddRange (errors);

			var writer = new MonoDevelop.DesignerSupport.CodeBehindWriter ();
			writer.WriteFile (defaultOutputName, code);
			writer.WriteOpenFiles ();

			result.GeneratedFilePath = defaultOutputName;

			foreach (var err in result.Errors) {
				monitor.Log.WriteLine (err);
			}
		}
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (delegate {
				var dnp = file.Project as DotNetProject;
				if (dnp == null) {
					var err = "ResXFileCodeGenerator can only be used with .NET projects";
					result.Errors.Add (new CompilerError (null, 0, 0, null, err));
					return;
				}

				var provider = dnp.LanguageBinding.GetCodeDomProvider ();
				if (provider == null) {
					var err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
					result.Errors.Add (new CompilerError (null, 0, 0, null, err));
					return;
				}

				var outputfile = file.FilePath.ChangeExtension (".Designer." + provider.FileExtension);
				var ns = CustomToolService.GetFileNamespace (file, outputfile);
				var cn = provider.CreateValidIdentifier (file.FilePath.FileNameWithoutExtension);

				string[] unmatchable;
				var ccu = StronglyTypedResourceBuilder.Create (file.FilePath, cn, ns, provider, true, out unmatchable);

				foreach (var p in unmatchable) {
					var msg = string.Format ("Could not generate property for resource ID '{0}'", p);
					result.Errors.Add (new CompilerError (file.FilePath, 0, 0, null, msg));
				}

				using (var w = new StreamWriter (outputfile, false, Encoding.UTF8))
					provider.GenerateCodeFromCompileUnit (ccu, w, new CodeGeneratorOptions ());

				result.GeneratedFilePath = outputfile;
			}, result);
		}
        static void Update(IProgressMonitor monitor, IEnumerator <ProjectFile> fileEnumerator, bool force, int succeeded, int warnings, int errors)
        {
            ProjectFile           file = fileEnumerator.Current;
            ISingleFileCustomTool tool;
            ProjectFile           genFile;

            bool shouldRun;

            while (!(shouldRun = ShouldRunGenerator(file, force, out tool, out genFile)) && fileEnumerator.MoveNext())
            {
                continue;
            }

            //no files which can be generated in remaining elements of the collection, nothing to do
            if (!shouldRun)
            {
                WriteSummaryResults(monitor, succeeded, warnings, errors);
                return;
            }

            TaskService.Errors.ClearByOwner(file);

            var result = new SingleFileCustomToolResult();

            monitor.BeginTask(GettextCatalog.GetString("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);

            try {
                IAsyncOperation op = tool.Generate(monitor, file, result);
                op.Completed += delegate {
                    if (result.Success)
                    {
                        monitor.Log.WriteLine(GettextCatalog.GetString("File '{0}' was generated successfully.", result.GeneratedFilePath));
                        succeeded++;
                    }
                    else if (result.SuccessWithWarnings)
                    {
                        monitor.Log.WriteLine(GettextCatalog.GetString("File '{0}' was generated with warnings.", result.GeneratedFilePath));
                        warnings++;
                    }
                    else
                    {
                        monitor.Log.WriteLine(GettextCatalog.GetString("Errors in file '{0}' generation.", result.GeneratedFilePath));
                        errors++;
                    }

                    //check that we can process further. If UpdateCompleted returns `true` this means no errors or non-fatal errors occured
                    if (UpdateCompleted(monitor, null, file, genFile, result, true) && fileEnumerator.MoveNext())
                    {
                        Update(monitor, fileEnumerator, force, succeeded, warnings, errors);
                    }
                    else
                    {
                        WriteSummaryResults(monitor, succeeded, warnings, errors);
                    }
                };
            } catch (Exception ex) {
                result.UnhandledException = ex;
                UpdateCompleted(monitor, null, file, genFile, result, true);
            }
        }
		private void HandleException(Exception ex, ProjectFile file, SingleFileCustomToolResult result)
		{
			if (ex is SpecFlowParserException)
			{
				SpecFlowParserException sfpex = (SpecFlowParserException) ex;
			                
				if (sfpex.ErrorDetails == null || sfpex.ErrorDetails.Count == 0)
				{
					result.UnhandledException = ex;
				}
				else
				{
					var compilerErrors = new CompilerErrorCollection();
					
					foreach (var errorDetail in sfpex.ErrorDetails)
					{
						var compilerError = new CompilerError(file.Name, errorDetail.ForcedLine, errorDetail.ForcedColumn, "0", errorDetail.Message);
						compilerErrors.Add(compilerError);
					}
							
					result.Errors.AddRange(compilerErrors);
				}
			}
			else
			{
				result.UnhandledException = ex;
			}
		}
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (delegate {
				try {
					GenerateInternal (monitor, file, result);
				} catch (Exception ex) {
					result.UnhandledException = ex;
				}
			}, result);
		}
		public async Task Generate (ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			var buildResult = await file.Project.PerformGeneratorAsync (monitor, IdeApp.Workspace.ActiveConfiguration, this.targetName);

			foreach (var err in buildResult.BuildResult.Errors) {
				result.Errors.Add (new CompilerError (err.FileName, err.Line, err.Column, err.ErrorNumber, err.ErrorText) {
					IsWarning = err.IsWarning
				});
			}
		}
		public ThreadAsyncOperation (Action task, SingleFileCustomToolResult result)
		{
			if (result == null)
				throw new ArgumentNullException ("result");
			
			this.task = task;
			this.result = result;
			thread = new Thread (Run);
			thread.Start ();
		}
		public Task Generate (ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return Task.Run (delegate {
				try {
					GenerateInternal (monitor, file, result);
				} catch (Exception ex) {
					result.UnhandledException = ex;
				}
			});
		}
        public static void Update(ProjectFile file, bool force)
        {
            ISingleFileCustomTool tool;
            ProjectFile           genFile;

            if (!ShouldRunGenerator(file, force, out tool, out genFile))
            {
                return;
            }

            TaskService.Errors.ClearByOwner(file);

            //if this file is already being run, cancel it
            lock (runningTasks) {
                IAsyncOperation runningTask;
                if (runningTasks.TryGetValue(file.FilePath, out runningTask))
                {
                    runningTask.Cancel();
                    runningTasks.Remove(file.FilePath);
                }
            }

            var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor(false);
            var result  = new SingleFileCustomToolResult();
            var aggOp   = new AggregatedOperationMonitor(monitor);

            try {
                monitor.BeginTask(GettextCatalog.GetString("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);
                IAsyncOperation op = tool.Generate(monitor, file, result);
                runningTasks.Add(file.FilePath, op);
                aggOp.AddOperation(op);
                op.Completed += delegate {
                    lock (runningTasks) {
                        IAsyncOperation runningTask;
                        if (runningTasks.TryGetValue(file.FilePath, out runningTask) && runningTask == op)
                        {
                            runningTasks.Remove(file.FilePath);
                            UpdateCompleted(monitor, aggOp, file, genFile, result, false);
                        }
                        else
                        {
                            //it was cancelled because another was run for the same file, so just clean up
                            aggOp.Dispose();
                            monitor.EndTask();
                            monitor.ReportWarning(GettextCatalog.GetString("Cancelled because generator ran again for the same file"));
                            monitor.Dispose();
                        }
                    }
                };
            } catch (Exception ex) {
                result.UnhandledException = ex;
                UpdateCompleted(monitor, aggOp, file, genFile, result, false);
            }
        }
 public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return new ThreadAsyncOperation (() => {
         var buildResult = file.Project.RunTarget (monitor, targetName, IdeApp.Workspace.ActiveConfiguration);
         foreach (var err in buildResult.Errors) {
             result.Errors.Add (new CompilerError (err.FileName, err.Line, err.Column, err.ErrorNumber, err.ErrorText) {
                 IsWarning = err.IsWarning
             });
         }
     }, result);
 }
        public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
        {
            return new ThreadAsyncOperation (delegate {
                var outputfile = file.FilePath.ChangeExtension(".Designer.cs");
                var ns = GetNamespaceHint (file, outputfile);
                var cn = file.FilePath.FileNameWithoutExtension;

                GenerateDesignerFile(file.FilePath.FullPath, ns, cn, outputfile);
                result.GeneratedFilePath = outputfile;
            }, result);
        }
        public static Action GenerateFile(ProjectFile file, SingleFileCustomToolResult result, bool internalClass)
        {
            return(delegate {
                var dnp = file.Project as DotNetProject;
                if (dnp == null)
                {
                    var err = "ResXFileCodeGenerator can only be used with .NET projects";
                    result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                    return;
                }

                var provider = dnp.LanguageBinding.GetCodeDomProvider();
                if (provider == null)
                {
                    var err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
                    result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                    return;
                }

                var outputfile = file.FilePath.ChangeExtension(".Designer." + provider.FileExtension);
                var ns = CustomToolService.GetFileNamespace(file, outputfile);
                var cn = provider.CreateValidIdentifier(file.FilePath.FileNameWithoutExtension);
                var rd = new Dictionary <object, object> ();

                using (var r = new ResXResourceReader(file.FilePath)) {
                    r.UseResXDataNodes = true;
                    r.BasePath = file.FilePath.ParentDirectory;

                    foreach (DictionaryEntry e in r)
                    {
                        rd.Add(e.Key, e.Value);
                    }
                }

                string[] unmatchable;
                var ccu = StronglyTypedResourceBuilder.Create(rd, cn, ns, provider, internalClass, out unmatchable);

                if (TargetsPcl2Framework(dnp))
                {
                    FixupPclTypeInfo(ccu);
                }

                foreach (var p in unmatchable)
                {
                    var msg = string.Format("Could not generate property for resource ID '{0}'", p);
                    result.Errors.Add(new CompilerError(file.FilePath, 0, 0, null, msg));
                }

                using (var w = new StreamWriter(outputfile, false, Encoding.UTF8))
                    provider.GenerateCodeFromCompileUnit(ccu, w, new CodeGeneratorOptions());

                result.GeneratedFilePath = outputfile;
            });
        }
Exemple #14
0
        public ThreadAsyncOperation(Action task, SingleFileCustomToolResult result)
        {
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            this.task   = task;
            this.result = result;
            thread      = new Thread(Run);
            thread.Start();
        }
Exemple #15
0
        public async Task Generate(ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
        {
            var buildResult = await file.Project.PerformGeneratorAsync(monitor, IdeApp.Workspace.ActiveConfiguration, this.targetName);

            foreach (var err in buildResult.BuildResult.Errors)
            {
                result.Errors.Add(new CompilerError(err.FileName, err.Line, err.Column, err.ErrorNumber, err.ErrorText)
                {
                    IsWarning = err.IsWarning
                });
            }
        }
Exemple #16
0
 public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return(new ThreadAsyncOperation(() => {
         var buildResult = file.Project.RunTarget(monitor, targetName, IdeApp.Workspace.ActiveConfiguration);
         foreach (var err in buildResult.Errors)
         {
             result.Errors.Add(new CompilerError(err.FileName, err.Line, err.Column, err.ErrorNumber, err.ErrorText)
             {
                 IsWarning = err.IsWarning
             });
         }
     }, result));
 }
		public static Action GenerateFile (ProjectFile file, SingleFileCustomToolResult result, bool internalClass)
		{
			return delegate {
				var dnp = file.Project as DotNetProject;
				if (dnp == null) {
					var err = "ResXFileCodeGenerator can only be used with .NET projects";
					result.Errors.Add (new CompilerError (null, 0, 0, null, err));
					return;
				}

				var provider = dnp.LanguageBinding.GetCodeDomProvider ();
				if (provider == null) {
					var err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
					result.Errors.Add (new CompilerError (null, 0, 0, null, err));
					return;
				}

				var outputfile = file.FilePath.ChangeExtension (".Designer." + provider.FileExtension);
				var ns = CustomToolService.GetFileNamespace (file, outputfile);
				var cn = provider.CreateValidIdentifier (file.FilePath.FileNameWithoutExtension);
				var rd = new Dictionary<object, object> ();

				using (var r = new ResXResourceReader (file.FilePath)) {
					r.UseResXDataNodes = true;
					r.BasePath = file.FilePath.ParentDirectory;

					foreach (DictionaryEntry e in r) {
						rd.Add (e.Key, e.Value);
					}
				}

				string[] unmatchable;
				var ccu = StronglyTypedResourceBuilder.Create (rd, cn, ns, provider, internalClass, out unmatchable);
				
				if (TargetsPcl2Framework (dnp)) {
					FixupPclTypeInfo (ccu);
				}

				foreach (var p in unmatchable) {
					var msg = string.Format ("Could not generate property for resource ID '{0}'", p);
					result.Errors.Add (new CompilerError (file.FilePath, 0, 0, null, msg));
				}

				using (var w = new StreamWriter (outputfile, false, Encoding.UTF8))
					provider.GenerateCodeFromCompileUnit (ccu, w, new CodeGeneratorOptions ());

				result.GeneratedFilePath = outputfile;
			};
		}
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (delegate {
				using (var h = TextTemplatingService.GetTemplatingDomain ()) {
					var host = (MonoDevelopTemplatingHost) h.Domain.CreateInstanceAndUnwrap (
						typeof (MonoDevelopTemplatingHost).Assembly.FullName,
						typeof (MonoDevelopTemplatingHost).FullName);
					var defaultOutputName = file.FilePath.ChangeExtension (".cs"); //cs extension for VS compat
					host.ProcessTemplate (file.FilePath, defaultOutputName);
					result.GeneratedFilePath = host.OutputFile;
					result.Errors.AddRange (host.Errors);
					foreach (var err in host.Errors)
						monitor.Log.WriteLine (err.ToString ());
				}
			}, result);
		}
		public Task Generate (ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return Task.Run (delegate {
				using (var host = new ProjectFileTemplatingHost (file, IdeApp.Workspace.ActiveConfiguration)) {

					string outputFile;
					Generate (host, file, out outputFile);

					result.GeneratedFilePath = outputFile;
					result.Errors.AddRange (host.Errors);

					foreach (var err in host.Errors)
						monitor.Log.WriteLine (err);
				}
			});
		}
		public Task Generate (ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return Task.Run (delegate {
				using (var host = new ProjectFileTemplatingHost (file, IdeApp.Workspace.ActiveConfiguration)) {
					host.AddMonoDevelopHostImport ();
					var defaultOutputName = file.FilePath.ChangeExtension (".cs"); //cs extension for VS compat
					
					string ns = CustomToolService.GetFileNamespace (file, defaultOutputName);
					LogicalSetData ("NamespaceHint", ns);
					
					host.ProcessTemplate (file.FilePath, defaultOutputName);
					result.GeneratedFilePath = host.OutputFile;
					result.Errors.AddRange (host.Errors);
					
					foreach (var err in host.Errors)
						monitor.Log.WriteLine (err);
				}
			});
		}
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (delegate {
				using (var host = new ProjectFileTemplatingHost (file)) {
					
					var defaultOutputName = file.FilePath.ChangeExtension (".cs"); //cs extension for VS compat
					
					string ns = TextTemplatingFilePreprocessor.GetNamespaceHint (file, defaultOutputName);
					TextTemplatingFilePreprocessor.LogicalSetData ("NamespaceHint", ns, result.Errors);
					
					host.ProcessTemplate (file.FilePath, defaultOutputName);
					result.GeneratedFilePath = host.OutputFile;
					result.Errors.AddRange (host.Errors);
					
					foreach (var err in host.Errors)
						monitor.Log.WriteLine (err);
				}
			}, result);
		}
		public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation(() => {
				
				FilePath codeFilePath = file.FilePath.ChangeExtension(".feature.cs");
				
				try
				{
					codeFilePath = GenerateFeatureCodeFileFor(file);
				}
				catch (Exception ex)
				{
					HandleException(ex, file, result);
				}
				
				result.GeneratedFilePath = codeFilePath;
				
			}, result);
		}
        internal static void Generate(IProgressMonitor monitor, ProjectFile file, 
		                               SingleFileCustomToolResult result, bool internalClass)
        {
            var outputFile = file.FilePath.ChangeExtension (".Designer.cs");

            DotNetProject dnProject = file.Project as DotNetProject;
            if (dnProject == null)
                return; //don't do anything if file not in project

            CodeDomProvider provider = dnProject.LanguageBinding.GetCodeDomProvider ();
            if (provider == null)
                return; //don't do anything if no provider available

            // this returns the namespace in accordance with DotNetNamingPolicy in use
            string resourcesNamespace = dnProject.GetDefaultNamespace (outputFile.ToString ());
            string baseName = file.FilePath.FileNameWithoutExtension;

            string genCodeNamespace = String.IsNullOrWhiteSpace (file.CustomToolNamespace) ?
                            resourcesNamespace : file.CustomToolNamespace;

            string [] unmatchables;
            CodeCompileUnit ccu;

            ccu = StronglyTypedResourceBuilder.Create (file.FilePath.ToString (),
                                                       baseName,
                                                       genCodeNamespace,
                                                       resourcesNamespace,
                                                       provider,
                                                       internalClass,
                                                       out unmatchables);
            // generate code overwriting existing file
            using (var writer = new StreamWriter (outputFile, false)) {
                provider.GenerateCodeFromCompileUnit (ccu,
                                                      writer,
                                                      new CodeGeneratorOptions());
            }

            result.GeneratedFilePath = outputFile;

            foreach (var u in unmatchables) //should report these better?
                monitor.Log.WriteLine ("Unable to create property for resource named: {0}", u);
        }
		public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile featureFile, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation(() => {
				
                var ideSingleFileGenerator = new IdeSingleFileGenerator();

                ideSingleFileGenerator.GenerationError += 
                    delegate(TestGenerationError error)
                        {
                            result.Errors.Add(new CompilerError(featureFile.Name, error.Line + 1, error.LinePosition + 1, "0", error.Message));
                        };
                ideSingleFileGenerator.OtherError += 
                    delegate(Exception exception)
                        {
                            result.UnhandledException = exception;
                        };

                string outputFilePath = ideSingleFileGenerator.GenerateFile(featureFile.FilePath, null, () => new MonoDevelopGeneratorServices(featureFile.Project));
				result.GeneratedFilePath = outputFilePath;
				
			}, result);
		}
        public static Action GenerateFile(ProjectFile file, SingleFileCustomToolResult result, bool internalClass)
        {
            return(delegate {
                var dnp = file.Project as DotNetProject;
                if (dnp == null)
                {
                    var err = "ResXFileCodeGenerator can only be used with .NET projects";
                    result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                    return;
                }

                var provider = dnp.LanguageBinding.GetCodeDomProvider();
                if (provider == null)
                {
                    var err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
                    result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                    return;
                }

                var outputfile = file.FilePath.ChangeExtension(".Designer." + provider.FileExtension);
                var ns = CustomToolService.GetFileNamespace(file, outputfile);
                var cn = provider.CreateValidIdentifier(file.FilePath.FileNameWithoutExtension);

                string[] unmatchable;
                var ccu = StronglyTypedResourceBuilder.Create(file.FilePath, cn, ns, provider, internalClass, out unmatchable);

                foreach (var p in unmatchable)
                {
                    var msg = string.Format("Could not generate property for resource ID '{0}'", p);
                    result.Errors.Add(new CompilerError(file.FilePath, 0, 0, null, msg));
                }

                using (var w = new StreamWriter(outputfile, false, Encoding.UTF8))
                    provider.GenerateCodeFromCompileUnit(ccu, w, new CodeGeneratorOptions());

                result.GeneratedFilePath = outputfile;
            });
        }
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (delegate {
				var host = new ProjectFileTemplatingHost (file);
				
				var dnp = file.Project as DotNetProject;
				if (dnp == null) {
					var msg = "Precompiled T4 templates are only supported in .NET projects";
					result.Errors.Add (new CompilerError (file.Name, -1, -1, null, msg));
					monitor.Log.WriteLine (msg);
					return;
				}
				
				var provider = dnp.LanguageBinding.GetCodeDomProvider ();
				if (provider == null) {
					var msg = "Precompiled T4 templates are only supported for .NET languages with CodeDOM providers";
					result.Errors.Add (new CompilerError (file.Name, -1, -1, null, msg));
					monitor.Log.WriteLine (msg);
					return;
				};
				
				var outputFile = file.FilePath.ChangeExtension (provider.FileExtension);
				var encoding = System.Text.Encoding.UTF8;
				string langauge;
				string[] references;
				string className = provider.CreateValidIdentifier (file.FilePath.FileNameWithoutExtension);
				
				string classNamespace = CustomToolService.GetFileNamespace (file, outputFile);
				LogicalSetData ("NamespaceHint", classNamespace, result.Errors);

				host.PreprocessTemplate (file.FilePath, className, classNamespace, outputFile, encoding, out langauge, out references);
				
				result.GeneratedFilePath = outputFile;
				result.Errors.AddRange (host.Errors);
				foreach (var err in host.Errors)
					monitor.Log.WriteLine (err.ToString ());
			}, result);
		}
		public async Task  Generate(ProgressMonitor monitor, ProjectFile featureFile,
            SingleFileCustomToolResult result)
        {

			await Task.Run(() =>
			{
				// This is the project directory containing the .imfl file
				string dir = System.IO.Path.GetDirectoryName(featureFile.FilePath);
				monitor.Log.WriteLine("Creating images for " + featureFile.FilePath);

				var processor = new ImageProcessor(monitor, result);

				var lines = System.IO.File.ReadLines(featureFile.FilePath);
				int lineNumber = 0;
				var outputSpecifiers = new List<OutputSpecifier>();
				foreach (var line in lines)
				{
					lineNumber++;
					if (String.IsNullOrWhiteSpace(line)) continue;
					if (line.StartsWith("#")) continue;

					//monitor.Log.WriteLine("Interpreting " + line);

					try
					{
						// Slight hack ...
						if (line.Contains("type:"))
						{
							var ts = JsonConvert.DeserializeObject<OutputSpecifier>(line);
							if (ts != null)
							{
								string testPath = processor.GetFullOutputPath(dir, ts, "test.svg");
								var directory = Path.GetDirectoryName(testPath);
								if (!Directory.Exists(directory))
								{
									string shortDirectory = Path.GetDirectoryName(string.Format(ts.path, "x.png"));
									result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err17", "Directory not found " + shortDirectory));
								}
								else
								{
									outputSpecifiers.Add(ts);
									monitor.Log.WriteLine("Added output specifier " + line);
								}
							}
							else
							{
								result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err2", "Could not parse output specifier"));
							}
						}
						else if (line.Contains("process:"))
						{
							var ps = JsonConvert.DeserializeObject<ProcessSpecifier>(line);
							if (ps != null)
							{
								// Process output
								var subdir = Path.GetDirectoryName(ps.process);
								var searchPattern = Path.GetFileName(ps.process);
								var inputDirectory = Path.Combine(dir, subdir);

								if (Directory.Exists(inputDirectory))
								{
									var outputters = outputSpecifiers.Where(s => [email protected](s.type));
									processor.Process(dir, Directory.GetFiles(inputDirectory, searchPattern), outputters, lineNumber);
								}
								else
								{
									result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err17", "Directory not found " + subdir));
								}

							}
							else
							{
								result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err2", "Could not parse process specifier"));
							}
						}
						else
						{
							result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err2", "Could not parse this line"));
						}
					}
					catch (Exception ex)
					{
						result.Errors.Add(new CompilerError(featureFile.FilePath, lineNumber, 1, "Err1", ex.ToString()));
					}
				}

				result.GeneratedFilePath = "";
			});
 
        }
 public override Task Generate(ProgressMonitor monitor, Project project, ProjectFile file, SingleFileCustomToolResult result)
 {
     return(this.customTool.Generate(monitor, file, result));
 }
 public ImageProcessor(IProgressMonitor monitor, SingleFileCustomToolResult result)
 {
     this.monitor = monitor;
     this.result = result;
 }
        public static void Update(ProjectFile file, bool force)
        {
            var tool = GetGenerator(file);

            if (tool == null)
            {
                return;
            }

            ProjectFile genFile = null;

            if (!string.IsNullOrEmpty(file.LastGenOutput))
            {
                genFile = file.Project.Files.GetFile(file.FilePath.ParentDirectory.Combine(file.LastGenOutput));
            }

            if (!force && genFile != null && File.Exists(genFile.FilePath) &&
                File.GetLastWriteTime(file.FilePath) < File.GetLastWriteTime(genFile.FilePath))
            {
                return;
            }

            TaskService.Errors.ClearByOwner(file);

            //if this file is already being run, cancel it
            lock (runningTasks)
            {
                IAsyncOperation runningTask;
                if (runningTasks.TryGetValue(file.FilePath, out runningTask))
                {
                    runningTask.Cancel();
                    runningTasks.Remove(file.FilePath);
                }
            }

            var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor(false);
            var result  = new SingleFileCustomToolResult();
            var aggOp   = new AggregatedOperationMonitor(monitor);

            try
            {
                monitor.BeginTask(GettextCatalog.GetString("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);
                var op = tool.Generate(monitor, file, result);
                runningTasks.Add(file.FilePath, op);
                aggOp.AddOperation(op);
                op.Completed += delegate
                {
                    lock (runningTasks)
                    {
                        IAsyncOperation runningTask;
                        if (runningTasks.TryGetValue(file.FilePath, out runningTask) && runningTask == op)
                        {
                            runningTasks.Remove(file.FilePath);
                            UpdateCompleted(monitor, aggOp, file, genFile, result);
                        }
                        else
                        {
                            //it was cancelled because another was run for the same file, so just clean up
                            aggOp.Dispose();
                            monitor.EndTask();
                            monitor.ReportWarning(GettextCatalog.GetString("Cancelled because generator ran again for the same file"));
                            monitor.Dispose();
                        }
                    }
                };
            }
            catch (Exception ex)
            {
                result.UnhandledException = ex;
                UpdateCompleted(monitor, aggOp, file, genFile, result);
            }
        }
        public async static Task GenerateFile(ProjectFile file, SingleFileCustomToolResult result, bool internalClass)
        {
            var dnp = file.Project as DotNetProject;

            if (dnp == null)
            {
                var err = "ResXFileCodeGenerator can only be used with .NET projects";
                result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                return;
            }

            var provider = dnp.LanguageBinding.GetCodeDomProvider();

            if (provider == null)
            {
                const string err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
                result.Errors.Add(new CompilerError(null, 0, 0, null, err));
                return;
            }

            var outputfile = file.FilePath.ChangeExtension(".Designer." + provider.FileExtension);

            //use the Visual Studio naming polict, so it matches code generated by VS
            var codeNamespace = CustomToolService.GetFileNamespace(file, outputfile, true);

            //no need to escape/cleanup, StronglyTypedResourceBuilder does that
            var name = file.FilePath.FileNameWithoutExtension;

            //NOTE: we fix it up later with the real resource ID, this is just a fallback in case that fails
            var resourcesNamespace = dnp.GetDefaultNamespace(outputfile, true);

            var rd                   = new Dictionary <object, object> ();
            var filePath             = file.FilePath;
            var targetsPcl2Framework = TargetsPcl2Framework(dnp);

            //Compute the *real* ID of the embedded resource. It can be affected by LogicalName so might not match the
            //class name, but StronglyTypedResourceBuilder only accepts a single name for both.
            //Fix this by patching it into the CodeDOM later.
            var          id     = file.ResourceId;
            const string suffix = ".resources";

            if (id.Length > suffix.Length && id.EndsWith(suffix, StringComparison.OrdinalIgnoreCase))
            {
                id = id.Substring(0, id.Length - suffix.Length);
            }

            await Task.Run(() => {
                using (var r = new ResXResourceReader(filePath)) {
                    r.BasePath = filePath.ParentDirectory;
                    foreach (DictionaryEntry e in r)
                    {
                        rd.Add(e.Key, e.Value);
                    }
                }

                string[] unmatchable;
                var ccu = StronglyTypedResourceBuilder.Create(rd, name, codeNamespace, resourcesNamespace, provider, internalClass, out unmatchable);

                if (targetsPcl2Framework)
                {
                    FixupPclTypeInfo(ccu);
                }

                FixupEmbeddedResourceID(ccu, id);

                foreach (var p in unmatchable)
                {
                    var msg = string.Format("Could not generate property for resource ID '{0}'", p);
                    result.Errors.Add(new CompilerError(filePath, 0, 0, null, msg));
                }

                lock (file) {
                    // Avoid race if ResXFileCodeGenerator is called more than once for the same file
                    using (var w = new StreamWriter(outputfile, false, Encoding.UTF8))
                        provider.GenerateCodeFromCompileUnit(ccu, w, new CodeGeneratorOptions());
                }

                result.GeneratedFilePath = outputfile;
            });
        }
 public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return(new ThreadAsyncOperation(GenerateFile(file, result, true), result));
 }
		public async static Task GenerateFile (ProjectFile file, SingleFileCustomToolResult result, bool internalClass)
		{
			var dnp = file.Project as DotNetProject;
			if (dnp == null) {
				var err = "ResXFileCodeGenerator can only be used with .NET projects";
				result.Errors.Add (new CompilerError (null, 0, 0, null, err));
				return;
			}

			var provider = dnp.LanguageBinding.GetCodeDomProvider ();
			if (provider == null) {
				const string err = "ResXFileCodeGenerator can only be used with languages that support CodeDOM";
				result.Errors.Add (new CompilerError (null, 0, 0, null, err));
				return;
			}

			var outputfile = file.FilePath.ChangeExtension (".Designer." + provider.FileExtension);

			//use the Visual Studio naming polict, so it matches code generated by VS
			var codeNamespace = CustomToolService.GetFileNamespace (file, outputfile, true);

			//no need to escape/cleanup, StronglyTypedResourceBuilder does that
			var name = file.FilePath.FileNameWithoutExtension;

			//NOTE: we fix it up later with the real resource ID, this is just a fallback in case that fails
			var resourcesNamespace = dnp.GetDefaultNamespace (outputfile, true);

			var rd = new Dictionary<object, object> ();
			var filePath = file.FilePath;
			var targetsPcl2Framework = TargetsPcl2Framework (dnp);

			//Compute the *real* ID of the embedded resource. It can be affected by LogicalName so might not match the
			//class name, but StronglyTypedResourceBuilder only accepts a single name for both.
			//Fix this by patching it into the CodeDOM later.
			var id = file.ResourceId;
			const string suffix = ".resources";
			if (id.Length > suffix.Length && id.EndsWith (suffix, StringComparison.OrdinalIgnoreCase)) {
				id = id.Substring (0, id.Length - suffix.Length);
			}

			await Task.Run (() => {
				using (var r = new ResXResourceReader (filePath)) {
					r.BasePath = filePath.ParentDirectory;
					foreach (DictionaryEntry e in r) {
						rd.Add (e.Key, e.Value);
					}
				}

				string[] unmatchable;
				var ccu = StronglyTypedResourceBuilder.Create (rd, name, codeNamespace, resourcesNamespace, provider, internalClass, out unmatchable);
			
				if (targetsPcl2Framework) {
					FixupPclTypeInfo (ccu);
				}

				FixupEmbeddedResourceID (ccu, id);

				foreach (var p in unmatchable) {
					var msg = string.Format ("Could not generate property for resource ID '{0}'", p);
					result.Errors.Add (new CompilerError (filePath, 0, 0, null, msg));
				}

				lock (file) {
					// Avoid race if ResXFileCodeGenerator is called more than once for the same file
					using (var w = new StreamWriter (outputfile, false, Encoding.UTF8))
						provider.GenerateCodeFromCompileUnit (ccu, w, new CodeGeneratorOptions ());
				}

				result.GeneratedFilePath = outputfile;
			});
		}
		static void Update (IProgressMonitor monitor, IEnumerator<ProjectFile> fileEnumerator, bool force, int succeeded, int warnings, int errors)
		{
			ProjectFile file = fileEnumerator.Current;
			ISingleFileCustomTool tool;
			ProjectFile genFile;

			bool shouldRun;
			while (!(shouldRun = ShouldRunGenerator (file, force, out tool, out genFile)) && fileEnumerator.MoveNext ())
				continue;

			//no files which can be generated in remaining elements of the collection, nothing to do
			if (!shouldRun) {
				WriteSummaryResults (monitor, succeeded, warnings, errors);
				return;
			}

			TaskService.Errors.ClearByOwner (file);

			var result = new SingleFileCustomToolResult ();
			monitor.BeginTask (GettextCatalog.GetString ("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);

			try {
				IAsyncOperation op = tool.Generate (monitor, file, result);
				op.Completed += delegate {
					if (result.Success) {
						monitor.Log.WriteLine (GettextCatalog.GetString ("File '{0}' was generated successfully.", result.GeneratedFilePath));
						succeeded++;
					} else if (result.SuccessWithWarnings) {
						monitor.Log.WriteLine (GettextCatalog.GetString ("File '{0}' was generated with warnings.", result.GeneratedFilePath));
						warnings++;
					} else {
						monitor.Log.WriteLine (GettextCatalog.GetString ("Errors in file '{0}' generation.", result.GeneratedFilePath));
						errors++;
					}

					//check that we can process further. If UpdateCompleted returns `true` this means no errors or non-fatal errors occured
					if (UpdateCompleted (monitor, null, file, genFile, result, true) && fileEnumerator.MoveNext ())
						Update (monitor, fileEnumerator, force, succeeded, warnings, errors);
					else
						WriteSummaryResults (monitor, succeeded, warnings, errors);
				};
			} catch (Exception ex) {
				result.UnhandledException = ex;
				UpdateCompleted (monitor, null, file, genFile, result, true);
			}
		}
		public static async void Update (ProjectFile file, bool force)
		{
			ISingleFileCustomTool tool;
			ProjectFile genFile;
			if (!ShouldRunGenerator (file, force, out tool, out genFile)) {
				return;
			}
			
			TaskService.Errors.ClearByOwner (file);
			
			TaskInfo runningTask;
			TaskCompletionSource<bool> newTask = new TaskCompletionSource<bool> ();
			var result = new SingleFileCustomToolResult ();
			Task existingTask = null;
			CancellationTokenSource cs = new CancellationTokenSource ();

			// if this file is already being run, cancel it

			lock (runningTasks) {
				if (runningTasks.TryGetValue (file.FilePath, out runningTask)) {
					runningTask.CancellationTokenSource.Cancel ();
					runningTasks.Remove (file.FilePath);
					existingTask = runningTask.Task;
				}
				runningTask = new TaskInfo { Task = newTask.Task, CancellationTokenSource = cs, Result = result };
				runningTasks.Add (file.FilePath, runningTask);
			}

			// If a task was already running, wait for it to finish. Running the same task in parallel may lead
			// to file sharing violation errors

			if (existingTask != null) {
				try {
					await existingTask;
				} catch {
					// Ignore exceptions, they are handled elsewhere
				}
			}

			// Maybe I was cancelled while I was waiting. In that case, the task has already been removed from
			// the runningTasks collection

			if (cs.IsCancellationRequested)
				return;

			// Execute the generator

			Exception error = null;
			var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (false).WithCancellationSource (cs);

			try {
				monitor.BeginTask (GettextCatalog.GetString ("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);

				try {
					await tool.Generate (monitor, file, result);
				} catch (Exception ex) {
					error = ex;
					result.UnhandledException = ex;
				}

				// Generation has finished. Remove the task from the runningTasks collection

				lock (runningTasks) {
					TaskInfo registeredTask;
					if (runningTasks.TryGetValue (file.FilePath, out registeredTask) && registeredTask == runningTask) {
						runningTasks.Remove (file.FilePath);
						UpdateCompleted (monitor, file, genFile, result, false);
					} else {
						// it was cancelled because another was run for the same file, so just clean up
						monitor.EndTask ();
						monitor.ReportWarning (GettextCatalog.GetString ("Cancelled because generator ran again for the same file"));
						monitor.Dispose ();
					}
				}
			} catch (Exception ex) {
				result.UnhandledException = ex;
				UpdateCompleted (monitor, file, genFile, result, false);
			} finally {
				if (error == null)
					newTask.SetResult (true);
				else {
					newTask.SetException (error);
				}
			}
		}
		static void UpdateCompleted (IProgressMonitor monitor, AggregatedOperationMonitor aggOp,
		                             ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result)
		{
			monitor.EndTask ();
			aggOp.Dispose ();
			
			if (monitor.IsCancelRequested) {
				monitor.ReportError (GettextCatalog.GetString ("Cancelled"), null);
				monitor.Dispose ();
				return;
			}
			
			string genFileName;
			try {
				
				bool broken = false;
				
				if (result.UnhandledException != null) {
					broken = true;
					string msg = GettextCatalog.GetString ("The '{0}' code generator crashed", file.Generator);
					result.Errors.Add (new CompilerError (file.Name, 0, 0, "", msg + ": " + result.UnhandledException.Message));
					monitor.ReportError (msg, result.UnhandledException);
					LoggingService.LogError (msg, result.UnhandledException);
				}
				
				genFileName = result.GeneratedFilePath.IsNullOrEmpty?
					null : result.GeneratedFilePath.ToRelative (file.FilePath.ParentDirectory);
				
				bool validName = !string.IsNullOrEmpty (genFileName)
					&& genFileName.IndexOfAny (new char[] { '/', '\\' }) < 0
					&& FileService.IsValidFileName (genFileName);
				
				if (!broken && !validName) {
					broken = true;
					string msg = GettextCatalog.GetString ("The '{0}' code generator output invalid filename '{1}'",
					                                       file.Generator, result.GeneratedFilePath);
					result.Errors.Add (new CompilerError (file.Name, 0, 0, "", msg));
					monitor.ReportError (msg, null);
				}
				
				if (result.Errors.Count > 0) {
					foreach (CompilerError err in result.Errors)
						TaskService.Errors.Add (new Task (file.FilePath, err.ErrorText, err.Column, err.Line,
							                                  err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
							                                  TaskPriority.Normal, file.Project.ParentSolution, file));
				}
				
				if (broken)
					return;
				
				if (result.Success)
					monitor.ReportSuccess ("Generated file successfully.");
				else
					monitor.ReportError ("Failed to generate file. See error pad for details.", null);
				
			} finally {
				monitor.Dispose ();
			}
			
			if (!result.GeneratedFilePath.IsNullOrEmpty && File.Exists (result.GeneratedFilePath)) {
				Gtk.Application.Invoke (delegate {
					if (genFile == null) {
						genFile = file.Project.AddFile (result.GeneratedFilePath);
					} else if (result.GeneratedFilePath != genFile.FilePath) {
						genFile.Name = result.GeneratedFilePath;
					}
					file.LastGenOutput = genFileName;
					genFile.DependsOn = file.FilePath.FileName;
					
					IdeApp.ProjectOperations.Save (file.Project);
				});
			}
		}
		public static void Update (ProjectFile file, bool force)
		{
			var tool = GetGenerator (file);
			if (tool == null)
				return;
			
			ProjectFile genFile = null;
			if (!string.IsNullOrEmpty (file.LastGenOutput))
				genFile = file.Project.Files.GetFile (file.FilePath.ParentDirectory.Combine (file.LastGenOutput));
			
			if (!force && genFile != null && File.Exists (genFile.FilePath) && 
			    File.GetLastWriteTime (file.FilePath) < File.GetLastWriteTime (genFile.FilePath)) {
				return;
			}
			
			TaskService.Errors.ClearByOwner (file);
			
			//if this file is already being run, cancel it
			lock (runningTasks) {
				IAsyncOperation runningTask;
				if (runningTasks.TryGetValue (file.FilePath, out runningTask)) {
					runningTask.Cancel ();
					runningTasks.Remove (file.FilePath);
				}
			}
			
			var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (false);
			var result = new SingleFileCustomToolResult ();
			var aggOp = new AggregatedOperationMonitor (monitor);
			try {
				monitor.BeginTask (GettextCatalog.GetString ("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);
				var op = tool.Generate (monitor, file, result);
				runningTasks.Add (file.FilePath, op);
				aggOp.AddOperation (op);
				op.Completed += delegate {
					lock (runningTasks) {
						IAsyncOperation runningTask;
						if (runningTasks.TryGetValue (file.FilePath, out runningTask) && runningTask == op) {
							runningTasks.Remove (file.FilePath);
							UpdateCompleted (monitor, aggOp, file, genFile, result);
						} else {
							//it was cancelled because another was run for the same file, so just clean up
							aggOp.Dispose ();
							monitor.EndTask ();
							monitor.ReportWarning (GettextCatalog.GetString ("Cancelled because generator ran again for the same file"));
							monitor.Dispose ();
						}
					}
				};
			} catch (Exception ex) {
				result.UnhandledException = ex;
				UpdateCompleted (monitor, aggOp, file, genFile, result);
			}
		}
		public IAsyncOperation Generate (IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
		{
			return new ThreadAsyncOperation (GenerateFile (file, result, true), result);
		}
        static void UpdateCompleted(IProgressMonitor monitor, AggregatedOperationMonitor aggOp,
                                    ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result)
        {
            monitor.EndTask();
            aggOp.Dispose();

            if (monitor.IsCancelRequested)
            {
                monitor.ReportError(GettextCatalog.GetString("Cancelled"), null);
                monitor.Dispose();
                return;
            }

            string genFileName;

            try
            {
                bool broken = false;

                if (result.UnhandledException != null)
                {
                    broken = true;
                    string msg = GettextCatalog.GetString("The '{0}' code generator crashed", file.Generator);
                    result.Errors.Add(new CompilerError(file.Name, 0, 0, "", msg + ": " + result.UnhandledException.Message));
                    monitor.ReportError(msg, result.UnhandledException);
                    LoggingService.LogError(msg, result.UnhandledException);
                }

                genFileName = result.GeneratedFilePath.IsNullOrEmpty?
                              null : result.GeneratedFilePath.ToRelative(file.FilePath.ParentDirectory);

                bool validName = !string.IsNullOrEmpty(genFileName) &&
                                 genFileName.IndexOfAny(new char[] { '/', '\\' }) < 0 &&
                                 FileService.IsValidFileName(genFileName);

                if (!broken && !validName)
                {
                    broken = true;
                    string msg = GettextCatalog.GetString("The '{0}' code generator output invalid filename '{1}'",
                                                          file.Generator, result.GeneratedFilePath);
                    result.Errors.Add(new CompilerError(file.Name, 0, 0, "", msg));
                    monitor.ReportError(msg, null);
                }

                if (result.Errors.Count > 0)
                {
                    foreach (CompilerError err in result.Errors)
                    {
                        TaskService.Errors.Add(new Task(file.FilePath, err.ErrorText, err.Column, err.Line,
                                                        err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
                                                        TaskPriority.Normal, file.Project.ParentSolution, file));
                    }
                }

                if (broken)
                {
                    return;
                }

                if (result.Success)
                {
                    monitor.ReportSuccess("Generated file successfully.");
                }
                else
                {
                    monitor.ReportError("Failed to generate file. See error pad for details.", null);
                }
            }
            finally
            {
                monitor.Dispose();
            }

            if (!result.GeneratedFilePath.IsNullOrEmpty && File.Exists(result.GeneratedFilePath))
            {
                Gtk.Application.Invoke(delegate
                {
                    if (genFile == null)
                    {
                        genFile = file.Project.AddFile(result.GeneratedFilePath);
                    }
                    else if (result.GeneratedFilePath != genFile.FilePath)
                    {
                        genFile.Name = result.GeneratedFilePath;
                    }
                    file.LastGenOutput = genFileName;
                    genFile.DependsOn  = file.FilePath.FileName;

                    IdeApp.ProjectOperations.Save(file.Project);
                });
            }
        }
 public IAsyncOperation Generate(IProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return new ThreadAsyncOperation (delegate {
         ResXCodeFileGenerator.Generate (monitor, file, result, false);
     }, result);
 }
 public abstract Task Generate(ProgressMonitor monitor, Project project, ProjectFile file, SingleFileCustomToolResult result);
Exemple #42
0
 public Task Generate(ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return(ResXFileCodeGenerator.GenerateFile(file, result, false));
 }
		public static void Update (ProjectFile file, bool force)
		{
			ISingleFileCustomTool tool;
			ProjectFile genFile;
			if (!ShouldRunGenerator (file, force, out tool, out genFile)) {
				return;
			}
			
			TaskService.Errors.ClearByOwner (file);
			
			//if this file is already being run, cancel it
			lock (runningTasks) {
				IAsyncOperation runningTask;
				if (runningTasks.TryGetValue (file.FilePath, out runningTask)) {
					runningTask.Cancel ();
					runningTasks.Remove (file.FilePath);
				}
			}
			
			var monitor = IdeApp.Workbench.ProgressMonitors.GetToolOutputProgressMonitor (false);
			var result = new SingleFileCustomToolResult ();
			var aggOp = new AggregatedOperationMonitor (monitor);
			try {
				monitor.BeginTask (GettextCatalog.GetString ("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);
				IAsyncOperation op = tool.Generate (monitor, file, result);
				runningTasks.Add (file.FilePath, op);
				aggOp.AddOperation (op);
				op.Completed += delegate {
					lock (runningTasks) {
						IAsyncOperation runningTask;
						if (runningTasks.TryGetValue (file.FilePath, out runningTask) && runningTask == op) {
							runningTasks.Remove (file.FilePath);
							UpdateCompleted (monitor, aggOp, file, genFile, result, false);
						} else {
							//it was cancelled because another was run for the same file, so just clean up
							aggOp.Dispose ();
							monitor.EndTask ();
							monitor.ReportWarning (GettextCatalog.GetString ("Cancelled because generator ran again for the same file"));
							monitor.Dispose ();
						}
					}
				};
			} catch (Exception ex) {
				result.UnhandledException = ex;
				UpdateCompleted (monitor, aggOp, file, genFile, result, false);
			}
		}
        static bool UpdateCompleted(IProgressMonitor monitor, AggregatedOperationMonitor aggOp,
                                    ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result,
                                    bool runMultipleFiles)
        {
            monitor.EndTask();
            if (aggOp != null)
            {
                aggOp.Dispose();
            }

            if (monitor.IsCancelRequested)
            {
                monitor.ReportError(GettextCatalog.GetString("Cancelled"), null);
                monitor.Dispose();
                return(false);
            }

            string genFileName;

            try {
                bool broken = false;

                if (result.UnhandledException != null)
                {
                    broken = true;
                    string msg = GettextCatalog.GetString("The '{0}' code generator crashed", file.Generator);
                    result.Errors.Add(new CompilerError(file.Name, 0, 0, "", msg + ": " + result.UnhandledException.Message));
                    monitor.ReportError(msg, result.UnhandledException);
                    LoggingService.LogError(msg, result.UnhandledException);
                }

                genFileName = result.GeneratedFilePath.IsNullOrEmpty?
                              null : result.GeneratedFilePath.ToRelative(file.FilePath.ParentDirectory);

                if (!string.IsNullOrEmpty(genFileName))
                {
                    bool validName = genFileName.IndexOfAny(new [] { '/', '\\' }) < 0 &&
                                     FileService.IsValidFileName(genFileName);

                    if (!broken && !validName)
                    {
                        broken = true;
                        string msg = GettextCatalog.GetString("The '{0}' code generator output invalid filename '{1}'",
                                                              file.Generator, result.GeneratedFilePath);
                        result.Errors.Add(new CompilerError(file.Name, 0, 0, "", msg));
                        monitor.ReportError(msg, null);
                    }
                }

                if (result.Errors.Count > 0)
                {
                    DispatchService.GuiDispatch(delegate {
                        foreach (CompilerError err in result.Errors)
                        {
                            TaskService.Errors.Add(new Task(file.FilePath, err.ErrorText, err.Column, err.Line,
                                                            err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
                                                            TaskPriority.Normal, file.Project.ParentSolution, file));
                        }
                    });
                }

                if (broken)
                {
                    return(true);
                }

                if (!runMultipleFiles)
                {
                    if (result.Success)
                    {
                        monitor.ReportSuccess("Generated file successfully.");
                    }
                    else if (result.SuccessWithWarnings)
                    {
                        monitor.ReportSuccess("Warnings in file generation.");
                    }
                    else
                    {
                        monitor.ReportError("Errors in file generation.", null);
                    }
                }
            } finally {
                if (!runMultipleFiles)
                {
                    monitor.Dispose();
                }
            }

            if (result.GeneratedFilePath.IsNullOrEmpty || !File.Exists(result.GeneratedFilePath))
            {
                return(true);
            }

            // broadcast a change event so text editors etc reload the file
            FileService.NotifyFileChanged(result.GeneratedFilePath);

            // add file to project, update file properties, etc
            Gtk.Application.Invoke(delegate {
                bool projectChanged = false;
                if (genFile == null)
                {
                    genFile        = file.Project.AddFile(result.GeneratedFilePath, result.OverrideBuildAction);
                    projectChanged = true;
                }
                else if (result.GeneratedFilePath != genFile.FilePath)
                {
                    genFile.Name   = result.GeneratedFilePath;
                    projectChanged = true;
                }

                if (file.LastGenOutput != genFileName)
                {
                    file.LastGenOutput = genFileName;
                    projectChanged     = true;
                }

                if (genFile.DependsOn != file.FilePath.FileName)
                {
                    genFile.DependsOn = file.FilePath.FileName;
                    projectChanged    = true;
                }

                if (projectChanged)
                {
                    IdeApp.ProjectOperations.Save(file.Project);
                }
            });

            return(true);
        }
		static bool UpdateCompleted (IProgressMonitor monitor, AggregatedOperationMonitor aggOp,
		                             ProjectFile file, ProjectFile genFile, SingleFileCustomToolResult result,
		                             bool runMultipleFiles)
		{
			monitor.EndTask ();
			if (aggOp != null)
				aggOp.Dispose ();
			
			if (monitor.IsCancelRequested) {
				monitor.ReportError (GettextCatalog.GetString ("Cancelled"), null);
				monitor.Dispose ();
				return false;
			}
			
			string genFileName;
			try {
				
				bool broken = false;
				
				if (result.UnhandledException != null) {
					broken = true;
					string msg = GettextCatalog.GetString ("The '{0}' code generator crashed", file.Generator);
					result.Errors.Add (new CompilerError (file.Name, 0, 0, "", msg + ": " + result.UnhandledException.Message));
					monitor.ReportError (msg, result.UnhandledException);
					LoggingService.LogError (msg, result.UnhandledException);
				}

				genFileName = result.GeneratedFilePath.IsNullOrEmpty?
					null : result.GeneratedFilePath.ToRelative (file.FilePath.ParentDirectory);
				
				if (!string.IsNullOrEmpty (genFileName)) {
					bool validName = genFileName.IndexOfAny (new [] { '/', '\\' }) < 0
						&& FileService.IsValidFileName (genFileName);
					
					if (!broken && !validName) {
						broken = true;
						string msg = GettextCatalog.GetString ("The '{0}' code generator output invalid filename '{1}'",
						                                       file.Generator, result.GeneratedFilePath);
						result.Errors.Add (new CompilerError (file.Name, 0, 0, "", msg));
						monitor.ReportError (msg, null);
					}
				}
				
				if (result.Errors.Count > 0) {
					DispatchService.GuiDispatch (delegate {
						foreach (CompilerError err in result.Errors)
							TaskService.Errors.Add (new Task (file.FilePath, err.ErrorText, err.Column, err.Line,
								err.IsWarning? TaskSeverity.Warning : TaskSeverity.Error,
								TaskPriority.Normal, file.Project.ParentSolution, file));
					});
				}
				
				if (broken)
					return true;

				if (!runMultipleFiles) {
					if (result.Success)
						monitor.ReportSuccess ("Generated file successfully.");
					else if (result.SuccessWithWarnings)
						monitor.ReportSuccess ("Warnings in file generation.");
					else
						monitor.ReportError ("Errors in file generation.", null);
				}
			} finally {
				if (!runMultipleFiles)
					monitor.Dispose ();
			}

			if (result.GeneratedFilePath.IsNullOrEmpty || !File.Exists (result.GeneratedFilePath))
				return true;

			// broadcast a change event so text editors etc reload the file
			FileService.NotifyFileChanged (result.GeneratedFilePath);

			// add file to project, update file properties, etc
			Gtk.Application.Invoke (delegate {
				bool projectChanged = false;
				if (genFile == null) {
					genFile = file.Project.AddFile (result.GeneratedFilePath, result.OverrideBuildAction);
					projectChanged = true;
				} else if (result.GeneratedFilePath != genFile.FilePath) {
					genFile.Name = result.GeneratedFilePath;
					projectChanged = true;
				}

				if (file.LastGenOutput != genFileName) {
					file.LastGenOutput = genFileName;
					projectChanged = true;
				}

				if (genFile.DependsOn != file.FilePath.FileName) {
					genFile.DependsOn = file.FilePath.FileName;
					projectChanged = true;
				}

				if (projectChanged)
					IdeApp.ProjectOperations.Save (file.Project);
			});

			return true;
		}
Exemple #46
0
        public static async void Update(ProjectFile file, Project project, bool force)
        {
            SingleProjectFileCustomTool tool;
            ProjectFile genFile;

            if (!ShouldRunGenerator(file, project, force, out tool, out genFile))
            {
                return;
            }

            TaskService.Errors.ClearByOwner(file);

            TaskInfo runningTask;
            TaskCompletionSource <bool> newTask = new TaskCompletionSource <bool> ();
            var  result                = new SingleFileCustomToolResult();
            Task existingTask          = null;
            CancellationTokenSource cs = new CancellationTokenSource();

            // if this file is already being run, cancel it

            lock (runningTasks) {
                if (runningTasks.TryGetValue(file.FilePath, out runningTask))
                {
                    runningTask.CancellationTokenSource.Cancel();
                    runningTasks.Remove(file.FilePath);
                    existingTask = runningTask.Task;
                }
                runningTask = new TaskInfo {
                    Task = newTask.Task, CancellationTokenSource = cs, Result = result
                };
                runningTasks.Add(file.FilePath, runningTask);
            }

            // If a task was already running, wait for it to finish. Running the same task in parallel may lead
            // to file sharing violation errors

            if (existingTask != null)
            {
                try {
                    await existingTask;
                } catch {
                    // Ignore exceptions, they are handled elsewhere
                }
            }

            // Maybe I was cancelled while I was waiting. In that case, the task has already been removed from
            // the runningTasks collection

            if (cs.IsCancellationRequested)
            {
                newTask.TrySetResult(true);
                return;
            }

            // Execute the generator

            Exception error = null;

            // Share the one pad for all Tool output.
            Pad pad = null;

            if (monitorPad != null)
            {
                monitorPad.TryGetTarget(out pad);
            }

            if (pad == null)
            {
                pad = IdeApp.Workbench.ProgressMonitors.CreateMonitorPad("MonoDevelop.Ide.ToolOutput", GettextCatalog.GetString("Tool Output"),
                                                                         Stock.PadExecute, false, true, true);
                pad.Visible = true;
                ((DefaultMonitorPad)pad.Content).ClearOnBeginProgress = false;

                monitorPad = new WeakReference <Pad> (pad);
            }
            var monitor = ((DefaultMonitorPad)pad.Content).BeginProgress(GettextCatalog.GetString("Tool Output"));

            monitor.WithCancellationSource(cs);

            try {
                monitor.BeginTask(GettextCatalog.GetString("Running generator '{0}' on file '{1}'...", file.Generator, file.Name), 1);

                try {
                    await tool.Generate(monitor, project, file, result);
                } catch (Exception ex) {
                    error = ex;
                    result.UnhandledException = ex;
                }

                // Generation has finished. Remove the task from the runningTasks collection

                lock (runningTasks) {
                    TaskInfo registeredTask;
                    if (runningTasks.TryGetValue(file.FilePath, out registeredTask) && registeredTask == runningTask)
                    {
                        runningTasks.Remove(file.FilePath);
                        UpdateCompleted(monitor, file, genFile, result, false);
                    }
                    else
                    {
                        // it was cancelled because another was run for the same file, so just clean up
                        monitor.EndTask();
                        monitor.ReportWarning(GettextCatalog.GetString("Cancelled because generator ran again for the same file"));
                        monitor.Dispose();
                    }
                }
            } catch (Exception ex) {
                result.UnhandledException = ex;
                UpdateCompleted(monitor, file, genFile, result, false);
            } finally {
                if (error == null)
                {
                    newTask.SetResult(true);
                }
                else
                {
                    newTask.SetException(error);
                }
            }
        }
 public Task Generate(ProgressMonitor monitor, ProjectFile file, SingleFileCustomToolResult result)
 {
     return(GenerateFile(file, result, true));
 }