コード例 #1
0
ファイル: Program.cs プロジェクト: Ilikia/naali
 static int CountMaxArgumentsForClassCtor(Symbol Class)
 {
     int args = 0;
     foreach (Symbol c in Class.children.Values)
         if (c.name == Class.name)
             args = Math.Max(args, c.parameters.Count);
     return args;
 }
コード例 #2
0
ファイル: Program.cs プロジェクト: katik/naali
        /*
        static void GenerateClassMemberVariableGet(Symbol variable, TextWriter tw)
        {
            Symbol Class = variable.parent;

            tw.WriteLine("static QScriptValue " + GetMemberVariableGetCppFuncName(variable) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");

            tw.WriteLine(Indent(1) + "if (context->argumentCount() != 0) { printf(\"Error! Invalid number of arguments passed to function " + GetMemberVariableGetCppFuncName(variable) + " in file %s, line %d!\\nExpected 0, but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
            tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + "return qScriptValueFromValue(context->engine(), This->" + variable.name + ");");
            tw.WriteLine("}");
            tw.WriteLine("");
        }

        static void GenerateClassMemberVariableSet(Symbol variable, TextWriter tw)
        {
            Symbol Class = variable.parent;

            tw.WriteLine("static QScriptValue " + GetMemberVariableSetCppFuncName(variable) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");

            tw.WriteLine(Indent(1) + "if (context->argumentCount() != 1) { printf(\"Error! Invalid number of arguments passed to function " + GetMemberVariableSetCppFuncName(variable) + " in file %s, line %d!\\nExpected 1, but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
            tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");
            tw.WriteLine(Indent(1) + variable.type + " " + variable.name + " = qscriptvalue_cast<" + variable.type + ">(context->argument(0));");
            tw.WriteLine(Indent(1) + "This->" + variable.name + " = " + variable.name + ";");
            tw.WriteLine(Indent(1) + "return QScriptValue();");
            tw.WriteLine("}");
            tw.WriteLine("");
        }
        */
        public static bool HasOpaqueQVariantBasedMarshalling(Symbol Class)
        {
            Symbol ctor = Class.FindChildByName(Class.name);
            foreach (string s in ctor.Comments())
            {
                if (s.Contains("[opaque-qtscript]"))
                    return true;
            }
            return false;
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        /*
        static void GenerateClassMemberVariableGet(Symbol variable, TextWriter tw)
        {
            Symbol Class = variable.parent;

            tw.WriteLine("static QScriptValue " + GetMemberVariableGetCppFuncName(variable) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");

            tw.WriteLine(Indent(1) + "if (context->argumentCount() != 0) { printf(\"Error! Invalid number of arguments passed to function " + GetMemberVariableGetCppFuncName(variable) + " in file %s, line %d!\\nExpected 0, but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
            tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + "return qScriptValueFromValue(context->engine(), This->" + variable.name + ");");
            tw.WriteLine("}");
            tw.WriteLine("");
        }

        static void GenerateClassMemberVariableSet(Symbol variable, TextWriter tw)
        {
            Symbol Class = variable.parent;

            tw.WriteLine("static QScriptValue " + GetMemberVariableSetCppFuncName(variable) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");

            tw.WriteLine(Indent(1) + "if (context->argumentCount() != 1) { printf(\"Error! Invalid number of arguments passed to function " + GetMemberVariableSetCppFuncName(variable) + " in file %s, line %d!\\nExpected 1, but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); return QScriptValue(); }");

            tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
            tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");
            tw.WriteLine(Indent(1) + variable.type + " " + variable.name + " = qscriptvalue_cast<" + variable.type + ">(context->argument(0));");
            tw.WriteLine(Indent(1) + "This->" + variable.name + " = " + variable.name + ";");
            tw.WriteLine(Indent(1) + "return QScriptValue();");
            tw.WriteLine("}");
            tw.WriteLine("");
        }
        */
        public static bool HasOpaqueQVariantBasedMarshalling(Symbol Class)
        {
            Symbol ctor = Class.FindChildByName(Class.name);
            foreach (string s in ctor.comments)
            {
                if (Class.name == "float3x4")
                    Console.WriteLine(s);
                if (s.Contains("[opaque-qtscript]"))
                    return true;
            }
            return false;
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: zhimaijoy/tundra
        static bool IsScriptable(Symbol s)
        {
            if (s.argList.Contains("["))
                return false;
            if (IsBadType(s.type))
                return false;
            foreach (Parameter p in s.parameters)
                if (IsBadType(p.type) || IsBadType(p.BasicType()))
                    return false;

            foreach (string str in s.Comments())
                if (str.Contains("[noscript]"))
                    return false;
            if (s.returnComment != null && s.returnComment.Contains("[noscript]"))
                return false;
            return true;
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateToExistingScriptValue(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("void ToExistingScriptValue_" + Class.name + "(QScriptEngine *engine, const " + Class.name + " &value, QScriptValue obj)");
            tw.WriteLine("{");

            if (HasOpaqueQVariantBasedMarshalling(Class)) // If enabled, this type is marshalled opaquely.
                tw.WriteLine(Indent(1) + "obj.setData(engine->newVariant(QVariant::fromValue(value)));");

            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public && !v.isStatic)
                {
                    string flags = v.IsConst() ? "QScriptValue::Undeletable | QScriptValue::ReadOnly" : "QScriptValue::Undeletable";

                    if (v.IsConst() && !Symbol.IsPODType(v.type))
                        tw.WriteLine(Indent(1) + "obj.setProperty(\"" + v.name + "\", ToScriptValue_const_" + v.type + "(engine, value." + v.name
                            + "), " + flags + ");");
                    else
                        tw.WriteLine(Indent(1) + "obj.setProperty(\"" + v.name + "\", qScriptValueFromValue(engine, value." + v.name
                            + "), " + flags + ");");
                }

            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #6
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        private void ParseFunctionParameterComments(Symbol s, string memdocContent)
        {
            int endIdx;
            string memberData = FindStringInBetween(memdocContent, 0, "<dl><dt><b>Parameters:</b></dt><dd>",
                "</table>", out endIdx);
            if (endIdx == -1)
                return;
            int startIdx = 0;
            while(startIdx < memberData.Length)
            {
                string row = FindStringInBetween(memberData, startIdx, "<tr>", "</tr>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                int paramNameEnd;
                string paramName = FindStringInBetween(row, 0, "<em>", "</em>", out paramNameEnd);
                paramName = paramName.Trim();
                if (paramNameEnd == -1)
                    continue;
                int cmEnd;
                string comment = FindStringInBetween(row, paramNameEnd, "<td>", "</td>", out cmEnd);
                if (cmEnd == -1)
                    continue;
                Parameter param = s.FindParamByName(paramName);
                if (param == null)
                    continue;

                param.comment = comment.Trim();
            }
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateFromScriptValue(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("void FromScriptValue_" + Class.name + "(const QScriptValue &obj, " + Class.name + " &value)");
            tw.WriteLine("{");

            if (HasOpaqueQVariantBasedMarshalling(Class)) // If enabled, this type is marshalled opaquely.
                tw.WriteLine(Indent(1) + "value = obj.data().toVariant().value<" + Class.name + ">();");

            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public && !v.isStatic)
                    tw.WriteLine(Indent(1) + "value." + v.name + " = qScriptValueToValue<" + v.type + ">(obj.property(\"" + v.name + "\"));");

            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static string GetScriptFunctionName(Symbol function)
        {
            string str = function.parent.name + "_" + function.name;
            for (int i = 0; i < function.parameters.Count; ++i)
                str += "_" + function.parameters[i].BasicTypeId();

            return str;
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static bool NeedsClassFunctionSelector(Symbol classSymbol, string functionName)
        {
            if (classSymbol.name == functionName)
                return true; // Always generate a selector for the ctor of the class, because it gets a fixed name 'class_ctor'.

            int nameCount = 0;
            List<Symbol> functions = new List<Symbol>();
            foreach (Symbol s in classSymbol.children.Values)
                if (s.name == functionName && IsScriptable(s))
                {
                    ++nameCount;
                    if (nameCount >= 2)
                        return true;
                }
            return false;
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static string GetMemberVariableGetScriptFuncName(Symbol variable)
        {
            return variable.name; // Scripts access the member variables using foo.member(); notation

            // Alternate notation: foo.getMember();
            //            string firstChar = variable.name.Substring(0, 1);
            //            return "get" + firstChar.ToUpper() + variable.name.Substring(1);
        }
コード例 #11
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        private void ParseClassCompound(Dictionary<string, Symbol> symbols, XmlElement classNode)
        {
            Symbol newSymbol = new Symbol();
            newSymbol.kind = classNode.GetAttribute("kind").StripHtmlCharacters();
            newSymbol.type = "";
            newSymbol.name = GetXmlElementChildNodeValue(classNode, "name").StripHtmlCharacters();
            newSymbol.path = "";
            newSymbol.filename = GetXmlElementChildNodeValue(classNode, "filename").StripHtmlCharacters();
            newSymbol.visibilityLevel = ParseVisibilityLevel(classNode);
            newSymbol.virtualness = ParseVirtualness(classNode);
            symbols.Add(newSymbol.name, newSymbol);
            List<XmlElement> members = GetChildElementsByName(classNode, "member");
            foreach (XmlElement member in members)
            {
                Symbol child = ParseMemberElement(newSymbol, member);
                string symbolName = child.type + " " + child.name + " " + child.argList;
                while (newSymbol.children.ContainsKey(symbolName))
                    symbolName = symbolName + "_2";

                newSymbol.children.Add(symbolName, child);
            }
        }
コード例 #12
0
ファイル: CodeStructure.cs プロジェクト: zhimaijoy/tundra
        /*
        /// <summary>
        /// Each doxygen documentation file on a class contains a single class comment near the top of the page.
        /// </summary>
        /// <param name="dataString"></param>
        private void ParseDocumentationFileForClassComments(string dataString)
        {
            int endIndex;
            string className = FindStringInBetween(dataString, 0, "<!-- doxytag: class=\"", "\" -->", out endIndex);
            if (endIndex == -1)
                return;
            if (!symbols.ContainsKey(className))
                return;
            Symbol classSymbol = symbols[className];

            string classComments = FindStringInBetween(dataString, endIndex,
                "<hr/><a name=\"_details\"></a><h2>Detailed Description</h2>",
                "<hr/><h2>Member",
                out endIndex);
            if (endIndex != -1)
            {
                classSymbol.comments.AddRange(SplitToParagraphs(classComments));
            }
        }
        */
        /*
        /// <summary>
        /// Breaks down the single string form arglist into a member args list structure.
        /// </summary>
        /// <param name="s"></param>
        static private void GenerateArgList(Symbol s)
        {
            s.parameters.Clear();
            string argList = s.argList;
            if (argList.StartsWith("("))
                argList = argList.Substring(1);
            if (argList.EndsWith(")"))
                argList = argList.Substring(0, argList.Length - 1);
            if (argList.EndsWith(")=0"))
                argList = argList.Substring(0, argList.Length - 3);
            argList = argList.Trim();
            if (argList.Length == 0)
                return;
            string[] args = argList.Split(',');
            foreach (string arg in args)
            {
                string a = arg.Trim();
//                int lastSpace = a.LastIndexOf(' ');
                Parameter p = new Parameter();
                p.type = a.StripHtmlCharacters().StripHtmlLinks();// a.Substring(0, lastSpace).Trim();
//                p.name = a.Substring(lastSpace + 1, a.Length - (lastSpace + 1)).Trim();
                s.parameters.Add(p);
            }
        }

        private void ParseFunctionArgList(Symbol s, string content)
        {
            s.parameters.Clear();

            int endIdx;
            content = FindStringInBetween(content, 0, "<table class=\"memname\">", "</table>", out endIdx);
            if (endIdx == -1)
                return;

            int startIdx = 0;
            while (startIdx < content.Length)
            {
                string paramType = FindStringInBetween(content, startIdx, "<td class=\"paramtype\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                string paramName = FindStringInBetween(content, startIdx, "<td class=\"paramname\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                string strippedParamName = FindStringInBetween(paramName, 0, "<em>", "</em>", out endIdx);

                Parameter p = new Parameter();
                p.type = paramType.StripHtmlCharacters().StripHtmlLinks();
                p.name = strippedParamName.StripHtmlCharacters().StripHtmlLinks();
                s.parameters.Add(p);
            }
        }

        private void ParseFunctionParameterComments(Symbol s, string memdocContent)
        {
            int endIdx;
            string memberData = FindStringInBetween(memdocContent, 0, "<dl><dt><b>Parameters:</b></dt><dd>",
                "</table>", out endIdx);
            if (endIdx == -1)
                return;
            int startIdx = 0;
            while(startIdx < memberData.Length)
            {
                string row = FindStringInBetween(memberData, startIdx, "<tr>", "</tr>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                int paramNameEnd;
                string paramName = FindStringInBetween(row, 0, "<em>", "</em>", out paramNameEnd);
                paramName = paramName.Trim();
                if (paramNameEnd == -1)
                    continue;
                int cmEnd;
                string comment = FindStringInBetween(row, paramNameEnd, "<td>", "</td>", out cmEnd);
                if (cmEnd == -1)
                    continue;
                Parameter param = s.FindParamByName(paramName);
                if (param == null)
                    continue;

                param.comment = comment.Trim();
            }
        }

        private void ParseFunctionReturnValueComments(Symbol s, string memdocContent)
        {
            int endIdx;
            string memberData = FindStringInBetween(memdocContent, 0, "<dl class=\"return\"><dt><b>Returns:</b></dt><dd>",
                "</dd></dl>", out endIdx);
            if (endIdx == -1)
                return;
            s.returnComment = memberData;
        }

        private void ParseDocumentationFileForBriefMemberComments(string dataString)
        {
            int startIdx = 0;
            while(startIdx < dataString.Length)
            {
                int endIdx;
                string elemRefStr = "<tr><td class=\"memItemLeft\" align=\"right\" valign=\"top\">";
                string memberLine1 = FindStringInBetween(dataString, startIdx,
                    elemRefStr,
                    "</tr>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                int endIdx2;
                int nextElemRefEnd;
                string nextElemRef = FindStringInBetween(dataString, endIdx+1,
                    elemRefStr, "</tr>", out nextElemRefEnd);
                string memberLine2 = FindStringInBetween(dataString, endIdx + 1,
                    "<tr><td class=\"mdescLeft\">", "</tr>",
                    out endIdx2);
                if (endIdx2 == -1)
                    continue;
                if (endIdx2 >= nextElemRefEnd)
                    continue; // Parsed too far with the comment line.
                startIdx = endIdx2 + 1;

                // Find the ref this brief comment is for.
                string refString = FindStringInBetween(memberLine1, 0, " ref=\"", "\"", out endIdx);
                if (endIdx == -1)
                    continue;
                if (!symbolsByAnchor.ContainsKey(refString))
                    continue;
                Symbol s = symbolsByAnchor[refString];
                string briefComment = FindStringInBetween(memberLine2, 0, "<td class=\"mdescRight\">",
                    "</td>", out endIdx);
                if (endIdx == -1)
                    continue;
                s.comments.Add(briefComment);
            }
        }

        private void ParseDocumentationFile(string filename)
        {
//            Console.WriteLine("Parsing documentation from file \"" + filename + "\"");
            TextReader t;
            try
            {
                t = new StreamReader(filename);
            } catch(System.IO.FileNotFoundException)
            {
                return;
            }

            string dataString = t.ReadToEnd();

            ParseDocumentationFileForClassComments(dataString);
            ParseDocumentationFileForBriefMemberComments(dataString);
            int startIndex = 0;
            int strLen = dataString.Length;
            while (startIndex < strLen)
            {
                int index = dataString.IndexOf("doxytag:", startIndex);
                if (index == -1)
                    break;
                startIndex = index + 1;
                int refStartIndex = dataString.IndexOf(" ref=\"", startIndex);
                if (refStartIndex == -1)
                    break;
                int refIndex = refStartIndex + 6;
                int refEndIndex = dataString.IndexOf("\"", refIndex);
                if (refEndIndex == -1)
                    break;
                startIndex = refEndIndex + 1;
                string anchorRef = dataString.Substring(refIndex, refEndIndex - refIndex);
                if (!symbolsByAnchor.ContainsKey(anchorRef))
                    continue;
                Symbol s = symbolsByAnchor[anchorRef];

                // Try to find memdoc content (detailed comment block).
                int memdocEnd;
                string memdocContent;
                bool success = FindMemdocContent(dataString, startIndex, out memdocContent, out memdocEnd);
                if (success)
                {
                    s.comments.AddRange(SplitToParagraphs(memdocContent));

                    if (s.kind == "function")
                    {
                        int protoEndIdx;
                        string memProto = FindStringInBetween(dataString, startIndex, "<div class=\"memproto\">",
                            "</div>", out protoEndIdx);
                        if (protoEndIdx != -1)
                            ParseFunctionArgList(s, memProto);
                        ParseFunctionParameterComments(s, memdocContent);
                        ParseFunctionReturnValueComments(s, memdocContent);
                    }

                    startIndex = memdocEnd + 1;
                }
                else
                {
                    success = FindBriefdocContent(dataString, startIndex, out memdocContent, out memdocEnd);
                    if (success)
                    {
                        s.comments.AddRange(SplitToParagraphs(memdocContent));
                        startIndex = memdocEnd + 1;
                    }
                }
            }

            foreach (Symbol s in symbolsByAnchor.Values)
                ProcessDocGeneratorCommentDirectives(s);

//            XmlDocument doc = new XmlDocument();
 //           doc.XmlResolver = null;
  //          doc.LoadXml(dataString);
/*
            HTMLDocument doc = new HTMLDocument();
            IHTMLDocument2 doc2 = (IHTMLDocument2)doc;
            doc2.write(dataString);
            doc.get
*/
   //         WebBrowser wb = new WebBrowser();
  //          wb.DocumentText = dataString;
 //           HtmlDocument doc = wb.Document;// new HtmlDocument();
//            doc.
//            doc.
/*
            List<XmlElement> anchorElements = new List<XmlElement>();
            FindAnchorElements(doc.DocumentElement, anchorElements);
            foreach (XmlElement n in anchorElements)
            {
                XmlElement memDocSibling = FindMemDocSibling(n);
                Symbol s = symbolsByAnchor[memDocSibling.GetAttribute("id")];

                List<XmlElement> paragraphs = GetChildElementsByName(memDocSibling, "p");
                foreach (XmlElement p in paragraphs)
                {
                    s.comments.Add(p.InnerXml);
                }
            }
 */ 
   //     }

        public void ParseSectionDefElement(Symbol parent, XmlElement e)
        {
            foreach(XmlElement child in e.ChildNodes)
            {
                if (child.Name == "memberdef")
                {
                    Symbol member = new Symbol();
                    member.parent = parent;
                    member.id = child.GetAttribute("id");
                    member.kind = child.GetAttribute("kind");
                    member.visibilityLevel = ParseVisibilityLevel(child.GetAttribute("prot"));
                    member.isStatic = (child.GetAttribute("static") == "yes");
                    member.isConst = (child.GetAttribute("const") == "yes");
                    member.isMutable = (child.GetAttribute("mutable") == "yes");
                    member.isExplicit = (child.GetAttribute("explicit") == "yes");
                    member.virtualness = ParseVirtualness(child.GetAttribute("virt"));
                    member.type = GetXmlElementChildNodeValue(child, "type", true);
                    member.fullDefinition = GetXmlElementChildNodeValue(child, "definition");
                    member.argList = GetXmlElementChildNodeValue(child, "argsstring");

                    member.classMemberIndexTitle = member.name = GetXmlElementChildNodeValue(child, "name");
                    if (member.name.StartsWith("@"))
                        continue; // Doxygen creates items with names starting with '@' at least for unnamed unions, ignore those altogether.
                    symbols[member.id] = member;
//                    symbolsByName[member.name] = member;
                    parent.children.Add(member);
                    
                    // Function parameters.
                    foreach(XmlElement param in child.ChildNodes.OfType<XmlElement>())
                        if (param.Name == "param")
                        {
                            Parameter p = new Parameter();
                            if (member.kind == "define") // This is a #define macro.
                            {
                                p.type = "";
                                p.name = GetXmlElementChildNodeValue(param, "defname");
                            }
                            else // This is a real function
                            {
                                p.type = GetXmlElementChildNodeValue(param, "type", true);
                                p.name = GetXmlElementChildNodeValue(param, "declname");
                            }
                            member.parameters.Add(p);
                        }

                    // If this is a #define macro, get the macro body code.
                    if (member.kind == "define")
                    {                    
                        member.macroBody = GetXmlElementChildNodeValue(child, "initializer");
                        // Create the argList from scratch, because it is not present in the xml in same form than for functions.
                        member.argList = member.ArgStringWithoutTypes();
                    }

                    // Function parameter comments.
                    List<XmlElement> parameters = child.AllGrandChildElementsOfTypeAndAttribute("parameterlist", "kind", "param");
                    if (parameters != null && parameters.Count > 0)
                    {
                        foreach (XmlElement paramNode in parameters.OfType<XmlElement>())
                        {
                            foreach (XmlElement param in paramNode.ChildNodes.OfType<XmlElement>())
                            {
                                if (param.Name == "parameteritem")
                                {
                                    string paramName = param.FirstChildElementOfType("parameternamelist").FirstChildElementOfType("parametername").InnerText.Trim();
                                    Parameter p = member.FindParamByName(paramName);
                                    if (p != null)
                                        p.comment = param.FirstChildElementOfType("parameterdescription").InnerText;
                                }
                            }
                            // Remove the parameterlist from the detailed description node so that it won't appear in the 'detailedDescription' documentation string.
                            // The detailed description is created manually.
                            paramNode.ParentNode.RemoveChild(paramNode);
                        }
                    }

                    // TODOs ^ BUGs 
                    List<XmlElement> xrefsects = child.AllGrandChildElementsOfType("xrefsect");
                    if (xrefsects != null)
                    {
                        foreach (XmlElement elem in xrefsects)
                        {
                            if (GetXmlElementChildNodeValue(elem, "xreftitle") == "Todo")
                                member.todos.Add(GetXmlElementChildNodeValue(elem, "xrefdescription"));
                            if (GetXmlElementChildNodeValue(elem, "xreftitle") == "Bug")
                                member.bugs.Add(GetXmlElementChildNodeValue(elem, "xrefdescription"));
                            elem.ParentNode.RemoveChild(elem);
                        }
                    }

                    // @notes.
                    List<XmlElement> notesects = child.AllGrandChildElementsOfTypeAndAttribute("simplesect", "kind", "note");
                    if (notesects != null)
                    {
                        foreach (XmlElement elem in notesects)
                        {
                            member.notes.Add(elem.InnerText);
                            elem.ParentNode.RemoveChild(elem);
                        }
                    }

                    // Function return value.
                    XmlElement retVal = child.FirstGrandChildElementOfTypeAndAttribute("simplesect", "kind", "return");
                    if (retVal != null)
                    {
                        member.returnComment = retVal.InnerText;
                        retVal.ParentNode.RemoveChild(retVal);
                    }

                    // The "see also" section.
                    XmlElement see = child.FirstGrandChildElementOfTypeAndAttribute("simplesect", "kind", "see");
                    if (see != null)
                    {
                        member.seeAlsoDocumentation = see.InnerXml;
                        see.ParentNode.RemoveChild(see);
                    }

                    member.briefDescription = GetXmlElementChildNodeValue(child, "briefdescription").Trim();
                    member.inbodyDescription = GetXmlElementChildNodeValue(child, "inbodydescription").Trim();
                    member.detailedDescription = GetXmlElementChildNodeValue(child, "detaileddescription").Trim();
                    XmlElement loc = child.FirstChildElementOfType("location");
                    if (loc != null)
                    {
                        member.sourceFilename = loc.GetAttribute("bodyfile");
                        int.TryParse(loc.GetAttribute("bodystart"), out member.sourceFileStartLine);
                        int.TryParse(loc.GetAttribute("bodyend"), out member.sourceFileEndLine);
                        if (member.sourceFileEndLine == -1)
                            member.sourceFileEndLine = member.sourceFileStartLine;
                    }
                    ProcessDocGeneratorCommentDirectives(member);

                    ///\todo Add location.
                }
            }            
        }
コード例 #13
0
ファイル: CodeStructure.cs プロジェクト: zhimaijoy/tundra
        public void ParseCompoundDefElement(XmlElement e)
        {
            Symbol s = new Symbol();
            s.id = e.GetAttribute("id");
            s.kind = e.GetAttribute("kind");
            s.visibilityLevel = ParseVisibilityLevel(e.GetAttribute("prot"));
            s.classMemberIndexTitle = s.name = GetXmlElementChildNodeValue(e, "compoundname");

            // The "author" section.
            XmlElement author = e.FirstGrandChildElementOfTypeAndAttribute("simplesect", "kind", "author");
            if (author != null)
            {
                s.author = author.InnerXml;
                author.ParentNode.RemoveChild(author);
            }

            s.briefDescription = GetXmlElementChildNodeValue(e, "briefdescription");
            s.inbodyDescription = GetXmlElementChildNodeValue(e, "inbodydescription");
            s.detailedDescription = GetXmlElementChildNodeValue(e, "detaileddescription");
            symbols[s.id] = s;
            symbolsByName[s.name] = s;

            ProcessDocGeneratorCommentDirectives(s);

            foreach(XmlElement child in e.ChildNodes)
            {
                if (child.Name == "sectiondef")
                    ParseSectionDefElement(s, child);
            }            
            // Also has the following members:
            // <collaborationgraph>
            // <location>
            // <listofallmembers>
            // <includes>
        }
コード例 #14
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        private void ParseFileCompound(Dictionary<string, Symbol> symbols, XmlElement fileNode)
        {
            Symbol newSymbol = new Symbol();
            newSymbol.kind = "file";
            newSymbol.type = "";
            newSymbol.name = GetXmlElementChildNodeValue(fileNode, "name").StripHtmlCharacters();
            newSymbol.path = GetXmlElementChildNodeValue(fileNode, "path").StripHtmlCharacters();
            newSymbol.filename = GetXmlElementChildNodeValue(fileNode, "filename").StripHtmlCharacters();
            newSymbol.includes = new List<string>();
            symbols.Add(newSymbol.name, newSymbol);
            List<XmlElement> includes = GetChildElementsByName(fileNode, "includes");
            foreach (XmlElement include in includes)
            {
                newSymbol.includes.Add(include.InnerText.StripHtmlCharacters());
            }

            List<XmlElement> classes = GetChildElementsByName(fileNode, "class");
            foreach (XmlElement classElem in classes)
            {
                if (symbols.ContainsKey(classElem.InnerText.StripHtmlCharacters()))
                    newSymbol.children.Add(classElem.InnerText, symbols[classElem.InnerText.StripHtmlCharacters()]);
            }
        }
コード例 #15
0
ファイル: Program.cs プロジェクト: katik/naali
        static string GetScriptFunctionName(Symbol function)
        {
            if (function.name == function.parent.name)
            {
                Symbol classSymbol = function.parent;
                List<Symbol> functions = new List<Symbol>();
                foreach (Symbol s in classSymbol.children)
                    if (s.name == function.name && IsScriptable(s))
                        functions.Add(s);

                if (functions.Count < 2)
                    return function.parent.name + "_ctor"; // No need to generate a selector.
            }
            string str = function.parent.name + "_" + function.name;
            for (int i = 0; i < function.parameters.Count; ++i)
                str += "_" + function.parameters[i].BasicTypeId();

            if (function.isConst)
                str += "_const";
            return str;
        }
コード例 #16
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        /// <summary>
        /// Goes through the given symbol and find all DocGenerator-style directives present in the comments
        /// and applies them. These directives are of form [foo].
        /// </summary>
        private void ProcessDocGeneratorCommentDirectives(Symbol s)
        {
            for (int i = 0; i < s.comments.Count; ++i)
            {
                s.comments[i] = s.comments[i].Trim();
                if (s.comments[i].EndsWith("<br/>"))
                    s.comments[i] = s.comments[i].Substring(0, s.comments[i].Length - 5);
                if (s.comments[i].EndsWith("<br />"))
                    s.comments[i] = s.comments[i].Substring(0, s.comments[i].Length - 6);
                s.comments[i] = s.comments[i].Trim();

                int endIdx;
                int startIndex = 0;
                while (startIndex < s.comments[i].Length)
                {
                    string directive = FindStringInBetween(s.comments[i], startIndex, "[", "]", out endIdx);
                    if (endIdx == -1)
                    {
                        s.comments[i] = s.comments[i].Trim();
                        if (s.comments[i].Length == 0)
                        {
                            s.comments.RemoveAt(i);
                            --i;
                        }
                        break;
                    }

                    int directiveStartIndex = endIdx - directive.Length - 1;
                    directive = directive.Trim();
                    string[] st = directive.Split(':');
                    string directiveParam = "";
                    if (st.Length == 2)
                        directiveParam = st[1].Trim();

                    if (directive.ToLower().StartsWith("similaroverload") && directiveParam.Length > 0)
                    {
                        Symbol similarOverloadSymbol = s.parent.FindChildByName(directiveParam);
                        if (similarOverloadSymbol != null)
                        {
                            if (s.similarOverload == null)
                            {
                                s.similarOverload = similarOverloadSymbol;
                                similarOverloadSymbol.otherOverloads.Add(s);
                            }
                        }
                        else
                        {
            //                            Console.WriteLine("Can't find similarOverload " + directiveParam + " for member " + s.FullQualifiedSymbolName());
                        }
                        s.comments[i] = CutDocGeneratorCommentDirective(s.comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);

                        // Don't update startIndex since we deleted the "[]" block.
                    }
                    else if (directive.ToLower().StartsWith("indextitle") && directiveParam.Length > 0)
                    {
                        s.classMemberIndexTitle = directiveParam;
                        s.comments[i] = CutDocGeneratorCommentDirective(s.comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                    }
                    else if (directive.ToLower().StartsWith("hideindex"))
                    {
                        s.classMemberIndexTitle = "";
                        s.comments[i] = CutDocGeneratorCommentDirective(s.comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                    }
                    else
                    {
                        startIndex = endIdx;
                    }
                }
            }
        }
コード例 #17
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        private Symbol ParseMemberElement(Symbol parent, XmlElement memberElem)
        {
            Symbol member = new Symbol();
            member.parent = parent;
            member.kind = memberElem.GetAttribute("kind").StripHtmlCharacters();
            member.isStatic = (memberElem.GetAttribute("static").StripHtmlCharacters() == "yes") ? true : false;
            member.type = GetXmlElementChildNodeValue(memberElem, "type").StripHtmlCharacters();
            if (member.type.StartsWith("static"))
            {
                member.type = member.type.Substring(6).Trim();
                member.isStatic = true;
            }
            member.name = GetXmlElementChildNodeValue(memberElem, "name").StripHtmlCharacters();
            member.classMemberIndexTitle = member.name;
            member.anchorFile = GetXmlElementChildNodeValue(memberElem, "anchorfile").StripHtmlCharacters();
            documentationFiles.Add(member.anchorFile);
            member.anchor = GetXmlElementChildNodeValue(memberElem, "anchor").StripHtmlCharacters();
            member.argList = GetXmlElementChildNodeValue(memberElem, "arglist").StripHtmlCharacters();
            if (member.kind == "function")
                GenerateArgList(member);
            member.visibilityLevel = ParseVisibilityLevel(memberElem);
            member.virtualness = ParseVirtualness(memberElem);
            if (!symbolsByAnchor.ContainsKey(member.anchor))
                symbolsByAnchor.Add(member.anchor, member);

            return member;
        }
コード例 #18
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
 private void ParseFunctionReturnValueComments(Symbol s, string memdocContent)
 {
     int endIdx;
     string memberData = FindStringInBetween(memdocContent, 0, "<dl class=\"return\"><dt><b>Returns:</b></dt><dd>",
         "</dd></dl>", out endIdx);
     if (endIdx == -1)
         return;
     s.returnComment = memberData;
 }
コード例 #19
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateToScriptValue(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("QScriptValue ToScriptValue_" + Class.name + "(QScriptEngine *engine, const " + Class.name + " &value)");
            tw.WriteLine("{");
            //            tw.WriteLine(Indent(1) + "QScriptValue obj = engine->newObject();");
            tw.WriteLine(Indent(1) + "QScriptValue obj = engine->newVariant(QVariant::fromValue(value)); // The contents of this variant are NOT used. The real data lies in the data() pointer of this QScriptValue. This only exists to enable overload resolution to work for QObject slots.");

            tw.WriteLine(Indent(1) + "ToExistingScriptValue_" + Class.name + "(engine, value, obj);");
            tw.WriteLine(Indent(1) + "return obj;");
            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #20
0
ファイル: CodeStructure.cs プロジェクト: zhimaijoy/tundra
 void GroupSimilarOverloads(Symbol s)
 {
     for(int i = 0; i < s.children.Count; ++i)
         for(int j = i+1; j < s.children.Count; ++j)
         {
             Symbol master = s.children[i];
             Symbol child = s.children[j];
             if (master.similarOverload == null && child.similarOverload == null && child.otherOverloads.Count == 0)
             {
                 if (master.name == child.name)
                 {
                     if (child.Comments().Length == 0 || child.groupSyntax)
                     {
                         child.similarOverload = master;
                         master.otherOverloads.Add(child);
                     }
                     else
                         break;
                 }
             }
         }
 }
コード例 #21
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateToScriptValueConst(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("QScriptValue ToScriptValue_const_" + Class.name + "(QScriptEngine *engine, const " + Class.name + " &value)");
            tw.WriteLine("{");
            //            tw.WriteLine(Indent(1) + "QScriptValue obj = engine->newObject();");
            tw.WriteLine(Indent(1) + "QScriptValue obj = engine->newVariant(QVariant::fromValue(value)); // The contents of this variant are NOT used. The real data lies in the data() pointer of this QScriptValue. This only exists to enable overload resolution to work for QObject slots.");

            tw.WriteLine(Indent(1) + "obj.setPrototype(engine->defaultPrototype(qMetaTypeId<" + Class.name + ">()));");

            if (HasOpaqueQVariantBasedMarshalling(Class)) // If enabled, this type is marshalled opaquely.
                tw.WriteLine(Indent(1) + "obj.setData(engine->newVariant(QVariant::fromValue(value)));");

            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public && !v.isStatic)
                {
                    string conversionFunc = Symbol.IsPODType(v.type) ? "qScriptValueFromValue" : ("ToScriptValue_const_" + v.type);
                    tw.WriteLine(Indent(1) + "obj.setProperty(\"" + v.name + "\", " + conversionFunc + "(engine, value." + v.name
                        + "), QScriptValue::Undeletable | QScriptValue::ReadOnly);");
                }

            //            tw.WriteLine(Indent(1) + "obj.setPrototype(engine->defaultPrototype(qMetaTypeId<" + Class.name + ">()));");
            tw.WriteLine(Indent(1) + "return obj;");
            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #22
0
ファイル: CodeStructure.cs プロジェクト: zhimaijoy/tundra
        /// <summary>
        /// Goes through the given symbol and find all DocGenerator-style directives present in the comments
        /// and applies them. These directives are of form [foo].
        /// </summary>
        private void ProcessDocGeneratorCommentDirectives(Symbol s)
        {
//            string[] comments = s.Comments();
            string[] comments = new string[3] { s.briefDescription, s.detailedDescription, s.inbodyDescription };
            for (int i = 0; i < comments.Length; ++i)
            {
                comments[i] = comments[i].Trim();
                if (comments[i].EndsWith("<br/>"))
                    comments[i] = comments[i].Substring(0, comments[i].Length - 5);
                if (comments[i].EndsWith("<br />"))
                    comments[i] = comments[i].Substring(0, comments[i].Length - 6);
                comments[i] = comments[i].Trim();

                int endIdx;
                int startIndex = 0;
                while (startIndex < comments[i].Length)
                {
                    string directive = FindStringInBetween(comments[i], startIndex, "[", "]", out endIdx);
                    if (endIdx == -1)
                        break;

                    int directiveStartIndex = endIdx - directive.Length - 1;
                    directive = directive.Trim();
                    string[] st = directive.Split(':');
                    string directiveParam = "";
                    if (st.Length == 2)
                        directiveParam = st[1].Trim();

                    if (directive.ToLower().StartsWith("similaroverload") && directiveParam.Length > 0)
                    {
                        Symbol similarOverloadSymbol = s.parent.FindChildByName(directiveParam);
                        if (similarOverloadSymbol != null)
                        {
                            if (s.similarOverload == null)
                            {
                                s.similarOverload = similarOverloadSymbol;
                                similarOverloadSymbol.otherOverloads.Add(s);
                            }
                        }
                        else
                        {
//                            Console.WriteLine("Can't find similarOverload " + directiveParam + " for member " + s.FullQualifiedSymbolName());
                        }
                        comments[i] = CutDocGeneratorCommentDirective(comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                        startIndex = 0;

                        // Don't update startIndex since we deleted the "[]" block.
                    }
                    else if (directive.ToLower().StartsWith("indextitle") && directiveParam.Length > 0)
                    {
                        s.classMemberIndexTitle = directiveParam;
                        comments[i] = CutDocGeneratorCommentDirective(comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                        startIndex = 0;
                    }
                    else if (directive.ToLower().StartsWith("hideindex"))
                    {
                        s.classMemberIndexTitle = "";
                        comments[i] = CutDocGeneratorCommentDirective(comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                        startIndex = 0;
                    }
                    else if (directive.ToLower().StartsWith("category"))
                    {
                        s.documentationCategory = directiveParam;
                        comments[i] = CutDocGeneratorCommentDirective(comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                        startIndex = 0;
                    }
                    else if (directive.ToLower().StartsWith("groupsyntax"))
                    {
                        s.groupSyntax = true;
                        comments[i] = CutDocGeneratorCommentDirective(comments[i], directiveStartIndex - 1, endIdx + 1 - directiveStartIndex);
                        startIndex = 0;
                    }
                    else
                    {
                        startIndex = endIdx;
                    }
                }
            }
            s.briefDescription = comments[0];
            s.detailedDescription = comments[1];
            s.inbodyDescription = comments[2];
        }
コード例 #23
0
ファイル: Program.cs プロジェクト: Ilikia/naali
 static string GetMemberVariableSetCppFuncName(Symbol variable)
 {
     return variable.parent.name + "_" + variable.name + "_set";
 }
コード例 #24
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
 void GroupSimilarOverloads(Symbol s)
 {
     foreach(Symbol s1 in s.children.Values)
         foreach(Symbol s2 in s.children.Values)
             if (s1 != s2 && s1.similarOverload == null && s2.similarOverload == null && s2.otherOverloads.Count == 0)
             {
                 Symbol master = s1;
                 Symbol child = s2;
                 if (master.name == child.name)
                 {
                     if (child.comments.Count == 0)
                     {
                         child.similarOverload = master;
                         master.otherOverloads.Add(child);
                     }
                 }
             }
 }
コード例 #25
0
ファイル: Program.cs プロジェクト: Ilikia/naali
 static string GetMemberVariableSetScriptFuncName(Symbol variable)
 {
     string firstChar = variable.name.Substring(0, 1);
     return "set" + firstChar.ToUpper() + variable.name.Substring(1);
 }
コード例 #26
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateClassFunctionSelector(Symbol classSymbol, string functionName, TextWriter tw)
        {
            List<Symbol> functions = new List<Symbol>();
            foreach (Symbol s in classSymbol.children.Values)
                if (s.name == functionName && IsScriptable(s))
                    functions.Add(s);

            if (functions.Count < 2)
                return; // No need to generate a selector.

            tw.WriteLine("static QScriptValue " + GetScriptFunctionSelectorName(functions[0]) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");
            foreach (Symbol f in functions)
            {
                tw.Write(Indent(1) + "if (context->argumentCount() == " + f.parameters.Count);
                for(int i = 0; i < f.parameters.Count; ++i)
                {
                    tw.Write(" && ");
                    tw.Write("QSVIsOfType<" + f.parameters[i].BasicType() + ">(context->argument(" + i + "))");
                }
                tw.WriteLine(")");
                tw.WriteLine(Indent(2) + "return " + GetScriptFunctionName(f) + "(context, engine);");
            }
            bool isClassCtor = (functionName == classSymbol.name);
            if (isClassCtor)
                tw.WriteLine(Indent(1) + "printf(\"" + GetScriptFunctionSelectorName(functions[0]) + " failed to choose the right function to call! Did you use 'var x = " + classSymbol.name + "();' instead of 'var x = new " + classSymbol.name + "();'?\\n\"); PrintCallStack(context->backtrace()); return QScriptValue();");
            else
                tw.WriteLine(Indent(1) + "printf(\"" + GetScriptFunctionSelectorName(functions[0]) + " failed to choose the right function to call in file %s, line %d!\\n\", __FILE__, __LINE__); PrintCallStack(context->backtrace()); return QScriptValue();");
            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #27
0
ファイル: Program.cs プロジェクト: Ilikia/naali
 static string GetScriptFunctionSelectorName(Symbol function)
 {
     if (function.name == function.parent.name)
         return function.parent.name  + "_ctor";
     string str = function.parent.name + "_" + function.name + "_selector";
     return str;
 }
コード例 #28
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        static void GenerateClassPrototype(Symbol Class, TextWriter tw)
        {
            HashSet<string> registeredFunctions = new HashSet<string>();
            tw.WriteLine("QScriptValue register_" + Class.name + "_prototype(QScriptEngine *engine)");
            tw.WriteLine("{");
            //            tw.WriteLine(Indent(1) + "engine->setDefaultPrototype(qMetaTypeId<" + Class.name + "*>(), QScriptValue());");
            //            tw.WriteLine(Indent(1) + "QScriptValue proto = engine->newVariant(qVariantFromValue((" + Class.name + "*)0));");
            tw.WriteLine(Indent(1) + "QScriptValue proto = engine->newObject();");

            // Add each member function to the prototype.
            foreach (Symbol child in Class.children.Values)
                if (!registeredFunctions.Contains(child.name + "_____" + child.parameters.Count) && child.kind == "function" && !child.isStatic && child.name != Class.name && !child.name.Contains("operator") && IsScriptable(child))
                {
                    tw.WriteLine(Indent(1) + "proto.setProperty(\"" + child.name + "\", engine->newFunction(" + (NeedsClassFunctionSelector(Class, child.name) ? GetScriptFunctionSelectorName(child) : GetScriptFunctionName(child))
                        + ", " + child.parameters.Count + "), QScriptValue::Undeletable | QScriptValue::ReadOnly);");
                    registeredFunctions.Add(child.name + "_____" + child.parameters.Count);
                }
            /*
            // Add setters and getters for each member variable to the prototype.
            foreach (Symbol child in Class.children.Values)
                if (child.kind == "variable" && !child.isStatic && child.name != Class.name && !child.name.Contains("operator") && IsScriptable(child) && child.visibilityLevel == VisibilityLevel.Public)
                {
                    tw.WriteLine(Indent(1) + "proto.setProperty(\"" + GetMemberVariableGetScriptFuncName(child) + "\", engine->newFunction(" + GetMemberVariableGetCppFuncName(child) + ", 1));");
                    tw.WriteLine(Indent(1) + "proto.setProperty(\"" + GetMemberVariableSetScriptFuncName(child) + "\", engine->newFunction(" + GetMemberVariableSetCppFuncName(child) + ", 1));");
                }
            */
            //            tw.WriteLine(Indent(1) + Class.name + "_scriptclass *sc = new " + Class.name + "_scriptclass(engine);");
            //            tw.WriteLine(Indent(1) + "engine->setProperty(\"" + Class.name + "_scriptclass\", QVariant::fromValue<QScriptClass*>(sc));");
            //            tw.WriteLine(Indent(1) + "proto.setScriptClass(sc);");
            //            tw.WriteLine(Indent(1) + "sc->objectPrototype = proto;");

            tw.WriteLine(Indent(1) + "proto.setProperty(\"metaTypeId\", engine->toScriptValue<qint32>((qint32)qMetaTypeId<" + Class.name + ">()));");
            tw.WriteLine(Indent(1) + "engine->setDefaultPrototype(qMetaTypeId<" + Class.name + ">(), proto);");
            tw.WriteLine(Indent(1) + "engine->setDefaultPrototype(qMetaTypeId<" + Class.name + "*>(), proto);");
            tw.WriteLine(Indent(1) + "qScriptRegisterMetaType(engine, ToScriptValue_" + Class.name + ", FromScriptValue_" + Class.name + ", proto);");
            tw.WriteLine("");

            tw.WriteLine(Indent(1) + "QScriptValue ctor = engine->newFunction(" + Class.name + "_ctor, proto, " + CountMaxArgumentsForClassCtor(Class) + ");");

            registeredFunctions.Clear();
            foreach (Symbol child in Class.children.Values)
                if (!registeredFunctions.Contains(child.name + "_____" + child.parameters.Count) && child.kind == "function" && child.isStatic && child.name != Class.name && !child.name.Contains("operator") && IsScriptable(child))
                {
                    tw.WriteLine(Indent(1) + "ctor.setProperty(\"" + child.name + "\", engine->newFunction(" + (NeedsClassFunctionSelector(Class, child.name) ? GetScriptFunctionSelectorName(child) : GetScriptFunctionName(child))
                        + ", " + child.parameters.Count + "), QScriptValue::Undeletable | QScriptValue::ReadOnly);");
                    registeredFunctions.Add(child.name + "_____" + child.parameters.Count);
                }

            foreach (Symbol child in Class.children.Values)
                if (child.kind == "variable" && child.isStatic && child.name != Class.name && !child.name.Contains("operator") && IsScriptable(child))
                {
            //                    tw.WriteLine(Indent(1) + "ctor.setProperty(\"" + child.name + "\", TypeToQScriptValue(engine, " + Class.name + "::" + child.name + "));");
                    tw.WriteLine(Indent(1) + "ctor.setProperty(\"" + child.name + "\", qScriptValueFromValue(engine, " + Class.name + "::" + child.name +
                        "), QScriptValue::Undeletable" + ( child.IsConst() ? " | QScriptValue::ReadOnly" : "" ) + ");");
                    registeredFunctions.Add(child.name + "_____" + child.parameters.Count);
                }

            tw.WriteLine(Indent(1) + "engine->globalObject().setProperty(\"" + Class.name + "\", ctor, QScriptValue::Undeletable | QScriptValue::ReadOnly);");
            tw.WriteLine("");

            tw.WriteLine(Indent(1) + "return ctor;");

            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #29
0
ファイル: Program.cs プロジェクト: Ilikia/naali
        /*
        static void GenerateScriptClass(Symbol Class, TextWriter tw)
        {
            tw.WriteLine("class " + Class.name + "_scriptclass : public QScriptClass");
            tw.WriteLine("{");
            tw.WriteLine("public:");
            tw.WriteLine(Indent(1) + "QScriptValue objectPrototype;");
            tw.WriteLine(Indent(1) + Class.name + "_scriptclass(QScriptEngine *engine):QScriptClass(engine){}");
            tw.WriteLine(Indent(1) + "QScriptValue property(const QScriptValue &object, const QScriptString &name, uint id)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + Class.name + " *This = TypeFromQScriptValue<" + Class.name + "*>(object);");
            tw.WriteLine(Indent(2) + "if (!This) { printf(\"Error! Cannot convert QScriptValue to type " + Class.name + " in file %s, line %d!\\nTry using " + Class.name + ".get%s() and " + Class.name + ".set%s() to query the member variable '%s'!\\n\", __FILE__, __LINE__, Capitalize((QString)name).c_str(), Capitalize((QString)name).c_str(), ((QString)name).toStdString().c_str()); return QScriptValue(); }");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");
            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public)
                {
        //                    tw.Write(Indent(2) + "if ((QString)name == (QString)\"" + v.name + "\")");
        // Experimental: Access members directly using 'foo.x_' and 'foo.x_ptr'.
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                        //tw.WriteLine(" return TypeToQScriptValue(engine(), This->" + v.name + ");");
                    }
                    else
                    {
                        tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        tw.WriteLine(" return TypeToQScriptValue(engine(), This->" + v.name + ");");
                        if (!Symbol.IsPODType(v.type))
                        {
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_ptr\")");
                            tw.WriteLine(" return TypeToQScriptValue(engine(), &This->" + v.name + ");");
                        }
                    }
                }

            tw.WriteLine(Indent(2) + "return QScriptValue();");
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + Class.name + " *This = TypeFromQScriptValue<" + Class.name + "*>(object);");
            tw.WriteLine(Indent(2) + "if (!This) { printf(\"Error! Cannot convert QScriptValue to type " + Class.name + " in file %s, line %d!\\nTry using " + Class.name + ".get%s() and " + Class.name + ".set%s() to query the member variable '%s'!\\n\", __FILE__, __LINE__, Capitalize((QString)name).c_str(), Capitalize((QString)name).c_str(), ((QString)name).toStdString().c_str()); return; }");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");

            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && !v.IsConst() && v.visibilityLevel == VisibilityLevel.Public)
                {
        //                    tw.Write(Indent(2) + "if (name_ == (QString)\"" + v.name + "\")");
        //                    tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                    // Experimental: Access members directly using 'foo.x_' and 'foo.x_ptr'.
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                       // tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                    }
                    else
                    {
                        tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        tw.WriteLine(" This->" + v.name + " = TypeFromQScriptValue<" + v.type + ">(value);");
                        if (!Symbol.IsPODType(v.type))
                        {
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_ptr\")");
                            tw.WriteLine(" This->" + v.name + " = *TypeFromQScriptValue<" + v.type + "*>(value);");
                        }
                    }
                }
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, QueryFlags flags, uint *id)");
            tw.WriteLine(Indent(1) + "{");
            tw.WriteLine(Indent(2) + "QString name_ = (QString)name;");
            foreach (Symbol v in Class.children.Values)
                if (v.kind == "variable" && IsScriptable(v) && v.visibilityLevel == VisibilityLevel.Public)
                {
                    if (v.isStatic)
                    {
                        //tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                    }
                    else
                    {
                        //                    tw.Write(Indent(2) + "if (name_ == \"" + v.name + "\")");
                        if (Symbol.IsPODType(v.type))
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\")");
                        else
                            tw.Write(Indent(2) + "if (name_ == \"" + v.name + "_\" || name_ == \"" + v.name + "_ptr\")");
                        tw.WriteLine(" return flags;");
                    }
        //                    tw.WriteLine(" return flags;");
                }
            tw.WriteLine(Indent(2) + "return 0;");
            tw.WriteLine(Indent(1) + "}");

            tw.WriteLine(Indent(1) + "QScriptValue prototype() const { return objectPrototype; }");
            tw.WriteLine("};");
        }
        */
        static void GenerateClassFunction(Symbol function, TextWriter tw)
        {
            Symbol Class = function.parent;

            tw.WriteLine("static QScriptValue " + GetScriptFunctionName(function) + "(QScriptContext *context, QScriptEngine *engine)");
            tw.WriteLine("{");
            int argIdx = 0;

            bool isClassCtor = (function.name == Class.name);

            if (function.name != "toString") // Qt oddities: It seems sometimes the hardcoded toString is called with this as the first argument and not as 'this'.
                tw.WriteLine(Indent(1) + "if (context->argumentCount() != " + function.parameters.Count + ") { printf(\"Error! Invalid number of arguments passed to function " + GetScriptFunctionName(function) + " in file %s, line %d!\\nExpected " + function.parameters.Count + ", but got %d!\\n\", __FILE__, __LINE__, context->argumentCount()); PrintCallStack(context->backtrace()); return QScriptValue(); }");

            // Test that we have a valid this.
            if (!function.isStatic && !isClassCtor)
            {
            //                tw.WriteLine(Indent(1) + Class.name + " *This = " + "TypeFromQScriptValue<" + Class.name + "*>(context->thisObject());");
            //                tw.WriteLine(Indent(1) + Class.name + " *This = " + "qscriptvalue_cast<" + Class.name + "*>(context->thisObject());");
                if (function.name == "toString") // Qt oddities: It seems sometimes the hardcoded toString is called with this as the first argument and not as 'this'.
                {
                    tw.WriteLine(Indent(1) + Class.name + " This;");
                    tw.WriteLine(Indent(1) + "if (context->argumentCount() > 0) This = qscriptvalue_cast<" + Class.name + ">(context->argument(0)); // Qt oddity (bug?): Sometimes the built-in toString() function doesn't give us this from thisObject, but as the first argument.");
                    tw.WriteLine(Indent(1) + "else This = qscriptvalue_cast<" + Class.name + ">(context->thisObject());");

                }
                else
                    tw.WriteLine(Indent(1) + Class.name + " This = " + "qscriptvalue_cast<" + Class.name + ">(context->thisObject());");
                //                tw.WriteLine(Indent(1) + "if (!This && context->argumentCount() > 0) This = TypeFromQScriptValue<" + Class.name + "*>(context->argument(0)); // Qt oddity (bug?): Sometimes the built-in toString() function doesn't give us this from thisObject, but as the first argument.");
            //                tw.WriteLine(Indent(1) + "if (!This) { printf(\"Error! Invalid context->thisObject in function " + GetScriptFunctionName(function) + " in file %s, line %d\\n!\", __FILE__, __LINE__); return QScriptValue(); }");
            }

            // Unmarshall all parameters to the function.
            foreach (Parameter p in function.parameters)
                tw.WriteLine(Indent(1) + p.BasicType() + " " + p.name + " = qscriptvalue_cast<" + p.BasicType() + ">(context->argument(" + (argIdx++) + "));");
            //            tw.WriteLine(Indent(1) + p.BasicType() + " " + p.name + " = TypeFromQScriptValue<" + p.BasicType() + ">(context->argument(" + (argIdx++) + "));");

            if (isClassCtor) // Is this function a ctor of this class.
            {
                if (function.parameters.Count == 0)
                    tw.WriteLine(Indent(1) + Class.name + " ret;"); // Create a new instance of this class, no parameters.
                else
                    tw.Write(Indent(1) + Class.name + " ret("); // Create a new instance of this class, one or more parameters.
            }
            else
            {
                string instanceName = (function.isStatic ? (Class.name + "::") : "This.");
            //                string instanceName = (function.isStatic ? (Class.name + "::") : "This->");
                if (function.type != "void")
                    tw.Write(Indent(1) + function.type + " ret = " + instanceName + function.name + "("); // Make the function call.
                else
                    tw.Write(Indent(1) + instanceName + function.name + "("); // Make the function call.
            }

            for (int i = 0; i < function.parameters.Count; ++i)
                tw.Write(function.parameters[i].name + (i + 1 < function.parameters.Count ? ", " : ""));
            if (!isClassCtor || function.parameters.Count > 0)
                tw.WriteLine(");");

            // If the function is non-const, regenerate the proper QScriptValue as the result.
            if (!function.IsConst() && !function.isStatic && function.name != Class.name)
                tw.WriteLine(Indent(1) + "ToExistingScriptValue_" + Class.name + "(engine, This, context->thisObject());");

            // Return the return value as QScriptValue.
            if (!isClassCtor)
            {
                if (function.type != "void")
            //                    tw.WriteLine(Indent(1) + "return TypeToQScriptValue(engine, ret);");
                    tw.WriteLine(Indent(1) + "return qScriptValueFromValue(engine, ret);");
                else
                    tw.WriteLine(Indent(1) + "return QScriptValue();");
            }
            else
            {
            //                tw.WriteLine(Indent(1) + "return TypeToQScriptValue(engine, ret);");
                tw.WriteLine(Indent(1) + "return qScriptValueFromValue(engine, ret);");
            }

            tw.WriteLine("}");
            tw.WriteLine("");
        }
コード例 #30
0
ファイル: CodeStructure.cs プロジェクト: Ilikia/naali
        private void ParseFunctionArgList(Symbol s, string content)
        {
            s.parameters.Clear();

            int endIdx;
            content = FindStringInBetween(content, 0, "<table class=\"memname\">", "</table>", out endIdx);
            if (endIdx == -1)
                return;

            int startIdx = 0;
            while (startIdx < content.Length)
            {
                string paramType = FindStringInBetween(content, startIdx, "<td class=\"paramtype\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx+1;
                string paramName = FindStringInBetween(content, startIdx, "<td class=\"paramname\">", "</td>", out endIdx);
                if (endIdx == -1)
                    return;
                startIdx = endIdx + 1;
                string strippedParamName = FindStringInBetween(paramName, 0, "<em>", "</em>", out endIdx);

                Parameter p = new Parameter();
                p.type = paramType.StripHtmlCharacters().StripHtmlLinks();
                p.name = strippedParamName.StripHtmlCharacters().StripHtmlLinks();
                s.parameters.Add(p);
            }
        }