public void AttributeOnClass_ConstructorArguments_Invalid() { //-- Arrange ImplementationClassWriter <object> classBody = DeriveClassFrom <object>().DefaultConstructor(); ArgumentException caughtException; //-- Act try { ExpectException <ArgumentException>( () => { classBody.Attribute <TestAttributeOne>(a => a.Arg(TimeSpan.Zero)); }, out caughtException); } finally { CreateClassInstanceAs <object>().UsingDefaultConstructor(); } //-- Assert Assert.That(caughtException, Is.Not.Null); StringAssert.Contains("signature", caughtException.Message); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- #region Overrides of ImplementationConvention protected override void OnImplementBaseClass(ImplementationClassWriter <TypeTemplate.TBase> writer) { writer.PrimaryConstructor("Target", out m_TargetField); writer.AllMethods(where : m => m.DeclaringType != typeof(object)).ImplementPropagate(m_TargetField); writer.AllProperties().ImplementPropagate(m_TargetField); writer.AllEvents().ImplementPropagate(m_TargetField); }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementBaseClass(ImplementationClassWriter<TT.TBase> writer) { var modelTypeKey = (EdmModelTypeKey)base.Context.TypeKey; var model = modelTypeKey.Model; writer.Constructor<Uri>((w, uri) => w.Base<Uri, string>(uri, w.Const(model.GetEntityNamespace()))); var allEntityTypes = model.SchemaElements.OfType<IEdmEntityType>().ToArray(); foreach ( var entityEdmType in allEntityTypes ) { var entityClrType = _entityFactory.ImplementClientEntity(model, entityEdmType); using ( TT.CreateScope<TT.TItem>(entityClrType) ) { writer.NewVirtualWritableProperty<DataServiceQuery<TT.TItem>>(entityEdmType.Name).Implement( p => p.Get(w => { w.If(p.BackingField == w.Const<DataServiceQuery<TT.TItem>>(null)).Then(() => p.BackingField.Assign( w.This<DataServiceContext>().Func<string, DataServiceQuery<TT.TItem>>( x => x.CreateQuery<TT.TItem>, w.Const(entityEdmType.Name))) ); w.Return(p.BackingField); }), p => p.Set((w, value) => { })); } } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementPrimaryInterface(ImplementationClassWriter<TypeTemplate.TInterface> writer) { var properties = new List<PropertyMember>(); ImplementProperties(writer, properties); ImplementLoadPropertiesMethod(writer, properties); ImplementGetXmlNameMethod(writer); ImplementConstructor(writer, properties); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void ImplementGetXmlNameMethod(ImplementationClassWriter<TypeTemplate.TInterface> writer) { var xmlName = ConfigurationSectionAttribute.From(Context.TypeKey.PrimaryInterface).XmlName; if ( string.IsNullOrEmpty(xmlName) ) { xmlName = Context.TypeKey.PrimaryInterface.Name.TrimPrefix("I").TrimSuffix("Config"); } writer.ImplementBase<ConfigurationSectionBase>().Method<string>(x => x.GetXmlName).Implement(m => m.Return(constantValue: xmlName)); }
public void SetUp() { StatementScope.Cleanup(); var key = new TypeKey(baseType: typeof(object)); m_Class = m_Module.DefineClass(key.BaseType, key, Guid.NewGuid().ToString()); var classBody = new ImplementationClassWriter <object>(m_Class); classBody.Method <string>(x => x.ToString).Implement(m => { }); m_Method = m_Class.GetMemberByName <MethodMember>("ToString"); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void ImplementConstructor(ImplementationClassWriter<TypeTemplate.TInterface> writer, List<PropertyMember> properties) { writer.Constructor<Auto<IConfigurationLogger>, string>((cw, logger, path) => { cw.Base(logger, path); foreach ( var property in properties ) { using ( TT.CreateScope<TT.TProperty>(property.PropertyDeclaration.PropertyType) ) { IOperand<TT.TProperty> defaultValue; if ( TryGetPropertyDefaultValue(cw, property.PropertyDeclaration, out defaultValue) ) { property.BackingField.AsOperand<TT.TProperty>().Assign(defaultValue); } } } }); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void CompileClosureClass() { m_ClosureClass = new NestedClassType( containingClass: m_OwnerClass, classFullName: m_HostMethod.Name + "<Closure>", baseType: typeof(object), closureDefinition: this); m_ClosureClassConstructor = m_ClosureClass.TypeBuilder.DefineDefaultConstructor( MethodAttributes.Public | MethodAttributes.ReuseSlot | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.HideBySig); var closureWriter = new ImplementationClassWriter <object>(m_ClosureClass); if (m_Parent != null) { m_ParentField = closureWriter.DefineField( name: "Parent", isStatic: false, isPublic: true, fieldType: m_Parent.ClosureClass.TypeBuilder); } foreach (var capture in m_Captures.Where(c => c.HoistingClosure == this)) { capture.DefineHoistedField(closureWriter); } foreach (var anonymousMethodOperand in m_AnonymousMethodsToHoist) { anonymousMethodOperand.CreateAnonymousMethod(m_ClosureClass, closure: this, isStatic: false, isPublic: true); anonymousMethodOperand.AnonymousMethod.AcceptVisitor(new ClosureHoistedMethodRewritingVisitor(anonymousMethodOperand.AnonymousMethod, this)); } m_ClosureClass.Compile(); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private static void ManuallyImplementLoggingDecorator( ImplementationClassWriter <AncestorRepository.IFewMethods> implementor, Field <List <string> > logField, string logSuffix = "") { var decorator = new ImplementationClassWriter <AncestorRepository.IFewMethods>(implementor.OwnerClass); decorator.AllMethods().ForEachMember(method => new TemplateMethodWriter(method, MethodWriterModes.Decorator, w => { logField.Add(w.Const(w.OwnerMethod.Name + ":BEFORE" + logSuffix)); w.Try(() => { var retVal = w.Proceed <TypeTemplate.TReturn>(); if (!method.Signature.IsVoid) { logField.Add(w.Const(w.OwnerMethod.Name + ":RETVAL" + logSuffix + "=") + retVal.Func <string>(x => x.ToString)); w.Return(retVal); } }).Catch <Exception>(e => { logField.Add(w.Const(w.OwnerMethod.Name + ":ERROR" + logSuffix + "=") + e.Prop(x => x.Message)); w.Throw(); }).Finally(() => { logField.Add(w.Const(w.OwnerMethod.Name + ":AFTER" + logSuffix)); }); })); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void WriteEntityProperty( ImplementationClassWriter<TypeTemplate.TBase> writer, IEdmModel model, IEdmProperty property, List<Action<ConstructorWriter>> initializers) { var propertyClrType = TranslateEdmTypeToClrType(model, property.Type.Definition); using (TT.CreateScope<TT.TProperty>(propertyClrType)) { var backingField = writer.Field<TT.TProperty>("_" + property.Name); if (property.Type.IsCollection()) { Type elementClrType = propertyClrType.GetGenericArguments()[0]; initializers.Add(cw => { using (TT.CreateScope<TT.TProperty, TT.TItem>(propertyClrType, elementClrType)) { backingField.Assign(cw.New<TT.TProperty>(cw.Const<IEnumerable<TT.TItem>>(null), cw.Const(TrackingMode.None))); } }); } writer.NewVirtualWritableProperty<TT.TProperty>(property.Name).ImplementAutomatic(backingField); } }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private static void WriteEntityAttributes(ImplementationClassWriter<TT.TBase> writer, IEdmEntityType entityType) { writer.Attribute<OriginalNameAttribute>(a => a.Arg(entityType.Name)); if ( entityType.DeclaredKey != null ) { var commaSeparatedKeyPropertyNames = string.Join(",", entityType.DeclaredKey.Select(p => p.Name).ToArray()); writer.Attribute<KeyAttribute>(a => a.Arg(commaSeparatedKeyPropertyNames)); } }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementBaseClass(ImplementationClassWriter<TT.TBase> writer) { var entityTypeKey = (EdmEntityTypeKey)base.Context.TypeKey; var entityType = entityTypeKey.EntityType; WriteEntityAttributes(writer, entityType); var initializers = new List<Action<ConstructorWriter>>(); foreach (var property in entityType.Properties()) { WriteEntityProperty(writer, entityTypeKey.Model, property, initializers); } writer.Constructor(cw => { initializers.ForEach(init => init(cw)); }); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- protected virtual void OnImplementAnyBaseType(ImplementationClassWriter <TypeTemplate.TBase> writer) { }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementPrimaryInterface(ImplementationClassWriter <TypeTemplate.TInterface> writer) { writer.AllMethods().ImplementEmpty(); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void ImplementLoadPropertiesMethod(ImplementationClassWriter<TypeTemplate.TInterface> writer, List<PropertyMember> properties) { writer.ImplementBase<ConfigurationSectionBase>().Method<XElement>(x => x.LoadProperties).Implement((m, xml) => { foreach ( var property in properties ) { using ( TT.CreateScope<TT.TProperty>(property.PropertyDeclaration.PropertyType) ) { m.This<ConfigurationSectionBase>().Void<XElement, string, TT.TProperty>( x => (a, b, c) => x.TryReadScalarValue<TT.TProperty>(a, b, ref c), xml, m.Const(property.Name), property.BackingField.AsOperand<TT.TProperty>()); } } }); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- private void ImplementProperties(ImplementationClassWriter<TypeTemplate.TInterface> writer, List<PropertyMember> properties) { writer.ReadOnlyProperties().Implement( p => p.Get(pw => { properties.Add(p.OwnerProperty); pw.Return(p.BackingField); }) ); }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementBaseClass(ImplementationClassWriter <TypeTemplate.TBase> writer) { writer.DefaultConstructor(); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementAnyInterface(ImplementationClassWriter <TypeTemplate.TInterface> writer) { writer.AllMethods().ImplementPropagate(m_TargetField.CastTo <TypeTemplate.TInterface>()); writer.AllProperties().ImplementPropagate(m_TargetField.CastTo <TypeTemplate.TInterface>()); writer.AllEvents().ImplementPropagate(m_TargetField.CastTo <TypeTemplate.TInterface>()); }
//------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementPrimaryInterface(ImplementationClassWriter <TypeTemplate.TInterface> writer) { writer.AllProperties().ImplementAutomatic(); }
//------------------------------------------------------------------------------------------------------------------------------------------------- public TupleClassBuilder(TypeKey key, ImplementationClassWriter <object> classBody) { m_Key = key; m_ClassBody = classBody; m_TupleProperties = TypeMemberCache.Of(key.PrimaryInterface).ImplementableProperties.ToDictionary(p => p.Name, StringComparer.OrdinalIgnoreCase); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- protected override void OnImplementPrimaryInterface(ImplementationClassWriter<TypeTemplate.TInterface> writer) { _threadLogAppenderField = writer.Field<IThreadLogAppender>("_threadLogAppender"); writer.Constructor<IThreadLogAppender>((w, appender) => _threadLogAppenderField.Assign(appender)); writer.AllMethods().Implement(ImplementLogMethod); writer.AllProperties().Implement( p => p.Get(w => w.Throw<NotSupportedException>("Events are not supported")), p => p.Set((w, value) => w.Throw<NotSupportedException>("Events are not supported"))); writer.AllEvents().Implement( e => e.Add((w, args) => w.Throw<NotSupportedException>("Events are not supported")), e => e.Remove((w, args) => w.Throw<NotSupportedException>("Events are not supported"))); }
//----------------------------------------------------------------------------------------------------------------------------------------------------- protected virtual void OnImplementAnyInterface(ImplementationClassWriter <TypeTemplate.TInterface> writer) { }