/// <summary> /// Merge one item into the list /// </summary> /// <param name="item">Item to merge</param> public void Merge(ASMember item) { ASMemberList list = new ASMemberList(); list.Add(item); Merge(list, 0); }
/// <summary> /// Parse import statements in source /// </summary> /// <param name="src">Class source</param> /// <param name="aClass">Class object to update</param> static private void ParseImports(string src, ASClass aClass) { aClass.Imports.Clear(); src = src.Replace('\r', '\n'); // fix .NET Regex line-ends detection MatchCollection mcImports = re_import.Matches(src); if (mcImports.Count > 0) { ArrayList known = new ArrayList(); string package; string cname; ASMember newImport; foreach (Match mImport in mcImports) { package = mImport.Groups["package"].Value; //DebugConsole.Trace("IMPORT '"+package+"'"); int p = package.LastIndexOf("."); cname = (p >= 0) ? package.Substring(p + 1) : package; // resolve wildcard if (cname.Length == 0) { context.ResolveWildcards(package, aClass, known); } else if (!known.Contains(package)) { known.Add(package); newImport = new ASMember(); newImport.Name = cname; newImport.Type = package; aClass.Imports.Add(newImport); } } } //else DebugConsole.Trace("NO IMPORTS"); }
public ASMember ToASMember() { ASMember self = new ASMember(); int p = ClassName.LastIndexOf("."); self.Name = (p >= 0) ? ClassName.Substring(p+1) : ClassName; self.Type = ClassName; self.Flags = Flags; return self; }
public ASMember ToASMember() { ASMember self = new ASMember(); int p = ClassName.LastIndexOf("."); self.Name = (p >= 0) ? ClassName.Substring(p + 1) : ClassName; self.Type = ClassName; self.Flags = Flags; return(self); }
public Object Clone() { ASMember copy = new ASMember(); copy.Name = Name; copy.Flags = Flags; copy.Parameters = Parameters; copy.Type = Type; copy.Comments = Comments; return(copy); }
static public string GetTipDetails(ASMember member, string highlightParam) { try { return((UITools.ShowDetails) ? GetTipFullDetails(member, highlightParam) : GetTipShortDetails(member, highlightParam)); } catch (Exception ex) { PluginCore.ErrorHandler.ShowError("Error while parsing comments.\n" + ex.Message, ex); return(""); } }
/// <summary> /// Short contextual details to display in tips /// </summary> /// <param name="member">Member data</param> /// <param name="highlightParam">Parameter to detail</param> /// <returns></returns> static public string GetTipShortDetails(ASMember member, string highlightParam) { if (member == null || member.Comments == null || !ASContext.DocumentationInTips) { return(""); } CommentBlock cb = ParseComment(member.Comments); string details = " …"; // get parameter detail if (highlightParam != null && highlightParam.Length > 0) { if (cb.ParamName != null) { for (int i = 0; i < cb.ParamName.Count; i++) { if (highlightParam == (string)cb.ParamName[i]) { details += "\n[B]" + highlightParam + ":[/B] " + (string)cb.ParamDesc[i]; return(details); } } } } // get description extract if (ASContext.DescriptionInTips) { if (cb.InfoTip != null && cb.InfoTip.Length > 0) { details += "\n" + cb.InfoTip; } else if (cb.Description != null && cb.Description.Length > 0) { string[] lines = cb.Description.Split('\n'); int n = Math.Min(lines.Length, 2); for (int i = 0; i < n; i++) { details += "\n" + lines[i]; } if (lines.Length > 2) { details += " …"; } } } return(details); }
static private string MemberTooltipText(ASMember member, ASClass inClass) { // modifiers FlagType ft = member.Flags; string modifiers = ""; if ((ft & FlagType.Class) == 0) { if ((ft & FlagType.Static) > 0) modifiers += "static "; if ((ft & FlagType.Private) > 0) modifiers += "private "; else if ((ft & FlagType.Public) > 0) modifiers += "public "; } // signature if ((ft & FlagType.Function) > 0) return String.Format("{0}function {1}\nin {2}", modifiers, member.ToString(), inClass.ClassName); else if ((ft & FlagType.Variable) > 0) return String.Format("{0}var {1}\nin {2}", modifiers, member.ToString(), inClass.ClassName); else if ((ft & (FlagType.Getter | FlagType.Setter)) > 0) return String.Format("{0}property {1}\nin {2}", modifiers, member.ToString(), inClass.ClassName); else return String.Format("{0}{1}\nin {2}", modifiers, member.ToString(), inClass.ClassName); }
static public string GetTipDetails(ASMember member, string highlightParam) { try { return (UITools.ShowDetails) ? GetTipFullDetails(member, highlightParam) : GetTipShortDetails(member, highlightParam); } catch(Exception ex) { PluginCore.ErrorHandler.ShowError("Error while parsing comments.\n"+ex.Message, ex); return ""; } }
/// <summary> /// Returns parameters string as member list /// </summary> /// <param name="parameters">Method parameters</param> /// <returns>Member list</returns> static public ASMemberList ParseMethodParameters(string parameters) { ASMemberList list = new ASMemberList(); if (parameters == null) return list; int p = parameters.IndexOf('('); if (p >= 0) parameters = parameters.Substring(p+1, parameters.IndexOf(')')-p-1); parameters = parameters.Trim(); if (parameters.Length == 0) return list; string[] sparam = parameters.Split(','); string[] parType; ASMember param; foreach(string pt in sparam) { parType = pt.Split(':'); param = new ASMember(); param.Name = parType[0].Trim(); if (param.Name.Length == 0) continue; if (parType.Length == 2) param.Type = parType[1].Trim(); else param.Type = "Object"; param.Flags = FlagType.Variable | FlagType.Dynamic; list.Add(param); } return list; }
public void Remove(ASMember value) { Sorted = false; items.Remove(value); }
public void Insert(int index, ASMember value) { Sorted = false; items.Insert(index, value); }
public MemberItem(ASMember oMember) { member = oMember; FlagType type = member.Flags; icon = 0; if ((type & FlagType.Function) > 0) icon = ((type & FlagType.Private) > 0) ? 12 : 3; else if ((type & FlagType.Variable) > 0) icon = ((type & FlagType.Private) > 0) ? 14 : 5; else if ((type & (FlagType.Getter | FlagType.Setter)) > 0) icon = ((type & FlagType.Private) > 0) ? 13 : 4; else if ((type & FlagType.Intrinsic) > 0) icon = 7; else if (type == FlagType.Package) icon = 6; else if ((type & FlagType.Template) > 0) icon = 8; }
/// <summary> /// Resolve wildcards in imports /// </summary> /// <param name="package">Package to explore</param> /// <param name="inClass">Current class</param> /// <param name="known">Packages already added</param> public void ResolveWildcards(string package, ASClass inClass, ArrayList known) { if (!known.Contains(package)) { known.Add(package); ASMember pMember = new ASMember(); pMember.Name = package+"*"; pMember.Type = package+"*"; inClass.Imports.Add(pMember); } }
/// <summary> /// Display method signature /// </summary> /// <param name="Sci">Scintilla control</param> /// <returns>Auto-completion has been handled</returns> static public bool HandleFunctionCompletion(ScintillaNet.ScintillaControl Sci) { // find method int position = Sci.CurrentPos-1; int parCount = 0; int braCount = 0; int comaCount = 0; int arrCount = 0; int style = 0; int stylemask = (1 << Sci.StyleBits) -1; char c; while (position >= 0) { style = Sci.StyleAt(position) & stylemask; if (style == 19) { string keyword = GetWordLeft(Sci, ref position); DebugConsole.Trace("Keyword "+keyword); if (!"new".StartsWith(keyword)) { position = -1; break; } } if (IsTextStyleEx(style)) { c = (char)Sci.CharAt(position); if (c == ';') { position = -1; break; } // skip {} () [] blocks if ( ((braCount > 0) && (c != '{')) || ((arrCount > 0) && (c != '[')) || ((parCount > 0) && (c != '('))) { position--; continue; } // new block if (c == '}') braCount++; else if (c == ']') arrCount++; else if (c == ')') parCount++; // block closed else if (c == '{') { if (braCount == 0) comaCount = 0; else braCount--; } else if (c == '[') { if (arrCount == 0) comaCount = 0; else arrCount--; } else if (c == '(') { if (--parCount < 0) // function start found break; } // new parameter reached else if (c == ',' && parCount == 0 && Sci.BaseStyleAt(position) != 6) comaCount++; } position--; } // continuing calltip ? if (HasCalltip()) { if (calltipPos == position) { ShowCalltip(Sci, comaCount); return true; } else InfoTip.Hide(); } else if (position < 0) return false; // get expression at cursor position ASExpr expr = GetExpression(Sci, position); DebugConsole.Trace("Expr: "+expr.Value); if (expr.Value == null || expr.Value.Length == 0 || expr.separator == ':' || (expr.Keyword == "function" && expr.separator == ' ')) return false; DebugConsole.Trace("** Display method parameters"); DebugConsole.Trace(expr.Value); // Context expr.LocalVars = ParseLocalVars(expr); ASClass aClass = ASContext.CurrentClass; // Expression before cursor ASResult result = EvalExpression(expr.Value, expr, aClass, true); // Show calltip if (!result.IsNull()) { ASMember method = result.Member; if (method == null) { string constructor = ASContext.GetLastStringToken(result.Class.ClassName,"."); method = result.Class.Methods.Search(constructor, FlagType.Constructor); if (method == null) return true; } else if ((method.Flags & FlagType.Function) == 0) return true; // calltip content calltipPos = position; calltipOffset = method.Name.Length; calltipDef = method.Name+"("+method.Parameters+")"; if (method.Type.Length > 0) calltipDef += " : "+method.Type; calltipMember = method; calltipDetails = UITools.ShowDetails; // show prevParam = ""; ShowCalltip(Sci, comaCount); } return true; }
/// <summary> /// Parse import statements in source /// </summary> /// <param name="src">Class source</param> /// <param name="aClass">Class object to update</param> static private void ParseImports(string src, ASClass aClass) { aClass.Imports.Clear(); src = src.Replace('\r', '\n'); // fix .NET Regex line-ends detection MatchCollection mcImports = re_import.Matches(src); if (mcImports.Count > 0) { ArrayList known = new ArrayList(); string package; string cname; ASMember newImport; foreach(Match mImport in mcImports) { package = mImport.Groups["package"].Value; //DebugConsole.Trace("IMPORT '"+package+"'"); int p = package.LastIndexOf("."); cname = (p >= 0) ? package.Substring(p+1) : package; // resolve wildcard if (cname.Length == 0) { context.ResolveWildcards(package, aClass, known); } else if (!known.Contains(package)) { known.Add(package); newImport = new ASMember(); newImport.Name = cname; newImport.Type = package; aClass.Imports.Add(newImport); } } } //else DebugConsole.Trace("NO IMPORTS"); }
/// <summary> /// Prepare Flash intrinsic know vars/methods/classes /// </summary> static private void ResolveTopLevelElements() { // // search top-level class // if (useMtascClasses) { topLevel = FindClassFromName("TopLevel",null); } else { topLevel = new ASClass(); topLevel.FileName = MMClassPath+"toplevel.as"; topLevel.OutOfDate = true; string src; // read file content try { StreamReader sr = new StreamReader(topLevel.FileName); src = sr.ReadToEnd(); sr.Close(); } catch (System.IO.FileNotFoundException) { // ignore files that don't exist (i.e. "Untitled.as") return; } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+topLevel.FileName, ex); return; } // make it look like a valid class src = "class toplevel {"+src+"}"; // parse ASClassParser.ParseClass(topLevel, src); } // not found if (topLevel.IsVoid()) { ErrorHandler.ShowInfo("Top-level elements class not found. Please check your Program Settings."); return; } // // init top-level elements // topLevel.ClassName = "top-level"; topLevel.Extends = new ASClass(); // special vars ASMember special; if (topLevel.Vars.Search("_root",0) == null) { special = new ASMember(); special.Name = "_root"; special.Flags = FlagType.Variable; special.Type = "MovieClip"; topLevel.Vars.Add(special); } if (topLevel.Vars.Search("_global",0) == null) { special = new ASMember(); special.Name = "_global"; special.Flags = FlagType.Variable; special.Type = "Object"; topLevel.Vars.Add(special); } if (topLevel.Vars.Search("this",0) == null) { special = new ASMember(); special.Name = "this"; special.Flags = FlagType.Variable; special.Type = "Object"; topLevel.Vars.Add(special); } if (topLevel.Vars.Search("super",0) == null) { special = new ASMember(); special.Name = "super"; special.Flags = FlagType.Variable; special.Type = "Object"; topLevel.Vars.Add(special); } // pre-sort topLevel.Sort(); // all intrinsic methods/vars foreach(ASMember member in topLevel.Methods) member.Flags |= FlagType.Intrinsic; foreach(ASMember member in topLevel.Vars) member.Flags |= FlagType.Intrinsic; // list instrinsic classes string package; ASMember newImport; foreach(string path in classPath) try { string[] files = System.IO.Directory.GetFiles(path, "*.as"); if (files == null) continue; // add classes found string iname; int plen = path.Length; foreach(string file in files) { package = file.Substring(plen,file.Length-3-plen).Replace(dirSeparator, "."); iname = GetLastStringToken(package, "."); newImport = new ASMember(); newImport.Name = iname; newImport.Type = package; newImport.Flags = FlagType.Intrinsic; if (!iname.Equals("TopLevel") && !iname.Equals("StdPresent") && (iname.IndexOf(' ') < 0) && (topLevel.Imports.Search(iname, 0) == null)) topLevel.Imports.Add(newImport); } } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+path, ex); continue; } // special case newImport = new ASMember(); newImport.Name = newImport.Type = "Void"; newImport.Flags = FlagType.Intrinsic; topLevel.Imports.Add(newImport); topLevel.Imports.Sort(); }
/// <summary> /// Extract member comments for display in the completion list /// </summary> /// <param name="member">Member data</param> /// <param name="member">Parameter to highlight</param> /// <returns>Formated comments</returns> static public string GetTipFullDetails(ASMember member, string highlightParam) { if (member == null || member.Comments == null || !ASContext.DocumentationInTips) { return(""); } CommentBlock cb = ParseComment(member.Comments); // details string details = ""; if (cb.Description.Length > 0) { string[] lines = cb.Description.Split('\n'); int n = Math.Min(lines.Length, ASContext.TipsDescriptionMaxLines); for (int i = 0; i < n; i++) { details += lines[i] + "\n"; } if (lines.Length > ASContext.TipsDescriptionMaxLines) { details = details.TrimEnd() + " …\n"; } } // @usage if (cb.TagName != null) { bool hasUsage = false; for (int i = 0; i < cb.TagName.Count; i++) { if ((string)cb.TagName[i] == "usage") { hasUsage = true; details += "\n " + (string)cb.TagDesc[i]; } } if (hasUsage) { details += "\n"; } } // @param if (cb.ParamName != null && cb.ParamName.Count > 0) { details += "\nParam:"; for (int i = 0; i < cb.ParamName.Count; i++) { details += "\n "; if (highlightParam == (string)cb.ParamName[i]) { details += "[B]" + highlightParam + "[/B]: "; } else { details += cb.ParamName[i] + ": "; } details += (string)cb.ParamDesc[i]; } } // @return if (cb.Return != null) { details += "\n\nReturn:\n " + cb.Return; } return("\n\n" + details.Trim()); }
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(); } } }
/// <summary> /// Resolve wildcards in imports /// </summary> /// <param name="package">Package to explore</param> /// <param name="inClass">Current class</param> /// <param name="known">Packages already added</param> static public void ResolveImports(string package, ASClass inClass, ArrayList known) { string subpath; string path; string[] files; // validation if ((package == null) || (inClass == null)) return; subpath = package.Replace(".", dirSeparator); // search in classpath ASMember newImport; foreach(string basepath in classPath) try { if (System.IO.Directory.Exists(basepath+subpath)) { path = basepath+subpath; DebugConsole.Trace("Search "+path); files = System.IO.Directory.GetFiles(path, "*.as"); if (files == null) continue; // add classes found int plen = basepath.Length; foreach(string file in files) { package = file.Substring(plen,file.Length-3-plen).Replace(dirSeparator,"."); if (known.Contains(package)) continue; known.Add(package); // newImport = new ASMember(); newImport.Name = GetLastStringToken(package, "."); newImport.Type = package; inClass.Imports.Add(newImport); } } } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+basepath+subpath, ex); } }
/// <summary> /// Search all base packages (com, net, org,...) in classpath /// </summary> /// <returns>Base packages list as members</returns> static public ASMemberList GetBasePackages() { ASMemberList packages = new ASMemberList(); ASMember package; string[] dirEntries; string[] fileEntries; string cname; string upPath; string mmCP = MMClassPath.ToUpper(); string mtascCP = mtascRootFolder.ToUpper(); bool notMacromedia; bool notMTASC; foreach(string path in classPath) try { upPath = path.ToUpper(); notMacromedia = (mmCP.Length == 0) || !upPath.StartsWith(mmCP); notMTASC = (mtascCP.Length == 0) || !upPath.StartsWith(mtascCP); // base classes if (notMacromedia && notMTASC) { try { fileEntries = System.IO.Directory.GetFiles(path, "*.as"); } catch { // fail silently fileEntries = null; } if (fileEntries != null) foreach(string entry in fileEntries) { cname = GetLastStringToken(entry, dirSeparator); int p = cname.LastIndexOf('.'); cname = cname.Substring(0,p); if (!cname.StartsWith("_") && (cname.IndexOf('.') < 0) && (cname.IndexOf(' ') < 0) && (packages.Search(cname, 0) == null)) { //DebugConsole.Trace("Base class "+cname); package = new ASMember(); package.Flags = 0; package.Type = package.Name = cname; packages.Add(package); } } } // base packages if (notMacromedia) { try { dirEntries = System.IO.Directory.GetDirectories(path); } catch { // fail silently dirEntries = null; } if (dirEntries != null) foreach(string entry in dirEntries) { cname = GetLastStringToken(entry, dirSeparator); if (!cname.StartsWith("_") && (cname.IndexOf(' ') < 0) && (cname.IndexOf('.') < 0) && (packages.Search(cname, 0) == null)) { //DebugConsole.Trace("Base package "+cname); package = new ASMember(); package.Flags = FlagType.Package; package.Type = package.Name = cname; packages.Add(package); } } } else if (packages.Search("mx", 0) == null) { package = new ASMember(); package.Flags = FlagType.Package; package.Type = package.Name = "mx"; packages.Add(package); } } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+path, ex); } packages.Sort(); return packages; }
/// <summary> /// Find folder and classes in classpath /// </summary> /// <param name="folder">Path to eval</param> /// <returns>Package folders and classes</returns> static public ASMemberList FindPackage(string folder, bool completeContent) { if ((folder == null) || (folder.Length == 0)) return null; ASMemberList package = new ASMemberList(); ASMember pathMember; string[] dirEntries; string cname; foreach(string path in classPath) try { if (System.IO.Directory.Exists(path+folder)) { // continue parsing? if (!completeContent) return package; // add sub packages try { dirEntries = System.IO.Directory.GetDirectories(path+folder); } catch { // fail silently dirEntries = null; } if (dirEntries != null) foreach(string entry in dirEntries) { cname = GetLastStringToken(entry, dirSeparator); if ((cname.Length > 0) && !cname.StartsWith("_") && (cname.IndexOf(' ') < 0) && (cname.IndexOf('.') < 0) && (package.Search(cname, 0) == null)) { pathMember = new ASMember(); pathMember.Flags = FlagType.Package; pathMember.Type = folder.Replace(dirSeparatorChar, '.')+"."+cname; pathMember.Name = cname; package.Add(pathMember); } } // add sub classes try { dirEntries = System.IO.Directory.GetFiles(path+folder); } catch { // fail silently dirEntries = null; } if (dirEntries != null) foreach(string entry in dirEntries) if (entry.EndsWith(".as")) { cname = GetLastStringToken(entry, dirSeparator); cname = cname.Substring(0, cname.LastIndexOf(".")); pathMember = package.Search(cname, 0); if ((pathMember == null) && (cname.Length > 0) && (cname.IndexOf(' ') < 0) && (cname.IndexOf('.') < 0)) { pathMember = new ASMember(); pathMember.Flags = 0; pathMember.Type = folder.Replace(dirSeparatorChar,'.')+"."+cname; pathMember.Name = cname; package.Add(pathMember); } } } } catch(Exception ex) { ErrorHandler.ShowError(ex.Message+"\n"+path+folder, ex); } // result if (package.Count > 0) { package.Sort(); return package; } else return null; }
/// <summary> /// Parse a class from source /// </summary> /// <param name="aClass">Class object</param> /// <param name="src">Class source</param> static public void ParseClass(ASClass aClass, string src) { // remove comments StringCollection comments = new StringCollection(); src = CleanClassSource(src, comments); // check class definition Match mClass = re_class.Match(src); if (!mClass.Success) { aClass.ClassName = null; return; } // classname string prevCName = aClass.ClassName; aClass.ClassName = mClass.Groups["cname"].Value; // HACK AS3 package support string preClassSrc = src.Substring(0,mClass.Groups["ctype"].Index); string AS3package = null; Match mPackage = re_AS3package.Match(preClassSrc); if (mPackage.Success) { aClass.IsAS3 = true; AS3package = mPackage.Groups["name"].Value; if (AS3package != null && AS3package.Length > 0) aClass.ClassName = AS3package+"."+aClass.ClassName; } else aClass.IsAS3 = false; // check classname int p = aClass.ClassName.LastIndexOf("."); string constructor = (p >= 0) ? aClass.ClassName.Substring(p+1) : aClass.ClassName; string classType = mClass.Groups["ctype"].Value; if (src.Substring(0, mClass.Groups["cname"].Index).IndexOf(" comment0 ") >= 0) aClass.Comments = comments[0]; // class base path bool validClassFile = true; int basepos = aClass.FileName.LastIndexOf( aClass.ClassName.Replace('.', Path.DirectorySeparatorChar)+".as" ); if (basepos < 0) { // this class name & file don't match, it can lead to dangerous errors validClassFile = false; // warm about the misspelled class name if (!aClass.FileName.EndsWith("/"+constructor+".as") || !aClass.FileName.ToUpper().EndsWith("\\"+aClass.ClassName.ToUpper().Replace('.','\\')+".AS")) { if (prevCName != aClass.ClassName) { string msg = String.Format("The {0} '{1}' does not match the file name:\n{2}", classType, aClass.ClassName, aClass.FileName); context.DisplayError(msg); } } aClass.BasePath = System.IO.Path.GetDirectoryName(aClass.FileName)+"\\"; } else { aClass.BasePath = aClass.FileName.Substring(0, basepos); } // add to classpath context.SetTemporaryBasePath(aClass.FileName, aClass.BasePath); // class flag aClass.Flags = FlagType.Class; if (classType == "interface") aClass.Flags |= FlagType.Interface; if (mClass.Groups["keys"].Value.IndexOf("intrinsic") >= 0) aClass.Flags |= FlagType.Intrinsic; if (mClass.Groups["keys"].Value.IndexOf("dynamic") >= 0) aClass.Flags |= FlagType.Dynamic; // import statements ParseImports(preClassSrc, aClass); preClassSrc = null; // inheritance string herit = mClass.Groups["herit"].Value; Match mExtends = re_extends.Match(herit); string extends = (validClassFile && mExtends.Success) ? mExtends.Groups["cname"].ToString() : "Object"; if ((extends != aClass.ClassName) && (aClass.ClassName != "TopLevel")) { aClass.Extends = null; // resolve extended class ASClass extendsClass = context.GetClassByName(extends, aClass); // detect infinite extension loop ASClass tmpClass = extendsClass; while (tmpClass != null) { if (tmpClass == aClass) { string msg = String.Format("The {0} '{1}' extends itself.", classType, aClass.ClassName); context.DisplayError(msg); extendsClass = null; break; } tmpClass = tmpClass.Extends; } if (extendsClass != null) aClass.Extends = extendsClass; else aClass.Extends = new ASClass(); } Match mImplements = re_implements.Match(herit); if (mImplements.Success) { string implements; if (!mExtends.Success || mImplements.Index > mExtends.Index) implements = herit.Substring(mImplements.Index+mImplements.Length).Trim(); else implements = herit.Substring(mImplements.Index+mImplements.Length, mExtends.Index-mImplements.Index-mImplements.Length).Trim(); aClass.Implements = re_parametersSeparator.Replace(implements, ", "); } else aClass.Implements = null; // clean class body src = "; "+src.Substring(mClass.Groups["herit"].Index + mClass.Groups["herit"].Value.Length+1); src = re_balancedBraces.Replace(src, ";"); // if updating, clear aClass.Methods.Clear(); aClass.Properties.Clear(); aClass.Vars.Clear(); // parse functions string keys; bool isStatic; MatchCollection mcFunc = re_functions.Matches(src); Match mFunc; Match mType; Match mComments; ASMember member; foreach(Match m in mcFunc) { mFunc = re_splitFunction.Match(m.Value); if (!mFunc.Success) continue; // keywords keys = mFunc.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Function; if (keys.IndexOf("private") >= 0) member.Flags |= FlagType.Private; else member.Flags |= FlagType.Public; isStatic = (keys.IndexOf("static") >= 0); if (isStatic) member.Flags |= FlagType.Static; else member.Flags |= FlagType.Dynamic; // comments if (comments.Count > 0) { mComments = re_commentIndex.Match(keys); if (mComments.Success) { member.Comments = comments[ Convert.ToInt16(mComments.Groups["index"].Value) ]; } } // method member.Name = mFunc.Groups["fname"].Value.Trim(); if (member.Name.Length == 0) continue; // parameters member.Parameters = re_colonParams.Replace( re_parametersSeparator.Replace(mFunc.Groups["params"].Value.Trim(), ", "), ":"); // return type mType = re_variableType.Match(mFunc.Groups["type"].Value); if (mType.Success) member.Type = mType.Groups["type"].Value; else member.Type = ""; // constructor type if (member.Name == constructor) { member.Flags |= FlagType.Constructor; member.Type = constructor; } // getter/setter if ((member.Name.Length > 4) && ((int)member.Name[3] < 33)) { Match mProp = re_isGetterSetter.Match(member.Name); if (mProp.Success) { string pname = mProp.Groups["pname"].Value; ASMember prop = aClass.Properties.Search(pname, 0); if (prop == null) { prop = member; prop.Name = pname; prop.Flags -= FlagType.Function; aClass.Properties.Add(prop); } if (mProp.Groups["type"].Value == "g") { prop.Flags |= FlagType.Getter; prop.Type = member.Type; if (!mType.Success) prop.Type = "Object"; } else { prop.Flags |= FlagType.Setter; prop.Parameters = member.Parameters; } if ((member.Comments != null) && ((prop.Comments == null) || (prop.Comments.Length < member.Comments.Length))) prop.Comments = member.Comments; } // store method else aClass.Methods.Add(member); } // store method else aClass.Methods.Add(member); } // parse variables MatchCollection mcVars = re_variable.Matches(src); Match mVar; foreach(Match m in mcVars) { mVar = re_splitVariable.Match(m.Value); if (!mVar.Success) continue; // parse method definition keys = mVar.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Variable; // keywords if (keys.IndexOf("private") >= 0) member.Flags |= FlagType.Private; else member.Flags |= FlagType.Public; isStatic = (keys.IndexOf("static") >= 0); if (isStatic) member.Flags |= FlagType.Static; else member.Flags |= FlagType.Dynamic; // comments mComments = re_commentIndex.Match(keys); if (mComments.Success) member.Comments = comments[ Convert.ToInt16(mComments.Groups["index"].Value) ]; // name member.Name = mVar.Groups["pname"].Value; // type mType = re_variableType.Match(mVar.Groups["type"].Value); if (mType.Success) member.Type = mType.Groups["type"].Value; else member.Type = "Object"; // store aClass.Vars.Add(member); } // HACK AS3 'const' declarations if (AS3package != null) { mcVars = re_constant.Matches(src); foreach(Match m in mcVars) { mVar = re_splitConstant.Match(m.Value); if (!mVar.Success) continue; // parse method definition keys = mVar.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Variable; // keywords if (keys.IndexOf("private") >= 0) member.Flags |= FlagType.Private; else member.Flags |= FlagType.Public; isStatic = (keys.IndexOf("static") >= 0); if (isStatic) member.Flags |= FlagType.Static; else member.Flags |= FlagType.Dynamic; // comments mComments = re_commentIndex.Match(keys); if (mComments.Success) member.Comments = comments[ Convert.ToInt16(mComments.Groups["index"].Value) ]; // name member.Name = mVar.Groups["pname"].Value; // type mType = re_variableType.Match(mVar.Groups["type"].Value); if (mType.Success) member.Type = mType.Groups["type"].Value; else member.Type = "Object"; // store aClass.Vars.Add(member); } } // is also a package? //DebugConsole.Trace("check folder "+aClass.FileName.Substring(0, aClass.FileName.Length-3)); if (System.IO.Directory.Exists(aClass.FileName.Substring(0, aClass.FileName.Length-3))) { string package = aClass.FileName.Substring(aClass.BasePath.Length); package = package.Substring(0, package.IndexOf('.')); ASMemberList pList = context.GetSubClasses(package); if ((pList != null) && (pList.Count > 0)) { //DebugConsole.Trace("Sub classes/packages "+package+" "+pList.Count); aClass.Flags |= FlagType.Package; aClass.Package = pList; // if intrinsic class, inherit flag if ((aClass.Flags & FlagType.Intrinsic) == FlagType.Intrinsic) foreach(ASMember import in pList) import.Flags |= FlagType.Intrinsic; } } // done }
/// <summary> /// Short contextual details to display in tips /// </summary> /// <param name="member">Member data</param> /// <param name="highlightParam">Parameter to detail</param> /// <returns></returns> static public string GetTipShortDetails(ASMember member, string highlightParam) { if (member == null || member.Comments == null || !ASContext.DocumentationInTips) return ""; CommentBlock cb = ParseComment(member.Comments); string details = " …"; // get parameter detail if (highlightParam != null && highlightParam.Length > 0) { if (cb.ParamName != null) for(int i=0; i<cb.ParamName.Count; i++) { if (highlightParam == (string)cb.ParamName[i]) { details += "\n[B]"+highlightParam+":[/B] "+(string)cb.ParamDesc[i]; return details; } } } // get description extract if (ASContext.DescriptionInTips) { if (cb.InfoTip != null && cb.InfoTip.Length > 0) details += "\n"+cb.InfoTip; else if (cb.Description != null && cb.Description.Length > 0) { string[] lines = cb.Description.Split('\n'); int n = Math.Min(lines.Length, 2); for(int i=0; i<n; i++) details += "\n"+lines[i]; if (lines.Length > 2) details += " …"; } } return details; }
/// <summary> /// Parse a class from source /// </summary> /// <param name="aClass">Class object</param> /// <param name="src">Class source</param> static public void ParseClass(ASClass aClass, string src) { // remove comments StringCollection comments = new StringCollection(); src = CleanClassSource(src, comments); // check class definition Match mClass = re_class.Match(src); if (!mClass.Success) { aClass.ClassName = null; return; } // classname string prevCName = aClass.ClassName; aClass.ClassName = mClass.Groups["cname"].Value; // HACK AS3 package support string preClassSrc = src.Substring(0, mClass.Groups["ctype"].Index); string AS3package = null; Match mPackage = re_AS3package.Match(preClassSrc); if (mPackage.Success) { aClass.IsAS3 = true; AS3package = mPackage.Groups["name"].Value; if (AS3package != null && AS3package.Length > 0) { aClass.ClassName = AS3package + "." + aClass.ClassName; } } else { aClass.IsAS3 = false; } // check classname int p = aClass.ClassName.LastIndexOf("."); string constructor = (p >= 0) ? aClass.ClassName.Substring(p + 1) : aClass.ClassName; string classType = mClass.Groups["ctype"].Value; if (src.Substring(0, mClass.Groups["cname"].Index).IndexOf(" comment0 ") >= 0) { aClass.Comments = comments[0]; } // class base path bool validClassFile = true; int basepos = aClass.FileName.LastIndexOf(aClass.ClassName.Replace('.', Path.DirectorySeparatorChar) + ".as"); if (basepos < 0) { // this class name & file don't match, it can lead to dangerous errors validClassFile = false; // warm about the misspelled class name if (!aClass.FileName.EndsWith("/" + constructor + ".as") || !aClass.FileName.ToUpper().EndsWith("\\" + aClass.ClassName.ToUpper().Replace('.', '\\') + ".AS")) { if (prevCName != aClass.ClassName) { string msg = String.Format("The {0} '{1}' does not match the file name:\n{2}", classType, aClass.ClassName, aClass.FileName); context.DisplayError(msg); } } aClass.BasePath = System.IO.Path.GetDirectoryName(aClass.FileName) + "\\"; } else { aClass.BasePath = aClass.FileName.Substring(0, basepos); } // add to classpath context.SetTemporaryBasePath(aClass.FileName, aClass.BasePath); // class flag aClass.Flags = FlagType.Class; if (classType == "interface") { aClass.Flags |= FlagType.Interface; } if (mClass.Groups["keys"].Value.IndexOf("intrinsic") >= 0) { aClass.Flags |= FlagType.Intrinsic; } if (mClass.Groups["keys"].Value.IndexOf("dynamic") >= 0) { aClass.Flags |= FlagType.Dynamic; } // import statements ParseImports(preClassSrc, aClass); preClassSrc = null; // inheritance string herit = mClass.Groups["herit"].Value; Match mExtends = re_extends.Match(herit); string extends = (validClassFile && mExtends.Success) ? mExtends.Groups["cname"].ToString() : "Object"; if ((extends != aClass.ClassName) && (aClass.ClassName != "TopLevel")) { aClass.Extends = null; // resolve extended class ASClass extendsClass = context.GetClassByName(extends, aClass); // detect infinite extension loop ASClass tmpClass = extendsClass; while (tmpClass != null) { if (tmpClass == aClass) { string msg = String.Format("The {0} '{1}' extends itself.", classType, aClass.ClassName); context.DisplayError(msg); extendsClass = null; break; } tmpClass = tmpClass.Extends; } if (extendsClass != null) { aClass.Extends = extendsClass; } else { aClass.Extends = new ASClass(); } } Match mImplements = re_implements.Match(herit); if (mImplements.Success) { string implements; if (!mExtends.Success || mImplements.Index > mExtends.Index) { implements = herit.Substring(mImplements.Index + mImplements.Length).Trim(); } else { implements = herit.Substring(mImplements.Index + mImplements.Length, mExtends.Index - mImplements.Index - mImplements.Length).Trim(); } aClass.Implements = re_parametersSeparator.Replace(implements, ", "); } else { aClass.Implements = null; } // clean class body src = "; " + src.Substring(mClass.Groups["herit"].Index + mClass.Groups["herit"].Value.Length + 1); src = re_balancedBraces.Replace(src, ";"); // if updating, clear aClass.Methods.Clear(); aClass.Properties.Clear(); aClass.Vars.Clear(); // parse functions string keys; bool isStatic; MatchCollection mcFunc = re_functions.Matches(src); Match mFunc; Match mType; Match mComments; ASMember member; foreach (Match m in mcFunc) { mFunc = re_splitFunction.Match(m.Value); if (!mFunc.Success) { continue; } // keywords keys = mFunc.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Function; if (keys.IndexOf("private") >= 0) { member.Flags |= FlagType.Private; } else { member.Flags |= FlagType.Public; } isStatic = (keys.IndexOf("static") >= 0); if (isStatic) { member.Flags |= FlagType.Static; } else { member.Flags |= FlagType.Dynamic; } // comments if (comments.Count > 0) { mComments = re_commentIndex.Match(keys); if (mComments.Success) { member.Comments = comments[Convert.ToInt16(mComments.Groups["index"].Value)]; } } // method member.Name = mFunc.Groups["fname"].Value.Trim(); if (member.Name.Length == 0) { continue; } // parameters member.Parameters = re_colonParams.Replace(re_parametersSeparator.Replace(mFunc.Groups["params"].Value.Trim(), ", "), ":"); // return type mType = re_variableType.Match(mFunc.Groups["type"].Value); if (mType.Success) { member.Type = mType.Groups["type"].Value; } else { member.Type = ""; } // constructor type if (member.Name == constructor) { member.Flags |= FlagType.Constructor; member.Type = constructor; } // getter/setter if ((member.Name.Length > 4) && ((int)member.Name[3] < 33)) { Match mProp = re_isGetterSetter.Match(member.Name); if (mProp.Success) { string pname = mProp.Groups["pname"].Value; ASMember prop = aClass.Properties.Search(pname, 0); if (prop == null) { prop = member; prop.Name = pname; prop.Flags -= FlagType.Function; aClass.Properties.Add(prop); } if (mProp.Groups["type"].Value == "g") { prop.Flags |= FlagType.Getter; prop.Type = member.Type; if (!mType.Success) { prop.Type = "Object"; } } else { prop.Flags |= FlagType.Setter; prop.Parameters = member.Parameters; } if ((member.Comments != null) && ((prop.Comments == null) || (prop.Comments.Length < member.Comments.Length))) { prop.Comments = member.Comments; } } // store method else { aClass.Methods.Add(member); } } // store method else { aClass.Methods.Add(member); } } // parse variables MatchCollection mcVars = re_variable.Matches(src); Match mVar; foreach (Match m in mcVars) { mVar = re_splitVariable.Match(m.Value); if (!mVar.Success) { continue; } // parse method definition keys = mVar.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Variable; // keywords if (keys.IndexOf("private") >= 0) { member.Flags |= FlagType.Private; } else { member.Flags |= FlagType.Public; } isStatic = (keys.IndexOf("static") >= 0); if (isStatic) { member.Flags |= FlagType.Static; } else { member.Flags |= FlagType.Dynamic; } // comments mComments = re_commentIndex.Match(keys); if (mComments.Success) { member.Comments = comments[Convert.ToInt16(mComments.Groups["index"].Value)]; } // name member.Name = mVar.Groups["pname"].Value; // type mType = re_variableType.Match(mVar.Groups["type"].Value); if (mType.Success) { member.Type = mType.Groups["type"].Value; } else { member.Type = "Object"; } // store aClass.Vars.Add(member); } // HACK AS3 'const' declarations if (AS3package != null) { mcVars = re_constant.Matches(src); foreach (Match m in mcVars) { mVar = re_splitConstant.Match(m.Value); if (!mVar.Success) { continue; } // parse method definition keys = mVar.Groups["keys"].Value; member = new ASMember(); member.Flags = FlagType.Variable; // keywords if (keys.IndexOf("private") >= 0) { member.Flags |= FlagType.Private; } else { member.Flags |= FlagType.Public; } isStatic = (keys.IndexOf("static") >= 0); if (isStatic) { member.Flags |= FlagType.Static; } else { member.Flags |= FlagType.Dynamic; } // comments mComments = re_commentIndex.Match(keys); if (mComments.Success) { member.Comments = comments[Convert.ToInt16(mComments.Groups["index"].Value)]; } // name member.Name = mVar.Groups["pname"].Value; // type mType = re_variableType.Match(mVar.Groups["type"].Value); if (mType.Success) { member.Type = mType.Groups["type"].Value; } else { member.Type = "Object"; } // store aClass.Vars.Add(member); } } // is also a package? //DebugConsole.Trace("check folder "+aClass.FileName.Substring(0, aClass.FileName.Length-3)); if (System.IO.Directory.Exists(aClass.FileName.Substring(0, aClass.FileName.Length - 3))) { string package = aClass.FileName.Substring(aClass.BasePath.Length); package = package.Substring(0, package.IndexOf('.')); ASMemberList pList = context.GetSubClasses(package); if ((pList != null) && (pList.Count > 0)) { //DebugConsole.Trace("Sub classes/packages "+package+" "+pList.Count); aClass.Flags |= FlagType.Package; aClass.Package = pList; // if intrinsic class, inherit flag if ((aClass.Flags & FlagType.Intrinsic) == FlagType.Intrinsic) { foreach (ASMember import in pList) { import.Flags |= FlagType.Intrinsic; } } } } // done }
/// <summary> /// Extract member comments for display in the completion list /// </summary> /// <param name="member">Member data</param> /// <param name="member">Parameter to highlight</param> /// <returns>Formated comments</returns> static public string GetTipFullDetails(ASMember member, string highlightParam) { if (member == null || member.Comments == null || !ASContext.DocumentationInTips) return ""; CommentBlock cb = ParseComment(member.Comments); // details string details = ""; if (cb.Description.Length > 0) { string[] lines = cb.Description.Split('\n'); int n = Math.Min(lines.Length, ASContext.TipsDescriptionMaxLines); for(int i=0; i<n; i++) details += lines[i]+"\n"; if (lines.Length > ASContext.TipsDescriptionMaxLines) details = details.TrimEnd()+" …\n"; } // @usage if (cb.TagName != null) { bool hasUsage = false; for(int i=0; i<cb.TagName.Count; i++) if ((string)cb.TagName[i] == "usage") { hasUsage = true; details += "\n "+(string)cb.TagDesc[i]; } if (hasUsage) details += "\n"; } // @param if (cb.ParamName != null && cb.ParamName.Count > 0) { details += "\nParam:"; for(int i=0; i<cb.ParamName.Count; i++) { details += "\n "; if (highlightParam == (string)cb.ParamName[i]) details += "[B]"+highlightParam+"[/B]: "; else details += cb.ParamName[i]+": "; details += (string)cb.ParamDesc[i]; } } // @return if (cb.Return != null) { details += "\n\nReturn:\n "+cb.Return; } return "\n\n"+details.Trim(); }
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 static string MemberDeclaration(ASMember member) { // modifiers FlagType ft = member.Flags; string modifiers = ""; if ((ft & FlagType.Class) > 0) { if ((ft & FlagType.Intrinsic) > 0) modifiers += "intrinsic "; if ((ft & FlagType.Dynamic) > 0) modifiers += "dynamic "; // TODO (or not?) ASClasses: parse classes in completion list to eval if there are interfaces or classes? string classType = ((member.Flags & FlagType.Interface) > 0) ? "interface" : "class"; return String.Format("{0}{1} {2}", modifiers, classType, member.Type); } else { if ((ft & FlagType.Static) > 0) modifiers += "static "; if ((ft & FlagType.Private) > 0) modifiers += "private "; else if ((ft & FlagType.Public) > 0) modifiers += "public "; } // signature if ((ft & FlagType.Function) > 0) return String.Format("{0}function {1}", modifiers, member.ToString()); else if ((ft & FlagType.Variable) > 0) { if (modifiers.Length == 0) modifiers = "local "; return String.Format("{0}var {1}", modifiers, member.ToString()); } else if ((ft & (FlagType.Getter | FlagType.Setter)) > 0) return String.Format("{0}property {1}", modifiers, member.ToString()); else if ((ft & FlagType.Template) > 0) return String.Format("Template {0}", member.Type); else if (ft == FlagType.Package) return String.Format("Package {0}", member.Type); else { if ((ft & FlagType.Intrinsic) > 0) modifiers = "intrinsic "+modifiers; return String.Format("{0}type {1}", modifiers, member.Type); } }
static public string MemberDeclaration(ASMember member) { // modifiers FlagType ft = member.Flags; string modifiers = ""; if ((ft & FlagType.Class) > 0) { if ((ft & FlagType.Intrinsic) > 0) { modifiers += "intrinsic "; } if ((ft & FlagType.Dynamic) > 0) { modifiers += "dynamic "; } // TODO (or not?) ASClasses: parse classes in completion list to eval if there are interfaces or classes? string classType = ((member.Flags & FlagType.Interface) > 0) ? "interface" : "class"; return(String.Format("{0}{1} {2}", modifiers, classType, member.Type)); } else { if ((ft & FlagType.Static) > 0) { modifiers += "static "; } if ((ft & FlagType.Private) > 0) { modifiers += "private "; } else if ((ft & FlagType.Public) > 0) { modifiers += "public "; } } // signature if ((ft & FlagType.Function) > 0) { return(String.Format("{0}function {1}", modifiers, member.ToString())); } else if ((ft & FlagType.Variable) > 0) { if (modifiers.Length == 0) { modifiers = "local "; } return(String.Format("{0}var {1}", modifiers, member.ToString())); } else if ((ft & (FlagType.Getter | FlagType.Setter)) > 0) { return(String.Format("{0}property {1}", modifiers, member.ToString())); } else if ((ft & FlagType.Template) > 0) { return(String.Format("Template {0}", member.Type)); } else if (ft == FlagType.Package) { return(String.Format("Package {0}", member.Type)); } else { if ((ft & FlagType.Intrinsic) > 0) { modifiers = "intrinsic " + modifiers; } return(String.Format("{0}type {1}", modifiers, member.Type)); } }
public Object Clone() { ASMember copy = new ASMember(); copy.Name = Name; copy.Flags = Flags; copy.Parameters = Parameters; copy.Type = Type; copy.Comments = Comments; return copy; }
public int Add(ASMember value) { Sorted = false; return(items.Add(value)); }
public int Add(ASMember value) { Sorted = false; return items.Add(value); }
/// <summary> /// Parse function body for local var definitions /// TODO ASComplete: parse coma separated local vars definitions /// </summary> /// <param name="expression">Expression source</param> /// <returns>Local vars dictionnary (name, type)</returns> static public ASMemberList ParseLocalVars(ASExpr expression) { ASMemberList vars = new ASMemberList(); if ((expression.ContextBody == null) || (expression.ContextBody.Length == 0)) return vars; // parse MatchCollection mcVars = re_variable.Matches(";"+expression.ContextBody); Match mVar; Match mType; string type; ASMember var; foreach(Match m in mcVars) { mVar = re_splitVariable.Match(m.Value); if (!mVar.Success) continue; mType = re_variableType.Match(mVar.Groups["type"].Value); if (mType.Success) type = mType.Groups["type"].Value; else type = "Object"; var = new ASMember(); var.Flags = FlagType.Variable | FlagType.Dynamic; var.Name = mVar.Groups["pname"].Value; var.Type = type; vars.Add(var); } // method parameters vars.Merge( ParseMethodParameters(expression.ContextFunction) ); return vars; }