/// <summary>
 /// Checks the type is priliminary or not
 /// </summary>
 /// <param tu.Name="type"></param>
 /// <returns></returns>
 public override bool IsPrimitiveType(TypeUse tu)
 {
     if(tu != null) {
         return BuiltInTypeFactory.IsBuiltIn(tu);
     } else {
         return false;
     }
 }
Exemple #2
0
        /// <summary>
        /// Adds <paramref name="parentTypeUse"/>as a parent type for this type definition.
        /// </summary>
        /// <param name="parentTypeUse">The parent type to add</param>
        public void AddParentType(TypeUse parentTypeUse)
        {
            if (null == parentTypeUse)
            {
                throw new ArgumentNullException("parentTypeUse");
            }

            parentTypeUse.ParentStatement = this;
            parentTypeCollection.Add(parentTypeUse);
        }
Exemple #3
0
 /// <summary>
 /// Adds a generic type parameter to this type use
 /// </summary>
 /// <param name="typeParameter">The type parameter to add</param>
 public void AddTypeParameter(TypeUse typeParameter)
 {
     if (typeParameter == null)
     {
         throw new ArgumentNullException("typeParameter");
     }
     typeParameter.ParentExpression = this;
     typeParameter.ParentStatement  = this.ParentStatement;
     typeParameterList.Add(typeParameter);
 }
Exemple #4
0
 /// <summary>
 /// Adds the given type argument to the TypeArguments collection.
 /// </summary>
 /// <param name="arg">The type argument to add.</param>
 public void AddTypeArgument(TypeUse arg)
 {
     if (arg == null)
     {
         throw new ArgumentNullException("arg");
     }
     arg.ParentExpression = this;
     arg.ParentStatement  = this.ParentStatement;
     typeArgumentList.Add(arg);
 }
        /// <summary>
        /// Checks if the <paramref name="use">given type use</paramref> is a built-in type.
        /// </summary>
        /// <param name="use">The type use to test</param>
        /// <returns>true if this is a built-in type; false otherwise</returns>
        public static bool IsBuiltIn(TypeUse use) {
            if(use == null) throw new ArgumentNullException("use");

            switch(use.ProgrammingLanguage) {
                case Language.CPlusPlus:
                    return IsCppBuiltIn(use.Name);
                case Language.CSharp:
                    return IsCSharpBuiltIn(use.Name);
                case Language.Java:
                    return IsJavaBuiltIn(use.Name);
            }
            return false;
        }
Exemple #6
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 #7
0
        /// <summary>
        /// Adds a return type to the internal return type collection. If the <paramref name="returnType"/> has a different
        /// type name than this object, then the map is cleared and <paramref name="returnType" /> is the
        /// sole return type for this method.
        /// </summary>
        /// <param name="returnType">The return type object to add</param>
        public void AddReturnType(TypeUse returnType)
        {
            if (returnType == null)
            {
                throw new ArgumentNullException("returnType");
            }

            if (null != ReturnType && this.ReturnType.Name != returnType.Name)
            {
                _returnTypeMap.Clear();
            }
            returnType.ParentStatement = this;
            _returnTypeMap[returnType.Location.ToString()] = returnType;
        }
        /// <summary>
        /// Returns the built-in type for the given type use
        /// </summary>
        /// <param name="use">the type use to locate</param>
        /// <returns>A type definition that matches the type use; null if this is not a built-in</returns>
        public static TypeDefinition GetBuiltIn(TypeUse use) {
            if(!IsBuiltIn(use)) return null;

            var key = new Tuple<Language, string>(use.ProgrammingLanguage, use.Name);
            TypeDefinition builtIn;
            if(!builtInTypeMap.TryGetValue(key, out builtIn)) {
                builtIn = new TypeDefinition() {
                    Accessibility = AccessModifier.None,
                    Kind = TypeKind.BuiltIn,
                    Name = key.Item2,
                    ProgrammingLanguage = key.Item1,
                };
                builtInTypeMap[key] = builtIn;
            }
            return builtIn;
        }
Exemple #9
0
        /// <summary>
        /// Finds all of the matching type definitions for the return type of this method definition
        /// </summary>
        /// <returns>An enumerable of the matching type definitions for this method</returns>
        public override IEnumerable <TypeDefinition> ResolveType()
        {
            var matchingMethods = FindMatches().OfType <MethodDefinition>().ToList();

            if (matchingMethods.Any())
            {
                foreach (var methodDefinition in matchingMethods)
                {
                    var matchingTypes = Enumerable.Empty <TypeDefinition>();

                    if (methodDefinition.ReturnType != null)
                    {
                        matchingTypes = methodDefinition.ReturnType.ResolveType();
                    }
                    else if (methodDefinition.IsConstructor)
                    {
                        var methodName = methodDefinition.Name; //define local var because of Resharper warning about accessing foreach var in closure
                        matchingTypes = methodDefinition.GetAncestors <TypeDefinition>().Where(td => td.Name == methodName);
                    }
                    foreach (var result in matchingTypes)
                    {
                        yield return(result);
                    }
                }
            }
            else
            {
                //no matches
                //handle case of calls to default (implicit) constructors
                if (IsConstructor && Arguments.Count == 0)
                {
                    var tempType = new TypeUse()
                    {
                        Name                = this.Name,
                        Location            = this.Location,
                        ParentStatement     = this.ParentStatement,
                        ProgrammingLanguage = this.ProgrammingLanguage
                    };
                    foreach (var result in tempType.ResolveType())
                    {
                        yield return(result);
                    }
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Checks if the
        /// <paramref name="use">given type use</paramref> is a built-in type.
        /// </summary>
        /// <param name="use">The type use to test</param>
        /// <returns>true if this is a built-in type; false otherwise</returns>
        public static bool IsBuiltIn(TypeUse use)
        {
            if (use == null)
            {
                throw new ArgumentNullException("use");
            }

            switch (use.ProgrammingLanguage)
            {
            case Language.CPlusPlus:
                return(IsCppBuiltIn(use.Name));

            case Language.CSharp:
                return(IsCSharpBuiltIn(use.Name));

            case Language.Java:
                return(IsJavaBuiltIn(use.Name));
            }
            return(false);
        }
Exemple #11
0
        /// <summary>
        /// Returns the built-in type for the given type use
        /// </summary>
        /// <param name="use">the type use to locate</param>
        /// <returns>A type definition that matches the type use; null if this is not a
        /// built-in</returns>
        public static TypeDefinition GetBuiltIn(TypeUse use)
        {
            if (!IsBuiltIn(use))
            {
                return(null);
            }

            var            key = new Tuple <Language, string>(use.ProgrammingLanguage, use.Name);
            TypeDefinition builtIn;

            if (!builtInTypeMap.TryGetValue(key, out builtIn))
            {
                builtIn = new TypeDefinition()
                {
                    Accessibility       = AccessModifier.None,
                    Kind                = TypeKind.BuiltIn,
                    Name                = key.Item2,
                    ProgrammingLanguage = key.Item1,
                };
                builtInTypeMap[key] = builtIn;
            }
            return(builtIn);
        }
Exemple #12
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);
        }
 /// <summary>
 /// Checks the type is priliminary or not
 /// </summary>
 /// <param name="tu"></param>
 /// <returns></returns>
 public abstract bool IsPrimitiveType(TypeUse tu);
Exemple #14
0
        /// <summary>
        /// Finds all of the matching type definitions for the return type of this method definition
        /// </summary>
        /// <returns>An enumerable of the matching type definitions for this method</returns>
        public override IEnumerable<TypeDefinition> ResolveType() {
            var matchingMethods = FindMatches().OfType<MethodDefinition>().ToList();
            if(matchingMethods.Any()) {
                foreach(var methodDefinition in matchingMethods) {
                    var matchingTypes = Enumerable.Empty<TypeDefinition>();

                    if(methodDefinition.ReturnType != null) {
                        matchingTypes = methodDefinition.ReturnType.ResolveType();
                    } else if(methodDefinition.IsConstructor) {
                        var methodName = methodDefinition.Name; //define local var because of Resharper warning about accessing foreach var in closure
                        matchingTypes = methodDefinition.GetAncestors<TypeDefinition>().Where(td => td.Name == methodName);
                    }
                    foreach(var result in matchingTypes) {
                        yield return result;
                    }
                }
            } else {
                //no matches
                //handle case of calls to default (implicit) constructors
                if(IsConstructor && Arguments.Count == 0) {
                    var tempType = new TypeUse() {
                        Name = this.Name, 
                        Location = this.Location,
                        ParentStatement = this.ParentStatement, 
                        ProgrammingLanguage = this.ProgrammingLanguage
                    };
                    foreach(var result in tempType.ResolveType()) {
                        yield return result;
                    }
                }
            }


        }
Exemple #15
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);

        }
Exemple #16
0
 /// <summary>
 /// Adds the given type argument to the TypeArguments collection.
 /// </summary>
 /// <param name="arg">The type argument to add.</param>
 public void AddTypeArgument(TypeUse arg) {
     if(arg == null) { throw new ArgumentNullException("arg"); }
     arg.ParentExpression = this;
     arg.ParentStatement = this.ParentStatement;
     typeArgumentList.Add(arg);
 }
Exemple #17
0
 /// <summary>
 /// Adds a generic type parameter to this type use
 /// </summary>
 /// <param name="typeParameter">The type parameter to add</param>
 public void AddTypeParameter(TypeUse typeParameter) {
     if(typeParameter == null) { throw new ArgumentNullException("typeParameter"); }
     typeParameter.ParentExpression = this;
     typeParameter.ParentStatement = this.ParentStatement;
     typeParameterList.Add(typeParameter);
 }
        /// <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;
        }
Exemple #19
0
        /// <summary>
        /// If there is a calling expession preceding this NameUse, this method resolves it
        /// to determine the scope(s) in which to search for the use's name.
        /// </summary>
        /// <returns>An enumerable of the named entities that may contain the name being used in this NameUse.
        /// Returns null if there is no suitable calling expression.
        /// Returns an empty enumerable if there is a calling expression, but no matches are found.</returns>
        protected IEnumerable<NamedScope> GetCallingScope() {
            var siblings = GetSiblingsBeforeSelf().ToList();
            var priorOp = siblings.LastOrDefault() as OperatorUse;
            if(priorOp == null || !NameInclusionOperators.Contains(priorOp.Text)) {
                return null;
            }

            if(siblings.Count == 1) {
                //This use is preceded by a name inclusion operator and nothing else
                //this is probably only possible in C++: ::MyGlobalClass
                //just return the global namespace
                return ParentStatement.GetAncestorsAndSelf<NamespaceDefinition>().Where(n => n.IsGlobal);
            }

            var callingExp = siblings[siblings.Count - 2]; //second-to-last sibling
            var callingName = callingExp as NameUse;
            if(callingName == null) {
                //Not a NameUse, probably an Expression
                return callingExp.ResolveType();
            }

            var matches = callingName.FindMatches();
            var scopes = new List<NamedScope>();
            foreach(var match in matches) {
                //TODO: update this to use polymorphism
                if(match is MethodDefinition) {
                    var method = match as MethodDefinition;
                    if(method.ReturnType != null) {
                        scopes.AddRange(((MethodDefinition)match).ReturnType.ResolveType());
                    } else if(method.IsConstructor) {
                        //create the constructor return type
                        var tempTypeUse = new TypeUse() {
                            Name = method.Name,
                            ParentStatement = method.ParentStatement,
                            Location = method.PrimaryLocation
                        };
                        scopes.AddRange(tempTypeUse.ResolveType());
                    } 
                } else if(match is PropertyDefinition) {
                    scopes.AddRange(((PropertyDefinition)match).ReturnType.ResolveType());
                } else if(match is VariableDeclaration) {
                    scopes.AddRange(((VariableDeclaration)match).VariableType.ResolveType());
                } else {
                    //the only other possibilities are all NamedScopes
                    scopes.Add((NamedScope)match);
                }
            }
            return scopes;
        }
Exemple #20
0
        /// <summary>
        /// If there is a calling expession preceding this NameUse, this method resolves it
        /// to determine the scope(s) in which to search for the use's name.
        /// </summary>
        /// <returns>An enumerable of the named entities that may contain the name being used in this NameUse.
        /// Returns null if there is no suitable calling expression.
        /// Returns an empty enumerable if there is a calling expression, but no matches are found.</returns>
        protected IEnumerable <NamedScope> GetCallingScope()
        {
            var siblings = GetSiblingsBeforeSelf().ToList();
            var priorOp  = siblings.LastOrDefault() as OperatorUse;

            if (priorOp == null || !NameInclusionOperators.Contains(priorOp.Text))
            {
                return(null);
            }

            if (siblings.Count == 1)
            {
                //This use is preceded by a name inclusion operator and nothing else
                //this is probably only possible in C++: ::MyGlobalClass
                //just return the global namespace
                return(ParentStatement.GetAncestorsAndSelf <NamespaceDefinition>().Where(n => n.IsGlobal));
            }

            var callingExp  = siblings[siblings.Count - 2]; //second-to-last sibling
            var callingName = callingExp as NameUse;

            if (callingName == null)
            {
                //Not a NameUse, probably an Expression
                return(callingExp.ResolveType());
            }

            var matches = callingName.FindMatches();
            var scopes  = new List <NamedScope>();

            foreach (var match in matches)
            {
                //TODO: update this to use polymorphism
                if (match is MethodDefinition)
                {
                    var method = match as MethodDefinition;
                    if (method.ReturnType != null)
                    {
                        scopes.AddRange(((MethodDefinition)match).ReturnType.ResolveType());
                    }
                    else if (method.IsConstructor)
                    {
                        //create the constructor return type
                        var tempTypeUse = new TypeUse()
                        {
                            Name            = method.Name,
                            ParentStatement = method.ParentStatement,
                            Location        = method.PrimaryLocation
                        };
                        scopes.AddRange(tempTypeUse.ResolveType());
                    }
                }
                else if (match is PropertyDefinition)
                {
                    scopes.AddRange(((PropertyDefinition)match).ReturnType.ResolveType());
                }
                else if (match is VariableDeclaration)
                {
                    scopes.AddRange(((VariableDeclaration)match).VariableType.ResolveType());
                }
                else
                {
                    //the only other possibilities are all NamedScopes
                    scopes.Add((NamedScope)match);
                }
            }
            if (scopes.Count == 0)
            {
                return(null);
            }
            else
            {
                return(scopes);
            }
        }
Exemple #21
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);
        }
Exemple #22
0
        /// <summary>
        /// Adds <paramref name="parentTypeUse"/> as a parent type for this type definition
        /// </summary>
        /// <param name="parentTypeUse">The parent type to add</param>
        public void AddParentType(TypeUse parentTypeUse) {
            if(null == parentTypeUse) throw new ArgumentNullException("parentTypeUse");

            parentTypeUse.ParentScope = this;
            ParentTypeCollection.Add(parentTypeUse);
        }