public MessageArgumentsFormatter(MethodBodyTransformationContext context)
 {
     this.context = context;
     this.targetMethod = context.TargetElement as MethodDefDeclaration;
     if (this.targetMethod == null)
     {
         throw new InvalidOperationException("Target element is not a method");
     }
 }
        private void EmitEqualsObjectOfReferenceType(InstructionWriter writer, IType genericTypeInstance,
                                                     MethodDefDeclaration typedEqualsMethod, CreatedEmptyMethod methodBody)
        {
            // Go to typed check.
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionType(OpCodeNumber.Castclass, genericTypeInstance);
            writer.EmitInstructionMethod(OpCodeNumber.Call, typedEqualsMethod.GetCanonicalGenericInstance());

            writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, methodBody.ReturnVariable);
            writer.EmitBranchingInstruction(OpCodeNumber.Br, methodBody.ReturnSequence);
        }
        private void EmitEqualsObjectOfValueType(InstructionWriter writer,
                                                 IType genericTypeInstance, MethodDefDeclaration typedEqualsMethod, CreatedEmptyMethod methodBody)
        {
            // return this.Equals((Typed)other);
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionType(OpCodeNumber.Unbox_Any, genericTypeInstance);
            writer.EmitInstructionMethod(OpCodeNumber.Call, typedEqualsMethod.GetCanonicalGenericInstance());

            writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, methodBody.ReturnVariable);
            writer.EmitBranchingInstruction(OpCodeNumber.Br, methodBody.ReturnSequence);
        }
                protected override void ImplementOnSuccess(InstructionBlock block, InstructionWriter writer)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    string messageFormatString = this.CreateMessageFormatString(this.onSuccessOptions, targetMethod);

                    this.EmitMessage(block, writer, targetMethod, "Leaving: " + messageFormatString);
                }
        bool FindInitializeCalls(Project project, AssemblyLoaderInfo assemblyLoaderInfo)
        {
            INamedType           packerUtilityType       = (INamedType)project.Module.FindType(typeof(PackerUtility));
            MethodDefDeclaration packerUtilityInitialize =
                project.Module.FindMethod(packerUtilityType, "Initialize").GetMethodDefinition();

            Sdk.CodeWeaver.Weaver weaver = new Sdk.CodeWeaver.Weaver(project);
            ReplacePackerUtilityInitializeAdvice replacingAdvice = new ReplacePackerUtilityInitializeAdvice(assemblyLoaderInfo.AttachMethod);

            weaver.AddMethodLevelAdvice(replacingAdvice, null,
                                        JoinPointKinds.InsteadOfCall, new[] { packerUtilityInitialize });
            weaver.Weave();
            return(replacingAdvice.ReplacedAtLeastOneCall);
        }
Example #6
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 => { });
     }
 }
Example #7
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);
        }
                private string CreateMessageFormatString(LogOptions logOption, MethodDefDeclaration targetMethod)
                {
                    StringBuilder formatBuilder = new StringBuilder();

                    formatBuilder.AppendFormat("{0}.{1}", targetMethod.DeclaringType, targetMethod.Name);
                    formatBuilder.Append("(");

                    int parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;

                    for (int i = 0; i < parameterCount; i++)
                    {
                        if (i > 0)
                        {
                            formatBuilder.Append(", ");
                        }

                        ITypeSignature parameterType = Context.MethodMapping.MethodSignature.GetParameterType(i);
                        if ((logOption & LogOptions.IncludeParameterType) != 0)
                        {
                            formatBuilder.Append(parameterType.ToString());
                            formatBuilder.Append(' ');
                        }

                        if ((logOption & LogOptions.IncludeParameterName) != 0)
                        {
                            formatBuilder.Append(Context.MethodMapping.MethodMappingInformation.GetParameterName(i));
                            formatBuilder.Append(' ');
                        }

                        if ((logOption & LogOptions.IncludeParameterValue) != 0)
                        {
                            formatBuilder.AppendFormat("= ");

                            if (IntrinsicTypeSignature.Is(parameterType, IntrinsicType.String))
                            {
                                formatBuilder.AppendFormat("\"" + "{{{0}}}" + "\"", i);
                            }
                            else
                            {
                                formatBuilder.AppendFormat("{{{0}}}", i);
                            }
                        }
                    }

                    formatBuilder.Append(")");

                    return(formatBuilder.ToString());
                }
        public override void CompileTimeValidate(MethodDefDeclaration method, IMessageSink messages)
        {
            base.CompileTimeValidate(method, messages);

            if (exception != null)
            {
                if (!ValidateExceptionTypeIsException(messages))
                {
                    return;
                }
                if (!ValidateExceptionTypeCanBeInstantiated(messages))
                {
                    return;
                }
            }
        }
Example #10
0
        private void ReplaceOperator(TypeDefDeclaration enhancedType, MethodDefDeclaration equalityMethodDef,
                                     bool negate)
        {
            InstructionBlock originalCode = equalityMethodDef.MethodBody.RootInstructionBlock;

            originalCode.Detach();

            InstructionBlock root = equalityMethodDef.MethodBody.CreateInstructionBlock();

            equalityMethodDef.MethodBody.RootInstructionBlock = root;
            var newSequence = root.AddInstructionSequence();

            using (var writer = InstructionWriter.GetInstance())
            {
                writer.AttachInstructionSequence(newSequence);

                if (enhancedType.IsValueType())
                {
                    var canonicalType = enhancedType.GetCanonicalGenericInstance();
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Box, canonicalType);
                }
                else
                {
                    writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                }

                writer.EmitInstructionMethod(OpCodeNumber.Call, this.staticEqualsMethod);

                if (negate)
                {
                    writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                    writer.EmitInstruction(OpCodeNumber.Ceq);
                }

                writer.EmitInstruction(OpCodeNumber.Ret);

                writer.DetachInstructionSequence();
            }
        }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name       = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType   = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };

            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name       = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };

            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes    = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence   = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(this.returnSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            return(logCategoriesType);
        }
Example #12
0
        public MethodTreeNode(MethodDefDeclaration method) :
            base(method, TreeViewImage.Method, method.Visibility)
        {
            this.method = method;

            StringBuilder name = new StringBuilder(255);

            this.method = method;
            name.Append(method.Name);

            bool first = true;

            if (method.Parameters.Count > 0)
            {
                name.Append("(");
                foreach (ParameterDeclaration parameter in method.Parameters)
                {
                    if (!first)
                    {
                        name.Append(", ");
                    }
                    else
                    {
                        name.Append(' ');
                        first = false;
                    }

                    name.Append(parameter.ParameterType.ToString());
                    name.Append(' ');
                    name.Append(parameter.Name);
                }
                name.Append(" )");
            }

            name.Append(" : ");
            name.Append(method.ReturnParameter.ParameterType.ToString());

            this.Text = name.ToString();

            this.EnableLatePopulate();
        }
        protected override void CompileTimeValidateParameters(MethodDefDeclaration method, IMessageSink messages, ParameterDeclaration firstParameter, ParameterDeclaration secondParameter)
        {
            base.CompileTimeValidateParameters(method, messages, firstParameter, secondParameter);

            if(typeof(IComparable).IsAssignableFrom(firstParameter.ParameterType.GetSystemType(null, null)))
            {
                firstParameterIsComparable = true;
            }
            else if(typeof(IComparable).IsAssignableFrom(secondParameter.ParameterType.GetSystemType(null, null)))
            {
                firstParameterIsComparable = false;
            }
            else
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "ComparisonValidatorAttribute_ParametersCantBeCompared",
                    string.Format(CultureInfo.InvariantCulture, "None of the parameters '{0}' and '{1}' implements IComparable.", firstParameter.Name, secondParameter.Name),
                    GetType().FullName
                ));
            }
        }
Example #14
0
        public MethodTreeNode( MethodDefDeclaration method ) :
            base( method, TreeViewImage.Method, method.Visibility )
        {
            this.method = method;

            StringBuilder name = new StringBuilder( 255 );
            this.method = method;
            name.Append( method.Name );

            bool first = true;
            if ( method.Parameters.Count > 0 )
            {
                name.Append( "(" );
                foreach ( ParameterDeclaration parameter in method.Parameters )
                {
                    if ( !first )
                    {
                        name.Append( ", " );
                    }
                    else
                    {
                        name.Append( ' ' );
                        first = false;
                    }

                    name.Append( parameter.ParameterType.ToString() );
                    name.Append( ' ' );
                    name.Append( parameter.Name );
                }
                name.Append( " )" );
            }

            name.Append( " : " );
            name.Append( method.ReturnParameter.ParameterType.ToString() );

            this.Text = name.ToString();

            this.EnableLatePopulate();
        }
        private static void GetPropertyAccessorDefinitions(PropertyDeclaration propertyDeclaration, out MethodDefDeclaration getMethodDef, out MethodDefDeclaration setMethodDef)
        {
            getMethodDef = null;
            setMethodDef = null;
            foreach (MethodSemanticDeclaration methodSemanticDef in propertyDeclaration.Members)
            {
                MethodDefDeclaration methodDef = methodSemanticDef.Method;

                if (methodDef.Name.StartsWith("get_"))
                {
                    getMethodDef = methodDef;
                }
                else if (methodDef.Name.StartsWith("set_"))
                {
                    setMethodDef = methodDef;
                }
                else
                {
                    throw new InvalidOperationException("Found a NotifyPropertyChanged attribute on something other than a property");
                }
            }
        }
        public override bool Execute()
        {
            var consoleWriteLine = FindConsoleWriteLine();

            var enumerator =
                annotationRepositoryService.GetAnnotationsOfType(typeof(HelloWorldAttribute), false, false);

            while (enumerator.MoveNext())
            {
                // Iterates over declarations to which our attribute has been applied. If the attribute weren't
                // a MulticastAttribute, that would be just the declarations that it annotates. With multicasting, it
                // can be far more declarations.

                MetadataDeclaration targetDeclaration = enumerator.Current.TargetElement;

                // Multicasting ensures that our attribute is only applied to methods, so there is little chance of
                // a class cast error here:
                MethodDefDeclaration targetMethod = (MethodDefDeclaration)targetDeclaration;

                AddHelloWorldToMethod(targetMethod, consoleWriteLine);
            }

            return(true);
        }
        private TypeDefDeclaration CreateContainingType()
        {
            string uniqueName = this.module.Types.GetUniqueName(
                DebuggerSpecialNames.GetDeclarationSpecialName("LoggingImplementationDetails{0}"));

            TypeDefDeclaration logCategoriesType = new TypeDefDeclaration
            {
                Name = uniqueName,
                Attributes = TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.Abstract,
                BaseType = ((IType)this.module.Cache.GetType("System.Object, mscorlib"))
            };
            this.module.Types.Add(logCategoriesType);

            // Add [CompilerGenerated] and [DebuggerNonUserCode] to the type
            this.weavingHelper.AddCompilerGeneratedAttribute(logCategoriesType.CustomAttributes);
            this.weavingHelper.AddDebuggerNonUserCodeAttribute(logCategoriesType.CustomAttributes);

            MethodDefDeclaration staticConstructor = new MethodDefDeclaration
            {
                Name = ".cctor",
                Attributes = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName |
                             MethodAttributes.SpecialName | MethodAttributes.HideBySig,
            };
            logCategoriesType.Methods.Add(staticConstructor);

            staticConstructor.ReturnParameter = new ParameterDeclaration
            {
                Attributes = ParameterAttributes.Retval,
                ParameterType = this.module.Cache.GetIntrinsic(IntrinsicType.Void)
            };

            this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
            this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(this.returnSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            return logCategoriesType;
        }
Example #18
0
 public ParameterCollectionTreeNode(MethodDefDeclaration declaration) : base(TreeViewImage.Folder, null)
 {
     this.declaration = declaration;
     this.Text        = "Parameters";
     this.EnableLatePopulate();
 }
                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 MethodDefDeclaration InjectEqualsType(TypeDefDeclaration enhancedType,
                                                      StructuralEqualityAttribute config, ICollection <FieldDefDeclaration> ignoredFields)
        {
            IType genericTypeInstance = enhancedType.GetCanonicalGenericInstance();

            var existingMethod = enhancedType.Methods.FirstOrDefault <IMethod>(declaration =>
            {
                return(declaration.Name == "Equals" &&
                       declaration.IsPublic() &&
                       !declaration.IsStatic &&
                       declaration.ParameterCount == 1 &&
                       declaration.GetParameterType(0).Equals(genericTypeInstance));
            });

            if (existingMethod != null)
            {
                return(existingMethod.GetMethodDefinition());
            }

            // public virtual bool Equals( Typed other )
            var equalsDeclaration = new MethodDefDeclaration
            {
                Name              = "Equals",
                Attributes        = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual,
                CallingConvention = CallingConvention.HasThis
            };

            enhancedType.Methods.Add(equalsDeclaration);
            equalsDeclaration.Parameters.Add(new ParameterDeclaration(0, "other", genericTypeInstance));
            equalsDeclaration.ReturnParameter = ParameterDeclaration.CreateReturnParameter(this.booleanType);
            CompilerGeneratedAttributeHelper.AddCompilerGeneratedAttribute(equalsDeclaration);

            using (var writer = InstructionWriter.GetInstance())
            {
                var methodBody = MethodBodyCreator.CreateModifiableMethodBody(writer, equalsDeclaration);
                writer.AttachInstructionSequence(methodBody.PrincipalBlock.AddInstructionSequence());

                writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, methodBody.ReturnVariable);

                this.InjectReferenceEquals(writer, methodBody, enhancedType);
                // Writer is either attached to the same sequence (value types) or to a new one which should check the structure.

                // return base.Equals(other) && this.field1 == other.field1 && ...;
                if (!config.IgnoreBaseClass && enhancedType.IsValueTypeSafe() != true)
                {
                    // Find the base method.
                    var baseEqualsMethod = this.instanceEqualsMethod.FindOverride(enhancedType.BaseTypeDef, true)
                                           .GetInstance(enhancedType.Module, enhancedType.BaseType.GetGenericContext());

                    // Do not invoke object.Equals();
                    if (baseEqualsMethod.DeclaringType.GetTypeDefinition() != this.objectTypeDef)
                    {
                        writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                        writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                        writer.EmitInstructionMethod(OpCodeNumber.Call, baseEqualsMethod);

                        // base.Equals(other) returned false, go to return.
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, methodBody.ReturnSequence);
                    }
                }

                foreach (var field in GetFieldsForComparison(enhancedType, ignoredFields))
                {
                    this.EmitEqualsField(writer, methodBody, field);
                }

                InjectCustomMethods(enhancedType, writer, methodBody);

                // return true;
                writer.EmitInstruction(OpCodeNumber.Ldc_I4_1);
                writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, methodBody.ReturnVariable);
                writer.EmitBranchingInstruction(OpCodeNumber.Br, methodBody.ReturnSequence);
                writer.DetachInstructionSequence();
            }

            return(equalsDeclaration);
        }
Example #21
0
        /// <summary>
        /// Finds a method with the same signature in the class
        /// </summary>
        /// <param name="decl">Class to inspect</param>
        /// <param name="method">Method with a name and signature</param>
        /// <returns>Found method or null</returns>
        public static MethodDefDeclaration FindSameMethod([NotNull] TypeDefDeclaration decl, [NotNull] MethodDefDeclaration method)
        {
            IMethod found =
                decl.Methods.GetMethod(
                    method.Name,
                    method,
                    BindingOptions.OnlyExisting);

            if (found == null)
            {
                return(null);
            }

            return(found.GetMethodDefinition(BindingOptions.OnlyExisting));
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="BuildParameterCollectionAdvice"/> class.
 /// </summary>
 /// <param name="method">The method.</param>
 public BuildParameterCollectionAdvice(MethodDefDeclaration method)
 {
     this.method = method;
 }
 public virtual void CompileTimeValidate(MethodDefDeclaration method, IMessageSink messages)
 {
 }
        /// <summary>
        /// Creates token for the specified placeholder.
        /// </summary>
        /// <param name="placeholder">Placeholder to create token for.</param>
        /// <param name="target">List to appent the token to.</param>
        /// <param name="wovenMethod">Method being woven.</param>
        /// <exception cref="ArgumentNullException"><paramref name="placeholder"/>, <paramref name="target"/> or <paramref name="wovenMethod"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException"><paramref name="placeholder"/> is invalid or unrecognized placeholder.</exception>
        private static void ProcessPlaceholder(string placeholder, ICollection<IMessageToken> target, MethodDefDeclaration wovenMethod)
        {
            if (placeholder == null) {
                throw new ArgumentNullException("placeholder");
            }
            if (target == null) {
                throw new ArgumentNullException("target");
            }
            if (wovenMethod == null) {
                throw new ArgumentNullException("wovenMethod");
            }

            if (string.Equals(placeholder, signaturePlaceholder2, StringComparison.InvariantCulture)
                || string.Equals(placeholder, signaturePlaceholder1, StringComparison.InvariantCulture)) {
                target.Add(new FixedToken(GetMethodSignature(wovenMethod)));
            } else if (placeholder.StartsWith(parameterPrefix, StringComparison.InvariantCulture)) {
                // Extract the name of the parameter.
                string parameterName = placeholder.Substring(parameterPrefix.Length);

                ParameterDeclaration referredParameter = null;
                foreach (ParameterDeclaration parameter in wovenMethod.Parameters) {
                    if (string.Equals(parameter.Name, parameterName, StringComparison.InvariantCulture)) {
                        referredParameter = parameter;
                        break;
                    }
                }
                if (referredParameter == null) {
                    throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Invalid parameter name: {0}.", parameterName));
                }

                target.Add(new ParameterValueToken(referredParameter));
            } else if (string.Equals(placeholder, shortParameterList, StringComparison.InvariantCulture)) {
                // Check if the method has any parameters.
                if (wovenMethod.Parameters.Count > 0) {
                    // Add opening quote for the first parameter.
                    target.Add(new FixedToken(@""""));

                    bool isFirstParameter = true;
                    foreach (ParameterDeclaration parameter in wovenMethod.Parameters) {
                        // Do not prepend anything before the first parameter.
                        if (! isFirstParameter) {
                            // Add closing quote for the previous parameter, then comma, then opening quote for the current parameter.
                            target.Add(new FixedToken(@""", """));
                        }

                        // Append parameter value.
                        target.Add(new ParameterValueToken(parameter));

                        // Next parameter is not the first one.
                        isFirstParameter = false;
                    }

                    // Add closing quote for the last parameter.
                    target.Add(new FixedToken(@""""));
                }
            } else if (string.Equals(placeholder, returnValue, StringComparison.InvariantCulture)) {
                target.Add(new ReturnValueToken(wovenMethod.ReturnParameter));
            } else {
                throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Unknown placeholder in template: {0}.", placeholder));
            }
        }
 protected virtual void CompileTimeValidateParameters(MethodDefDeclaration method, IMessageSink messages, ParameterDeclaration firstParameter, ParameterDeclaration secondParameter)
 {
 }
Example #26
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 BeforeOnDeserializingMethodAdvice( MethodDefDeclaration onDeserializingMethodDef, MethodDefDeclaration initializeMethodDef )
 {
     this.Method = onDeserializingMethodDef;
     this.initializeMethodDef = initializeMethodDef;
 }
Example #28
0
        public void AddGetHashCodeTo(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config,
                                     ISet <FieldDefDeclaration> ignoredFields)
        {
            if (enhancedType.Methods.Any <IMethod>(m => m.Name == "GetHashCode" &&
                                                   m.ParameterCount == 0))
            {
                // GetHashCode already present, just keep it.
                return;
            }

            // Create signature
            MethodDefDeclaration method = new MethodDefDeclaration
            {
                Name = "GetHashCode",
                CallingConvention = CallingConvention.HasThis,
                Attributes        = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig
            };

            enhancedType.Methods.Add(method);
            CompilerGeneratedAttributeHelper.AddCompilerGeneratedAttribute(method);
            method.ReturnParameter =
                ParameterDeclaration.CreateReturnParameter(enhancedType.Module.Cache.GetIntrinsic(IntrinsicType.Int32));

            // Generate ReSharper-style Fowler–Noll–Vo hash:
            using (InstructionWriter writer = InstructionWriter.GetInstance())
            {
                CreatedEmptyMethod getHashCodeData = MethodBodyCreator.CreateModifiableMethodBody(writer, method);
                var resultVariable = getHashCodeData.ReturnVariable;
                writer.AttachInstructionSequence(getHashCodeData.PrincipalBlock.AddInstructionSequence());

                // Start with 0
                writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
                writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, resultVariable);
                bool first = true;

                // Add base.GetHashCode():
                if (!config.IgnoreBaseClass)
                {
                    bool ignorable = enhancedType.BaseTypeDef.Name == "System.Object" ||
                                     enhancedType.IsValueTypeSafe() == true;
                    if (!ignorable)
                    {
                        var baseHashCode = project.Module.FindMethod(enhancedType.BaseTypeDef, "GetHashCode",
                                                                     BindingOptions.DontThrowException, 0);
                        // TODO Gael says: using FindOverride would be better
                        if (baseHashCode != null)
                        {
                            writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, resultVariable);
                            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                            // TODO what if it is two steps removed? then we won't call it!
                            writer.EmitInstructionMethod(OpCodeNumber.Call,
                                                         baseHashCode.GetGenericInstance(enhancedType.BaseType.GetGenericContext()));
                            writer.EmitInstruction(OpCodeNumber.Add);
                            writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, resultVariable);
                            first = false;
                        }
                    }
                }

                // For each field, do "hash = hash * 397 ^ field?.GetHashCode();
                foreach (FieldDefDeclaration field in enhancedType.Fields)
                {
                    if (field.IsConst || field.IsStatic || ignoredFields.Contains(field))
                    {
                        continue;
                    }

                    this.AddFieldCode(field, first, writer, resultVariable, method, enhancedType);
                    first = false;
                }

                // Now custom logic:
                foreach (var customLogic in enhancedType.Methods)
                {
                    if (customLogic.CustomAttributes.GetOneByType(typeof(AdditionalGetHashCodeMethodAttribute)
                                                                  .FullName) != null)
                    {
                        writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, resultVariable);
                        writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, magicNumber);
                        writer.EmitInstruction(OpCodeNumber.Mul);
                        AddCustomLogicCall(enhancedType, writer, customLogic);
                        writer.EmitInstruction(OpCodeNumber.Xor);
                        writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, resultVariable);
                    }
                }

                // Return the hash:
                writer.EmitBranchingInstruction(OpCodeNumber.Br, getHashCodeData.ReturnSequence);
                writer.DetachInstructionSequence();
            }
        }
 private bool MethodContainsSerializationAttribute(MethodDefDeclaration method, string simpleName)
 {
     return(method.CustomAttributes.GetOneByType("System.Runtime.Serialization." + simpleName)
            != null);
 }
        /// <summary>
        /// Creates a new method body and assigns it to <paramref name="hostMethod"/>. The method body looks as described in <see cref="CreatedEmptyMethod"/>.
        /// </summary>
        /// <param name="instructionWriter">A <b>detached</b> instruction writer.</param>
        /// <param name="hostMethod">The method without body. The body will be assigned to this method.</param>
        /// <returns>References to points in the method body.</returns>
        public static CreatedEmptyMethod CreateModifiableMethodBody(InstructionWriter instructionWriter, MethodDefDeclaration hostMethod)
        {
            // Create a new method body to host the pipeline.
            hostMethod.MethodBody = new MethodBodyDeclaration();
            InstructionBlock rootInstructionBlock = hostMethod.MethodBody.RootInstructionBlock = hostMethod.MethodBody.CreateInstructionBlock();

            InstructionBlock    sequencePointBlock    = rootInstructionBlock.AddChildBlock();
            InstructionSequence sequencePointSequence = sequencePointBlock.AddInstructionSequence();

            instructionWriter.AttachInstructionSequence(sequencePointSequence);
            instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            instructionWriter.EmitInstruction(OpCodeNumber.Nop);
            instructionWriter.DetachInstructionSequence();

            InstructionBlock    implementationBlock = rootInstructionBlock.AddChildBlock();
            InstructionBlock    returnBlock         = rootInstructionBlock.AddChildBlock();
            InstructionSequence returnSequence      = returnBlock.AddInstructionSequence();

            instructionWriter.AttachInstructionSequence(returnSequence);
            instructionWriter.EmitSymbolSequencePoint(SymbolSequencePoint.Hidden);
            LocalVariableSymbol returnVariable;

            if (!hostMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Void))
            {
                hostMethod.MethodBody.InitLocalVariables = true;
                returnVariable = rootInstructionBlock.DefineLocalVariable(
                    hostMethod.ReturnParameter.ParameterType,
                    DebuggerSpecialNames.GetVariableSpecialName(hostMethod.Domain, "returnValue", DebuggerSpecialVariableKind.ReturnValue)
                    );
                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, returnVariable);
            }
            else
            {
                returnVariable = null;
            }

            instructionWriter.EmitInstruction(OpCodeNumber.Ret);
            instructionWriter.DetachInstructionSequence();
            return(new CreatedEmptyMethod(hostMethod, implementationBlock, returnVariable, returnSequence));
        }
                private bool ShouldUseWrapper(MethodDefDeclaration targetMethod)
                {
                    if (targetMethod.Name == "ToString")
                    {
                        MethodDefDeclaration parent = targetMethod.GetParentDefinition(true);
                        if (parent != null)
                        {
                            if (parent.MatchesReference(
                                this.transformationInstance.parent.assets.ToStringMethodSignature))
                            {
                                return true;
                            }
                        }
                    }

                    for (int i = 0; i < targetMethod.Parameters.Count; i++)
                    {
                        ITypeSignature parameterType = targetMethod.Parameters[i].ParameterType;

                        if (!parameterType.BelongsToClassification(TypeClassifications.Intrinsic) ||
                            IntrinsicTypeSignature.Is(parameterType, IntrinsicType.Object))
                        {
                            return true;
                        }
                    }

                    return false;
                }
        private void EmitWrapperCallBody(MethodDefDeclaration wrapperMethod, IMethod loggerMethod)
        {
            InstructionBlock rootBlock = wrapperMethod.MethodBody.CreateInstructionBlock();

            wrapperMethod.MethodBody.RootInstructionBlock = rootBlock;

            InstructionBlock parentBlock   = rootBlock.AddChildBlock(null, NodePosition.After, null);
            InstructionBlock tryBlock      = rootBlock.AddChildBlock(null, NodePosition.After, null);
            InstructionBlock leaveTryBlock = rootBlock.AddChildBlock(null, NodePosition.After, null);

            InstructionSequence sequence = parentBlock.AddInstructionSequence(null, NodePosition.After, null);

            // set isLogging to true
            this.writer.AttachInstructionSequence(sequence);
            this.writer.EmitInstruction(OpCodeNumber.Ldc_I4_1);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, this.isLoggingField);
            this.writer.DetachInstructionSequence();

            // if isLogging is true, return
            InstructionSequence branchSequence = parentBlock.AddInstructionSequence(null, NodePosition.Before, null);

            this.writer.AttachInstructionSequence(branchSequence);
            this.writer.EmitInstructionField(OpCodeNumber.Ldsfld, this.isLoggingField);
            this.writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, sequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            // return instruction at the end of the method
            InstructionSequence retSequence = leaveTryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(retSequence);
            this.writer.EmitInstruction(OpCodeNumber.Ret);
            this.writer.DetachInstructionSequence();

            InstructionSequence trySequence = tryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(trySequence);

            for (int i = 0; i < wrapperMethod.Parameters.Count; i++)
            {
                writer.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)i);
            }

            this.EmitCallHandler(loggerMethod);

            this.writer.DetachInstructionSequence();

            InstructionSequence leaveSequence = tryBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(leaveSequence);
            this.writer.EmitBranchingInstruction(OpCodeNumber.Leave, retSequence);
            this.writer.DetachInstructionSequence();

            InstructionBlock protectedBlock;

            InstructionBlock[] catchBlocks;
            InstructionBlock   finallyBlock;

            this.weavingHelper.AddExceptionHandlers(this.writer, tryBlock, leaveSequence, null, true, out protectedBlock, out catchBlocks, out finallyBlock);

            InstructionSequence finallySequence = finallyBlock.AddInstructionSequence(null, NodePosition.After, null);

            this.writer.AttachInstructionSequence(finallySequence);
            this.writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
            this.writer.EmitInstructionField(OpCodeNumber.Stsfld, this.isLoggingField);
            //this.writer.EmitInstruction(OpCodeNumber.Endfinally);
            this.writer.DetachInstructionSequence();
        }
        private static void ImplementSetter(
            PropertyDeclaration property,
            TypeDefDeclaration type,
            IField field,
            MethodAttributes methodAttributes,
            CustomAttributeDeclaration compilerGenerated)
        {
            // Implement setter
            var setter = new MethodDefDeclaration
            {
                Attributes = methodAttributes,
                Name = "set_" + property.Name,
                CallingConvention = CallingConvention.HasThis,
            };
            type.Methods.Add(setter);

            MarkCompilerGenerated(setter, compilerGenerated);
            setter.ReturnParameter = new ParameterDeclaration
            {
                ParameterType = type.Module.Cache.GetIntrinsic(IntrinsicType.Void),
                Attributes = ParameterAttributes.Retval
            };
            setter.Parameters.Add(new ParameterDeclaration(0, "value", property.PropertyType));

            var methodBody = new MethodBodyDeclaration();
            var sequence = methodBody.CreateInstructionSequence();
            var instructionBlock = methodBody.CreateInstructionBlock();
            instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null);
            methodBody.RootInstructionBlock = instructionBlock;
            setter.MethodBody = methodBody;

            var writer = new InstructionWriter();
            writer.AttachInstructionSequence(sequence);
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionField(OpCodeNumber.Stfld, field);
            writer.EmitInstruction(OpCodeNumber.Ret);
            writer.DetachInstructionSequence();

            property.Members.Add(new MethodSemanticDeclaration(MethodSemantics.Setter, setter));
        }
Example #34
0
 /// <summary>
 /// Remove a method from a class
 /// </summary>
 public static void RemoveMethod([NotNull] ref TypeDefDeclaration decl, [NotNull] MethodDefDeclaration method)
 {
     decl.Methods.Remove(method);
 }
 public MethodDefDeclaration GetTraceStringFormatMethod()
 {
     return(this.traceWriteLineWrapperMethod ??
            (this.traceWriteLineWrapperMethod = this.CreateTraceStringFormatWrapper("TraceWriteLineFormat")));
 }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString)
                {
                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, LogSeverity.Trace);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    int  parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    bool hasThis        = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis;

                    builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null,
                                      (i, instructionWriter) =>
                    {
                        instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i));
                        instructionWriter.EmitConvertToObject(
                            this.Context.MethodMapping.MethodSignature.GetParameterType(i));
                    });

                    writer.DetachInstructionSequence();
                }
 /// <summary>
 /// Yields all the input parameters of the given woven method.
 /// </summary>
 /// <param name="wovenMethod">A woven method.</param>
 /// <remarks>
 /// Note, that a <c>ref</c> parameter is an input parameter.
 /// </remarks>
 private static IEnumerable<ParameterDeclaration> YieldInParameters(MethodDefDeclaration wovenMethod)
 {
     foreach (ParameterDeclaration parameter in wovenMethod.Parameters)
       {
     if ((parameter.Attributes & (ParameterAttributes.Out | ParameterAttributes.Retval)) == 0)
     {
       // Found a parameter, which is neither Out nor Retval. It is an input parameter.
       // Note, that by ref parameters are also input.
       yield return parameter;
     }
       }
 }
            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 bool RequiresStackStatus(MethodDefDeclaration method)
 {
     return(true);
 }
        public static void ImplementRemoveOn(
            this EventDeclaration theEvent,
            TypeDefDeclaration type,
            IField field,
            WeavingHelper weavingHelper = null,
            MethodAttributes methodAttributes =
                MethodAttributes.Public | MethodAttributes.HideBySig
                | MethodAttributes.Virtual | MethodAttributes.Final 
                | MethodAttributes.NewSlot | MethodAttributes.SpecialName)
        {
            var module = type.Module;
            weavingHelper = weavingHelper ?? new WeavingHelper(module);
            var pEWeavingHelper = module.Cache.GetItem(() => new PostEdgeWeaverAssets(module));

            var method = new MethodDefDeclaration {
                Attributes = methodAttributes,
                Name = "remove_" + theEvent.Name,
                CallingConvention = CallingConvention.HasThis
            };
            type.Methods.Add(method);
            weavingHelper.AddCompilerGeneratedAttribute(method.CustomAttributes);
            var parameter = new ParameterDeclaration {
                Name = "value",
                ParameterType = theEvent.EventType,
            };
            method.Parameters.Add(parameter);

            var methodBody = new MethodBodyDeclaration();
            methodBody.EnsureWritableLocalVariables();
            var instructionBlock = methodBody.CreateInstructionBlock();
            var initSequence = methodBody.CreateInstructionSequence();
            var loopSequence = methodBody.CreateInstructionSequence();
            var endSequence = methodBody.CreateInstructionSequence();
            instructionBlock.AddInstructionSequence(initSequence, NodePosition.After, null);
            instructionBlock.AddInstructionSequence(loopSequence, NodePosition.After, initSequence);
            instructionBlock.AddInstructionSequence(endSequence, NodePosition.After, loopSequence);
            methodBody.RootInstructionBlock = instructionBlock;
            method.MethodBody = methodBody;
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(theEvent.EventType);
            methodBody.CreateLocalVariable(module.Cache.GetIntrinsic(typeof(bool)));

            var writer = new InstructionWriter();
            //Initialize
            writer.AttachInstructionSequence(initSequence);

            //PropertyChangedHandler handler = this.PropertyChanged
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);           //Get the this pointer
            writer.EmitInstructionField(OpCodeNumber.Ldfld, field); //Get the event's field
            writer.EmitInstruction(OpCodeNumber.Stloc_0);           //store into the first local variable
            writer.DetachInstructionSequence();

            //Loop
            //do {
            writer.AttachInstructionSequence(loopSequence);

            //PropertyChangedHandler handler2 = handler;
            writer.EmitInstruction(OpCodeNumber.Ldloc_0);
            writer.EmitInstruction(OpCodeNumber.Stloc_1);

            //PropertyChangedHandler handler3 = System.Delegate.Remove(handler2, value)
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstruction(OpCodeNumber.Ldarg_1);
            writer.EmitInstructionMethod(OpCodeNumber.Call, pEWeavingHelper.DelegateRemoveMethod);
            writer.EmitInstructionType(OpCodeNumber.Castclass, theEvent.EventType);
            writer.EmitInstruction(OpCodeNumber.Stloc_2);

            //handler = System.Threading.Interlocked.CompareExchnage<PropertyChangedEventHandler>(ref this.PropertyChtyChanged, handler3, handler2);
            var compareExchangeMethodT = pEWeavingHelper.CompareExchangeMethod;
            var compareExchangeMethod = compareExchangeMethodT.GetGenericInstance(module, theEvent.EventType);
            writer.EmitInstruction(OpCodeNumber.Ldarg_0);           //Load this
            writer.EmitInstructionField(OpCodeNumber.Ldflda, field);
            writer.EmitInstruction(OpCodeNumber.Ldloc_2);
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstructionMethod(OpCodeNumber.Call, compareExchangeMethod);
            writer.EmitInstruction(OpCodeNumber.Stloc_0);

            //flag = handler != handler2;
            writer.EmitInstruction(OpCodeNumber.Ldloc_0);
            writer.EmitInstruction(OpCodeNumber.Ldloc_1);
            writer.EmitInstruction(OpCodeNumber.Ceq);
            writer.EmitInstruction(OpCodeNumber.Ldc_I4_0);
            writer.EmitInstruction(OpCodeNumber.Ceq);
            writer.EmitInstruction(OpCodeNumber.Stloc_3);

            //} while (flag);
            writer.EmitInstruction(OpCodeNumber.Ldloc_3);
            writer.EmitBranchingInstruction(OpCodeNumber.Brtrue_S, loopSequence);

            writer.DetachInstructionSequence();

            //End
            writer.AttachInstructionSequence(endSequence);
            writer.EmitInstruction(OpCodeNumber.Ret);               //Exit the method
            writer.DetachInstructionSequence();

            theEvent.Members.Add(new MethodSemanticDeclaration(MethodSemantics.RemoveOn, method));
        }
                private string CreateMessageFormatString(LogOptions logOption, MethodDefDeclaration targetMethod)
                {
                    StringBuilder formatBuilder = new StringBuilder();

                    formatBuilder.AppendFormat("{0}.{1}", targetMethod.DeclaringType, targetMethod.Name);
                    formatBuilder.Append("(");

                    int parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    for (int i = 0; i < parameterCount; i++)
                    {
                        if (i > 0)
                        {
                            formatBuilder.Append(", ");
                        }

                        ITypeSignature parameterType = Context.MethodMapping.MethodSignature.GetParameterType(i);
                        if ((logOption & LogOptions.IncludeParameterType) != 0)
                        {
                            formatBuilder.Append(parameterType.ToString());
                            formatBuilder.Append(' ');
                        }

                        if ((logOption & LogOptions.IncludeParameterName) != 0)
                        {
                            formatBuilder.Append(Context.MethodMapping.MethodMappingInformation.GetParameterName(i));
                            formatBuilder.Append(' ');
                        }

                        if ((logOption & LogOptions.IncludeParameterValue) != 0)
                        {
                            formatBuilder.AppendFormat("= ");

                            if (IntrinsicTypeSignature.Is(parameterType, IntrinsicType.String))
                            {
                                formatBuilder.AppendFormat("\"" + "{{{0}}}" + "\"", i);
                            }
                            else
                            {
                                formatBuilder.AppendFormat("{{{0}}}", i);
                            }
                        }
                    }

                    formatBuilder.Append(")");

                    return formatBuilder.ToString();
                }
            public override void Implement( TransformationContext context )
            {
                TypeDefDeclaration typeDef = (TypeDefDeclaration) context.TargetElement;

                ModuleDeclaration module = this.AspectWeaver.Module;
                ITypeSignature baseEntityType = module.Cache.GetType( typeof(BaseEntity) );

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

                while (baseCopyToMethod == null && baseTypeCursor != null)
                {
                    TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

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

                    baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                }

                if (baseCopyToMethod == null)
                    throw new AssertionFailedException("Could not find a method CopyTo.");

                if ( baseCopyToMethod.DeclaringType == typeDef )
                    return;


                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                                                     {
                                                         Name = "CopyTo",
                                                         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
                                                };

                ParameterDeclaration cloneParameter =
                    new ParameterDeclaration( 0, "clone", baseEntityType );
                methodDef.Parameters.Add( cloneParameter );

                // 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 );

                    // Cast the argument and store it in a local variable.
                    IType typeSpec = GenericHelper.GetTypeCanonicalGenericInstance( typeDef );
                    LocalVariableSymbol castedCloneLocal = instructionBlock.DefineLocalVariable( typeSpec, "typedClone" );
                    writer.EmitInstruction( OpCodeNumber.Ldarg_1 );
                    writer.EmitInstructionType( OpCodeNumber.Castclass, typeSpec );
                    writer.EmitInstructionLocalVariable( OpCodeNumber.Stloc, castedCloneLocal );

                  
                    // TODO: support generic base types.


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

                    // Loop on all fields and clone cloneable ones.
                    TypeRefDeclaration cloneableTypeRef = (TypeRefDeclaration)
                                                          module.Cache.GetType( typeof(ICloneable) );
                    MethodRefDeclaration cloneMethodRef = (MethodRefDeclaration) cloneableTypeRef.MethodRefs.GetMethod(
                                                                                     "Clone",
                                                                                     new MethodSignature(
                                                                                         module,
                                                                                         CallingConvention.HasThis,
                                                                                         module.Cache.GetIntrinsic(
                                                                                             IntrinsicType.Object ),
                                                                                         new ITypeSignature[0], 0 ),
                                                                                     BindingOptions.Default );

                    foreach ( FieldDefDeclaration fieldDef in typeDef.Fields )
                    {
                        if ( (fieldDef.Attributes & FieldAttributes.Static) != 0 )
                            continue;

                        if ( fieldDef.FieldType == module.Cache.GetIntrinsic( IntrinsicType.String ) )
                            continue;

                        // Does not work?
                        //bool cloneable = fieldDef.FieldType.Inherits(cloneableTypeRef, GenericMap.Empty);
                        bool cloneable = typeof(ICloneable).IsAssignableFrom( fieldDef.FieldType.GetSystemType( null, null ) );


                        if ( cloneable )
                        {
                            IField fieldSpec = GenericHelper.GetFieldCanonicalGenericInstance( fieldDef );
                            bool isValueType =
                                fieldSpec.FieldType.BelongsToClassification( TypeClassifications.ValueType ).Equals(
                                    NullableBool.True );

                            InstructionSequence nextSequence = null;
                            if ( !isValueType )
                            {
                                nextSequence = methodBody.CreateInstructionSequence();
                                writer.EmitInstruction( OpCodeNumber.Ldarg_0 );
                                writer.EmitInstructionField( OpCodeNumber.Ldfld, fieldSpec );
                                writer.EmitBranchingInstruction( OpCodeNumber.Brfalse, nextSequence );
                            }
                            writer.EmitInstructionLocalVariable( OpCodeNumber.Ldloc, castedCloneLocal );
                            writer.EmitInstruction( OpCodeNumber.Ldarg_0 );
                            writer.EmitInstructionField( OpCodeNumber.Ldfld, fieldSpec );
                            if ( isValueType )
                            {
                                writer.EmitInstructionType( OpCodeNumber.Box, fieldSpec.FieldType );
                            }
                            //writer.EmitInstructionType(OpCodeNumber.Castclass, cloneableTypeRef);
                            writer.EmitInstructionMethod( OpCodeNumber.Callvirt, cloneMethodRef );
                            if ( isValueType )
                            {
                                writer.EmitInstructionType( OpCodeNumber.Unbox, fieldSpec.FieldType );
                                writer.EmitInstructionType( OpCodeNumber.Ldobj, fieldSpec.FieldType );
                            }
                            else
                            {
                                writer.EmitInstructionType( OpCodeNumber.Castclass, fieldSpec.FieldType );
                            }
                            writer.EmitInstructionField( OpCodeNumber.Stfld, fieldSpec );


                            if ( !isValueType )
                            {
                                writer.DetachInstructionSequence();
                                instructionBlock.AddInstructionSequence( nextSequence, NodePosition.After, sequence );
                                sequence = nextSequence;
                                writer.AttachInstructionSequence( sequence );
                            }
                        }
                    }

                    writer.EmitInstruction( OpCodeNumber.Ret );
                    writer.DetachInstructionSequence();
                }
            }
        /// <summary>
        /// Splits the template into the list of tokens.
        /// </summary>
        /// <param name="template">Template to find tokens in.</param>
        /// <param name="wovenMethod">Method being woven.</param>
        /// <returns>List of tokens in the specified template.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="template"/> or <paramref name="wovenMethod"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException"><paramref name="template"/> is invalid and cannot be parsed.</exception>
        public static List<IMessageToken> Tokenize(string template, MethodDefDeclaration wovenMethod,
            bool includeParamName)
        {
            if (template == null)
              {
            throw new ArgumentNullException("template");
              }
              if (wovenMethod == null)
              {
            throw new ArgumentNullException("wovenMethod");
              }

              // List to put all recognized message parts in.
              List<IMessageToken> ret = new List<IMessageToken>();

              // Algorithm parses the messages by fragments. Boundaries of fragments are special characters,
              // like sequence indicators.

              // Position of the first character of the fragment that is currently processed.
              int fragmentBeginningIndex = 0;
              while (fragmentBeginningIndex < template.Length)
              {
            // Position of the first character of the next fragment.
            int nextFragmentBeginningIndex;

            // Search for the beginning-of-special-sequence indicator.
            int sequenceBeginningIndex = template.IndexOf(beginOfSequenceMarker, fragmentBeginningIndex);
            if (sequenceBeginningIndex != -1)
            {
              // Special sequence indicator has been found.

              // Append to the buffer the text preceding the marker.
              ret.Add(new FixedToken(template.Substring(fragmentBeginningIndex, sequenceBeginningIndex - fragmentBeginningIndex)));

              // Ensure that the special character is not the last one in the template.
              if (sequenceBeginningIndex + 1 < template.Length)
              {
            // Check if the next character in the template is again the sequence marker.
            char nextTemplateChar = template[sequenceBeginningIndex + 1];
            if (nextTemplateChar != beginOfSequenceMarker)
            {
              // Find the end-of-sequence marker.
              int sequenceEndingIndex = template.IndexOf(endOfSequenceMarker, sequenceBeginningIndex);
              if (sequenceEndingIndex != -1)
              {
                // Obtain the placeholder.
                string placeholder = template.Substring(sequenceBeginningIndex + 1, sequenceEndingIndex - sequenceBeginningIndex - 1);
                ProcessPlaceholder(placeholder, ret, wovenMethod, includeParamName);

                // Next fragment starts right after the sequence.
                nextFragmentBeginningIndex = sequenceEndingIndex + 1;
              }
              else
              {
                // Sequence is not closed.
                throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Unfinished placeholder in template: {0}.", template));
              }
            }
            else
            {
              // Repeated begin-of-sequence marker, indicates the marker should be used literally.
              ret.Add(new FixedToken(beginOfSequenceMarker.ToString(CultureInfo.InvariantCulture)));
              nextFragmentBeginningIndex = sequenceBeginningIndex + 2;
            }
              }
              else
              {
            // Begin-of-sequence marker is the last char in the template.
            throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Invalid placeholder in template: {0}.", template));
              }
            }
            else
            {
              // No special sequence indicator has been found.

              // Copy the remaining part of the template as literal message text.
              ret.Add(new FixedToken(template.Substring(fragmentBeginningIndex, template.Length - fragmentBeginningIndex)));
              // Set the index to the position which causes the parsing loop to exit.
              nextFragmentBeginningIndex = template.Length;
            }

            fragmentBeginningIndex = nextFragmentBeginningIndex;
              }

              return ret;
        }
        public override void CompileTimeValidate(MethodDefDeclaration method, IMessageSink messages)
        {
            base.CompileTimeValidate(method, messages);

            ParameterDeclaration firstParameter = null;
            ParameterDeclaration secondParameter = null;

            foreach(var parameter in method.Parameters)
            {
                if(parameter.Name == firstParameterName)
                {
                    firstParameter = parameter;
                }
                if(parameter.Name == secondParameterName)
                {
                    secondParameter = parameter;
                }
            }

            if(firstParameter == null)
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "TwoParametersValidatorAttribute_ParameterNotFound",
                    string.Format(CultureInfo.InvariantCulture,
                        "The parameter '{0}' does not exist in method '{1}'.",
                        firstParameterName,
                        method.Name),
                    GetType().FullName
                ));
            }

            if(secondParameter == null)
            {
                messages.Write(new Message(
                    SeverityType.Error,
                    "TwoParametersValidatorAttribute_ParameterNotFound",
                    string.Format(CultureInfo.InvariantCulture,
                        "The parameter '{0}' does not exist in method '{1}'.",
                        secondParameterName,
                        method.Name),
                    GetType().FullName
                ));
            }

            if(firstParameter != null && secondParameter != null)
            {
                if(firstParameterName == secondParameterName)
                {
                    {
                        messages.Write(new Message(
                            SeverityType.Error,
                            "TwoParametersValidatorAttribute_CantSpecifyTheSameParameter",
                            "The same name has been specified for both parameters.",
                            GetType().FullName
                        ));
                    }
                }
                else
                {
                    CompileTimeValidateParameters(method, messages, firstParameter, secondParameter);
                }
            }
        }
 public CollectParametersAdvice(MethodDefDeclaration declaration)
 {
     this.declaration = declaration;
 }
            public override void Implement(TransformationContext context)
            {
                TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement;

                ModuleDeclaration module         = this.AspectWeaver.Module;
                ITypeSignature    baseEntityType = module.Cache.GetType(typeof(BaseEntity));

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

                while (baseCopyToMethod == null && baseTypeCursor != null)
                {
                    TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition();

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

                    baseTypeCursor = baseTypeCursorTypeDef.BaseType;
                }

                if (baseCopyToMethod == null)
                {
                    throw new AssertionFailedException("Could not find a method CopyTo.");
                }

                if (baseCopyToMethod.DeclaringType == typeDef)
                {
                    return;
                }


                // Declare the method.
                MethodDefDeclaration methodDef = new MethodDefDeclaration
                {
                    Name       = "CopyTo",
                    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
                };

                ParameterDeclaration cloneParameter =
                    new ParameterDeclaration(0, "clone", baseEntityType);

                methodDef.Parameters.Add(cloneParameter);

                // 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);

                    // Cast the argument and store it in a local variable.
                    IType typeSpec = GenericHelper.GetTypeCanonicalGenericInstance(typeDef);
                    LocalVariableSymbol castedCloneLocal = instructionBlock.DefineLocalVariable(typeSpec, "typedClone");
                    writer.EmitInstruction(OpCodeNumber.Ldarg_1);
                    writer.EmitInstructionType(OpCodeNumber.Castclass, typeSpec);
                    writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, castedCloneLocal);


                    // TODO: support generic base types.


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

                    // Loop on all fields and clone cloneable ones.
                    TypeRefDeclaration cloneableTypeRef = (TypeRefDeclaration)
                                                          module.Cache.GetType(typeof(ICloneable));
                    MethodRefDeclaration cloneMethodRef = (MethodRefDeclaration)cloneableTypeRef.MethodRefs.GetMethod(
                        "Clone",
                        new MethodSignature(
                            module,
                            CallingConvention.HasThis,
                            module.Cache.GetIntrinsic(
                                IntrinsicType.Object),
                            new ITypeSignature[0], 0),
                        BindingOptions.Default);

                    foreach (FieldDefDeclaration fieldDef in typeDef.Fields)
                    {
                        if ((fieldDef.Attributes & FieldAttributes.Static) != 0)
                        {
                            continue;
                        }

                        if (fieldDef.FieldType == module.Cache.GetIntrinsic(IntrinsicType.String))
                        {
                            continue;
                        }

                        // Does not work?
                        //bool cloneable = fieldDef.FieldType.Inherits(cloneableTypeRef, GenericMap.Empty);
                        bool cloneable = typeof(ICloneable).IsAssignableFrom(fieldDef.FieldType.GetSystemType(null, null));


                        if (cloneable)
                        {
                            IField fieldSpec   = GenericHelper.GetFieldCanonicalGenericInstance(fieldDef);
                            bool   isValueType =
                                fieldSpec.FieldType.BelongsToClassification(TypeClassifications.ValueType).Equals(
                                    NullableBool.True);

                            InstructionSequence nextSequence = null;
                            if (!isValueType)
                            {
                                nextSequence = methodBody.CreateInstructionSequence();
                                writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                                writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                                writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, nextSequence);
                            }
                            writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, castedCloneLocal);
                            writer.EmitInstruction(OpCodeNumber.Ldarg_0);
                            writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec);
                            if (isValueType)
                            {
                                writer.EmitInstructionType(OpCodeNumber.Box, fieldSpec.FieldType);
                            }
                            //writer.EmitInstructionType(OpCodeNumber.Castclass, cloneableTypeRef);
                            writer.EmitInstructionMethod(OpCodeNumber.Callvirt, cloneMethodRef);
                            if (isValueType)
                            {
                                writer.EmitInstructionType(OpCodeNumber.Unbox, fieldSpec.FieldType);
                                writer.EmitInstructionType(OpCodeNumber.Ldobj, fieldSpec.FieldType);
                            }
                            else
                            {
                                writer.EmitInstructionType(OpCodeNumber.Castclass, fieldSpec.FieldType);
                            }
                            writer.EmitInstructionField(OpCodeNumber.Stfld, fieldSpec);


                            if (!isValueType)
                            {
                                writer.DetachInstructionSequence();
                                instructionBlock.AddInstructionSequence(nextSequence, NodePosition.After, sequence);
                                sequence = nextSequence;
                                writer.AttachInstructionSequence(sequence);
                            }
                        }
                    }

                    writer.EmitInstruction(OpCodeNumber.Ret);
                    writer.DetachInstructionSequence();
                }
            }
        private MethodDefDeclaration CreateTraceStringFormatWrapper( string name )
        {
            MethodDefDeclaration formatWrapperMethod = new MethodDefDeclaration
                                                           {
                                                               Name = name,
                                                               Attributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                                                           };
            this.implementationType.Methods.Add( formatWrapperMethod );

            formatWrapperMethod.Parameters.Add( new ParameterDeclaration( 0, "format", this.module.Cache.GetIntrinsic( IntrinsicType.String ) ) );
            formatWrapperMethod.Parameters.Add( new ParameterDeclaration( 1, "args", this.module.Cache.GetType( typeof(object[]) ) ) );

            InstructionBlock block = formatWrapperMethod.MethodBody.CreateInstructionBlock();
            formatWrapperMethod.MethodBody.RootInstructionBlock = block;
            InstructionSequence sequence = block.AddInstructionSequence( null, NodePosition.After, null );
            this.writer.AttachInstructionSequence( sequence );

            for ( int i = 0; i < formatWrapperMethod.Parameters.Count; i++ )
            {
                this.writer.EmitInstructionInt16( OpCodeNumber.Ldarg, (short) i );
            }

            this.writer.EmitInstructionMethod( OpCodeNumber.Call, this.stringFormatArrayMethod );

            this.EmitCallHandler( this.traceWriteLineMethod );
            this.writer.EmitInstruction( OpCodeNumber.Ret );
            this.writer.DetachInstructionSequence();

            return formatWrapperMethod;
        }
        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 MethodDefDeclaration CreateWrapperMethod( IMethod loggerMethod )
        {
            MethodDefDeclaration wrapperMethod = new MethodDefDeclaration
                                                     {
                                                         Name = this.implementationType.Methods.GetUniqueName( loggerMethod.Name + "{0}" ),
                                                         Attributes = MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig,
                                                     };
            this.implementationType.Methods.Add( wrapperMethod );

            wrapperMethod.ReturnParameter = new ParameterDeclaration
                                                {
                                                    Attributes = ParameterAttributes.Retval,
                                                    ParameterType = this.module.Cache.GetIntrinsic( IntrinsicType.Void )
                                                };

            ITypeSignature loggerFieldType = loggerMethod.DeclaringType.GetNakedType();
            MethodDefDeclaration loggerMethodDefinition = loggerMethod.GetMethodDefinition();
            if ( !loggerMethodDefinition.IsStatic )
            {
                wrapperMethod.Parameters.Add( new ParameterDeclaration( 0, "logger", loggerFieldType ) );
            }

            for ( int i = 0; i < loggerMethodDefinition.Parameters.Count; i++ )
            {
                ParameterDeclaration parameter = loggerMethodDefinition.Parameters[i];
                wrapperMethod.Parameters.Add( new ParameterDeclaration( wrapperMethod.Parameters.Count, parameter.Name,
                                                                        parameter.ParameterType.TranslateType( this.module ) ) );
            }

            this.EmitWrapperCallBody( wrapperMethod, loggerMethod );

            return wrapperMethod;
        }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer,
                                         LogLevel logLevel, string messageFormatString, int[] arguments, ITypeSignature exceptionType = null)
                {
                    MethodDefDeclaration targetMethod = Context.TargetElement as MethodDefDeclaration;

                    if (targetMethod == null)
                    {
                        return;
                    }

                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);

                    writer.AttachInstructionSequence(sequence);

                    LocalVariableSymbol exceptionLocal = null;

                    if (exceptionType != null)
                    {
                        exceptionLocal = block.MethodBody.RootInstructionBlock.DefineLocalVariable(
                            exceptionType, DebuggerSpecialNames.GetVariableSpecialName("ex"));
                    }

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, logLevel);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    bool useWrapper = ShouldUseWrapper(targetMethod);

                    Action <InstructionWriter> getExceptionAction = exceptionLocal != null ? (Action <InstructionWriter>)(w => w.EmitInstructionLocalVariable(OpCodeNumber.Stloc, exceptionLocal)) : null;

                    builder.EmitWrite(writer,
                                      messageFormatString,
                                      exceptionType == null ? arguments.Length : arguments.Length + 1,
                                      logLevel,
                                      getExceptionAction,
                                      (i, instructionWriter) =>
                    {
                        if (i < arguments.Length)
                        {
                            int index = arguments[i];
                            if (index == MessageArgumentsFormatter.ThisArgumentPosition)
                            {
                                this.methodMappingWriter.EmitLoadInstance(false, instructionWriter);
                            }
                            else if (index == MessageArgumentsFormatter.ReturnParameterPosition)
                            {
                                instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, Context.ReturnValueVariable);
                                instructionWriter.EmitConvertToObject(
                                    Context.MethodMapping.MethodSignature.ReturnType);
                            }
                            else
                            {
                                this.methodMappingWriter.EmitLoadArgument(index, instructionWriter);

                                instructionWriter.EmitConvertToObject(this.methodMappingWriter.MethodMapping.MethodSignature.GetParameterType(index).GetNakedType(TypeNakingOptions.IgnoreManagedPointers));
                            }
                        }
                        else
                        {
                            //Emit exception parameter
                            instructionWriter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, exceptionLocal);
                        }
                    },
                                      useWrapper);
                    if (exceptionType == null)
                    {
                        writer.DetachInstructionSequence();
                    }
                }
 private void EmitContstructorBlock( MethodDefDeclaration staticConstructor )
 {
     this.constructorBlock = staticConstructor.MethodBody.RootInstructionBlock = staticConstructor.MethodBody.CreateInstructionBlock();
     this.returnSequence = staticConstructor.MethodBody.RootInstructionBlock.AddInstructionSequence( null,
                                                                                                     NodePosition.After,
                                                                                                     null );
     this.writer.AttachInstructionSequence( this.returnSequence );
     this.writer.EmitInstruction( OpCodeNumber.Ret );
     this.writer.DetachInstructionSequence();
 }
                private void EmitMessage(InstructionBlock block, InstructionWriter writer, MethodDefDeclaration targetMethod, string messageFormatString)
                {
                    // TODO: nested types
                    string category = targetMethod.DeclaringType.Name;
                    ILoggingCategoryBuilder builder = this.backendInstance.GetCategoryBuilder(category);

                    InstructionSequence sequence = block.AddInstructionSequence(null, NodePosition.After, null);
                    writer.AttachInstructionSequence(sequence);

                    if (builder.SupportsIsEnabled)
                    {
                        builder.EmitGetIsEnabled(writer, LogSeverity.Trace);
                        InstructionSequence branchSequence = block.AddInstructionSequence(null, NodePosition.After, sequence);
                        writer.EmitBranchingInstruction(OpCodeNumber.Brfalse_S, branchSequence);
                    }

                    int parameterCount = Context.MethodMapping.MethodSignature.ParameterCount;
                    bool hasThis = Context.MethodMapping.MethodSignature.CallingConvention == CallingConvention.HasThis;

                    builder.EmitWrite(writer, block, messageFormatString, parameterCount, LogSeverity.Trace, null,
                                      (i, instructionWriter) =>
                                      {
                                          instructionWriter.EmitInstructionInt16(OpCodeNumber.Ldarg, (short)(hasThis ? i + 1 : i));
                                          instructionWriter.EmitConvertToObject(
                                              this.Context.MethodMapping.MethodSignature.GetParameterType(i));
                                      });

                    writer.DetachInstructionSequence();
                }
        private void EmitWrapperCallBody( MethodDefDeclaration wrapperMethod, IMethod loggerMethod )
        {
            InstructionBlock rootBlock = wrapperMethod.MethodBody.CreateInstructionBlock();
            wrapperMethod.MethodBody.RootInstructionBlock = rootBlock;

            InstructionBlock parentBlock = rootBlock.AddChildBlock( null, NodePosition.After, null );
            InstructionBlock tryBlock = rootBlock.AddChildBlock( null, NodePosition.After, null );
            InstructionBlock leaveTryBlock = rootBlock.AddChildBlock( null, NodePosition.After, null );

            InstructionSequence sequence = parentBlock.AddInstructionSequence( null, NodePosition.After, null );
            // set isLogging to true
            this.writer.AttachInstructionSequence( sequence );
            this.writer.EmitInstruction( OpCodeNumber.Ldc_I4_1 );
            this.writer.EmitInstructionField( OpCodeNumber.Stsfld, this.isLoggingField );
            this.writer.DetachInstructionSequence();

            // if isLogging is true, return
            InstructionSequence branchSequence = parentBlock.AddInstructionSequence( null, NodePosition.Before, null );
            this.writer.AttachInstructionSequence( branchSequence );
            this.writer.EmitInstructionField( OpCodeNumber.Ldsfld, this.isLoggingField );
            this.writer.EmitBranchingInstruction( OpCodeNumber.Brfalse_S, sequence );
            this.writer.EmitInstruction( OpCodeNumber.Ret );
            this.writer.DetachInstructionSequence();

            // return instruction at the end of the method
            InstructionSequence retSequence = leaveTryBlock.AddInstructionSequence( null, NodePosition.After, null );
            this.writer.AttachInstructionSequence( retSequence );
            this.writer.EmitInstruction( OpCodeNumber.Ret );
            this.writer.DetachInstructionSequence();

            InstructionSequence trySequence = tryBlock.AddInstructionSequence( null, NodePosition.After, null );
            this.writer.AttachInstructionSequence( trySequence );

            for ( int i = 0; i < wrapperMethod.Parameters.Count; i++ )
            {
                writer.EmitInstructionInt16( OpCodeNumber.Ldarg, (short) i );
            }

            this.EmitCallHandler( loggerMethod );

            this.writer.DetachInstructionSequence();

            InstructionSequence leaveSequence = tryBlock.AddInstructionSequence( null, NodePosition.After, null );
            this.writer.AttachInstructionSequence( leaveSequence );
            this.writer.EmitBranchingInstruction( OpCodeNumber.Leave, retSequence );
            this.writer.DetachInstructionSequence();

            InstructionBlock protectedBlock;
            InstructionBlock[] catchBlocks;
            InstructionBlock finallyBlock;
            this.weavingHelper.AddExceptionHandlers( this.writer, tryBlock, leaveSequence, null, true, out protectedBlock, out catchBlocks, out finallyBlock );

            InstructionSequence finallySequence = finallyBlock.AddInstructionSequence( null, NodePosition.After, null );
            this.writer.AttachInstructionSequence( finallySequence );
            this.writer.EmitInstruction( OpCodeNumber.Ldc_I4_0 );
            this.writer.EmitInstructionField( OpCodeNumber.Stsfld, this.isLoggingField );
            //this.writer.EmitInstruction(OpCodeNumber.Endfinally);
            this.writer.DetachInstructionSequence();
        }
        /// <summary>
        /// Creates token for the specified placeholder.
        /// </summary>
        /// <param name="placeholder">Placeholder to create token for.</param>
        /// <param name="target">List to appent the token to.</param>
        /// <param name="wovenMethod">Method being woven.</param>
        /// <param name="includeParamName">Indicates, whether parameter names should be included in the log.</param>
        /// <exception cref="ArgumentNullException"><paramref name="placeholder"/>, <paramref name="target"/> or <paramref name="wovenMethod"/> is <see langword="null"/>.</exception>
        /// <exception cref="FormatException"><paramref name="placeholder"/> is invalid or unrecognized placeholder.</exception>
        private static void ProcessPlaceholder(string placeholder, ICollection<IMessageToken> target,
            MethodDefDeclaration wovenMethod, bool includeParamName)
        {
            if (placeholder == null)
              {
            throw new ArgumentNullException("placeholder");
              }
              if (target == null)
              {
            throw new ArgumentNullException("target");
              }
              if (wovenMethod == null)
              {
            throw new ArgumentNullException("wovenMethod");
              }

              if (string.Equals(placeholder, signaturePlaceholder, StringComparison.InvariantCulture))
              {
            target.Add(new FixedToken(GetMethodSignature(wovenMethod)));
              }
              else if (string.Equals(placeholder, methodNamePlaceholder, StringComparison.InvariantCulture))
              {
            target.Add(new FixedToken(wovenMethod.Name));
              }
              else if (placeholder.StartsWith(parameterPrefix, StringComparison.InvariantCulture))
              {
            // Extract the name of the parameter.
            string parameterName = placeholder.Substring(parameterPrefix.Length);

            ParameterDeclaration referredParameter = null;
            foreach (ParameterDeclaration parameter in wovenMethod.Parameters)
            {
              if (string.Equals(parameter.Name, parameterName, StringComparison.InvariantCulture))
              {
            referredParameter = parameter;
            break;
              }
            }
            if (referredParameter == null)
            {
              throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Invalid parameter name: {0}.", parameterName));
            }

            target.Add(new ParameterValueToken(referredParameter));
              }
              else if (string.Equals(placeholder, shortParameterList, StringComparison.InvariantCulture))
              {
            AddParamsMessageTokens(target, wovenMethod.Parameters, includeParamName);
              }
              else if (string.Equals(placeholder, shortInParameterList, StringComparison.InvariantCulture))
              {
            AddParamsMessageTokens(target, YieldInParameters(wovenMethod), includeParamName);
              }
              else if (string.Equals(placeholder, shortOutParameterList, StringComparison.InvariantCulture))
              {
            AddParamsMessageTokens(target, YieldOutParameters(wovenMethod), includeParamName);
              }
              else if (string.Equals(placeholder, returnValue, StringComparison.InvariantCulture))
              {
            target.Add(new ReturnValueToken(wovenMethod.ReturnParameter));
              }
              else
              {
            throw new FormatException(string.Format(CultureInfo.CurrentCulture, "Unknown placeholder in template: {0}.", placeholder));
              }
        }
 public MethodDefDeclaration GetTraceStringFormatMethod()
 {
     return this.traceWriteLineWrapperMethod ??
            (this.traceWriteLineWrapperMethod = this.CreateTraceStringFormatWrapper( "TraceWriteLineFormat" ));
 }
 /// <summary>
 /// Yields all the output parameters of the given woven method.
 /// </summary>
 /// <param name="wovenMethod">A woven method.</param>
 private static IEnumerable<ParameterDeclaration> YieldOutParameters(MethodDefDeclaration wovenMethod)
 {
     foreach (ParameterDeclaration parameter in wovenMethod.Parameters)
       {
     if ((parameter.Attributes & (ParameterAttributes.Out | ParameterAttributes.Retval)) != 0 ||
     parameter.ParameterType.BelongsToClassification(TypeClassifications.Pointer))
     {
       yield return parameter;
     }
       }
 }
        private static void CustomMethodSignatureError(TypeDefDeclaration enhancedType, MethodDefDeclaration method)
        {
            string message =
                $"Method {method.Name} marked with [CustomEqualsInternal] must be public, instance, must return bool and accept 1 parameter of the same type as the declaring type {enhancedType.Name}";

            throw new InjectionException("EQU3", message);
        }