/// <summary> /// Creates a property declaration for buddy class. /// </summary> /// <param name="codeGenContext">Gode generation context.</param> /// <param name="buddyClass"><see cref="CodeTypeDeclaration"/> for a buddy class.</param> /// <param name="propertyInfo"><see cref="PropertyInfo"/> for the original property.</param> /// <param name="insideNamespace">Whether or not our buddy class is inside a namespace.</param> /// <returns>A code snippet for a buddy property.</returns> public static CodeSnippetTypeMember CreateAutomaticPropertyDeclaration(CodeGenContext codeGenContext, CodeTypeDeclaration buddyClass, PropertyInfo propertyInfo, bool insideNamespace) { // Create a field declaration: public static $propertyType$ $propertyName; CodeTypeReference propTypeRef = CodeGenUtilities.GetTypeReference(propertyInfo.PropertyType, codeGenContext, buddyClass); CodeMemberField field = new CodeMemberField(propTypeRef, propertyInfo.Name); field.Attributes = MemberAttributes.Public; CodeSnippetTypeMember property = null; CodeGeneratorOptions codeGeneratorOptions = codeGenContext.CodeGeneratorOptions; using (StringWriter stringWriter = new StringWriter(System.Globalization.CultureInfo.InvariantCulture)) { // create a StringBuilder with correct identation (we expect identation to stay constant) string indentString = codeGeneratorOptions.IndentString; StringBuilder stringBuilder = new StringBuilder(indentString); stringBuilder.Append(indentString); // If we're inside an namespace increase indent (in VB there's usually no explicit namespace) if (insideNamespace) { stringBuilder.Append(indentString); } // generate the code for a field codeGenContext.Provider.GenerateCodeFromMember(field, stringWriter, codeGenContext.CodeGeneratorOptions); stringBuilder.Append(stringWriter.GetStringBuilder()); stringBuilder.Replace(Environment.NewLine, String.Empty); // do a manual replace to transform a field into a property if (codeGenContext.IsCSharp) { stringBuilder.Replace(";", " { get; set; }"); } else { // typical VB code gen looks like: Public MyName As Integer // insert 'Property' between 'Public' and 'MyName' int propertyTokenPosition = stringBuilder.ToString().IndexOf("Public", StringComparison.Ordinal) + "Public".Length; stringBuilder.Insert(propertyTokenPosition, " Property"); } // create a code snippet out of resulting code property = new CodeSnippetTypeMember(stringBuilder.ToString()); } return(property); }
/// <summary> /// Gets a <see cref="CodeTypeReference"/> for a CLR type. /// </summary> /// <param name="type">A CLR type.</param> /// <param name="codegenContext">A <see cref="ClientProxyGenerator"/>.</param> /// <param name="referencingType">The referencing type.</param> /// <returns>A <see cref="CodeTypeReference"/> for a CLR type.</returns> public static CodeTypeReference GetTypeReference(Type type, CodeGenContext codegenContext, CodeTypeDeclaration referencingType) { if (type.IsPrimitive || type == typeof(void) || type == typeof(decimal) || type == typeof(string) || type == typeof(object)) { return(new CodeTypeReference(type)); } if (codegenContext != null && referencingType != null) { CodeNamespace ns = codegenContext.GetNamespace(referencingType); if (ns != null && !ns.Name.Equals(type.Namespace)) { // If the namespace is already imported, the following line will be a no-op. ns.Imports.Add(new CodeNamespaceImport(type.Namespace)); } } if (type.IsArray) { return(new CodeTypeReference( CodeGenUtilities.GetTypeReference(type.GetElementType(), codegenContext, referencingType), type.GetArrayRank())); } if (type.IsGenericType) { Type[] genericArguments = type.GetGenericArguments(); CodeTypeReference[] typeArguments = new CodeTypeReference[genericArguments.Length]; for (int i = 0; i < genericArguments.Length; i++) { typeArguments[i] = GetTypeReference(genericArguments[i]); } return(new CodeTypeReference(type.Name, typeArguments)); } return(new CodeTypeReference(type.Name)); }