private void AddCustomLogicCall(TypeDefDeclaration enhancedType, InstructionWriter writer, MethodDefDeclaration customMethod) { var parameters = customMethod.Parameters; if (parameters.Count != 0) { Message.Write(enhancedType, SeverityType.Error, "EQU1", "The signature of a method annotated with [" + nameof(AdditionalGetHashCodeMethodAttribute) + "] must be 'int MethodName()'. It can't have parameters."); writer.EmitInstruction(OpCodeNumber.Ldc_I4_0); return; } if (!customMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Int32)) { Message.Write(enhancedType, SeverityType.Error, "EQU2", "The signature of a method annotated with [" + nameof(AdditionalGetHashCodeMethodAttribute) + "] must be 'int MethodName()'. Its return type must be 'int'."); writer.EmitInstruction(OpCodeNumber.Ldc_I4_0); return; } writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstructionMethod( enhancedType.IsValueTypeSafe() == true ? OpCodeNumber.Call : OpCodeNumber.Callvirt, customMethod.GetCanonicalGenericInstance()); }
private static void InjectCustomMethods(TypeDefDeclaration enhancedType, InstructionWriter writer, CreatedEmptyMethod methodBody) { // Custom equality methods. foreach (var customEqualsMethod in enhancedType.Methods) { if (customEqualsMethod.CustomAttributes.GetOneByType( "PostSharp.Community.StructuralEquality.AdditionalEqualsMethodAttribute") != null) { if (customEqualsMethod.IsStatic || !customEqualsMethod.ReturnParameter.ParameterType.IsIntrinsic(IntrinsicType.Boolean) || customEqualsMethod.Parameters.Count != 1 || !customEqualsMethod.Parameters[0].ParameterType.GetTypeDefinition().Equals(enhancedType) ) { CustomMethodSignatureError(enhancedType, customEqualsMethod); } writer.EmitInstruction(OpCodeNumber.Ldarg_0); writer.EmitInstruction(OpCodeNumber.Ldarg_1); writer.EmitInstructionMethod(OpCodeNumber.Call, customEqualsMethod.GetCanonicalGenericInstance()); writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, methodBody.ReturnSequence); } } }
public TypeTreeNode(TypeDefDeclaration type, string name) : base( type, GetImage(type), type.Visibility) { this.type = type; this.Text = name; this.EnableLatePopulate(); }
public InterfaceImplementationCollectionTreeNode(TypeDefDeclaration type) : base(TreeViewImage.Folder, null) { this.type = type; this.Text = "Interfaces"; this.EnableLatePopulate(); }
public InterfaceImplementationCollectionTreeNode( TypeDefDeclaration type ) : base( TreeViewImage.Folder, null ) { this.type = type; this.Text = "Interfaces"; this.EnableLatePopulate(); }
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); }
public NestedTypeFolderTreeNode(TypeDefDeclaration parentType) : base(TreeViewImage.Folder, null) { this.Text = "Nested Types"; this.parentType = parentType; this.EnableLatePopulate(); }
private void MakeSerializable(TypeDefDeclaration type) { if (!IsSerializable(type)) { type.Attributes |= TypeAttributes.Serializable; } }
public TypeTreeNode( TypeDefDeclaration type, string name ) : base( type, GetImage( type ), type.Visibility ) { this.type = type; this.Text = name; this.EnableLatePopulate(); }
public override void ProvideAspectTransformations(AspectWeaverTransformationAdder adder) { // Find the MoveNext method. TypeDefDeclaration targetType = (TypeDefDeclaration)this.aspectInstanceInfo.TargetElement; MethodDefDeclaration moveNextMethod = targetType.Methods.Single <MethodDefDeclaration>(m => m.Name.EndsWith("MoveNext")); adder.Add(moveNextMethod, this.parent.moveNextTransformation.CreateInstance(this)); }
private void AddEquatable(TypeDefDeclaration enhancedType) { var genericInstance = this.equatableInterface.GetTypeDefinition().GetGenericInstance(new GenericMap( enhancedType.Module, new ITypeSignature[] { enhancedType.GetCanonicalGenericInstance() })); ITypeSignature interfaceRef = genericInstance.TranslateType(enhancedType.Module); enhancedType.InterfaceImplementations.Add(interfaceRef); }
public void AddEqualsTo(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config, ISet <FieldDefDeclaration> ignoredFields) { var typedEqualsMethod = this.InjectEqualsType(enhancedType, config, ignoredFields); this.InjectEqualsObject(enhancedType, config, typedEqualsMethod); this.AddEquatable(enhancedType); }
private void InjectEqualsObject(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config, MethodDefDeclaration typedEqualsMethod) { var existingMethod = enhancedType.Methods.FirstOrDefault <IMethod>(declaration => { return(declaration.Name == "Equals" && declaration.IsPublic() && !declaration.IsStatic && declaration.ParameterCount == 1 && declaration.GetParameterType(0).Equals(this.objectType)); }); if (existingMethod != null) { return; } // public virtual bool Equals( object 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", this.objectType)); 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); var genericTypeInstance = enhancedType.GetCanonicalGenericInstance(); this.EmitTypeCheck(enhancedType, config, writer, genericTypeInstance, methodBody); if (enhancedType.IsValueTypeSafe() == true) { this.EmitEqualsObjectOfValueType(writer, genericTypeInstance, typedEqualsMethod, methodBody); } else { this.EmitEqualsObjectOfReferenceType(writer, genericTypeInstance, typedEqualsMethod, methodBody); } writer.DetachInstructionSequence(); } }
public void ProcessEqualityOperators(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config) { if (config.DoNotAddEqualityOperators) { return; } ProcessOperator(enhancedType, "op_Equality", "==", false); ProcessOperator(enhancedType, "op_Inequality", "!=", true); }
/// <summary> /// Adds a method to a class /// </summary> /// <param name="decl">Class to add the method to</param> /// <param name="method">Method to add</param> public static void AddMethod([NotNull] TypeDefDeclaration decl, [NotNull] MethodDefDeclaration method) { MethodDefDeclaration previous = FindSameMethod(decl, method); if (previous != null) { previous.Remove(); } decl.Methods.Add(method); }
private void VerifySerializable(TypeDefDeclaration type, MessageLocation location) { if (!IsSerializable(type)) { // This does not work properly on .NET Core. // PostSharp has difficulty understanding that some classes in .NET Core are serializable. // In addition, some fields are not meant to be serialized so it's better not to emit a warning for those // as well. // Message.Write(location, SeverityType.Warning, "DSER001", // "A type (" + type.Name + // ") is not serializable, but it's not in the same assembly so I cannot modify it."); } }
private static MethodDefDeclaration FindOnPropertyChangedMethod(TypeDefDeclaration currentType) { foreach (MethodDefDeclaration declaration in currentType.Methods) { foreach (CustomAttributeDeclaration attributeType in declaration.CustomAttributes) { if (attributeType.ConstructRuntimeObject().GetType().UnderlyingSystemType == typeof(OnPropertyChangedAttribute)) { return declaration; } } } return null; }
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); }
/// <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)); }
private void IdentifyAndMakeSerializableRecursively(ITypeSignature type, MessageLocation location) { switch (type.TypeSignatureElementKind) { case TypeSignatureElementKind.Intrinsic: // This works automatically for most, but: // Consider an error for object, IntPtr, but also consider that those fields may be marked as [NonSerialized]. // In the future, we might want to exclude such fields. break; case TypeSignatureElementKind.TypeDef: TypeDefDeclaration typeDef = (TypeDefDeclaration)type; if (typeDef.DeclaringAssembly == this.Project.Module.DeclaringAssembly) { MakeSerializableRecursively(typeDef); } else { VerifySerializable(typeDef, location); } break; case TypeSignatureElementKind.TypeRef: IdentifyAndMakeSerializableRecursively(type.GetTypeDefinition(), location); break; case TypeSignatureElementKind.GenericInstance: GenericTypeInstanceTypeSignature genericInstanceSignature = type as GenericTypeInstanceTypeSignature; IdentifyAndMakeSerializableRecursively(genericInstanceSignature.ElementType, location); foreach (ITypeSignature argument in genericInstanceSignature.GenericArguments) { IdentifyAndMakeSerializableRecursively(argument, location); } break; case TypeSignatureElementKind.Array: ArrayTypeSignature arraySignature = type as ArrayTypeSignature; IdentifyAndMakeSerializableRecursively(arraySignature.ElementType, location); break; default: // Other possible signature types can be ignored: // Pointers: they cannot be serialized // Custom modifiers: they should not be used on fields. break; } }
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 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 void ProcessOperator(TypeDefDeclaration enhancedType, string operatorName, string operatorSourceName, bool negate) { var operatorMethod = GetOperatorMethod(enhancedType, operatorName); string operatorExample = $"public static bool operator {operatorSourceName}({enhancedType.ShortName} left, {enhancedType.ShortName} right) => Operator.Weave(left, right);"; if (operatorMethod == null) { throw new InjectionException("EQU10", $"The equality operator was not found on type {enhancedType.Name}, implement it like this: {operatorExample}"); } var operatorMethodDef = operatorMethod.GetMethodDefinition(); this.CheckOperator(operatorMethodDef, operatorExample); CompilerGeneratedAttributeHelper.AddCompilerGeneratedAttribute(operatorMethodDef); this.ReplaceOperator(enhancedType, operatorMethodDef, negate); }
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 MakeSerializableRecursively(TypeDefDeclaration type) { if (examinedTypes.Contains(type)) { // We've already analyzed this type. return; } examinedTypes.Add(type); MakeSerializable(type); foreach (FieldDefDeclaration field in type.Fields) { IdentifyAndMakeSerializableRecursively(field.FieldType, field); } IdentifyAndMakeSerializableRecursively(type.BaseType, type); }
public bool Match(PostSharp.CodeModel.IType type) { try { TypeDefDeclaration definition = type.GetTypeDefinition(); if (definition == null) { return(false); } } catch (Exception exc) { // bind error, or type does not have a definition // in either case, not a type we want to process return(false); } 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); }
public static bool InheritsBase(this TypeDefDeclaration?declaration, TypeDefDeclaration baseType) { if (!baseType.IsClass()) { return(false); } if (declaration?.BaseType == null) { return(false); } if (declaration.BaseType.Name == baseType.Name) { return(true); } return(declaration.BaseTypeDef.InheritsBase(baseType)); }
public static bool ImplementsInterface(this TypeDefDeclaration?declaration, TypeDefDeclaration interfaceType) { if (!interfaceType.IsInterface()) { return(false); } if (declaration?.BaseType == null) { return(false); } if (declaration.InterfaceImplementations.Any(i => i.ImplementedInterface.Name == interfaceType.Name)) { return(true); } return(declaration.BaseTypeDef.ImplementsInterface(interfaceType)); }
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; }
public override bool Execute() { this.wrapperType = this.GetWrapperType(this.Project.Module.Assembly, new HashSet <string>()); if (this.wrapperType == null) { Message.Write(this.Project.Module.Assembly.GetSystemAssembly(), SeverityType.Error, "CUMA001", "You must create a CheckMemoryAccess class with the appropriate source code in your project."); return(false); } this.methods.Add(OpCodeNumber.Stind_I, this.wrapperType.Methods.GetOneByName("StoreIntPtr").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_I1, this.wrapperType.Methods.GetOneByName("StoreByte").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_I2, this.wrapperType.Methods.GetOneByName("StoreInt16").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_I4, this.wrapperType.Methods.GetOneByName("StoreInt32").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_I8, this.wrapperType.Methods.GetOneByName("StoreInt64").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_R4, this.wrapperType.Methods.GetOneByName("StoreSingle").Translate(this.Project.Module)); this.methods.Add(OpCodeNumber.Stind_R8, this.wrapperType.Methods.GetOneByName("StoreDouble").Translate(this.Project.Module)); Sdk.CodeWeaver.Weaver weaver = new Sdk.CodeWeaver.Weaver(this.Project); weaver.AddMethodLevelAdvice(this, null, JoinPointKinds.InsteadOfStoreIndirect, null); weaver.Weave(); return(base.Execute()); }
public TypeDefDeclaration GetWrapperType(AssemblyEnvelope assembly, HashSet <string> visitedAssemblies) { visitedAssemblies.Add(assembly.Name); TypeDefDeclaration result = assembly.GetTypeDefinition(wrapperTypeName, BindingOptions.DontThrowException); if (result != null) { return(result); } foreach (ModuleDeclaration module in assembly.Modules) { foreach (AssemblyRefDeclaration assemblyRef in module.AssemblyRefs) { if (visitedAssemblies.Contains(assemblyRef.Name)) { continue; } AssemblyEnvelope assemblyRefEnvelope = assemblyRef.GetAssemblyEnvelope(BindingOptions.DontThrowException); if (assemblyRefEnvelope == null) { continue; } result = this.GetWrapperType(assemblyRefEnvelope, visitedAssemblies); if (result != null) { return(result); } } } return(null); }
public EqualsInjection(Project project) { this.objectType = project.Module.Cache.GetIntrinsic(IntrinsicType.Object); this.booleanType = project.Module.Cache.GetIntrinsic(IntrinsicType.Boolean); this.objectTypeDef = this.objectType.GetTypeDefinition(); this.referenceEqualsMethod = project.Module.FindMethod(objectTypeDef, "ReferenceEquals"); this.instanceEqualsMethod = project.Module.FindMethod(objectTypeDef, "Equals", 1); this.staticEqualsMethod = project.Module.FindMethod(objectTypeDef, "Equals", 2); this.getTypeMethod = project.Module.FindMethod(objectTypeDef, "GetType"); var collectionHelperTypeDef = project.Module.Cache.GetType(typeof(CollectionHelper)).GetTypeDefinition(); this.collectionEqualsMethod = project.Module.FindMethod(collectionHelperTypeDef, "Equals", declaration => declaration.IsStatic); var typeTypeDef = project.Module.Cache.GetType(typeof(Type)).GetTypeDefinition(); this.getTypeFromHandleMethod = project.Module.FindMethod(typeTypeDef, "GetTypeFromHandle"); this.equatableInterface = project.Module.Cache.GetType(typeof(IEquatable <>)); }
private static TreeViewImage GetImage( TypeDefDeclaration type ) { if ( type.BelongsToClassification( TypeClassifications.Class ) ) { return TreeViewImage.Class; } else if ( type.BelongsToClassification( TypeClassifications.Interface ) ) { return TreeViewImage.Interface; } else if ( type.BelongsToClassification( TypeClassifications.Struct ) ) { return TreeViewImage.Struct; } else if ( type.BelongsToClassification( TypeClassifications.Enum ) ) { return TreeViewImage.Enum; } else { return TreeViewImage.Class; } }
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 static TreeViewImage GetImage(TypeDefDeclaration type) { if (type.BelongsToClassification(TypeClassifications.Class)) { return(TreeViewImage.Class); } else if (type.BelongsToClassification(TypeClassifications.Interface)) { return(TreeViewImage.Interface); } else if (type.BelongsToClassification(TypeClassifications.Struct)) { return(TreeViewImage.Struct); } else if (type.BelongsToClassification(TypeClassifications.Enum)) { return(TreeViewImage.Enum); } else { return(TreeViewImage.Class); } }
private void EmitTypeCheck(TypeDefDeclaration enhancedType, StructuralEqualityAttribute config, InstructionWriter writer, IType genericTypeInstance, CreatedEmptyMethod methodBody) { switch (config.TypeCheck) { case TypeCheck.ExactlyTheSameTypeAsThis: this.InjectExactlyTheSameTypeAsThis(writer, enhancedType, genericTypeInstance); break; case TypeCheck.ExactlyOfType: this.InjectExactlyOfType(writer, genericTypeInstance); break; case TypeCheck.SameTypeOrSubtype: this.InjectSameTypeOrSubtype(writer, genericTypeInstance); break; default: throw new InjectionException("EQU4", $"Unknown TypeCheck value: {config.TypeCheck}"); } // Types are different, return false. writer.EmitBranchingInstruction(OpCodeNumber.Brfalse, methodBody.ReturnSequence); }
public LoggingImplementationTypeBuilder(ModuleDeclaration module) { this.module = module; this.weavingHelper = new WeavingHelper(module); this.containingType = this.CreateContainingType(); }
private static TypeDefDeclaration GetTypeDeclarationOfBase(TypeDefDeclaration type) { if(type.BaseType == null) return null; TypeDefDeclaration baseTypeDefDeclaration = type.BaseType as TypeDefDeclaration; if (baseTypeDefDeclaration == null) { TypeRefDeclaration baseAsTypeRefDeclaration = type.BaseType as TypeRefDeclaration; if (baseAsTypeRefDeclaration != null) { baseTypeDefDeclaration = baseAsTypeRefDeclaration.GetTypeDefinition(); } else { TypeSpecDeclaration baseAsTypeSpecDeclaration = type.BaseType as TypeSpecDeclaration; baseTypeDefDeclaration = baseAsTypeSpecDeclaration.GetTypeDefinition(); } } return baseTypeDefDeclaration; }
internal PerTypeLoggingData GetPerTypeLoggingData(TypeDefDeclaration type) { return this.perTypeLoggingDatas[type]; }
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)); }
private static PropertyDeclaration CreateProperty(TypeDefDeclaration type, string name, ITypeSignature propertyType, IEnumerable<CustomAttributeDeclaration> attributesList) { var property = new PropertyDeclaration { Name = name, PropertyType = propertyType, CallingConvention = CallingConvention.HasThis, }; type.Properties.Add(property); ImplementAttributes(property, attributesList); return property; }
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 void AddTypeLogginData(TypeDefDeclaration wovenType) { this.perTypeLoggingDatas.Add(wovenType, new PerTypeLoggingData()); // Logging data for the woven type. PerTypeLoggingData perTypeLoggingData = this.perTypeLoggingDatas[wovenType]; // Field where ILog instance is stored. FieldDefDeclaration logField = CreateField("~log4PostSharp~log", this.ilogType); wovenType.Fields.Add(logField); perTypeLoggingData.Log = logField; }
/// <summary> /// Determines whether a type is annotated with the <b>DataContract</b> /// custom attribute. /// </summary> /// <param name="typeDef">Type.</param> /// <returns><b>true</b> if <paramref name="typeDef"/> is annotated with the <b>DataContract</b> /// custom attribute, otherwise <b>false</b>.</returns> private static bool ContainsDataContractAttribute( TypeDefDeclaration typeDef ) { foreach ( CustomAttributeDeclaration customAttribute in typeDef.CustomAttributes ) { if ( ((INamedType) customAttribute.Constructor.DeclaringType).Name == dataContractTypeName ) return true; } return false; }
public NestedTypeFolderTreeNode( TypeDefDeclaration parentType ) : base( TreeViewImage.Folder, null ) { this.Text = "Nested Types"; this.parentType = parentType; this.EnableLatePopulate(); }
public SingletonAccessorAdvice(TypeDefDeclaration typeDef) { m_type = typeDef; }
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); }