359
359
if (generating || !GtkDesignInfo.HasDesignedObjects (project))
362
GtkDesignInfo info = GtkDesignInfo.FromProject (project);
364
DateTime last_gen_time = File.Exists (info.SteticGeneratedFile) ? File.GetLastWriteTime (info.SteticGeneratedFile) : DateTime.MinValue;
366
bool ref_changed = false;
367
foreach (ProjectReference pref in project.References) {
370
foreach (string filename in pref.GetReferencedFileNames (configuration)) {
371
if (File.GetLastWriteTime (filename) > last_gen_time) {
362
using (var timer = Counters.SteticFileGeneratedTimer.BeginTiming ()) {
364
timer.Trace ("Checking references");
365
GtkDesignInfo info = GtkDesignInfo.FromProject (project);
367
DateTime last_gen_time = File.Exists (info.SteticGeneratedFile) ? File.GetLastWriteTime (info.SteticGeneratedFile) : DateTime.MinValue;
369
bool ref_changed = false;
370
foreach (ProjectReference pref in project.References) {
373
foreach (string filename in pref.GetReferencedFileNames (configuration)) {
374
if (File.GetLastWriteTime (filename) > last_gen_time) {
383
// Check if generated code is already up to date.
384
if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
387
if (info.GuiBuilderProject.HasError) {
388
monitor.ReportError (GettextCatalog.GetString ("GUI code generation failed for project '{0}'. The file '{1}' could not be loaded.", project.Name, info.SteticFile), null);
389
monitor.AsyncOperation.Cancel ();
393
if (info.GuiBuilderProject.IsEmpty)
396
monitor.Log.WriteLine (GettextCatalog.GetString ("Generating GUI code for project '{0}'...", project.Name));
398
timer.Trace ("Copy support files");
400
// Make sure the referenced assemblies are up to date. It is necessary to do
401
// it now since they may contain widget libraries.
402
project.CopySupportFiles (monitor, configuration);
404
timer.Trace ("Update libraries");
406
info.GuiBuilderProject.UpdateLibraries ();
408
ArrayList projects = new ArrayList ();
409
projects.Add (info.GuiBuilderProject.File);
412
Stetic.CodeGenerationResult generationResult = null;
413
Exception generatedException = null;
415
bool canGenerateInProcess = IsolationMode != Stetic.IsolationMode.None || info.GuiBuilderProject.SteticProject.CanGenerateCode;
417
if (!canGenerateInProcess) {
418
timer.Trace ("Generating out of process");
420
// Run the generation in another thread to avoid freezing the GUI
421
System.Threading.ThreadPool.QueueUserWorkItem ( delegate {
423
// Generate the code in another process if stetic is not isolated
424
CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
426
generationResult = cob.GenerateCode (projects, info.GenerateGettext, info.GettextClass, project.UsePartialTypes);
428
} catch (Exception ex) {
429
generatedException = ex;
436
DispatchService.RunPendingEvents ();
437
System.Threading.Thread.Sleep (100);
380
// Check if generated code is already up to date.
381
if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
384
if (info.GuiBuilderProject.HasError) {
385
monitor.ReportError (GettextCatalog.GetString ("GUI code generation failed for project '{0}'. The file '{1}' could not be loaded.", project.Name, info.SteticFile), null);
386
monitor.AsyncOperation.Cancel ();
390
if (info.GuiBuilderProject.IsEmpty)
393
monitor.Log.WriteLine (GettextCatalog.GetString ("Generating GUI code for project '{0}'...", project.Name));
395
// Make sure the referenced assemblies are up to date. It is necessary to do
396
// it now since they may contain widget libraries.
397
project.CopySupportFiles (monitor, configuration);
399
info.GuiBuilderProject.UpdateLibraries ();
401
ArrayList projects = new ArrayList ();
402
projects.Add (info.GuiBuilderProject.File);
405
Stetic.CodeGenerationResult generationResult = null;
406
Exception generatedException = null;
408
bool canGenerateInProcess = IsolationMode != Stetic.IsolationMode.None || info.GuiBuilderProject.SteticProject.CanGenerateCode;
410
if (!canGenerateInProcess) {
411
// Run the generation in another thread to avoid freezing the GUI
412
System.Threading.ThreadPool.QueueUserWorkItem ( delegate {
440
timer.Trace ("Generating in-process");
441
// No need to create another process, since stetic has its own backend process
442
// or the widget libraries have no custom wrappers
414
// Generate the code in another process if stetic is not isolated
415
CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
417
generationResult = cob.GenerateCode (projects, info.GenerateGettext, info.GettextClass, project.UsePartialTypes);
444
Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
445
options.UseGettext = info.GenerateGettext;
446
options.GettextClass = info.GettextClass;
447
options.UsePartialClasses = project.UsePartialTypes;
448
options.GenerateSingleFile = false;
449
generationResult = SteticApp.GenerateProjectCode (options, info.GuiBuilderProject.SteticProject);
419
450
} catch (Exception ex) {
420
451
generatedException = ex;
455
timer.Trace ("Writing code units");
457
if (generatedException != null) {
458
LoggingService.LogError ("GUI code generation failed", generatedException);
459
throw new UserException ("GUI code generation failed: " + generatedException.Message);
462
if (generationResult == null)
465
CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
466
if (provider == null)
467
throw new UserException ("Code generation not supported for language: " + project.LanguageName);
469
string basePath = Path.GetDirectoryName (info.SteticGeneratedFile);
470
string ext = Path.GetExtension (info.SteticGeneratedFile);
472
foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
474
if (unit.Name.Length == 0)
475
fname = info.SteticGeneratedFile;
477
fname = Path.Combine (basePath, unit.Name) + ext;
478
StringWriter sw = new StringWriter ();
480
foreach (CodeNamespace ns in unit.Namespaces)
481
ns.Comments.Add (new CodeCommentStatement ("This file has been generated by the GUI designer. Do not modify."));
482
timer.Trace ("Generating code for " + unit.Name);
483
provider.GenerateCodeFromCompileUnit (unit, sw, new CodeGeneratorOptions ());
484
string content = sw.ToString ();
485
timer.Trace ("Formatting code");
486
content = FormatGeneratedFile (fname, content, provider);
487
timer.Trace ("Writing code");
488
File.WriteAllText (fname, content);
490
timer.Trace ("Notifying changes");
491
FileService.NotifyFileChanged (fname);
427
DispatchService.RunPendingEvents ();
428
System.Threading.Thread.Sleep (100);
431
// No need to create another process, since stetic has its own backend process
432
// or the widget libraries have no custom wrappers
434
Stetic.GenerationOptions options = new Stetic.GenerationOptions ();
435
options.UseGettext = info.GenerateGettext;
436
options.GettextClass = info.GettextClass;
437
options.UsePartialClasses = project.UsePartialTypes;
438
options.GenerateSingleFile = false;
439
generationResult = SteticApp.GenerateProjectCode (options, info.GuiBuilderProject.SteticProject);
440
} catch (Exception ex) {
441
generatedException = ex;
446
if (generatedException != null) {
447
LoggingService.LogError ("GUI code generation failed", generatedException);
448
throw new UserException ("GUI code generation failed: " + generatedException.Message);
451
if (generationResult == null)
454
CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
455
if (provider == null)
456
throw new UserException ("Code generation not supported for language: " + project.LanguageName);
458
string basePath = Path.GetDirectoryName (info.SteticGeneratedFile);
459
string ext = Path.GetExtension (info.SteticGeneratedFile);
461
foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
463
if (unit.Name.Length == 0)
464
fname = info.SteticGeneratedFile;
466
fname = Path.Combine (basePath, unit.Name) + ext;
467
StringWriter sw = new StringWriter ();
469
foreach (CodeNamespace ns in unit.Namespaces)
470
ns.Comments.Add (new CodeCommentStatement ("This file has been generated by the GUI designer. Do not modify."));
471
provider.GenerateCodeFromCompileUnit (unit, sw, new CodeGeneratorOptions ());
472
string content = sw.ToString ();
473
content = FormatGeneratedFile (fname, content, provider);
474
File.WriteAllText (fname, content);
476
FileService.NotifyFileChanged (fname);
480
// Make sure the generated files are added to the project
481
if (info.UpdateGtkFolder ()) {
482
Gtk.Application.Invoke (delegate {
483
IdeApp.ProjectOperations.Save (project);
487
return generationResult;
495
timer.Trace ("Updating GTK folder");
497
// Make sure the generated files are added to the project
498
if (info.UpdateGtkFolder ()) {
499
Gtk.Application.Invoke (delegate {
500
IdeApp.ProjectOperations.Save (project);
504
return generationResult;
490
508
internal static string ImportFile (Project prj, string file)