public static int CompareToCustomAttribute(this CustomAttribute first, CustomAttribute second, bool fullNameCheck = false) { if (first.AttributeType.Name != second.AttributeType.Name) { if (fullNameCheck) { return first.AttributeType.FullName.CompareTo(second.AttributeType.FullName); } return first.AttributeType.Name.CompareTo(second.AttributeType.Name); } if (first == second) { return 0; } int returnValue = CompareConstructorArguments(first, second); if(returnValue != 0) { return returnValue; } returnValue = CompareConstructorFields(first, second); if (returnValue != 0) { return returnValue; } returnValue = CompareConstructorProperties(first, second); if (returnValue != 0) { return returnValue; } return 0; }
/// <summary> /// Generates a proxy that forwards all virtual method calls /// to a single <see cref="IInterceptor"/> instance. /// </summary> /// <param name="originalBaseType">The base class of the type being constructed.</param> /// <param name="baseInterfaces">The list of interfaces that the new type must implement.</param> /// <param name="module">The module that will hold the brand new type.</param> /// <param name="targetType">The <see cref="TypeDefinition"/> that represents the type to be created.</param> public override void Construct(Type originalBaseType, IEnumerable<Type> baseInterfaces, ModuleDefinition module, TypeDefinition targetType) { var interfaces = new HashSet<Type>(baseInterfaces); if (!interfaces.Contains(typeof (ISerializable))) interfaces.Add(typeof (ISerializable)); var serializableInterfaceType = module.ImportType<ISerializable>(); if (!targetType.Interfaces.Contains(serializableInterfaceType)) targetType.Interfaces.Add(serializableInterfaceType); // Create the proxy type base.Construct(originalBaseType, interfaces, module, targetType); // Add the Serializable attribute targetType.IsSerializable = true; var serializableCtor = module.ImportConstructor<SerializableAttribute>(); var serializableAttribute = new CustomAttribute(serializableCtor); targetType.CustomAttributes.Add(serializableAttribute); ImplementGetObjectData(originalBaseType, baseInterfaces, module, targetType); DefineSerializationConstructor(module, targetType); var interceptorType = module.ImportType<IInterceptor>(); var interceptorGetterProperty = (from PropertyDefinition m in targetType.Properties where m.Name == "Interceptor" && m.PropertyType == interceptorType select m).First(); }
private static int CompareConstructorArguments(CustomAttribute first, CustomAttribute second) { if (first.HasConstructorArguments && !second.HasConstructorArguments) { return 1; } if (!first.HasConstructorArguments && second.HasConstructorArguments) { return -1; } int maxArguments = Math.Max(first.ConstructorArguments.Count, second.ConstructorArguments.Count); for (int i = 0; i < maxArguments; i++) { if (first.ConstructorArguments.Count <= i) { return 1; } if (second.ConstructorArguments.Count <= i) { return -1; } CustomAttributeArgument firstArgument = first.ConstructorArguments[i]; CustomAttributeArgument secondArgument = second.ConstructorArguments[i]; int compareResult = CompareCustomAttributeArguments(firstArgument, secondArgument); if (compareResult != 0) { return compareResult; } } return 0; }
public static bool IsIndexer(this PropertyDefinition property, out CustomAttribute defaultMemberAttribute) { defaultMemberAttribute = null; if (!property.HasParameters) return false; var accessor = property.GetMethod ?? property.SetMethod; var basePropDef = property; if (accessor.HasOverrides) { // if the property is explicitly implementing an interface, look up the property in the interface: var baseAccessor = accessor.Overrides.First().Resolve(); if (baseAccessor != null) { foreach (var baseProp in baseAccessor.DeclaringType.Properties.Where(baseProp => baseProp.GetMethod == baseAccessor || baseProp.SetMethod == baseAccessor)) { basePropDef = baseProp; break; } } else return false; } CustomAttribute attr; var defaultMemberName = basePropDef.DeclaringType.GetDefaultMemberName(out attr); if (defaultMemberName != basePropDef.Name) return false; defaultMemberAttribute = attr; return true; }
/// <summary> /// Writes a custom attribute /// </summary> /// <param name="helper">Helper class</param> /// <param name="ca">The custom attribute</param> /// <returns>Custom attribute blob</returns> public static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca) { using (var writer = new CustomAttributeWriter(helper)) { writer.Write(ca); return writer.GetResult(); } }
public void createSSAEktronMember(string PIN) { //try //{ Dictionary<string, string> UserDetails = loginSSA.GetUsersDetails(PIN); UserManager Usermanager = new UserManager(); CustomAttributeList attrList = new CustomAttributeList(); CustomAttribute timeZone = new CustomAttribute(); timeZone.Name = "Time Zone"; timeZone.Value = "Eastern Standard Time"; attrList.Add(timeZone); UserData newUserdata = new UserData() { Username = PIN, Password = EktronMemberDefaultPassword, FirstName = UserDetails["FirstName"], LastName = UserDetails["LastName"], DisplayName = UserDetails["DisplayName"], Email = UserDetails["Email"], CustomProperties = attrList, // IsMemberShip = true }; if (Ektron.Cms.Framework.Context.UserContextService.Current.IsLoggedIn) { Usermanager.Add(newUserdata); // add user to group MSBA Members UserGroupManager UserGroupmanager = new UserGroupManager(); //Add a User to a UserGroup UserGroupmanager.AddUser(1, newUserdata.Id); } }
public static CustomAttributeSignature FromReader(CustomAttribute parent, IBinaryStreamReader reader) { long position = reader.Position; if (!reader.CanRead(sizeof (ushort)) || reader.ReadUInt16() != 0x0001) throw new ArgumentException("Signature doesn't refer to a valid custom attribute signature."); var signature = new CustomAttributeSignature() { StartOffset = position, }; if (parent.Constructor != null) { var methodSignature = parent.Constructor.Signature as MethodSignature; if (methodSignature != null) { foreach (var parameter in methodSignature.Parameters) { signature.FixedArguments.Add(CustomAttributeArgument.FromReader(parent.Header, parameter.ParameterType, reader)); } } } var namedElementCount = reader.CanRead(sizeof (ushort)) ? reader.ReadUInt16() : 0; for (uint i = 0; i < namedElementCount; i++) { signature.NamedArguments.Add(CustomAttributeNamedArgument.FromReader(parent.Header, reader)); } return signature; }
internal CilCustomAttribute(CustomAttribute attribute, ref CilReaders readers) { _attribute = attribute; _readers = readers; _parent = null; _constructor = null; _value = null; }
void Write(CustomAttribute ca) { if (ca == null) { helper.Error("The custom attribute is null"); return; } // Check whether it's raw first. If it is, we don't care whether the ctor is // invalid. Just use the raw data. if (ca.IsRawBlob) { if ((ca.ConstructorArguments != null && ca.ConstructorArguments.Count > 0) || (ca.NamedArguments != null && ca.NamedArguments.Count > 0)) helper.Error("Raw custom attribute contains arguments and/or named arguments"); writer.Write(ca.RawData); return; } if (ca.Constructor == null) { helper.Error("Custom attribute ctor is null"); return; } var methodSig = GetMethodSig(ca.Constructor); if (methodSig == null) { helper.Error("Custom attribute ctor's method signature is invalid"); return; } if (ca.ConstructorArguments.Count != methodSig.Params.Count) helper.Error("Custom attribute arguments count != method sig arguments count"); if (methodSig.ParamsAfterSentinel != null && methodSig.ParamsAfterSentinel.Count > 0) helper.Error("Custom attribute ctor has parameters after the sentinel"); if (ca.NamedArguments.Count > ushort.MaxValue) helper.Error("Custom attribute has too many named arguments"); // A generic custom attribute isn't allowed by most .NET languages (eg. C#) but // the CLR probably supports it. var mrCtor = ca.Constructor as MemberRef; if (mrCtor != null) { var owner = mrCtor.Class as TypeSpec; if (owner != null) { var gis = owner.TypeSig as GenericInstSig; if (gis != null) { genericArguments = new GenericArguments(); genericArguments.PushTypeArgs(gis.GenericArguments); } } } writer.Write((ushort)1); int numArgs = Math.Min(methodSig.Params.Count, ca.ConstructorArguments.Count); for (int i = 0; i < numArgs; i++) WriteValue(FixTypeSig(methodSig.Params[i]), ca.ConstructorArguments[i]); int numNamedArgs = Math.Min((int)ushort.MaxValue, ca.NamedArguments.Count); writer.Write((ushort)numNamedArgs); for (int i = 0; i < numNamedArgs; i++) Write(ca.NamedArguments[i]); }
public void Decorate(MethodDefinition method, CustomAttribute attribute) { method.Body.InitLocals = true; var getMethodFromHandleRef = referenceFinder.GetMethodReference(typeof(MethodBase), md => md.Name == "GetMethodFromHandle" && md.Parameters.Count == 2); var getCustomAttributesRef = referenceFinder.GetMethodReference(typeof(MemberInfo), md => md.Name == "GetCustomAttributes" && md.Parameters.Count == 2); var getTypeFromHandleRef = referenceFinder.GetMethodReference(typeof(Type), md => md.Name == "GetTypeFromHandle"); var methodBaseTypeRef = referenceFinder.GetTypeReference(typeof(MethodBase)); var exceptionTypeRef = referenceFinder.GetTypeReference(typeof(Exception)); var methodVariableDefinition = AddVariableDefinition(method, "__fody$method", methodBaseTypeRef); var attributeVariableDefinition = AddVariableDefinition(method, "__fody$attribute", attribute.AttributeType); var exceptionVariableDefinition = AddVariableDefinition(method, "__fody$exception", exceptionTypeRef); VariableDefinition retvalVariableDefinition = null; if (method.ReturnType.FullName != "System.Void") retvalVariableDefinition = AddVariableDefinition(method, "__fody$retval", method.ReturnType); var onEntryMethodRef = referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnEntry"); var onExitMethodRef = referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnExit"); var onExceptionMethodRef = referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnException"); var processor = method.Body.GetILProcessor(); var methodBodyFirstInstruction = method.Body.Instructions.First(); if (method.IsConstructor) methodBodyFirstInstruction = method.Body.Instructions.First(i => i.OpCode == OpCodes.Call).Next; var getAttributeInstanceInstructions = GetAttributeInstanceInstructions(processor, method, attribute, attributeVariableDefinition, methodVariableDefinition, getCustomAttributesRef, getTypeFromHandleRef, getMethodFromHandleRef); var callOnEntryInstructions = GetCallOnEntryInstructions(processor, attributeVariableDefinition, methodVariableDefinition, onEntryMethodRef); var saveRetvalInstructions = GetSaveRetvalInstructions(processor, retvalVariableDefinition); var callOnExitInstructions = GetCallOnExitInstructions(processor, attributeVariableDefinition, methodVariableDefinition, onExitMethodRef); var methodBodyReturnInstructions = GetMethodBodyReturnInstructions(processor, retvalVariableDefinition); var methodBodyReturnInstruction = methodBodyReturnInstructions.First(); var tryCatchLeaveInstructions = GetTryCatchLeaveInstructions(processor, methodBodyReturnInstruction); var catchHandlerInstructions = GetCatchHandlerInstructions(processor, attributeVariableDefinition, exceptionVariableDefinition, methodVariableDefinition, onExceptionMethodRef); ReplaceRetInstructions(processor, saveRetvalInstructions.Concat(callOnExitInstructions).First()); processor.InsertBefore(methodBodyFirstInstruction, getAttributeInstanceInstructions); processor.InsertBefore(methodBodyFirstInstruction, callOnEntryInstructions); processor.InsertAfter(method.Body.Instructions.Last(), methodBodyReturnInstructions); processor.InsertBefore(methodBodyReturnInstruction, saveRetvalInstructions); processor.InsertBefore(methodBodyReturnInstruction, callOnExitInstructions); processor.InsertBefore(methodBodyReturnInstruction, tryCatchLeaveInstructions); processor.InsertBefore(methodBodyReturnInstruction, catchHandlerInstructions); method.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { CatchType = exceptionTypeRef, TryStart = methodBodyFirstInstruction, TryEnd = tryCatchLeaveInstructions.Last().Next, HandlerStart = catchHandlerInstructions.First(), HandlerEnd = catchHandlerInstructions.Last().Next }); }
private HostAttributeMapping ToHostAttributeMapping(CustomAttribute arg) { var prms = arg.ConstructorArguments.First().Value as CustomAttributeArgument[]; if (null == prms) return null; return new HostAttributeMapping { HostAttribute = arg, AttribyteTypes = prms.Select(c => ((TypeReference)c.Value).Resolve()).ToArray() }; }
bool? GetCheckForEquality(CustomAttribute notifyAttribute) { var performEqualityCheck = notifyAttribute.Properties.FirstOrDefault(x => x.Name == "PerformEqualityCheck"); var equalityCheckValue = performEqualityCheck.Argument.Value; if (equalityCheckValue != null) { return (bool) equalityCheckValue; } return null; }
bool? GetSetIsChanged(CustomAttribute notifyAttribute) { var setIsChanged = notifyAttribute.Properties.FirstOrDefault(x => x.Name == "SetIsChanged"); var setIsChangedValue = setIsChanged.Argument.Value; if (setIsChangedValue != null) { return (bool) setIsChangedValue; } return null; }
void AddEditorBrowsableAttribute(Collection<CustomAttribute> customAttributes) { if (customAttributes.Any(x=>x.AttributeType.Name == "EditorBrowsableAttribute")) { return; } var customAttribute = new CustomAttribute(EditorBrowsableConstructor); customAttribute.ConstructorArguments.Add(new CustomAttributeArgument(EditorBrowsableStateType, AdvancedStateConstant)); customAttributes.Add(customAttribute); }
void ImportExternal(CustomAttribute validationTemplateAttribute) { var typeReference = (TypeReference) validationTemplateAttribute.ConstructorArguments.First().Value; TypeDefinition = typeReference.Resolve(); TypeReference = ModuleDefinition.ImportReference(TypeDefinition); TemplateConstructor = ModuleDefinition.ImportReference(FindConstructor(TypeDefinition)); ModuleDefinition .Assembly .CustomAttributes.Remove(validationTemplateAttribute); }
public async Task<ActionResult> Create(CustomAttribute customAttribute) { try { await new AttributeHelper().SaveCustomAttribute(customAttribute); return RedirectToAction("Index"); } catch { return View(); } }
public static string GetDefaultMemberName(this TypeDefinition type, out CustomAttribute defaultMemberAttribute) { if (type.HasCustomAttributes) foreach (var ca in type.CustomAttributes) if (ca.Constructor.DeclaringType.Name == "DefaultMemberAttribute" && ca.Constructor.DeclaringType.Namespace == "System.Reflection" && ca.Constructor.FullName == @"System.Void System.Reflection.DefaultMemberAttribute::.ctor(System.String)") { defaultMemberAttribute = ca; return ca.ConstructorArguments[0].Value as string; } defaultMemberAttribute = null; return null; }
TypeReference GetEnumType(CustomAttribute attribute, GenericParameter parameter) { if (attribute.HasConstructorArguments) { var typeReference = (TypeReference) attribute.ConstructorArguments[0].Value; if (!typeReference.IsEnumType()) { var message = $"The type '{typeReference.FullName}' is not an enum type. Only enum types are permitted in an EnumConstraintAttribute."; throw new WeavingException(message); } return typeReference; } return CreateConstraint("System", "Enum", parameter); }
void AddObsoleteAttribute(AttributeData attributeData, Collection<CustomAttribute> customAttributes) { var customAttribute = new CustomAttribute(ObsoleteConstructorReference); var message = ConvertToMessage(attributeData); var messageArgument = new CustomAttributeArgument(ModuleDefinition.TypeSystem.String, message); customAttribute.ConstructorArguments.Add(messageArgument); var isError = GetIsError(attributeData); var isErrorArgument = new CustomAttributeArgument(ModuleDefinition.TypeSystem.Boolean, isError); customAttribute.ConstructorArguments.Add(isErrorArgument); customAttributes.Add(customAttribute); }
public static AttributeData ReadAttributeData(CustomAttribute obsoleteExAttribute, bool throwsNotImplemented) { var treatAsErrorFromVersionString = obsoleteExAttribute.GetValue("TreatAsErrorFromVersion"); var removeInVersionString = obsoleteExAttribute.GetValue("RemoveInVersion"); return new AttributeData { Message = obsoleteExAttribute.GetValue("Message"), Replacement = obsoleteExAttribute.GetValue("ReplacementTypeOrMember"), TreatAsErrorFromVersion = treatAsErrorFromVersionString, RemoveInVersion = removeInVersionString, ThrowsNotImplemented = throwsNotImplemented }; }
IEnumerable<PropertyDefinition> GetPropertyNamesToNotify(CustomAttribute notifyAttribute, PropertyDefinition property, List<PropertyDefinition> allProperties) { var customAttributeArguments = notifyAttribute.ConstructorArguments.ToList(); var value = (string)customAttributeArguments[0].Value; yield return GetPropertyDefinition(property, allProperties, value); if (customAttributeArguments.Count > 1) { var paramsArguments = (CustomAttributeArgument[]) customAttributeArguments[1].Value; foreach (string argument in paramsArguments.Select(x=>x.Value)) { yield return GetPropertyDefinition(property, allProperties, argument); } } }
private static bool IsValidServicingAttribute(CustomAttribute asmAttr) { if (asmAttr.AttributeType.FullName != typeof(AssemblyMetadataAttribute).FullName) { return false; } if (asmAttr.ConstructorArguments.Count != 2) { return false; } var keyValue = asmAttr.ConstructorArguments[0].Value as string; var valueValue = asmAttr.ConstructorArguments[1].Value as string; return (keyValue == "Serviceable") && (valueValue == "True"); }
public async Task SaveCustomAttribute(CustomAttribute attribute) { var currentUser = await UserUtility.GetCurrentParseUser(); if (currentUser == null) return; var itemObject = new ParseObject("CustomAttribute"); if (!string.IsNullOrEmpty(attribute.Id)) itemObject.ObjectId = attribute.Id; itemObject["Name"] = attribute.Name; itemObject["Type"] = attribute.Type; itemObject["CompanyId"] = currentUser["CompanyId"].ToString(); await itemObject.SaveAsync(); }
private static CustomAttributeArgument? GetConstructorArgument( IAssemblyInfo assemblyInfo, CustomAttribute info) { var argumnet = info.ConstructorArguments.First(); if( argumnet.Type != assemblyInfo.Assembly.MainModule.TypeSystem.String ) { Log.WarnFormat( "Argument type of constructor has invalid type> Expected string type but get '{0}.", argumnet.Type.FullName ); return null; } return argumnet; }
private static bool HasAttribute(TypeDefinition declaringType, string attributeType, out CustomAttribute attribute) { foreach (CustomAttribute typeAttribute in declaringType.CustomAttributes) { if (typeAttribute.AttributeType.FullName == attributeType) { attribute = typeAttribute; if (!attribute.IsResolved) { attribute.Resolve(); } return true; } } attribute = null; return false; }
public bool Process(AssemblyProcessorContext context) { var assembly = context.Assembly; var mscorlibAssembly = CecilExtensions.FindCorlibAssembly(assembly); if (mscorlibAssembly == null) throw new InvalidOperationException("Missing mscorlib.dll from assembly"); // Resolve mscorlib types var assemblyFileVersionAttributeType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(AssemblyFileVersionAttribute).FullName); var assemblyMethodConstructor = assembly.MainModule.ImportReference(assemblyFileVersionAttributeType.Methods.FirstOrDefault(method => method.IsConstructor && method.Parameters.Count == 1)); var stringType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(string).FullName); // TODO: Git Commit SHA var gitCommitShortId = "0"; // Use epoch time to get a "unique" build number (different each time) var build = (long)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds; // Get current AssemblyVersion and clone it var version = assembly.Name.Version; var fileVersion = string.Format("{0}.{1}.{2}.{3}", version.Major, version.Minor, build, gitCommitShortId); // Copy build/revision to the AssemblyFileVersion bool fileVersionUpdated = false; for (int i = 0; i < assembly.CustomAttributes.Count; i++) { var customAttribute = assembly.CustomAttributes[i]; if (customAttribute.AttributeType.FullName == typeof(AssemblyFileVersionAttribute).FullName) { customAttribute.ConstructorArguments.Clear(); customAttribute.ConstructorArguments.Add(new CustomAttributeArgument(stringType, fileVersion)); fileVersionUpdated = true; break; } } if (!fileVersionUpdated) { var assemblyFileVersion = new CustomAttribute(assemblyMethodConstructor); assemblyFileVersion.ConstructorArguments.Add(new CustomAttributeArgument(stringType, fileVersion)); assembly.CustomAttributes.Add(assemblyFileVersion); } return true; }
public async Task<ActionResult> Edit(string id, CustomAttribute customAttribute) { try { await new AttributeHelper().SaveCustomAttribute(customAttribute); return RedirectToAction("Index"); } catch { ViewBag.SupportedAttributes = new List<SelectListItem> { new SelectListItem {Text = "String", Value = SupportedAttributeTypes.String}, new SelectListItem {Text = "Number", Value = SupportedAttributeTypes.Number}, }; var attr = new AttributeHelper().GetCustomAttributeById(id); return View(attr); } }
IEnumerable<PropertyDefinition> GetPropertyNamesToNotify(CustomAttribute notifyAttribute, PropertyDefinition property, List<PropertyDefinition> allProperties) { var alsoNotifyProperty = notifyAttribute.Properties.FirstOrDefault(x => x.Name == "AlsoNotifyFor"); var alsoValue = (CustomAttributeArgument[]) alsoNotifyProperty.Argument.Value; if (alsoValue != null) { foreach (string argument in alsoValue.Select(x => x.Value)) { var propertyDefinition = allProperties.FirstOrDefault(x => x.Name == argument); if (propertyDefinition == null) { logger.LogError(string.Format("Could not find property '{0}' for AlsoNotifyFor attribute assinged to '{1}'.", argument, property.Name)); continue; } yield return propertyDefinition; } } }
InjectImportsField(TypeReference importType) { // [ImportMany(typeof(ImportType))] // private IEnumerable<ImportType> _imports; var importerCollectionType = ModuleDefinition.ImportReference( typeof(IEnumerable<>)).MakeGenericInstanceType(importType); var fieldDefinition = new FieldDefinition("_imports", FieldAttributes.Private, importerCollectionType); var importAttribute = new CustomAttribute(ModuleDefinition.ImportReference( typeof(ImportManyAttribute).GetConstructor(new[] {typeof(Type)}))); importAttribute.ConstructorArguments.Add(new CustomAttributeArgument( ModuleDefinition.TypeSystem.TypedReference, importType)); fieldDefinition.CustomAttributes.Add(importAttribute); return Tuple.Create(fieldDefinition, importerCollectionType); }
public static void AddDebuggerDisplayAttributes(ModuleDefinition moduleDefinition, TypeDefinition type) { if (type.IsEnum || type.CustomAttributes.Any(c => c.AttributeType.Name == "CompilerGeneratedAttribute" || c.AttributeType.Name == "DebuggerDisplayAttribute")) return; var fields = type.Fields.Where(f => f.IsPublic && CanPrint(f.FieldType)).Cast<MemberReference>(); var props = type.Properties.Where(p => p.GetMethod != null && p.GetMethod.IsPublic && CanPrint(p.PropertyType)).Cast<MemberReference>(); var displayBits = fields.Concat(props) .OrderBy(m => m.Name) .Select(m => string.Format("{0} = {{{0}}}", m.Name)); if (displayBits.Any()) { var debuggerDisplay = new CustomAttribute(ReferenceFinder.DebuggerDisplayAttributeCtor); debuggerDisplay.ConstructorArguments.Add(new CustomAttributeArgument(moduleDefinition.TypeSystem.String, string.Join(" | ", displayBits))); type.CustomAttributes.Add(debuggerDisplay); } }
static bool IsNamed(this CustomAttribute attribute, string name) { return(attribute.AttributeType.Name == name + "Attribute"); }
// set 'removeAttribute' to true if you want the preserved attribute to be removed from the final assembly protected abstract bool IsPreservedAttribute(ICustomAttributeProvider provider, CustomAttribute attribute, out bool removeAttribute);
public static bool IsAssemblyAssertion(CustomAttribute attr) { return(attr.AttributeType.Name == nameof(KeptAssemblyAttribute) || attr.AttributeType.Name == nameof(RemovedAssemblyAttribute)); }
static bool IsConstraintAttribute(string type, CustomAttribute attribute) { return(attribute.AttributeType.Name == type); }
private static bool IsDebuggerStepThroughAttribute(CustomAttribute customAttribute) { return(String.op_Equality(customAttribute.get_AttributeType().get_FullName(), "System.Diagnostics.DebuggerStepThroughAttribute")); }
// tools for loading headers based on attributes in compiled C# code (early setup for shipping Q# libraries) /// <summary> /// There are two possible handle kinds in use for the constructor of a custom attribute, /// one pointing to the MethodDef table and one to the MemberRef table, see p.216 in the ECMA standard linked above and /// https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/src/System/Reflection/Metadata/TypeSystem/CustomAttribute.cs#L42 /// This routine extracts the namespace and type name of the given attribute and returns the corresponding string handles. /// Returns null if the constructor handle is not a MethodDefinition or a MemberDefinition. /// </summary> private static (StringHandle, StringHandle)? GetAttributeType(MetadataReader metadataReader, CustomAttribute attribute) { if (attribute.Constructor.Kind == HandleKind.MethodDefinition) { var ctor = metadataReader.GetMethodDefinition((MethodDefinitionHandle)attribute.Constructor); var type = metadataReader.GetTypeDefinition(ctor.GetDeclaringType()); return(type.Namespace, type.Name); } else if (attribute.Constructor.Kind == HandleKind.MemberReference) { var ctor = metadataReader.GetMemberReference((MemberReferenceHandle)attribute.Constructor); var type = metadataReader.GetTypeReference((TypeReferenceHandle)ctor.Parent); return(type.Namespace, type.Name); } else { return(null); } }
/// <summary>Load our fields from the metadata of the file as represented by the provided metadata reader.</summary> /// <param name="metadataReader">The metadata reader for the CLI file this represents.</param>\ /// <param name="isExe">true if the assembly represents an executable; false if it's a dll.</param> private void LoadManagedAssemblyMetadata(MetadataReader metadataReader, bool isExe) { AssemblyDefinition assemblyDefinition = metadataReader.GetAssemblyDefinition(); // Set the internal and original names based on the assembly name. We avoid using the // current filename for determinism and better alignment with behavior on Windows. string assemblyName = metadataReader.GetString(assemblyDefinition.Name); if (!assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && !assemblyName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { assemblyName += isExe ? ".exe" : ".dll"; } _internalName = _originalFilename = assemblyName; // Set the product version based on the assembly's version (this may be overwritten // later in the method). Version productVersion = assemblyDefinition.Version; _productVersion = productVersion.ToString(); _productMajor = productVersion.Major; _productMinor = productVersion.Minor; _productBuild = productVersion.Build != -1 ? productVersion.Build : 0; _productPrivate = productVersion.Revision != -1 ? productVersion.Revision : 0; // "Language Neutral" is used on Win32 for unknown language identifiers. _language = "Language Neutral"; // Set other fields to default values in case they're not overwritten by attributes _companyName = string.Empty; _comments = string.Empty; _fileDescription = " "; // this is what the managed compiler outputs when value isn't set _fileVersion = string.Empty; _legalCopyright = " "; // this is what the managed compiler outputs when value isn't set _legalTrademarks = string.Empty; _productName = string.Empty; _privateBuild = string.Empty; _specialBuild = string.Empty; // Be explicit about initialization to suppress warning about fields not being set _isDebug = false; _isPatched = false; _isPreRelease = false; _isPrivateBuild = false; _isSpecialBuild = false; bool sawAssemblyInformationalVersionAttribute = false; // Everything else is parsed from assembly attributes MetadataStringComparer comparer = metadataReader.StringComparer; foreach (CustomAttributeHandle attrHandle in assemblyDefinition.GetCustomAttributes()) { CustomAttribute attr = metadataReader.GetCustomAttribute(attrHandle); StringHandle typeNamespaceHandle = default(StringHandle), typeNameHandle = default(StringHandle); if (TryGetAttributeName(metadataReader, attr, out typeNamespaceHandle, out typeNameHandle) && comparer.Equals(typeNamespaceHandle, "System.Reflection")) { if (comparer.Equals(typeNameHandle, "AssemblyCompanyAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _companyName); } else if (comparer.Equals(typeNameHandle, "AssemblyCopyrightAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _legalCopyright); } else if (comparer.Equals(typeNameHandle, "AssemblyDescriptionAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _comments); } else if (comparer.Equals(typeNameHandle, "AssemblyFileVersionAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _fileVersion); ParseVersion(_fileVersion, out _fileMajor, out _fileMinor, out _fileBuild, out _filePrivate); } else if (comparer.Equals(typeNameHandle, "AssemblyInformationalVersionAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _productVersion); ParseVersion(_productVersion, out _productMajor, out _productMinor, out _productBuild, out _productPrivate); sawAssemblyInformationalVersionAttribute = true; } else if (comparer.Equals(typeNameHandle, "AssemblyProductAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _productName); } else if (comparer.Equals(typeNameHandle, "AssemblyTrademarkAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _legalTrademarks); } else if (comparer.Equals(typeNameHandle, "AssemblyTitleAttribute")) { GetStringAttributeArgumentValue(metadataReader, attr, ref _fileDescription); } } } // When the managed compiler sees an [AssemblyVersion(...)] attribute, it uses that to set // both the assembly version and the product version in the Win32 resources. If it doesn't // see an [AssemblyVersion(...)], then it sets the assembly version to 0.0.0.0, however it // sets the product version in the Win32 resources to whatever was defined in the // [AssemblyFileVersionAttribute(...)] if there was one (unless there is an AssemblyInformationalVersionAttribute, // in which case it always uses that for the product version). Without parsing the Win32 resources, // we can't differentiate these two cases, so given the rarity of explicitly setting an // assembly's version number to 0.0.0.0, we assume that if it is 0.0.0.0 then the attribute // wasn't specified and we use the file version. if (!sawAssemblyInformationalVersionAttribute && _productVersion == "0.0.0.0") { _productVersion = _fileVersion; _productMajor = _fileMajor; _productMinor = _fileMinor; _productBuild = _fileBuild; _productPrivate = _filePrivate; } }
public override (bool success, bool dirty) ProcessClass(ModuleDefinition module, TypeDefinition type) { members.Clear(); instructions.Clear(); firstInstructions.Clear(); ifsLast.Clear(); if (type.HasFields) { for (int i = 0; i < type.Fields.Count; i++) { if (type.Fields[i].HasAttribute <FindProperty>()) { members.Add(new MemberData(type.Fields[i])); } } } if (type.HasProperties) { for (int i = 0; i < type.Properties.Count; i++) { if (type.Properties[i].HasAttribute <FindProperty>()) { members.Add(new MemberData(type.Properties[i])); } } } if (members.Count == 0) { // There are no valid fields/properties. Stop here. return(true, false); } bool createdOnEnable = false; if (!type.TryGetMethod("OnEnable", out MethodDefinition enableMethod)) { enableMethod = new MethodDefinition("OnEnable", MethodAttributes.Private | MethodAttributes.HideBySig, module.ImportReference(typeof(void))); type.Methods.Add(enableMethod); createdOnEnable = true; } MethodReference getSerializedObject = module.ImportReference(type.GetMethodInBaseType("get_serializedObject")); MethodReference getTarget = module.ImportReference(type.GetMethodInBaseType("get_target")); MethodReference findProperty = module.ImportReference(typeof(SerializedObject).GetMethod("FindProperty", new Type[] { typeof(string) })); MethodReference findPropertyRelative = module.ImportReference(typeof(SerializedProperty).GetMethod("FindPropertyRelative", new Type[] { typeof(string) })); MethodReference logError = module.ImportReference(typeof(Debug).GetMethod("LogError", new Type[] { typeof(object) })); for (int i = 0; i < members.Count; i++) { CustomAttribute attribute = members[i].GetAttribute <FindProperty>(); string path = attribute.GetConstructorArgument(0, string.Empty); Instruction beforeGetProperty = Instruction.Create(OpCodes.Ldarg_0); string[] paths = string.IsNullOrWhiteSpace(path) ? (new string[1] { members[i].Name }) : path.Split('/'); for (int j = 0; j < paths.Length; j++) { firstInstructions.Add(Instruction.Create(OpCodes.Ldarg_0)); } for (int j = 0; j < paths.Length; j++) { instructions.Add(firstInstructions[j]); instructions.Add(Instruction.Create(OpCodes.Call, getSerializedObject)); for (int k = 0; k <= j; k++) { instructions.Add(Instruction.Create(OpCodes.Ldstr, paths[k])); Instruction last = Instruction.Create(OpCodes.Call, k == 0 ? findProperty : findPropertyRelative); instructions.Add(last); if (k == j) { ifsLast.Add(new Tuple <Instruction, Instruction>(last, j == paths.Length - 1 ? beforeGetProperty : firstInstructions[j + 1])); } } instructions.Add(Instruction.Create(OpCodes.Ldstr, "There's no serialized property called '" + paths[j] + "' on {0}")); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Call, getTarget)); instructions.Add(Instruction.Create(OpCodes.Call, LogCalledProcessor.GetStringFormatMethod(module, 1))); instructions.Add(Instruction.Create(OpCodes.Call, logError)); instructions.Add(Instruction.Create(OpCodes.Ret)); } instructions.Add(beforeGetProperty); instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); instructions.Add(Instruction.Create(OpCodes.Call, getSerializedObject)); for (int j = 0; j < paths.Length; j++) { instructions.Add(Instruction.Create(OpCodes.Ldstr, paths[j])); instructions.Add(Instruction.Create(OpCodes.Callvirt, j == 0 ? findProperty : findPropertyRelative)); } if (members[i].IsProperty) { instructions.Add(Instruction.Create(OpCodes.Call, members[i].property.SetMethod)); } else { instructions.Add(Instruction.Create(OpCodes.Stfld, members[i].field)); } } ILProcessor il = enableMethod.Body.GetILProcessor(); for (int i = 0; i < instructions.Count; i++) { if (createdOnEnable) { il.Append(instructions[i]); } else { il.InsertBefore(enableMethod.Body.Instructions[i], instructions[i]); } } if (createdOnEnable) { il.Emit(OpCodes.Ret); } for (int i = 0; i < ifsLast.Count; i++) { il.InsertAfter(ifsLast[i].Item1, Instruction.Create(OpCodes.Brtrue_S, ifsLast[i].Item2)); } return(true, true); }
/// <summary> /// Decides if the given type should be decompiled as partial or not. /// </summary> /// <param name="type">The type in question.</param> /// <returns> Returns true, if some of the members of the type should be skipped, and the type must be declared partial.</returns> public static bool ShouldBePartial(TypeDefinition type) { AssemblyDefinition assembly = type.Module.Assembly; if (assembly.EntryPoint != null && assembly.EntryPoint.DeclaringType == type) { return(false); } // The pattern is observed in wpf applications. // The type is marked with the GeneratedCode attribute // and all its generated members are marked with DebuggerNonUserCode if (!type.HasCustomAttribute(new string[1] { "System.CodeDom.Compiler.GeneratedCodeAttribute" })) { return(false); } CustomAttribute generatedCodeCustomAttribute = type.CustomAttributes.First(x => x.AttributeType.FullName == "System.CodeDom.Compiler.GeneratedCodeAttribute"); generatedCodeCustomAttribute.Resolve(); if (generatedCodeCustomAttribute.ConstructorArguments[0].Type.FullName != "System.String" || generatedCodeCustomAttribute.ConstructorArguments[0].Value.ToString() != "PresentationBuildTasks") { return(false); } if (type.HasMethods) { foreach (MethodDefinition method in type.Methods) { if (method.HasCustomAttributes) { if (method.HasCustomAttribute(new string[1] { "System.Diagnostics.DebuggerNonUserCodeAttribute" })) { return(true); } } } } if (type.HasProperties) { foreach (PropertyDefinition property in type.Properties) { if (property.HasCustomAttributes) { if (property.HasCustomAttribute(new string[1] { "System.Diagnostics.DebuggerNonUserCodeAttribute" })) { return(true); } } } } if (type.HasFields) { foreach (FieldDefinition field in type.Fields) { if (field.HasCustomAttributes) { if (field.HasCustomAttribute(new string[1] { "System.Diagnostics.DebuggerNonUserCodeAttribute" })) { return(true); } } } } return(false); }
protected internal override void Execute(DotProtectContext context, ProtectionParameters parameters) { var rt = context.Registry.GetService <IRuntimeService>(); var marker = context.Registry.GetService <IMarkerService>(); var name = context.Registry.GetService <INameService>(); foreach (ModuleDef module in parameters.Targets.OfType <ModuleDef>()) { AntiMode mode = parameters.GetParameter(context, module, "mode", AntiMode.Safe); TypeDef rtType; TypeDef attr = null; const string attrName = "System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute"; switch (mode) { case AntiMode.Safe: rtType = rt.GetRuntimeType("DotProtect.Runtime.AntiDebugSafe"); break; case AntiMode.Win32: rtType = rt.GetRuntimeType("DotProtect.Runtime.AntiDebugWin32"); break; case AntiMode.Antinet: rtType = rt.GetRuntimeType("DotProtect.Runtime.AntiDebugAntinet"); attr = rt.GetRuntimeType(attrName); module.Types.Add(attr = InjectHelper.Inject(attr, module)); foreach (IDnlibDef member in attr.FindDefinitions()) { marker.Mark(member, (Protection)Parent); name.Analyze(member); } name.SetCanRename(attr, false); break; default: throw new UnreachableException(); } IEnumerable <IDnlibDef> members = InjectHelper.Inject(rtType, module.GlobalType, module); MethodDef cctor = module.GlobalType.FindStaticConstructor(); var init = (MethodDef)members.Single(method => method.Name == "Initialize"); cctor.Body.Instructions.Insert(0, Instruction.Create(OpCodes.Call, init)); foreach (IDnlibDef member in members) { marker.Mark(member, (Protection)Parent); name.Analyze(member); bool ren = true; if (member is MethodDef) { var method = (MethodDef)member; if (method.Access == MethodAttributes.Public) { method.Access = MethodAttributes.Assembly; } if (!method.IsConstructor) { method.IsSpecialName = false; } else { ren = false; } CustomAttribute ca = method.CustomAttributes.Find(attrName); if (ca != null) { ca.Constructor = attr.FindMethod(".ctor"); } } else if (member is FieldDef) { var field = (FieldDef)member; if (field.Access == FieldAttributes.Public) { field.Access = FieldAttributes.Assembly; } if (field.IsLiteral) { field.DeclaringType.Fields.Remove(field); continue; } } if (ren) { member.Name = name.ObfuscateName(member.Name, RenameMode.Unicode); name.SetCanRename(member, false); } } } }
// CustomAttribute public static bool IsEqual(CustomAttribute x, CustomAttribute y) => x.AttributeType.Is(y.AttributeType) && x.GetBlob().SequenceEqual(y.GetBlob());
static bool IsEnumConstraintAttribute(CustomAttribute attribute) { return(IsConstraintAttribute("EnumConstraintAttribute", attribute)); }
bool IEqualityComparer <CustomAttribute> .Equals(CustomAttribute x, CustomAttribute y) => IsEqual(x, y);
private static string[] _MakeProxiesByName(string key, MemberReference mr) { var icap = mr.DeclaringType as Mono.Cecil.ICustomAttributeProvider; if (icap == null) { return(null); } CustomAttribute proxyAttribute = null; for (int i = 0, c = icap.CustomAttributes.Count; i < c; i++) { var ca = icap.CustomAttributes[i]; if ((ca.AttributeType.Name == "JSProxy") && (ca.AttributeType.Namespace == "JSIL.Proxy")) { proxyAttribute = ca; break; } } if (proxyAttribute == null) { return(null); } string[] proxyTargets = null; var args = proxyAttribute.ConstructorArguments; foreach (var arg in args) { switch (arg.Type.FullName) { case "System.Type": proxyTargets = new string[] { ((TypeReference)arg.Value).FullName }; break; case "System.Type[]": { var values = (CustomAttributeArgument[])arg.Value; proxyTargets = new string[values.Length]; for (var i = 0; i < proxyTargets.Length; i++) { proxyTargets[i] = ((TypeReference)values[i].Value).FullName; } break; } case "System.String": { proxyTargets = new string[] { (string)arg.Value }; break; } case "System.String[]": { var values = (CustomAttributeArgument[])arg.Value; proxyTargets = (from v in values select(string) v.Value).ToArray(); break; } } } return(proxyTargets); }
/// <summary> /// Scan a single assembly for extensions marked by ExtensionAttribute. /// For each extension, create an ExtensionNode and link it to the /// correct ExtensionPoint. Public for testing. /// </summary> internal void FindExtensionsInAssembly(ExtensionAssembly assembly) { log.Info($"Scanning {assembly.FilePath} for Extensions"); if (!CanLoadTargetFramework(Assembly.GetEntryAssembly(), assembly)) { log.Info($"{assembly.FilePath} cannot be loaded on this runtime"); return; } IRuntimeFramework assemblyTargetFramework = null; #if NETFRAMEWORK var currentFramework = RuntimeFramework.CurrentFramework; assemblyTargetFramework = assembly.TargetFramework; if (!currentFramework.CanLoad(assemblyTargetFramework)) { //Temp fix: Prevent crash in agent if an extension is used by the main engine, which targets a framework that can not be loaded on a particular agent // https://github.com/nunit/nunit-console/issues/757 //Long-term fix is to not search for extensions within the agent, see https://github.com/nunit/nunit-console/issues/760 if (_isRunningOnAgent) { return; } if (!assembly.FromWildCard) { throw new NUnitEngineException($"Extension {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available."); } else { log.Info($"Assembly {assembly.FilePath} targets {assemblyTargetFramework.DisplayName}, which is not available. Assembly found via wildcard."); return; } } #endif foreach (var type in assembly.MainModule.GetTypes()) { CustomAttribute extensionAttr = type.GetAttribute("NUnit.Engine.Extensibility.ExtensionAttribute"); if (extensionAttr == null) { continue; } object versionArg = extensionAttr.GetNamedArgument("EngineVersion"); if (versionArg != null && new Version((string)versionArg) > ENGINE_VERSION) { continue; } var node = new ExtensionNode(assembly.FilePath, assembly.AssemblyVersion, type.FullName, assemblyTargetFramework); node.Path = extensionAttr.GetNamedArgument("Path") as string; node.Description = extensionAttr.GetNamedArgument("Description") as string; object enabledArg = extensionAttr.GetNamedArgument("Enabled"); node.Enabled = enabledArg != null ? (bool)enabledArg : true; log.Info(" Found ExtensionAttribute on Type " + type.Name); foreach (var attr in type.GetAttributes("NUnit.Engine.Extensibility.ExtensionPropertyAttribute")) { string name = attr.ConstructorArguments[0].Value as string; string value = attr.ConstructorArguments[1].Value as string; if (name != null && value != null) { node.AddProperty(name, value); log.Info(" ExtensionProperty {0} = {1}", name, value); } } _extensions.Add(node); ExtensionPoint ep; if (node.Path == null) { ep = DeduceExtensionPointFromType(type); if (ep == null) { string msg = string.Format( "Unable to deduce ExtensionPoint for Type {0}. Specify Path on ExtensionAttribute to resolve.", type.FullName); throw new NUnitEngineException(msg); } node.Path = ep.Path; } else { ep = GetExtensionPoint(node.Path); if (ep == null) { string msg = string.Format( "Unable to locate ExtensionPoint for Type {0}. The Path {1} cannot be found.", type.FullName, node.Path); throw new NUnitEngineException(msg); } } ep.Install(node); } }
static bool IsDelegateConstraintAttribute(CustomAttribute attribute) { return(IsConstraintAttribute("DelegateConstraintAttribute", attribute)); }
protected static IEnumerable <string> GetStringArrayAttributeValue(CustomAttribute attribute) { return(((CustomAttributeArgument[])attribute.ConstructorArguments[0].Value)?.Select(arg => arg.Value.ToString())); }
/// <summary> /// Gets the children of the given item. /// </summary> /// <param name="item">Item to get children of.</param> /// <returns>Children of <paramref name="item"/>.</returns> protected override IEnumerable <object> InvokeForItem(CustomAttribute item) { return(new object[0]); }
public static bool IsSymbolAssertion(CustomAttribute attr) { return(attr.AttributeType.Name == nameof(KeptSymbolsAttribute) || attr.AttributeType.Name == nameof(RemovedSymbolsAttribute)); }
public CustomAttributeRef(CustomAttribute cattr, int index, IMemberRef reference) { this.cattr = cattr; this.index = index; this.reference = reference; }
public static object GetConstructorArgumentValue(this CustomAttribute attr, int argumentIndex) { return(attr.ConstructorArguments[argumentIndex].Value); }
/* generates code like: * public void CallTargetTest (NetworkConnection conn, int param) * { * NetworkWriter writer = new NetworkWriter (); * writer.WritePackedUInt32 ((uint)param); * base.SendTargetRPCInternal (conn, typeof(class), "TargetTest", val); * } * * or if optional: * public void CallTargetTest (int param) * { * NetworkWriter writer = new NetworkWriter (); * writer.WritePackedUInt32 ((uint)param); * base.SendTargetRPCInternal (null, typeof(class), "TargetTest", val); * } */ public static MethodDefinition ProcessTargetRpcCall(TypeDefinition td, MethodDefinition md, CustomAttribute ca) { MethodDefinition rpc = new MethodDefinition("Call" + md.Name, MethodAttributes.Public | MethodAttributes.HideBySig, Weaver.voidType); // add parameters foreach (ParameterDefinition pd in md.Parameters) { rpc.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType)); } ILProcessor rpcWorker = rpc.Body.GetILProcessor(); NetworkBehaviourProcessor.WriteSetupLocals(rpcWorker); NetworkBehaviourProcessor.WriteCreateWriter(rpcWorker); // NetworkConnection parameter is optional bool hasNetworkConnection = HasNetworkConnectionParameter(md); // write all the arguments that the user passed to the TargetRpc call // (skip first one if first one is NetworkConnection) if (!NetworkBehaviourProcessor.WriteArguments(rpcWorker, md, hasNetworkConnection)) { return(null); } string rpcName = md.Name; int index = rpcName.IndexOf(TargetRpcPrefix); if (index > -1) { rpcName = rpcName.Substring(TargetRpcPrefix.Length); } // invoke SendInternal and return rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_0)); // this if (HasNetworkConnectionParameter(md)) { rpcWorker.Append(rpcWorker.Create(OpCodes.Ldarg_1)); // connection } else { rpcWorker.Append(rpcWorker.Create(OpCodes.Ldnull)); // null } rpcWorker.Append(rpcWorker.Create(OpCodes.Ldtoken, td)); rpcWorker.Append(rpcWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); // invokerClass rpcWorker.Append(rpcWorker.Create(OpCodes.Ldstr, rpcName)); rpcWorker.Append(rpcWorker.Create(OpCodes.Ldloc_0)); // writer rpcWorker.Append(rpcWorker.Create(OpCodes.Ldc_I4, NetworkBehaviourProcessor.GetChannelId(ca))); rpcWorker.Append(rpcWorker.Create(OpCodes.Callvirt, Weaver.sendTargetRpcInternal)); NetworkBehaviourProcessor.WriteRecycleWriter(rpcWorker); rpcWorker.Append(rpcWorker.Create(OpCodes.Ret)); return(rpc); }
public bool Process(AssemblyProcessorContext context) { var assembly = context.Assembly; var fields = new List <FieldDefinition>(); var mscorlibAssembly = CecilExtensions.FindCorlibAssembly(assembly); if (mscorlibAssembly == null) { throw new InvalidOperationException("Missing mscorlib.dll from assembly"); } MethodDefinition parameterKeysMergeMethod = null; TypeDefinition assemblyEffectKeysAttributeType = null; var getTypeFromHandleMethod = new Lazy <MethodReference>(() => { // Find Type.GetTypeFromHandle var typeType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(Type).FullName); return(assembly.MainModule.ImportReference(typeType.Methods.First(x => x.Name == "GetTypeFromHandle"))); }); var effectKeysStaticConstructors = new List <MethodReference>(); var effectKeysArrayElemementTypes = new HashSet <TypeReference>(); foreach (var type in assembly.MainModule.GetTypes()) { fields.Clear(); foreach (var field in type.Fields.Where(x => x.IsStatic)) { var fieldBaseType = field.FieldType; while (fieldBaseType != null) { if (fieldBaseType.FullName == "SiliconStudio.Xenko.Rendering.ParameterKey") { break; } // TODO: Get PropertyKey.PropertyType instead var genericInstance = fieldBaseType as GenericInstanceType; if (genericInstance != null && genericInstance.ElementType.FullName == "SiliconStudio.Xenko.Rendering.ParameterKey`1") { var genericArgument = genericInstance.GenericArguments.First(); if (genericArgument.IsArray) { effectKeysArrayElemementTypes.Add(genericArgument.GetElementType()); } } var resolvedFieldBaseType = fieldBaseType.Resolve(); if (resolvedFieldBaseType == null) { fieldBaseType = null; break; } fieldBaseType = resolvedFieldBaseType.BaseType; } if (fieldBaseType == null) { continue; } fields.Add(field); } if (fields.Count == 0) { continue; } // ParameterKey present means we should have a static cctor. var cctor = type.GetStaticConstructor(); if (cctor == null) { continue; } // Load necessary SiliconStudio.Xenko methods/attributes if (parameterKeysMergeMethod == null) { AssemblyDefinition xenkoEngineAssembly; try { xenkoEngineAssembly = assembly.Name.Name == "SiliconStudio.Xenko" ? assembly : context.AssemblyResolver.Resolve("SiliconStudio.Xenko"); } catch (Exception) { context.Log.WriteLine("Error, cannot find [SiliconStudio.Xenko] assembly for processing ParameterKeyProcessor"); // We can't generate an exception, so we are just returning. It means that SiliconStudio.Xenko has not been generated so far. return(true); } var parameterKeysType = xenkoEngineAssembly.MainModule.GetTypes().First(x => x.Name == "ParameterKeys"); parameterKeysMergeMethod = parameterKeysType.Methods.First(x => x.Name == "Merge"); assemblyEffectKeysAttributeType = xenkoEngineAssembly.MainModule.GetTypes().First(x => x.Name == "AssemblyEffectKeysAttribute"); } var cctorIL = cctor.Body.GetILProcessor(); var cctorInstructions = cctor.Body.Instructions; var keyClassName = type.Name; if (keyClassName.EndsWith("Keys")) { keyClassName = keyClassName.Substring(0, keyClassName.Length - 4); } keyClassName += '.'; bool cctorModified = false; // Find field store instruction for (int i = 0; i < cctorInstructions.Count; ++i) { var fieldInstruction = cctorInstructions[i]; if (fieldInstruction.OpCode == OpCodes.Stsfld && fields.Contains(fieldInstruction.Operand)) { var activeField = (FieldReference)fieldInstruction.Operand; var nextInstruction = cctorInstructions[i + 1]; cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Ldsfld, activeField)); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Ldtoken, type)); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Call, getTypeFromHandleMethod.Value)); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Ldstr, keyClassName + activeField.Name)); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Call, assembly.MainModule.ImportReference(parameterKeysMergeMethod))); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Castclass, activeField.FieldType)); cctorIL.InsertBefore(nextInstruction, Instruction.Create(OpCodes.Stsfld, activeField)); i = cctorInstructions.IndexOf(nextInstruction); cctorModified = true; } } if (cctorModified) { effectKeysStaticConstructors.Add(cctor); } } if (effectKeysStaticConstructors.Count > 0) { // Add [AssemblyEffectKeysAttribute] to the assembly assembly.CustomAttributes.Add(new CustomAttribute(assembly.MainModule.ImportReference(assemblyEffectKeysAttributeType.GetConstructors().First(x => !x.HasParameters)))); // Get or create module static constructor var voidType = assembly.MainModule.TypeSystem.Void; var moduleClass = assembly.MainModule.Types.First(t => t.Name == "<Module>"); var staticConstructor = moduleClass.GetStaticConstructor(); if (staticConstructor == null) { staticConstructor = new MethodDefinition(".cctor", MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, voidType); staticConstructor.Body.GetILProcessor().Append(Instruction.Create(OpCodes.Ret)); moduleClass.Methods.Add(staticConstructor); } var il = staticConstructor.Body.GetILProcessor(); var returnInstruction = staticConstructor.Body.Instructions.Last(); var newReturnInstruction = Instruction.Create(returnInstruction.OpCode); newReturnInstruction.Operand = returnInstruction.Operand; returnInstruction.OpCode = OpCodes.Nop; returnInstruction.Operand = null; var typeType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(Type).FullName); var typeHandleProperty = typeType.Properties.First(x => x.Name == "TypeHandle"); var getTypeHandleMethod = assembly.MainModule.ImportReference(typeHandleProperty.GetMethod); var runtimeHelpersType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(RuntimeHelpers).FullName); var runClassConstructorMethod = assembly.MainModule.ImportReference(runtimeHelpersType.Methods.Single(x => x.IsPublic && x.Name == "RunClassConstructor" && x.Parameters.Count == 1 && x.Parameters[0].ParameterType.FullName == typeof(RuntimeTypeHandle).FullName)); // Call every key class static constructor from the module static constructor so that they are properly constructed (because accessing through reflection might cause problems) staticConstructor.Body.SimplifyMacros(); foreach (var effectKeysStaticConstructor in effectKeysStaticConstructors) { il.Append(Instruction.Create(OpCodes.Ldtoken, effectKeysStaticConstructor.DeclaringType)); il.Append(Instruction.Create(OpCodes.Call, getTypeFromHandleMethod.Value)); il.Append(Instruction.Create(OpCodes.Callvirt, getTypeHandleMethod)); il.Append(Instruction.Create(OpCodes.Call, runClassConstructorMethod)); } if (effectKeysArrayElemementTypes.Count > 0) { var methodImplAttributeType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(MethodImplAttribute).FullName); var methodImplAttributesType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(MethodImplOptions).FullName); var attribute = new CustomAttribute(methodImplAttributeType.GetConstructors().First(x => x.HasParameters && x.Parameters[0].ParameterType.FullName == methodImplAttributesType.FullName)); attribute.ConstructorArguments.Add(new CustomAttributeArgument(methodImplAttributesType, MethodImplOptions.NoOptimization)); staticConstructor.CustomAttributes.Add(attribute); } // Create instances of InternalValueArray<T>. Required for LLVM AOT foreach (var elementType in effectKeysArrayElemementTypes) { var siliconStudioXenkoAssembly = assembly.Name.Name == "SiliconStudio.Xenko" ? assembly : assembly.MainModule.AssemblyResolver.Resolve("SiliconStudio.Xenko"); var parameterCollectionType = siliconStudioXenkoAssembly.MainModule.GetTypeResolved("SiliconStudio.Xenko.Rendering.ParameterCollection"); var internalValueArrayType = parameterCollectionType.NestedTypes.First(x => x.Name == "InternalValueArray`1"); var constructor = internalValueArrayType.GetConstructors().First(); var internalValueArrayConstructor = siliconStudioXenkoAssembly.MainModule.ImportReference(constructor).MakeGeneric(elementType); il.Append(Instruction.Create(OpCodes.Ldc_I4_0)); il.Append(Instruction.Create(OpCodes.Newobj, internalValueArrayConstructor)); il.Append(Instruction.Create(OpCodes.Pop)); } il.Append(newReturnInstruction); staticConstructor.Body.OptimizeMacros(); } return(true); }
public int GetHashCode(CustomAttribute obj) => obj.GetHashCode();
internal static void RelinkType(TypeDefinition type) { foreach (TypeDefinition nested in type.NestedTypes) { RelinkType(nested); } type.BaseType = type.BaseType.Relinked(type); for (int i = 0; i < type.Interfaces.Count; i++) { InterfaceImplementation interf = new InterfaceImplementation(type.Interfaces[i].InterfaceType.Relinked(type)); for (int cai = 0; cai < type.Interfaces[i].CustomAttributes.Count; cai++) { CustomAttribute oca = type.Interfaces[i].CustomAttributes[cai]; // TODO relink that method CustomAttribute ca = new CustomAttribute(oca.Constructor /*.Relinked(type)*/, oca.GetBlob()); for (int caii = 0; caii < oca.ConstructorArguments.Count; caii++) { //TODO do more with the attributes CustomAttributeArgument ocaa = oca.ConstructorArguments[caii]; ca.ConstructorArguments.Add(new CustomAttributeArgument(ocaa.Type.Relinked(type), ocaa.Value is TypeReference ? ocaa.Type.Relinked(type) : ocaa.Value )); } interf.CustomAttributes.Add(ca); } type.Interfaces[i] = interf; } foreach (FieldDefinition field in type.Fields) { field.FieldType = field.FieldType.Relinked(type); } foreach (PropertyDefinition property in type.Properties) { property.PropertyType = property.PropertyType.Relinked(type); if (property.GetMethod != null) { property.GetMethod.ReturnType = property.GetMethod.ReturnType.Relinked(type); for (int i = 0; i < property.GetMethod.Parameters.Count; i++) { property.GetMethod.Parameters[i].ParameterType = property.GetMethod.Parameters[i].ParameterType.Relinked(type); } } if (property.SetMethod != null) { property.SetMethod.ReturnType = property.GetMethod.ReturnType.Relinked(type); for (int i = 0; i < property.SetMethod.Parameters.Count; i++) { property.SetMethod.Parameters[i].ParameterType = property.SetMethod.Parameters[i].ParameterType.Relinked(type); } } } foreach (MethodDefinition method in type.Methods) { method.ReturnType = method.ReturnType.Relinked(method); for (int i = 0; i < method.Parameters.Count; i++) { method.Parameters[i].ParameterType = method.Parameters[i].ParameterType.Relinked(method); } for (int i = 0; method.HasBody && i < method.Body.Instructions.Count; i++) { Instruction instruction = method.Body.Instructions[i]; object operand = instruction.Operand; if (operand is MethodReference) { MethodReference old = (MethodReference)operand; MethodReference relink = new MethodReference(old.Name, old.ReturnType.Relinked(method), old.DeclaringType.Relinked(method)); foreach (ParameterDefinition param in old.Parameters) { param.ParameterType = param.ParameterType.Relinked(method); relink.Parameters.Add(param); } foreach (GenericParameter param in old.GenericParameters) { relink.GenericParameters.Add(param.Relinked(method)); } relink.CallingConvention = old.CallingConvention; relink.ExplicitThis = old.ExplicitThis; relink.HasThis = old.HasThis; operand = type.Module.ImportReference(relink); } else if (operand is FieldReference) { FieldReference old = (FieldReference)operand; FieldReference relink = new FieldReference(old.Name, old.FieldType.Relinked(method), old.DeclaringType.Relinked(method)); operand = type.Module.ImportReference(relink); } else if (operand is TypeReference) { operand = ((TypeReference)operand).Relinked(method); } instruction.Operand = operand; } for (int i = 0; method.HasBody && i < method.Body.Variables.Count; i++) { method.Body.Variables[i].VariableType = method.Body.Variables[i].VariableType.Relinked(method); } } }
public static void PatchJumpSuperUpdate(MethodDefinition method, CustomAttribute attrib) { if (!method.HasBody) { return; } MethodDefinition m_IsCoyoteFrameEnabled = method.DeclaringType.FindMethod("System.Boolean _IsCoyoteFrameEnabled(System.Boolean,PlayerMachine)"); if (m_IsCoyoteFrameEnabled == null) { return; } Mono.Collections.Generic.Collection <Instruction> instrs = method.Body.Instructions; ILProcessor il = method.Body.GetILProcessor(); if (instrs[0].OpCode == OpCodes.Ldsfld && instrs[1].OpCode == OpCodes.Callvirt) { //Looking for something like this: // ldarg.0 // ldfld float32 PlayerMachine::FallTime // ldc.r4 2 // bge.un.s IL_00ff Instruction jumpTo = null; int j = -1; for (int k = 2; k < instrs.Count - 2; ++k) { if (instrs[k].OpCode == OpCodes.Brfalse && instrs[k - 1].OpCode == OpCodes.Ldfld && (instrs[k - 1].Operand as FieldReference).FullName == "System.Boolean PlayerMachine::FallJumpWindowJumpCheck") { instrs[k] = il.Create(OpCodes.Nop); } if (instrs[k].OpCode == OpCodes.Bge_Un && instrs[k - 1].OpCode == OpCodes.Ldfld && (instrs[k - 1].Operand as FieldReference).FullName == "System.Single PlayerMachine::FallJumpWindow") { instrs[k] = il.Create(OpCodes.Clt_Un); ++k; instrs.Insert(k, il.Create(OpCodes.And)); j = ++k; } if (instrs[k].OpCode == OpCodes.Ldarg_0 && instrs[k + 1].OpCode == OpCodes.Ldfld && instrs[k + 2].OpCode == OpCodes.Ldc_R4 && (instrs[k + 1].Operand as FieldReference).FullName == "System.Single PlayerMachine::FallTime") { jumpTo = instrs[k]; break; } } if (jumpTo == null || j <= 0) { return; } //Push this instrs.Insert(j, il.Create(OpCodes.Ldarg_0)); ++j; // Process. instrs.Insert(j, il.Create(OpCodes.Call, m_IsCoyoteFrameEnabled)); ++j; instrs.Insert(j, il.Create(OpCodes.Brfalse, jumpTo)); } }
private void AddRegistrationCode(List <TypeMemo> memos) { var autoClassName = $"__UnmanagedPostProcessorOutput__{(uint)AssemblyDefinition.FullName.GetHashCode()}"; var mod = AssemblyDefinition.MainModule; var classDef = new TypeDefinition("", autoClassName, TypeAttributes.Class, AssemblyDefinition.MainModule.ImportReference(typeof(object))); classDef.IsBeforeFieldInit = false; mod.Types.Add(classDef); var funcDef = new MethodDefinition("EarlyInit", MethodAttributes.Static | MethodAttributes.Public | MethodAttributes.HideBySig, AssemblyDefinition.MainModule.ImportReference(typeof(void))); funcDef.Body.InitLocals = false; #if !UNITY_DOTSRUNTIME if (!Defines.Contains("UNITY_EDITOR")) { // Needs to run automatically in the player, but we need to // exclude this attribute when building for the editor, or // it will re-run the registration for every enter play mode. var loadTypeEnumType = mod.ImportReference(typeof(UnityEngine.RuntimeInitializeLoadType)); var attributeCtor = mod.ImportReference(typeof(UnityEngine.RuntimeInitializeOnLoadMethodAttribute).GetConstructor(new[] { typeof(UnityEngine.RuntimeInitializeLoadType) })); var attribute = new CustomAttribute(attributeCtor); attribute.ConstructorArguments.Add(new CustomAttributeArgument(loadTypeEnumType, UnityEngine.RuntimeInitializeLoadType.AfterAssembliesLoaded)); funcDef.CustomAttributes.Add(attribute); } if (Defines.Contains("UNITY_EDITOR")) { // Needs to run automatically in the editor. var attributeCtor2 = AssemblyDefinition.MainModule.ImportReference(typeof(UnityEditor.InitializeOnLoadMethodAttribute).GetConstructor(Type.EmptyTypes)); funcDef.CustomAttributes.Add(new CustomAttribute(attributeCtor2)); } #endif classDef.Methods.Add(funcDef); var processor = funcDef.Body.GetILProcessor(); var registryType = mod.ImportReference(typeof(SystemBaseRegistry)).Resolve(); var addMethod = mod.ImportReference(registryType.Methods.FirstOrDefault((x) => x.Name == nameof(SystemBaseRegistry.AddUnmanagedSystemType))); var delegateCtor = mod.ImportReference(registryType.NestedTypes.FirstOrDefault((x) => x.Name == nameof(SystemBaseRegistry.ForwardingFunc)).GetConstructors().FirstOrDefault((x) => x.Parameters.Count == 2)); var genericHashFunc = mod.ImportReference(typeof(BurstRuntime)).Resolve().Methods.FirstOrDefault((x) => x.Name == nameof(BurstRuntime.GetHashCode64) && x.HasGenericParameters); var typeType = mod.ImportReference(typeof(Type)).Resolve(); var getTypeFromHandle = mod.ImportReference(typeType.Methods.FirstOrDefault((x) => x.Name == "GetTypeFromHandle")); foreach (var memo in memos) { // This craziness is equivalent to typeof(n) processor.Emit(OpCodes.Ldtoken, memo.m_SystemType); processor.Emit(OpCodes.Call, getTypeFromHandle); processor.Emit(OpCodes.Call, mod.ImportReference(genericHashFunc.MakeGenericInstanceMethod(memo.m_SystemType))); for (int i = 0; i < memo.m_Wrappers.Length; ++i) { if (memo.m_Wrappers[i] != null) { processor.Emit(OpCodes.Ldnull); processor.Emit(OpCodes.Ldftn, memo.m_Wrappers[i]); processor.Emit(OpCodes.Newobj, delegateCtor); } else { processor.Emit(OpCodes.Ldnull); } } processor.Emit(OpCodes.Ldstr, memo.m_SystemType.Name); processor.Emit(OpCodes.Ldc_I4, memo.m_BurstCompileBits); processor.Emit(OpCodes.Call, addMethod); } processor.Emit(OpCodes.Ret); }
private TypeMemo AddStaticForwarders(TypeDefinition systemType) { var mod = systemType.Module; var intPtrRef = mod.ImportReference(typeof(IntPtr)); var intPtrToVoid = mod.ImportReference(intPtrRef.Resolve().Methods.FirstOrDefault(x => x.Name == nameof(IntPtr.ToPointer))); TypeMemo memo = default; memo.m_SystemType = systemType; memo.m_Wrappers = new MethodDefinition[5]; var hasStartStop = systemType.Interfaces.Any((x) => x.InterfaceType.FullName == "Unity.Entities.ISystemBaseStartStop"); for (int i = 0; i < MethodNames.Length; ++i) { var name = MethodNames[i]; var fullName = MethodFullNames[i]; // Cecil sees interface method names from other assemblies as the full namespaced name if (!hasStartStop && i >= 3) { break; } var methodDef = new MethodDefinition(GeneratedPrefix + name, MethodAttributes.Static | MethodAttributes.Assembly, mod.ImportReference(typeof(void))); methodDef.Parameters.Add(new ParameterDefinition("self", ParameterAttributes.None, intPtrRef)); methodDef.Parameters.Add(new ParameterDefinition("state", ParameterAttributes.None, intPtrRef)); var targetMethod = systemType.Methods.FirstOrDefault(x => x.Parameters.Count == 1 && (x.Name == name || x.Name == fullName)); if (targetMethod == null) { continue; } // Transfer any BurstCompile attribute from target function to the forwarding wrapper var burstAttribute = targetMethod.CustomAttributes.FirstOrDefault(x => x.Constructor.DeclaringType.Name == nameof(BurstCompileAttribute)); if (burstAttribute != null) { methodDef.CustomAttributes.Add(new CustomAttribute(burstAttribute.Constructor, burstAttribute.GetBlob())); memo.m_BurstCompileBits |= 1 << i; } #if UNITY_DOTSRUNTIME // Burst CompileFunctionPointer in DOTS Runtime will not currently decorate methods as [MonoPInvokeCallback] // so we add that here until that is supported var monoPInvokeCallbackAttributeConstructor = typeof(Jobs.MonoPInvokeCallbackAttribute).GetConstructor(Type.EmptyTypes); methodDef.CustomAttributes.Add(new CustomAttribute(mod.ImportReference(monoPInvokeCallbackAttributeConstructor))); #else // Adding MonoPInvokeCallbackAttribute needed for IL2CPP to work when burst is disabled var monoPInvokeCallbackAttributeConstructors = typeof(MonoPInvokeCallbackAttribute).GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var monoPInvokeCallbackAttribute = new CustomAttribute(mod.ImportReference(monoPInvokeCallbackAttributeConstructors[0])); monoPInvokeCallbackAttribute.ConstructorArguments.Add(new CustomAttributeArgument(mod.ImportReference(typeof(Type)), mod.ImportReference(typeof(SystemBaseDelegates.Function)))); methodDef.CustomAttributes.Add(monoPInvokeCallbackAttribute); #endif var processor = methodDef.Body.GetILProcessor(); processor.Emit(OpCodes.Ldarga, 0); processor.Emit(OpCodes.Call, intPtrToVoid); processor.Emit(OpCodes.Ldarga, 1); processor.Emit(OpCodes.Call, intPtrToVoid); processor.Emit(OpCodes.Call, targetMethod); processor.Emit(OpCodes.Ret); systemType.Methods.Add(methodDef); memo.m_Wrappers[i] = methodDef; } return(memo); }
private static bool IsAsyncStateMachineAttribute(CustomAttribute customAttribute) { return(String.op_Equality(customAttribute.get_AttributeType().get_FullName(), "System.Runtime.CompilerServices.AsyncStateMachineAttribute")); }
public static MethodDefinition ProcessEventCall(TypeDefinition td, EventDefinition ed, CustomAttribute ca) { var invoke = Resolvers.ResolveMethod(ed.EventType, Weaver.CurrentAssembly, "Invoke"); var evt = new MethodDefinition("Call" + ed.Name, MethodAttributes.Public | MethodAttributes.HideBySig, Weaver.voidType); // add paramters foreach (var pd in invoke.Parameters) { evt.Parameters.Add(new ParameterDefinition(pd.Name, ParameterAttributes.None, pd.ParameterType)); } var evtWorker = evt.Body.GetILProcessor(); var label = evtWorker.Create(OpCodes.Nop); NetworkBehaviourProcessor.WriteSetupLocals(evtWorker); NetworkBehaviourProcessor.WriteServerActiveCheck(evtWorker, ed.Name, label, "Event"); NetworkBehaviourProcessor.WriteCreateWriter(evtWorker); // write all the arguments that the user passed to the syncevent if (!NetworkBehaviourProcessor.WriteArguments(evtWorker, invoke.Resolve(), false)) { return(null); } // invoke interal send and return evtWorker.Append(evtWorker.Create(OpCodes.Ldarg_0)); // this evtWorker.Append(evtWorker.Create(OpCodes.Ldtoken, td)); evtWorker.Append(evtWorker.Create(OpCodes.Call, Weaver.getTypeFromHandleReference)); // invokerClass evtWorker.Append(evtWorker.Create(OpCodes.Ldstr, ed.Name)); evtWorker.Append(evtWorker.Create(OpCodes.Ldloc_0)); // writer evtWorker.Append(evtWorker.Create(OpCodes.Ldc_I4, NetworkBehaviourProcessor.GetChannelId(ca))); evtWorker.Append(evtWorker.Create(OpCodes.Call, Weaver.sendEventInternal)); NetworkBehaviourProcessor.WriteRecycleWriter(evtWorker); evtWorker.Append(evtWorker.Create(OpCodes.Ret)); return(evt); }