public void Add(IReturnType parameterType, IReturnType type) { //Console.WriteLine ("Add:" + parameterType +"->" + type); if (type == null || string.IsNullOrEmpty(type.FullName)) { return; } string name = parameterType.Name; if (!typeTable.ContainsKey(name)) { DomReturnType newType = new DomReturnType(type.FullName); newType.ArrayDimensions = Math.Max(0, type.ArrayDimensions - parameterType.ArrayDimensions); newType.PointerNestingLevel = Math.Max(0, type.PointerNestingLevel - parameterType.PointerNestingLevel); newType.Type = type.Type; // May be anonymous type for (int i = 0; i < newType.ArrayDimensions; i++) { newType.SetDimension(i, parameterType.GetDimension(i)); } foreach (var generic in type.GenericArguments) { newType.AddTypeParameter(generic); } typeTable[name] = newType; } }
public void Add(ProjectDom dom, IReturnType parameterType, IReturnType type) { // Console.WriteLine ("Add:" + parameterType +"\n\t->" + type); if (type == null || string.IsNullOrEmpty(type.FullName)) { return; } string name = parameterType.Name; bool contains = typeTable.ContainsKey(name); // when the type is already in the table use the type that is more general in the inheritance tree. if (contains && dom != null) { var t1 = dom.GetType(typeTable[name]); var t2 = dom.GetType(type); if (t1 != null && !dom.GetInheritanceTree(t1).Any(t => t.DecoratedFullName == t2.DecoratedFullName)) { return; } } DomReturnType newType = new DomReturnType(type.FullName); newType.ArrayDimensions = Math.Max(0, type.ArrayDimensions - parameterType.ArrayDimensions); newType.PointerNestingLevel = Math.Max(0, type.PointerNestingLevel - parameterType.PointerNestingLevel); newType.Type = type.Type; // May be anonymous type for (int i = 0; i < newType.ArrayDimensions; i++) { newType.SetDimension(i, parameterType.GetDimension(i)); } foreach (var generic in type.GenericArguments) { newType.AddTypeParameter(generic); } typeTable[name] = newType; }
/* * // Check if 'type' has some decorations applied to it * if (type is Mono.Cecil.TypeSpecification) { * // Go through all levels of 'indirection', 'array dimensions' * // and 'generic types' - in the end, we should get the actual * // type of the ReturnType (but all data about its array * // dimensions, levels of indirection and even its generic * // parameters is correctly stored within ArrayCount and * // ArrayDimensions, PointerNestingLevel and GenericArguments * // respectively). * if (type is ArrayType) { * // This return type is obviously an array - add the rank * ArrayType at = (ArrayType) type; * if (arrays == null) * arrays = new Stack<int>(); * arrays.Push(at.Rank); * type = at.ElementType; * } else else if (type is Mono.Cecil.ReferenceType) { * Mono.Cecil.ReferenceType rt = (Mono.Cecil.ReferenceType) type; * byRef = true; * type = rt.ElementType; * } else if (type is PointerType) { * // The type is a pointer * PointerType pt = (PointerType) type; ++pointerNestingLevel; * type = pt.ElementType; * // Go down one level * } else { * // TODO: Check if we loose some relevant info here * type = ((TypeSpecification)type).ElementType; * }*/ public static DomReturnType GetReturnType(TypeReference typeReference) { if (typeReference == null) { return(new DomReturnType(DomReturnType.Void.ToInvariantString())); } if (typeReference is Mono.Cecil.GenericInstanceType) { Mono.Cecil.GenericInstanceType genType = (Mono.Cecil.GenericInstanceType)typeReference; DomReturnType result = GetReturnType(genType.ElementType); foreach (TypeReference typeRef in genType.GenericArguments) { DomReturnType param = GetReturnType(typeRef); foreach (IReturnTypePart part in result.Parts) { if (part.Tag is TypeDefinition) { TypeDefinition typeDef = (TypeDefinition)part.Tag; foreach (TypeReference typeParam in typeDef.GenericParameters) { if (typeParam.Name == param.Name) { part.AddTypeParameter(param); goto skip; } } } } result.AddTypeParameter(param); skip :; } return(result); } if (typeReference is Mono.Cecil.ArrayType) { Mono.Cecil.ArrayType arrType = (Mono.Cecil.ArrayType)typeReference; DomReturnType result = GetReturnType(arrType.ElementType); result.ArrayDimensions++; result.SetDimension(result.ArrayDimensions - 1, arrType.Rank - 1); return(result); } if (typeReference is Mono.Cecil.PointerType) { Mono.Cecil.PointerType ptrType = (Mono.Cecil.PointerType)typeReference; DomReturnType result = GetReturnType(ptrType.ElementType); if (result.ArrayDimensions > 0) { result.ArrayPointerNestingLevel++; } else { result.PointerNestingLevel++; } return(result); } if (typeReference is Mono.Cecil.ByReferenceType) { return(GetReturnType(((Mono.Cecil.ByReferenceType)typeReference).ElementType)); } if (typeReference is Mono.Cecil.TypeDefinition) { Mono.Cecil.TypeDefinition typeDefinition = (Mono.Cecil.TypeDefinition)typeReference; DomReturnType result; if (typeDefinition.DeclaringType != null) { result = GetReturnType(typeDefinition.DeclaringType); result.Parts.Add(new ReturnTypePart(typeDefinition.Name)); result.Tag = typeDefinition; } else { result = new DomReturnType(typeDefinition.Name); result.Namespace = typeDefinition.Namespace; result.Tag = typeDefinition; } return(result); } return(new DomReturnType(DomCecilType.RemoveGenericParamSuffix(typeReference.FullName))); }
public ExtensionMethod(IType extensionType, IMethod originalMethod, IList <IReturnType> genericArguments, IEnumerable <IReturnType> methodArguments) { if (extensionType == null) { throw new ArgumentNullException("extensionType"); } if (originalMethod == null) { throw new ArgumentNullException("originalMethod"); } this.DeclaringType = extensionType; List <IReturnType> args = new List <IReturnType> (); if (extensionType.FullName.EndsWith("[]")) { foreach (IReturnType returnType in extensionType.BaseTypes) { if (returnType.FullName == "System.Collections.Generic.IList" && returnType.GenericArguments.Count > 0) { args.Add(returnType.GenericArguments[0]); break; } } if (args.Count == 0) { args.Add(new DomReturnType(extensionType)); } } else if (extensionType is InstantiatedType) { InstantiatedType instType = (InstantiatedType)extensionType; DomReturnType uninstantiatedReturnType = new DomReturnType(instType.UninstantiatedType.FullName); foreach (IReturnType genArg in instType.GenericParameters) { uninstantiatedReturnType.AddTypeParameter(genArg); } args.Add(uninstantiatedReturnType); } else { args.Add(new DomReturnType(extensionType)); } if (methodArguments != null) { args.AddRange(methodArguments); } // Console.WriteLine ("Create Extension method from:"); // Console.WriteLine ("ext type:" + args[0]); // Console.WriteLine (originalMethod); this.method = DomMethod.CreateInstantiatedGenericMethod(originalMethod, genericArguments, args); // skip first parameter. for (int i = 1; i < method.Parameters.Count; i++) { Add(method.Parameters[i]); } foreach (ITypeParameter par in method.TypeParameters) { AddTypeParameter(par); } this.ExtensionType = extensionType; this.OriginalMethod = originalMethod; //Console.WriteLine (this); //Console.WriteLine ("oOoOoOoOoOoOoOoOoOoOoOoOoOoO"); }