private TypeDefinition GenerateTypeA(AssemblyDefinition assembly) { var objType = assembly.MainModule.Import(typeof (object)); // define base class var aType = new TypeDefinition("A", "", TypeAttributes.Class, objType); assembly.MainModule.Types.Add(aType); var typeParameter = new GenericParameter("T", aType); aType.GenericParameters.Add(typeParameter); var baseMethod = new MethodDefinition("Get", MethodAttributes.Assem | MethodAttributes.Virtual | MethodAttributes.NewSlot, typeParameter); aType.Methods.Add(baseMethod); baseMethod.DeclaringType = aType; var local = new VariableDefinition(typeParameter); baseMethod.Body.Variables.Add(local); var cil = baseMethod.Body.CilWorker; cil.Emit(OpCodes.Ldloca, local); cil.Emit(OpCodes.Initobj, typeParameter); cil.Emit(OpCodes.Ldloc, local); cil.Emit(OpCodes.Ret); return aType; }
public SystemTypeForGenericParameterValue(GenericParameter genericParameter, DynamicallyAccessedMemberTypes dynamicallyAccessedMemberTypes) { Kind = ValueNodeKind.SystemTypeForGenericParameter; GenericParameter = genericParameter; DynamicallyAccessedMemberTypes = dynamicallyAccessedMemberTypes; SourceContext = genericParameter; }
public AnalysisNet.Types.IGenericParameterReference GetGenericParameter(Cecil.GenericParameter cecilParameter) { Cecil.IGenericParameterProvider owner = cecilParameter.Owner; if (genericParamsMap.TryGetValue(owner, out GenericParameterMap map)) { return(map[cecilParameter.Position]); } // populates map if (cecilParameter.Type == Cecil.GenericParameterType.Method) { typeExtractor.ExtractMethod(owner as Cecil.MethodReference); } else { // check my assumption if ((owner is Cecil.GenericInstanceType)) { throw new Exception(); } typeExtractor.ExtractType(owner as Cecil.TypeReference); } map = genericParamsMap[owner]; return(map[cecilParameter.Position]); }
/// <summary> /// Default ctor /// </summary> public ILGenericParameter(XModule module, GenericParameter p) : base(module) { this.p = p; constraints = new Lazy<XTypeReference[]>(()=> p.Constraints.Select(k=>AsTypeReference(module, k)).ToArray()); }
/// <summary> /// Clones the specified generic parameter. /// </summary> /// <param name="genericParameter">The generic parameter.</param> /// <param name="methodDefinition">The method definition.</param> /// <returns></returns> public static GenericParameter Clone(this GenericParameter genericParameter, MethodDefinition methodDefinition) { var newGenericParameter = new GenericParameter(methodDefinition); newGenericParameter.Attributes = genericParameter.Attributes; newGenericParameter.Name = genericParameter.Name; return newGenericParameter; }
public static int GetIndexOfGenericParameter(MethodDefinition method, GenericParameter parameter) { if (parameter.IsGenericParameter) { // Genetic parameter has origin on method? for (var index = 0; index < method.GenericParameters.Count; index++) { if (method.GenericParameters[index].MetadataToken == parameter.MetadataToken) { return index; } } // Genetic parameter has origin on declared type? for (var index = 0; index < method.DeclaringType.GenericParameters.Count; index++) { if (method.DeclaringType.GenericParameters[index].MetadataToken == parameter.MetadataToken) { return index; } } } throw new InvalidOperationException("Could not find generic parameter."); }
/// <summary> /// Resolve the given generic parameter to a generic argument. /// </summary> public TypeReference Resolve(GenericParameter gp) { var owner = gp.Owner as TypeReference; if (owner == null) return gp; // Do not resolve generic method parameters for now // Try to resolve the owner var ownerDef = owner.GetElementType().Resolve(); if (ownerDef == null) return gp; // Try to find the owner in our map var map = GetTypeToGit(); GenericInstanceType git; if (!map.TryGetValue(ownerDef, out git)) { // No mapping found return gp; } // Replace with the given generic argument var result = git.GenericArguments[gp.Position]; var resultAsGp = result as GenericParameter; return (resultAsGp != null) ? Resolve(resultAsGp) : result; }
public override TypeReference Visit(GenericParameter type) { TypeReference result; if (genericTypeMapping.TryGetValue(type, out result)) return result; return base.Visit(type); }
private TypeReference HandleOwnerlessInvalidILCode(GenericParameter genericParameter) { if (((genericParameter.Type == GenericParameterType.Method) && (this._typeDefinitionContext != null)) && (genericParameter.Position < this._typeDefinitionContext.GenericArguments.Count)) { return this._typeDefinitionContext.GenericArguments[genericParameter.Position]; } return genericParameter.Module.TypeSystem.Object; }
public TypeReference GetGenericParameter(GenericParameter genericParamter, IGenericParameterProvider[] paramProviders) { #if GENERIC IGenericParameterProvider context = GetContext(genericParamter, paramProviders); return context.GenericParameters[genericParamter.Position]; #else return type; #endif }
static TypeReference CreateConstraint (string @namespace, string name, GenericParameter parameter) { return new TypeReference ( @namespace, name, parameter.Module, parameter.Module.AssemblyReferences.First<AssemblyNameReference> (a => a.Name == "mscorlib"), false); }
static void AddConstraintsFromType(ITypeParameter tp, GenericParameter g) { foreach (TypeReference constraint in g.Constraints) { if (tp.Method != null) { tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Method, constraint)); } else { tp.Constraints.Add(CreateType(tp.Class.ProjectContent, tp.Class, constraint)); } } }
private List<GenericConstraint> CreateGenericConstraints(GenericParameter genericParameter) { List<GenericConstraint> result = null; if ((genericParameter.Attributes & GenericParameterAttributes.ReferenceTypeConstraint) == GenericParameterAttributes.ReferenceTypeConstraint) { result = new List<GenericConstraint>(); result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Class)); } else if ((genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == GenericParameterAttributes.NotNullableValueTypeConstraint) { result = new List<GenericConstraint>(); result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.Struct)); } ConstraintCollection baseOrInterfaceConstraints = genericParameter.Constraints; if (baseOrInterfaceConstraints != null) { if (result == null) { result = new List<GenericConstraint>(); } for (int i = 0; i < baseOrInterfaceConstraints.Count; i++) { TypeReference baseTypeOrInterface = baseOrInterfaceConstraints[i]; if (baseTypeOrInterface.FullName == "System.ValueType") { continue; } if (Utils.IsGenericParameter(baseTypeOrInterface)) { result.Add(new NakedTypeConstraint(baseTypeOrInterface.Name)); } else { string[] readableForms = Tools.GetHumanReadableForms(baseTypeOrInterface); result.Add(new TypeGenericConstraint(readableForms[0])); } } } if ((genericParameter.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) == GenericParameterAttributes.DefaultConstructorConstraint && (genericParameter.Attributes & GenericParameterAttributes.NotNullableValueTypeConstraint) == 0) { if (result == null) { result = new List<GenericConstraint>(); } result.Add(new BuiltInGenericConstraint(BuiltInGenericConstraintsTypes.New)); } return result; }
public static bool GenericParameterEquals(GenericParameter genericParameter, GenericParameter genericParameter2) { if (genericParameter.Position != genericParameter.Position) { return false; } if (!TypeReferenceEquals(genericParameter, genericParameter2, false)) { return false; } return true; // TODO: Implement this properly }
private static void CloneGenericParameterProperties(GenericParameter genericParameter, GenericParameter newGenericParameter) { newGenericParameter.Attributes = genericParameter.Attributes; genericParameter.Constraints.ForEach(gp => newGenericParameter.Constraints.Add(gp)); genericParameter.CustomAttributes.ForEach(ca => newGenericParameter.CustomAttributes.Add(ca)); newGenericParameter.DeclaringType = genericParameter.DeclaringType; genericParameter.GenericParameters.ForEach(gp => newGenericParameter.GenericParameters.Add(gp)); newGenericParameter.HasDefaultConstructorConstraint = genericParameter.HasDefaultConstructorConstraint; newGenericParameter.IsContravariant = genericParameter.IsContravariant; newGenericParameter.IsCovariant = genericParameter.IsCovariant; newGenericParameter.IsNonVariant = genericParameter.IsNonVariant; }
private AnalysisNet.Types.GenericParameterKind GetKind(Cecil.GenericParameter cecilContainer) { if (cecilContainer.Type == Cecil.GenericParameterType.Type) { return(AnalysisNet.Types.GenericParameterKind.Type); } else if (cecilContainer.Type == Cecil.GenericParameterType.Method) { return(AnalysisNet.Types.GenericParameterKind.Method); } throw new NotImplementedException(); }
private AnalysisNet.Types.TypeKind GetGenericParameterTypeKind(Cecil.GenericParameter parameterdef) { AnalysisNet.Types.TypeKind result; if (parameterdef.IsValueType) { result = AnalysisNet.Types.TypeKind.ValueType; } else { result = AnalysisNet.Types.TypeKind.ReferenceType; } return(result); }
internal static GenericParameterVariance GetVariance(this GenericParameter genericParameter) { if (genericParameter.IsCovariant) { return(GenericParameterVariance.Covariant); } if (genericParameter.IsContravariant) { return(GenericParameterVariance.Contravariant); } return(GenericParameterVariance.NonVariant); }
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); }
private void ExtractGenericTypeParameters(AnalysisNet.Types.IGenericDefinition definingType, Cecil.TypeDefinition typedef) { for (int i = 0; i < typedef.GenericParameters.Count; ++i) { Cecil.GenericParameter parameterdef = typedef.GenericParameters[i]; ushort index = (ushort)i; string name = parameterdef.Name; AnalysisNet.Types.TypeKind typeKind = GetGenericParameterTypeKind(parameterdef); AnalysisNet.Types.GenericParameter parameter = new AnalysisNet.Types.GenericParameter(AnalysisNet.Types.GenericParameterKind.Type, index, name, typeKind); ExtractCustomAttributes(parameter.Attributes, parameterdef.CustomAttributes); parameter.GenericContainer = definingType; definingType.GenericParameters.Add(parameter); parameter.Constraints.AddRange(parameterdef.Constraints.Select(c => ExtractType(c.ConstraintType))); } }
public void MapGenericParameters(Cecil.IGenericParameterProvider cecilContainer, AnalysisNet.Types.IGenericReference analysisNetContainer) { GenericParameterMap map = new GenericParameterMap(); for (int i = 0; i < cecilContainer.GenericParameters.Count; i++) { Cecil.GenericParameter cecilParam = cecilContainer.GenericParameters.ElementAt(i); AnalysisNet.Types.GenericParameterReference analysisNetParam = new AnalysisNet.Types.GenericParameterReference(GetKind(cecilParam), (ushort)cecilParam.Position) { GenericContainer = analysisNetContainer }; map[i] = analysisNetParam; } genericParamsMap[cecilContainer] = map; //throw new NotImplementedException(); }
private static string CollectConstraints(GenericParameter param) { List<string> constraints = new List<string>(); if (param.HasDefaultConstructorConstraint) { constraints.Add("new()"); } if(param.HasReferenceTypeConstraint) { constraints.Add("class"); } constraints.AddRange(param.Constraints.Select(constraint => constraint.ToString())); return string.Join(", ", constraints.ToArray()); }
public static void InjectGenericParameter(this IGenericParameterProvider owner, GenericParameter parameter, ReferenceResolver resolver) { GenericParameter newParameter = new GenericParameter(parameter.Name, owner) { Attributes = parameter.Attributes }; owner.GenericParameters.Add(newParameter); MetadataBuilderHelper.CopyCustomAttributes(newParameter, parameter, resolver); foreach (var constraint in parameter.Constraints) { if (owner is MethodReference) newParameter.Constraints.Add(resolver.ReferenceType(constraint, owner, ((MethodReference)owner).DeclaringType)); else newParameter.Constraints.Add(resolver.ReferenceType(constraint, owner)); } }
static void Process (GenericParameter parameter) { if (!parameter.HasCustomAttributes) return; var attributes = parameter.CustomAttributes; for (int i = 0; i < attributes.Count; i++) { var attribute = attributes [i]; if (IsDelegateConstraintAttribute (attribute)) { parameter.Attributes = GenericParameterAttributes.NonVariant; parameter.Constraints.Clear (); parameter.Constraints.Add (CreateConstraint ("System", "Delegate", parameter)); attributes.RemoveAt (i--); } else if (IsEnumConstraintAttribute (attribute)) { parameter.Attributes = GenericParameterAttributes.NonVariant; parameter.Constraints.Clear (); parameter.Constraints.Add (CreateConstraint ("System", "Enum", parameter)); attributes.RemoveAt (i--); } } }
public MethodReference GetCallableObjectFactoryCreateMethod(AssemblyDefinition assemblyDef, ModuleDefinition moduleDefinition, TypeReference instantiatedType, IAssemblyTracker tracker) { var tempRef = GetOrCreateRemotionInterfacesReference (assemblyDef, moduleDefinition, tracker); var objectFactoryReference = new TypeReference (_objectFactoryNamespace, _objectFactoryName, moduleDefinition, tempRef); var paramListReference = new TypeReference (_paramListNamespace, _paramListName, moduleDefinition, tempRef); var createReference = new MethodReference ("Create", moduleDefinition.TypeSystem.Void, objectFactoryReference); var createTypeParam = new GenericParameter ("T", createReference); createReference.GenericParameters.Add (createTypeParam); createReference.ReturnType = createTypeParam; createReference.Parameters.Add (new ParameterDefinition (moduleDefinition.TypeSystem.Boolean)); createReference.Parameters.Add (new ParameterDefinition (paramListReference)); createReference.Parameters.Add (new ParameterDefinition (new ArrayType (moduleDefinition.TypeSystem.Object))); var instanceMethod = new GenericInstanceMethod (createReference); instanceMethod.GenericArguments.Add (instantiatedType); return instanceMethod; }
public TypeDefinition GenerateClass() { var commandClass = new TypeDefinition( GeneratedCommandClassNamespace , GeneratedCommandClassName , DefaultTypeAttributesForCommand , Assets.TypeReferences.Object); commandClass.Interfaces.Add(Assets.TypeReferences.ICommand); var genericParameter = new GenericParameter("TParameter", commandClass); commandClass.GenericParameters.Add(genericParameter); AddFields(commandClass); AddConstructors(commandClass); AddExecuteMethod(commandClass); AddCanExecuteMethod(commandClass); Assets.AddCanExecuteChangedEvent(commandClass); ModuleDefinition.Types.Add(commandClass); Assets.DelegateCommandImplementationWasInjected = true; return commandClass; }
void Process(GenericParameter parameter) { var hasDelegateConstraint = false; var hasEnumConstraint = false; var attributes = parameter.CustomAttributes; for (var i = 0; i < attributes.Count; i++) { var attribute = attributes[i]; if (IsDelegateConstraintAttribute(attribute)) { hasDelegateConstraint = true; parameter.Attributes = GenericParameterAttributes.NonVariant; parameter.Constraints.Clear(); var typeReference = GetDelegateType(attribute, parameter); parameter.Constraints.Add(typeReference); attributes.RemoveAt(i--); } else if (IsEnumConstraintAttribute(attribute)) { hasEnumConstraint = true; parameter.Attributes = GenericParameterAttributes.NonVariant | GenericParameterAttributes.NotNullableValueTypeConstraint; parameter.Constraints.Clear(); var typeReference = GetEnumType(attribute, parameter); parameter.Constraints.Add(typeReference); attributes.RemoveAt(i--); } } if (hasDelegateConstraint && hasEnumConstraint) { throw new WeavingException("Cannot contain both [EnumConstraint] and [DelegateConstraint]."); } }
private TypeReference GetFixedReturnType(TypeReference type) { if (type == null) { return(null); } if (type.IsOptionalModifier) { OptionalModifierType omt = (OptionalModifierType)type; TypeReference fixedElement = GetFixedReturnType(omt.ElementType); return(new OptionalModifierType(omt.ModifierType, fixedElement)); } if (type.IsRequiredModifier) { RequiredModifierType rmt = (RequiredModifierType)type; TypeReference fixedElement = GetFixedReturnType(rmt.ElementType); return(new RequiredModifierType(rmt.ModifierType, fixedElement)); } if (type.IsGenericParameter) { return(GetActualType(type)); } if (type.IsArray) { ArrayType at = (ArrayType)type; int rank = at.Rank; TypeReference arrayElementType = at.ElementType; arrayElementType = GetFixedReturnType(arrayElementType); return(new ArrayType(arrayElementType, rank)); } if (type.IsPointer) { TypeReference fixedElement = GetFixedReturnType(((PointerType)type).ElementType); return(new PointerType(fixedElement)); } if (type.IsByReference) { TypeReference fixedElement = GetFixedReturnType(((ByReferenceType)type).ElementType); return(new ByReferenceType(fixedElement)); } if (type.IsGenericInstance && DeclaringType.IsGenericInstance) { GenericInstanceType result = type as GenericInstanceType; GenericInstanceType declaringTypeGenericInstance = DeclaringType as GenericInstanceType; TypeReference declaringElementType = DeclaringType.GetElementType(); for (int i = 0; i < result.GenericArguments.Count; i++) { GenericParameter currentParam = result.GenericArguments[i] as GenericParameter; if (currentParam != null && currentParam.Owner == declaringElementType) { if (declaringTypeGenericInstance.PostionToArgument.ContainsKey(currentParam.Position)) { result.ReplaceGenericArgumentAt(i, declaringTypeGenericInstance.PostionToArgument[currentParam.position]); } } } return(result); } return(type); }
private static TypeReference ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericParameter genericParameterElement) { return((genericParameterElement.MetadataType == MetadataType.MVar) ? (genericInstanceMethod != null ? genericInstanceMethod.GenericArguments[genericParameterElement.Position] : genericParameterElement) : genericInstanceType.GenericArguments[genericParameterElement.Position]); }
public void RemoveGenericConstraintMapping(GenericParameter generic_parameter) { GenericConstraints.Remove(generic_parameter.token.RID); }
static bool AreSame(GenericParameter a, GenericParameter b) { return a.Position == b.Position; }
protected override TypeReference[] GetInterfaces(GenericParameter[] genericParameters) => new[] { !SourceType.HasGenericParameters ? Context.ModuleDefinition.Import(SourceType) : Context.ModuleDefinition.Import(SourceType).MakeGenericInstanceType(genericParameters) };
private AnalysisNet.Types.IGenericParameterReference ExtractType(Cecil.GenericParameter typeref) { return(genericParameterExtractor.GetGenericParameter(typeref)); }
public RuntimeTypeHandleForGenericParameterValue(GenericParameter genericParameter) { Kind = ValueNodeKind.RuntimeTypeHandleForGenericParameter; GenericParameter = genericParameter; }
public void Add(GenericParameter value) { List.Add(value); }
public bool Contains(GenericParameter value) { return(List.Contains(value)); }
public int IndexOf(GenericParameter value) { return(List.IndexOf(value)); }
public void Insert(int index, GenericParameter value) { List.Insert(index, value); }
protected virtual void CreateCoroutineType() { var typeGeneric = new GenericParameter [method.DeclaringType.GenericParameters.Count]; var methodGeneric = new GenericParameter [method.GenericParameters.Count]; int i = typeGeneric.Length + methodGeneric.Length; var futureName = string.Format ("__c{0}_{1}_{2}_impl", asyncMethodID++, method.Name.Replace ("`", "$"), string.Join ("_", method.Parameters.Select (p => p.ParameterType.Name.Replace ("`", "$")).ToArray ())); if (i > 0) futureName += string.Format ("`{0}", i); coroutineType = new TypeDefinition (null, futureName, Mono.Cecil.TypeAttributes.NestedPrivate | Mono.Cecil.TypeAttributes.Sealed | Mono.Cecil.TypeAttributes.BeforeFieldInit); //if (debug) // coroutineType.CustomAttributes.Add (new CustomAttribute (module.Import (compilerGenerated))); // copy all generic parameters from method's containing type and method into new coroutinefuture type for (i = 0; i < typeGeneric.Length; i++) { typeGeneric [i] = new GenericParameter (method.DeclaringType.GenericParameters [i].Name, coroutineType); foreach (var constraint in method.DeclaringType.GenericParameters [i].Constraints) typeGeneric [i].Constraints.Add (constraint); foreach (var attr in method.DeclaringType.GenericParameters [i].CustomAttributes) typeGeneric [i].CustomAttributes.Add (attr); coroutineType.GenericParameters.Add (typeGeneric [i]); } for (i = 0; i < methodGeneric.Length; i++) { methodGeneric [i] = new GenericParameter (method.GenericParameters [i].Name, coroutineType); foreach (var constraint in method.GenericParameters [i].Constraints) methodGeneric [i].Constraints.Add (constraint); foreach (var attr in method.GenericParameters [i].CustomAttributes) methodGeneric [i].CustomAttributes.Add (attr); coroutineType.GenericParameters.Add (methodGeneric [i]); } if (typeGeneric.Length != 0 || methodGeneric.Length != 0) { genType = new GenericInstanceType (coroutineType); foreach (var genParam in coroutineType.GenericParameters) genType.GenericArguments.Add (genParam); } // add fields for original method's "this" and other arguments.. i = 0; string name; FieldDefinition fld; if (method.HasThis) { var thisType = method.DeclaringType.MakeGeneric (typeGeneric); argsFields [0] = fld = new FieldDefinition ("$ths", Mono.Cecil.FieldAttributes.Private | Mono.Cecil.FieldAttributes.InitOnly, thisType); coroutineType.Fields.Add (fld); if (genType != null) argsFields [0] = new FieldReference (fld.Name, fld.FieldType, genType); i = 1; } foreach (var arg in method.Parameters) { var paramType = arg.ParameterType.CopyGeneric (coroutineType, skews); name = "$a" + i; if (debug) name = arg.Name ?? name; argsFields [i] = fld = new FieldDefinition (name, Mono.Cecil.FieldAttributes.Private, paramType); coroutineType.Fields.Add (fld); if (genType != null) argsFields [i] = new FieldReference (fld.Name, fld.FieldType, genType); i++; } // create a field for each local i = 0; foreach (var local in method.Body.Variables) { name = "$l" + i; if (debug) name = local.Name ?? name; localsFields [i] = fld = new FieldDefinition (name, Mono.Cecil.FieldAttributes.Private, local.VariableType.CopyGeneric (coroutineType, skews)); coroutineType.Fields.Add (fld); if (genType != null) localsFields [i] = new FieldReference (fld.Name, fld.FieldType, genType); i++; } }
private string GetGenericParameterName(GenericParameter genericParameter) { if (genericParameter.Owner is TypeReference) { return "!" + genericParameter.Position; } else { return "!!" + genericParameter.Position; } }
public ConstraintCollection(GenericParameter container) { m_container = container; }
private TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context) { switch (type.etype) { case ElementType.SzArray: { ArrayType arrayType = (ArrayType)type; return(new ArrayType(ImportType(arrayType.ElementType, context))); } case ElementType.Ptr: { PointerType pointerType = (PointerType)type; return(new PointerType(ImportType(pointerType.ElementType, context))); } case ElementType.ByRef: { ByReferenceType byReferenceType = (ByReferenceType)type; return(new ByReferenceType(ImportType(byReferenceType.ElementType, context))); } case ElementType.Pinned: { PinnedType pinnedType = (PinnedType)type; return(new PinnedType(ImportType(pinnedType.ElementType, context))); } case ElementType.Sentinel: { SentinelType sentinelType = (SentinelType)type; return(new SentinelType(ImportType(sentinelType.ElementType, context))); } case ElementType.FnPtr: { FunctionPointerType functionPointerType = (FunctionPointerType)type; FunctionPointerType functionPointerType2 = new FunctionPointerType { HasThis = functionPointerType.HasThis, ExplicitThis = functionPointerType.ExplicitThis, CallingConvention = functionPointerType.CallingConvention, ReturnType = ImportType(functionPointerType.ReturnType, context) }; if (!functionPointerType.HasParameters) { return(functionPointerType2); } for (int j = 0; j < functionPointerType.Parameters.Count; j++) { functionPointerType2.Parameters.Add(new ParameterDefinition(ImportType(functionPointerType.Parameters[j].ParameterType, context))); } return(functionPointerType2); } case ElementType.CModOpt: { OptionalModifierType optionalModifierType = (OptionalModifierType)type; return(new OptionalModifierType(ImportType(optionalModifierType.ModifierType, context), ImportType(optionalModifierType.ElementType, context))); } case ElementType.CModReqD: { RequiredModifierType requiredModifierType = (RequiredModifierType)type; return(new RequiredModifierType(ImportType(requiredModifierType.ModifierType, context), ImportType(requiredModifierType.ElementType, context))); } case ElementType.Array: { ArrayType arrayType2 = (ArrayType)type; ArrayType arrayType3 = new ArrayType(ImportType(arrayType2.ElementType, context)); if (arrayType2.IsVector) { return(arrayType3); } Collection <ArrayDimension> dimensions = arrayType2.Dimensions; Collection <ArrayDimension> dimensions2 = arrayType3.Dimensions; dimensions2.Clear(); for (int k = 0; k < dimensions.Count; k++) { ArrayDimension arrayDimension = dimensions[k]; dimensions2.Add(new ArrayDimension(arrayDimension.LowerBound, arrayDimension.UpperBound)); } return(arrayType3); } case ElementType.GenericInst: { GenericInstanceType genericInstanceType = (GenericInstanceType)type; GenericInstanceType genericInstanceType2 = new GenericInstanceType(ImportType(genericInstanceType.ElementType, context)); Collection <TypeReference> genericArguments = genericInstanceType.GenericArguments; Collection <TypeReference> genericArguments2 = genericInstanceType2.GenericArguments; for (int i = 0; i < genericArguments.Count; i++) { genericArguments2.Add(ImportType(genericArguments[i], context)); } return(genericInstanceType2); } case ElementType.Var: { GenericParameter genericParameter2 = (GenericParameter)type; if (genericParameter2.DeclaringType == null) { throw new InvalidOperationException(); } return(context.TypeParameter(genericParameter2.DeclaringType.FullName, genericParameter2.Position)); } case ElementType.MVar: { GenericParameter genericParameter = (GenericParameter)type; if (genericParameter.DeclaringMethod == null) { throw new InvalidOperationException(); } return(context.MethodParameter(context.NormalizeMethodName(genericParameter.DeclaringMethod), genericParameter.Position)); } default: throw new NotSupportedException(type.etype.ToString()); } }
public virtual void VisitGenericParameter(GenericParameter genparam) { }
private static bool AreSame(GenericParameter a, GenericParameter b) => (a.Position == b.Position);
public void OnMethod(MethodDefinition method) { if (method.DeclaringType.IsInterface) { return; } if (!method.HasBody) { if (Verbosity >= 9) { Console.WriteLine("method has no body: " + method.FullName); } return; } if (method.GenericParameters.Count > 0) { if (Verbosity >= Verbosities.SkippingVerbose) { Console.WriteLine(" . Skipping generic method: " + method.FullName); } return; } var processor = method.Body.GetILProcessor(); foreach (var i in method.Body.Instructions.ToArray()) { if (i.OpCode != OpCodes.Callvirt && i.OpCode != OpCodes.Call && i.OpCode != OpCodes.Calli ) { continue; } Mono.Cecil.GenericParameter genPar = null; MethodReference mr = i.Operand as MethodReference; if (mr == null) { throw new Exception("Call method does not have MethodReference as Operand."); } if (!mr.IsGenericInstance) { continue; } if (!mr.FullName.Contains("<")) { // if(Verbosity >= 8) - shouldn't be reached Console.WriteLine("Skipping method that contains no <"); continue; } if (mr.FullName.Contains(" System.")) { if (Verbosity >= Verbosities.Skipping) { Console.WriteLine("Skipping method invocation that contains ' System.': " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } #if CUSTOM // Custom blacklist if (!mr.FullName.Contains(" LionFire.") && !mr.FullName.Contains(" Dycen.")) { if (Verbosity >= Verbosities.Skipping) { Console.WriteLine("Skipping method that is not LionFire or Dycen:" + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } #endif var genPars = mr.Resolve().GenericParameters; // Console.WriteLine("TEMP2 - " + genPars.Count); // var genPars = mr.GetGenericParameters(method.Module); // Console.WriteLine("TEMP " + mr.Name); // Console.WriteLine("TEMP genPars.Count " + genPars.Count); if (genPars.Count != 1) { if (Verbosity >= Verbosities.Warning) { Console.WriteLine("[NS] Replacing methods with more than 1 generic parameter not supported: " + genPars.Count + ": " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } continue; } else { genPar = genPars[0]; // var resolved = genPar.Resolve(); // Console.WriteLine("NEW -- <" + (resolved == null ? "null" : resolved.Name) + ">"); if (Verbosity >= 10) { Console.WriteLine("NEW |- <" + genPar + ">"); } } #region string genericParameter = ...; string genericParameter; Type genericTypeParameter; TypeDefinition genericTypeParameterDefinition = null; { string n = mr.FullName.Split(' ')[1]; n = n.Split(new string[] { "::" }, StringSplitOptions.RemoveEmptyEntries)[1]; int startI = n.IndexOf('<') + 1; int stack = 0; int endI = startI + 1; while (stack > 0 || n[endI] != '>') { if (n[endI] == '<') { stack++; } if (n[endI] == '>') { stack--; } endI++; } int length = endI - startI; genericParameter = n.Substring(startI, length); // if(genericParameter.StartsWith("!!")) // { // int genParAliasIndex = Convert.ToInt32(genericParameter.Substring(2)); // // var genParAlias = genPars[genParAliasIndex]; // // // genericParameter = genParAlias.FullName; // Console.WriteLine("NEW - Generic method alias param: " + genericParameter); // } // if(genericParameter.Contains("<") || genericParameter.Contains(">")) // { // Console.WriteLine("Unsupported generic method ("+mr.FullName+") with generic parameter: " + genericParameter); // skipped++; // continue; // } if (Verbosity >= 8) { Console.WriteLine("Generic method param: " + genericParameter); } genericTypeParameter = Type.GetType(genericParameter, false); //if(genericTypeParameter == null) { foreach (ModuleDefinition modDef in ads.SelectMany(assDef => assDef.Modules)) { // foreach(var modType in modDef.Types) // { // Console.WriteLine("ccc - " + modType); // } genericTypeParameterDefinition = modDef.Types.Where(td => td.FullName == genericParameter // && !td.IsGenericInstance ).FirstOrDefault(); if (genericTypeParameterDefinition != null) { if (Verbosity >= 9) { Console.WriteLine("TODO - got genTD: " + genericTypeParameterDefinition); } break; } } if (genericTypeParameterDefinition == null) { if (Verbosity >= 8) { Console.WriteLine(" x Could not get TypeDefinition for " + genericParameter); } // No continue, this is not a problem } if (genericTypeParameter == null && genericTypeParameterDefinition == null) { if (Verbosity >= Verbosities.Error) { Console.WriteLine(" x - Failed to get Type for " + genericParameter + " in invocation: " + mr.FullName + " in method " + method.FullName); } skipped++; continue; } } } #endregion #if ONLY_VOID_OR_GENPARM // OLD, now other return types are supported if they are the same as replaced method string matchingReturnType = "!!0"; // genericTypeParameter.FullName; if (mr.ReturnType.FullName != "System.Void" && mr.ReturnType.FullName != matchingReturnType) // && mr.ReturnType.FullName != genericTypeParameter.FullName) { if (Verbosity >= 3) { Console.WriteLine(" x generic method doesn't return System.Void or '" + matchingReturnType + "': " + mr.FullName + ", but instead: " + mr.ReturnType.FullName); } continue; } #endif // if(Verbosity >= 9) Console.WriteLine("mr: " + mr.Name); TypeDefinition tr = mr.DeclaringType.Resolve(); MethodDefinition replacementMethod = null; // if(mr.DeclaringType.Name == "MultiType") // { // foreach(MethodDefinition replacementMethod_ in // tr.Methods) // { // Console.WriteLine("z " + replacementMethod_.Name + " " + replacementMethod_.FullName); // } // } bool noCast = false; foreach (MethodDefinition replacementMethod_ in tr.Methods.Where(mr_ => mr_.Name == mr.Name && !mr_.HasGenericParameters)) { noCast = false; // TODO: Verify parameters if (!replacementMethod_.HasParameters) { continue; } if (replacementMethod_.Parameters.Count != mr.Parameters.Count + 1) { if (Verbosity >= 8) { Console.WriteLine(" x - (alt) candidate replacement method has wrong parameter count: " + replacementMethod_.FullName); } continue; } // Console.WriteLine("Replacement param type: "+ replacementMethod_.Parameters[0].ParameterType.FullName); if (replacementMethod_.Parameters[replacementMethod_.Parameters.Count - 1].ParameterType.FullName != "System.Type") { if (Verbosity >= 8) { Console.WriteLine(" x - (alt) candidate replacement does not have Type parameter at the end of parameters : " + replacementMethod_.FullName); } continue; } if (mr.ReturnType.FullName == replacementMethod_.ReturnType.Resolve().FullName) { noCast = true; if (Verbosity >= 9) { Console.WriteLine(" - (alt) generic method and alt method return same type:: " + mr.ReturnType.FullName); } } else if (mr.ReturnType.FullName != "System.Void") // Replacement must return object { if (replacementMethod_.ReturnType.Resolve().FullName != "System.Object") { if (Verbosity >= 3) { Console.WriteLine(" [x?] (alt) generic method returns T but candidate replacement method does not return System.Object: " + replacementMethod_.FullName + " [[" + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name + "]]"); } continue; } } if (Verbosity >= 8) { Console.WriteLine("FOUND ALTERNATE METHOD: " + replacementMethod_); } replacementMethod = replacementMethod_; break; // FUTURE: don't break here, keep going to see if there are multiple (ambiguous) matches and throw/output error } if (replacementMethod == null) { if (!(" " + mr.FullName).Contains(" System.")) { if (Verbosity >= Verbosities.Warning) { Console.WriteLine("[__] No alternate found for " + mr.FullName + " in " + method.DeclaringType.FullName + "." + method.Name); } // + mr.DeclaringType.FullName+"." +mr.Name + "(...)"); } skipped++; continue; } // if(mr.Name != "TestMethod") continue; // TEMP if (Verbosity >= Verbosities.Success) { Console.WriteLine(" O Replacing " + mr.FullName + " " + mr.GenericParameters.Count + " generic parameters" + " " + mr.Parameters.Count + " parameters" + " | " + mr.GetElementMethod().FullName + "" + " | " + mr.GetElementMethod().HasGenericParameters + "" + " | " + mr.GetElementMethod().GenericParameters[0].Name + "" ); } // if(Verbosity >= 6) // Console.WriteLine("Resolved non-specific generic method: " + mr.FullName); // if(Verbosity >= 8) Console.WriteLine("RESOLVED TYPE: " + genericTypeParameter); // var typeModuleDefinition = ModuleDefinition.ReadModule(type.Module.Assembly.Location); // var typeDefinition = typeModuleDefinition.Types.Where(td => td.FullName == genericParameter).FirstOrDefault(); // if(typeDefinition != null && Verbosity >= 5) // { // Console.WriteLine("Resolved typeDefinition: " + typeDefinition); // } // else // { // Console.WriteLine("Failed to resolve typeDefinition: " + type.FullName); //// foreach(var td in ModuleDefinition.ReadModule(type.Module.Assembly.Location).Types) //// { //// Console.WriteLine(" ... " + td.FullName); //// } // continue; // } // method.Module.Import(type); // try removing this // IMetadataScope scope = method.Module; // var typeRef = new TypeReference(type.Namespace, type.Name, typeModuleDefinition, scope, type.IsValueType); // Console.WriteLine("TypeRef: "+ typeRef); // method.Module.Import(type); var replacementMethodImported = method.Module.Import(replacementMethod); // IL_0000: ldtoken Rewriter.TestClass if (genericTypeParameter != null) { processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameter))); } else { processor.InsertBefore(i, processor.Create(OpCodes.Ldtoken, method.Module.Import(genericTypeParameterDefinition))); } // IL_0005: call class [mscorlib]System.Type class // [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle) var gtfh = typeof(Type).GetMethod("GetTypeFromHandle"); MethodReference gtfhRef = method.Module.Import(gtfh, mr); processor.InsertBefore(i, processor.Create(OpCodes.Call, gtfhRef)); // IL_000a: call void class Rewriter.TestClass::TestMethod(class [mscorlib]System.Type) var callMethod = processor.Create(i.OpCode, replacementMethodImported); processor.InsertAfter(i, callMethod); #region Cast the result, if it exists if (mr.ReturnType.FullName != "System.Void" && !noCast) { string castAssembly; string castType; if (genericTypeParameter != null) { castAssembly = genericTypeParameter.Assembly.GetName(false).Name; castType = "[" + castAssembly + "]" + genericTypeParameter.FullName; } else if (genericTypeParameterDefinition != null) { castAssembly = ""; castType = genericTypeParameterDefinition.ToString(); // var resolvedGTPD = genericTypeParameterDefinition.Resolve(); // resolvedGTPD.FullName } else { castType = "???"; Console.WriteLine("INTERNAL ERROR - genericTypeParameter not set for " + mr.FullName + ". genericTypeParameterDefinition:" + genericTypeParameterDefinition.Resolve()); continue; } // castAssembly = castAssembly.Substring(castAssembly.IndexOf(",")); if (Verbosity > 8) { Console.WriteLine("CAST to " + castType + " | " + genericTypeParameterDefinition); } var importedGenericType = mr.Module.Import(genericTypeParameterDefinition); processor.InsertAfter(callMethod, processor.Create(OpCodes.Castclass, importedGenericType)); } #endregion processor.Remove(i); replaced++; // if(Verbosity >= Verbosities.Success) // Console.WriteLine(" - " + ((MethodReference)i.Operand).Name + " replaced with " + replacementMethod.FullName); // mr.GetGenericParameters(null); // // if(method.GenericParameters.Count == 0) return; // // if(method.GenericParameters.Count > 1) // { // Console.WriteLine("Warning: cannot handle more than one generic parameter yet: " + // method.DeclaringType.FullName + "." + method.Name); // return; // } // // var body = method.Body; // body.Instructions // if(method.GenericParameters.Count == 1) // { // } } }
protected bool IsParameterCopyNeeded (FunctionAnalysis2ndPass sa, string parameterName, JSExpression expression, out GenericParameter relevantParameter) { if (!IsCopyNeeded(expression, out relevantParameter)) return false; if (sa == null) return true; if (!OptimizeCopies) return true; bool modified = true, escapes = true, isResult = false; if (parameterName != null) { modified = sa.ModifiedVariables.Contains(parameterName); escapes = sa.EscapingVariables.Contains(parameterName); isResult = sa.ResultVariable == parameterName; } return modified || (escapes && !isResult); }
internal static GenericParameter Clone(GenericParameter gp, ImportContext context) { GenericParameter ngp; if (gp.Owner is TypeReference) ngp = new GenericParameter (gp.m_name, context.GenericContext.Type); else if (gp.Owner is MethodReference) ngp = new GenericParameter (gp.m_name, context.GenericContext.Method); else throw new NotSupportedException (); ngp.Position = gp.Owner.GenericParameters.IndexOf (gp); ngp.Attributes = gp.Attributes; foreach (TypeReference constraint in gp.Constraints) ngp.Constraints.Add (context.Import (constraint)); foreach (CustomAttribute ca in gp.CustomAttributes) ngp.CustomAttributes.Add (CustomAttribute.Clone (ca, context)); return ngp; }
internal static MethodDefinition Clone(MethodDefinition meth, ImportContext context) { MethodDefinition nm = new MethodDefinition( meth.Name, RVA.Zero, meth.Attributes, meth.ImplAttributes, meth.HasThis, meth.ExplicitThis, meth.CallingConvention); context.GenericContext.Method = nm; foreach (GenericParameter p in meth.GenericParameters) { nm.GenericParameters.Add(GenericParameter.Clone(p, context)); } nm.ReturnType.ReturnType = context.Import(meth.ReturnType.ReturnType); if (meth.ReturnType.HasConstant) { nm.ReturnType.Constant = meth.ReturnType.Constant; } if (meth.ReturnType.MarshalSpec != null) { nm.ReturnType.MarshalSpec = meth.ReturnType.MarshalSpec; } foreach (CustomAttribute ca in meth.ReturnType.CustomAttributes) { nm.ReturnType.CustomAttributes.Add(CustomAttribute.Clone(ca, context)); } if (meth.PInvokeInfo != null) { nm.PInvokeInfo = meth.PInvokeInfo; // TODO: import module ? } foreach (ParameterDefinition param in meth.Parameters) { nm.Parameters.Add(ParameterDefinition.Clone(param, context)); } foreach (MethodReference ov in meth.Overrides) { nm.Overrides.Add(context.Import(ov)); } foreach (CustomAttribute ca in meth.CustomAttributes) { nm.CustomAttributes.Add(CustomAttribute.Clone(ca, context)); } foreach (SecurityDeclaration sec in meth.SecurityDeclarations) { nm.SecurityDeclarations.Add(SecurityDeclaration.Clone(sec)); } if (meth.Body != null) { nm.Body = MethodBody.Clone(meth.Body, nm, context); } return(nm); }
protected bool IsCopyNeeded (JSExpression value, out GenericParameter relevantParameter) { relevantParameter = null; if ((value == null) || (value.IsNull)) return false; while (value is JSReferenceExpression) value = ((JSReferenceExpression)value).Referent; var sce = value as JSStructCopyExpression; if (sce != null) return false; var valueType = value.GetActualType(TypeSystem); var valueTypeDerefed = TypeUtil.DereferenceType(valueType) ?? valueType; var cte = value as JSChangeTypeExpression; var cast = value as JSCastExpression; TypeReference originalType; int temp; if (cte != null) { originalType = cte.Expression.GetActualType(TypeSystem); } else if (cast != null) { originalType = cast.Expression.GetActualType(TypeSystem); } else { originalType = null; } if (originalType != null) { originalType = TypeUtil.FullyDereferenceType(originalType, out temp); if (!IsStructOrGenericParameter(valueTypeDerefed) && !IsStructOrGenericParameter(originalType)) return false; relevantParameter = (originalType as GenericParameter) ?? (valueTypeDerefed as GenericParameter); } else { if (!IsStructOrGenericParameter(valueTypeDerefed)) return false; relevantParameter = (valueTypeDerefed as GenericParameter); } if (IsTypeExcludedFromCopies(valueType)) return false; var iae = value as JSInitializerApplicationExpression; if ( (value is JSLiteral) || (value is JSNewExpression) || (value is JSPassByReferenceExpression) || (value is JSNewBoxedVariable) || (value is JSDefaultValueLiteral) || ((iae != null) && ((iae.Target is JSNewExpression) || (iae.Target is JSDefaultValueLiteral))) ) { return false; } if (!OptimizeCopies) return true; if (IsImmutable(value)) { return false; } var valueDot = value as JSDotExpressionBase; // The value is being read out of an element proxy, so no copy is necessary - the read unpacks the value // on demand from the packed array. if ((valueDot != null) && PackedArrayUtil.IsElementProxy(valueDot.Target)) return false; var valueTypeInfo = TypeInfo.GetExisting(valueType); if ((valueTypeInfo != null) && valueTypeInfo.IsImmutable) return false; // If the expression is a parameter that is only used once and isn't aliased, // we don't need to copy it. var rightVar = value as JSVariable; if (rightVar != null) { int referenceCount; if ( ReferenceCounts.TryGetValue(rightVar.Identifier, out referenceCount) && (referenceCount == 1) && !rightVar.IsReference && rightVar.IsParameter && !SecondPass.VariableAliases.ContainsKey(rightVar.Identifier) ) { if (Tracing) Debug.WriteLine(String.Format("Returning false from IsCopyNeeded for parameter {0} because reference count is 1 and it has no aliases", value)); return false; } } var rightInvocation = value as JSInvocationExpression; if (rightInvocation == null) return true; var invokeMethod = rightInvocation.JSMethod; if (invokeMethod == null) return true; var secondPass = GetSecondPass(invokeMethod); if (secondPass == null) return true; // If this expression is the return value of a function invocation, we can eliminate struct // copies if the return value is a 'new' expression. if (secondPass.ResultIsNew) return false; // We can also eliminate a return value copy if the return value is one of the function's // arguments, and we are sure that argument does not need a copy either. if (secondPass.ResultVariable != null) { var parameters = invokeMethod.Method.Parameters; int parameterIndex = -1; for (var i = 0; i < parameters.Length; i++) { if (parameters[i].Name != secondPass.ResultVariable) continue; parameterIndex = i; break; } if (parameterIndex < 0) return true; return IsCopyNeeded(rightInvocation.Arguments[parameterIndex], out relevantParameter); } return true; }
public bool TryGetGenericConstraintMapping(GenericParameter generic_parameter, out MetadataToken [] mapping) { return(GenericConstraints.TryGetValue(generic_parameter.token.RID, out mapping)); }
protected JSStructCopyExpression MakeCopyForExpression (JSExpression expression, GenericParameter relevantParameter) { if (relevantParameter != null) return new JSConditionalStructCopyExpression(relevantParameter, expression); else return new JSStructCopyExpression(expression); }
public void Remove(GenericParameter value) { List.Remove(value); }
public override void VisitGenericParameter(GenericParameter genparam) { }
static bool AreSame(GenericParameter a, GenericParameter b) { return(a.Position == b.Position); }
void MarkGenericParameter (GenericParameter parameter) { MarkCustomAttributes (parameter); foreach (TypeReference constraint in parameter.Constraints) MarkType (constraint); }
public void WriteTypeSignature(TypeReference type) { if (type == null) { throw new ArgumentNullException(); } ElementType etype = type.etype; switch (etype) { case ElementType.Var: case ElementType.MVar: { GenericParameter obj = (GenericParameter)type; WriteElementType(etype); int position = obj.Position; if (position == -1) { throw new NotSupportedException(); } base.WriteCompressedUInt32((uint)position); break; } case ElementType.GenericInst: { GenericInstanceType genericInstanceType = (GenericInstanceType)type; WriteElementType(ElementType.GenericInst); WriteElementType(genericInstanceType.IsValueType ? ElementType.ValueType : ElementType.Class); base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(genericInstanceType.ElementType)); WriteGenericInstanceSignature(genericInstanceType); break; } case ElementType.Ptr: case ElementType.ByRef: case ElementType.Sentinel: case ElementType.Pinned: { TypeSpecification typeSpecification = (TypeSpecification)type; WriteElementType(etype); WriteTypeSignature(typeSpecification.ElementType); break; } case ElementType.FnPtr: { FunctionPointerType method = (FunctionPointerType)type; WriteElementType(ElementType.FnPtr); WriteMethodSignature(method); break; } case ElementType.CModReqD: case ElementType.CModOpt: { IModifierType type2 = (IModifierType)type; WriteModifierSignature(etype, type2); break; } case ElementType.Array: { ArrayType arrayType = (ArrayType)type; if (!arrayType.IsVector) { WriteArrayTypeSignature(arrayType); } else { WriteElementType(ElementType.SzArray); WriteTypeSignature(arrayType.ElementType); } break; } case ElementType.None: WriteElementType(type.IsValueType ? ElementType.ValueType : ElementType.Class); base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(type)); break; default: if (TryWriteElementType(type)) { break; } throw new NotSupportedException(); } }