예제 #1
0
        /// <summary>
        /// Returns the children of this statement that have the same name as the given <paramref name="use"/>, and the given type.
        /// This method searches only the immediate children, and not further descendants.
        /// If the <paramref name="use"/> occurs within this statement, this method will return only the children
        /// that occur prior to that use.
        /// </summary>
        /// <typeparam name="T">The type of children to return.</typeparam>
        /// <param name="use">The use containing the name to search for.</param>
        /// <param name="searchDeclarations">Whether to search the child DeclarationStatements for named entities.</param>
        public virtual IEnumerable <T> GetNamedChildren <T>(NameUse use, bool searchDeclarations) where T : INamedEntity
        {
            if (use == null)
            {
                throw new ArgumentNullException("use");
            }
            //location comparison is only valid if the use occurs within this statement (or its children)
            bool filterLocation = PrimaryLocation.Contains(use.Location);

            if (filterLocation)
            {
                var scopes = GetChildren().OfType <T>().Where(ns => string.Equals(ns.Name, use.Name, StringComparison.Ordinal) &&
                                                              PositionComparer.CompareLocation(PrimaryLocation, use.Location) < 0);
                if (!searchDeclarations)
                {
                    return(scopes);
                }

                //this will return the var decls in document order
                var decls = from declStmt in GetChildren().OfType <DeclarationStatement>()
                            where PositionComparer.CompareLocation(declStmt.PrimaryLocation, use.Location) < 0
                            from decl in declStmt.GetDeclarations().OfType <T>()
                            where string.Equals(decl.Name, use.Name, StringComparison.Ordinal)
                            select decl;
                return(scopes.Concat(decls));
            }
            else
            {
                return(GetNamedChildren <T>(use.Name, searchDeclarations));
            }
        }
예제 #2
0
        /// <summary>
        /// Returns the children of this MethodDefinition that have the same name as the given <paramref name="use"/>, and the given type.
        /// This method searches only the immediate children, and not further descendants.
        /// If the <paramref name="use"/> occurs within this MethodDefinition, only the children that occur prior to that use will be returned.
        /// </summary>
        /// <typeparam name="T">The type of children to return.</typeparam>
        /// <param name="use">The use containing the name to search for.</param>
        /// <param name="searchDeclarations">Whether to search the child DeclarationStatements for named entities.</param>
        public override IEnumerable <T> GetNamedChildren <T>(NameUse use, bool searchDeclarations)
        {
            //location comparison is only valid if the use occurs within this method (or its children)
            var filterLocation = PrimaryLocation.Contains(use.Location);

            if (filterLocation)
            {
                var scopes = GetChildren().OfType <T>().Where(ns => ns.Name == use.Name && PositionComparer.CompareLocation(PrimaryLocation, use.Location) < 0);
                if (!searchDeclarations)
                {
                    return(scopes);
                }

                //this will return the var decls in document order
                var decls = from declStmt in GetChildren().OfType <DeclarationStatement>()
                            where PositionComparer.CompareLocation(declStmt.PrimaryLocation, use.Location) < 0
                            from decl in declStmt.GetDeclarations().OfType <T>()
                            where decl.Name == use.Name
                            select decl;
                return(scopes.Concat(decls));
            }
            else
            {
                return(GetNamedChildren <T>(use.Name, searchDeclarations));
            }
        }
예제 #3
0
        /// <summary>
        /// Returns the children of this namespace that have the same name as the given <paramref name="use"/>, and the given type.
        /// This method searches only the immediate children, and not further descendants.
        /// If this is a global namespace, and the lanugage is C or C++, then only children that occur in the same file as, and prior to, the use will be returned.
        /// If there are no such children, then all matching children will be returned.
        /// </summary>
        /// <typeparam name="T">The type of children to return.</typeparam>
        /// <param name="use">The use containing the name to search for.</param>
        /// <param name="searchDeclarations">Whether to search the child DeclarationStatements for named entities.</param>
        public override IEnumerable <T> GetNamedChildren <T>(NameUse use, bool searchDeclarations)
        {
            if (use == null)
            {
                throw new ArgumentNullException("use");
            }
            var matches = base.GetNamedChildren <T>(use, searchDeclarations);

            if (IsGlobal && (ProgrammingLanguage == Language.C || ProgrammingLanguage == Language.CPlusPlus))
            {
                Func <INamedEntity, bool> occursBeforeUse = delegate(INamedEntity match) {
                    var matchLocs = match.GetLocations().ToList();
                    if (matchLocs.Count == 1 &&
                        string.Compare(matchLocs[0].SourceFileName, use.Location.SourceFileName, StringComparison.OrdinalIgnoreCase) == 0 &&
                        PositionComparer.CompareLocation(matchLocs[0], use.Location) >= 0)
                    {
                        //match occurs exclusively after the use, so don't include
                        return(false);
                    }
                    return(true);
                };
                return(matches.Where(m => occursBeforeUse(m)));
            }
            else
            {
                return(matches);
            }
        }
예제 #4
0
        /// <summary>
        /// Returns the children of this statement that have the same name as the given <paramref name="use"/>, and the given type.
        /// This method searches only the immediate children, and not further descendants.
        /// If the <paramref name="use"/> occurs within this statement, this method will return only the children
        /// that occur prior to that use.
        /// </summary>
        /// <typeparam name="T">The type of children to return.</typeparam>
        /// <param name="use">The use containing the name to search for.</param>
        /// <param name="searchDeclarations">Whether to search the child DeclarationStatements for named entities.</param>
        public override IEnumerable <T> GetNamedChildren <T>(NameUse use, bool searchDeclarations)
        {
            var matches = base.GetNamedChildren <T>(use, searchDeclarations);

            //check if we should filter the results
            if (ElseStatements.Count > 0)
            {
                var firstElseLoc = ElseStatements.First().PrimaryLocation;
                var lastElseLoc  = ElseStatements.Last().PrimaryLocation;
                var elseLocation = new SourceLocation(firstElseLoc.SourceFileName, firstElseLoc.StartingLineNumber, firstElseLoc.StartingColumnNumber, lastElseLoc.EndingLineNumber, lastElseLoc.EndingColumnNumber);
                if (string.Compare(elseLocation.SourceFileName, use.Location.SourceFileName, StringComparison.OrdinalIgnoreCase) == 0 &&
                    elseLocation.Contains(use.Location))
                {
                    //the use is in the else-block, don't return results from the then-block
                    return(matches.SkipWhile(m => PositionComparer.CompareLocation(m.GetLocations().First(), elseLocation) < 0));
                }
            }
            return(matches);
        }