Пример #1
0
        /// <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);
        }
Пример #2
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");
        }
Пример #3
0
		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;
		}
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #8
0
		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);
		}
Пример #9
0
		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 "";
			}
		}
Пример #10
0
		/// <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;
		}
Пример #11
0
 public void Remove(ASMember value)
 {
     Sorted = false;
     items.Remove(value);
 }
Пример #12
0
 public void Insert(int index, ASMember value)
 {
     Sorted = false;
     items.Insert(index, value);
 }
Пример #13
0
			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;
			}
Пример #14
0
		/// <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);
			}
		}
Пример #15
0
		/// <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;
		}
Пример #16
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");
		}
Пример #17
0
		/// <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());
        }
Пример #19
0
        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();
                }
            }
        }
Пример #20
0
		/// <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);
			}
		}
Пример #21
0
		/// <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;
		}
Пример #22
0
		/// <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;
		}
Пример #23
0
		/// <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
		}
Пример #24
0
		/// <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;
		}
Пример #25
0
        /// <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
        }
Пример #26
0
		/// <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();
		}
Пример #27
0
		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();
			}
		}
Пример #28
0
 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);
     }
 }
Пример #29
0
        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));
            }
        }
Пример #30
0
 public Object Clone()
 {
     ASMember copy = new ASMember();
     copy.Name = Name;
     copy.Flags = Flags;
     copy.Parameters = Parameters;
     copy.Type = Type;
     copy.Comments = Comments;
     return copy;
 }
Пример #31
0
 public int Add(ASMember value)
 {
     Sorted = false;
     return(items.Add(value));
 }
Пример #32
0
 public int Add(ASMember value)
 {
     Sorted = false;
     return items.Add(value);
 }
Пример #33
0
 public void Remove(ASMember value)
 {
     Sorted = false;
     items.Remove(value);
 }
Пример #34
0
 public void Insert(int index, ASMember value)
 {
     Sorted = false;
     items.Insert(index, value);
 }
Пример #35
0
 /// <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);
 }
Пример #36
0
		/// <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;
		}