protected virtual CodeTypeDeclaration GenerateClass(CodeNamespace @namespace) { var generator = typeof(ResourceTypeBuilder); var version = generator.Assembly.GetName( ).Version; var type = Declare.Class(settings.ClassName) .Modifiers(settings.AccessModifiers) .IsPartial(CodeDomProvider.Supports(GeneratorSupport.PartialTypes)) .AddSummary(ClassSummary) .AddTo(@namespace); if (settings.CustomToolType != null) { type.AddRemarks(ClassRemarksFormat, generator.FullName, settings.CustomToolType.Name); } else { type.AddRemarks(ClassRemarksToollessFormat, generator.FullName); } if (string.Equals(@namespace.Name.Split('.').Last( ), settings.ClassName, StringComparison.OrdinalIgnoreCase)) { type.Attributed(Declare.Attribute <SuppressMessageAttribute> ("Microsoft.Naming", "CA1724:TypeNamesShouldNotMatchNamespaces")); } return(type.Attributed(Declare.Attribute <GeneratedCodeAttribute> (generator.FullName, version.ToString( )), Declare.Attribute <DebuggerNonUserCodeAttribute> ( ), Declare.Attribute <ObfuscationAttribute> ( ) .WithArgument(nameof(ObfuscationAttribute.Exclude), true) .WithArgument(nameof(ObfuscationAttribute.ApplyToMembers), true))); }
static void AddToStringHelper(CodeTypeDeclaration type, CodeDomProvider provider) { var helperClass = Declare.Class("ToStringInstanceHelper") .AsNestedPublic() .WithReference(out var helperClassType); helperClass.AddField <IFormatProvider> ("formatProvider", TypeReference <System.Globalization.CultureInfo> .Global.Property("InvariantCulture")) .WithReference(out var formatProvider); helperClass.AddProperty <IFormatProvider> ("FormatProvider") .WithGet(formatProvider) .WithSetIgnoresNull(formatProvider); helperClass.AddMethod("ToStringWithCulture") .Returns <string> () .WithParameter <object> ("objectToConvert", out var objectToConvert) .WithStatements( objectToConvert.ThrowIfNull(), Declare.Variable <Type> ("type", objectToConvert.InvokeMethod("GetType"), out var objType), Declare.Variable <Type> ("iConvertibleType", Expression.TypeOf <IConvertible> (), out var iConvertibleType), Statement.If(iConvertibleType.InvokeMethod("IsAssignableFrom", objType), Then: Statement.Return(objectToConvert.Cast <IConvertible> ().InvokeMethod("ToString", formatProvider))), Declare.Variable <System.Reflection.MethodInfo> ("methInfo", objType.InvokeMethod("GetMethod", Expression.Primitive("ToString"), Expression.Array <Type> (iConvertibleType)), out var methInfoLocalRef), Statement.If(methInfoLocalRef.IsNotNull(), Then: Statement.Return(Expression.Cast <string> ( methInfoLocalRef.InvokeMethod("Invoke", objectToConvert, Expression.Array <object> (formatProvider))))), Statement.Return(objectToConvert.InvokeMethod("ToString")) ); var helperFieldName = provider.CreateValidIdentifier("_toStringHelper"); type.AddPropertyGetOnly("ToStringHelper", type.AddField(helperFieldName, helperClassType, Expression.New(helperClassType))); type.AddMember(helperClass); }
private static CodeTypeDeclaration Build(string className, MemberAttributes memberAttributes, IList <ResourceMapping> map, string extensionType, bool generateConstructors, string bindingType, CodeAttributeDeclaration bindingTypeConverter) { var type = Declare.Class(className + "Extension") .Modifiers(memberAttributes); var keyEnum = Declare.NestedEnum(ResourceKeyEnumName) .Modifiers(memberAttributes) .AddSummary(ResourceKeyEnumNameSummary) .AddTo(type); var keyEnumType = Code.Type(ResourceKeyEnumName).Local( ); var objectType = Code.Type <object> ( ); type.BaseTypes.Add(Code.Type(extensionType, Code.NestedType(type.Name, ResourceKeyEnumName).Local( ))); if (generateConstructors) { var distinctNumberOfArguments = map.Select(mapping => mapping.NumberOfArguments) .DefaultIfEmpty(0) .Distinct( ) .OrderBy(numberOfArguments => numberOfArguments); foreach (var numberOfArguments in distinctNumberOfArguments) { var ctor = new CodeConstructor( ) { Attributes = memberAttributes }.AddTo(type); for (var argument = 0; argument < numberOfArguments; argument++) { var parameterName = Format(CultureInfo.InvariantCulture, FormatMethodParameterName, argument); ctor.Parameters.Add(objectType.Parameter(parameterName)); ctor.BaseConstructorArgs.Add(Code.Variable(parameterName)); } } } var keyPathType = Code.Type(bindingType); var _key = Code.This( ).Field("_key"); var _keyPath = Code.This( ).Field("_keyPath"); var _type = Code.This( ).Field("_type"); Declare.Field(keyEnumType, _key.FieldName).AddTo(type); Declare.Property(keyEnumType, "Key").Public( ).Override( ) .Get(get => get.Return(_key)) .Set((set, value) => set.Add(Code.Assign(_key, value))) .AddTo(type); Declare.Field(keyPathType, _keyPath.FieldName).AddTo(type); Declare.Property(keyPathType, "KeyPath").Public( ).Override( ) .Get(get => get.Return(_keyPath)) .Set((set, value) => set.Add(Code.Assign(_keyPath, value))) .Attributed(bindingTypeConverter) .AddTo(type); Declare.Field <Type> (_type.FieldName).AddTo(type); Declare.Property <Type> ("Type").Public( ).Override( ) .Get(get => get.Return(_type)) .Set((set, value) => set.Add(Code.Assign(_type, value))) .AddTo(type); Declare.Property(Code.Type <ILocalizer> ( ), "Localizer").Protected( ).Override( ) .Get(get => get.Return(Code.Type(className).Local( ).Static( ).Property(LocalizerPropertyName))) .AddTo(type); var translation = new CodeArrayCreateExpression(Code.Type <string> ( )); var index = 0; foreach (var mapping in map) { Declare.Field(keyEnumType, mapping.Property).Const( ) .Modifiers(memberAttributes) .Initialize(Code.Constant(index++)) .AddSummary(ResourceKeyFieldSummaryFormat, mapping.Resource.Name) .AddTo(keyEnum); translation.Initializers.Add(Code.Constant(mapping.Resource.Name)); } var translator = Declare.Field <string []> (ResourceKeyTranslatorFieldName).Static( ) .Initialize(translation) .AddTo(type); var translate = Declare.Method <string> ("KeyToName", MemberAttributes.Family | MemberAttributes.Override) .AddTo(type); var key = Code.Variable(ResourceKeyParameterName); var first = keyEnumType.Static( ).Field(map [0].Property); var last = keyEnumType.Static( ).Field(map [index - 1].Property); translate.Parameters.Add(keyEnumType.Parameter(ResourceKeyParameterName)); translate.Statements.Add(Code.If(key.IsLessThan(first).Or( key.IsGreaterThan(last))) .Then(Code.Throw <ArgumentOutOfRangeException> (Code.Constant(ResourceKeyParameterName)))); translate.Statements.Return(Code.Static( ) .Field(ResourceKeyTranslatorFieldName) .Indexer(Code.Variable(ResourceKeyParameterName).Cast <int> ( ))); return(type); }
public static CodeTypeDeclaration AddClass(this CodeNamespace ns, string className) => ns.AddType(Declare.Class(className));