/// <summary> /// Updates the cli types. /// </summary> /// <returns> /// Returns whether or not any files were added to the project. /// </returns> /// <param name='monitor'> /// A progress monitor. /// </param> /// <param name='context'> /// A sync-back context. /// </param> /// <param name='typesAdded'> /// An output variable specifying whether or not any types were added to the project. /// </param> bool UpdateCliTypes (IProgressMonitor monitor, XcodeSyncBackContext context, out bool typesAdded) { var provider = dnp.LanguageBinding.GetCodeDomProvider (); var options = new System.CodeDom.Compiler.CodeGeneratorOptions (); var writer = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject ( new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor (), dnp); monitor.BeginTask (GettextCatalog.GetString ("Detecting changes made in Xcode to custom user types..."), 0); Dictionary<string, NSObjectTypeInfo> newTypes; Dictionary<string, ProjectFile> newFiles; var updates = context.GetTypeUpdates (monitor, provider, out newTypes, out newFiles); if ((updates == null || updates.Count == 0) && newTypes == null && newFiles == null) { monitor.Log.WriteLine ("No changes found."); monitor.EndTask (); typesAdded = false; return false; } monitor.EndTask (); int count = updates.Count + (newTypes != null ? newTypes.Count : 0); monitor.BeginTask (GettextCatalog.GetString ("Updating custom user types in MonoDevelop..."), count); // First, add new types... if (newTypes != null && newTypes.Count > 0) { foreach (var nt in newTypes) { monitor.Log.WriteLine ("Adding new type: {0}", nt.Value.CliName); if (provider is Microsoft.CSharp.CSharpCodeProvider) { var cs = new CSharpCodeTypeDefinition () { WrapperNamespace = infoService.WrapperRoot, Provider = provider, Type = nt.Value, }; string baseDir = Path.GetDirectoryName (nt.Key); if (!Directory.Exists (baseDir)) Directory.CreateDirectory (baseDir); writer.WriteFile (nt.Key, cs.TransformText ()); } else { // FIXME: implement support for non-C# languages } monitor.Step (1); } typesAdded = true; } else { typesAdded = false; } // Next, generate the designer files for any added/changed types foreach (var df in updates) { monitor.Log.WriteLine ("Generating designer file: {0}", df.Key); if (provider is Microsoft.CSharp.CSharpCodeProvider) { var cs = new CSharpCodeCodebehind () { Types = df.Value, WrapperNamespace = infoService.WrapperRoot, Provider = provider, }; writer.WriteFile (df.Key, cs.TransformText ()); } else { var ccu = GenerateCompileUnit (provider, options, df.Key, df.Value); writer.WriteFile (df.Key, ccu); } monitor.Step (1); } writer.WriteOpenFiles (); // Update sync timestamps foreach (var df in updates) { foreach (var type in df.Value) context.SetSyncTime (type.ObjCName + ".h", DateTime.Now); } // Add new files to the DotNetProject if (newFiles != null) { foreach (var f in newFiles) { monitor.Log.WriteLine ("Added new designer file: {0}", f.Key); dnp.AddFile (f.Value); } } monitor.EndTask (); return newFiles != null && newFiles.Count > 0; }
/// <summary> /// Adds the custom classes from user interface definition files. /// </summary> /// <returns> /// <c>true</c> if new types were added to the project, or <c>false</c> otherwise. /// </returns> /// <param name='monitor'> /// A progress monitor. /// </param> /// <param name='context'> /// A sync-back context. /// </param> bool AddCustomClassesFromUIDefinitionFiles (IProgressMonitor monitor, XcodeSyncBackContext context) { var provider = dnp.LanguageBinding.GetCodeDomProvider (); var options = new System.CodeDom.Compiler.CodeGeneratorOptions (); var writer = MonoDevelop.DesignerSupport.CodeBehindWriter.CreateForProject ( new MonoDevelop.Core.ProgressMonitoring.NullProgressMonitor (), dnp); bool addedTypes = false; bool beganTask = false; // Collect our list of custom classes from UI definition files foreach (var job in context.FileSyncJobs) { if (!HasInterfaceDefinitionExtension (job.Original)) continue; if (!beganTask) { monitor.BeginTask (GettextCatalog.GetString ("Generating custom classes defined in UI definition files..."), 0); beganTask = true; } string relative = job.SyncedRelative.ParentDirectory; string dir = dnp.BaseDirectory; if (!string.IsNullOrEmpty (relative)) dir = Path.Combine (dir, relative); foreach (var type in GetCustomTypesFromUIDefinition (job.Original)) { if (context.ProjectInfo.ContainsType (type.ObjCName)) continue; string designerPath = Path.Combine (dir, type.ObjCName + ".designer." + provider.FileExtension); string path = Path.Combine (dir, type.ObjCName + "." + provider.FileExtension); string ns = dnp.GetDefaultNamespace (path); type.CliName = ns + "." + provider.CreateValidIdentifier (type.ObjCName); if (provider is Microsoft.CSharp.CSharpCodeProvider) { CodebehindTemplateBase cs = new CSharpCodeTypeDefinition () { WrapperNamespace = infoService.WrapperRoot, Provider = provider, Type = type, }; writer.WriteFile (path, cs.TransformText ()); List<NSObjectTypeInfo> types = new List<NSObjectTypeInfo> (); types.Add (type); cs = new CSharpCodeCodebehind () { WrapperNamespace = infoService.WrapperRoot, Provider = provider, Types = types, }; writer.WriteFile (designerPath, cs.TransformText ()); context.ProjectInfo.InsertUpdatedType (type); } else { // FIXME: implement support for non-C# languages } dnp.AddFile (new ProjectFile (path)); dnp.AddFile (new ProjectFile (designerPath) { DependsOn = path }); addedTypes = true; } } writer.WriteOpenFiles (); if (beganTask) monitor.EndTask (); return addedTypes; }