public LocalMethods(string source) { _methods = new List <MethodDefinition>(); /* * Get all the method declarations in the source. */ Regex methodRegex = new Regex(@"(public\s+|private\s+|protected\s+|internal\s+)(internal\s+)?(abstract\s+|virtual\s+|override\s+|static\s+)?(.+)\s+([\w\d_]+)\s*\(([\d\.\w\s,<>\[\]_]*)\)\s+{"); foreach (Match m in methodRegex.Matches(source)) { MethodDefinition method = new MethodDefinition(); method.Name = m.Groups[5].Value.Trim(); method.ReturnType = m.Groups[4].Value.Trim(); method.Parameters = m.Groups[6].Value.Trim(); method.Visibility = m.Groups[1].Value.Trim(); method.IsProtectedInternal = (m.Groups[2].Value.Trim() == "internal"); method.IsStatic = (m.Groups[3].Value.Trim() == "static"); method.StartPos = m.Index; method.ReturnType = CSharpFormattingTools.ToCTSType(method.ReturnType); /* * The parameter types should ideally be formatted to * show the CLR type names to make them consistent with * the display of other types but we'll leave that for * now and make do with the formatted typed by the user. */ _methods.Add(method); } /* * Now find the constructors. */ Regex constructorRegex = new Regex(@"(public\s+|private\s+|protected\s+|internal\s+|static\s+)(internal\s+)?([\w\d_]+)\s*\(([\d\.\w\s,<>\[\]_]*)\)\s+({|:)"); foreach (Match m in constructorRegex.Matches(source)) { MethodDefinition method = new MethodDefinition(); method.Name = m.Groups[3].Value.Trim(); method.ReturnType = null; method.Parameters = m.Groups[4].Value.Trim(); method.Visibility = m.Groups[1].Value.Trim(); method.IsProtectedInternal = (m.Groups[2].Value.Trim() == "internal"); method.IsStatic = (m.Groups[1].Value.Trim() == "static"); method.StartPos = m.Index; _methods.Add(method); } /* * Now we have the methods and their start positions we need * to find their end positions to mark out the method 'zones'. */ foreach (MethodDefinition method in _methods) { method.EndPos = FindMethodEnd(method.StartPos, source); } }
protected LookupList GetCSharpLookupList(LookupContext context) { List <LookupListItem> lookupItemList = null; /****************************************************************** * CodeAssist lookups start here. The type of lookup performed * depends on the context of the search target and the result * of each lookup so order is important. At each stage we ask * "what are we looking for?" and "what are we expecting to find?" ******************************************************************/ /* * Are we looking for namespaces as part of a 'using' declaration? * We have typed 'using' and now expect to see a list of available * namespaces (as determined by the assemblies available in the * assembly search list). If nothing else has been typed, the root * namespaces will be shown; if a partial namespace has been entered * (i.e. the name includes one or more '.') the appropriate child * namespaces are shown. */ lookupItemList = GetChildNamespaces( context.Target, context.Line); if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } /* * If before the class definition give up looking. */ if (!context.BeforeClass) { return(null); } /* * Are we looking for members of a namespace? * We have typed a name including at least one '.' and expect to * see the relevant members of this entity. This could be a * namespace, class or variable. First we check to see if we get * anything back by assuming it's a namespace. */ if (context.Target.Entity != String.Empty) { List <LookupListItem> types = FindNamespaceTypeLookupItems(context.Target.Entity); List <LookupListItem> namespaces = FindNamespaceChildLookupItems(context.Target.Entity); if (types != null || namespaces != null) { lookupItemList = new List <LookupListItem>(); if (types != null) { lookupItemList.AddRange(types); } if (namespaces != null) { lookupItemList.AddRange(namespaces); } } } if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } /* * Get the local variables declared within the scope visible from * the lookup location (the caret) and any variables inherited * from the base class. */ /* * Are we in a static or instance method? * Set the context accordingly. */ GetDeclarationContext(context); context.DeclaredVariables = GetDeclaredVariables( context.PreSource, true, context.DeclarationContext); context.InheritedVariables = GetInheritedVariables( context.PreSource, context.DeclarationContext, workspaceAssemblyList, fullNamespaceList, rootNamespaceList); /* * Are we looking for anything in scope? * We have typed a name without a '.' so it could be a local * variable, a class visible within any of the imported namespaces * or any root namespace in the referenced assemblies. */ if (String.IsNullOrEmpty(context.Target.Entity)) { lookupItemList = GetVisibleTypes(context, true, true, true); if (lookupItemList != null) { // Add the root namespaces foreach (string ns in rootNamespaceList) { LookupListItem item = new LookupListItem(); item.DisplayText = ns; item.InsertText = ns; item.Category = QuickSharp.CodeAssist.Constants.NAMESPACE; item.ToolTipText = String.Format("namespace {0}", ns); lookupItemList.Add(item); } return(new LookupList( context.Target.LookAhead, lookupItemList)); } } /* * The target cannot be blank after this point; if we haven't * found anything using a blank target then there's nothing * to find. */ if (String.IsNullOrEmpty(context.Target.Entity)) { return(null); } /****************************************************************** * From this point on we must have at least one '.' in the target * so we're looking for members of various entities not the * entities themselves. These could be the current class or its * base; variables (instance member lookup) or classes (static * member lookup). ******************************************************************/ /* * Convert C# type names to .NET type names. */ context.Target.Entity = CSharpFormattingTools.ToCTSType(context.Target.Entity); /* * Are we looking for members of the current class? * This is inaccurate in that it doesn't include the members of * the current type (as we're not parsing the code) only the * inherited members and local variables. It's basically the * same as 'base' with variables added. */ if (context.Target.Entity == "this") { lookupItemList = GetVisibleTypes( context, true, false, true); if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } } /* * Are we looking for members of the base class? */ if (context.Target.Entity == "base") { lookupItemList = GetVisibleTypes( context, false, false, false); if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } } /* * If the target is a sub-member of 'this' or 'base' we can * treat this as though the 'this' or 'base' aren't there. */ if (context.Target.Entity.StartsWith("this.") || context.Target.Entity.StartsWith("base.")) { context.Target.Entity = context.Target.Entity.Substring(5); } /* * Are we looking for members of a variable? * We will have the variable name followed by one or more * sub-members (e.g. sr.ReadLine().ToString().GetType()...). * We need to convert the variable to it's type * (e.g. StreamReader) and perform instance lookups * down the member chain getting the return type of * each so we can get its members, find the type of the next * and so on. The last type found is the type we need to * show in the lookup list. */ Variable variable = context.DeclaredVariables. GetVariable(context.Target.Entity); if (variable == null) { variable = context.Properties. GetProperty(context.Target.Entity); } if (variable == null) { variable = context.InheritedVariables. GetVariable(context.Target.Entity); } if (variable != null) { context.Target.Name = variable.Name; String[] split = context.Target.Entity.Split('.'); /* * An added complication is if the variable is a collection * type such as an array or List<T>. If we have item operators * (e.g. list[]) we need to convert the variable type to * the type being collected not the collection itself. So if * we have a List<String>, List. presents members of the * List class but List[]. presents members of the String class. */ if (context.Target.IsIndexed) { context.Target.Entity = variable.GetVariableCollectionType( context.Target.Entity); } else { split[0] = variable.Type; context.Target.Entity = String.Join(".", split); } lookupItemList = GetTypeMembers( context, context.Target, DeclarationContext.Instance, null, false, false); if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } } /* * Are we looking for members of a local * method's return type? */ string[] methodSplit = context.Target.Name.Split('.'); LocalMethods.MethodDefinition method = context.Methods.GetMethod(methodSplit[0]); if (method != null) { int i = context.Target.Entity.IndexOf('.'); if (i == -1) { context.Target.Entity = method.ReturnType; } else { context.Target.Entity = method.ReturnType + context.Target.Entity.Substring(i); } lookupItemList = GetTypeMembers( context, context.Target, DeclarationContext.Instance, null, false, false); if (lookupItemList != null) { return(new LookupList( context.Target.LookAhead, lookupItemList)); } } /* * Are we looking for members of a class? * We expect to see a list of static members of the class. This is * almost the same as the previous instance lookup except that we * already know the type of the entity and our first level member * lookup will be for static members. */ lookupItemList = GetTypeMembers( context, context.Target, DeclarationContext.Static, null, false, false); return(new LookupList( context.Target.LookAhead, lookupItemList)); /* * If the final lookup finds nothing we will return null. */ }