/// <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)); } }
/// <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)); } }
/// <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); } }
/// <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); }