Re: [Mono-dev] Mono.Cecil: Full names of generic types
Hi Matej, Matej Urbas wrote: I'm working on code completion (generics support) in MonoDevelop and I'm making extensive use of Mono.Cecil. Great news! 2. Question about methods that have generic types as parameters: Here is an example of such a method: static T System.Array.FindLast T (T[] array, System.PredicateT match) Now, the problem: Parameters are specified in MethodDefinition with a collection of ParameterDefinition classes which have TypeReference as their type. If we look at the 'match' parameter in the upper method, Cecil will store this info in its m_paramType: Full name of type: System.Predicate`1T GenericParameters: empty! Here, the second parameter of the FindLast method is a predicate, which is a constructed generic type, which has as its first argument the first generic parameter of the method. You can find constructed generic types (GenericInstanceType) and constructed generic methods (GenericInstanceMethod). They both implement IGenericInstance wich provides a collection of argument. An argument is a TypeReference, which is the base class for any kinf of type (hence, it could be a TypeDefinition as well as another GenericInstanceType). You see, the GenericParameters collection of the 'match' parameter is empty and its full name has the generic parameters already appended (i.e.: T). Now, in monodevelop I have to extract generic parameters of such parameters but it seems like there is no other way but to parse them from the 'full name' string... In fact, one can tell that a method parameter is generic only if one searches for a gt; or lt; character in its name... I would really like to see those parameters specified in a collection rather than appended to the string. What can I do about it? You can check: MethodReference ref = ...; GenericInstanceMethod gim = ref as GenericInstanceMethod; if (gim != null) { foreach (TypeReference argument in gim.Arguments) { } } 3. Oh, and to what extent is Mono.Cecil compatible with System.Reflection? E.g.: are the Mono.Cecil.GenericParamAttributes and System.Reflection.GenericParameterAttributes cast safe? - I mean, can they be cast from one-another and still preserve the expected information? Check that the values are the same before doing so. In theory, it may work. Hope I'm not annoying. Feel free to ask if you have other questions about Cecil! Jb Thanks in ahead --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
On Mon, 2006-07-24 at 11:20 +0200, Jb Evain wrote: You can find constructed generic types (GenericInstanceType) and constructed generic methods (GenericInstanceMethod). They both implement IGenericInstance wich provides a collection of argument. An argument is a TypeReference, which is the base class for any kinf of type (hence, it could be a TypeDefinition as well as another GenericInstanceType). Thanks! I figured that out yesterday, just before I wanted to start writing the 'name parser' :D I have one question though: Suppose we have such a TypeReference: SomeType`2int, T[][] Here is what I do to get all info about SomeType`2 out of there: I have a loop that goes like this: Check if the TypeReference is of any of these types: 1. ArrayType 2. GenericInstanceType 3. ReferenceType 4. PointerType 5. None of the above if we stumble on either of cases 1-4, we can cast the TypeReference to either of them and gather whatever additional info they have (e.g.: ArrayType gives us info about the Rank, GenericInstanceType gives us info about GenericAttributes, ReferenceType tells us that the type is passed ByRef and PointerType gives us the level of indirection). Moreover, each of the above types has a property named 'ElementType' which is the one I use to gather all info about the type. Now in the 5th case, we have only the plain type - without the array modifier or any generic attributes - which is our end point... Here is what my algorithm would do (looking at SomeType`2int, T[][]): Step 1: current type is an ArrayType - get its rank -- now visit its ElementType Step 2: current type is an ArrayType - get its rank -- now visit its ElementType Step 3: current type is a GenericInstanceType - traverse its GenericArguments --- now visit its ElementType Step 4: current type falls into the 5th case (its neither an ArrayType or GenericInstanceType or whatever) - it is simply a TypeReference: with the name SomeType`2 --- without any decorations... --- I store this name in MonoDevelop My question is if there are any other possible TypeReference types (other then the 4 mentioned above)? Did I miss something? You see, the GenericParameters collection of the 'match' parameter is empty and its full name has the generic parameters already appended (i.e.: T). Now, in monodevelop I have to extract generic parameters of such parameters but it seems like there is no other way but to parse them from the 'full name' string... In fact, one can tell that a method parameter is generic only if one searches for a gt; or lt; character in its name... I would really like to see those parameters specified in a collection rather than appended to the string. What can I do about it? You can check: MethodReference ref = ...; GenericInstanceMethod gim = ref as GenericInstanceMethod; if (gim != null) { foreach (TypeReference argument in gim.Arguments) { } } I see. Do you have a case where we would stumble upon a MethodReference? I mean, if we go through all types in the MainModule of an assembly, would we find a method reference with actual arguments specified? Do you have a C# example of such an occurrence? 3. Oh, and to what extent is Mono.Cecil compatible with System.Reflection? E.g.: are the Mono.Cecil.GenericParamAttributes and System.Reflection.GenericParameterAttributes cast safe? - I mean, can they be cast from one-another and still preserve the expected information? Check that the values are the same before doing so. In theory, it may work. Will do that. Thank you very much! BTW, Cecil rocks! Great work! Enjoy, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
Hi, Matej Urbas wrote: I have one question though: Suppose we have such a TypeReference: SomeType`2int, T[][] Here is what I do to get all info about SomeType`2 out of there: I have a loop that goes like this: Check if the TypeReference is of any of these types: 1. ArrayType 2. GenericInstanceType 3. ReferenceType 4. PointerType 5. None of the above if we stumble on either of cases 1-4, we can cast the TypeReference to either of them and gather whatever additional info they have (e.g.: ArrayType gives us info about the Rank, GenericInstanceType gives us info about GenericAttributes, ReferenceType tells us that the type is passed ByRef and PointerType gives us the level of indirection). Moreover, each of the above types has a property named 'ElementType' which is the one I use to gather all info about the type. Now in the 5th case, we have only the plain type - without the array modifier or any generic attributes - which is our end point... Here is what my algorithm would do (looking at SomeType`2int, T[][]): Step 1: current type is an ArrayType - get its rank -- now visit its ElementType Step 2: current type is an ArrayType - get its rank -- now visit its ElementType Step 3: current type is a GenericInstanceType - traverse its GenericArguments --- now visit its ElementType Step 4: current type falls into the 5th case (its neither an ArrayType or GenericInstanceType or whatever) - it is simply a TypeReference: with the name SomeType`2 --- without any decorations... --- I store this name in MonoDevelop There is a simpler way. The inheritance tree is like this: - TypeReference - TypeSpecification - ArrayType - PointerType - ReferenceType - FunctionPointerType - GenericInstanceType - ModType - ModifierOptional - ModifierRequired - PinnedType - TypeDefinition - GenericParameter You can say that if the type is a TypeSpecification, you loop until its ElementType property is not a TypeSpecification itself. You can then check which kind of TypeSpec it is. Please note that a visitor approach would probably be much better, and that I'll have to modify Cecil one day to handle this. My question is if there are any other possible TypeReference types (other then the 4 mentioned above)? Did I miss something? cf above. I see. Do you have a case where we would stumble upon a MethodReference? I mean, if we go through all types in the MainModule of an assembly, would we find a method reference with actual arguments specified? Do you have a C# example of such an occurrence? You can find MethodReferences only in the MemberReference collection of the Module. You'll encounter them as operands of the opcodes in the bodies of the methods. They are only markers. BTW, Cecil rocks! Great work! Thanks, Jb ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
Hey! On Mon, 2006-07-24 at 12:33 +0200, Jb Evain wrote: There is a simpler way. The inheritance tree is like this: - TypeReference - TypeSpecification - ArrayType - PointerType - ReferenceType - FunctionPointerType - GenericInstanceType - ModType - ModifierOptional - ModifierRequired - PinnedType - TypeDefinition - GenericParameter You can say that if the type is a TypeSpecification, you loop until its ElementType property is not a TypeSpecification itself. You can then check which kind of TypeSpec it is. Gureat! That voids all my worries, and what is more, the code is much cleaner and faster when we have tons of TypeReferences that are not of type TypeSpecifications :D Now I'm really happy! Thank you! Well, in any event, it's sad that I don't have the capacity to figure out such things by myself... well, maybe some day... Please note that a visitor approach would probably be much better, and that I'll have to modify Cecil one day to handle this. Tell me if you need help, would be glad to help :D Cecil sure is a project worth spending time on. I see. Do you have a case where we would stumble upon a MethodReference? I mean, if we go through all types in the MainModule of an assembly, would we find a method reference with actual arguments specified? Do you have a C# example of such an occurrence? You can find MethodReferences only in the MemberReference collection of the Module. You'll encounter them as operands of the opcodes in the bodies of the methods. They are only markers. BTW, Cecil rocks! Great work! Thanks, Well, it really does :D (nods) mhm Jb Regards, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
On Mon, 2006-07-24 at 11:20 +0200, Jb Evain wrote: 3. Oh, and to what extent is Mono.Cecil compatible with System.Reflection? E.g.: are the Mono.Cecil.GenericParamAttributes and System.Reflection.GenericParameterAttributes cast safe? - I mean, can they be cast from one-another and still preserve the expected information? Check that the values are the same before doing so. In theory, it may work. I figured that they are 'compatible'. But there is one slight difference. You are missing a 'n' in DefaultConstructorConstraint :D Compare: System.Reflection.GenericParameterAttributes.DefaultConstructorConstraint Mono.Cecil.GenericParamAttributes.DefaultConstructorConstrait Other than that, they match perfectly. Sorry to bother you about that... Enjoy, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
Hey, Matej Urbas wrote: I figured that they are 'compatible'. But there is one slight difference. You are missing a 'n' in DefaultConstructorConstraint :D This is fixed in SVN. Jb ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
On Mon, 2006-07-24 at 14:22 +0200, Jb Evain wrote: Hey, Matej Urbas wrote: I figured that they are 'compatible'. But there is one slight difference. You are missing a 'n' in DefaultConstructorConstraint :D This is fixed in SVN. Oh, sorry about that. Yep, we are using an old copy in MonoDevelop - I guess there must be a reason for this. Regards, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
On Sun, 2006-07-23 at 12:32 -0400, Miguel de Icaza wrote: The complete specification for this syntax is available on the ECMA 335 specification: http://www.ecma-international.org/publications/standards/Ecma-334.htm Thank you. I have also found the answer to the second question: it is not necessary to parse the names of parameter and return types - the info is stored in GenericInstanceType.GenericArguments. I only had to figure out that TypeReferences of parameters are of type GenericInstanceType. Thank god I found this :) - I was just about to write a name parser :D Hope I didn't bug you too much. Enjoy, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
[Mono-dev] Mono.Cecil: Full names of generic types
Hi I'm working on code completion (generics support) in MonoDevelop and I'm making extensive use of Mono.Cecil. I have a few questions about the way Mono.Cecil decorates full names of generic types: 1. All generic types have such a string appended to their full name: `# - where # represents the number of generic parameters. Is this a standard way of decorating generic names? If it is, can you point me to a document that specifies this? (I need it mostly because I'm interested, but I also expect to be using it when extracting undecorated names for code completion in monodevelop.) 2. Question about methods that have generic types as parameters: Here is an example of such a method: static T System.Array.FindLast T (T[] array, System.PredicateT match) Now, the problem: Parameters are specified in MethodDefinition with a collection of ParameterDefinition classes which have TypeReference as their type. If we look at the 'match' parameter in the upper method, Cecil will store this info in its m_paramType: Full name of type: System.Predicate`1T GenericParameters: empty! You see, the GenericParameters collection of the 'match' parameter is empty and its full name has the generic parameters already appended (i.e.: T). Now, in monodevelop I have to extract generic parameters of such parameters but it seems like there is no other way but to parse them from the 'full name' string... In fact, one can tell that a method parameter is generic only if one searches for a gt; or lt; character in its name... I would really like to see those parameters specified in a collection rather than appended to the string. What can I do about it? 3. Oh, and to what extent is Mono.Cecil compatible with System.Reflection? E.g.: are the Mono.Cecil.GenericParamAttributes and System.Reflection.GenericParameterAttributes cast safe? - I mean, can they be cast from one-another and still preserve the expected information? Hope I'm not annoying. Thanks in ahead --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
--- Matej Urbas [EMAIL PROTECTED] escribió: Hi I'm working on code completion (generics support) in MonoDevelop and I'm making extensive use of Mono.Cecil. I have a few questions about the way Mono.Cecil decorates full names of generic types: 1. All generic types have such a string appended to their full name: `# - where # represents the number of generic parameters. Is this a standard way of decorating generic names? If it is, can you point me to a document that specifies this? (I need it mostly because I'm interested, but I also expect to be using it when extracting undecorated names for code completion in monodevelop.) Decorating generic types with a grave (`) and the number of generic parameters is the way the CLI represents generic types, so we could have: FuncA = Func`1A FuncA, B = Func`2A, B because the runtime imposes that all types must have different names. It is well documented in the ECMA Standard papers for the CLI. Hope this helps, Alejandro Serrano __ LLama Gratis a cualquier PC del Mundo. Llamadas a fijos y móviles desde 1 céntimo por minuto. http://es.voice.yahoo.com ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
On Sat, 2006-07-22 at 16:29 +0200, Alejandro Serrano wrote: Decorating generic types with a grave (`) and the number of generic parameters is the way the CLI represents generic types, so we could have: FuncA = Func`1A FuncA, B = Func`2A, B because the runtime imposes that all types must have different names. It is well documented in the ECMA Standard papers for the CLI. Thanks, I thought as much. But still, when displaying the name of such types in code completion, those '`#' suffixes must be removed. Ok, so there's no other way but to truncate - I understand, period. :) There is still one question open, though: I still have to know about (generic) parameters in methods (see the example in my previous post). It seems that the only way to obtain generic arguments for a method's parameter is to parse its full name. Or should there be a collection of generic parameters for method's parameters too? You see, all Mono.Cecil.TypeReference and Mono.Cecil.TypeDefinition have a GenericParameters property, but for all method's parameters it is always empty (although they too can have generic parameters e.g.: void MyMethod(ListString names) --- here 'names' should have a generic parameter 'String', but its GenericParameters collection is empty). Hehe, you must know that I'm just asking - I don't want to reinvent the wheel, you see. If it's not possible, I will have to parse those names - period... but imagine just how funny it would be to parse such a parameter: void MyMethod(List MyClass MyClass2String strangeParam ), when on the other hand I could just grab all those generic parameters from a collection :D So, do I have to parse generic parameters from the names? Enjoy, --- Matej ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list
Re: [Mono-dev] Mono.Cecil: Full names of generic types
1. All generic types have such a string appended to their full name: `# - where # represents the number of generic parameters. Is this a standard way of decorating generic names? If it is, can you point me to a document that specifies this? (I need it mostly because I'm interested, but I also expect to be using it when extracting undecorated names for code completion in monodevelop.) The complete specification for this syntax is available on the ECMA 335 specification: http://www.ecma-international.org/publications/standards/Ecma-334.htm ___ Mono-devel-list mailing list Mono-devel-list@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-devel-list