public void UpdateAndActive(ASClass aClass) { try { classTree.BeginUpdate(); if (aClass.IsVoid()) { AddInView(ASContext.MainForm.CurFile); } else { UpdateView(aClass); } SetActiveClass(aClass); } finally { classTree.EndUpdate(); Win32.Scrolling.scrollToLeft(classTree); } }
public string GenerateIntrinsic() { StringBuilder sb = new StringBuilder(); string nl = "\r\n"; char semi = ';'; char tab = '\t'; // IMPORTS ArrayList known = new ArrayList(); known.Add(ClassName); foreach (ASMember import in Imports) { if (!known.Contains(import.Type)) { known.Add(import.Type); sb.Append("import ").Append(import.Type).Append(semi).Append(nl); } } // CLASS sb.Append(CommentDeclaration(Comments, false)); if ((this.Flags & (FlagType.Intrinsic | FlagType.Interface)) == 0) { sb.Append("intrinsic "); } sb.Append(ClassDeclaration(this)); if (!extends.IsVoid() && (extends.ClassName != "Object")) { sb.Append(" extends ").Append(extends.ClassName); } if (Implements != null) { sb.Append(" implements ").Append(Implements); } sb.Append(nl).Append('{').Append(nl); // MEMBERS int count = 0; foreach (ASMember var in Vars) //if ( (var.Flags & FlagType.Public) > 0 ) { sb.Append(CommentDeclaration(var.Comments, true)); sb.Append(tab).Append(MemberDeclaration(var)).Append(semi).Append(nl); count++; } if (count > 0) { sb.Append(nl); } // MEMBERS string decl; ASMember temp; count = 0; foreach (ASMember property in Properties) //if ( (property.Flags & FlagType.Public) > 0 ) { sb.Append(CommentDeclaration(property.Comments, true)); FlagType flags = (property.Flags & ~(FlagType.Setter | FlagType.Getter)) | FlagType.Function; if ((property.Flags & FlagType.Getter) > 0) { temp = (ASMember)property.Clone(); temp.Name = "get " + temp.Name; temp.Flags = flags; temp.Parameters = ""; sb.Append(tab).Append(MemberDeclaration(temp)).Append(semi).Append(nl); } if ((property.Flags & FlagType.Setter) > 0) { temp = (ASMember)property.Clone(); temp.Name = "set " + temp.Name; temp.Flags = flags; temp.Type = (IsAS3) ? "void" : "Void"; sb.Append(tab).Append(MemberDeclaration(temp)).Append(semi).Append(nl); } sb.Append(nl); count++; } if (count > 0) { sb.Append(nl); } // MEMBERS count = 0; foreach (ASMember method in Methods) //if ( (method.Flags & FlagType.Public) > 0 ) { decl = MemberDeclaration(method); if ((method.Flags & FlagType.Constructor) > 0) { decl = decl.Replace(" : constructor", ""); } sb.Append(CommentDeclaration(method.Comments, true)); sb.Append(tab).Append(decl).Append(semi).Append(nl).Append(nl); count++; } // END CLASS sb.Append('}'); return(sb.ToString()); }
/// <summary> /// Recursively convert classes /// </summary> /// <param name="path">folder to convert</param> static void ExploreFolder(string path) { currentFile = path; known.Add(path); // convert classes string[] files = Directory.GetFiles(path, "*.as"); ASClass fClass; string destFile; DateTime timestamp; int codepage; foreach(string file in files) { currentFile = file; destFile = destPath+file.Substring(srcPath.Length); // not modified: ignore timestamp = File.GetLastWriteTime(file); if (File.Exists(destFile) && File.GetLastWriteTime(destFile) == timestamp) continue; // parse class codepage = GetFileCodepage(file); fClass = new ASClass(); fClass.FileName = file; ASClassParser.ParseClass(fClass); if (fClass.IsVoid()) continue; // create intrinsic Directory.CreateDirectory(Path.GetDirectoryName(destFile)); Write(destFile, fClass.GenerateIntrinsic(), Encoding.GetEncoding(codepage)); File.SetCreationTime(destFile, timestamp); File.SetLastWriteTime(destFile, timestamp); total++; } // explore subfolders currentFile = path; string[] dirs = Directory.GetDirectories(path); foreach(string dir in dirs) { if (!known.Contains(dir)) ExploreFolder(dir); } }
public void UpdateView(ASClass aClass) { bool updateToken = false; try { DebugConsole.Trace("UI: update "+aClass.ClassName); if (aClass.IsVoid()) return; // compute class data "checksum" to know if it changed string fileName = aClass.FileName; string prevDataCheck = (string)checkEntries[fileName]; StringBuilder sb = new StringBuilder().Append(aClass.Extends.ClassName); foreach(ASMember import in aClass.Imports) sb.Append(import.Name); foreach(ASMember method in aClass.Methods) sb.Append(method.Flags.ToString()).Append(method.ToString()); foreach(ASMember prop in aClass.Properties) sb.Append(prop.Flags.ToString()).Append(prop.ToString()); foreach(ASMember var in aClass.Vars) sb.Append(var.Flags.ToString()).Append(var.ToString()); string classDataCheck = sb.ToString(); // for tree exploration TreeNodeCollection nodes = classTree.Nodes; TreeNode node = null; TreeNode insertBefore = null; // re-sort imports by package aClass.Sort(); ASMemberList import2 = new ASMemberList(); ASMember newImport; foreach(ASMember import in aClass.Imports) { newImport = new ASMember(); newImport.Name = import.Type; import2.Add(newImport); } import2.Sort(); // search item insertion/update position string cname = aClass.ClassName; bool entryExists = false; foreach(TreeNode sub in nodes) { if (sub.Text == cname) { node = sub; entryExists = true; break; } else if (sub.Text.CompareTo(cname) > 0) { insertBefore = sub; break; } } // New class if (node == null) { updateToken = true; classTree.BeginStatefulUpdate(); // create class node node = new TreeNode(cname); node.Tag = aClass.FileName; if (insertBefore != null) nodes.Insert(insertBefore.Index, node); else nodes.Add(node); // class details nodes if (showExtend) node.Nodes.Add(new TreeNode("Extends",1,1)); if (showImports) node.Nodes.Add(new TreeNode("Imports",1,1)); // class members nodes if (memberGroups == 1) { node.Nodes.Add(new TreeNode("Members",1,1)); } else { if (memberGroups > 1) { node.Nodes.Add(new TreeNode("Methods",1,1)); node.Nodes.Add(new TreeNode("Properties",1,1)); } if (memberGroups > 2) node.Nodes.Add(new TreeNode("Variables",1,1)); } } // Check class infos else { if (classDataCheck == prevDataCheck) return; updateToken = true; classTree.BeginStatefulUpdate(); } // // UPDATE CLASS INFO // checkEntries[fileName] = classDataCheck; int index = 0; TreeNode sub2; // entends if (showExtend) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); if (!aClass.Extends.IsVoid()) { if ((aClass.Extends.Flags & FlagType.Intrinsic) > 0) sub2 = new TreeNode(aClass.Extends.ClassName, 7,7); else sub2 = new TreeNode(aClass.Extends.ClassName, 0,0); sub2.Tag = aClass.Extends.FileName; nodes.Add(sub2); } } // imports if (showImports) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); foreach(ASMember import in import2) { if ((import.Flags & FlagType.Intrinsic) > 0) nodes.Add(new TreeNode(import.Name, 7,7)); else nodes.Add(new TreeNode(import.Name, 0,0)); } } // methods int img; if (memberGroups > 0) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); foreach(ASMember method in aClass.Methods) { img = ((method.Flags & FlagType.Private) > 0) ? 12 : 3; sub2 = new TreeNode(method.ToString(), img,img); sub2.Tag = method.Name; nodes.Add(sub2); } // properties if (memberGroups > 1) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); } foreach(ASMember prop in aClass.Properties) { img = ((prop.Flags & FlagType.Private) > 0) ? 13 : 4; sub2 = new TreeNode(prop.ToString(), img,img); sub2.Tag = prop.Name; nodes.Add(sub2); } // variables if (memberGroups > 2) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); } foreach(ASMember var in aClass.Vars) { img = ((var.Flags & FlagType.Private) > 0) ? 14 : 5; sub2 = new TreeNode(var.ToString(),img,img); sub2.Tag = var.Name; nodes.Add(sub2); } } // expand index = 0; if (showExtend) index++; if (showImports) index++; for (int i=0; i<memberGroups; i++) node.Nodes[index++].Expand(); node.Expand(); if (!entryExists) node.EnsureVisible(); } finally { if (updateToken) classTree.EndStatefulUpdate(); } }
public void SetActiveClass(ASClass aClass) { try { classTree.BeginUpdate(); string filename; if (aClass.IsVoid()) filename = ASContext.MainForm.CurFile; else filename = aClass.FileName; DebugConsole.Trace("UI: set active "+filename); // bool found = false; foreach(TreeNode node in classTree.Nodes) if ((string)node.Tag == filename) { if (!found) { found = true; classTree.SelectedNode = node; int index = 0; if (showExtend) index++; if (showImports) index++; for (int i=0; i<memberGroups; i++) node.Nodes[index++].Expand(); node.Expand(); } else classTree.Nodes.Remove(node); } else node.Collapse(); // if (classTree.SelectedNode != null) classTree.SelectedNode.EnsureVisible(); } catch { classTree.SelectedNode = null; } finally { classTree.EndUpdate(); Win32.Scrolling.scrollToLeft(classTree); } }
public void UpdateAndActive(ASClass aClass) { try { classTree.BeginUpdate(); if (aClass.IsVoid()) AddInView(ASContext.MainForm.CurFile); else UpdateView(aClass); SetActiveClass(aClass); } finally { classTree.EndUpdate(); Win32.Scrolling.scrollToLeft(classTree); } }
private void delayedClassTreeSelect(Object sender, System.Timers.ElapsedEventArgs e) { TreeNode node = classTree.SelectedNode; if (node == null) { return; } try { // class node if (node.Parent == null) { if (node.Tag != null) { ASContext.MainForm.OpenSelectedFile((string)node.Tag); } } // group node else if (node.Nodes.Count > 0) { node.Toggle(); } // leaf node else if ((node.Parent != null) && (node.Parent.Tag == null)) { TreeNode classNode = node.Parent.Parent; ScintillaNet.ScintillaControl sci = ASContext.MainForm.CurSciControl; // for Back command: if (sci != null) { SetLastLookupPosition(ASContext.CurrentFile, sci.CurrentPos); } // int index = node.Parent.Index; // extends if (showExtend && index == 0) { if (node.Tag != null) { ASContext.MainForm.OpenSelectedFile((string)node.Tag); } } // import else if (showImports && ((showExtend && index == 1) || (!showExtend && index == 0))) { ASClass aClass = ASContext.FindClassFromFile((string)classNode.Tag); if (aClass.IsVoid()) { return; } ASContext.OpenFileFromClass(node.Text, aClass); } // members else if (node.Tag != null) { ASContext.MainForm.OpenSelectedFile((string)classNode.Tag); sci = ASContext.MainForm.CurSciControl; if (sci == null) { return; } // look for declaration string pname = Regex.Escape((string)node.Tag); Match m = null; switch (node.ImageIndex) { case 12: // method case 3: m = Regex.Match(sci.Text, "function[\\s]+(?<pname>" + pname + ")[\\s]*\\("); break; case 13: // property case 4: m = Regex.Match(sci.Text, "function[\\s]+(?<pname>(g|s)et[\\s]+" + pname + ")[\\s]*\\("); break; case 14: // variables case 5: m = Regex.Match(sci.Text, "var[\\s]+(?<pname>" + pname + ")[^\\w]"); break; } // show if (m != null && m.Success) { GotoPosAndFocus(sci, m.Groups["pname"].Index); sci.SetSel(sci.CurrentPos, sci.CurrentPos + m.Groups["pname"].Length); } } } } catch (Exception ex) { ErrorHandler.ShowError(ex.Message, ex); } }
public void UpdateView(ASClass aClass) { bool updateToken = false; try { DebugConsole.Trace("UI: update " + aClass.ClassName); if (aClass.IsVoid()) { return; } // compute class data "checksum" to know if it changed string fileName = aClass.FileName; string prevDataCheck = (string)checkEntries[fileName]; StringBuilder sb = new StringBuilder().Append(aClass.Extends.ClassName); foreach (ASMember import in aClass.Imports) { sb.Append(import.Name); } foreach (ASMember method in aClass.Methods) { sb.Append(method.Flags.ToString()).Append(method.ToString()); } foreach (ASMember prop in aClass.Properties) { sb.Append(prop.Flags.ToString()).Append(prop.ToString()); } foreach (ASMember var in aClass.Vars) { sb.Append(var.Flags.ToString()).Append(var.ToString()); } string classDataCheck = sb.ToString(); // for tree exploration TreeNodeCollection nodes = classTree.Nodes; TreeNode node = null; TreeNode insertBefore = null; // re-sort imports by package aClass.Sort(); ASMemberList import2 = new ASMemberList(); ASMember newImport; foreach (ASMember import in aClass.Imports) { newImport = new ASMember(); newImport.Name = import.Type; import2.Add(newImport); } import2.Sort(); // search item insertion/update position string cname = aClass.ClassName; bool entryExists = false; foreach (TreeNode sub in nodes) { if (sub.Text == cname) { node = sub; entryExists = true; break; } else if (sub.Text.CompareTo(cname) > 0) { insertBefore = sub; break; } } // New class if (node == null) { updateToken = true; classTree.BeginStatefulUpdate(); // create class node node = new TreeNode(cname); node.Tag = aClass.FileName; if (insertBefore != null) { nodes.Insert(insertBefore.Index, node); } else { nodes.Add(node); } // class details nodes if (showExtend) { node.Nodes.Add(new TreeNode("Extends", 1, 1)); } if (showImports) { node.Nodes.Add(new TreeNode("Imports", 1, 1)); } // class members nodes if (memberGroups == 1) { node.Nodes.Add(new TreeNode("Members", 1, 1)); } else { if (memberGroups > 1) { node.Nodes.Add(new TreeNode("Methods", 1, 1)); node.Nodes.Add(new TreeNode("Properties", 1, 1)); } if (memberGroups > 2) { node.Nodes.Add(new TreeNode("Variables", 1, 1)); } } } // Check class infos else { if (classDataCheck == prevDataCheck) { return; } updateToken = true; classTree.BeginStatefulUpdate(); } // // UPDATE CLASS INFO // checkEntries[fileName] = classDataCheck; int index = 0; TreeNode sub2; // entends if (showExtend) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); if (!aClass.Extends.IsVoid()) { if ((aClass.Extends.Flags & FlagType.Intrinsic) > 0) { sub2 = new TreeNode(aClass.Extends.ClassName, 7, 7); } else { sub2 = new TreeNode(aClass.Extends.ClassName, 0, 0); } sub2.Tag = aClass.Extends.FileName; nodes.Add(sub2); } } // imports if (showImports) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); foreach (ASMember import in import2) { if ((import.Flags & FlagType.Intrinsic) > 0) { nodes.Add(new TreeNode(import.Name, 7, 7)); } else { nodes.Add(new TreeNode(import.Name, 0, 0)); } } } // methods int img; if (memberGroups > 0) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); foreach (ASMember method in aClass.Methods) { img = ((method.Flags & FlagType.Private) > 0) ? 12 : 3; sub2 = new TreeNode(method.ToString(), img, img); sub2.Tag = method.Name; nodes.Add(sub2); } // properties if (memberGroups > 1) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); } foreach (ASMember prop in aClass.Properties) { img = ((prop.Flags & FlagType.Private) > 0) ? 13 : 4; sub2 = new TreeNode(prop.ToString(), img, img); sub2.Tag = prop.Name; nodes.Add(sub2); } // variables if (memberGroups > 2) { nodes = node.Nodes[index++].Nodes; nodes.Clear(); } foreach (ASMember var in aClass.Vars) { img = ((var.Flags & FlagType.Private) > 0) ? 14 : 5; sub2 = new TreeNode(var.ToString(), img, img); sub2.Tag = var.Name; nodes.Add(sub2); } } // expand index = 0; if (showExtend) { index++; } if (showImports) { index++; } for (int i = 0; i < memberGroups; i++) { node.Nodes[index++].Expand(); } node.Expand(); if (!entryExists) { node.EnsureVisible(); } } finally { if (updateToken) { classTree.EndStatefulUpdate(); } } }
public void SetActiveClass(ASClass aClass) { try { classTree.BeginUpdate(); string filename; if (aClass.IsVoid()) { filename = ASContext.MainForm.CurFile; } else { filename = aClass.FileName; } DebugConsole.Trace("UI: set active " + filename); // bool found = false; foreach (TreeNode node in classTree.Nodes) { if ((string)node.Tag == filename) { if (!found) { found = true; classTree.SelectedNode = node; int index = 0; if (showExtend) { index++; } if (showImports) { index++; } for (int i = 0; i < memberGroups; i++) { node.Nodes[index++].Expand(); } node.Expand(); } else { classTree.Nodes.Remove(node); } } else { node.Collapse(); } } // if (classTree.SelectedNode != null) { classTree.SelectedNode.EnsureVisible(); } } catch { classTree.SelectedNode = null; } finally { classTree.EndUpdate(); Win32.Scrolling.scrollToLeft(classTree); } }
/// <summary> /// Retrieves a parsed class from its name /// </summary> /// <param name="cname">Class (short or full) name</param> /// <param name="inClass">Current class</param> /// <returns>A parsed class or an empty ASClass if the class is not found</returns> static public ASClass FindClassFromName(string cname, ASClass inClass) { ASClass aClass; if ((cname == null) || (cname.Length == 0)) cname = defaultMethodReturnType; if (inClass != null) DebugConsole.Trace("Find class "+cname+" in "+inClass.ClassName); else DebugConsole.Trace("Find class "+cname); // unknown if (cname.ToLower() == "void" || classes == null) return new ASClass(); if (inClass != null && !inClass.IsVoid()) { // current class if (inClass.Extends != null && (inClass.ClassName.IndexOf('.') > 0) && (cname == GetLastStringToken(inClass.ClassName, "."))) { cname = inClass.ClassName; } // complete class name else if (cname.IndexOf(".") < 0) { // search in imported classes foreach(ASMember path in inClass.Imports) if (path.Name == cname) { cname = path.Type; break; } } } // retrieve class from cache aClass = (ASClass)classes[cname]; if (aClass != null) return UpdateClass(aClass); // search in intrinsic classes /*if ((topLevel != null) && !topLevel.IsVoid() && (cname.IndexOf(".") < 0)) foreach(ASMember import in topLevel.Imports) { if (import.Name == cname) { DebugConsole.Trace("Use intrinsic class "+cname); if (cname.ToLower() == "void") return new ASClass(); else return FindClassFromFile(topLevel.BasePath+cname+".as"); } }*/ DebugConsole.Trace("In classpath "+cname); // search in classpath aClass = new ASClass(); string file = cname.Replace(".", dirSeparator)+".as"; foreach(string path in classPath) try { DebugConsole.Trace("Try "+path+file); if (System.IO.File.Exists(path+file)) { // case sensitive check string[] check = System.IO.Directory.GetFiles(path, file); if (check.Length == 0) continue; if (check[0].LastIndexOf(file) != check[0].Length-file.Length) continue; // parse file aClass.FileName = check[0]; ASClassParser.ParseClass(aClass); if (!aClass.IsVoid()) { classes[aClass.ClassName] = aClass; break; } } } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+path+file, ex); } // no match return aClass; }
/// <summary> /// Add the class object to a cache /// </summary> /// <param name="aClass">Class object to cache</param> static private bool AddClassToCache(ASClass aClass) { if (!aClass.IsVoid()) { ASClass check = (ASClass)classes[aClass.ClassName]; if (check != null && lastClassWarning != aClass.ClassName) { // if this class was defined in another file, check if it is still open if (String.CompareOrdinal(check.FileName, aClass.FileName) != 0) { ScintillaNet.ScintillaControl sci = MainForm.CurSciControl; WeifenLuo.WinFormsUI.DockContent[] docs = MainForm.GetDocuments(); int found = 0; bool isActive = false; string tabFile; // check if the classes are open foreach(WeifenLuo.WinFormsUI.DockContent doc in docs) { tabFile = (string)MainForm.GetSciControl(doc).Tag; //FileName; if (String.CompareOrdinal(check.FileName, tabFile) == 0 || String.CompareOrdinal(aClass.FileName, tabFile) == 0) { if (MainForm.GetSciControl(doc) == sci) isActive = true; found++; } } // if there are several files declaring the same class if (found > 1 && isActive) { lastClassWarning = aClass.ClassName; Match cdecl = Regex.Match(sci.Text, "[\\s]class[\\s]+(?<cname>"+aClass.ClassName+")[^\\w]"); int line = 1; if (cdecl.Success) { line = 1+sci.LineFromPosition( sci.MBSafeCharPosition(cdecl.Groups["cname"].Index) ); } string msg = String.Format("The class '{2}' is already declared in {3}", aClass.FileName, line, aClass.ClassName, check.FileName); MessageBar.ShowWarning(msg); } else lastClassWarning = null; } } classes[aClass.ClassName] = aClass; return true; } return false; }
/// <summary> /// (Re)Parse and cache a class file /// </summary> /// <param name="aClass">Class object</param> /// <returns>The class object</returns> static public ASClass UpdateClass(ASClass aClass) { if (!aClass.OutOfDate || (classes == null)) return aClass; // remove from cache if (!aClass.IsVoid()) classes.Remove(aClass.ClassName); // (re)parse aClass.OutOfDate = false; ASClassParser.ParseClass(aClass); // add to cache AddClassToCache(aClass); return aClass; }