Exemplo n.º 1
0
        /*
         * Get the immediate child namespaces for a 'using' declaration
         */

        protected List <LookupListItem> GetChildNamespaceList(
            LookupTarget target, string text)
        {
            string[] split = text.Split(';');
            text = split[split.Length - 1];

            // Is it a using declaration...
            Regex           re1 = new Regex(@"using\s+");
            MatchCollection mc  = re1.Matches(text);

            if (mc.Count == 0)
            {
                return(null);
            }

            // ...but not a using statement.
            Regex re2 = new Regex(@"using\s*\(");
            Match m   = re2.Match(text);

            if (m.Success)
            {
                return(null);
            }

            // Get the namespaces
            return(GetImmediateChildNamespaces(target.Entity));
        }
Exemplo n.º 2
0
        /*
         * Use the namespace list to create each possible fully
         * qualified name for the target and test each one by
         * seeing if the type really exists. We have to do this
         * because C# allows unqualified type names which are
         * inferred from the 'using' declarations in the source.
         */

        protected void GetFullyQualifiedTarget(
            LookupTarget target, List <string> namespaceList)
        {
            foreach (string ns in namespaceList)
            {
                string fullEntity = ns;
                if (ns != String.Empty)
                {
                    fullEntity += ".";
                }
                fullEntity += target.Entity;

                string[] split = fullEntity.Split('.');

                string type = String.Empty;

                for (int i = 0; i < split.Length; i++)
                {
                    if (i > 0)
                    {
                        type += ".";
                    }
                    type += split[i];

                    /*
                     * Try a lookahead for nested types. This is a hack
                     * and only works for one level (i.e. just one '+').
                     */

                    if (i < split.Length - 1)
                    {
                        string nestedName = type + "+" + split[i + 1];

                        target.Type = SearchAssemblyList(nestedName);

                        if (target.Type != null)
                        {
                            target.FullEntity = fullEntity;
                            return;
                        }
                    }

                    /*
                     * Get back to looking for 'normal' types.
                     */

                    target.Type = SearchAssemblyList(type);

                    if (target.Type != null)
                    {
                        target.FullEntity = fullEntity;
                        return;
                    }
                }
            }
        }
Exemplo n.º 3
0
        public LookupContext(string fullSource, string preSource,
                             string line, int lineStartPos, int currentPos, bool insideClass)
        {
            _fullSource   = fullSource;
            _preSource    = preSource;
            _line         = line;
            _lineStartPos = lineStartPos;
            _currentPos   = currentPos;
            _beforeClass  = insideClass;

            /*
             * Cleanup the source code.
             */

            _preSource = CSharpFormattingTools.RemoveUnwantedText(_preSource);
            _preSource = CSharpFormattingTools.RemoveUnwantedBracketText(_preSource);
            _line      = CSharpFormattingTools.RemoveUnwantedText(_line);
            _line      = CSharpFormattingTools.RemoveUnwantedBracketText(_line);

            /*
             * Get rid of 'global::' - we don't do anything with them
             * so we might as well not have them.
             */

            _line = _line.Replace("global::", String.Empty);

            /*
             * We remove the content of any balanced brackets to
             * allow indexed variables to identified and classified.
             */

            _line = CSharpFormattingTools.RemoveUnwantedParentheses(Line);

            /*
             * Create the target.
             */

            _target = new LookupTarget(_line);

            /*
             * Find the visible methods and properties.
             */

            _localMethods    = new LocalMethods(_fullSource);
            _localProperties = new LocalProperties(_fullSource);
        }
 protected override List <LookupListItem> GetChildNamespaces(
     LookupTarget target, string text)
 {
     return(GetChildNamespaceList(target, text));
 }
Exemplo n.º 5
0
        protected List <LookupListItem> GetVisibleTypes(
            LookupContext context,
            bool includeLocals,
            bool includeNamespaces,
            bool includeVariables)
        {
            /*
             * Get the names of the base types of the current class.
             * This includes and ancestor class and any interfaces
             * implemented by the class.
             */

            List <String> baseTypes = GetBaseTypes(context.PreSource);

            List <String> namespaceList = GetNamespaceList(context.PreSource);

            namespaceList.Insert(0, String.Empty);

            /*
             * We want to find the members inherited from the base
             * class not the interfaces. If there is no base type
             * System.Object is assumed.
             */

            List <LookupListItem> list = new List <LookupListItem>();

            foreach (string baseType in baseTypes)
            {
                LookupTarget target =
                    new LookupTarget(baseType, String.Empty);

                List <LookupListItem> typeList = GetTypeMembers(
                    context, target, context.DeclarationContext,
                    namespaceList, true, true);

                if (typeList != null && !target.Type.IsInterface)
                {
                    list.AddRange(typeList);
                }
            }

            if (list.Count == 0)
            {
                LookupTarget target =
                    new LookupTarget("System.Object", String.Empty);

                List <LookupListItem> typeList = GetTypeMembers(
                    context, target, context.DeclarationContext,
                    namespaceList, true, true);

                if (typeList != null)
                {
                    list.AddRange(typeList);
                }
            }

            if (includeNamespaces)
            {
                /*
                 * Add all members of declared namespaces.
                 */

                List <LookupListItem> itemList =
                    FindNamespaceTypeLookupItems(namespaceList);

                if (itemList != null)
                {
                    list.AddRange(itemList);
                }
            }

            /*
             * Add declared (local) variables.
             */

            if (includeVariables)
            {
                list.AddRange(context.DeclaredVariables.
                              GetList(context.LineStartPos));
            }

            /*
             * Add local methods and properties.
             */

            if (includeLocals)
            {
                list.AddRange(context.Methods.GetList(
                                  context.DeclarationContext));

                list.AddRange(context.Properties.GetList(
                                  context.DeclarationContext));
            }

            return(list);
        }
 protected abstract List <LookupListItem> GetChildNamespaces(
     LookupTarget target, string text);
        protected List <LookupListItem> GetTypeMembers(
            LookupContext context, LookupTarget target,
            DeclarationContext declarationContext,
            List <String> namespaceList,
            bool allowNonPublic, bool isInherited)
        {
            #region Part 1: Find the type

            /*
             * To avoid multiple calls to GetNamespaceList in any
             * single lookup we can preload this list or create it here.
             */

            if (namespaceList == null)
            {
                namespaceList = GetNamespaceList(context.PreSource);
                namespaceList.Insert(0, String.Empty);
            }

            /*
             * First we need to fully qualify the target type if it's
             * not already fully qualified. We assume it isn't and
             * test each possible namespace prefix until we find a
             * valid type. We add a blank namespace to the list to allow
             * for types that are already fully qualified.
             */

            GetFullyQualifiedTarget(target, namespaceList);
            if (target.Type == null)
            {
                return(null);
            }

            if (target.Type.FullName == "System.Void")
            {
                return(new List <LookupListItem>());
            }

            /*
             * We now need to separate the type from its sub-members
             * and work down the chain getting the type of
             * each sub-member until we either get a void return type or
             * reach the end of the list. The last type we get that's
             * not void is the type we want.
             */

            string members = target.FullEntity.Substring(
                target.Type.FullName.Length).TrimStart('.');

            Type type = target.Type;

            List <Type> allTypes = null;

            if (members != String.Empty)
            {
                string[] split = members.Split('.');

                if (split.Length == 0)
                {
                    return(null);
                }

                foreach (string member in split)
                {
                    MemberInfo[] mi = type.GetMember(member);

                    if (mi.Length == 0)
                    {
                        /*
                         * Member not found; could be an
                         * extension method...
                         */

                        allTypes = FindNamespaceTypes(namespaceList);

                        bool foundMember = false;

                        foreach (Type t in allTypes)
                        {
                            if (!TypeHasExtensionMethods(t))
                            {
                                continue;
                            }

                            MethodInfo[] mia = t.GetMethods();

                            if (ExtensionMethodFoundInTypeMembers(
                                    mia, member))
                            {
                                mi          = mia;
                                foundMember = true;
                            }
                        }

                        if (!foundMember)
                        {
                            return(null);
                        }
                    }

                    /*
                     * We are past the first level members which can
                     * belong to a static or instance item; from here
                     * all sub-members will be in instance contexts.
                     */

                    declarationContext = DeclarationContext.Instance;

                    string typeName = GetMemberTypeName(mi[0]);

                    if (typeName == null)
                    {
                        return(null);
                    }
                    if (typeName == "System.Void")
                    {
                        return(null);
                    }

                    type = SearchAssemblyList(typeName);

                    /*
                     * If not found try a nested type.
                     */

                    if (type == null)
                    {
                        typeName = target.Type.FullName + "+" + typeName;
                        type     = SearchAssemblyList(typeName);
                    }

                    /*
                     * Exit if no return type found.
                     */

                    if (type == null)
                    {
                        return(null);
                    }
                }
            }

            #endregion

            #region Part 2: Get the type members

            /*
             * Now we can get the members of the type we've found.
             */

            Dictionary <String, LookupListItem> foundItems =
                new Dictionary <String, LookupListItem>();

            BindingFlags bindingAttr =
                BindingFlags.Public | BindingFlags.FlattenHierarchy;

            /*
             * Use static or instance lookup?
             */

            if (declarationContext == DeclarationContext.Static || type.IsEnum)
            {
                bindingAttr |= BindingFlags.Static;
            }
            else
            {
                bindingAttr |= BindingFlags.Instance;
                if (isInherited)
                {
                    bindingAttr |= BindingFlags.Static;
                }
            }

            /*
             * Include non-public?
             */

            if (allowNonPublic)
            {
                bindingAttr |= BindingFlags.NonPublic;
            }

            MemberInfo[] items = type.GetMembers(bindingAttr);

            foreach (MemberInfo item in items)
            {
                if (item.MemberType == MemberTypes.Property)
                {
                    AddProperty(foundItems, item);
                }
                else if (item.MemberType == MemberTypes.Method)
                {
                    /*
                     * Hide methods for Enums.
                     */

                    if (type.IsEnum)
                    {
                        continue;
                    }

                    AddMethod(foundItems, item);
                }
                else if (item.MemberType == MemberTypes.Field)
                {
                    AddField(foundItems, item);
                }
                else if (item.MemberType == MemberTypes.Event)
                {
                    AddEvent(foundItems, item,
                             target.Name, context.LineStartPos);
                }
            }

            #endregion

            #region Part 3: Find any extension methods for the type

            if (allTypes == null)
            {
                allTypes = FindNamespaceTypes(namespaceList);
            }

            foreach (Type t in allTypes)
            {
                if (!TypeHasExtensionMethods(t))
                {
                    continue;
                }

                MethodInfo[] mia = t.GetMethods();

                foreach (MethodInfo mi in mia)
                {
                    if (!mi.IsStatic)
                    {
                        continue;
                    }

                    if (mi.GetCustomAttributes(
                            typeof(ExtensionAttribute), false).Length > 0)
                    {
                        ParameterInfo[] pia = mi.GetParameters();
                        if (pia.Length == 0)
                        {
                            break;
                        }

                        /*
                         * Is the extension applicable to the current type?
                         * We're assuming that the extension type is the
                         * type of the 0-index parameter.
                         */

                        /*
                         * This doesn't appear to be 100% accurate
                         * but it's OK for simple (i.e. non-generic)
                         * extensions. (Might have something to do with
                         * the above assumption?)
                         */

                        if (pia[0].ParameterType.IsAssignableFrom(type))
                        {
                            AddExtensionMethod(foundItems, mi);
                        }
                    }
                }
            }

            #endregion

            #region Part 4: Update overload information

            List <LookupListItem> lookupList =
                foundItems.Values.ToList <LookupListItem>();

            foreach (LookupListItem li in lookupList)
            {
                /*
                 * Update the tooltips to include overload count
                 * or remove overload marker.
                 */

                string overloads = String.Empty;

                if (li.MenuItems.Count > 1)
                {
                    overloads = String.Format(" (+{0} {1})",
                                              li.MenuItems.Count - 1,
                                              li.MenuItems.Count > 2 ? "overloads" : "overload");
                }

                li.ToolTipText =
                    li.ToolTipText.Replace("_OVR_", overloads);
            }

            #endregion

            return(lookupList);
        }