示例#1
0
        public static TypeNode GetTemplateType(TypeNode type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            // Console.WriteLine(type.FullName);

            // only generic types have templates
            if (!type.IsGeneric)
            {
                return(type);
            }

            if (type.DeclaringType == null)
            {
                // if the type is not nested, life is simpler

                // if the type is not specified, the type is the template
                if (type.TemplateArguments == null)
                {
                    return(type);
                }

                // otherwise, construct the template type identifier and use it to fetch the template type
                Module     templateModule = type.DeclaringModule;
                Identifier name           = new Identifier(String.Format("{0}`{1}", type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count));
                Identifier space          = type.Namespace;
                TypeNode   template       = templateModule.GetType(space, name);
                return(template);
            }
            else
            {
                // if the type is nested, life is harder; we have to walk up the chain, constructing
                // un-specialized identifiers as we go, then walk back down the chain, fetching
                // template types as we go

                // create a stack to keep track of identifiers
                Stack <Identifier> identifiers = new Stack <Identifier>();

                // populate the stack with the identifiers of all the types up to the outermost type
                TypeNode current = type;
                while (true)
                {
                    int count = 0;
                    if ((current.TemplateArguments != null) && (current.TemplateArguments.Count > count))
                    {
                        count = current.TemplateArguments.Count;
                    }
                    if ((current.TemplateParameters != null) && (current.TemplateParameters.Count > count))
                    {
                        count = current.TemplateParameters.Count;
                    }
                    TypeNodeList arguments = current.TemplateParameters;
                    if (count == 0)
                    {
                        identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters()));
                    }
                    else
                    {
                        identifiers.Push(new Identifier(String.Format("{0}`{1}", current.GetUnmangledNameWithoutTypeParameters(), count)));
                    }
                    // Console.WriteLine("U {0} {1}", identifiers.Peek(), CountArguments(current));
                    if (current.DeclaringType == null)
                    {
                        break;
                    }
                    current = current.DeclaringType;
                }

                // fetch a TypeNode representing that outermost type
                Module     module = current.DeclaringModule;
                Identifier space  = current.Namespace;
                current = module.GetType(space, identifiers.Pop());

                // move down the stack to the inner type we want
                while (identifiers.Count > 0)
                {
                    current = (TypeNode)current.GetMembersNamed(identifiers.Pop())[0];
                    // Console.WriteLine("D {0} {1}", current.GetFullUnmangledNameWithTypeParameters(), CountArguments(current));
                }

                // whew, finally we've got it
                return(current);
            }
        }
示例#2
0
        //=====================================================================

        /// <summary>
        /// Write out a type name
        /// </summary>
        /// <param name="type">The type for which to write out the name</param>
        /// <param name="sb">The string builder to which the name is written</param>
        private static void WriteType(TypeNode type, StringBuilder sb)
        {
            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType array = (ArrayType)type;
                WriteType(array.ElementType, sb);

                sb.Append("[");

                if (array.Rank > 1)
                {
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(",");
                        }

                        sb.Append("0:");
                    }
                }

                sb.Append("]");
                break;

            case NodeType.Reference:
                Reference reference = (Reference)type;
                WriteType(reference.ElementType, sb);
                sb.Append("@");
                break;

            case NodeType.Pointer:
                Pointer pointer = (Pointer)type;
                WriteType(pointer.ElementType, sb);
                sb.Append("*");
                break;

            case NodeType.OptionalModifier:
                TypeModifier optionalModifierClause = (TypeModifier)type;
                WriteType(optionalModifierClause.ModifiedType, sb);
                sb.Append("!");
                WriteType(optionalModifierClause.Modifier, sb);
                break;

            case NodeType.RequiredModifier:
                TypeModifier requiredModifierClause = (TypeModifier)type;
                WriteType(requiredModifierClause.ModifiedType, sb);

                // !EFW - Skip writing out the modifier if it's an InAttribute.  Not sure if this is the best
                // way to handle this so we'll have to wait and see.
                if (requiredModifierClause.Modifier.Name.Name != "InAttribute")
                {
                    sb.Append("|");
                    WriteType(requiredModifierClause.Modifier, sb);
                }
                break;

            default:
                if (type.IsTemplateParameter)
                {
                    ITypeParameter gtp = (ITypeParameter)type;

                    if (gtp.DeclaringMember is TypeNode)
                    {
                        sb.Append("`");
                    }
                    else
                    if (gtp.DeclaringMember is Method)
                    {
                        sb.Append("``");
                    }
                    else
                    {
                        throw new InvalidOperationException("Generic parameter not on type or method");
                    }

                    sb.Append(gtp.ParameterListIndex);
                }
                else
                {
                    // Namespace
                    TypeNode declaringType = type.DeclaringType;

                    if (declaringType != null)
                    {
                        // Names of nested types begin with outer type name
                        WriteType(declaringType, sb);
                        sb.Append(".");
                    }
                    else
                    {
                        // Otherwise just prefix with the namespace
                        Identifier space = type.Namespace;

                        if (space != null && !String.IsNullOrEmpty(space.Name))
                        {
                            sb.Append(space.Name);
                            sb.Append(".");
                        }
                    }

                    // Name
                    sb.Append(type.GetUnmangledNameWithoutTypeParameters());

                    // Generic parameters
                    if (type.IsGeneric)
                    {
                        // Number of parameters
                        TypeNodeList parameters = type.TemplateParameters;

                        if (parameters != null)
                        {
                            sb.Append('`');
                            sb.Append(parameters.Count);
                        }

                        // Arguments
                        TypeNodeList arguments = type.TemplateArguments;

                        if (arguments != null && arguments.Count > 0)
                        {
                            sb.Append("{");

                            for (int i = 0; i < arguments.Count; i++)
                            {
                                if (i > 0)
                                {
                                    sb.Append(",");
                                }

                                WriteType(arguments[i], sb);
                            }

                            sb.Append("}");
                        }
                    }
                }
                break;
            }
        }
示例#3
0
        private static void WriteType(TypeNode type, TextWriter writer)
        {
            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType array = type as ArrayType;
                WriteType(array.ElementType, writer);
                writer.Write("[");
                if (array.Rank > 1)
                {
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (i > 0)
                        {
                            writer.Write(",");
                        }
                        writer.Write("0:");
                    }
                }
                writer.Write("]");
                break;

            case NodeType.Reference:
                Reference reference      = type as Reference;
                TypeNode  referencedType = reference.ElementType;
                WriteType(referencedType, writer);
                writer.Write("@");
                break;

            case NodeType.Pointer:
                Pointer pointer = type as Pointer;
                WriteType(pointer.ElementType, writer);
                writer.Write("*");
                break;

            case NodeType.OptionalModifier:
                TypeModifier optionalModifierClause = type as TypeModifier;
                WriteType(optionalModifierClause.ModifiedType, writer);
                writer.Write("!");
                WriteType(optionalModifierClause.Modifier, writer);
                break;

            case NodeType.RequiredModifier:
                TypeModifier requiredModifierClause = type as TypeModifier;
                WriteType(requiredModifierClause.ModifiedType, writer);
                writer.Write("|");
                WriteType(requiredModifierClause.Modifier, writer);
                break;

            default:
                if (type.IsTemplateParameter)
                {
                    ITypeParameter gtp = (ITypeParameter)type;
                    if (gtp.DeclaringMember is TypeNode)
                    {
                        writer.Write("`");
                    }
                    else if (gtp.DeclaringMember is Method)
                    {
                        writer.Write("``");
                    }
                    else
                    {
                        throw new InvalidOperationException("Generic parameter not on type or method.");
                    }
                    writer.Write(gtp.ParameterListIndex);
                }
                else
                {
                    // namespace
                    TypeNode declaringType = type.DeclaringType;
                    if (declaringType != null)
                    {
                        // names of nested types begin with outer type name
                        WriteType(declaringType, writer);
                        writer.Write(".");
                    }
                    else
                    {
                        // otherwise just prepend the namespace
                        Identifier space = type.Namespace;
                        if ((space != null) && !String.IsNullOrEmpty(space.Name))
                        {
                            //string space = type.Namespace.Name;
                            //if (space != null && space.Length > 0) {
                            writer.Write(space.Name);
                            writer.Write(".");
                        }
                    }
                    // name
                    writer.Write(type.GetUnmangledNameWithoutTypeParameters());
                    // generic parameters
                    if (type.IsGeneric)
                    {
                        // number of parameters
                        TypeNodeList parameters = type.TemplateParameters;
                        if (parameters != null)
                        {
                            writer.Write("`{0}", parameters.Count);
                        }
                        // arguments
                        TypeNodeList arguments = type.TemplateArguments;
                        if ((arguments != null) && (arguments.Count > 0))
                        {
                            writer.Write("{");
                            for (int i = 0; i < arguments.Count; i++)
                            {
                                TypeNode argument = arguments[i];
                                if (i > 0)
                                {
                                    writer.Write(",");
                                }
                                WriteType(arguments[i], writer);
                            }
                            writer.Write("}");
                        }
                    }
                }
                break;
            }
        }
示例#4
0
        /// <summary>
        /// Get the template type for the given type
        /// </summary>
        /// <param name="type">The type for which to get the template type</param>
        /// <returns>The type itself if it is not generic or the template type if it is</returns>
        public static TypeNode GetTemplateType(this TypeNode type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            // Only generic types have templates
            if (!type.IsGeneric)
            {
                return(type);
            }

            // If the type is not nested, life is simpler.
            if (type.DeclaringType == null)
            {
                // If the type is not specified, the type is the template
                if (type.TemplateArguments == null)
                {
                    return(type);
                }

                // Otherwise, construct the template type identifier and use it to fetch the template type
                Identifier name = new Identifier(String.Format(CultureInfo.InvariantCulture, "{0}`{1}",
                                                               type.GetUnmangledNameWithoutTypeParameters(), type.TemplateArguments.Count));

                TypeNode template = type.DeclaringModule.GetType(type.Namespace, name);

                // !EFW - Added by ComponentOne
                if (template == null)
                {
                    template = type;
                }

                return(template);
            }

            // If the type is nested, life is harder.  We have to walk up the chain, constructing unspecialized
            // identifiers as we go, then walk back down the chain, fetching template types as we go.

            // Create a stack to keep track of identifiers
            Stack <Identifier> identifiers = new Stack <Identifier>();

            // Populate the stack with the identifiers of all the types up to the outermost type
            TypeNode current = type;

            while (true)
            {
                int count = 0;

                if (current.TemplateArguments != null && current.TemplateArguments.Count > count)
                {
                    count = current.TemplateArguments.Count;
                }

                if (current.TemplateParameters != null && current.TemplateParameters.Count > count)
                {
                    count = current.TemplateParameters.Count;
                }

                if (count == 0)
                {
                    identifiers.Push(new Identifier(current.GetUnmangledNameWithoutTypeParameters()));
                }
                else
                {
                    identifiers.Push(new Identifier(String.Format(CultureInfo.InvariantCulture, "{0}`{1}",
                                                                  current.GetUnmangledNameWithoutTypeParameters(), count)));
                }

                if (current.DeclaringType == null)
                {
                    break;
                }

                current = current.DeclaringType;
            }

            // Fetch a TypeNode representing the outermost type
            current = current.DeclaringModule.GetType(current.Namespace, identifiers.Pop());

            // Move down the stack to the inner type we want
            while (identifiers.Count > 0 && current != null)
            {
                current = (TypeNode)current.GetMembersNamed(identifiers.Pop()).FirstOrDefault();
            }

            // !EFW - Added by ComponentOne
            if (current == null)
            {
                return(type);
            }

            // Whew, finally we've got it
            return(current);
        }
        //=====================================================================

        /// <summary>
        /// Write out a type name
        /// </summary>
        /// <param name="type">The type for which to write out the name</param>
        /// <param name="sb">The string builder to which the name is written</param>
        private static void WriteType(TypeNode type, StringBuilder sb)
        {
            switch (type.NodeType)
            {
            case NodeType.ArrayType:
                ArrayType array = (ArrayType)type;
                WriteType(array.ElementType, sb);

                sb.Append('[');

                if (array.Rank > 1)
                {
                    for (int i = 0; i < array.Rank; i++)
                    {
                        if (i > 0)
                        {
                            sb.Append(',');
                        }

                        sb.Append("0:");
                    }
                }

                sb.Append(']');
                break;

            case NodeType.Reference:
                Reference reference = (Reference)type;
                WriteType(reference.ElementType, sb);
                sb.Append('@');
                break;

            case NodeType.Pointer:
                Pointer pointer = (Pointer)type;
                WriteType(pointer.ElementType, sb);
                sb.Append('*');
                break;

            case NodeType.OptionalModifier:
                TypeModifier optionalModifierClause = (TypeModifier)type;
                WriteType(optionalModifierClause.ModifiedType, sb);
                sb.Append('!');
                WriteType(optionalModifierClause.Modifier, sb);
                break;

            case NodeType.RequiredModifier:
                TypeModifier requiredModifierClause = (TypeModifier)type;
                WriteType(requiredModifierClause.ModifiedType, sb);
                sb.Append('|');
                WriteType(requiredModifierClause.Modifier, sb);
                break;

            default:
                if (type.IsTemplateParameter)
                {
                    ITypeParameter gtp = (ITypeParameter)type;

                    if (gtp.DeclaringMember is TypeNode)
                    {
                        sb.Append('`');
                    }
                    else
                    if (gtp.DeclaringMember is Method)
                    {
                        sb.Append("``");
                    }
                    else
                    {
                        throw new InvalidOperationException("Generic parameter not on type or method");
                    }

                    sb.Append(gtp.ParameterListIndex);
                }
                else
                {
                    // Namespace
                    TypeNode declaringType = type.DeclaringType;

                    if (declaringType != null)
                    {
                        // Names of nested types begin with outer type name
                        WriteType(declaringType, sb);
                        sb.Append('.');
                    }
                    else
                    {
                        // Otherwise just prefix with the namespace
                        Identifier space = type.Namespace;

                        if (space != null && !String.IsNullOrEmpty(space.Name))
                        {
                            sb.Append(space.Name);
                            sb.Append('.');
                        }
                    }

                    // Name
                    sb.Append(type.GetUnmangledNameWithoutTypeParameters());

                    RenameTypeIfNecessary(sb);

                    // Generic parameters
                    if (type.IsGeneric)
                    {
                        // Number of parameters
                        TypeNodeList parameters = type.TemplateParameters;

                        if (parameters != null)
                        {
                            sb.Append('`');
                            sb.Append(parameters.Count);
                        }

                        // Arguments
                        TypeNodeList arguments = type.TemplateArguments;

                        if (arguments != null && arguments.Count > 0)
                        {
                            sb.Append('{');

                            for (int i = 0; i < arguments.Count; i++)
                            {
                                if (i > 0)
                                {
                                    sb.Append(',');
                                }

                                WriteType(arguments[i], sb);
                            }

                            sb.Append('}');
                        }
                    }
                }
                break;
            }
        }