Example #1
0
        /// <summary>
        /// Builds and adds the needed nested types in a current type representing explicit interfaces
        /// </summary>
        /// <param name="currentType"></param>
        public static void GetExplicitInterfaceTypes(TypeDeclaration currentType)
        {
            //Trim the type name to avoid errors with generic types
            string currentTypeName = currentType.Name.TrimEnd("_Base".ToCharArray()).TrimEnd("_T".ToCharArray());

            //SEARCH FOR THE METHODS IN THE CURRENT TYPE THAT SHOULD BE IMPLEMENTED IN A NESTED CLASS
            List<MethodDeclaration> methodsOfCurrentType = new List<MethodDeclaration>();
            foreach (KeyValuePair<AstType, List<MethodDeclaration>> kvp in Cache.GetPrivateImplementation())
            {
                foreach (MethodDeclaration m in kvp.Value)
                {
                    if (m.TypeMember.Name == currentTypeName)
                        methodsOfCurrentType.Add(m);
                }
            }

            //CREATE A DICTIONARY WITH THE NESTEDCLASS AND METHODS NEEDED (SORTED)
            Dictionary<AstType, List<MethodDeclaration>> privateImplClass = new Dictionary<AstType, List<MethodDeclaration>>();
            foreach (MethodDeclaration m in methodsOfCurrentType)
            {
                foreach (KeyValuePair<AstType, List<MethodDeclaration>> kvp in Cache.GetPrivateImplementation())
                {
                    if (kvp.Value.Contains(m))
                    {
                        //If the method private implementation is corresponding to the current key type in the loop, continue
                        if (GetTypeName(m.PrivateImplementationType) == GetTypeName(kvp.Key))
                        {
                            //REMOVE THE METHOD FROM THE CURRENT TYPE                            
                            currentType.Members.Remove(m);
                            RemoveHeaderNode(m, currentType);

                            //REMOVE THE PRIVATE IMPLEMENTATION
                            m.PrivateImplementationType = Ast.AstType.Null;

                            //Add the method in the sorted dictionary
                            if (privateImplClass.ContainsKey(kvp.Key))
                                privateImplClass[kvp.Key].Add((MethodDeclaration)m.Clone());

                            else
                                privateImplClass.Add(kvp.Key, new List<MethodDeclaration>() { (MethodDeclaration)m.Clone() });

                        }
                    }
                }
            }

            //CREATE FROM THE NESTED CLASS THE NESTEDTYPEDECLARATION NODE
            foreach (KeyValuePair<AstType, List<MethodDeclaration>> kvp in privateImplClass)
            {
                TypeDeclaration type = new TypeDeclaration();
                string nestedTypeName = "_interface_" + GetTypeName(kvp.Key);
                type.NameToken = new Identifier(nestedTypeName, TextLocation.Empty);
                type.Name = nestedTypeName;
                type.ModifierTokens.Add(new CppModifierToken(TextLocation.Empty, Modifiers.Public));

                if (kvp.Key is SimpleType)
                {
                    foreach (AstType tp in (kvp.Key as SimpleType).TypeArguments)
                        type.TypeParameters.Add(new TypeParameterDeclaration() { NameToken = new Identifier(GetTypeName(tp), TextLocation.Empty) });
                }

                //ADD BASE TYPES
                SimpleType baseType = new SimpleType(GetTypeName(kvp.Key));
                if (kvp.Key is SimpleType)
                {
                    foreach (AstType tp in (kvp.Key as SimpleType).TypeArguments)
                        baseType.TypeArguments.Add((AstType)tp.Clone());
                }

                type.AddChild(baseType, TypeDeclaration.BaseTypeRole);

                //REMOVE THE BASE TYPE BECAUSE THE NESTED TYPE WILL INHERIT FROM IT
                try
                {
                    currentType.BaseTypes.Remove(currentType.BaseTypes.First(x => GetTypeName(x) == GetTypeName(baseType)));
                }
                catch (InvalidOperationException)
                {
                    //The element is not present in the list
                    //Safe to ignore this :)
                }

                //ADD METHODS
                type.Members.AddRange(kvp.Value);

                //ADD FIELD
                HeaderFieldDeclaration fdecl = new HeaderFieldDeclaration();
                SimpleType nestedType = new SimpleType(nestedTypeName);
                foreach (TypeParameterDeclaration tp in type.TypeParameters)
                    nestedType.TypeArguments.Add(new SimpleType(tp.Name));

                ExplicitInterfaceTypeDeclaration ntype = new Ast.ExplicitInterfaceTypeDeclaration(type);

                fdecl.ReturnType = nestedType;
                string _tmp = "_" + GetTypeName(fdecl.ReturnType).ToLower();
                fdecl.Variables.Add(new VariableInitializer(_tmp));
                fdecl.ModifierTokens.Clear();
                fdecl.ModifierTokens.Add(new CppModifierToken(TextLocation.Empty, Modifiers.Private));
                //ADD FIELD TO THE GLOBAL CLASS
                ntype.OutMembers.Add(fdecl);


                //ADD OPERATORS TO THE GLOBAL CLASS
                //ADD OPERATOR HEADER NODE
                ConversionConstructorDeclaration op = new ConversionConstructorDeclaration();
                op.ReturnType = new PtrType((AstType)kvp.Key.Clone());
                op.ModifierTokens.Add(new CppModifierToken(TextLocation.Empty, Modifiers.Public));

                //In the first line of this method we have trimed end the string with the _T and the _Base for searching the lists
                //At this point we have to add that string
                if (currentType.TypeParameters.Any())
                    op.type = currentTypeName + "_T_Base";
                else
                    op.type = currentTypeName;
                BlockStatement blck = new BlockStatement();
                Statement st = new ReturnStatement(new AddressOfExpression(new IdentifierExpression(_tmp)));
                blck.Add(st);
                op.Body = blck;

                currentType.Members.Add(op);


                //If is generic type, we have to implement the operator inside of the templates header
                if (currentType.TypeParameters.Any())
                {
                    op.type = String.Empty;
                    ntype.OutMembers.Add((AttributedNode)op.Clone());
                    //The method is implemented, we must delete the node from the header nodes
                    RemoveHeaderNode(op, currentType);
                }
                else
                {
                    HeaderConversionConstructorDeclaration hc = new HeaderConversionConstructorDeclaration();
                    GetHeaderNode(op, hc);
                    //Add the header member to the out members of the nested type
                    ntype.OutMembers.Add(hc);
                }


                //ADD NESTED TYPE TO THE HEADER DECLARATION
                currentType.HeaderNodes.Add(ntype);
            }
        }
Example #2
0
        /// <summary>
        /// Returns the member string for calling a conversion constructor declaration: i.e. operator IB<Object>*();
        /// </summary>
        /// <param name="conv">The conversion constructor declaration</param>
        /// <returns>The member string</returns>
        public static string GetInlineConversionConstructorDeclarationCall(ConversionConstructorDeclaration conv)
        {
            //TODO:
            //ESTA FUNCION NO ME GUSTA NADA !
            //HAY QUE CREAR NODOS INLINE    
            string ret = "operator ";
            ret += Resolver.GetTypeName(conv.ReturnType);

            if (conv.ReturnType is SimpleType)
            {
                if ((conv.ReturnType as SimpleType).TypeArguments.Any())
                {
                    bool first = true;
                    ret += "<";
                    foreach (AstType t in (conv.ReturnType as SimpleType).TypeArguments)
                    {
                        if (first)
                            first = false;
                        else
                            ret += ",";

                        AstType tmp;
                        TryPatchTemplateToObjectType(t, out tmp);
                        ret += Resolver.GetTypeName(tmp);
                    }
                    ret += "*>";
                }
            }
            else if (conv.ReturnType is PtrType)
            {
                PtrType ptr = conv.ReturnType as PtrType;
                if (ptr.Target is SimpleType)
                {
                    if ((ptr.Target as SimpleType).TypeArguments.Any())
                    {
                        bool first = true;
                        ret += "<";
                        foreach (AstType t in (ptr.Target as SimpleType).TypeArguments)
                        {
                            if (first)
                                first = false;
                            else
                                ret += ",";

                            AstType tmp;
                            TryPatchTemplateToObjectType(t, out tmp);
                            ret += Resolver.GetTypeName(tmp);
                        }
                        ret += ">";
                    }
                }
                ret += "*";
            }
            return ret;

        }