Ejemplo n.º 1
0
        /// <summary>
        /// Finds all of the matching type definitions for all of the variable declarations that
        /// match this variable use
        /// </summary>
        /// <returns>An enumerable of matching type definitions</returns>
        public override IEnumerable <TypeDefinition> ResolveType()
        {
            IEnumerable <TypeDefinition> typeDefinitions;

            if (this.Name == "this" ||
                (this.Name == "base" && this.ProgrammingLanguage == Language.CSharp) ||
                (this.Name == "super" && this.ProgrammingLanguage == Language.Java))
            {
                typeDefinitions = TypeDefinition.GetTypeForKeyword(this);
            }
            else
            {
                typeDefinitions = from declaration in FindMatches().OfType <VariableDeclaration>()
                                  where declaration.VariableType != null
                                  from definition in declaration.VariableType.ResolveType()
                                  select definition;
            }

            //TODO: figure out what the type should be when we have an indexer
            //if(Index != null) {

            //}

            return(typeDefinitions);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Finds matching <see cref="IMethodDefinition">method definitions</see> from the
        /// <see cref="IScope.GetParentScopes()"/> of this usage. Because method calls can also be
        /// to constructors and destructors, this will also search for matching types and then
        /// constructors within those types
        /// </summary>
        /// <returns>An enumerable of method definitions that match this method call</returns>
        public override IEnumerable <IMethodDefinition> FindMatches()
        {
            IEnumerable <IMethodDefinition> matchingMethods = Enumerable.Empty <IMethodDefinition>();

            if (IsConstructor || IsDestructor)
            {
                IEnumerable <ITypeDefinition> typeDefinitions;
                if (this.Name == "this" || (this.Name == "base" && this.ProgrammingLanguage == Language.CSharp))
                {
                    typeDefinitions = TypeDefinition.GetTypeForKeyword(this);
                }
                else
                {
                    ITypeUse tempTypeUse = new TypeUse()
                    {
                        Name        = this.Name,
                        ParentScope = this.ParentScope,
                    };
                    tempTypeUse.AddAliases(this.Aliases);
                    typeDefinitions = tempTypeUse.FindMatches();
                }

                matchingMethods = from typeDefinition in typeDefinitions
                                  from method in typeDefinition.GetChildScopesWithId <IMethodDefinition>(typeDefinition.Name)
                                  where Matches(method)
                                  select method;
            }
            else if (CallingObject != null)
            {
                matchingMethods = from matchingType in CallingObject.FindMatchingTypes()
                                  from typeDefinition in matchingType.GetParentTypesAndSelf()
                                  from method in typeDefinition.GetChildScopesWithId <IMethodDefinition>(this.Name)
                                  where Matches(method)
                                  select method;
            }
            else
            {
                var matches             = base.FindMatches();
                var matchingTypeMethods = from containingType in ParentScope.GetParentScopesAndSelf <ITypeDefinition>()
                                          from typeDefinition in containingType.GetParentTypes()
                                          from method in typeDefinition.GetChildScopesWithId <IMethodDefinition>(this.Name)
                                          where Matches(method)
                                          select method;
                matchingMethods = matches.Concat(matchingTypeMethods);
            }
            foreach (var method in matchingMethods)
            {
                yield return(method);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds all of the matching type definitions for all of the variable declarations that
        /// match this variable use
        /// </summary>
        /// <returns>An enumerable of matching type definitions</returns>
        public IEnumerable <ITypeDefinition> FindMatchingTypes()
        {
            IEnumerable <ITypeDefinition> typeDefinitions;

            if (this.Name == "this" || (this.Name == "base" && this.ProgrammingLanguage == Language.CSharp))
            {
                typeDefinitions = TypeDefinition.GetTypeForKeyword(this);
            }
            else
            {
                var matchingVariables = FindMatches();
                if (matchingVariables.Any())
                {
                    typeDefinitions = from declaration in matchingVariables
                                      where declaration.VariableType != null
                                      from definition in declaration.VariableType.FindMatches()
                                      select definition;
                }
                else
                {
                    var tempTypeUse = new TypeUse()
                    {
                        Name                = this.Name,
                        ParentScope         = this.ParentScope,
                        ProgrammingLanguage = this.ProgrammingLanguage,
                    };
                    if (CallingObject != null && CallingObject is IVariableUse)
                    {
                        var caller = CallingObject as IVariableUse;
                        Stack <INamedScopeUse> callerStack = new Stack <INamedScopeUse>();
                        while (caller != null)
                        {
                            var scopeUse = new NamedScopeUse()
                            {
                                Name = caller.Name,
                                ProgrammingLanguage = this.ProgrammingLanguage,
                            };
                            callerStack.Push(scopeUse);
                            caller = caller.CallingObject as IVariableUse;
                        }

                        INamedScopeUse prefix = null, last = null;

                        foreach (var current in callerStack)
                        {
                            if (null == prefix)
                            {
                                prefix = current;
                                last   = prefix;
                            }
                            else
                            {
                                last.ChildScopeUse = current;
                                last = current;
                            }
                        }
                        prefix.ParentScope = this.ParentScope;
                        tempTypeUse.Prefix = prefix;
                    }
                    tempTypeUse.AddAliases(this.Aliases);
                    typeDefinitions = tempTypeUse.FindMatchingTypes();
                }
            }
            return(typeDefinitions);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds matching <see cref="MethodDefinition">method definitions</see> for this method call.
        /// This method searches for matches in the ancestor scopes of the call. Because method calls can also be
        /// to constructors and destructors, this will also search for matching types and then
        /// constructors within those types
        /// </summary>
        /// <returns>An enumerable of method definitions that match this method call</returns>
        public override IEnumerable <INamedEntity> FindMatches()
        {
            if (ParentStatement == null)
            {
                throw new InvalidOperationException("ParentStatement is null");
            }

            if (IsConstructor || IsDestructor)
            {
                List <TypeDefinition> typeDefinitions;
                if (this.Name == "this" ||
                    (this.Name == "base" && this.ProgrammingLanguage == Language.CSharp) ||
                    (this.Name == "super" && this.ProgrammingLanguage == Language.Java))
                {
                    typeDefinitions = TypeDefinition.GetTypeForKeyword(this).ToList();
                }
                else
                {
                    var tempTypeUse = new TypeUse()
                    {
                        Name            = this.Name,
                        ParentStatement = this.ParentStatement,
                        Location        = this.Location
                    };
                    typeDefinitions = tempTypeUse.ResolveType().ToList();
                }

                //Handle case of C++ constructor initialization lists.
                //These will be marked as constructor calls. They can be used to initialize fields, though, in which case the call name will be the field name,
                //rather than a type name.
                if (!typeDefinitions.Any() && IsConstructorInitializer && ProgrammingLanguage == Language.CPlusPlus)
                {
                    var containingType = ParentStatement.GetAncestorsAndSelf <TypeDefinition>().FirstOrDefault();
                    if (containingType != null)
                    {
                        //search this type and its parents for a field matching the name of the call
                        var matchingField = containingType.GetParentTypesAndSelf(true).SelectMany(t => t.GetNamedChildren <VariableDeclaration>(this.Name)).FirstOrDefault();
                        if (matchingField != null)
                        {
                            typeDefinitions = matchingField.VariableType.ResolveType().ToList();
                        }
                    }
                }

                var matchingMethods = from typeDefinition in typeDefinitions
                                      from method in typeDefinition.GetNamedChildren <MethodDefinition>(typeDefinition.Name)
                                      where SignatureMatches(typeDefinition.Name, method)
                                      select method;
                return(matchingMethods);
            }

            //If there's a calling expression, resolve and search under the results
            var callingScopes = GetCallingScope();

            if (callingScopes != null)
            {
                IEnumerable <INamedEntity> matches = Enumerable.Empty <INamedEntity>();
                foreach (var scope in callingScopes)
                {
                    var localMatches = scope.GetNamedChildren <MethodDefinition>(this.Name).Where(SignatureMatches).ToList();
                    var callingType  = scope as TypeDefinition;
                    if (!localMatches.Any() && callingType != null)
                    {
                        //also search under the base types of the calling scope
                        matches = matches.Concat(callingType.SearchParentTypes <MethodDefinition>(this.Name, SignatureMatches));
                    }
                    else
                    {
                        matches = matches.Concat(localMatches);
                    }
                }
                return(matches);
            }

            //search enclosing scopes and base types for the method
            foreach (var scope in ParentStatement.GetAncestors())
            {
                var matches = scope.GetNamedChildren <MethodDefinition>(this).Where(SignatureMatches).ToList();
                if (matches.Any())
                {
                    return(matches);
                }
                var typeDef = scope as TypeDefinition;
                if (typeDef != null)
                {
                    //search the base types
                    var baseTypeMatches = typeDef.SearchParentTypes <MethodDefinition>(this.Name, SignatureMatches).ToList();
                    if (baseTypeMatches.Any())
                    {
                        return(baseTypeMatches);
                    }
                }
            }

            //we didn't find it locally, search under imported namespaces
            return(from import in GetImports()
                   from match in import.ImportedNamespace.GetDescendantsAndSelf <NameUse>().Last().FindMatches().OfType <NamedScope>()
                   from child in match.GetNamedChildren <MethodDefinition>(this.Name)
                   where SignatureMatches(child)
                   select child);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Finds definitions that match this name.
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable <INamedEntity> FindMatches()
        {
            if (ParentStatement == null)
            {
                throw new InvalidOperationException("ParentStatement is null");
            }

            //handle keywords
            if (Name == "this" ||
                (Name == "base" && ProgrammingLanguage == Language.CSharp) ||
                (Name == "super" && ProgrammingLanguage == Language.Java))
            {
                return(TypeDefinition.GetTypeForKeyword(this));
            }

            //We don't want to match a NameUse to a MethodDefinition, so exclude them in all the queries

            //If there's a prefix, resolve that and search under results
            if (Prefix != null)
            {
                return(Prefix.FindMatches().SelectMany(ns => ns.GetNamedChildren <INamedEntity>(this.Name)).Where(e => !(e is MethodDefinition)));
            }

            //If there's a calling expression, match and search under results
            var callingScopes = GetCallingScope();

            if (callingScopes != null)
            {
                IEnumerable <INamedEntity> matches = Enumerable.Empty <INamedEntity>();
                foreach (var scope in callingScopes)
                {
                    var localMatches = scope.GetNamedChildren(this.Name).Where(e => !(e is MethodDefinition)).ToList();
                    var callingType  = scope as TypeDefinition;
                    if (!localMatches.Any() && callingType != null)
                    {
                        //also search under the base types of the calling scope
                        matches = matches.Concat(callingType.SearchParentTypes <INamedEntity>(this.Name, e => !(e is MethodDefinition)));
                    }
                    else
                    {
                        matches = matches.Concat(localMatches);
                    }
                }
                return(matches);
            }

            //search enclosing scopes and base types
            foreach (var scope in ParentStatement.GetAncestors())
            {
                var matches = scope.GetNamedChildren(this).Where(e => !(e is MethodDefinition)).ToList();
                if (matches.Any())
                {
                    return(matches);
                }
                var expMatches = (from decl in scope.GetExpressions().SelectMany(e => e.GetDescendantsAndSelf <VariableDeclaration>())
                                  where decl.Name == this.Name
                                  select decl).ToList();
                if (expMatches.Any())
                {
                    return(expMatches);
                }
                var typeDef = scope as TypeDefinition;
                if (typeDef != null)
                {
                    var baseTypeMatches = typeDef.SearchParentTypes <INamedEntity>(this.Name, e => !(e is MethodDefinition)).ToList();
                    if (baseTypeMatches.Any())
                    {
                        return(baseTypeMatches);
                    }
                }
            }

            //search if there is an alias for this name
            foreach (var alias in GetAliases())
            {
                if (alias.AliasName == this.Name)
                {
                    var targetName = alias.Target as NameUse;
                    if (targetName == null)
                    {
                        //Target is not a NameUse, probably an Expression
                        targetName = alias.Target.GetDescendantsAndSelf <NameUse>().LastOrDefault();
                    }
                    if (targetName != null)
                    {
                        return(targetName.FindMatches());
                    }
                }
            }

            //we didn't find it locally, search under imported namespaces
            return(from import in GetImports()
                   from match in import.ImportedNamespace.GetDescendantsAndSelf <NameUse>().Last().FindMatches().OfType <NamedScope>()
                   from child in match.GetNamedChildren(this.Name)
                   where !(child is MethodDefinition)
                   select child);
        }