internal static MemberInfo[] GetInstanceFieldsAndProperties(Type type, bool publicOnly) { #if WINRT System.Collections.Generic.List<MemberInfo> members = new System.Collections.Generic.List<MemberInfo>(); foreach(FieldInfo field in type.GetRuntimeFields()) { if(field.IsStatic) continue; if(field.IsPublic || !publicOnly) members.Add(field); } foreach(PropertyInfo prop in type.GetRuntimeProperties()) { MethodInfo getter = Helpers.GetGetMethod(prop, true, true); if(getter == null || getter.IsStatic) continue; if(getter.IsPublic || !publicOnly) members.Add(prop); } return members.ToArray(); #else BindingFlags flags = publicOnly ? BindingFlags.Public | BindingFlags.Instance : BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; PropertyInfo[] props = type.GetProperties(flags); FieldInfo[] fields = type.GetFields(flags); MemberInfo[] members = new MemberInfo[fields.Length + props.Length]; props.CopyTo(members, 0); fields.CopyTo(members, props.Length); return members; #endif }
protected IEnumerable <PropertyInfo> GetProperties(Type t) { foreach (var pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly)) { var pt = pi.PropertyType; if (!IsSupported(pt)) { Delayed.Add(ErrorHelper.CreateWarning(1040, $"Property `{pi}` is not generated because of parameter type `{pt}` is not supported.")); continue; } yield return(pi); } }
public void GenerateFilter(Type type) { var is_abstract = AttributeManager.HasAttribute <AbstractAttribute> (type); var filter = AttributeManager.GetCustomAttribute <CoreImageFilterAttribute> (type); var base_type = AttributeManager.GetCustomAttribute <BaseTypeAttribute> (type); var type_name = type.Name; var native_name = base_type.Name ?? type_name; var base_name = base_type.BaseType.Name; // internal static CIFilter FromName (string filterName, IntPtr handle) filters.Add(type_name); // type declaration print("public{0} partial class {1} : {2} {{", is_abstract ? " abstract" : String.Empty, type_name, base_name); print(""); indent++; // default constructor - if type is not abstract string v; if (!is_abstract) { v = GetVisibility(filter.DefaultCtorVisibility); if (v.Length > 0) { print_generated_code(); print("{0}{1} () : base (\"{2}\")", v, type.Name, native_name); PrintEmptyBody(); } } // IntPtr constructor - always present var intptrctor_visibility = filter.IntPtrCtorVisibility; if (intptrctor_visibility == MethodAttributes.PrivateScope) { // since it was not generated code we never fixed the .ctor(IntPtr) visibility for unified if (Generator.XamcoreVersion >= 3) { intptrctor_visibility = MethodAttributes.FamORAssem; } else { intptrctor_visibility = MethodAttributes.Public; } } print_generated_code(); print("{0}{1} (IntPtr handle) : base (handle)", GetVisibility(intptrctor_visibility), type_name); PrintEmptyBody(); // NSObjectFlag constructor - always present (needed to implement NSCoder for subclasses) print_generated_code(); print("[EditorBrowsable (EditorBrowsableState.Advanced)]"); print("protected {0} (NSObjectFlag t) : base (t)", type_name); PrintEmptyBody(); // NSCoder constructor - all filters conforms to NSCoding print_generated_code(); print("[EditorBrowsable (EditorBrowsableState.Advanced)]"); print("[Export (\"initWithCoder:\")]"); print("public {0} (NSCoder coder) : base (NSObjectFlag.Empty)", type_name); print("{"); indent++; print("IntPtr h;"); print("if (IsDirectBinding) {"); indent++; print("h = global::{0}.Messaging.IntPtr_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime); indent--; print("} else {"); indent++; print("h = global::{0}.Messaging.IntPtr_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle (\"initWithCoder:\"), coder.Handle);", ns.CoreObjCRuntime); indent--; print("}"); print("InitializeHandle (h, \"initWithCoder:\");"); indent--; print("}"); print(""); // string constructor // default is protected (for abstract) but backward compatibility (XAMCORE_2_0) requires some hacks v = GetVisibility(filter.StringCtorVisibility); if (is_abstract && (v.Length == 0)) { v = "protected "; } if (v.Length > 0) { print_generated_code(); print("{0} {1} (string name) : base (CreateFilter (name))", v, type_name); PrintEmptyBody(); } // properties foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (p.IsUnavailable()) { continue; } print(""); print_generated_code(); var ptype = p.PropertyType.Name; // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac) switch (ptype) { case "Boolean": ptype = "bool"; break; case "Int32": ptype = "int"; break; case "Single": ptype = "float"; break; case "String": ptype = "string"; break; } print("public {0} {1} {{", ptype, p.Name); indent++; var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name; if (p.GetGetMethod() != null) { GenerateFilterGetter(ptype, name); } if (p.GetSetMethod() != null) { GenerateFilterSetter(ptype, name); } indent--; print("}"); } indent--; print("}"); // namespace closing (it's optional to use namespaces even if it's a bad practice, ref #35283) if (indent > 0) { indent--; print("}"); } }
public void OutlineType() { bool first; OutlineAttributes(); o.Write(GetTypeVisibility(t)); if (t.IsClass && !t.IsSubclassOf(type_multicast_delegate)) { if (t.IsSealed) { o.Write(t.IsAbstract ? " static" : " sealed"); } else if (t.IsAbstract) { o.Write(" abstract"); } } o.Write(" "); o.Write(GetTypeKind(t)); o.Write(" "); Type [] interfaces = (Type [])Comparer.Sort(TypeGetInterfaces(t, declared_only)); Type parent = t.BaseType; if (t.IsSubclassOf(type_multicast_delegate)) { MethodInfo method; method = t.GetMethod("Invoke"); o.Write(FormatType(method.ReturnType)); o.Write(" "); o.Write(GetTypeName(t)); o.Write(" ("); OutlineParams(method.GetParameters()); o.Write(")"); WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(";"); return; } o.Write(GetTypeName(t)); if (((parent != null && parent != type_object && parent != type_value_type) || interfaces.Length != 0) && !t.IsEnum) { first = true; o.Write(" : "); if (parent != null && parent != type_object && parent != type_value_type) { o.Write(FormatType(parent)); first = false; } foreach (Type intf in interfaces) { if (!first) { o.Write(", "); } first = false; o.Write(FormatType(intf)); } } if (t.IsEnum) { Type underlyingType = t.GetEnumUnderlyingType(); if (underlyingType != type_int) { o.Write(" : {0}", FormatType(underlyingType)); } } WriteGenericConstraints(t.GetGenericArguments()); o.WriteLine(" {"); o.Indent++; if (t.IsEnum) { bool is_first = true; foreach (FieldInfo fi in t.GetFields(BindingFlags.Public | BindingFlags.Static)) { if (!is_first) { o.WriteLine(","); } is_first = false; o.Write(fi.Name); } o.WriteLine(); o.Indent--; o.WriteLine("}"); return; } first = true; foreach (ConstructorInfo ci in t.GetConstructors(DefaultFlags)) { if (!ShowMember(ci)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ci); OutlineConstructor(ci); o.WriteLine(); } first = true; foreach (MethodInfo m in Comparer.Sort(t.GetMethods(DefaultFlags))) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) != 0) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineMethod(m); o.WriteLine(); } first = true; foreach (MethodInfo m in t.GetMethods(DefaultFlags)) { if (!ShowMember(m)) { continue; } if ((m.Attributes & MethodAttributes.SpecialName) == 0) { continue; } if (!(m.Name.StartsWith("op_"))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(m); OutlineOperator(m); o.WriteLine(); } first = true; foreach (PropertyInfo pi in Comparer.Sort(t.GetProperties(DefaultFlags))) { if (!((pi.CanRead && ShowMember(pi.GetGetMethod(true))) || (pi.CanWrite && ShowMember(pi.GetSetMethod(true))))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(pi); OutlineProperty(pi); o.WriteLine(); } first = true; foreach (FieldInfo fi in t.GetFields(DefaultFlags)) { if (!ShowMember(fi)) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(fi); OutlineField(fi); o.WriteLine(); } first = true; foreach (EventInfo ei in Comparer.Sort(t.GetEvents(DefaultFlags))) { if (!ShowMember(ei.GetAddMethod(true))) { continue; } if (first) { o.WriteLine(); } first = false; OutlineMemberAttribute(ei); OutlineEvent(ei); o.WriteLine(); } first = true; foreach (Type ntype in Comparer.Sort(t.GetNestedTypes(DefaultFlags))) { if (!ShowMember(ntype)) { continue; } if (first) { o.WriteLine(); } first = false; #if STATIC new Outline(universe, mscorlib, ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #else new Outline(ntype, o, declared_only, show_private, filter_obsolete).OutlineType(); #endif } o.Indent--; o.WriteLine("}"); }
void GenerateProperties(Type type) { foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (p.IsUnavailable(this)) { continue; } if (AttributeManager.HasAttribute <StaticAttribute> (p)) { continue; } print(""); PrintPropertyAttributes(p); print_generated_code(); var ptype = p.PropertyType.Name; // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac) switch (ptype) { case "Boolean": ptype = "bool"; break; case "Int32": ptype = "int"; break; case "Single": ptype = "float"; break; case "String": ptype = "string"; break; // adding `using ImageIO;` would lead to `error CS0104: 'CGImageProperties' is an ambiguous reference between 'CoreGraphics.CGImageProperties' and 'ImageIO.CGImageProperties'` case "CGImageMetadata": ptype = "ImageIO.CGImageMetadata"; break; } print("public {0} {1} {{", ptype, p.Name); indent++; // an export will be present (only) if it's defined in a protocol var export = AttributeManager.GetCustomAttribute <ExportAttribute> (p); var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name; // we can skip the name when it's identical to a protocol selector if (name == null) { if (export == null) { throw new BindingException(1072, true, $"Missing [CoreImageFilterProperty] attribute on {0} property {1}", type.Name, p.Name); } var sel = export.Selector; if (sel.StartsWith("input", StringComparison.Ordinal)) { name = sel; } else { name = "input" + Capitalize(sel); } } if (p.GetGetMethod() != null) { PrintFilterExport(p, export, setter: false); GenerateFilterGetter(ptype, name); } if (p.GetSetMethod() != null) { PrintFilterExport(p, export, setter: true); GenerateFilterSetter(ptype, name); } indent--; print("}"); } }
internal static Type GetListItemType(TypeModel model, Type listType) { Helpers.DebugAssert(listType != null); #if WINRT TypeInfo listTypeInfo = listType.GetTypeInfo(); if (listType == typeof(string) || listType.IsArray || !typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(listTypeInfo)) { return(null); } #else if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } #endif BasicList candidates = new BasicList(); #if WINRT foreach (MethodInfo method in listType.GetRuntimeMethods()) #else foreach (MethodInfo method in listType.GetMethods()) #endif { if (method.IsStatic || method.Name != "Add") { continue; } ParameterInfo[] parameters = method.GetParameters(); Type paramType; if (parameters.Length == 1 && !candidates.Contains(paramType = parameters[0].ParameterType)) { candidates.Add(paramType); } } string name = listType.Name; bool isQueueStack = name != null && (name.IndexOf("Queue", System.StringComparison.Ordinal) >= 0 || name.IndexOf("Stack", System.StringComparison.Ordinal) >= 0); #if !NO_GENERICS if (!isQueueStack) { TestEnumerableListPatterns(model, candidates, listType); #if WINRT foreach (Type iType in listTypeInfo.ImplementedInterfaces) { TestEnumerableListPatterns(model, candidates, iType); } #else foreach (Type iType in listType.GetInterfaces()) { TestEnumerableListPatterns(model, candidates, iType); } #endif } #endif #if WINRT // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetRuntimeProperties()) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != typeof(int)) { continue; } MethodInfo getter = indexer.GetMethod; if (getter == null || getter.IsStatic) { continue; } candidates.Add(indexer.PropertyType); } #else // more convenient GetProperty overload not supported on all platforms foreach (PropertyInfo indexer in listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (indexer.Name != "Item" || candidates.Contains(indexer.PropertyType)) { continue; } ParameterInfo[] args = indexer.GetIndexParameters(); if (args.Length != 1 || args[0].ParameterType != model.MapType(typeof(int))) { continue; } candidates.Add(indexer.PropertyType); } #endif switch (candidates.Count) { case 0: return(null); case 1: return((Type)candidates[0]); case 2: if (CheckDictionaryAccessors(model, (Type)candidates[0], (Type)candidates[1])) { return((Type)candidates[0]); } if (CheckDictionaryAccessors(model, (Type)candidates[1], (Type)candidates[0])) { return((Type)candidates[1]); } break; } return(null); }
void GenerateProperties(Type type, Type originalType = null, bool fromProtocol = false) { foreach (var p in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (p.IsUnavailable(this)) { continue; } if (AttributeManager.HasAttribute <StaticAttribute> (p)) { continue; } print(""); // an export will be present (only) if it's defined in a protocol var export = AttributeManager.GetCustomAttribute <ExportAttribute> (p); // this is a bit special since CoreImage filter protocols are much newer than the our generated, key-based bindings // so we do not want to advertise the protocol versions since most properties would be incorrectly advertised PrintPropertyAttributes(p, originalType, skipTypeInjection: export != null); print_generated_code(); var ptype = p.PropertyType.Name; var nullable = false; // keep C# names as they are reserved keywords (e.g. Boolean also exists in OpenGL for Mac) switch (ptype) { case "Boolean": ptype = "bool"; break; case "Int32": ptype = "int"; break; case "Single": ptype = "float"; break; case "String": ptype = "string"; break; // adding `using ImageIO;` would lead to `error CS0104: 'CGImageProperties' is an ambiguous reference between 'CoreGraphics.CGImageProperties' and 'ImageIO.CGImageProperties'` case "CGImageMetadata": ptype = "ImageIO.CGImageMetadata"; break; case "CIVector": case "CIColor": case "CIImage": // protocol-based bindings have annotations - but the older, key-based, versions did not if (!fromProtocol) { nullable = true; } break; } if (AttributeManager.HasAttribute <NullAllowedAttribute> (p)) { nullable = true; } print("public {0}{1} {2} {{", ptype, nullable ? "?" : "", p.Name); indent++; var name = AttributeManager.GetCustomAttribute <CoreImageFilterPropertyAttribute> (p)?.Name; // we can skip the name when it's identical to a protocol selector if (name == null) { if (export == null) { throw new BindingException(1074, true, type.Name, p.Name); } var sel = export.Selector; if (sel.StartsWith("input", StringComparison.Ordinal)) { name = sel; } else { name = "input" + Capitalize(sel); } } if (p.GetGetMethod() != null) { PrintFilterExport(p, export, setter: false); GenerateFilterGetter(ptype, name); } if (p.GetSetMethod() != null) { PrintFilterExport(p, export, setter: true); GenerateFilterSetter(ptype, name); } indent--; print("}"); } }
protected override void Generate(Type t) { var managed_name = t.Name; implementation.WriteLine($"static void __lookup_class_{managed_name} ()"); implementation.WriteLine("{"); implementation.WriteLine($"\tif (!{managed_name}_class) {{"); implementation.WriteLine("\t\t__initialize_mono ();"); implementation.WriteLine("\t\t__lookup_assembly_managed ();"); implementation.WriteLine($"\t\t{managed_name}_class = mono_class_from_name (__{t.Assembly.GetName ().Name}_image, \"{t.Namespace}\", \"{managed_name}\");"); implementation.WriteLine("\t}"); implementation.WriteLine("}"); implementation.WriteLine(); var native_name = GetTypeName(t); headers.WriteLine(); headers.WriteLine($"// {t.AssemblyQualifiedName}"); headers.WriteLine($"@interface {native_name} : {GetTypeName (t.BaseType)} {{"); headers.WriteLine("\tMonoEmbedObject* _object;"); headers.WriteLine("}"); headers.WriteLine(); implementation.WriteLine(); implementation.WriteLine($"// {t.AssemblyQualifiedName}"); implementation.WriteLine($"@implementation {native_name}"); implementation.WriteLine(); var default_init = false; List <ConstructorInfo> constructors; if (ctors.TryGetValue(t, out constructors)) { foreach (var ctor in constructors) { var pcount = ctor.ParameterCount; default_init |= pcount == 0; var parameters = ctor.GetParameters(); StringBuilder name = new StringBuilder("init"); foreach (var p in parameters) { if (name.Length == 4) { name.Append("With"); } else { name.Append(' '); } name.Append(PascalCase(p.Name)); name.Append(":(").Append(GetTypeName(p.ParameterType)).Append(") ").Append(p.Name); } var signature = new StringBuilder(".ctor("); foreach (var p in parameters) { if (signature.Length > 6) { signature.Append(','); } signature.Append(GetMonoName(p.ParameterType)); } signature.Append(")"); headers.WriteLine($"- (instancetype){name};"); implementation.WriteLine($"- (instancetype){name}"); implementation.WriteLine("{"); implementation.WriteLine($"\tconst char __method_name [] = \"{t.FullName}:{signature}\";"); implementation.WriteLine("\tstatic MonoMethod* __method = nil;"); implementation.WriteLine("\tif (!__method) {"); implementation.WriteLine($"\t\t__lookup_class_{managed_name} ();"); implementation.WriteLine($"\t\t__method = mono_embeddinator_lookup_method (__method_name, {managed_name}_class);"); implementation.WriteLine("\t}"); // TODO: this logic will need to be update for managed NSObject types (e.g. from XI / XM) not to call [super init] implementation.WriteLine("\tif (self = [super init]) {"); implementation.WriteLine($"\t\tMonoObject* __instance = mono_object_new (__mono_context.domain, {managed_name}_class);"); implementation.WriteLine("\t\tMonoObject* __exception = nil;"); var args = "nil"; if (pcount > 0) { implementation.WriteLine($"\t\tvoid* __args [{pcount}];"); for (int i = 0; i < pcount; i++) { var p = parameters [i]; switch (Type.GetTypeCode(p.ParameterType)) { case TypeCode.String: implementation.WriteLine($"\t\t__args [{i}] = mono_string_new (__mono_context.domain, [{p.Name} UTF8String]);"); break; case TypeCode.Boolean: case TypeCode.Char: case TypeCode.SByte: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Byte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Single: case TypeCode.Double: implementation.WriteLine($"\t\t__args [{i}] = &{p.Name};"); break; default: throw new NotImplementedException($"Converting type {p.ParameterType.FullName} to mono code"); } } args = "__args"; } implementation.WriteLine($"\t\tmono_runtime_invoke (__method, __instance, {args}, &__exception);"); implementation.WriteLine("\t\tif (__exception)"); // TODO: Apple often do NSLog (or asserts but they are more brutal) and returning nil is allowed (and common) implementation.WriteLine("\t\t\treturn nil;"); //implementation.WriteLine ("\t\t\tmono_embeddinator_throw_exception (__exception);"); implementation.WriteLine("\t\t_object = mono_embeddinator_create_object (__instance);"); implementation.WriteLine("\t\t_object->_handle = mono_gchandle_new (__instance, /*pinned=*/false);"); implementation.WriteLine("\t}"); implementation.WriteLine("\treturn self;"); implementation.WriteLine("}"); implementation.WriteLine(); } } var static_type = t.IsSealed && t.IsAbstract; if (!default_init || static_type) { if (static_type) { headers.WriteLine("// a .net static type cannot be initialized"); } headers.WriteLine("- (instancetype)init NS_UNAVAILABLE;"); } headers.WriteLine(); foreach (var pi in t.GetProperties()) { Generate(pi); } headers.WriteLine("@end"); headers.WriteLine(); implementation.WriteLine("@end"); implementation.WriteLine(); }
void GenerateCode(Type type) { if (type.IsGenericType && !type.IsGenericTypeDefinition) return; // generate nothing. var implprops = new List<PropertyInfo> (); var miscprops = new List<PropertyInfo> (); foreach (var p in type.GetProperties (BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { if (targets.Contains (p.PropertyType) && !p.PropertyType.IsEnum) implprops.Add (p); else miscprops.Add (p); } output.WriteLine ("// generic ordinal type for " + type); string template = @" public {10}partial class {0} : {1} {2} {{ {7} impl; // constructor, if not abstract. {9} // impl-to-wrapper constructor internal protected {8} ({7} impl) {6} {{ this.impl = impl; {11} Initialize (); }} // initializer void Initialize () {{ // repeat for all auto (new-Android-type) properties {3} }} // explicit conversion operator public static explicit operator {7} ({0} source) {{ return source.impl; }} // For a property whose type is wrapper for Android type, just make it auto property (use private set for get-only ones) {4} // Non-Android properties follow. {5} }} "; var actx = android_ass.GetType ("Android.Content.Context"); var aaset = android_ass.GetType ("Android.Util.IAttributeSet"); // somehow GetConstructor() returns weird results, so this workarounds that. string args = type.GetConstructors ().Any (c => c.GetParameters ().Length == 1 && c.GetParameters () [0].ParameterType.FullName == actx.FullName) ? "XamlView.CurrentContext" : type.GetConstructors ().Any (c => c.GetParameters ().Length == 2 && c.GetParameters () [0].ParameterType.FullName == actx.FullName && c.GetParameters () [1].ParameterType.FullName == aaset.FullName) ? "XamlView.CurrentContext, null" : ""; //if (type.Name == "SlidingDrawer") foreach (var ccc in type.GetConstructors ()) Console.WriteLine ("!!!! " + ccc + " / " + type.GetConstructor (new Type [] {actx}).GetParameters ().Length); string publicConstructor = type.IsAbstract ? String.Empty : String.Format (@" public {0} () : this (new {1} ({2})) {{ }}", type.NonGenericName (), type.CSFullName (), args); string templateInit = @" if (impl.{0} != null) {0} = Extensions.GetWrappedItem<{1}> (impl.{0});"; var isw = new StringWriter () { NewLine = "\n" }; foreach (var p in implprops) if (!p.IsAbstract ()) isw.WriteLine (templateInit, p.Name, p.PropertyType.CSName ()); string templateImplProp = @" public {3}{0} {1} {{ get; {2}set; }}"; var dpsw = new StringWriter () { NewLine = "\n" }; foreach (var p in implprops) dpsw.WriteLine (templateImplProp, p.PropertyType.CSSwitchName (), p.Name, p.IsSetterPublic () ? null : "internal ", GetModifier (p)); string templateOrdProp1 = @" public {3}{0} {1} {{ get {{ return {4}; }} {2} }}"; string templateOrdProp2 = @" public {3}{0} {1} {{ get; {5} }}"; var nsw = new StringWriter () { NewLine = "\n" }; foreach (var p in miscprops) { var setter = String.Format ("set {{ impl.{0} = value; }}", p.Name); nsw.WriteLine (p.IsAbstract () ? templateOrdProp2 : templateOrdProp1, p.PropertyType.CSSwitchName (), p.Name, p.IsSetterPublic () ? setter : null, GetModifier (p), GetValueExpression (p), p.IsSetterPublic () ? "set;" : null); } string gconsts = null; foreach (var arg in type.GetGenericArguments ()) { var gca = String.Join (",", (from t in arg.GetGenericParameterConstraints () select t.CSSwitchName ()).ToArray ()); gconsts += String.IsNullOrEmpty (gca) ? null : "where " + arg.Name + " : " + gca; } // FIXME: write custom attributes bool callBase = targets.Contains (type.BaseType); output.WriteLine (template, type.CSName (), type.BaseType.CSSwitchName (), gconsts, isw, dpsw, nsw, callBase ? " : base (impl)" : null, type.CSFullName (), type.NonGenericName (), publicConstructor, type.IsAbstract ? "abstract " : null, callBase ? null : "XamlView.Register (impl, this);"); }