Exemple #1
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));
            }
        }
Exemple #2
0
        /// <summary>
        /// This handles the "this" keyword, the "base" keyword (C# only), and the "super" keyword (Java only).
        /// It searches for the appropriate type definition depending on the context of the usage.
        /// </summary>
        /// <param name="use">The use to find the containing type for</param>
        /// <returns>The type(s) referred to by the keyword</returns>
        public static IEnumerable <TypeDefinition> GetTypeForKeyword(NameUse use)
        {
            if (use == null)
            {
                throw new ArgumentNullException("use");
            }
            if (use.ParentStatement == null)
            {
                throw new ArgumentException("ParentStatement is null", "use");
            }

            if (use.Name == "this")
            {
                //return the surrounding type definition
                return(use.ParentStatement.GetAncestorsAndSelf <TypeDefinition>().Take(1));
            }
            if ((use.Name == "base" && use.ProgrammingLanguage == Language.CSharp) ||
                (use.Name == "super" && use.ProgrammingLanguage == Language.Java))
            {
                //return all the parent classes of the surrounding type definition
                var enclosingType = use.ParentStatement.GetAncestorsAndSelf <TypeDefinition>().FirstOrDefault();
                if (enclosingType == null)
                {
                    return(Enumerable.Empty <TypeDefinition>());
                }
                else
                {
                    return(enclosingType.GetParentTypes(true));
                }
            }

            return(Enumerable.Empty <TypeDefinition>());
        }
Exemple #3
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));
            }
        }
Exemple #4
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);
            }
        }
 /// <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.
 /// The order of children within a NamedScope does not matter, so the location of the use is not taken into account.
 /// </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");
     }
     return(GetNamedChildren <T>(use.Name, searchDeclarations));
 }
        /// <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 (ChildStatements.Count > 0)
            {
                var firstTryLoc      = ChildStatements.First().PrimaryLocation;
                var lastTryLoc       = ChildStatements.Last().PrimaryLocation;
                var tryBlockLocation = new SourceLocation(firstTryLoc.SourceFileName, firstTryLoc.StartingLineNumber, firstTryLoc.StartingColumnNumber, lastTryLoc.EndingLineNumber, lastTryLoc.EndingColumnNumber);
                if (this.PrimaryLocation.Contains(use.Location) && !tryBlockLocation.Contains(use.Location))
                {
                    //the use is within the overall TryStatement, but not in the try block. Don't return results from the try block
                    return(matches.SkipWhile(m => tryBlockLocation.Contains(m.GetLocations().First())));
                }
            }
            return(matches);
        }
Exemple #7
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);
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="nu"></param>
 private void UpdateReturnInfoByNU(NameUse nu)
 {
     VariableDeclaration vdNameUse = FindFieldVarDecl(nu);
     if(vdNameUse != null) {
         GetSelfFields.Add(vdNameUse);
     } else {
         //update if assignedVar is a local variable
         var lVarInfo = FindLocalVarInfo(nu);
         if(lVarInfo != null) {
             foreach(var vd in lVarInfo.AssignedFields) {
                 PropertyFields.Add(vd);
             }
             lVarInfo.IsReturned = true;
             ReturnedVariable = lVarInfo;  //bnie-add
         }
         //update if assignedVar is a paramether
         var pVarInfo = FindParaVarInfo(nu);
         if(pVarInfo != null) {
             foreach(var vd in pVarInfo.AssignedFields) {
                 PropertyFields.Add(vd);
             }
             pVarInfo.IsReturned = true;
             ReturnedVariable = lVarInfo;  //bnie-add
         }
     }
 }
 /// <summary>
 /// Find and return parameters' VariableInfo by the given NameUse        
 /// </summary>
 /// <param name="vb"></param>
 /// <returns></returns>
 private VariableInfo FindParaVarInfo(NameUse vb)
 {
     if(vb == null) {
         return null;
     }
     var decl = vb.FindMatches().FirstOrDefault() as VariableDeclaration;
     if(decl != null) {
         foreach(var varInfo in ParametersInfo) {
             if(varInfo.Variable.Equals(decl)) {
                 return varInfo;
             }
         }
     }
     return null;
 }
 /// <summary>
 /// Find field varible declaration for the given variable (return null if it's a local variable)
 /// </summary>
 /// <param name="vb"></param>
 /// <returns></returns>
 private VariableDeclaration FindFieldVarDecl(NameUse vb)
 {
     if(vb == null) {
         return null;
     }
     var decl = vb.FindMatches().FirstOrDefault() as VariableDeclaration;
     if(decl != null) {
         //if did not find in the current list, but method is matching
         MethodDefinition md = decl.ParentStatement.GetAncestorsAndSelf<MethodDefinition>().FirstOrDefault();
         if(md == null || !Method.Equals(md)) {
             return decl;
         }
     }
     return null;
 }
Exemple #11
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>
        public IEnumerable <T> GetNamedChildren <T>(NameUse use) where T : INamedEntity
        {
            bool searchDeclarations = typeof(T).IsInterface || typeof(T).IsSubclassOf(typeof(Expression));

            return(GetNamedChildren <T>(use, searchDeclarations));
        }
Exemple #12
0
 /// <summary>
 /// Returns the children of this statement that have the same name as the given <paramref name="use"/>.
 /// 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>
 /// <param name="use">The use containing the name to search for.</param>
 public IEnumerable <INamedEntity> GetNamedChildren(NameUse use)
 {
     return(GetNamedChildren <INamedEntity>(use, true));
 }