~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/MonoDevelop.GtkCore/MonoDevelop.GtkCore.GuiBuilder/GuiBuilderService.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
343
343
                        if (ProjectDomService.HasDom (project)) {
344
344
                                // Only update the parser database if the project is actually loaded in the IDE.
345
345
                                if (saveToFile) {
346
 
                                        ProjectDomService.Parse (project, fileName, "");
 
346
                                        ProjectDomService.Parse (project, fileName);
347
347
                                        FileService.NotifyFileChanged (fileName);
348
348
                                }
349
349
                                else
350
 
                                        ProjectDomService.Parse (project, fileName, "", ((StringWriter)fileStream).ToString ());
 
350
                                        ProjectDomService.Parse (project, fileName, ((StringWriter)fileStream).ToString ());
351
351
                        }
352
352
 
353
353
                        return fileName;
358
358
                {
359
359
                        if (generating || !GtkDesignInfo.HasDesignedObjects (project))
360
360
                                return null;
361
 
 
362
 
                        GtkDesignInfo info = GtkDesignInfo.FromProject (project);
363
 
 
364
 
                        DateTime last_gen_time = File.Exists (info.SteticGeneratedFile) ? File.GetLastWriteTime (info.SteticGeneratedFile) : DateTime.MinValue;
365
361
                        
366
 
                        bool ref_changed = false;
367
 
                        foreach (ProjectReference pref in project.References) {
368
 
                                if (!pref.IsValid)
369
 
                                        continue;
370
 
                                foreach (string filename in pref.GetReferencedFileNames (configuration)) {
371
 
                                        if (File.GetLastWriteTime (filename) > last_gen_time) {
372
 
                                                ref_changed = true;
 
362
                        using (var timer = Counters.SteticFileGeneratedTimer.BeginTiming ()) {
 
363
                                
 
364
                                timer.Trace ("Checking references");
 
365
                                GtkDesignInfo info = GtkDesignInfo.FromProject (project);
 
366
        
 
367
                                DateTime last_gen_time = File.Exists (info.SteticGeneratedFile) ? File.GetLastWriteTime (info.SteticGeneratedFile) : DateTime.MinValue;
 
368
                                
 
369
                                bool ref_changed = false;
 
370
                                foreach (ProjectReference pref in project.References) {
 
371
                                        if (!pref.IsValid)
 
372
                                                continue;
 
373
                                        foreach (string filename in pref.GetReferencedFileNames (configuration)) {
 
374
                                                if (File.GetLastWriteTime (filename) > last_gen_time) {
 
375
                                                        ref_changed = true;
 
376
                                                        break;
 
377
                                                }
 
378
                                        }
 
379
                                        if (ref_changed)
373
380
                                                break;
 
381
                                }
 
382
        
 
383
                                // Check if generated code is already up to date.
 
384
                                if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
 
385
                                        return null;
 
386
                                
 
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 ();
 
390
                                        return null;
 
391
                                }
 
392
                                
 
393
                                if (info.GuiBuilderProject.IsEmpty) 
 
394
                                        return null;
 
395
        
 
396
                                monitor.Log.WriteLine (GettextCatalog.GetString ("Generating GUI code for project '{0}'...", project.Name));
 
397
                                
 
398
                                timer.Trace ("Copy support files");
 
399
                                
 
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);
 
403
                                
 
404
                                timer.Trace ("Update libraries");
 
405
                                
 
406
                                info.GuiBuilderProject.UpdateLibraries ();
 
407
                                
 
408
                                ArrayList projects = new ArrayList ();
 
409
                                projects.Add (info.GuiBuilderProject.File);
 
410
                                
 
411
                                generating = true;
 
412
                                Stetic.CodeGenerationResult generationResult = null;
 
413
                                Exception generatedException = null;
 
414
                                
 
415
                                bool canGenerateInProcess = IsolationMode != Stetic.IsolationMode.None || info.GuiBuilderProject.SteticProject.CanGenerateCode;
 
416
                                
 
417
                                if (!canGenerateInProcess) {
 
418
                                        timer.Trace ("Generating out of process");
 
419
                                
 
420
                                        // Run the generation in another thread to avoid freezing the GUI
 
421
                                        System.Threading.ThreadPool.QueueUserWorkItem ( delegate {
 
422
                                                try {
 
423
                                                        // Generate the code in another process if stetic is not isolated
 
424
                                                        CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
 
425
                                                        using (cob) {
 
426
                                                                generationResult = cob.GenerateCode (projects, info.GenerateGettext, info.GettextClass, project.UsePartialTypes);
 
427
                                                        }
 
428
                                                } catch (Exception ex) {
 
429
                                                        generatedException = ex;
 
430
                                                } finally {
 
431
                                                        generating = false;
 
432
                                                }
 
433
                                        });
 
434
                                
 
435
                                        while (generating) {
 
436
                                                DispatchService.RunPendingEvents ();
 
437
                                                System.Threading.Thread.Sleep (100);
374
438
                                        }
375
 
                                }
376
 
                                if (ref_changed)
377
 
                                        break;
378
 
                        }
379
 
 
380
 
                        // Check if generated code is already up to date.
381
 
                        if (!ref_changed && last_gen_time >= File.GetLastWriteTime (info.SteticFile))
382
 
                                return null;
383
 
                        
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 ();
387
 
                                return null;
388
 
                        }
389
 
                        
390
 
                        if (info.GuiBuilderProject.IsEmpty) 
391
 
                                return null;
392
 
 
393
 
                        monitor.Log.WriteLine (GettextCatalog.GetString ("Generating GUI code for project '{0}'...", project.Name));
394
 
                        
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);
398
 
                        
399
 
                        info.GuiBuilderProject.UpdateLibraries ();
400
 
                        
401
 
                        ArrayList projects = new ArrayList ();
402
 
                        projects.Add (info.GuiBuilderProject.File);
403
 
                        
404
 
                        generating = true;
405
 
                        Stetic.CodeGenerationResult generationResult = null;
406
 
                        Exception generatedException = null;
407
 
                        
408
 
                        bool canGenerateInProcess = IsolationMode != Stetic.IsolationMode.None || info.GuiBuilderProject.SteticProject.CanGenerateCode;
409
 
                        
410
 
                        if (!canGenerateInProcess) {
411
 
                                // Run the generation in another thread to avoid freezing the GUI
412
 
                                System.Threading.ThreadPool.QueueUserWorkItem ( delegate {
 
439
                                } else {
 
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
413
443
                                        try {
414
 
                                                // Generate the code in another process if stetic is not isolated
415
 
                                                CodeGeneratorProcess cob = (CodeGeneratorProcess) Runtime.ProcessService.CreateExternalProcessObject (typeof (CodeGeneratorProcess), false);
416
 
                                                using (cob) {
417
 
                                                        generationResult = cob.GenerateCode (projects, info.GenerateGettext, info.GettextClass, project.UsePartialTypes);
418
 
                                                }
 
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;
 
452
                                        }
 
453
                                        generating = false;
 
454
                                }
 
455
                                timer.Trace ("Writing code units");
 
456
                                
 
457
                                if (generatedException != null) {
 
458
                                        LoggingService.LogError ("GUI code generation failed", generatedException);
 
459
                                        throw new UserException ("GUI code generation failed: " + generatedException.Message);
 
460
                                }
 
461
                                
 
462
                                if (generationResult == null)
 
463
                                        return null;
 
464
                                        
 
465
                                CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
 
466
                                if (provider == null)
 
467
                                        throw new UserException ("Code generation not supported for language: " + project.LanguageName);
 
468
                                
 
469
                                string basePath = Path.GetDirectoryName (info.SteticGeneratedFile);
 
470
                                string ext = Path.GetExtension (info.SteticGeneratedFile);
 
471
                                
 
472
                                foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
 
473
                                        string fname;
 
474
                                        if (unit.Name.Length == 0)
 
475
                                                fname = info.SteticGeneratedFile;
 
476
                                        else
 
477
                                                fname = Path.Combine (basePath, unit.Name) + ext;
 
478
                                        StringWriter sw = new StringWriter ();
 
479
                                        try {
 
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);
421
489
                                        } finally {
422
 
                                                generating = false;
 
490
                                                timer.Trace ("Notifying changes");
 
491
                                                FileService.NotifyFileChanged (fname);
423
492
                                        }
424
 
                                });
425
 
                        
426
 
                                while (generating) {
427
 
                                        DispatchService.RunPendingEvents ();
428
 
                                        System.Threading.Thread.Sleep (100);
429
 
                                }
430
 
                        } else {
431
 
                                // No need to create another process, since stetic has its own backend process
432
 
                                // or the widget libraries have no custom wrappers
433
 
                                try {
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;
442
 
                                }
443
 
                                generating = false;
444
 
                        }
445
 
                        
446
 
                        if (generatedException != null) {
447
 
                                LoggingService.LogError ("GUI code generation failed", generatedException);
448
 
                                throw new UserException ("GUI code generation failed: " + generatedException.Message);
449
 
                        }
450
 
                        
451
 
                        if (generationResult == null)
452
 
                                return null;
453
 
                                
454
 
                        CodeDomProvider provider = project.LanguageBinding.GetCodeDomProvider ();
455
 
                        if (provider == null)
456
 
                                throw new UserException ("Code generation not supported for language: " + project.LanguageName);
457
 
                        
458
 
                        string basePath = Path.GetDirectoryName (info.SteticGeneratedFile);
459
 
                        string ext = Path.GetExtension (info.SteticGeneratedFile);
460
 
                        
461
 
                        foreach (Stetic.SteticCompilationUnit unit in generationResult.Units) {
462
 
                                string fname;
463
 
                                if (unit.Name.Length == 0)
464
 
                                        fname = info.SteticGeneratedFile;
465
 
                                else
466
 
                                        fname = Path.Combine (basePath, unit.Name) + ext;
467
 
                                StringWriter sw = new StringWriter ();
468
 
                                try {
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);
475
 
                                } finally {
476
 
                                        FileService.NotifyFileChanged (fname);
477
 
                                }
478
 
                        }
479
 
                        
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);
484
 
                                });
485
 
                        }
486
 
                        
487
 
                        return generationResult;
 
493
                                }
 
494
                                
 
495
                                timer.Trace ("Updating GTK folder");
 
496
                                
 
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);
 
501
                                        });
 
502
                                }
 
503
                                
 
504
                                return generationResult;
 
505
                        }
488
506
                }
489
507
                
490
508
                internal static string ImportFile (Project prj, string file)
511
529
                {
512
530
                        content = StripHeaderAndBlankLines (content, provider);
513
531
                        string mt = DesktopService.GetMimeTypeForUri (file);
514
 
                        Formatter formatter = TextFileService.GetFormatter (mt);
 
532
                        var formatter = MonoDevelop.Ide.CodeFormatting.CodeFormatterService.GetFormatter (mt);
515
533
                        if (formatter != null)
516
534
                                content = formatter.FormatText (PolicyService.InvariantPolicies, content);
517
535
                        return content;
522
540
                        Mono.TextEditor.Document doc = new Mono.TextEditor.Document ();
523
541
                        doc.Text = text;
524
542
                        int realStartLine = 0;
525
 
                        for (int i = 0; i < doc.LineCount; i++) {
 
543
                        for (int i = 1; i <= doc.LineCount; i++) {
526
544
                                string lineText = doc.GetTextAt (doc.GetLine (i));
527
545
                                // Microsoft.NET generates "auto-generated" tags where Mono generates "autogenerated" tags.
528
546
                                if (lineText.Contains ("</autogenerated>") || lineText.Contains ("</auto-generated>")) {
536
554
                        // We reformat the C# generated output to the user's coding style anyway, but the reformatter preserves blank lines
537
555
                        if (provider is Microsoft.CSharp.CSharpCodeProvider) {
538
556
                                bool previousWasBlank = false;
539
 
                                for (int i = 0; i < doc.LineCount; i++) {
 
557
                                for (int i = 1; i <= doc.LineCount; i++) {
540
558
                                        Mono.TextEditor.LineSegment line = doc.GetLine (i);
541
559
                                        bool isBlank, isBracket;
542
560
                                        CheckLine (doc, line, out isBlank, out isBracket);