public static bool ShouldImplementIDeserializable(TypeReference typeDeclaration) { if (typeDeclaration.FullName == "UnityEngine.ExposedReference`1") { return(true); } if (IsNonSerialized(typeDeclaration)) { return(false); } try { if (UnityEngineTypePredicates.ShouldHaveHadSerializableAttribute(typeDeclaration)) { return(true); } var resolvedTypeDeclaration = typeDeclaration.CheckedResolve(); if (resolvedTypeDeclaration.IsValueType) { return(resolvedTypeDeclaration.IsSerializable && !resolvedTypeDeclaration.CustomAttributes.Any(a => a.AttributeType.FullName.Contains("System.Runtime.CompilerServices.CompilerGenerated"))); } else { return((resolvedTypeDeclaration.IsSerializable && !resolvedTypeDeclaration.CustomAttributes.Any(a => a.AttributeType.FullName.Contains("System.Runtime.CompilerServices.CompilerGenerated"))) || resolvedTypeDeclaration.IsSubclassOf(UnityEngineTypePredicates.MonoBehaviour, UnityEngineTypePredicates.ScriptableObject)); } } catch (Exception) { return(false); } }
internal static bool HasAttributeOrFieldWithAttribute(this TypeReference type, Type checkAttribute) { var typeDef = type.CheckedResolve(); if (HasAttribute(typeDef, checkAttribute)) { return(true); } return(typeDef.Fields.Any(f => { if (f.IsStatic) { return false; } if (f.FieldType.IsPrimitive) { return false; } if (f.FieldType is GenericParameter) { return false; } if (f.FieldType is PointerType) { return false; } if (f.FieldType is ArrayType) { return false; } return f.FieldType.HasAttributeOrFieldWithAttribute(checkAttribute); })); }
public static bool IsAssignableTo(this TypeReference typeRef, string typeName) { bool result; try { if (typeRef.IsGenericInstance) { result = ElementType.For(typeRef).IsAssignableTo(typeName); } else if (typeRef.FullName == typeName) { result = true; } else { result = typeRef.CheckedResolve().IsSubclassOf(typeName); } } catch (AssemblyResolutionException) { result = false; } return(result); }
public static IEnumerable <TypeDefinition> TypeAndBaseTypesOf(TypeReference typeReference) { while (typeReference != null) { var typeDefinition = typeReference.CheckedResolve(); yield return(typeDefinition); typeReference = typeDefinition.BaseType; } }
public static bool ShouldImplementIDeserializable(TypeReference typeDeclaration) { if (typeDeclaration.FullName == "UnityEngine.ExposedReference`1") { return(true); } if (IsNonSerialized(typeDeclaration)) { return(false); } var genericInstance = typeDeclaration as GenericInstanceType; if (genericInstance != null) { if (genericInstance.ElementType.FullName == "UnityEngine.ExposedReference`1") { return(true); } return(false); } try { return(UnityEngineTypePredicates.IsMonoBehaviour(typeDeclaration) || UnityEngineTypePredicates.IsScriptableObject(typeDeclaration) || (typeDeclaration.CheckedResolve().IsSerializable&& !typeDeclaration.CheckedResolve().IsAbstract&& !typeDeclaration.CheckedResolve().CustomAttributes.Any(a => a.AttributeType.FullName.Contains("System.Runtime.CompilerServices.CompilerGenerated"))) || UnityEngineTypePredicates.ShouldHaveHadSerializableAttribute(typeDeclaration)); } catch (Exception) { return(false); } }
public static bool IsAssignableTo(this TypeReference typeRef, string typeName) { try { if (typeRef.IsGenericInstance) { return(ElementType.For(typeRef).IsAssignableTo(typeName)); } return((typeRef.FullName == typeName) || typeRef.CheckedResolve().IsSubclassOf(typeName)); } catch (AssemblyResolutionException) { return(false); } }
private bool VisitJobStructs(TypeReference t, ILProcessor processor, MethodBody body) { if (t.GenericParameters.Count > 0) { // Generic jobs need to be either reference in fully closed form, or registered explicitly with an attribute. return(false); } var rt = t.CheckedResolve(); bool didAnything = false; if (rt.HasInterfaces) { foreach (var iface in rt.Interfaces) { var idef = iface.InterfaceType.CheckedResolve(); if (!idef.HasCustomAttributes) { continue; } foreach (var attr in idef.CustomAttributes) { if (attr.AttributeType.FullName != ProducerAttributeName) { continue; } var producerRef = (TypeReference)attr.ConstructorArguments[0].Value; var launderedType = LaunderTypeRef(t); didAnything |= GenerateCalls(producerRef, launderedType, body, processor); } } } foreach (var nestedType in rt.NestedTypes) { didAnything |= VisitJobStructs(nestedType, processor, body); } return(didAnything); }
public static bool IsAssignableTo(this TypeReference typeRef, string typeName) { try { if (typeRef.IsGenericInstance) { return(ElementType.For(typeRef).IsAssignableTo(typeName)); } if (typeRef.FullName == typeName) { return(true); } return(typeRef.CheckedResolve().IsSubclassOf(typeName)); } catch (AssemblyResolutionException) // If we can't resolve our typeref or one of its base types, { // let's assume it is not assignable to our target type return(false); } }
private bool VisitJobStructs(TypeReference t, ILProcessor processor, MethodBody body, HashSet <string> declaredGenerics) { var rt = t.CheckedResolve(); bool didAnything = false; if (rt.HasInterfaces) { foreach (var iface in rt.Interfaces) { var idef = iface.InterfaceType.CheckedResolve(); if (!idef.HasCustomAttributes) { continue; } foreach (var attr in idef.CustomAttributes) { if (attr.AttributeType.FullName != ProducerAttributeName) { continue; } var producerRef = (TypeReference)attr.ConstructorArguments[0].Value; didAnything |= GenerateCalls(producerRef, t, body, processor, declaredGenerics); } } } foreach (var nestedType in rt.NestedTypes) { didAnything |= VisitJobStructs(nestedType, processor, body, declaredGenerics); } return(didAnything); }
private bool GenerateCalls(TypeReference producerRef, TypeReference jobStructType, MethodBody body, ILProcessor processor, HashSet <string> declaredGenerics) { try { var carrierType = producerRef.CheckedResolve(); MethodDefinition methodToCall = null; while (carrierType != null) { methodToCall = carrierType.GetMethods().FirstOrDefault((x) => x.Name == "EarlyJobInit" && x.Parameters.Count == 0 && x.IsStatic && x.IsPublic); if (methodToCall != null) { break; } carrierType = carrierType.DeclaringType; } // Legacy jobs lazy initialize. if (methodToCall == null) { return(false); } // We need a separate solution for generic jobs if (jobStructType.HasGenericParameters) { if (!declaredGenerics.Contains(jobStructType.FullName)) { AddDiagnostic(UserError.DC3002(jobStructType)); } return(false); } var asm = AssemblyDefinition.MainModule; var errorHandler = asm.ImportReference((asm.ImportReference(typeof(EarlyInitHelpers)).Resolve().Methods.First(x => x.Name == nameof(EarlyInitHelpers.JobReflectionDataCreationFailed)))); var typeType = asm.ImportReference(typeof(Type)).CheckedResolve(); var getTypeFromHandle = asm.ImportReference(typeType.Methods.FirstOrDefault((x) => x.Name == "GetTypeFromHandle")); var mref = asm.ImportReference(asm.ImportReference(methodToCall).MakeGenericInstanceMethod(jobStructType)); var callInsn = Instruction.Create(OpCodes.Call, mref); var handler = Instruction.Create(OpCodes.Nop); var landingPad = Instruction.Create(OpCodes.Nop); processor.Append(callInsn); processor.Append(handler); // This craziness is equivalent to typeof(n) processor.Append(Instruction.Create(OpCodes.Ldtoken, jobStructType)); processor.Append(Instruction.Create(OpCodes.Call, getTypeFromHandle)); processor.Append(Instruction.Create(OpCodes.Call, errorHandler)); processor.Append(landingPad); var leaveSuccess = Instruction.Create(OpCodes.Leave, landingPad); var leaveFail = Instruction.Create(OpCodes.Leave, landingPad); processor.InsertAfter(callInsn, leaveSuccess); processor.InsertBefore(landingPad, leaveFail); var exc = new ExceptionHandler(ExceptionHandlerType.Catch); exc.TryStart = callInsn; exc.TryEnd = leaveSuccess.Next; exc.HandlerStart = handler; exc.HandlerEnd = leaveFail.Next; exc.CatchType = asm.ImportReference(typeof(Exception)); body.ExceptionHandlers.Add(exc); return(true); } catch (Exception ex) { AddDiagnostic(InternalCompilerError.DCICE300(producerRef, jobStructType, ex)); } return(false); }
public static bool IsSubclassOf(this TypeDefinition type, string baseTypeName) { TypeReference baseType = type.BaseType; return(baseType != null && (baseType.FullName == baseTypeName || baseType.CheckedResolve().IsSubclassOf(baseTypeName))); }
public static bool IsScriptableObject(TypeReference type) { return(IsScriptableObject(type.CheckedResolve())); }
public static bool IsMonoBehaviour(TypeReference type) { return(IsMonoBehaviour(type.CheckedResolve())); }
public static bool IsScriptableObject(TypeReference type) { return(UnityEngineTypePredicates.IsScriptableObject(type.CheckedResolve())); }
public static bool IsMonoBehaviour(TypeReference type) { return(UnityEngineTypePredicates.IsMonoBehaviour(type.CheckedResolve())); }
public static bool IsEnum(this TypeReference type) { return(type.IsValueType && !type.IsPrimitive && type.CheckedResolve().IsEnum); }