Example #1
0
        private TypeTree FixTypeTree(TypeTree typeTree, Symbol type, UserTypeFactory factory)
        {
            // Check basic type
            BasicTypeTree basicTypeTree = typeTree as BasicTypeTree;

            if (basicTypeTree != null)
            {
                // Basic type tree is not challenged against template arguments, so try to do that.
                UserType basicUserType;

                if (CreateFactory(factory).GetUserType(type, out basicUserType))
                {
                    TypeTree tree = UserTypeTree.Create(basicUserType, factory);

                    if (tree != null)
                    {
                        return(tree);
                    }
                }

                // Failed to match the type
                // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now.
                return(new VariableTypeTree());
            }

            // Check array type
            ArrayTypeTree arrayTypeTree = typeTree as ArrayTypeTree;

            if (arrayTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(arrayTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != arrayTypeTree.ElementType)
                {
                    return(new ArrayTypeTree(elementTypeTree));
                }

                return(arrayTypeTree);
            }

            // Check pointer type
            PointerTypeTree pointerTypeTree = typeTree as PointerTypeTree;

            if (pointerTypeTree != null)
            {
                TypeTree elementTypeTree = FixTypeTree(pointerTypeTree.ElementType, type.ElementType, factory);

                if (elementTypeTree != pointerTypeTree.ElementType)
                {
                    return(new PointerTypeTree(elementTypeTree));
                }

                return(pointerTypeTree);
            }

            return(typeTree);
        }
Example #2
0
        /// <summary>
        /// Gets the type tree for the specified field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="extractingBaseClass">if set to <c>true</c> user type field is being generated for getting base class.</param>
        /// <param name="bitLength">Number of bits used for this symbol.</param>
        protected override TypeTree GetFieldTypeTree(SymbolField field, UserTypeFactory factory, bool extractingBaseClass, int bitLength = 0)
        {
            // Do not match specializations when getting type for base class.
            if (extractingBaseClass || NumberOfTemplateArguments == 0)
            {
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            // Check field in all specializations
            var specializedFields = SpecializedTypes.Select(r => new Tuple <TemplateUserType, SymbolField>(r, r.Symbol.Fields.FirstOrDefault(q => q.Name == field.Name))).ToArray();

            if (specializedFields.Any(r => r.Item2 == null))
            {
                // TODO: Incorrect bucketization. Field does not exist in all specialization.
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            if (specializedFields.All(r => r.Item2.Type.Name == field.Type.Name))
            {
                // There is no specialization, all types across the specializations are the same.
                return(GetSymbolTypeTree(field.Type, factory, bitLength));
            }

            // Try to get type tree
            TypeTree result = GetSymbolTypeTree(field.Type, factory, bitLength);

            if (result is BasicTypeTree)
            {
                // Basic type tree is not challenged against template arguments, so try to do that.
                UserType basicUserType;

                if (CreateFactory(factory).GetUserType(field.Type, out basicUserType))
                {
                    TypeTree tree = UserTypeTree.Create(basicUserType, factory);

                    if (tree != null)
                    {
                        return(tree);
                    }
                }

                // Failed to match the type
                // TODO: Look for typedeclared. Class is using different types than in template specialization. We cannot support it right now.
                return(new VariableTypeTree());
            }

            return(result);
        }
Example #3
0
        /// <summary>
        /// Gets the type tree for the base class.
        /// If class has multi inheritance, it can return MultiClassInheritanceTypeTree or SingleClassInheritanceWithInterfacesTypeTree.
        /// </summary>
        /// <param name="error">The error text writer.</param>
        /// <param name="type">The type for which we are getting base class.</param>
        /// <param name="factory">The user type factory.</param>
        /// <param name="baseClassOffset">The base class offset.</param>
        protected override TypeTree GetBaseClassTypeTree(TextWriter error, Symbol type, UserTypeFactory factory, out int baseClassOffset)
        {
            TypeTree baseType = base.GetBaseClassTypeTree(error, type, CreateFactory(factory), out baseClassOffset);

            // Check if base type is template argument. It if is, export it as if it is multi class inheritance.
            UserTypeTree             userBaseType      = baseType as UserTypeTree;
            TemplateArgumentUserType primitiveUserType = userBaseType != null ? userBaseType.UserType as TemplateArgumentUserType : null;

            if (userBaseType != null && primitiveUserType != null)
            {
                var    dict = GetGenericTypeConstraintsDictionary(factory);
                string commonBaseClass;

                if (dict.TryGetValue(primitiveUserType.ClassName, out commonBaseClass))
                {
                    return(UserTypeTree.Create(new TemplateArgumentUserType(commonBaseClass, null), factory));
                }

                baseClassOffset = 0;
                return(new MultiClassInheritanceTypeTree());
            }

            return(baseType);
        }