/// <summary> /// スクリプト内の関数リストをListView形式にして返します。 /// 1列目:行数、2列目:関数名 /// </summary> /// <returns></returns> public static List <ListViewItem> GetFunctionList(string rPath) { var textlines = new List <string>(); var list = new List <ListViewItem>(); //スクリプトを行単位で読み込む using (var R = new StreamReader(Common.OpenFileReadOnly(ProjectManager.ProjectPath + rPath), Common.SJIS)) { while (!R.EndOfStream) { textlines.Add(R.ReadLine()); } } //全行の行頭を走査 var i = 0; foreach (var line in textlines) { int index; //関数定義を検索 var buf = Common.CutHeadTabs(line); var funcKeyword = Resources.SQ_Function.Trim(); //関数のキーワードだが、ここでは空白部分をカットする index = buf.IndexOf(funcKeyword, StringComparison.InvariantCulture); if (index != -1 && buf.IndexOf("(") != -1) { //見つかった場合、関数名を抜き出す buf = buf.Substring(index + funcKeyword.Length); index = buf.IndexOf("("); if (index == -1) { //構文エラー continue; } buf = buf.Substring(0, index).Trim(); if (string.IsNullOrEmpty(buf)) { //無名関数 buf = "(無名関数)"; } var item = new ListViewItem { Text = buf }; item.SubItems.Add((i + 1).ToString()); //行番号 item.SubItems.Add("?"); //ステートメント数 item.SubItems.Add("?"); //サイクロマティック複雑度 //引数リストをTagに入れる item.Tag = SQ.GetArgumentListByCall(line); list.Add(item); } i++; } return(list); }
/// <summary> /// 指定したノードの下にゲームプログラムがサポートするオブジェクト群を登録します。 /// </summary> public static void SetCPPObjectsTree(TreeNode root) { //直下のノードのToolTipをやさしくする foreach (TreeNode node in root.Nodes) { node.ToolTipText = node.ToolTipText.Replace("。", "。\r\n"); } //リソースから読み込む using (var R = new StringReader(Resources.SQCodeTree)) { GenerateGlueCode.GenerateCPPDocument.LoadDocumentByStream(R); } //仮名称(識別子)でツリーを生成する var currentNode = root; TreeNode parentNode = null; TreeNode tempNode = null; var parentPath = ""; foreach (var obj in GenerateGlueCode.GenerateCPPDocument.SQObjects) { var node = new TreeNode { Text = obj.Name, //暫定的に識別子で登録する Tag = obj //詳細なオブジェクト情報はTagに格納する }; obj.ClassPath = obj.ClassPath .Replace("TS::", "") .Replace("SQEventHandler::", "") .Replace("::", "\\"); //区切り記号をTreeView用にする parentPath = Path.GetDirectoryName(obj.ClassPath); //種別に応じて振り分ける switch (obj.NodeID) { case GenerateGlueCode.GenerateCPPDocument.ObjectType.Const: //定数: 途中のノードは機械的なものなので自動生成にする switch (obj.SubType) { case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Enum: currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjEnum], parentPath); tempNode = Common.GetExistsNode(currentNode, node.Text); if (tempNode != null) { //生成しようとしているノードが既に存在する(メンバーが先に登録される等で先行的に仮生成された)場合はそれに置き換える node = tempNode; tempNode.Tag = obj; } else { //存在しない場合は新規追加する currentNode.Nodes.Add(node); } Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPEnum); parentNode = node; break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.EnumMember: Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPEnumMember); parentNode.Nodes.Add(node); break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Const: currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjConst], parentPath); Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPConst); currentNode.Nodes.Add(node); break; } break; case GenerateGlueCode.GenerateCPPDocument.ObjectType.Value: //ノード直下に並べる currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjValue], parentPath); Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPValue); currentNode.Nodes.Add(node); break; case GenerateGlueCode.GenerateCPPDocument.ObjectType.Function: //ノード直下に並べる currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjFunc], parentPath); Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPFunc); currentNode.Nodes.Add(node); break; case GenerateGlueCode.GenerateCPPDocument.ObjectType.GameObject: //途中のノードもクラス階層を成すが、まずは識別子の階層で生成する currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjClass], parentPath); switch (obj.SubType) { case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Class: tempNode = Common.GetExistsNode(currentNode, node.Text); if (tempNode != null) { //生成しようとしているノードが既に存在する(入れ子クラス等により先行的に仮生成された)場合はそれに置き換える node = tempNode; tempNode.Tag = obj; } else { //存在しない場合は新規追加する currentNode.Nodes.Add(node); } Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPClass); break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.ClassFunc: case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.MemberFunc: Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPFunc); currentNode.Nodes.Add(node); break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.ClassValue: case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.MemberValue: Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPValue); currentNode.Nodes.Add(node); break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.MemberProperty: Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.CPPProperty); currentNode.Nodes.Add(node); break; } break; case GenerateGlueCode.GenerateCPPDocument.ObjectType.SQEventHandler: currentNode = Common.CreateNodePath(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjSQEventHandler], null); Common.SetTreeNodeImageIndex(node, (int)CtrlComponent.Text.ctlCommandTree.CPPObjectIconIndices.SQEventHandler); currentNode.Nodes.Add(node); break; } } //変数/プロパティは、そのクラス型に対応するメンバーをコピーする //クラスは、派生元クラスがあるならそれらのメンバーをコピーする var nodes = new List <TreeNode>(); nodes.AddRange(Common.GetNodeListToFlat(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjClass])); nodes.AddRange(Common.GetNodeListToFlat(root.Nodes[CtrlComponent.Text.ctlCommandTree.NodeNameCppObjValue])); foreach (var node in nodes) { var obj = node.Tag as SQObject; if (obj == null) { continue; } if (obj.NodeID == GenerateGlueCode.GenerateCPPDocument.ObjectType.Value || obj.SubType == GenerateGlueCode.GenerateCPPDocument.ObjectSubType.MemberProperty) { //変数/プロパティ: 該当クラス型を検索 if (string.IsNullOrEmpty(obj.ReturnType) || obj.ReturnType.Substring(0, 1) != "C") { //クラスでない型は処理しない continue; } // [読み取り専用] の文字列を無視する var idx = obj.ReturnType.IndexOf(" "); var typeName = (idx == -1) ? obj.ReturnType : obj.ReturnType.Substring(0, idx); foreach (var sub in nodes) { var subobj = sub.Tag as SQObject; if (subobj == null) { continue; } else if (subobj.SubType == GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Class && typeName == subobj.Name) { //一致するクラスを発見: クラス以外のノードをコピーする SQ.addNodeExceptClass(node, sub); break; } } } else if (obj.SubType == GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Class && !string.IsNullOrEmpty(obj.SuperClassName)) { //派生元クラスがあるクラス //派生元クラス名を抽出 var superClass = obj.SuperClassName; int idx; idx = superClass.IndexOf(","); if (idx != -1) { superClass = superClass.Substring(0, idx); } idx = superClass.LastIndexOf("::"); if (idx != -1) { superClass = superClass.Substring(idx + 2); } //派生元クラスを検索 var found = false; foreach (var sub in nodes) { var subobj = sub.Tag as SQObject; if (subobj == null) { continue; } else if (subobj.SubType == GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Class && subobj.Name == superClass) { //一致するクラスを発見 foreach (TreeNode subnode in sub.Nodes) { node.Nodes.Add(subnode.Clone() as TreeNode); } found = true; break; } } if (!found) { System.Diagnostics.Debug.WriteLine("見つからない: " + superClass); } } } //表示名とツールチップをセットする nodes = Common.GetNodeListToFlat(root); foreach (var node in nodes) { var obj = node.Tag as SQObject; if (obj == null) { continue; } if (!string.IsNullOrEmpty(obj.Summary)) { node.Text = obj.Summary; } switch (obj.SubType) { case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.ClassFunc: case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.ClassValue: //staticなメンバーには名称の頭に接頭辞を付ける node.Text = CtrlComponent.Text.ctlCommandTree.ClassStaticMemberHeader + node.Text; break; } //ツールチップのテキストをやさしくする node.ToolTipText = obj.Comment.Replace("。", "。\r\n"); //先頭行に実際の識別子と型名(クラス以外)を追加する switch (obj.SubType) { case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Const: node.ToolTipText = obj.Name + " [" + (obj.ReturnType ?? "定数") + "]\r\n" + node.ToolTipText; break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.SQEnum: case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Enum: node.ToolTipText = obj.Name + " [列挙体]\r\n" + node.ToolTipText; break; case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.SQEnumMember: case GenerateGlueCode.GenerateCPPDocument.ObjectSubType.EnumMember: node.ToolTipText = obj.Name + " [列挙体メンバー]\r\n" + node.ToolTipText; break; default: if (obj.SubType != GenerateGlueCode.GenerateCPPDocument.ObjectSubType.Class) { //プロパティは型名も追加する node.ToolTipText = obj.Name + " [" + obj.ReturnType + "]\r\n" + node.ToolTipText; } else { node.ToolTipText = obj.Name + "\r\n" + node.ToolTipText; } break; } } }