/// <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"), 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.Log.WriteLine("Found {0} changed types", updates.Count); monitor.EndTask(); int count = updates.Count + (newTypes != null ? newTypes.Count : 0); monitor.BeginTask(GettextCatalog.GetString("Updating types in MonoDevelop"), count); // First, add new types... if (newTypes != null && newTypes.Count > 0) { foreach (var nt in newTypes) { 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("Syncing {0} types from Xcode to file '{1}'", df.Value.Count, 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.SetSyncTimeToNow(type.ObjCName + ".h"); context.SetSyncTimeToNow(type.ObjCName + ".m"); } } // 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; monitor.BeginTask(GettextCatalog.GetString("Generating custom classes defined in UI definition files"), 0); // Collect our list of custom classes from UI definition files foreach (var job in context.FileSyncJobs) { if (!HasInterfaceDefinitionExtension(job.Original)) { continue; } 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(); monitor.EndTask(); return(addedTypes); }