Esempio n. 1
0
        /// <summary>
        /// Tries to match the specified type name against template arguments.
        /// </summary>
        /// <param name="typeName">The type name.</param>
        /// <param name="argumentName">The found argument name.</param>
        /// <returns><c>true</c> if template argument was matched.</returns>
        public bool TryGetTemplateArgument(string typeName, out string argumentName)
        {
            // Does it belong to our template arguments?
            int index = ((List <Symbol>)TemplateArgumentsAsSymbols).FindIndex(s => s.Name == typeName);

            if (index >= 0)
            {
                argumentName = GetTemplateArgumentName(index);
                return(true);
            }

            // Does it belong to one of the "parent" template types?
            UserType parentType = DeclaredInType;

            while (parentType != null)
            {
                SpecializedTemplateUserType templateParentType = parentType as SpecializedTemplateUserType;

                if (templateParentType != null)
                {
                    return(templateParentType.TryGetTemplateArgument(typeName, out argumentName));
                }
                parentType = parentType.DeclaredInType;
            }

            // Template argument wasn't found
            argumentName = "";
            return(false);
        }
Esempio n. 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TemplateUserType"/> class.
 /// </summary>
 /// <param name="template">Specialized template user type that will be used as representative for generating code.</param>
 /// <param name="specializations"></param>
 /// <param name="factory">User type factory that contains this element.</param>
 public TemplateUserType(SpecializedTemplateUserType template, List <SpecializedTemplateUserType> specializations, UserTypeFactory factory)
     : base(template.Symbol, null, template.Namespace, factory)
 {
     Specializations           = specializations;
     SpecializedRepresentative = template;
     foreach (SpecializedTemplateUserType specialization in specializations)
     {
         specialization.TemplateType = this;
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TemplateUserTypeFactory"/> class.
 /// </summary>
 /// <param name="originalFactory">The original user type factory.</param>
 /// <param name="templateType">The template user type.</param>
 public TemplateUserTypeFactory(UserTypeFactory originalFactory, SpecializedTemplateUserType templateType)
     : base(originalFactory)
 {
     TemplateType    = templateType;
     OriginalFactory = originalFactory;
 }
Esempio n. 4
0
        /// <summary>
        /// Adds template symbols to user type factory and generates template user types.
        /// </summary>
        /// <param name="symbols">The template symbols grouped around the same template type.</param>
        /// <param name="nameSpace">The namespace.</param>
        /// <param name="generationFlags">The user type generation flags.</param>
        /// <returns>Generated user types for the specified symbols.</returns>
        internal IEnumerable <UserType> AddTemplateSymbols(IEnumerable <Symbol> symbols, string nameSpace, UserTypeGenerationFlags generationFlags)
        {
            // Bucketize template user types based on number of template arguments
            var buckets = new Dictionary <int, List <SpecializedTemplateUserType> >();

            foreach (Symbol symbol in symbols)
            {
                UserType userType = null;

                // We want to ignore "empty" generic classes (for now)
                if (symbol.Name == null || symbol.Size == 0)
                {
                    continue;
                }

                // Generate template user type
                SpecializedTemplateUserType templateType = new SpecializedTemplateUserType(symbol, null, nameSpace, this);

                if (!templateType.WronglyFormed)
                {
                    List <SpecializedTemplateUserType> templates;

                    symbol.UserType = templateType;
                    if (!buckets.TryGetValue(templateType.AllTemplateArguments.Count, out templates))
                    {
                        buckets.Add(templateType.AllTemplateArguments.Count, templates = new List <SpecializedTemplateUserType>());
                    }
                    templates.Add(templateType);
                }

                if (userType != null)
                {
                    yield return(userType);
                }
            }

            // Add newly generated types
            foreach (List <SpecializedTemplateUserType> templatesInBucket in buckets.Values)
            {
                // TODO: Verify that all templates in the list can be described by the same class (also do check for inner-types)

                // Sort Templates by Class Name.
                // This removes ambiguity caused by parallel type processing.
                //
                List <SpecializedTemplateUserType> templates = templatesInBucket.OrderBy(t => t.Symbol.Name.Count(c => c == '*'))
                                                               .ThenBy(t => t.Symbol.Name.Count(c => c == '<'))
                                                               .ThenBy(t => t.Symbol.Name).ToList();

                // Select best suited type for template
                SpecializedTemplateUserType template = templates.First();
                int bestScore = int.MaxValue;

                foreach (var specializedTemplate in templates)
                {
                    var arguments = specializedTemplate.AllTemplateArguments;
                    int score     = 0;

                    for (int i = 0; i < arguments.Count; i++)
                    {
                        var argument = arguments[i];

                        // Check if this is repeated type
                        bool repeated = false;

                        for (int j = 0; j < i && !repeated; j++)
                        {
                            repeated = argument == arguments[j];
                        }
                        if (repeated)
                        {
                            score += 100;
                        }

                        // Check if argument is constant
                        if (argument.Tag == CodeTypeTag.TemplateArgumentConstant)
                        {
                            continue;
                        }

                        // Check if argument is simple user type
                        if ((argument.Tag == CodeTypeTag.Class || argument.Tag == CodeTypeTag.Structure || argument.Tag == CodeTypeTag.Union || argument.Tag == CodeTypeTag.Enum) && !argument.Name.Contains("<"))
                        {
                            score += 1;
                            continue;
                        }

                        // Check if argments is function
                        if (argument.Tag == CodeTypeTag.Function)
                        {
                            score += 2;
                            continue;
                        }

                        // Check if argument is template
                        if (argument.Name.Contains("<"))
                        {
                            score += 20;
                            continue;
                        }

                        // All others fall into the same category
                        score += 5;
                    }

                    // Check if this is the best one
                    if (score < bestScore)
                    {
                        bestScore = score;
                        template  = specializedTemplate;
                    }
                }

                yield return(new TemplateUserType(template, templates, this));
            }
        }