private static FieldDefDeclaration GetNonGenericLoggerField(WeavingContext context, bool create) { var type = context.Method.DeclaringType; foreach(var currentField in type.Fields) { if(currentField.Name == loggerFieldName) { return currentField; } } if(create) { FieldDefDeclaration field = new FieldDefDeclaration(); field.Name = loggerFieldName; field.FieldType = type.Module.FindType(typeof(ILog), BindingOptions.Default); field.Attributes = FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly; type.Fields.Add(field); return field; } else { return null; } }
/// <summary> /// Gets the set of all fields that should not participate in Equals and GetHashCode generated because they're /// the target of [IgnoreDuringEquals]. /// </summary> public static ISet <FieldDefDeclaration> GetIgnoredFields(IAnnotationRepositoryService annotations, ICompilerAdapterService compilerAdapterService) { HashSet <FieldDefDeclaration> fields = new HashSet <FieldDefDeclaration>(); IEnumerator <IAnnotationInstance> ignoredFieldsAnnotations = annotations.GetAnnotationsOfType(typeof(IgnoreDuringEqualsAttribute), false, false); while (ignoredFieldsAnnotations.MoveNext()) { IAnnotationInstance annotationInstance = ignoredFieldsAnnotations.Current; MetadataDeclaration targetElement = annotationInstance.TargetElement; if (targetElement is FieldDefDeclaration field) { fields.Add(field); } else if (targetElement is PropertyDeclaration propertyDeclaration) { FieldDefDeclaration backingField = compilerAdapterService.GetBackingField(propertyDeclaration); if (backingField != null) { fields.Add(backingField); } else { // The property is not an automatic property. // It's ignored, because there is no backing field and we make equality by fields. // We could emit a warning but I don't think that's a great idea. Like, yeah, ignoring a // non-automatic property has no effect but so what: it's ignored, just like the user wanted. } } } return(fields); }
private void AddFieldCode(FieldDefDeclaration field, bool isFirst, InstructionWriter writer, LocalVariableSymbol resultVariable, MethodDefDeclaration method, TypeDefDeclaration enhancedType) { bool isCollection; var propType = field.FieldType; bool isValueType = propType.IsValueTypeSafe() == true; bool isGenericParameter = false; if (propType.TypeSignatureElementKind == TypeSignatureElementKind.GenericParameter || propType.TypeSignatureElementKind == TypeSignatureElementKind.GenericParameterReference) { // TODO what does this mean? // maybe something else also needs to be checked? isCollection = false; isGenericParameter = true; } else { isCollection = propType.IsCollection() || propType.TypeSignatureElementKind == TypeSignatureElementKind.Array; } AddMultiplicityByMagicNumber(isFirst, writer, resultVariable, isCollection); if (propType.GetReflectionName().StartsWith("System.Nullable")) { AddNullableProperty(field, writer); } else if (isCollection && propType.GetReflectionName() != "System.String") { AddCollectionCode(field, writer, resultVariable, method, enhancedType); } else if (isValueType || isGenericParameter) { LoadVariable(field, writer); if (propType.GetReflectionName() != "System.Int32") { writer.EmitInstructionType(OpCodeNumber.Box, propType); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode); } } else { LoadVariable(field, writer); AddNormalCode(field, writer, enhancedType); } if (!isFirst && !isCollection) { writer.EmitInstruction(OpCodeNumber.Xor); } if (!isCollection) { writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, resultVariable); } }
public NLogCategoryBuilder(NLogBackend parent, string categoryName) { this.parent = parent; this.loggerField = this.parent.loggingImplementation.GetCategoryField(categoryName, this.parent.loggerType, writer => { writer.EmitInstructionString(OpCodeNumber.Ldstr, categoryName); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.categoryInitializerMethod); }); }
private void AddNormalCode(FieldDefDeclaration field, InstructionWriter writer, TypeDefDeclaration enhancedType) { writer.IfNotZero( thenw => { LoadVariable(field, thenw); thenw.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode); }, elsew => { elsew.EmitInstruction(OpCodeNumber.Ldc_I4_0); }); }
void AddGetEnumerator(InstructionWriter ins, LocalVariableSymbol variable, FieldDefDeclaration field) { if (field.FieldType.IsValueTypeSafe() == true) { ins.EmitInstructionType(OpCodeNumber.Box, field.FieldType); } ins.EmitInstructionMethod(OpCodeNumber.Callvirt, GetEnumerator); ins.EmitInstructionLocalVariable(OpCodeNumber.Stloc, variable); }
private void EmitEqualsField(InstructionWriter writer, CreatedEmptyMethod methodBody, FieldDefDeclaration field) { ITypeSignature fieldType = field.FieldType; if ((fieldType.GetNakedType() is IntrinsicTypeSignature sig && sig.IntrinsicType != IntrinsicType.Object && sig.IntrinsicType != IntrinsicType.String ) || fieldType.IsEnum()) { this.EmitSimpleValueCheck(writer, methodBody, field); }
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 void AddCollectionCode(FieldDefDeclaration field, InstructionWriter writer, LocalVariableSymbol resultVariable, MethodDefDeclaration method, TypeDefDeclaration enhancedType) { if (field.FieldType.IsValueTypeSafe() == true) { AddCollectionCodeInternal(field, resultVariable, method, enhancedType, writer); } else { LoadVariable(field, writer); writer.IfNotZero( thenw => { AddCollectionCodeInternal(field, resultVariable, method, enhancedType, thenw); }, elsew => { }); } }
private FieldDefDeclaration CreateIsLoggingField() { FieldDefDeclaration isLoggingFieldDef = new FieldDefDeclaration { Name = "isLogging", Attributes = FieldAttributes.Private | FieldAttributes.Static, FieldType = this.module.Cache.GetType(typeof(bool)) }; this.implementationType.Fields.Add(isLoggingFieldDef); isLoggingFieldDef.CustomAttributes.Add(this.CreateThreadStaticAttribute()); return(isLoggingFieldDef); }
private static TreeViewImage GetImageKind( FieldDefDeclaration field ) { if ( ( field.Attributes & FieldAttributes.Literal ) != 0 ) { if ( field.DeclaringType.BelongsToClassification( TypeClassifications.Enum ) ) { return TreeViewImage.EnumValue; } else { return TreeViewImage.Const; } } else { return TreeViewImage.Field; } }
private static TreeViewImage GetImageKind(FieldDefDeclaration field) { if ((field.Attributes & FieldAttributes.Literal) != 0) { if (field.DeclaringType.BelongsToClassification(TypeClassifications.Enum)) { return(TreeViewImage.EnumValue); } else { return(TreeViewImage.Const); } } else { return(TreeViewImage.Field); } }
public LoggingImplementationTypeBuilder(ModuleDeclaration module) { this.module = module; this.categoryFields = new Dictionary <string, FieldDefDeclaration>(); this.wrapperMethods = new Dictionary <IMethod, MethodDefDeclaration>(); this.stringFormatArrayMethod = module.FindMethod(module.Cache.GetIntrinsic(IntrinsicType.String), "Format", method => method.Parameters.Count == 2 && IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String) && method.Parameters[1].ParameterType.BelongsToClassification(TypeClassifications.Array)); this.traceWriteLineMethod = module.FindMethod(module.Cache.GetType(typeof(System.Diagnostics.Trace)), "WriteLine", method => method.Parameters.Count == 1 && IntrinsicTypeSignature.Is(method.Parameters[0].ParameterType, IntrinsicType.String)); this.weavingHelper = new WeavingHelper(module); this.implementationType = this.CreateContainingType(); this.isLoggingField = this.CreateIsLoggingField(); }
public LoggingImplementationTypeBuilder( ModuleDeclaration module ) { this.module = module; this.categoryFields = new Dictionary<string, FieldDefDeclaration>(); this.wrapperMethods = new Dictionary<IMethod, MethodDefDeclaration>(); this.stringFormatArrayMethod = module.FindMethod( module.Cache.GetIntrinsic( IntrinsicType.String ), "Format", method => method.Parameters.Count == 2 && IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) && method.Parameters[1].ParameterType.BelongsToClassification( TypeClassifications.Array ) ); this.traceWriteLineMethod = module.FindMethod( module.Cache.GetType( typeof(System.Diagnostics.Trace) ), "WriteLine", method => method.Parameters.Count == 1 && IntrinsicTypeSignature.Is( method.Parameters[0].ParameterType, IntrinsicType.String ) ); this.weavingHelper = new WeavingHelper( module ); this.implementationType = this.CreateContainingType(); this.isLoggingField = this.CreateIsLoggingField(); }
private void AddNullableProperty(FieldDefDeclaration field, InstructionWriter writer) { IMethodSignature getHasValue = new MethodSignature(field.Module, CallingConvention.HasThis, field.Module.Cache.GetIntrinsic(IntrinsicType.Boolean), new List <ITypeSignature>(), 0); var hasValueMethod = field.FieldType.FindMethod("get_HasValue", getHasValue); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldflda, field.GetCanonicalGenericInstance()); writer.EmitInstructionMethod(OpCodeNumber.Call, hasValueMethod.GetInstance(field.Module, hasValueMethod.GenericMap)); writer.IfNotZero((then) => { writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, field.GetCanonicalGenericInstance()); writer.EmitInstructionType(OpCodeNumber.Box, field.FieldType); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, Object_GetHashCode); }, (elseBranch) => { writer.EmitInstruction(OpCodeNumber.Ldc_I4_0); }); }
private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action<InstructionWriter> initializeFieldAction) { string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1); FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration { Name = fieldName, Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly, FieldType = fieldType }; this.containingType.Fields.Add(loggerFieldDef); InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null, NodePosition.Before, this.returnSequence); this.writer.AttachInstructionSequence(sequence); initializeFieldAction(this.writer); this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef); this.writer.DetachInstructionSequence(); return loggerFieldDef; }
protected void IntroduceEvent(TransformationContext context, TypeDefDeclaration type, EventDeclaration theEvent) { var fieldRef = type.FindField(theEvent.Name); FieldDefDeclaration field; if(fieldRef == null) { field = new FieldDefDeclaration { Attributes = FieldAttributes.Private, Name = theEvent.Name, FieldType = theEvent.EventType, }; type.Fields.Add(field); } else { field = fieldRef.Field; } var addOn = theEvent.GetAccessor(MethodSemantics.AddOn); if (addOn == null) { theEvent.ImplementAddOn(type, field, AspectInfrastructureTask.WeavingHelper); } var removeOn = theEvent.GetAccessor(MethodSemantics.RemoveOn); if (removeOn == null) { theEvent.ImplementRemoveOn(type, field, AspectInfrastructureTask.WeavingHelper); } }
private FieldDefDeclaration CreateCategoryField(ITypeSignature fieldType, Action <InstructionWriter> initializeFieldAction) { string fieldName = string.Format("l{0}", this.containingType.Fields.Count + 1); FieldDefDeclaration loggerFieldDef = new FieldDefDeclaration { Name = fieldName, Attributes = FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.InitOnly, FieldType = fieldType }; this.containingType.Fields.Add(loggerFieldDef); InstructionSequence sequence = this.constructorBlock.AddInstructionSequence(null, NodePosition.Before, this.returnSequence); this.writer.AttachInstructionSequence(sequence); initializeFieldAction(this.writer); this.writer.EmitInstructionField(OpCodeNumber.Stsfld, loggerFieldDef); this.writer.DetachInstructionSequence(); return(loggerFieldDef); }
/// <summary> /// Emits the MSIL that calls the logging method with the specified message and exception. /// </summary> /// <param name="emitter">IL emitter.</param> /// <param name="log">Field that stores reference to the logger.</param> /// <param name="method">Logging method to use. The method must return no value and must take 2 parameters of types <see cref="string"/> and <see cref="Exception"/>.</param> /// <param name="message">Message to log.</param> /// <param name="exception">Local variable where reference to the exception is stored.</param> /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="method"/>, <paramref name="message"/> or <paramref name="exception"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack /// and it leaves the stack unmodified.</para> /// </remarks> private static void EmitLogStringException(InstructionWriter emitter, FieldDefDeclaration log, IMethod method, string message, LocalVariableSymbol exception) { if (emitter == null) { throw new ArgumentNullException("emitter"); } if (log == null) { throw new ArgumentNullException("log"); } if (method == null) { throw new ArgumentNullException("method"); } if (message == null) { throw new ArgumentNullException("message"); } if (exception == null) { throw new ArgumentNullException("exception"); } emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(log)); emitter.EmitInstructionString(OpCodeNumber.Ldstr, message); emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc_S, exception); emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method); }
/// <summary> /// Emits the MSIL that calls the logging method with the specified format provider, message and arguments. /// </summary> /// <param name="emitter">IL emitter.</param> /// <param name="log">Field that stores reference to the logger.</param> /// <param name="method">Logging method to use. The method must return no value and must take 3 arguments of types <see cref="IFormatProvider"/>, <see cref="string"/> and <see cref="Array"/> of <see cref="object"/>s.</param> /// <param name="formatProviderGetter">Getter of the property that returns the <see cref="IFormatProvider"/> instance.</param> /// <param name="formatString">Format string for the log.</param> /// <param name="args">Variable storing reference to array of arguments for placeholders used in the format string.</param> /// <exception cref="ArgumentNullException"><paramref name="emitter"/>, <paramref name="log"/>, <paramref name="formatProviderGetter"/>, <paramref name="formatString"/> or <paramref name="args"/> is <see langword="null"/>.</exception> /// <remarks> /// <para>Code emitted by this method makes no assumptions on the state of the evaluation stack /// and it leaves the stack unmodified.</para> /// </remarks> private static void EmitLogProviderStringArgs(InstructionWriter emitter, FieldDefDeclaration log, IMethod method, IMethod formatProviderGetter, string formatString, LocalVariableSymbol args) { if (emitter == null) { throw new ArgumentNullException("emitter"); } if (log == null) { throw new ArgumentNullException("log"); } if (method == null) { throw new ArgumentNullException("method"); } if (formatProviderGetter == null) { throw new ArgumentNullException("formatProviderGetter"); } if (args == null) { throw new ArgumentNullException("args"); } emitter.EmitInstructionField(OpCodeNumber.Ldsfld, GenericHelper.GetCanonicalGenericInstance(log)); emitter.EmitInstructionMethod(OpCodeNumber.Call, formatProviderGetter); emitter.EmitInstructionString(OpCodeNumber.Ldstr, formatString); emitter.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, args); emitter.EmitInstructionMethod(OpCodeNumber.Callvirt, method); }
public Log4NetCategoryBuilder(Log4NetBackend parent, string categoryName) { this.parent = parent; this.loggerField = this.parent.loggingImplementation.GetCategoryField(categoryName, this.parent.loggerType, writer => { writer.EmitInstructionString(OpCodeNumber.Ldstr, categoryName); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.categoryInitializerMethod); }); }
public void Weave(WeavingContext context, PostSharp.CodeModel.InstructionBlock block) { TypeDefDeclaration typeDef = m_type; // Declare the static field FieldDefDeclaration fieldDef = new FieldDefDeclaration(); fieldDef.Attributes = FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.NotSerialized | FieldAttributes.InitOnly; fieldDef.Name = "s_instance"; fieldDef.FieldType = typeDef; typeDef.Fields.Add(fieldDef); // Declare the static accessor. PropertyDeclaration propDef = new PropertyDeclaration(); propDef.Name = "Instance"; typeDef.Properties.Add(propDef); MethodSemanticDeclaration sematic = new MethodSemanticDeclaration(); sematic.Semantic = MethodSemantics.Getter; MethodDefDeclaration methodDef = new MethodDefDeclaration(); methodDef.Name = "get_Instance"; methodDef.Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.SpecialName; methodDef.CallingConvention = CallingConvention.Default; typeDef.Methods.Add(methodDef); ParameterDeclaration retVal = new ParameterDeclaration(); retVal.ParameterType = typeDef; retVal.Attributes = ParameterAttributes.Retval; methodDef.ReturnParameter = retVal; sematic.Method = methodDef; propDef.Members.Add(sematic); propDef.PropertyType = typeDef; methodDef.MethodBody = new MethodBodyDeclaration(); methodDef.MethodBody.MaxStack = 1; methodDef.MethodBody.RootInstructionBlock = methodDef.MethodBody.CreateInstructionBlock(); //throw new NotFiniteNumberException(); InstructionSequence sequence = methodDef.MethodBody.CreateInstructionSequence(); methodDef.MethodBody.RootInstructionBlock.AddInstructionSequence(sequence, NodePosition.After , null); context.InstructionWriter.AttachInstructionSequence(sequence); context.InstructionWriter.EmitInstructionField(OpCodeNumber.Ldsfld, typeDef.Fields.GetByName("s_instance")); context.InstructionWriter.EmitInstruction(OpCodeNumber.Ret); context.InstructionWriter.DetachInstructionSequence(); // code for the static constructor sequence = context.Method.MethodBody.CreateInstructionSequence(); block.AddInstructionSequence(sequence, NodePosition.Before, null); context.InstructionWriter.AttachInstructionSequence(sequence); context.InstructionWriter.EmitInstructionMethod(OpCodeNumber.Newobj, typeDef.Methods.GetOneByName(".ctor")); context.InstructionWriter.EmitInstructionField(OpCodeNumber.Stsfld, typeDef.Fields.GetByName("s_instance")); context.InstructionWriter.DetachInstructionSequence(); // Change visibility to the constructor typeDef.Methods.GetOneByName(".ctor").Attributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; }
private static IField CreateBackingField( TypeDefDeclaration type, string name, ITypeSignature fieldType, CustomAttributeDeclaration compilerGenerated) { var field = new FieldDefDeclaration { Attributes = FieldAttributes.Private, Name = string.Format("<{0}>k__BackingField", name), FieldType = fieldType }; // Create a backing field type.Fields.Add(field); MarkCompilerGenerated(field, compilerGenerated); return GenericHelper.GetCanonicalGenericInstance(field); }
/// <summary> /// Creates a private static readonly field. /// </summary> /// <param name="name">Name of the field.</param> /// <param name="type">Type of the field.</param> /// <returns>Private static readonly field of the specified type.</returns> /// <exception cref="ArgumentNullException"><paramref name="name"/> or <paramref name="type"/> is <see langword="null"/>.</exception> private static FieldDefDeclaration CreateField(string name, ITypeSignature type) { if (name == null) { throw new ArgumentNullException("name"); } if (type == null) { throw new ArgumentNullException("type"); } FieldDefDeclaration field = new FieldDefDeclaration(); field.Attributes = FieldAttributes.InitOnly | FieldAttributes.Private | FieldAttributes.Static; field.Name = name; field.FieldType = type; return field; }
public FieldTreeNode(FieldDefDeclaration field) : base(field, GetImageKind(field), field.Visibility) { this.Text = field.Name + " : " + field.FieldType.ToString(); }
/// <summary> /// Validates the usage of the attribute on a specific property. /// </summary> /// <param name="setter">The setter method of the property.</param> /// <param name="propertyType">Type of the property.</param> /// <param name="propertyName">Name of the property.</param> protected override void CompileTimeValidateSetter(MethodBase setter, Type propertyType, string propertyName) { //bool isControl = false; //Type baseType = setter.DeclaringType; //while (baseType != null) //{ // if (baseType.FullName == "System.Web.UI.Control") // { // isControl = true; // break; // } // baseType = baseType.BaseType; //} //if (!isControl) //{ // MessageSource.MessageSink.Write(new Message( // SeverityType.Error, // "ViewStateVariableAttribute_PropertyDoesNotBelongToControl", // string.Format(CultureInfo.InvariantCulture, "The property '{0}' does not belong to a System.Web.UI.Control.", propertyName), // GetType().FullName // )); //} if(setter.IsStatic) { MessageSource.MessageSink.Write(new Message( SeverityType.Error, "ViewStateVariableAttribute_PropertyCannotBeStatic", string.Format(CultureInfo.InvariantCulture, "The property '{0}' must not be static.", propertyName), GetType().FullName )); } SetFieldName(propertyName); MethodDefDeclaration postsharpMethod = ((IReflectionWrapper<MethodDefDeclaration>)setter).WrappedObject; FieldDefDeclaration propertyField = new FieldDefDeclaration(); propertyField.Name = fieldName; if(propertyType.IsGenericType) { propertyField.FieldType = postsharpMethod.Module.FindType(propertyType, BindingOptions.RequireGenericInstance); } else { propertyField.FieldType = postsharpMethod.Module.FindType(propertyType, BindingOptions.Default); } propertyField.Attributes = FieldAttributes.Private; postsharpMethod.DeclaringType.Fields.Add(propertyField); }
public override void Implement(MethodBodyTransformationContext context) { /* We want to generate the following * if ( !this.<>4__this.Dispatcher.CheckAccess() ) * { * SynchronizationContext oldContext = SynchronizationContext.Current; * SynchronizationContext.SetSynchronizationContext( this.<>4__this.Dispatcher.SynchronizationContext ); * this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter(); * this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref this.<>t__dispatchAwaiter, ref this); * SynchronizationContext.SetSynchronizationContext( oldContext ); * return; * } * */ MethodDefDeclaration targetMethod = (MethodDefDeclaration)context.TargetElement; TypeDefDeclaration targetType = targetMethod.DeclaringType; targetMethod.MethodBody.MaxStack = -1; // Add the field where we will store the awaiter. FieldDefDeclaration awaiterFieldDef = new FieldDefDeclaration { Name = "<>t__dispatchAwaiter", FieldType = this.parent.yieldAwaiter_Type, Attributes = FieldAttributes.Private }; targetType.Fields.Add(awaiterFieldDef); IField awaiterField = awaiterFieldDef.GetCanonicalGenericInstance(); // Find other fields. IField thisField = targetType.Fields.Single <FieldDefDeclaration>(f => f.Name.EndsWith("__this")).GetCanonicalGenericInstance(); IField builderField = targetType.Fields.GetByName("<>t__builder").GetCanonicalGenericInstance(); // Emit instructions. InstructionBlock myBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null); InstructionBlock theirBlock = context.InstructionBlock.AddChildBlock(null, NodePosition.After, null); LocalVariableSymbol awaitableLocal = myBlock.DefineLocalVariable(this.parent.task_Yield_Method.ReturnType, "awaitable"); LocalVariableSymbol synchronizationContextLocal = myBlock.DefineLocalVariable(this.parent.synchronizationContext_Type, "oldContext"); InstructionSequence entrySequence = myBlock.AddInstructionSequence(null, NodePosition.After, null); InstructionSequence exitSequence = myBlock.AddInstructionSequence(null, NodePosition.After, null); InstructionWriter writer = new InstructionWriter(); writer.AttachInstructionSequence(entrySequence); // Emit: if ( this.<>4__this.Dispatcher.CheckAccess() ) goto exitSequence; writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_CheckAccess_Method); writer.EmitBranchingInstruction(OpCodeNumber.Brtrue, exitSequence); // Emit: this.<>t__dispatchAwaiter = Task.Yield().GetAwaiter() writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.task_Yield_Method); writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, awaitableLocal); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloca, awaitableLocal); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.yieldAwaitable_GetAwaiter_Method); writer.EmitInstructionField(OpCodeNumber.Stfld, awaiterField); // Emit: oldContext = SynchronizationContext.Current writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_getCurrent_Method); writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, synchronizationContextLocal); // Emit: SynchronizationContext.SetSynchronizationContext(this.<>4__this.Dispatcher.SynchronizationContext) writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, thisField); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.actor_GetDispatcher_Method); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, this.parent.dispatcher_getSynchronizationContext_Method); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method); // Choose which AwaitUnsafeOnCompleted method to call. IGenericMethodDefinition awaitUnsafeOnCompletedMethod; ITypeSignature[] awaitUnsafeOnCompletedGenericTypeParameters; if (builderField.FieldType == this.parent.asyncVoidMethodBuilder_Type) { awaitUnsafeOnCompletedMethod = this.parent.asyncVoidMethodBuilder_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = null; } else if (builderField.FieldType == this.parent.asyncTaskMethodBuilder_Type) { awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilder_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = null; } else { // This is a generic task. awaitUnsafeOnCompletedMethod = this.parent.asyncTaskMethodBuilderGeneric_AwaitUnsafeOnCompleted_Method; awaitUnsafeOnCompletedGenericTypeParameters = builderField.FieldType.GetGenericContext(GenericContextOptions.None).GetGenericTypeParameters(); } IMethod awaitUnsafeOnCompletedGenericMethod = awaitUnsafeOnCompletedMethod.GetGenericInstance(new GenericMap(awaitUnsafeOnCompletedGenericTypeParameters, new ITypeSignature[] { this.parent.yieldAwaiter_Type, targetType.GetCanonicalGenericInstance() })); // Emit: this.<>t__builder.AwaitUnsafeOnCompleted<YieldAwaitable.YieldAwaiter, Player.<Ping>d__2>(ref this.<>t__dispatchAwaiter, ref this); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldflda, builderField); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldflda, awaiterField); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod(OpCodeNumber.Call, awaitUnsafeOnCompletedGenericMethod); // Emit: SynchronizationContext.SetSynchronizationContext( oldContext ); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, synchronizationContextLocal); writer.EmitInstructionMethod(OpCodeNumber.Call, this.parent.synchronizationContext_SetSynchronizationContext_Method); writer.EmitBranchingInstruction(OpCodeNumber.Leave, context.LeaveBranchTarget); writer.DetachInstructionSequence(); // We are done. Give the pipeline to the next node. context.AddRedirection(theirBlock, context.LeaveBranchTarget); }
private FieldDefDeclaration CreateIsLoggingField() { FieldDefDeclaration isLoggingFieldDef = new FieldDefDeclaration { Name = "isLogging", Attributes = FieldAttributes.Private | FieldAttributes.Static, FieldType = this.module.Cache.GetType( typeof(bool) ) }; this.implementationType.Fields.Add( isLoggingFieldDef ); isLoggingFieldDef.CustomAttributes.Add( this.CreateThreadStaticAttribute() ); return isLoggingFieldDef; }
private void LoadVariable(FieldDefDeclaration field, InstructionWriter writer) { writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, field.GetCanonicalGenericInstance()); }
public override void Implement(TransformationContext context) { ModuleDeclaration module = this.AspectWeaver.Module; TypeDefDeclaration typeDef = (TypeDefDeclaration)context.TargetElement; // Declare the method. MethodDefDeclaration methodDef = new MethodDefDeclaration { Name = "AutoGeneratedValidate", Attributes = (MethodAttributes.Family | MethodAttributes.ReuseSlot | MethodAttributes.Virtual), CallingConvention = CallingConvention.HasThis }; typeDef.Methods.Add(methodDef); methodDef.CustomAttributes.Add(this.AspectWeaver.AspectInfrastructureTask.WeavingHelper.GetDebuggerNonUserCodeAttribute()); // Define parameter. methodDef.ReturnParameter = new ParameterDeclaration { ParameterType = module.Cache.GetIntrinsic(IntrinsicType.Void), Attributes = ParameterAttributes.Retval }; // Define the body MethodBodyDeclaration methodBody = new MethodBodyDeclaration(); methodDef.MethodBody = methodBody; InstructionBlock instructionBlock = methodBody.CreateInstructionBlock(); methodBody.RootInstructionBlock = instructionBlock; InstructionSequence sequence = methodBody.CreateInstructionSequence(); instructionBlock.AddInstructionSequence(sequence, NodePosition.After, null); using (InstructionWriter writer = new InstructionWriter()) { writer.AttachInstructionSequence(sequence); // Find the base method. IMethod baseValidateMethod = null; IType baseTypeCursor = typeDef.BaseType; MethodSignature methodSignature = new MethodSignature(module, CallingConvention.HasThis, module.Cache.GetIntrinsic(IntrinsicType.Void), new ITypeSignature[0], 0); while (baseValidateMethod == null) { TypeDefDeclaration baseTypeCursorTypeDef = baseTypeCursor.GetTypeDefinition(); baseValidateMethod = baseTypeCursorTypeDef.Methods.GetMethod("AutoGeneratedValidate", methodSignature.Translate(baseTypeCursorTypeDef.Module), BindingOptions.OnlyExisting | BindingOptions.DontThrowException); baseTypeCursor = baseTypeCursorTypeDef.BaseType; } // TODO: support generic base types. // Call the base method. writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod(OpCodeNumber.Call, (IMethod)baseValidateMethod.Translate(typeDef.Module)); // Make an array with the boxed field values. TypeValidationAspect aspect = (TypeValidationAspect)this.AspectWeaverInstance.Aspect; LocalVariableSymbol fieldValuesArrayLocal = instructionBlock.DefineLocalVariable( module.Cache.GetType(typeof(object[])), "fieldValues"); writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, aspect.Validators.Count); writer.EmitInstructionType(OpCodeNumber.Newarr, module.Cache.GetIntrinsic(IntrinsicType.Object)); writer.EmitInstructionLocalVariable(OpCodeNumber.Stloc, fieldValuesArrayLocal); int i = 0; foreach (FieldValidationAttribute validator in aspect.Validators) { FieldDefDeclaration fieldDef = typeDef.Fields.GetByName(validator.TargetLocation.Name); IField fieldSpec = GenericHelper.GetFieldCanonicalGenericInstance(fieldDef); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal); writer.EmitInstructionInt32(OpCodeNumber.Ldc_I4, i); writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionField(OpCodeNumber.Ldfld, fieldSpec); writer.EmitConvertToObject(fieldSpec.FieldType); writer.EmitInstruction(OpCodeNumber.Stelem_Ref); i++; } // Get the validator method. IMethod validateMethod = module.Cache.GetItem( () => module.FindMethod( typeof(TypeValidationAspect).GetMethod("Validate"), BindingOptions.Default)); // Call the validator. this.AspectWeaverInstance.AspectRuntimeInstanceField.EmitLoadField(writer, null); writer.EmitInstructionLocalVariable(OpCodeNumber.Ldloc, fieldValuesArrayLocal); writer.EmitInstructionMethod(OpCodeNumber.Callvirt, validateMethod); writer.EmitInstruction(OpCodeNumber.Ret); writer.DetachInstructionSequence(); } }
public FieldTreeNode( FieldDefDeclaration field ) : base( field, GetImageKind( field ), field.Visibility ) { this.Text = field.Name + " : " + field.FieldType.ToString(); }