private static FieldDefDeclaration GetNonGenericLoggerField(WeavingContext context, bool create)
        {
            var type = context.Method.DeclaringType;
            foreach(var currentField in type.Fields)
            {
                if(currentField.Name == loggerFieldName)
                {
                    return currentField;
                }
            }

            if(create)
            {
                FieldDefDeclaration field = new FieldDefDeclaration();
                field.Name = loggerFieldName;
                field.FieldType = type.Module.FindType(typeof(ILog), BindingOptions.Default);
                field.Attributes = FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly;
                type.Fields.Add(field);

                return field;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// Gets the set of all fields that should not participate in Equals and GetHashCode generated because they're
        /// the target of [IgnoreDuringEquals].
        /// </summary>
        public static ISet <FieldDefDeclaration> GetIgnoredFields(IAnnotationRepositoryService annotations,
                                                                  ICompilerAdapterService compilerAdapterService)
        {
            HashSet <FieldDefDeclaration>     fields = new HashSet <FieldDefDeclaration>();
            IEnumerator <IAnnotationInstance> ignoredFieldsAnnotations =
                annotations.GetAnnotationsOfType(typeof(IgnoreDuringEqualsAttribute), false, false);

            while (ignoredFieldsAnnotations.MoveNext())
            {
                IAnnotationInstance annotationInstance = ignoredFieldsAnnotations.Current;
                MetadataDeclaration targetElement      = annotationInstance.TargetElement;
                if (targetElement is FieldDefDeclaration field)
                {
                    fields.Add(field);
                }
                else if (targetElement is PropertyDeclaration propertyDeclaration)
                {
                    FieldDefDeclaration backingField = compilerAdapterService.GetBackingField(propertyDeclaration);
                    if (backingField != null)
                    {
                        fields.Add(backingField);
                    }
                    else
                    {
                        // The property is not an automatic property.
                        // It's ignored, because there is no backing field and we make equality by fields.
                        // We could emit a warning but I don't think that's a great idea. Like, yeah, ignoring a
                        // non-automatic property has no effect but so what: it's ignored, just like the user wanted.
                    }
                }
            }

            return(fields);
        }
Exemple #3
0
        private void AddFieldCode(FieldDefDeclaration field, bool isFirst, InstructionWriter writer,
                                  LocalVariableSymbol resultVariable, MethodDefDeclaration method, TypeDefDeclaration enhancedType)
        {
            bool isCollection;
            var  propType           = field.FieldType;
            bool isValueType        = propType.IsValueTypeSafe() == true;
            bool isGenericParameter = false;

            if (propType.TypeSignatureElementKind == TypeSignatureElementKind.GenericParameter ||
                propType.TypeSignatureElementKind == TypeSignatureElementKind.GenericParameterReference)
            {
                // TODO what does this mean?
                // maybe something else also needs to be checked?
                isCollection       = false;
                isGenericParameter = true;
            }
            else
            {
                isCollection = propType.IsCollection() ||
                               propType.TypeSignatureElementKind == TypeSignatureElementKind.Array;
            }

            AddMultiplicityByMagicNumber(isFirst, writer, resultVariable, isCollection);

            if (propType.GetReflectionName().StartsWith("System.Nullable"))
            {
                AddNullableProperty(field, writer);
            }
            else if (isCollection && propType.GetReflectionName() != "System.String")
            {
                AddCollectionCode(field, writer, resultVariable, method, enhancedType);
            }
            else if (isValueType || isGenericParameter)
            {
                LoadVariable(field, writer);
                if (propType.GetReflectionName() != "System.Int32")
                {
                    writer.EmitInstructionType(OpCodeNumber.Box, propType);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode);
                }
            }
            else
            {
                LoadVariable(field, writer);
                AddNormalCode(field, writer, enhancedType);
            }

            if (!isFirst && !isCollection)
            {
                writer.EmitInstruction(OpCodeNumber.Xor);
            }

            if (!isCollection)
            {
                writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, resultVariable);
            }
        }
Exemple #4
0
            public NLogCategoryBuilder(NLogBackend parent, string categoryName)
            {
                this.parent = parent;

                this.loggerField = this.parent.loggingImplementation.GetCategoryField(categoryName, this.parent.loggerType, writer =>
                {
                    writer.EmitInstructionString(OpCodeNumber.Ldstr, categoryName);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.categoryInitializerMethod);
                });
            }
Exemple #5
0
 private void AddNormalCode(FieldDefDeclaration field, InstructionWriter writer, TypeDefDeclaration enhancedType)
 {
     writer.IfNotZero(
         thenw =>
     {
         LoadVariable(field, thenw);
         thenw.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode);
     },
         elsew => { elsew.EmitInstruction(OpCodeNumber.Ldc_I4_0); });
 }
Exemple #6
0
        void AddGetEnumerator(InstructionWriter ins, LocalVariableSymbol variable, FieldDefDeclaration field)
        {
            if (field.FieldType.IsValueTypeSafe() == true)
            {
                ins.EmitInstructionType(OpCodeNumber.Box, field.FieldType);
            }

            ins.EmitInstructionMethod(OpCodeNumber.Callvirt, GetEnumerator);
            ins.EmitInstructionLocalVariable(OpCodeNumber.Stloc, variable);
        }
        private void EmitEqualsField(InstructionWriter writer, CreatedEmptyMethod methodBody,
                                     FieldDefDeclaration field)
        {
            ITypeSignature fieldType = field.FieldType;

            if ((fieldType.GetNakedType() is IntrinsicTypeSignature sig &&
                 sig.IntrinsicType != IntrinsicType.Object &&
                 sig.IntrinsicType != IntrinsicType.String
                 ) || fieldType.IsEnum())
            {
                this.EmitSimpleValueCheck(writer, methodBody, field);
            }
Exemple #8
0
        private void AddCollectionCodeInternal(FieldDefDeclaration field, LocalVariableSymbol resultVariable,
                                               MethodDefDeclaration method, TypeDefDeclaration enhancedType, InstructionWriter writer)
        {
            LoadVariable(field, writer);

            var enumeratorVariable =
                method.MethodBody.RootInstructionBlock.DefineLocalVariable(IEnumeratorType, "enumeratorVariable");
            var currentVariable =
                method.MethodBody.RootInstructionBlock.DefineLocalVariable(
                    method.Module.Cache.GetIntrinsic(IntrinsicType.Object), "enumeratorObject");

            AddGetEnumerator(writer, enumeratorVariable, field);

            AddCollectionLoop(resultVariable, writer, enumeratorVariable, currentVariable);
        }
Exemple #9
0
 private void AddCollectionCode(FieldDefDeclaration field, InstructionWriter writer,
                                LocalVariableSymbol resultVariable, MethodDefDeclaration method, TypeDefDeclaration enhancedType)
 {
     if (field.FieldType.IsValueTypeSafe() == true)
     {
         AddCollectionCodeInternal(field, resultVariable, method, enhancedType, writer);
     }
     else
     {
         LoadVariable(field, writer);
         writer.IfNotZero(
             thenw => { AddCollectionCodeInternal(field, resultVariable, method, enhancedType, thenw); },
             elsew => { });
     }
 }
        private FieldDefDeclaration CreateIsLoggingField()
        {
            FieldDefDeclaration isLoggingFieldDef = new FieldDefDeclaration
            {
                Name       = "isLogging",
                Attributes = FieldAttributes.Private | FieldAttributes.Static,
                FieldType  = this.module.Cache.GetType(typeof(bool))
            };

            this.implementationType.Fields.Add(isLoggingFieldDef);

            isLoggingFieldDef.CustomAttributes.Add(this.CreateThreadStaticAttribute());

            return(isLoggingFieldDef);
        }
 private static TreeViewImage GetImageKind( FieldDefDeclaration field )
 {
     if ( ( field.Attributes & FieldAttributes.Literal ) != 0 )
     {
         if ( field.DeclaringType.BelongsToClassification( TypeClassifications.Enum ) )
         {
             return TreeViewImage.EnumValue;
         }
         else
         {
             return TreeViewImage.Const;
         }
     }
     else
     {
         return TreeViewImage.Field;
     }
 }
 private static TreeViewImage GetImageKind(FieldDefDeclaration field)
 {
     if ((field.Attributes & FieldAttributes.Literal) != 0)
     {
         if (field.DeclaringType.BelongsToClassification(TypeClassifications.Enum))
         {
             return(TreeViewImage.EnumValue);
         }
         else
         {
             return(TreeViewImage.Const);
         }
     }
     else
     {
         return(TreeViewImage.Field);
     }
 }
        public LoggingImplementationTypeBuilder(ModuleDeclaration module)
        {
            this.module         = module;
            this.categoryFields = new Dictionary <string, FieldDefDeclaration>();
            this.wrapperMethods = new Dictionary <IMethod, MethodDefDeclaration>();

            this.stringFormatArrayMethod = module.FindMethod(module.Cache.GetIntrinsic(IntrinsicType.String), "Format",
                                                             method => method.Parameters.Count == 2 &&
                                                             IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String) &&
                                                             method.Parameters[1].ParameterType.BelongsToClassification(TypeClassifications.Array));

            this.traceWriteLineMethod = module.FindMethod(module.Cache.GetType(typeof(System.Diagnostics.Trace)), "WriteLine",
                                                          method => method.Parameters.Count == 1 &&
                                                          IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String));

            this.weavingHelper      = new WeavingHelper(module);
            this.implementationType = this.CreateContainingType();
            this.isLoggingField     = this.CreateIsLoggingField();
        }
        public LoggingImplementationTypeBuilder( ModuleDeclaration module )
        {
            this.module = module;
            this.categoryFields = new Dictionary<string, FieldDefDeclaration>();
            this.wrapperMethods = new Dictionary<IMethod, MethodDefDeclaration>();

            this.stringFormatArrayMethod = module.FindMethod( module.Cache.GetIntrinsic( IntrinsicType.String ), "Format",
                                                              method => method.Parameters.Count == 2 &&
                                                                        IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) &&
                                                                        method.Parameters[1].ParameterType.BelongsToClassification( TypeClassifications.Array ) );

            this.traceWriteLineMethod = module.FindMethod( module.Cache.GetType( typeof(System.Diagnostics.Trace) ), "WriteLine",
                                                           method => method.Parameters.Count == 1 &&
                                                                     IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) );

            this.weavingHelper = new WeavingHelper( module );
            this.implementationType = this.CreateContainingType();
            this.isLoggingField = this.CreateIsLoggingField();
        }
Exemple #15
0
        private void AddNullableProperty(FieldDefDeclaration field, InstructionWriter writer)
        {
            IMethodSignature getHasValue = new MethodSignature(field.Module, CallingConvention.HasThis,
                                                               field.Module.Cache.GetIntrinsic(IntrinsicType.Boolean), new List <ITypeSignature>(), 0);
            var hasValueMethod = field.FieldType.FindMethod("get_HasValue", getHasValue);

            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstructionField(OpCodeNumber.Ldflda, field.GetCanonicalGenericInstance());
            writer.EmitInstructionMethod(OpCodeNumber.Call,
                                         hasValueMethod.GetInstance(field.Module, hasValueMethod.GenericMap));

            writer.IfNotZero((then) =>
            {
                writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                writer.EmitInstructionField(OpCodeNumber.Ldfld, field.GetCanonicalGenericInstance());
                writer.EmitInstructionType(OpCodeNumber.Box, field.FieldType);
                writer.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode);
            },
                             (elseBranch) => { writer.EmitInstruction(OpCodeNumber.Ldc_I4_0); });
        }
        private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action<InstructionWriter> initializeFieldAction)
        {
            string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1);

            FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration
            {
                Name = fieldName,
                Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly,
                FieldType = fieldType
            };
            this.containingType.Fields.Add(loggerFieldDef);

            InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null,
                                                                                        NodePosition.Before,
                                                                                        this.returnSequence);

            this.writer.AttachInstructionSequence(sequence);
            initializeFieldAction(this.writer);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef);
            this.writer.DetachInstructionSequence();

            return loggerFieldDef;
        }
 protected void IntroduceEvent(TransformationContext context, TypeDefDeclaration type, EventDeclaration theEvent)
 {
     var fieldRef = type.FindField(theEvent.Name);
     FieldDefDeclaration field;
     if(fieldRef == null) {
         field = new FieldDefDeclaration {
             Attributes = FieldAttributes.Private,
             Name = theEvent.Name,
             FieldType = theEvent.EventType,
         };
         type.Fields.Add(field);
     } else {
         field = fieldRef.Field;
     }
     var addOn = theEvent.GetAccessor(MethodSemantics.AddOn);
     if (addOn == null) {
         theEvent.ImplementAddOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
     var removeOn = theEvent.GetAccessor(MethodSemantics.RemoveOn);
     if (removeOn == null) {
         theEvent.ImplementRemoveOn(type, field, AspectInfrastructureTask.WeavingHelper);
     }
 }
        private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action <InstructionWriter> initializeFieldAction)
        {
            string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1);

            FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration
            {
                Name       = fieldName,
                Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly,
                FieldType  = fieldType
            };

            this.containingType.Fields.Add(loggerFieldDef);

            InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null,
                                                                                        NodePosition.Before,
                                                                                        this.returnSequence);

            this.writer.AttachInstructionSequence(sequence);
            initializeFieldAction(this.writer);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef);
            this.writer.DetachInstructionSequence();

            return(loggerFieldDef);
        }
        /// <summary>
        /// Emits the MSIL that calls the logging method with the specified message and exception.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="log">Field that stores reference to the logger.</param>
        /// <param name="method">Logging method to use. The method must return no value and must take 2 parameters of types <see cref="string"/> and <see cref="Exception"/>.</param>
        /// <param name="message">Message to log.</param>
        /// <param name="exception">Local variable where reference to the exception is stored.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="method"/>, <paramref name="message"/> or <paramref name="exception"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLogStringException(InstructionWriter emitter, FieldDefDeclaration log, IMethod method, string message, LocalVariableSymbol exception)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (log == null)
              {
            throw new ArgumentNullException("log");
              }
              if (method == null)
              {
            throw new ArgumentNullException("method");
              }
              if (message == null)
              {
            throw new ArgumentNullException("message");
              }
              if (exception == null)
              {
            throw new ArgumentNullException("exception");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(log));
              emitter.EmitInstructionString(OpCodeNumber.Ldstr, message);
              emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc_S, exception);
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method);
        }
        /// <summary>
        /// Emits the MSIL that calls the logging method with the specified format provider, message and arguments.
        /// </summary>
        /// <param name="emitter">IL emitter.</param>
        /// <param name="log">Field that stores reference to the logger.</param>
        /// <param name="method">Logging method to use. The method must return no value and must take 3 arguments of types <see cref="IFormatProvider"/>, <see cref="string"/> and <see cref="Array"/> of <see cref="object"/>s.</param>
        /// <param name="formatProviderGetter">Getter of the property that returns the <see cref="IFormatProvider"/> instance.</param>
        /// <param name="formatString">Format string for the log.</param>
        /// <param name="args">Variable storing reference to array of arguments for placeholders used in the format string.</param>
        /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="formatProviderGetter"/>, <paramref name="formatString"/> or <paramref name="args"/> is <see langword="null"/>.</exception>
        /// <remarks>
        /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack 
        /// and it leaves the stack unmodified.</para>
        /// </remarks>
        private static void EmitLogProviderStringArgs(InstructionWriter emitter, FieldDefDeclaration log, IMethod method, IMethod formatProviderGetter, string formatString, LocalVariableSymbol args)
        {
            if (emitter == null)
              {
            throw new ArgumentNullException("emitter");
              }
              if (log == null)
              {
            throw new ArgumentNullException("log");
              }
              if (method == null)
              {
            throw new ArgumentNullException("method");
              }
              if (formatProviderGetter == null)
              {
            throw new ArgumentNullException("formatProviderGetter");
              }
              if (args == null)
              {
            throw new ArgumentNullException("args");
              }

              emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(log));
              emitter.EmitInstructionMethod(OpCodeNumber.Call, formatProviderGetter);
              emitter.EmitInstructionString(OpCodeNumber.Ldstr, formatString);
              emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, args);
              emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method);
        }
            public Log4NetCategoryBuilder(Log4NetBackend parent, string categoryName)
            {
                this.parent = parent;

                this.loggerField = this.parent.loggingImplementation.GetCategoryField(categoryName, this.parent.loggerType, writer =>
                {
                    writer.EmitInstructionString(OpCodeNumber.Ldstr, categoryName);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.categoryInitializerMethod);
                });
            }
        public void Weave(WeavingContext context, PostSharp.CodeModel.InstructionBlock block)
        {
            TypeDefDeclaration typeDef = m_type;
            // Declare the static field
            FieldDefDeclaration fieldDef = new FieldDefDeclaration();
            fieldDef.Attributes = FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.NotSerialized | FieldAttributes.InitOnly;
            fieldDef.Name = "s_instance";
            fieldDef.FieldType = typeDef;

            typeDef.Fields.Add(fieldDef);

            // Declare the static accessor.
            PropertyDeclaration propDef = new PropertyDeclaration();
            propDef.Name = "Instance";

            typeDef.Properties.Add(propDef);

            MethodSemanticDeclaration sematic = new MethodSemanticDeclaration();
            sematic.Semantic = MethodSemantics.Getter;

            MethodDefDeclaration methodDef = new MethodDefDeclaration();
            methodDef.Name = "get_Instance";
            methodDef.Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.SpecialName;
            methodDef.CallingConvention = CallingConvention.Default;

            typeDef.Methods.Add(methodDef);

            ParameterDeclaration retVal = new ParameterDeclaration();
            retVal.ParameterType = typeDef;
            retVal.Attributes = ParameterAttributes.Retval;
            methodDef.ReturnParameter = retVal;

            sematic.Method = methodDef;

            propDef.Members.Add(sematic);
            propDef.PropertyType = typeDef;

            methodDef.MethodBody = new MethodBodyDeclaration();
            methodDef.MethodBody.MaxStack = 1;
            methodDef.MethodBody.RootInstructionBlock = methodDef.MethodBody.CreateInstructionBlock();

            //throw new NotFiniteNumberException();
            InstructionSequence sequence = methodDef.MethodBody.CreateInstructionSequence();
            methodDef.MethodBody.RootInstructionBlock.AddInstructionSequence(sequence, NodePosition.After , null);
            context.InstructionWriter.AttachInstructionSequence(sequence);

            context.InstructionWriter.EmitInstructionField(OpCodeNumber.Ldsfld, typeDef.Fields.GetByName("s_instance"));
            context.InstructionWriter.EmitInstruction(OpCodeNumber.Ret);

            context.InstructionWriter.DetachInstructionSequence();

            // code for the static constructor
            sequence = context.Method.MethodBody.CreateInstructionSequence();
            block.AddInstructionSequence(sequence, NodePosition.Before, null);
            context.InstructionWriter.AttachInstructionSequence(sequence);
            context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj, typeDef.Methods.GetOneByName(".ctor"));
            context.InstructionWriter.EmitInstructionField(OpCodeNumber.Stsfld, typeDef.Fields.GetByName("s_instance"));
            context.InstructionWriter.DetachInstructionSequence();

            // Change visibility to the constructor
            typeDef.Methods.GetOneByName(".ctor").Attributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName;
        }
        private static IField CreateBackingField(
            TypeDefDeclaration type,
            string name,
            ITypeSignature fieldType,
            CustomAttributeDeclaration compilerGenerated)
        {
            var field = new FieldDefDeclaration
            {
                Attributes = FieldAttributes.Private,
                Name = string.Format("<{0}>k__BackingField", name),
                FieldType = fieldType
            };

            // Create a backing field
            type.Fields.Add(field);
            MarkCompilerGenerated(field, compilerGenerated);
            return GenericHelper.GetCanonicalGenericInstance(field);
        }
        /// <summary>
        /// Creates a private static readonly field.
        /// </summary>
        /// <param name="name">Name of the field.</param>
        /// <param name="type">Type of the field.</param>
        /// <returns>Private static readonly field of the specified type.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="name"/> or <paramref name="type"/> is <see langword="null"/>.</exception>
        private static FieldDefDeclaration CreateField(string name, ITypeSignature type)
        {
            if (name == null)
              {
            throw new ArgumentNullException("name");
              }
              if (type == null)
              {
            throw new ArgumentNullException("type");
              }

              FieldDefDeclaration field = new FieldDefDeclaration();
              field.Attributes = FieldAttributes.InitOnly | FieldAttributes.Private | FieldAttributes.Static;
              field.Name = name;
              field.FieldType = type;
              return field;
        }
 public FieldTreeNode(FieldDefDeclaration field) :
     base(field, GetImageKind(field), field.Visibility)
 {
     this.Text = field.Name + " : " + field.FieldType.ToString();
 }
        /// <summary>
        /// Validates the usage of the attribute on a specific property.
        /// </summary>
        /// <param name="setter">The setter method of the property.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <param name="propertyName">Name of the property.</param>
        protected override void CompileTimeValidateSetter(MethodBase setter, Type propertyType, string propertyName)
        {
            //bool isControl = false;
            //Type baseType = setter.DeclaringType;
            //while (baseType != null)
            //{
            //    if (baseType.FullName == "System.Web.UI.Control")
            //    {
            //        isControl = true;
            //        break;
            //    }
            //    baseType = baseType.BaseType;
            //}

            //if (!isControl)
            //{
            //    MessageSource.MessageSink.Write(new Message(
            //        SeverityType.Error,
            //        "ViewStateVariableAttribute_PropertyDoesNotBelongToControl",
            //        string.Format(CultureInfo.InvariantCulture, "The property '{0}' does not belong to a System.Web.UI.Control.", propertyName),
            //        GetType().FullName
            //    ));
            //}
            if(setter.IsStatic)
            {
                MessageSource.MessageSink.Write(new Message(
                    SeverityType.Error,
                    "ViewStateVariableAttribute_PropertyCannotBeStatic",
                    string.Format(CultureInfo.InvariantCulture, "The property '{0}' must not be static.", propertyName),
                    GetType().FullName
                ));
            }

            SetFieldName(propertyName);

            MethodDefDeclaration postsharpMethod = ((IReflectionWrapper<MethodDefDeclaration>)setter).WrappedObject;

            FieldDefDeclaration propertyField = new FieldDefDeclaration();
            propertyField.Name = fieldName;

            if(propertyType.IsGenericType)
            {
                propertyField.FieldType = postsharpMethod.Module.FindType(propertyType, BindingOptions.RequireGenericInstance);
            }
            else
            {
                propertyField.FieldType = postsharpMethod.Module.FindType(propertyType, BindingOptions.Default);
            }

            propertyField.Attributes = FieldAttributes.Private;

            postsharpMethod.DeclaringType.Fields.Add(propertyField);
        }
                public override void Implement(MethodBodyTransformationContext context)
                {
                    /* We want to generate the following
                     *  if ( !this.<>4__this.Dispatcher.CheckAccess() )
                     *   {
                     *      SynchronizationContext oldContext = SynchronizationContext.Current;
                     *      SynchronizationContext.SetSynchronizationContext( this.<>4__this.Dispatcher.SynchronizationContext );
                     *      this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter();
                     *      this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                     *      SynchronizationContext.SetSynchronizationContext( oldContext );
                     *      return;
                     *   }
                     *
                     */



                    MethodDefDeclaration targetMethod = (MethodDefDeclaration)context.TargetElement;
                    TypeDefDeclaration   targetType   = targetMethod.DeclaringType;

                    targetMethod.MethodBody.MaxStack = -1;

                    // Add the field where we will store the awaiter.
                    FieldDefDeclaration awaiterFieldDef = new FieldDefDeclaration
                    {
                        Name       = "<>t__dispatchAwaiter",
                        FieldType  = this.parent.yieldAwaiter_Type,
                        Attributes = FieldAttributes.Private
                    };

                    targetType.Fields.Add(awaiterFieldDef);
                    IField awaiterField = awaiterFieldDef.GetCanonicalGenericInstance();

                    // Find other fields.
                    IField thisField    = targetType.Fields.Single <FieldDefDeclaration>(f => f.Name.EndsWith("__this")).GetCanonicalGenericInstance();
                    IField builderField = targetType.Fields.GetByName("<>t__builder").GetCanonicalGenericInstance();

                    // Emit instructions.
                    InstructionBlock myBlock    = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);
                    InstructionBlock theirBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null);

                    LocalVariableSymbol awaitableLocal = myBlock.DefineLocalVariable(this.parent.task_Yield_Method.ReturnType, "awaitable");
                    LocalVariableSymbol synchronizationContextLocal = myBlock.DefineLocalVariable(this.parent.synchronizationContext_Type, "oldContext");

                    InstructionSequence entrySequence = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionSequence exitSequence  = myBlock.AddInstructionSequence(null, NodePosition.After, null);
                    InstructionWriter   writer        = new InstructionWriter();

                    writer.AttachInstructionSequence(entrySequence);

                    // Emit: if ( this.<>4__this.Dispatcher.CheckAccess() ) goto exitSequence;
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_CheckAccess_Method);
                    writer.EmitBranchingInstruction(OpCodeNumber.Brtrue, exitSequence);

                    // Emit: this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter()
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.task_Yield_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, awaitableLocal);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloca, awaitableLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.yieldAwaitable_GetAwaiter_Method);
                    writer.EmitInstructionField(OpCodeNumber.Stfld, awaiterField);

                    // Emit: oldContext = SynchronizationContext.Current
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_getCurrent_Method);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, synchronizationContextLocal);

                    // Emit: SynchronizationContext.SetSynchronizationContext(this.<>4__this.Dispatcher.SynchronizationContext)
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_getSynchronizationContext_Method);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);

                    // Choose which AwaitUnsafeOnCompleted method to call.
                    IGenericMethodDefinition awaitUnsafeOnCompletedMethod;

                    ITypeSignature[] awaitUnsafeOnCompletedGenericTypeParameters;
                    if (builderField.FieldType == this.parent.asyncVoidMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncVoidMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else if (builderField.FieldType == this.parent.asyncTaskMethodBuilder_Type)
                    {
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilder_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters = null;
                    }
                    else
                    {
                        // This is a generic task.
                        awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilderGeneric_AwaitUnsafeOnCompleted_Method;
                        awaitUnsafeOnCompletedGenericTypeParameters =
                            builderField.FieldType.GetGenericContext(GenericContextOptions.None).GetGenericTypeParameters();
                    }

                    IMethod awaitUnsafeOnCompletedGenericMethod =
                        awaitUnsafeOnCompletedMethod.GetGenericInstance(new GenericMap(awaitUnsafeOnCompletedGenericTypeParameters,
                                                                                       new ITypeSignature[]
                    {
                        this.parent.yieldAwaiter_Type,
                        targetType.GetCanonicalGenericInstance()
                    }));

                    // Emit: this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref  this.<>t__dispatchAwaiter, ref this);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, builderField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionField(OpCodeNumber.Ldflda, awaiterField);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, awaitUnsafeOnCompletedGenericMethod);

                    // Emit: SynchronizationContext.SetSynchronizationContext( oldContext );
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, synchronizationContextLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method);


                    writer.EmitBranchingInstruction(OpCodeNumber.Leave, context.LeaveBranchTarget);

                    writer.DetachInstructionSequence();

                    // We are done. Give the pipeline to the next node.
                    context.AddRedirection(theirBlock, context.LeaveBranchTarget);
                }
        private FieldDefDeclaration CreateIsLoggingField()
        {
            FieldDefDeclaration isLoggingFieldDef = new FieldDefDeclaration
                                                        {
                                                            Name = "isLogging",
                                                            Attributes = FieldAttributes.Private | FieldAttributes.Static,
                                                            FieldType = this.module.Cache.GetType( typeof(bool) )
                                                        };
            this.implementationType.Fields.Add( isLoggingFieldDef );

            isLoggingFieldDef.CustomAttributes.Add( this.CreateThreadStaticAttribute() );

            return isLoggingFieldDef;
        }
Exemple #29
0
 private void LoadVariable(FieldDefDeclaration field, InstructionWriter writer)
 {
     writer.EmitInstruction(OpCodeNumber.Ldarg_0);
     writer.EmitInstructionField(OpCodeNumber.Ldfld, field.GetCanonicalGenericInstance());
 }
Exemple #30
0
            public override void Implement(TransformationContext context)
            {
                ModuleDeclaration module = this.AspectWeaver.Module;

                TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement;

                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                {
                    Name              = "AutoGeneratedValidate",
                    Attributes        = (MethodAttributes.Family | MethodAttributes.ReuseSlot | MethodAttributes.Virtual),
                    CallingConvention = CallingConvention.HasThis
                };

                typeDef.Methods.Add(methodDef);
                methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute());

                // Define parameter.
                methodDef.ReturnParameter = new ParameterDeclaration
                {
                    ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void),
                    Attributes    = ParameterAttributes.Retval
                };

                // Define the body
                MethodBodyDeclaration methodBody = new MethodBodyDeclaration();

                methodDef.MethodBody = methodBody;
                InstructionBlock instructionBlock = methodBody.CreateInstructionBlock();

                methodBody.RootInstructionBlock = instructionBlock;
                InstructionSequence sequence = methodBody.CreateInstructionSequence();

                instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);

                using (InstructionWriter writer = new InstructionWriter())
                {
                    writer.AttachInstructionSequence(sequence);

                    // Find the base method.
                    IMethod         baseValidateMethod = null;
                    IType           baseTypeCursor     = typeDef.BaseType;
                    MethodSignature methodSignature    =
                        new MethodSignature(module, CallingConvention.HasThis, module.Cache.GetIntrinsic(IntrinsicType.Void),
                                            new ITypeSignature[0], 0);

                    while (baseValidateMethod == null)
                    {
                        TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

                        baseValidateMethod =
                            baseTypeCursorTypeDef.Methods.GetMethod("AutoGeneratedValidate",
                                                                    methodSignature.Translate(baseTypeCursorTypeDef.Module),
                                                                    BindingOptions.OnlyExisting |
                                                                    BindingOptions.DontThrowException);

                        baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                    }

                    // TODO: support generic base types.

                    // Call the base method.
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionMethod(OpCodeNumber.Call, (IMethod)baseValidateMethod.Translate(typeDef.Module));

                    // Make an array with the boxed field values.
                    TypeValidationAspect aspect = (TypeValidationAspect)this.AspectWeaverInstance.Aspect;
                    LocalVariableSymbol  fieldValuesArrayLocal = instructionBlock.DefineLocalVariable(
                        module.Cache.GetType(typeof(object[])), "fieldValues");
                    writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, aspect.Validators.Count);
                    writer.EmitInstructionType(OpCodeNumber.Newarr, module.Cache.GetIntrinsic(IntrinsicType.Object));
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, fieldValuesArrayLocal);

                    int i = 0;
                    foreach (FieldValidationAttribute validator in aspect.Validators)
                    {
                        FieldDefDeclaration fieldDef = typeDef.Fields.GetByName(validator.TargetLocation.Name);
                        IField fieldSpec             = GenericHelper.GetFieldCanonicalGenericInstance(fieldDef);

                        writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal);
                        writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, i);
                        writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                        writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                        writer.EmitConvertToObject(fieldSpec.FieldType);
                        writer.EmitInstruction(OpCodeNumber.Stelem_Ref);

                        i++;
                    }

                    // Get the validator method.
                    IMethod validateMethod = module.Cache.GetItem(
                        () => module.FindMethod(
                            typeof(TypeValidationAspect).GetMethod("Validate"),
                            BindingOptions.Default));

                    // Call the validator.
                    this.AspectWeaverInstance.AspectRuntimeInstanceField.EmitLoadField(writer, null);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal);
                    writer.EmitInstructionMethod(OpCodeNumber.Callvirt, validateMethod);

                    writer.EmitInstruction(OpCodeNumber.Ret);
                    writer.DetachInstructionSequence();
                }
            }
 public FieldTreeNode( FieldDefDeclaration field ) :
     base( field, GetImageKind( field ), field.Visibility )
 {
     this.Text = field.Name + " : " + field.FieldType.ToString();
 }