NSObjectTypeInfo ConvertType(TypeSystemService.ProjectContentWrapper dom, ITypeDefinition type)
        {
            string objcName             = null;
            bool   isModel              = false;
            bool   registeredInDesigner = true;

            foreach (var att in type.Attributes)
            {
                var attType = att.AttributeType;
                if (attType.Equals(Resolve(dom, registerAttType)))
                {
                    if (type.GetProjectContent() != null)
                    {
                        registeredInDesigner &=
                            MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(att.Region.FileName);
                    }

                    //type registered with an explicit type name are up to the user to provide a valid name
                    var posArgs = att.PositionalArguments;
                    if (posArgs.Count == 1 || posArgs.Count == 2)
                    {
                        objcName = posArgs [0].ConstantValue as string;
                    }
                    //non-nested types in the root namespace have names accessible from obj-c
                    else if (string.IsNullOrEmpty(type.Namespace) && type.Name.IndexOf('.') < 0)
                    {
                        objcName = type.Name;
                    }
                }

                if (attType.Equals(Resolve(dom, modelAttType)))
                {
                    isModel = true;
                }
            }

            if (string.IsNullOrEmpty(objcName))
            {
                return(null);
            }

            string baseType = type.DirectBaseTypes.First().ReflectionName;

            if (baseType == "System.Object")
            {
                baseType = null;
            }

            bool isUserType = !type.ParentAssembly.Equals(Resolve(dom, nsobjectType).ParentAssembly);

            var info = new NSObjectTypeInfo(objcName, type.ReflectionName, null, baseType, isModel, isUserType, registeredInDesigner);

            if (info.IsUserType)
            {
                UpdateTypeMembers(dom, info, type);
                info.DefinedIn = type.Parts.Select(p => (string)p.Region.FileName).ToArray();
            }

            return(info);
        }
        bool TryResolveObjcToCli(string objcType, out NSObjectTypeInfo resolved)
        {
            if (objcTypes.TryGetValue(objcType, out resolved))
            {
                return(true);
            }
            if (refObjcTypes.TryGetValue(objcType, out resolved))
            {
                return(true);
            }
#if false
            var msg = new StringBuilder("Can't resolve " + objcType + Environment.NewLine);
            foreach (var r in dom.References)
            {
                msg.Append("Referenced dom:");
                msg.Append(r);
                var rDom = infoService.GetProjectInfo(r);
                if (rDom == null)
                {
                    msg.AppendLine("projectinfo == null");
                    continue;
                }
                msg.Append("known types:");
                msg.AppendLine(string.Join(",", rDom.objcTypes.Keys.ToArray()));
            }
            LoggingService.LogWarning(msg.ToString());
#endif
            resolved = null;
            return(false);
        }
Example #3
0
        void UpdateType(ProjectDom dom, NSObjectTypeInfo info, IType type)
        {
            info.Actions.Clear();
            info.Outlets.Clear();

            foreach (var prop in type.Properties)
            {
                foreach (var att in prop.Attributes)
                {
                    if (att.AttributeType.FullName != connectAttType.FullName)
                    {
                        continue;
                    }
                    string name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                    }
                    if (string.IsNullOrEmpty(name))
                    {
                        name = prop.Name;
                    }
                    info.Outlets.Add(new IBOutlet(name, prop.Name, null, prop.ReturnType.FullName));
                    break;
                }
            }

            foreach (var meth in type.Methods)
            {
                foreach (var att in meth.Attributes)
                {
                    if (att.AttributeType.FullName != exportAttType.FullName)
                    {
                        continue;
                    }
                    string[] name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                        if (!string.IsNullOrEmpty(n))
                        {
                            name = n.Split(colonChar);
                        }
                    }
                    var action = new IBAction(name != null? name [0] : meth.Name, meth.Name);
                    info.Actions.Add(action);
                    int i = 1;
                    foreach (var param in meth.Parameters)
                    {
                        string label = name != null && i < name.Length? name[i] : null;
                        if (label != null && label.Length == 0)
                        {
                            label = null;
                        }
                        action.Parameters.Add(new IBActionParameter(label, param.Name, null, param.ReturnType.FullName));
                    }
                    break;
                }
            }
        }
Example #4
0
        /// <summary>
        /// Merges CLI info from previous version of the type into the parsed objc-type.
        /// </summary>
        public void MergeCliInfo(NSObjectTypeInfo previousType)
        {
            CliName     = previousType.CliName;
            DefinedIn   = previousType.DefinedIn;
            IsModel     = previousType.IsModel;
            BaseIsModel = previousType.BaseIsModel;
            IsUserType  = previousType.IsUserType;

            var existingOutlets = new Dictionary <string, IBOutlet> ();

            foreach (var o in previousType.Outlets)
            {
                existingOutlets[o.ObjCName] = o;
            }

            var existingActions = new Dictionary <string, IBAction> ();

            foreach (var a in previousType.Actions)
            {
                existingActions[a.ObjCName] = a;
            }

            foreach (var a in Actions)
            {
                IBAction existing;
                if (existingActions.TryGetValue(a.ObjCName, out existing))
                {
                    a.CliName = existing.CliName;
                    if (!existing.IsDesigner)
                    {
                        continue;
                    }
                }
                else
                {
                    a.CliName = a.ObjCName;
                }
                a.IsDesigner = true;
            }

            foreach (var o in Outlets)
            {
                IBOutlet existing;
                if (existingOutlets.TryGetValue(o.ObjCName, out existing))
                {
                    o.CliName = existing.CliName;
                    if (!existing.IsDesigner)
                    {
                        continue;
                    }
                }
                else
                {
                    o.CliName = o.ObjCName;
                }
                o.IsDesigner = true;
            }
        }
        NSObjectTypeInfo ConvertType(ProjectDom dom, IType type)
        {
            string objcName             = null;
            bool   isModel              = false;
            bool   registeredInDesigner = true;

            foreach (var part in type.Parts)
            {
                foreach (var att in part.Attributes)
                {
                    if (att.AttributeType.FullName == registerAttType.FullName)
                    {
                        if (type.SourceProject != null)
                        {
                            registeredInDesigner &=
                                MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(part.CompilationUnit.FileName);
                        }

                        //type registered with an explicit type name are up to the user to provide a valid name
                        // Note that the attribute now takes one *or* two parameters.
                        if (att.PositionalArguments.Count == 1 || att.PositionalArguments.Count == 2)
                        {
                            objcName = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                        }
                        //non-nested types in the root namespace have names accessible from obj-c
                        else if (string.IsNullOrEmpty(type.Namespace) && type.Name.IndexOf('.') < 0)
                        {
                            objcName = type.Name;
                        }
                    }

                    if (att.AttributeType.FullName == modelAttType.FullName)
                    {
                        isModel = true;
                    }
                }
            }

            if (string.IsNullOrEmpty(objcName))
            {
                return(null);
            }

            var info = new NSObjectTypeInfo(objcName, type.DecoratedFullName, null, type.BaseType.DecoratedFullName, isModel,
                                            type.SourceProject != null, registeredInDesigner);

            if (info.IsUserType)
            {
                UpdateTypeMembers(dom, info, type);
                info.DefinedIn = type.Parts.Select(p => (string)p.CompilationUnit.FileName).ToArray();
            }

            return(info);
        }
 bool TryResolveCliToObjc(string cliType, out NSObjectTypeInfo resolved)
 {
     if (cliTypes.TryGetValue(cliType, out resolved))
     {
         return(true);
     }
     if (refCliTypes.TryGetValue(cliType, out resolved))
     {
         return(true);
     }
     resolved = null;
     return(false);
 }
 bool TryResolveCliToObjc(string cliType, out NSObjectTypeInfo resolved)
 {
     if (cliTypes.TryGetValue(cliType, out resolved))
     {
         return(true);
     }
     foreach (var r in dom.References)
     {
         var rDom = infoService.GetProjectInfo(r);
         if (rDom != null && rDom.cliTypes.TryGetValue(cliType, out resolved))
         {
             return(true);
         }
     }
     resolved = null;
     return(false);
 }
Example #8
0
        public static NSObjectTypeInfo ParseHeader(string headerFile)
        {
            var text    = System.IO.File.ReadAllText(headerFile);
            var matches = ibRegex.Matches(text);
            var type    = new NSObjectTypeInfo(System.IO.Path.GetFileNameWithoutExtension(headerFile), null, null, null, false);

            foreach (Match match in matches)
            {
                var kind = match.Groups[1].Value;
                var def  = match.Groups[2].Value;
                if (kind == "IBOutlet")
                {
                    var split = def.Split(whitespaceChars, StringSplitOptions.RemoveEmptyEntries);
                    if (split.Length != 2)
                    {
                        continue;
                    }
                    string objcType = split[1].TrimStart('*');
                    if (objcType == "id")
                    {
                        objcType = "NSObject";
                    }
                    type.Outlets.Add(new IBOutlet((objcType), null, split[0].TrimEnd('*'), null));
                }
                else
                {
                    string[] split  = def.Split(colonChar);
                    var      action = new IBAction(split[0].Trim(), null);
                    string   label  = null;
                    for (int i = 1; i < split.Length; i++)
                    {
                        var    s        = split[i].Split(splitActionParamsChars, StringSplitOptions.RemoveEmptyEntries);
                        string objcType = s[0];
                        if (objcType == "id")
                        {
                            objcType = "NSObject";
                        }
                        var par = new IBActionParameter(label, s[1], objcType, null);
                        label = s.Length == 3? s[2] : null;
                        action.Parameters.Add(par);
                    }
                    type.Actions.Add(action);
                }
            }
            return(type);
        }
Example #9
0
        NSObjectTypeInfo ConvertType(ProjectDom dom, IType type)
        {
            string objcName = null;
            bool   isModel  = false;

            foreach (var att in type.Attributes)
            {
                if (att.AttributeType.FullName == registerAttType.FullName)
                {
                    //type registered with an explicit type name are up to the user to proide a valid name
                    if (att.PositionalArguments.Count == 1)
                    {
                        objcName = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                    }
                    //non-nested types in the root namespace have names accessible from obj-c
                    else if (string.IsNullOrEmpty(type.Namespace) && type.Name.IndexOf('.') < 0)
                    {
                        objcName = type.Name;
                    }
                }
                if (att.AttributeType.FullName == modelAttType.FullName)
                {
                    isModel = true;
                }
            }
            if (string.IsNullOrEmpty(objcName))
            {
                return(null);
            }

            var info = new NSObjectTypeInfo(objcName, type.FullName, null, type.BaseType.FullName, isModel);

            info.IsUserType = type.SourceProject != null;

            if (info.IsUserType)
            {
                UpdateType(dom, info, type);
                info.DefinedIn = type.Parts.Select(p => (string)p.CompilationUnit.FileName).ToArray();
            }

            return(info);
        }
Example #10
0
		/// <summary>
		/// Resolves the type by mapping the known Objective-C type information to .NET types.
		/// </summary>
		/// <returns>
		/// The number of unresolved types still remaining.
		/// </returns>
		/// <param name='type'>
		/// The NSObjectTypeInfo that contains the known Objective-C type information.
		/// Typically this will be the result of NSObjectInfoService.ParseHeader().
		/// </param>
		/// <param name='provider'>
		/// A CodeDom provider which is used to make sure type names don't conflict with language keywords.
		/// </param>
		/// <param name='defaultNamespace'>
		/// The default namespace used when forcing type resolution.
		/// </param>
		public void ResolveObjcToCli (IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace)
		{
			NSObjectTypeInfo resolved;
			
			// Resolve our base type
			if (type.BaseCliType == null) {
				if (TryResolveObjcToCli (type.BaseObjCType, out resolved)) {
					type.BaseCliType = resolved.CliName;
				} else  {
					type.BaseCliType = defaultNamespace + "." + provider.CreateValidIdentifier (type.BaseObjCType);
					monitor.ReportWarning (string.Format ("Failed to resolve Objective-C type {0} to CLI type on type {1}",
						type.BaseObjCType, type.ObjCName));
				}
			}
			
			// Resolve [Outlet] types
			foreach (var outlet in type.Outlets) {
				if (outlet.CliType != null)
					continue;
				
				if (TryResolveObjcToCli (outlet.ObjCType, out resolved)) {
					outlet.CliType = resolved.CliName;
				} else {
					outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (outlet.ObjCType);
					monitor.ReportWarning (string.Format ("Failed to resolve Objective-C type {0} to CLI type on outlet {1} on type {2}",
						outlet.ObjCType, outlet.ObjCName, type.ObjCName));
				}
			}
			
			// Resolve [Action] param types
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.CliType != null)
						continue;
					
					if (TryResolveObjcToCli (param.ObjCType, out resolved)) {
						param.CliType = resolved.CliName;
					} else {
						param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (param.ObjCType);
						monitor.ReportWarning (string.Format ("Failed to resolve Objective-C type {0} to CLI type on action parameter {1} for action {2} on type {3}",
							param.ObjCType, param.Name, action.ObjCName, type.ObjCName));
					}
				}
			}
		}
Example #11
0
		bool TryResolveCliToObjc (string cliType, out NSObjectTypeInfo resolved)
		{
			if (cliTypes.TryGetValue (cliType, out resolved))
				return true;
			foreach (var r in dom.References) {
				var rDom = infoService.GetProjectInfo (r);
				if (rDom != null && rDom.cliTypes.TryGetValue (cliType, out resolved))
					return true;
			}
			resolved = null;
			return false;
		}
Example #12
0
		public XcodeSyncedType (NSObjectTypeInfo type)
		{
			this.Type = type;
		}
        /// <summary>
        /// Resolves the type by mapping the known Objective-C type information to .NET types.
        /// </summary>
        /// <returns>
        /// The number of unresolved types still remaining.
        /// </returns>
        /// <param name='type'>
        /// The NSObjectTypeInfo that contains the known Objective-C type information.
        /// Typically this will be the result of NSObjectInfoService.ParseHeader().
        /// </param>
        /// <param name='provider'>
        /// A CodeDom provider which is used to make sure type names don't conflict with language keywords.
        /// </param>
        /// <param name='defaultNamespace'>
        /// The default namespace used when forcing type resolution.
        /// </param>
        public void ResolveObjcToCli(IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace)
        {
            NSObjectTypeInfo resolved;

            // Resolve our base type
            if (type.BaseCliType == null)
            {
                if (TryResolveObjcToCli(type.BaseObjCType, out resolved))
                {
                    type.BaseCliType = resolved.CliName;
                }
                else
                {
                    var reference = new GetClassTypeReference(defaultNamespace, provider.CreateValidIdentifier(type.BaseObjCType));
                    type.BaseCliType = reference.Resolve(dom.Compilation).ReflectionName;

                    var message = string.Format("Failed to resolve Objective-C type '{0}' to a type in the current solution.", type.BaseObjCType);
                    message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", type.BaseObjCType);
                    monitor.ReportError(null, new UserException("Error while syncing", message));
                }
            }

            // Resolve [Outlet] types
            foreach (var outlet in type.Outlets)
            {
                if (outlet.CliType != null)
                {
                    continue;
                }

                if (TryResolveObjcToCli(outlet.ObjCType, out resolved))
                {
                    outlet.CliType = resolved.CliName;
                }
                else
                {
                    outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(outlet.ObjCType);

                    var message = string.Format("Failed to resolve Objective-C outlet '{0}' of type '{1}' to a type in the current solution.", outlet.ObjCName, outlet.ObjCType);
                    message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", outlet.ObjCType);
                    monitor.ReportError(null, new UserException("Error while syncing", message));
                }
            }

            // Resolve [Action] param types
            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.CliType != null)
                    {
                        continue;
                    }

                    if (TryResolveObjcToCli(param.ObjCType, out resolved))
                    {
                        param.CliType = resolved.CliName;
                    }
                    else
                    {
                        param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(param.ObjCType);

                        var message = string.Format("Failed to resolve paramater '{0}' of type '{2}' on Objective-C action '{1}' to a type in the current solution.", param.Name, action.ObjCName, param.ObjCType);
                        message += string.Format(" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", param.ObjCType);
                        monitor.ReportError(null, new UserException("Error while syncing", message));
                    }
                }
            }
        }
        void UpdateTypeMembers(ProjectDom dom, NSObjectTypeInfo info, IType type)
        {
            info.Actions.Clear();
            info.Outlets.Clear();

            foreach (var prop in type.Properties)
            {
                foreach (var att in prop.Attributes)
                {
                    bool isIBOutlet = att.AttributeType.FullName == iboutletAttType.FullName;
                    if (!isIBOutlet)
                    {
                        if (att.AttributeType.FullName != connectAttType.FullName)
                        {
                            continue;
                        }
                    }
                    string name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                    }
                    if (string.IsNullOrEmpty(name))
                    {
                        name = prop.Name;
                    }

                    // HACK: Work around bug #1586 in the least obtrusive way possible. Strip out any outlet
                    // with the name 'view' on subclasses of MonoTouch.UIKit.UIViewController to avoid
                    // conflicts with the view property mapped there
                    if (name == "view")
                    {
                        if (dom.GetInheritanceTree(type).Any(p => p.FullName == "MonoTouch.UIKit.UIViewController"))
                        {
                            continue;
                        }
                    }

                    var ol = new IBOutlet(name, prop.Name, null, prop.ReturnType.FullName);
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(prop.DeclaringType.CompilationUnit.FileName))
                    {
                        ol.IsDesigner = true;
                    }
                    info.Outlets.Add(ol);
                    break;
                }
            }

            foreach (var meth in type.Methods)
            {
                foreach (var att in meth.Attributes)
                {
                    bool isIBAction = att.AttributeType.FullName == ibactionAttType.FullName;
                    if (!isIBAction)
                    {
                        if (att.AttributeType.FullName != exportAttType.FullName)
                        {
                            continue;
                        }
                    }
                    bool isDesigner = MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(
                        meth.DeclaringType.CompilationUnit.FileName);
                    //only support Export from old designer files, user code must be IBAction
                    if (!isDesigner && !isIBAction)
                    {
                        continue;
                    }

                    string[] name = null;
                    if (att.PositionalArguments.Count == 1)
                    {
                        var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
                        if (!string.IsNullOrEmpty(n))
                        {
                            name = n.Split(colonChar);
                        }
                    }
                    var action = new IBAction(name != null? name [0] : meth.Name, meth.Name);
                    int i      = 1;
                    foreach (var param in meth.Parameters)
                    {
                        string label = name != null && i < name.Length? name[i] : null;
                        if (label != null && label.Length == 0)
                        {
                            label = null;
                        }
                        action.Parameters.Add(new IBActionParameter(label, param.Name, null, param.ReturnType.FullName));
                    }
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(meth.DeclaringType.CompilationUnit.FileName))
                    {
                        action.IsDesigner = true;
                    }
                    info.Actions.Add(action);
                    break;
                }
            }
        }
 internal void InsertUpdatedType(NSObjectTypeInfo type)
 {
     objcTypes[type.ObjCName] = type;
     cliTypes[type.CliName]   = type;
 }
Example #16
0
        public void GenerateObjcType(NSObjectTypeInfo type, string directory)
        {
            if (type.IsModel)
            {
                throw new ArgumentException("Cannot generate definition for model");
            }

            string hFilePath = Path.Combine(directory, type.ObjCName + ".h");
            string mFilePath = Path.Combine(directory, type.ObjCName + ".m");

            using (var sw = File.CreateText(hFilePath)) {
                sw.WriteLine(modificationWarning);
                sw.WriteLine();

                sw.WriteLine("#import <UIKit/UIKit.h>");
                foreach (var reference in type.UserTypeReferences)
                {
                    sw.WriteLine("#import \"{0}.h\"", reference);
                }
                sw.WriteLine();

                sw.WriteLine("@interface {0} : {1} {{", type.ObjCName, type.BaseIsModel? "NSObject" : type.BaseObjCType);
                foreach (var outlet in type.Outlets)
                {
                    sw.WriteLine("\t{0} *_{1};", outlet.ObjCType, outlet.ObjCName);
                }
                sw.WriteLine("}");
                sw.WriteLine();

                foreach (var outlet in type.Outlets)
                {
                    sw.WriteLine("@property (nonatomic, retain) IBOutlet {0} *{1};", outlet.ObjCType, outlet.ObjCName);
                    sw.WriteLine();
                }

                foreach (var action in type.Actions)
                {
                    if (action.Parameters.Any(p => p.ObjCType == null))
                    {
                        continue;
                    }
                    WriteActionSignature(action, sw);
                    sw.WriteLine(";");
                    sw.WriteLine();
                }

                sw.WriteLine("@end");
            }

            using (var sw = File.CreateText(mFilePath)) {
                sw.WriteLine(modificationWarning);
                sw.WriteLine();

                sw.WriteLine("#import \"{0}.h\"", type.ObjCName);
                sw.WriteLine();

                sw.WriteLine("@implementation {0}", type.ObjCName);
                sw.WriteLine();

                bool hasOutlet = false;
                foreach (var outlet in type.Outlets)
                {
                    sw.WriteLine("@synthesize {0} = _{0};", outlet.ObjCName);
                    hasOutlet = true;
                }
                if (hasOutlet)
                {
                    sw.WriteLine();
                }

                foreach (var action in type.Actions)
                {
                    if (action.Parameters.Any(p => p.ObjCType == null))
                    {
                        continue;
                    }
                    WriteActionSignature(action, sw);
                    sw.WriteLine(" {");
                    sw.WriteLine("}");
                    sw.WriteLine();
                }

                sw.WriteLine("@end");
            }
        }
Example #17
0
		NSObjectTypeInfo ConvertType (TypeSystemService.ProjectContentWrapper dom, ITypeDefinition type)
		{
			string objcName = null;
			bool isModel = false;
			bool registeredInDesigner = true;
			
			foreach (var att in type.Attributes) {
				var attType = att.AttributeType;
				if (attType.Equals (Resolve (dom, registerAttType))) {
					if (type.GetProjectContent () != null) {
						registeredInDesigner &=
							MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (att.Region.FileName);
					}
					
					//type registered with an explicit type name are up to the user to provide a valid name
					var posArgs = att.PositionalArguments;
					if (posArgs.Count == 1 || posArgs.Count == 2)
						objcName = posArgs [0].ConstantValue as string;
					//non-nested types in the root namespace have names accessible from obj-c
					else if (string.IsNullOrEmpty (type.Namespace) && type.Name.IndexOf ('.') < 0)
						objcName = type.Name;
				}
				
				if (attType.Equals (Resolve (dom, modelAttType)))
					isModel = true;
			}
			
			if (string.IsNullOrEmpty (objcName))
				return null;
			
			string baseType = type.DirectBaseTypes.First ().ReflectionName;
			if (baseType == "System.Object")
				baseType = null;
			
			bool isUserType = !type.ParentAssembly.Equals (Resolve (dom, nsobjectType).ParentAssembly);
			
			var info = new NSObjectTypeInfo (objcName, type.ReflectionName, null, baseType, isModel, isUserType, registeredInDesigner);

			if (info.IsUserType) {
				UpdateTypeMembers (dom, info, type);
				info.DefinedIn = type.Parts.Select (p => (string) p.Region.FileName).ToArray ();
			}
			
			return info;
		}
		public void ResolveTypes (NSObjectTypeInfo type)
		{
			NSObjectTypeInfo resolved;
			if (type.BaseObjCType == null && type.BaseCliType != null) {
				if (TryResolveCliToObjc (type.BaseCliType, out resolved)) {
					if (resolved.IsModel)
						type.BaseIsModel = true;
					type.BaseObjCType = resolved.ObjCName;
					//FIXME: handle type references better
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				} else {
					//managed classes many have implicitly registered base classes with a name not
					//expressible in obj-c. In this case, the best we can do is walk down the 
					//hierarchy until we find a valid base class
					foreach (var bt in dom.GetInheritanceTree (dom.GetType (type.BaseCliType))) {
						if (bt.ClassType != ClassType.Class)
							continue;
						if (TryResolveCliToObjc (bt.FullName, out resolved)) {
							if (resolved.IsModel)
								type.BaseIsModel = true;
							type.BaseObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
							break;
						}
					}
				}
			}
			
			if (type.BaseCliType == null && type.BaseObjCType != null) {
				if (TryResolveObjcToCli (type.BaseObjCType, out resolved))
					type.BaseCliType = resolved.CliName;
			}
			
			foreach (var outlet in type.Outlets) {
				if (outlet.ObjCType == null) {
					if (TryResolveCliToObjc (outlet.CliType, out resolved)) {
						outlet.ObjCType = resolved.ObjCName;
						if (resolved.IsUserType)
							type.UserTypeReferences.Add (resolved.ObjCName);
					}
				}
				if (outlet.CliType == null) {
					if (TryResolveObjcToCli (outlet.ObjCType, out resolved)) {
						outlet.CliType = resolved.CliName;
					} else {
						MessageService.ShowError (GettextCatalog.GetString ("Error while syncing object c type."),
							string.Format (GettextCatalog.GetString ("Type '{0}' can't be resolved to a valid cli type."), outlet.ObjCType));
						ContainsErrors = true;
						outlet.CliType = outlet.ObjCType;
					}
				}
			}
			
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.ObjCType == null) {
						if (TryResolveCliToObjc (param.CliType, out resolved)) {
							param.ObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
						}
					}
					if (param.CliType == null) {
						if (TryResolveObjcToCli (param.ObjCType, out resolved))
							param.CliType = resolved.CliName;
					}
				}
			}
		}
		void UpdateUserType (NSObjectTypeInfo type)
		{
			if (userClasses.Add (type.ObjCName))
				xcodeProjectDirty = true;

			//FIXME: types dep on other types on project, need better regeneration skipping			
			//FilePath target = outputDir.Combine (type.ObjCName + ".h");
			//if (File.Exists (target) && File.GetLastWriteTime (target) >= type.DefinedIn.Max (f => File.GetLastWriteTime (f)))
			//	return;
			
			if (!Directory.Exists (outputDir))
				Directory.CreateDirectory (outputDir);
			
			type.GenerateObjcType (outputDir);
			
			string fullH = outputDir.Combine (type.ObjCName + ".h");
			trackedFiles[fullH] = File.GetLastWriteTime (fullH);
		}
Example #20
0
		public void GenerateObjcType (NSObjectTypeInfo type, string directory)
		{
			if (type.IsModel)
				throw new ArgumentException ("Cannot generate definition for model");
			
			string hFilePath = Path.Combine (directory, type.ObjCName + ".h");
			string mFilePath = Path.Combine (directory, type.ObjCName + ".m");
			
			using (var sw = File.CreateText (hFilePath)) {
				sw.WriteLine (modificationWarning);
				sw.WriteLine ();
				
				sw.WriteLine ("#import <UIKit/UIKit.h>");
				foreach (var reference in type.UserTypeReferences) {
					sw.WriteLine ("#import \"{0}.h\"", reference);
				}
				sw.WriteLine ();
				
				sw.WriteLine ("@interface {0} : {1} {{", type.ObjCName, type.BaseIsModel? "NSObject" : type.BaseObjCType);
				foreach (var outlet in type.Outlets) {
					sw.WriteLine ("\t{0} *_{1};", outlet.ObjCType, outlet.ObjCName);
				}
				sw.WriteLine ("}");
				sw.WriteLine ();
				
				foreach (var outlet in type.Outlets) {
					sw.WriteLine ("@property (nonatomic, retain) IBOutlet {0} *{1};", outlet.ObjCType, outlet.ObjCName);
					sw.WriteLine ();
				}
				
				foreach (var action in type.Actions) {
					if (action.Parameters.Any (p => p.ObjCType == null))
						continue;
					WriteActionSignature (action, sw);
					sw.WriteLine (";");
					sw.WriteLine ();
				}
				
				sw.WriteLine ("@end");
			}
			
			using (var sw = File.CreateText (mFilePath)) {
				sw.WriteLine (modificationWarning);
				sw.WriteLine ();
				
				sw.WriteLine ("#import \"{0}.h\"", type.ObjCName);
				sw.WriteLine ();
				
				sw.WriteLine ("@implementation {0}", type.ObjCName);
				sw.WriteLine ();
				
				bool hasOutlet = false;
				foreach (var outlet in type.Outlets) {
					sw.WriteLine ("@synthesize {0} = _{0};", outlet.ObjCName);
					hasOutlet = true;
				}
				if (hasOutlet)
					sw.WriteLine ();
				
				foreach (var action in type.Actions) {
					if (action.Parameters.Any (p => p.ObjCType == null))
						continue;
					WriteActionSignature (action, sw);
					sw.WriteLine (" {");
					sw.WriteLine ("}");
					sw.WriteLine ();
				}
				
				sw.WriteLine ("@end");
			}
		}
Example #21
0
		void ResolveTypes (ProjectDom dom, NSObjectTypeInfo type)
		{
			NSObjectTypeInfo resolved;
			
			if (type.BaseObjCType == null && type.BaseCliType != null) {
				if (cliTypes.TryGetValue (type.BaseCliType, out resolved)) {
					if (resolved.IsModel)
						type.BaseIsModel = true;
					type.BaseObjCType = resolved.ObjCName;
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				} else {
					//managed classes many have implicitly registered base classes with a name not
					//expressible in obj-c. In this case, the best we can do is walk down the 
					//hierarchy until we find a valid base class
					foreach (var bt in dom.GetInheritanceTree (dom.GetType (type.BaseCliType))) { 
						if (cliTypes.TryGetValue (bt.FullName, out resolved)) {
							if (resolved.IsModel)
								type.BaseIsModel = true;
							type.BaseObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
							break;
						}
					}
					if (type.BaseObjCType == null)
						Console.WriteLine ("Could not resolve CLI type '{0}'", type.BaseCliType);
				}
			}
			
			if (type.BaseCliType == null && type.BaseObjCType != null) {
				if (objcTypes.TryGetValue (type.BaseObjCType, out resolved))
					type.BaseCliType = resolved.CliName;
			}
			
			foreach (var outlet in type.Outlets) {
				if (outlet.ObjCType == null) {
					if (cliTypes.TryGetValue (outlet.CliType, out resolved)) {
						outlet.ObjCType = resolved.ObjCName;
						if (resolved.IsUserType)
							type.UserTypeReferences.Add (resolved.ObjCName);
					}
				}
				if (outlet.CliType == null) {
					if (objcTypes.TryGetValue (outlet.ObjCType, out resolved))
						outlet.CliType = resolved.CliName;
				}
			}
			
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.ObjCType == null) {
						if (cliTypes.TryGetValue (param.CliType, out resolved)) {
							param.ObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
						}
					}
					if (param.CliType == null) {
						if (objcTypes.TryGetValue (param.ObjCType, out resolved))
							param.CliType = resolved.CliName;
					}
				}
			}
		}
Example #22
0
        void ResolveTypes(NSObjectTypeInfo type)
        {
            NSObjectTypeInfo resolved;

            if (type.BaseObjCType == null && type.BaseCliType != null)
            {
                if (TryResolveCliToObjc(type.BaseCliType, out resolved))
                {
                    if (resolved.IsModel)
                    {
                        type.BaseIsModel = true;
                    }
                    type.BaseObjCType = resolved.ObjCName;
                    //FIXME: handle type references better
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
                else
                {
                    //managed classes many have implicitly registered base classes with a name not
                    //expressible in obj-c. In this case, the best we can do is walk down the
                    //hierarchy until we find a valid base class
                    foreach (var bt in dom.GetInheritanceTree(dom.GetType(type.BaseCliType)))
                    {
                        if (bt.ClassType != ClassType.Class)
                        {
                            continue;
                        }
                        if (TryResolveCliToObjc(bt.FullName, out resolved))
                        {
                            if (resolved.IsModel)
                            {
                                type.BaseIsModel = true;
                            }
                            type.BaseObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                            break;
                        }
                    }
                }
            }

            if (type.BaseCliType == null && type.BaseObjCType != null)
            {
                if (TryResolveObjcToCli(type.BaseObjCType, out resolved))
                {
                    type.BaseCliType = resolved.CliName;
                }
            }

            foreach (var outlet in type.Outlets)
            {
                if (outlet.ObjCType == null)
                {
                    if (TryResolveCliToObjc(outlet.CliType, out resolved))
                    {
                        outlet.ObjCType = resolved.ObjCName;
                        if (resolved.IsUserType)
                        {
                            type.UserTypeReferences.Add(resolved.ObjCName);
                        }
                    }
                }
                if (outlet.CliType == null)
                {
                    if (TryResolveObjcToCli(outlet.ObjCType, out resolved))
                    {
                        outlet.CliType = resolved.CliName;
                    }
                }
            }

            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.ObjCType == null)
                    {
                        if (TryResolveCliToObjc(param.CliType, out resolved))
                        {
                            param.ObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                        }
                    }
                    if (param.CliType == null)
                    {
                        if (TryResolveObjcToCli(param.ObjCType, out resolved))
                        {
                            param.CliType = resolved.CliName;
                        }
                    }
                }
            }
        }
Example #23
0
		bool TryResolveCliToObjc (string cliType, out NSObjectTypeInfo resolved)
		{
			if (cliTypes.TryGetValue (cliType, out resolved))
				return true;
			if (refCliTypes.TryGetValue (cliType, out resolved))
				return true;
			resolved = null;
			return false;
		}
Example #24
0
		/// <summary>
		/// Resolves the Objective-C types by mapping the known .NET type information.
		/// </summary>
		/// <param name='type'>
		/// An NSObjectTypeInfo with the .NET type information filled in.
		/// </param>
		public void ResolveCliToObjc (NSObjectTypeInfo type)
		{
			NSObjectTypeInfo resolved;
			
			if (type.BaseObjCType == null && type.BaseCliType != null) {
				if (TryResolveCliToObjc (type.BaseCliType, out resolved)) {
					if (resolved.IsModel)
						type.BaseIsModel = true;
					type.BaseObjCType = resolved.ObjCName;
					//FIXME: handle type references better
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				} else {
					//managed classes many have implicitly registered base classes with a name not
					//expressible in obj-c. In this case, the best we can do is walk down the 
					//hierarchy until we find a valid base class
					var reference = ReflectionHelper.ParseReflectionName (type.BaseCliType);
					var baseCliType = reference.Resolve (dom.Compilation);
					foreach (var bt in baseCliType.GetAllBaseTypeDefinitions ()) {
						if (bt.Kind != TypeKind.Class) 
							continue;
						
						if (TryResolveCliToObjc (bt.ReflectionName, out resolved)) {
							if (resolved.IsModel)
								type.BaseIsModel = true;
							type.BaseObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
							break;
						}
					}
				}
			}
			
			foreach (var outlet in type.Outlets) {
				if (outlet.ObjCType != null)
					continue;
				
				if (TryResolveCliToObjc (outlet.CliType, out resolved)) {
					outlet.ObjCType = resolved.ObjCName;
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				}
			}
			
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.ObjCType != null)
						continue;
					
					if (TryResolveCliToObjc (param.CliType, out resolved)) {
						param.ObjCType = resolved.ObjCName;
						if (resolved.IsUserType)
							type.UserTypeReferences.Add (resolved.ObjCName);
					}
				}
			}
		}
Example #25
0
		void UpdateTypeMembers (TypeSystemService.ProjectContentWrapper dom, NSObjectTypeInfo info, ITypeDefinition type)
		{
			info.Actions.Clear ();
			info.Outlets.Clear ();
			foreach (var prop in type.Properties) {
				foreach (var att in prop.Attributes) {
					var attType = att.AttributeType;
					bool isIBOutlet = attType.Equals (Resolve (dom, iboutletAttType));
					if (!isIBOutlet) {
						if (!attType.Equals (Resolve (dom, connectAttType)))
							continue;
					}
					string name = null;
					var posArgs = att.PositionalArguments;
					if (posArgs.Count == 1)
						name = posArgs [0].ConstantValue as string;
					if (string.IsNullOrEmpty (name))
						name = prop.Name;
					
					// HACK: Work around bug #1586 in the least obtrusive way possible. Strip out any outlet
					// with the name 'view' on subclasses of MonoTouch.UIKit.UIViewController to avoid 
					// conflicts with the view property mapped there
					if (name == "view") {
						if (type.GetAllBaseTypeDefinitions ().Any (p => p.ReflectionName == "MonoTouch.UIKit.UIViewController"))
							continue;
					}
					
					var ol = new IBOutlet (name, prop.Name, null, prop.ReturnType.ReflectionName);
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (prop.Region.FileName))
						ol.IsDesigner = true;
					info.Outlets.Add (ol);
					break;
				}
			}
			
			foreach (var meth in type.Methods) {
				foreach (var att in meth.Attributes) {
					var attType = att.AttributeType;
					bool isIBAction = attType.Equals (Resolve (dom, ibactionAttType));
					if (!isIBAction) {
						if (!attType.Equals (Resolve (dom, exportAttType)))
							continue;
					}
					bool isDesigner = MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (
						meth.DeclaringTypeDefinition.Region.FileName);
					//only support Export from old designer files, user code must be IBAction
					if (!isDesigner && !isIBAction)
						continue;
					
					string[] name = null;
					var posArgs = att.PositionalArguments;
					if (posArgs.Count == 1 || posArgs.Count == 2) {
						var n = posArgs [0].ConstantValue as string;
						if (!string.IsNullOrEmpty (n))
							name = n.Split (colonChar);
					}
					var action = new IBAction (name != null ? name [0] : meth.Name, meth.Name);
					int i = 1;
					foreach (var param in meth.Parameters) {
						string label = name != null && i < name.Length ? name [i] : null;
						if (label != null && label.Length == 0)
							label = null;
						action.Parameters.Add (new IBActionParameter (label, param.Name, null, param.Type.ReflectionName));
					}
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (meth.Region.FileName))
						action.IsDesigner = true;
					info.Actions.Add (action);
					break;
				}
			}
		}
Example #26
0
		public ObjectiveCGenerationException (string message, NSObjectTypeInfo typeInfo) : base (message)
		{
			this.typeInfo = typeInfo;
		}
		void UpdateTypeMembers (ProjectDom dom, NSObjectTypeInfo info, IType type)
		{
			info.Actions.Clear ();
			info.Outlets.Clear ();
			
			foreach (var prop in type.Properties) {
				foreach (var att in prop.Attributes) {
					bool isIBOutlet = att.AttributeType.FullName == iboutletAttType.FullName;
					if (!isIBOutlet) {
						if (att.AttributeType.FullName != connectAttType.FullName)
							continue;
					}
					string name = null;
					if (att.PositionalArguments.Count == 1)
						name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
					if (string.IsNullOrEmpty (name))
						name = prop.Name;
					var ol = new IBOutlet (name, prop.Name, null, prop.ReturnType.FullName);
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (prop.DeclaringType.CompilationUnit.FileName))
						ol.IsDesigner = true;
					info.Outlets.Add (ol);
					break;
				}
			}
			
			foreach (var meth in type.Methods) {
				foreach (var att in meth.Attributes) {
					bool isIBAction = att.AttributeType.FullName == ibactionAttType.FullName;
					if (!isIBAction) {
						if (att.AttributeType.FullName != exportAttType.FullName)
							continue;
					}
					bool isDesigner =  MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (
						meth.DeclaringType.CompilationUnit.FileName);
					//only support Export from old designer files, user code must be IBAction
					if (!isDesigner && !isIBAction)
						continue;
					
					string[] name = null;
					if (att.PositionalArguments.Count == 1) {
						var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
						if (!string.IsNullOrEmpty (n))
							name = n.Split (colonChar);
					}
					var action = new IBAction (name != null? name [0] : meth.Name, meth.Name);
					int i = 1;
					foreach (var param in meth.Parameters) {
						string label = name != null && i < name.Length? name[i] : null;
						if (label != null && label.Length == 0)
							label = null;
						action.Parameters.Add (new IBActionParameter (label, param.Name, null, param.ReturnType.FullName));
					}
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (meth.DeclaringType.CompilationUnit.FileName))
						action.IsDesigner = true;
					info.Actions.Add (action);
					break;
				}
			}
		}
Example #28
0
		void UpdateUserType (NSObjectTypeInfo type)
		{
			if (userClasses.Add (type.ObjCName))
				xcodeProjectDirty = true;
			
			FilePath target = outputDir.Combine (type.ObjCName + ".h");
			if (File.Exists (target) && File.GetLastWriteTime (target) >= type.DefinedIn.Max (f => File.GetLastWriteTime (f)))
				return;
			
			if (!Directory.Exists (outputDir))
				Directory.CreateDirectory (outputDir);
			
			typeTracker.GenerateObjcType (type, outputDir);
		}
Example #29
0
		static NSObjectTypeInfo ConvertType (ProjectDom dom, IType type)
		{
			string objcName = null;
			bool isModel = false;
			foreach (var att in type.Attributes) {
				if (att.AttributeType.FullName == registerAttType.FullName) {
					//type registered with an explicit type name are up to the user to proide a valid name
					if (att.PositionalArguments.Count == 1)
						objcName = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
					//non-nested types in the root namespace have names accessible from obj-c
					else if (string.IsNullOrEmpty (type.Namespace) && type.Name.IndexOf ('.') < 0)
						objcName = type.Name;
				}
				if (att.AttributeType.FullName == modelAttType.FullName) {
					isModel = true;
				}
			}
			if (string.IsNullOrEmpty (objcName))
				return null;
			var info = new NSObjectTypeInfo (objcName, type.FullName, null, type.BaseType.FullName, isModel);
			info.IsUserType = type.SourceProject != null;
			
			if (info.IsUserType) {
				UpdateTypeMembers (dom, info, type);
				info.DefinedIn = type.Parts.Select (p => (string) p.CompilationUnit.FileName).ToArray ();
			}
			
			return info;
		}
        /// <summary>
        /// Resolves the Objective-C types by mapping the known .NET type information.
        /// </summary>
        /// <param name='type'>
        /// An NSObjectTypeInfo with the .NET type information filled in.
        /// </param>
        public void ResolveCliToObjc(NSObjectTypeInfo type)
        {
            NSObjectTypeInfo resolved;

            if (type.BaseObjCType == null && type.BaseCliType != null)
            {
                if (TryResolveCliToObjc(type.BaseCliType, out resolved))
                {
                    if (resolved.IsModel)
                    {
                        type.BaseIsModel = true;
                    }
                    type.BaseObjCType = resolved.ObjCName;
                    //FIXME: handle type references better
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
                else
                {
                    //managed classes many have implicitly registered base classes with a name not
                    //expressible in obj-c. In this case, the best we can do is walk down the
                    //hierarchy until we find a valid base class
                    var reference   = ReflectionHelper.ParseReflectionName(type.BaseCliType);
                    var baseCliType = reference.Resolve(dom.Compilation);
                    foreach (var bt in GetAllBaseClassDefinitions(baseCliType))
                    {
                        if (TryResolveCliToObjc(bt.ReflectionName, out resolved))
                        {
                            if (resolved.IsModel)
                            {
                                type.BaseIsModel = true;
                            }
                            type.BaseObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                            break;
                        }
                    }
                }
            }

            foreach (var outlet in type.Outlets)
            {
                if (outlet.ObjCType != null)
                {
                    continue;
                }

                if (TryResolveCliToObjc(outlet.CliType, out resolved))
                {
                    outlet.ObjCType = resolved.ObjCName;
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
            }

            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.ObjCType != null)
                    {
                        continue;
                    }

                    if (TryResolveCliToObjc(param.CliType, out resolved))
                    {
                        param.ObjCType = resolved.ObjCName;
                        if (resolved.IsUserType)
                        {
                            type.UserTypeReferences.Add(resolved.ObjCName);
                        }
                    }
                }
            }
        }
Example #31
0
		static void UpdateTypeMembers (ProjectDom dom, NSObjectTypeInfo info, IType type)
		{
			info.Actions.Clear ();
			info.Outlets.Clear ();
			
			foreach (var prop in type.Properties) {
				foreach (var att in prop.Attributes) {
					if (att.AttributeType.FullName != connectAttType.FullName)
						continue;
					string name = null;
					if (att.PositionalArguments.Count == 1)
						name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
					if (string.IsNullOrEmpty (name))
						name = prop.Name;
					info.Outlets.Add (new IBOutlet (name, prop.Name, null, prop.ReturnType.FullName));
					break;
				}
			}
			
			foreach (var meth in type.Methods) {
				foreach (var att in meth.Attributes) {
					if (att.AttributeType.FullName != exportAttType.FullName)
						continue;
					string[] name = null;
					if (att.PositionalArguments.Count == 1) {
						var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
						if (!string.IsNullOrEmpty (n))
							name = n.Split (colonChar);
					}
					var action = new IBAction (name != null? name [0] : meth.Name, meth.Name);
					info.Actions.Add (action);
					int i = 1;
					foreach (var param in meth.Parameters) {
						string label = name != null && i < name.Length? name[i] : null;
						if (label != null && label.Length == 0)
							label = null;
						action.Parameters.Add (new IBActionParameter (label, param.Name, null, param.ReturnType.FullName));
					}
					break;
				}
			}
		}
Example #32
0
		public XcodeSyncedType (NSObjectTypeInfo type, string[] frameworks)
		{
			Frameworks = frameworks;
			Type = type;
		}
Example #33
0
		public static NSObjectTypeInfo ParseHeader (string headerFile)
		{
			var text = System.IO.File.ReadAllText (headerFile);
			var matches = ibRegex.Matches (text);
			var type = new NSObjectTypeInfo (System.IO.Path.GetFileNameWithoutExtension (headerFile), null, null, null, false);
			foreach (Match match in matches) {
				var kind = match.Groups[1].Value;
				var def = match.Groups[2].Value;
				if (kind == "IBOutlet") {
					var split = def.Split (whitespaceChars, StringSplitOptions.RemoveEmptyEntries);
					if (split.Length != 2)
						continue;
					type.Outlets.Add (new IBOutlet (split[1].TrimStart ('*'), null, split[0].TrimEnd ('*'), null));
				} else {
					string[] split = def.Split (colonChar);
					var action = new IBAction (split[0].Trim (), null);
					string label = null;
					for (int i = 1; i < split.Length; i++) {
						var s = split[i].Split (splitActionParamsChars, StringSplitOptions.RemoveEmptyEntries);
						var par = new IBActionParameter (label, s[1], s[0], null);
						label = s.Length == 3? s[2] : null;
						action.Parameters.Add (par);
					}
					type.Actions.Add (action);
				}
			}
			return type;
		}
Example #34
0
 public ObjectiveCGenerationException(string message, NSObjectTypeInfo typeInfo) : base(message)
 {
     this.typeInfo = typeInfo;
 }
Example #35
0
        void ResolveTypes(ProjectDom dom, NSObjectTypeInfo type)
        {
            NSObjectTypeInfo resolved;

            if (type.BaseObjCType == null && type.BaseCliType != null)
            {
                if (cliTypes.TryGetValue(type.BaseCliType, out resolved))
                {
                    if (resolved.IsModel)
                    {
                        type.BaseIsModel = true;
                    }
                    type.BaseObjCType = resolved.ObjCName;
                    if (resolved.IsUserType)
                    {
                        type.UserTypeReferences.Add(resolved.ObjCName);
                    }
                }
                else
                {
                    //managed classes many have implicitly registered base classes with a name not
                    //expressible in obj-c. In this case, the best we can do is walk down the
                    //hierarchy until we find a valid base class
                    foreach (var bt in dom.GetInheritanceTree(dom.GetType(type.BaseCliType)))
                    {
                        if (cliTypes.TryGetValue(bt.FullName, out resolved))
                        {
                            if (resolved.IsModel)
                            {
                                type.BaseIsModel = true;
                            }
                            type.BaseObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                            break;
                        }
                    }
                    if (type.BaseObjCType == null)
                    {
                        Console.WriteLine("Could not resolve CLI type '{0}'", type.BaseCliType);
                    }
                }
            }

            if (type.BaseCliType == null && type.BaseObjCType != null)
            {
                if (objcTypes.TryGetValue(type.BaseObjCType, out resolved))
                {
                    type.BaseCliType = resolved.CliName;
                }
            }

            foreach (var outlet in type.Outlets)
            {
                if (outlet.ObjCType == null)
                {
                    if (cliTypes.TryGetValue(outlet.CliType, out resolved))
                    {
                        outlet.ObjCType = resolved.ObjCName;
                        if (resolved.IsUserType)
                        {
                            type.UserTypeReferences.Add(resolved.ObjCName);
                        }
                    }
                }
                if (outlet.CliType == null)
                {
                    if (objcTypes.TryGetValue(outlet.ObjCType, out resolved))
                    {
                        outlet.CliType = resolved.CliName;
                    }
                }
            }

            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.ObjCType == null)
                    {
                        if (cliTypes.TryGetValue(param.CliType, out resolved))
                        {
                            param.ObjCType = resolved.ObjCName;
                            if (resolved.IsUserType)
                            {
                                type.UserTypeReferences.Add(resolved.ObjCName);
                            }
                        }
                    }
                    if (param.CliType == null)
                    {
                        if (objcTypes.TryGetValue(param.ObjCType, out resolved))
                        {
                            param.CliType = resolved.CliName;
                        }
                    }
                }
            }
        }
Example #36
0
		/// <summary>
		/// Resolves the Objective-C types by mapping the known .NET type information.
		/// </summary>
		/// <param name='type'>
		/// An NSObjectTypeInfo with the .NET type information filled in.
		/// </param>
		public void ResolveCliToObjc (NSObjectTypeInfo type)
		{
			NSObjectTypeInfo resolved;
			
			if (type.BaseObjCType == null && type.BaseCliType != null) {
				if (TryResolveCliToObjc (type.BaseCliType, out resolved)) {
					if (resolved.IsModel)
						type.BaseIsModel = true;
					type.BaseObjCType = resolved.ObjCName;
					//FIXME: handle type references better
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				} else {
					// managed classes may have implicitly registered base classes with a name not
					// expressible in obj-c. In this case, the best we can do is walk down the 
					// hierarchy until we find a valid base class
					foreach (var bt in dom.GetInheritanceTree (dom.GetType (type.BaseCliType))) {
						if (bt.ClassType != ClassType.Class)
							continue;
						
						if (TryResolveCliToObjc (bt.FullName, out resolved)) {
							if (resolved.IsModel)
								type.BaseIsModel = true;
							type.BaseObjCType = resolved.ObjCName;
							if (resolved.IsUserType)
								type.UserTypeReferences.Add (resolved.ObjCName);
							break;
						}
					}
				}
			}
			
			foreach (var outlet in type.Outlets) {
				if (outlet.ObjCType != null)
					continue;
				
				if (TryResolveCliToObjc (outlet.CliType, out resolved)) {
					outlet.ObjCType = resolved.ObjCName;
					if (resolved.IsUserType)
						type.UserTypeReferences.Add (resolved.ObjCName);
				}
			}
			
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.ObjCType != null)
						continue;
					
					if (TryResolveCliToObjc (param.CliType, out resolved)) {
						param.ObjCType = resolved.ObjCName;
						if (resolved.IsUserType)
							type.UserTypeReferences.Add (resolved.ObjCName);
					}
				}
			}
		}
        public static NSObjectTypeInfo ParseHeader(string headerFile)
        {
            string           text = File.ReadAllText(headerFile);
            string           userType = null, userBaseType = null;
            MatchCollection  matches;
            NSObjectTypeInfo type;

            // First, grep for classes
            matches = typeInfoRegex.Matches(text);
            foreach (Match match in matches)
            {
                if (match.Groups[1].Value != "interface")
                {
                    continue;
                }

                if (userType != null)
                {
                    // UNSUPPORTED: more than 1 user-type defined in this header
                    return(null);
                }

                userType     = match.Groups[2].Value;
                userBaseType = match.Groups[3].Value;
            }

            if (userType == null)
            {
                return(null);
            }

            type = new NSObjectTypeInfo(userType, null, userBaseType, null, false, true, true);

            // Now grep for IBActions and IBOutlets
            matches = ibRegex.Matches(text);
            foreach (Match match in matches)
            {
                var kind = match.Groups[1].Value;
                var def  = match.Groups[2].Value;
                if (kind == "IBOutlet")
                {
                    var    split    = def.Split(whitespaceChars, StringSplitOptions.RemoveEmptyEntries);
                    string objcType = split[0].TrimEnd('*');
                    string objcName = null;

                    for (int i = 1; i < split.Length; i++)
                    {
                        objcName = split[i].TrimStart('*');
                        if (string.IsNullOrEmpty(objcName))
                        {
                            continue;
                        }

                        if (i + 1 < split.Length)
                        {
                            // This is a bad sign... what tokens are after the name??
                            objcName = null;
                            break;
                        }
                    }

                    if (string.IsNullOrEmpty(objcType) || string.IsNullOrEmpty(objcName))
                    {
                        MessageService.ShowError(GettextCatalog.GetString("Error while parsing header file."),
                                                 string.Format(GettextCatalog.GetString("The definition '{0}' can't be parsed."), def));

                        // We can't recover if objcName is empty...
                        if (string.IsNullOrEmpty(objcName))
                        {
                            continue;
                        }

                        // We can try using NSObject...
                        objcType = "NSObject";
                    }

                    if (objcType == "id")
                    {
                        objcType = "NSObject";
                    }

                    IBOutlet outlet = new IBOutlet(objcName, objcName, objcType, null);
                    outlet.IsDesigner = true;

                    type.Outlets.Add(outlet);
                }
                else
                {
                    string[] split  = def.Split(colonChar);
                    string   name   = split[0].Trim();
                    var      action = new IBAction(name, name);
                    action.IsDesigner = true;

                    string label = null;
                    for (int i = 1; i < split.Length; i++)
                    {
                        var    s        = split[i].Split(splitActionParamsChars, StringSplitOptions.RemoveEmptyEntries);
                        string objcType = s[0];
                        if (objcType == "id")
                        {
                            objcType = "NSObject";
                        }
                        var par = new IBActionParameter(label, s[1], objcType, null);
                        label = s.Length == 3? s[2] : null;
                        action.Parameters.Add(par);
                    }

                    type.Actions.Add(action);
                }
            }

            return(type);
        }
Example #38
0
		internal void InsertUpdatedType (NSObjectTypeInfo type)
		{
			objcTypes[type.ObjCName] = type;
			cliTypes[type.CliName] = type;
		}
		NSObjectTypeInfo ConvertType (ProjectDom dom, IType type)
		{
			string objcName = null;
			bool isModel = false;
			bool registeredInDesigner = true;
			
			foreach (var part in type.Parts) {
				foreach (var att in part.Attributes) {
					if (att.AttributeType.FullName == registerAttType.FullName) {
						if (type.SourceProject != null) {
							registeredInDesigner &=
								MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (part.CompilationUnit.FileName);
						}
						
						//type registered with an explicit type name are up to the user to provide a valid name
						// Note that the attribute now takes one *or* two parameters.
						if (att.PositionalArguments.Count == 1 || att.PositionalArguments.Count == 2)
							objcName = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
						//non-nested types in the root namespace have names accessible from obj-c
						else if (string.IsNullOrEmpty (type.Namespace) && type.Name.IndexOf ('.') < 0)
							objcName = type.Name;
					}
					
					if (att.AttributeType.FullName == modelAttType.FullName) {
						isModel = true;
					}
				}
			}
			
			if (string.IsNullOrEmpty (objcName))
				return null;
			
			var info = new NSObjectTypeInfo (objcName, type.FullName, null, type.BaseType.FullName, isModel,
				type.SourceProject != null, registeredInDesigner);
			
			if (info.IsUserType) {
				UpdateTypeMembers (dom, info, type);
				info.DefinedIn = type.Parts.Select (p => (string) p.CompilationUnit.FileName).ToArray ();
			}
			
			return info;
		}
Example #40
0
		bool TryResolveObjcToCli (string objcType, out NSObjectTypeInfo resolved)
		{
			if (objcTypes.TryGetValue (objcType, out resolved))
				return true;
			if (refObjcTypes.TryGetValue (objcType, out resolved))
				return true;
#if false
			var msg = new StringBuilder ("Can't resolve "+ objcType + Environment.NewLine);
			foreach (var r in dom.References) {
				msg.Append ("Referenced dom:");
				msg.Append (r);
				var rDom = infoService.GetProjectInfo (r);
				if (rDom == null) {
					msg.AppendLine ("projectinfo == null");
					continue;
				}
				msg.Append ("known types:");
				msg.AppendLine (string.Join (",", rDom.objcTypes.Keys.ToArray()));
			}
			LoggingService.LogWarning (msg.ToString ());
#endif
			resolved = null;
			return false;
		}
		public static NSObjectTypeInfo ParseHeader (string headerFile)
		{
			string text = File.ReadAllText (headerFile);
			string userType = null, userBaseType = null;
			MatchCollection matches;
			NSObjectTypeInfo type;
			
			// First, grep for classes
			matches = typeInfoRegex.Matches (text);
			foreach (Match match in matches) {
				if (match.Groups[1].Value != "interface")
					continue;
				
				if (userType != null) {
					// UNSUPPORTED: more than 1 user-type defined in this header
					return null;
				}
				
				userType = match.Groups[2].Value;
				userBaseType = match.Groups[3].Value;
			}
			
			if (userType == null)
				return null;
			
			type = new NSObjectTypeInfo (userType, null, userBaseType, null, false, true, true);
			
			// Now grep for IBActions and IBOutlets
			matches = ibRegex.Matches (text);
			foreach (Match match in matches) {
				var kind = match.Groups[1].Value;
				var def = match.Groups[2].Value;
				if (kind == "IBOutlet") {
					var split = def.Split (whitespaceChars, StringSplitOptions.RemoveEmptyEntries);
					if (split.Length != 2)
						continue;
					string objcName = split[1].TrimStart ('*');
					string objcType = split[0].TrimEnd ('*');
					if (objcType == "id")
						objcType = "NSObject";
					if (string.IsNullOrEmpty (objcType)) {
						MessageService.ShowError (GettextCatalog.GetString ("Error while parsing header file."),
							string.Format (GettextCatalog.GetString ("The definition '{0}' can't be parsed."), def));
						objcType = "NSObject";
					}
					
					IBOutlet outlet = new IBOutlet (objcName, objcName, objcType, null);
					outlet.IsDesigner = true;
					
					type.Outlets.Add (outlet);
				} else {
					string[] split = def.Split (colonChar);
					string name = split[0].Trim ();
					var action = new IBAction (name, name);
					action.IsDesigner = true;
					
					string label = null;
					for (int i = 1; i < split.Length; i++) {
						var s = split[i].Split (splitActionParamsChars, StringSplitOptions.RemoveEmptyEntries);
						string objcType = s[0];
						if (objcType == "id")
							objcType = "NSObject";
						var par = new IBActionParameter (label, s[1], objcType, null);
						label = s.Length == 3? s[2] : null;
						action.Parameters.Add (par);
					}
					
					type.Actions.Add (action);
				}
			}
			
			return type;
		}
Example #42
0
		/// <summary>
		/// Resolves the type by mapping the known Objective-C type information to .NET types.
		/// </summary>
		/// <returns>
		/// The number of unresolved types still remaining.
		/// </returns>
		/// <param name='type'>
		/// The NSObjectTypeInfo that contains the known Objective-C type information.
		/// Typically this will be the result of NSObjectInfoService.ParseHeader().
		/// </param>
		/// <param name='provider'>
		/// A CodeDom provider which is used to make sure type names don't conflict with language keywords.
		/// </param>
		/// <param name='defaultNamespace'>
		/// The default namespace used when forcing type resolution.
		/// </param>
		public void ResolveObjcToCli (IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace)
		{
			NSObjectTypeInfo resolved;
			
			// Resolve our base type
			if (type.BaseCliType == null) {
				if (TryResolveObjcToCli (type.BaseObjCType, out resolved)) {
					type.BaseCliType = resolved.CliName;
				} else {
					var reference = new GetClassTypeReference (defaultNamespace, provider.CreateValidIdentifier (type.BaseObjCType));
					type.BaseCliType = reference.Resolve (dom.Compilation).ReflectionName;

					var message = string.Format ("Failed to resolve Objective-C type '{0}' to a type in the current solution.", type.BaseObjCType);
					message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", type.BaseObjCType);
					monitor.ReportError (null, new UserException ("Error while syncing", message));
				}
			}
			
			// Resolve [Outlet] types
			foreach (var outlet in type.Outlets) {
				if (outlet.CliType != null)
					continue;
				
				if (TryResolveObjcToCli (outlet.ObjCType, out resolved)) {
					outlet.CliType = resolved.CliName;
				} else {
					outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (outlet.ObjCType);

					var message = string.Format ("Failed to resolve Objective-C outlet '{0}' of type '{1}' to a type in the current solution.", outlet.ObjCName, outlet.ObjCType);
					message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", outlet.ObjCType);
					monitor.ReportError (null, new UserException ("Error while syncing", message));
				}
			}
			
			// Resolve [Action] param types
			foreach (var action in type.Actions) {
				foreach (var param in action.Parameters) {
					if (param.CliType != null)
						continue;
					
					if (TryResolveObjcToCli (param.ObjCType, out resolved)) {
						param.CliType = resolved.CliName;
					} else {
						param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier (param.ObjCType);
	
						var message = string.Format ("Failed to resolve paramater '{0}' of type '{2}' on Objective-C action '{1}' to a type in the current solution.", param.Name, action.ObjCName, param.ObjCType);
						message += string.Format (" Adding a [Register (\"{0}\")] attribute to the class which corresponds to this will allow it to be synced to Objective-C.", param.ObjCType);
						monitor.ReportError (null, new UserException ("Error while syncing", message));
					}
				}
			}
		}
Example #43
0
		void UpdateUserType (NSObjectTypeInfo type)
		{
			if (userClasses.Add (type.ObjCName))
				xcodeProjectDirty = true;

			//FIXME: types dep on other types on project, need better regeneration skipping			
			//FilePath target = outputDir.Combine (type.ObjCName + ".h");
			//if (File.Exists (target) && File.GetLastWriteTime (target) >= type.DefinedIn.Max (f => File.GetLastWriteTime (f)))
			//	return;
			
			if (!Directory.Exists (outputDir))
				Directory.CreateDirectory (outputDir);
			
			type.GenerateObjcType (outputDir);
			
			string headerFlag = outputDir.Combine (type.ObjCName + ".h.modified");
			if (File.Exists (headerFlag))
				File.SetLastWriteTime (headerFlag, DateTime.Now);
			else
				File.WriteAllText (headerFlag, "");
		}
        void UpdateTypeMembers(TypeSystemService.ProjectContentWrapper dom, NSObjectTypeInfo info, ITypeDefinition type)
        {
            info.Actions.Clear();
            info.Outlets.Clear();
            foreach (var prop in type.Properties)
            {
                foreach (var att in prop.Attributes)
                {
                    var  attType    = att.AttributeType;
                    bool isIBOutlet = attType.Equals(Resolve(dom, iboutletAttType));
                    if (!isIBOutlet)
                    {
                        if (!attType.Equals(Resolve(dom, connectAttType)))
                        {
                            continue;
                        }
                    }
                    string name    = null;
                    var    posArgs = att.PositionalArguments;
                    if (posArgs.Count == 1)
                    {
                        name = posArgs [0].ConstantValue as string;
                    }
                    if (string.IsNullOrEmpty(name))
                    {
                        name = prop.Name;
                    }

                    // HACK: Work around bug #1586 in the least obtrusive way possible. Strip out any outlet
                    // with the name 'view' on subclasses of MonoTouch.UIKit.UIViewController to avoid
                    // conflicts with the view property mapped there
                    if (name == "view")
                    {
                        if (type.GetAllBaseTypeDefinitions().Any(p => p.ReflectionName == "MonoTouch.UIKit.UIViewController"))
                        {
                            continue;
                        }
                    }

                    var ol = new IBOutlet(name, prop.Name, null, prop.ReturnType.ReflectionName);
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(prop.Region.FileName))
                    {
                        ol.IsDesigner = true;
                    }
                    info.Outlets.Add(ol);
                    break;
                }
            }
            foreach (var meth in type.Methods)
            {
                foreach (var att in meth.Attributes)
                {
                    var  attType    = att.AttributeType;
                    bool isIBAction = attType.Equals(Resolve(dom, ibactionAttType));
                    if (!isIBAction)
                    {
                        if (!attType.Equals(Resolve(dom, exportAttType)))
                        {
                            continue;
                        }
                    }
                    bool isDesigner = MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(meth.Region.FileName);
                    //only support Export from old designer files, user code must be IBAction
                    if (!isDesigner && !isIBAction)
                    {
                        continue;
                    }

                    string[] name    = null;
                    var      posArgs = att.PositionalArguments;
                    if (posArgs.Count == 1 || posArgs.Count == 2)
                    {
                        var n = posArgs [0].ConstantValue as string;
                        if (!string.IsNullOrEmpty(n))
                        {
                            name = n.Split(colonChar);
                        }
                    }
                    var action = new IBAction(name != null ? name [0] : meth.Name, meth.Name);
                    int i      = 1;
                    foreach (var param in meth.Parameters)
                    {
                        string label = name != null && i < name.Length ? name [i] : null;
                        if (label != null && label.Length == 0)
                        {
                            label = null;
                        }
                        action.Parameters.Add(new IBActionParameter(label, param.Name, null, param.Type.ReflectionName));
                    }
                    if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile(meth.Region.FileName))
                    {
                        action.IsDesigner = true;
                    }
                    info.Actions.Add(action);
                    break;
                }
            }
        }
        /// <summary>
        /// Resolves the type by mapping the known Objective-C type information to .NET types.
        /// </summary>
        /// <returns>
        /// The number of unresolved types still remaining.
        /// </returns>
        /// <param name='type'>
        /// The NSObjectTypeInfo that contains the known Objective-C type information.
        /// Typically this will be the result of NSObjectInfoService.ParseHeader().
        /// </param>
        /// <param name='provider'>
        /// A CodeDom provider which is used to make sure type names don't conflict with language keywords.
        /// </param>
        /// <param name='defaultNamespace'>
        /// The default namespace used when forcing type resolution.
        /// </param>
        public void ResolveObjcToCli(IProgressMonitor monitor, NSObjectTypeInfo type, CodeDomProvider provider, string defaultNamespace)
        {
            NSObjectTypeInfo resolved;

            // Resolve our base type
            if (type.BaseCliType == null)
            {
                if (TryResolveObjcToCli(type.BaseObjCType, out resolved))
                {
                    type.BaseCliType = resolved.CliName;
                }
                else
                {
                    type.BaseCliType = defaultNamespace + "." + provider.CreateValidIdentifier(type.BaseObjCType);
                    monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on type {1}",
                                                        type.BaseObjCType, type.ObjCName));
                }
            }

            // Resolve [Outlet] types
            foreach (var outlet in type.Outlets)
            {
                if (outlet.CliType != null)
                {
                    continue;
                }

                if (TryResolveObjcToCli(outlet.ObjCType, out resolved))
                {
                    outlet.CliType = resolved.CliName;
                }
                else
                {
                    outlet.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(outlet.ObjCType);
                    monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on outlet {1} on type {2}",
                                                        outlet.ObjCType, outlet.ObjCName, type.ObjCName));
                }
            }

            // Resolve [Action] param types
            foreach (var action in type.Actions)
            {
                foreach (var param in action.Parameters)
                {
                    if (param.CliType != null)
                    {
                        continue;
                    }

                    if (TryResolveObjcToCli(param.ObjCType, out resolved))
                    {
                        param.CliType = resolved.CliName;
                    }
                    else
                    {
                        param.CliType = defaultNamespace + "." + provider.CreateValidIdentifier(param.ObjCType);
                        monitor.ReportWarning(string.Format("Failed to resolve Objective-C type {0} to CLI type on action parameter {1} for action {2} on type {3}",
                                                            param.ObjCType, param.Name, action.ObjCName, type.ObjCName));
                    }
                }
            }
        }
 public UserTypeChange(NSObjectTypeInfo type, UserTypeChangeKind kind)
 {
     this.Type = type;
     this.Kind = kind;
 }
		public static XcodeSyncObjcBackJob NewType (NSObjectTypeInfo type, string relativePath)
		{
			return new XcodeSyncObjcBackJob () {
				RelativePath = relativePath,
				IsFreshlyAdded = true,
				Type = type,
			};
		}
		void UpdateTypeMembers (ProjectDom dom, NSObjectTypeInfo info, IType type)
		{
			info.Actions.Clear ();
			info.Outlets.Clear ();
			
			foreach (var prop in type.Properties) {
				foreach (var att in prop.Attributes) {
					bool isIBOutlet = att.AttributeType.FullName == iboutletAttType.FullName;
					if (!isIBOutlet) {
						if (att.AttributeType.FullName != connectAttType.FullName)
							continue;
					}
					string name = null;
					if (att.PositionalArguments.Count == 1)
						name = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
					if (string.IsNullOrEmpty (name))
						name = prop.Name;
					
					// HACK: Work around bug #1586 in the least obtrusive way possible. Strip out any outlet
					// with the name 'view' on subclasses of MonoTouch.UIKit.UIViewController to avoid 
					// conflicts with the view property mapped there
					if (name == "view")
						if (dom.GetInheritanceTree (type).Any (p => p.FullName == "MonoTouch.UIKit.UIViewController"))
							continue;
					
					var ol = new IBOutlet (name, prop.Name, null, prop.ReturnType.FullName);
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (prop.DeclaringType.CompilationUnit.FileName))
						ol.IsDesigner = true;
					info.Outlets.Add (ol);
					break;
				}
			}
			
			foreach (var meth in type.Methods) {
				foreach (var att in meth.Attributes) {
					bool isIBAction = att.AttributeType.FullName == ibactionAttType.FullName;
					if (!isIBAction) {
						if (att.AttributeType.FullName != exportAttType.FullName)
							continue;
					}
					bool isDesigner =  MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (
						meth.DeclaringType.CompilationUnit.FileName);
					//only support Export from old designer files, user code must be IBAction
					if (!isDesigner && !isIBAction)
						continue;
					
					string[] name = null;
					if (att.PositionalArguments.Count == 1) {
						var n = (string)((System.CodeDom.CodePrimitiveExpression)att.PositionalArguments[0]).Value;
						if (!string.IsNullOrEmpty (n))
							name = n.Split (colonChar);
					}
					var action = new IBAction (name != null? name [0] : meth.Name, meth.Name);
					int i = 1;
					foreach (var param in meth.Parameters) {
						string label = name != null && i < name.Length? name[i] : null;
						if (label != null && label.Length == 0)
							label = null;
						action.Parameters.Add (new IBActionParameter (label, param.Name, null, param.ReturnType.FullName));
					}
					if (MonoDevelop.DesignerSupport.CodeBehind.IsDesignerFile (meth.DeclaringType.CompilationUnit.FileName))
						action.IsDesigner = true;
					info.Actions.Add (action);
					break;
				}
			}
		}
		public static XcodeSyncObjcBackJob UpdateType (NSObjectTypeInfo type, string designerFile)
		{
			return new XcodeSyncObjcBackJob () {
				DesignerFile = designerFile,
				Type = type,
			};
		}
		public UserTypeChange (NSObjectTypeInfo type, UserTypeChangeKind kind)
		{
			this.Type = type;
			this.Kind = kind;
		}
Example #51
0
		/// <summary>
		/// Merges CLI info from previous version of the type into the parsed objc-type.
		/// </summary>
		public void MergeCliInfo (NSObjectTypeInfo previousType)
		{
			CliName = previousType.CliName;
			DefinedIn = previousType.DefinedIn;
			IsModel = previousType.IsModel;
			BaseIsModel = previousType.BaseIsModel;
			IsUserType = previousType.IsUserType;
			IsRegisteredInDesigner = previousType.IsRegisteredInDesigner;
			
			var existingOutlets = new Dictionary<string,IBOutlet> ();
			foreach (var o in previousType.Outlets)
				existingOutlets[o.ObjCName] = o;
			
			var existingActions = new Dictionary<string,IBAction> ();
			foreach (var a in previousType.Actions)
				existingActions[a.ObjCName] = a;
			
			foreach (var a in Actions) {
				IBAction existing;
				if (existingActions.TryGetValue (a.ObjCName, out existing)) {
					a.IsDesigner = existing.IsDesigner;
					a.CliName = existing.CliName;
				}
			}
			
			foreach (var o in Outlets) {
				IBOutlet existing;
				if (existingOutlets.TryGetValue (o.ObjCName, out existing)) {
					o.IsDesigner = existing.IsDesigner;
					o.CliName = existing.CliName;
				}
			}
		}