Exemple #1
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);
            }
        }
Exemple #2
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);
        }
        /// <summary>
        /// Creates a type use element
        /// </summary>
        /// <param name="typeUseElement">the element to parse. Must be of a <see cref="ABB.SrcML.SRC.Type"/> or <see cref="ABB.SrcML.SRC.Name"/></param>
        /// <param name="context">the parser context</param>
        /// <returns>A Type Use object</returns>
        public virtual TypeUse ParseTypeUseElement(XElement typeUseElement, ParserContext context) {
            if(typeUseElement == null) throw new ArgumentNullException("typeUseElement");

            XElement typeNameElement;

            // validate the type use typeUseElement (must be a SRC.Name or SRC.Type)
            if(typeUseElement.Name == SRC.Type) {
                typeNameElement = typeUseElement.Elements(SRC.Name).LastOrDefault();
            } else if(typeUseElement.Name == SRC.Name) {
                typeNameElement = typeUseElement;
            } else {
                throw new ArgumentException("typeUseElement should be of type type or name", "typeUseElement");
            }

            XElement lastNameElement = null;                  // this is the name element that identifies the type being used
            NamedScopeUse prefix = null;                      // This is the prefix (in A::B::C, this would be the chain A::B)
            XElement typeParameterArgumentList = null;        // the argument list element holds the parameters for generic type uses
            var typeParameters = Enumerable.Empty<TypeUse>(); // enumerable for the actual generic parameters

            // get the last name element and the prefix
            if(typeNameElement != null) {
                lastNameElement = NameHelper.GetLastNameElement(typeNameElement);
                prefix = ParseNamedScopeUsePrefix(typeNameElement, context);
            }

            // if the last name element exists, then this *may* be a generic type use
            // go look for the argument list element
            if(lastNameElement != null) {
                if(prefix == null) { // if there is no prefix, then the argument list element will be the first sibling of lastNameElement
                    typeParameterArgumentList = lastNameElement.ElementsAfterSelf(SRC.ArgumentList).FirstOrDefault();
                } else {             // otherwise, it will be the first *child* of lastNameElement
                    typeParameterArgumentList = lastNameElement.Elements(SRC.ArgumentList).FirstOrDefault();
                }
            }

            if(typeParameterArgumentList != null) {
                typeParameters = from argument in typeParameterArgumentList.Elements(SRC.Argument)
                                 where argument.Elements(SRC.Name).Any()
                                 select ParseTypeUseElement(argument.Element(SRC.Name), context);
                // if this is a generic type use and there is a prefix (A::B::C) then the last name element will actually be the first child of lastNameElement
                if(prefix != null) {
                    lastNameElement = lastNameElement.Element(SRC.Name);
                }
            }

            // construct the type use
            var typeUse = new TypeUse() {
                Name = (lastNameElement != null ? lastNameElement.Value : string.Empty),
                ParentScope = context.CurrentScope,
                Location = context.CreateLocation(lastNameElement != null ? lastNameElement : typeUseElement),
                Prefix = prefix,
                ProgrammingLanguage = this.ParserLanguage,
            };
            typeUse.AddTypeParameters(typeParameters);

            typeUse.AddAliases(context.Aliases);
            return typeUse;
        }