Example #1
0
		/// <summary>
		/// Complete object member
		/// </summary>
		/// <param name="Sci">Scintilla control</param>
		/// <param name="autoHide">Don't keep the list open if the word does not match</param>
		/// <returns>Auto-completion has been handled</returns>
		static private bool HandleDotCompletion(ScintillaNet.ScintillaControl Sci, bool autoHide)
		{
			// get expression at cursor position
			int position = Sci.CurrentPos;
			ASExpr expr = GetExpression(Sci, position);
			if (expr.Value == null)
				return true;
			int dotIndex = expr.Value.LastIndexOf('.');
			if (dotIndex == 0) return true;
			string tail = (dotIndex >= 0) ? expr.Value.Substring(dotIndex+1) : expr.Value;
			
			DebugConsole.Trace("? "+dotIndex+" '"+expr.separator+"' "+expr.Keyword+" ."+tail);
			// complete keyword
			if (dotIndex < 0)
			{
				if (expr.Keyword == "new") return HandleNewCompletion(Sci, expr.Value, autoHide);
				else if (expr.separator == ':') {
					if (HandleColonCompletion(Sci, expr.Value, autoHide)) return true;
				}
				else if (expr.Keyword == "import")
					return HandleImportCompletion(Sci, expr.Value, autoHide);
				else if ((expr.Keyword == "extends") || (expr.Keyword == "implements"))
					return HandleNewCompletion(Sci, expr.Value, autoHide);
			}
			else if ((expr.ContextBody == null) && (expr.separator != ':') && (expr.separator != '=')
			         && (expr.Keyword != "import") && (expr.Keyword != "extends") && (expr.Keyword != "implements") )
				return true;
			
			// complete declaration
			if ((expr.ContextBody == null) && 
			    ((expr.separator == ';') || (expr.separator == ' ') || (expr.separator == '}') || (expr.separator == '{')))
			{
				if (expr.Value.IndexOf('#') >= 0) return true;
				else 
				{
					string text = " "+ASClassParser.CleanClassSource(Sci.GetText(Sci.CurrentPos), null)+" ";
					if (Regex.IsMatch(text, "[\\s](class|interface)[\\s]"))
					{
						DebugConsole.Trace("Match class");
						Match m = Regex.Match(text, "[\\s](class|interface)[\\s]+"+ASContext.CurrentClass.ClassName+"[\\s{]");
						if (m.Success)
						{
							if (text.Substring(m.Index).IndexOf('{') > 0)
								return HandleDeclarationCompletion(Sci, "function private public static var", tail, autoHide);
							else if ((expr.Keyword != "extends") && (expr.Keyword != "implements"))
								return HandleDeclarationCompletion(Sci, "extends implements", tail, autoHide);
						}
						else return true;
					}
					else if (expr.Keyword == "class") return true;
					else if (dotIndex < 0) return HandleDeclarationCompletion(Sci, "import", tail, autoHide);
				}
			}
			
			DebugConsole.Trace("** Complete expression '"+expr.separator+"' "+expr.Value.Length);
			DebugConsole.Trace(expr.Value);
			
			// Context
			expr.LocalVars = ParseLocalVars(expr);
			ASClass cClass = ASContext.CurrentClass; 
			ASResult result;
			ASClass tmpClass;
			if (dotIndex > 0)
			{
				// Expression before cursor
				result = EvalExpression(expr.Value, expr, cClass, false);
				if (result.IsNull())
					return true;
				tmpClass = result.Class;
			}
			else 
			{
				result = new ASResult();
				tmpClass = cClass;
			}
			ASMemberList mix = new ASMemberList();
			// local vars are the first thing to try
			if ((result.IsNull() || (dotIndex < 0)) && (expr.ContextFunction != null)) 
				mix.Merge(expr.LocalVars);
			
			// packages
			if (tmpClass.Package != null)
				mix.Merge(tmpClass.Package);
			
			// get all members
			FlagType mask = 0;
			if ((expr.ContextFunction != null) || (expr.separator != ':'))
			{
				// user setting may ask to hide some members
				bool limitMembers = ASContext.HideIntrinsicMembers || (autoHide && !ASContext.AlwaysShowIntrinsicMembers);
				// static or dynamic members?
				if (!result.IsNull()) 
					mask = (result.IsStatic) ? FlagType.Static : FlagType.Dynamic;
				// show private member of current class only only 
				if (!FriendClasses(cClass, tmpClass))
					mask |= FlagType.Public;
				DebugConsole.Trace("Filter members by: "+mask);
				
				// explore members
				bool classExtend = false;
				if (!limitMembers || (tmpClass.ClassName != "Object"))
				while ((tmpClass != null) && (!tmpClass.IsVoid()))
				{
					tmpClass.Sort();
					// add members
					mix.Merge(tmpClass.Methods, mask, classExtend);
					// remove constructor methods
					foreach(ASMember meth in tmpClass.Methods)
					if ((meth.Flags & FlagType.Constructor) > 0) {
						mix.Remove(meth);
						break;
					}
					mix.Merge(tmpClass.Properties, mask, classExtend);
					mix.Merge(tmpClass.Vars, mask, classExtend);
					if (result.IsStatic && (tmpClass.Package != null))
					{
						DebugConsole.Trace("Class is package "+tmpClass.ClassName);
						mix.Merge(tmpClass.Package, 0);
					}
					tmpClass = tmpClass.Extends;
					if (tmpClass != null)
					{
						// static members not inherited in AS3 
						classExtend = tmpClass.IsAS3;

						if (((tmpClass.Flags & FlagType.Intrinsic) == FlagType.Intrinsic)
					    	&& (tmpClass.FileName.StartsWith(ASContext.TopLevelClassPath)))
						{
							if (limitMembers)
								tmpClass = null;
						}
					}
				}
			}
			// known classes / toplevel vars/methods
			if (result.IsNull() || (dotIndex < 0))
			{
				mix.Merge(cClass.ToASMember());
				mix.Merge(cClass.Imports);
				mix.Merge(ASContext.TopLevel.Imports);
				mix.Merge(ASContext.TopLevel.Methods);
				mix.Merge(ASContext.TopLevel.Vars);
				mix.Merge(ASContext.GetBasePackages());
			}
			
			// show
			ArrayList list = new ArrayList();
			foreach(ASMember member in mix)
				list.Add(new MemberItem(member));
			CompletionList.Show(list, autoHide, tail);
			return true;
		}