Inheritance: Rubberduck.Parsing.Symbols.Declaration
 private Declaration CreateProjectDeclaration(QualifiedModuleName projectQualifiedName, VBProject project)
 {
     var qualifiedName = projectQualifiedName.QualifyMemberName(project.Name);
     var projectId = qualifiedName.QualifiedModuleName.ProjectId;
     var projectDeclaration = new ProjectDeclaration(qualifiedName, project.Name);
     var references = _projectReferences.Where(projectContainingReference => projectContainingReference.ContainsKey(projectId));
     foreach (var reference in references)
     {
         int priority = reference[projectId];
         projectDeclaration.AddProjectReference(reference.ReferencedProjectId, priority);
     }
     return projectDeclaration;
 }
        public List <Declaration> GetDeclarationsForReference(Reference reference)
        {
            var      output      = new List <Declaration>();
            var      projectName = reference.Name;
            var      path        = reference.FullPath;
            ITypeLib typeLibrary;

            // Failure to load might mean that it's a "normal" VBProject that will get parsed by us anyway.
            LoadTypeLibEx(path, REGKIND.REGKIND_NONE, out typeLibrary);
            if (typeLibrary == null)
            {
                return(output);
            }
            var projectQualifiedModuleName = new QualifiedModuleName(projectName, path, projectName);
            var projectQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, projectName);
            var projectDeclaration         = new ProjectDeclaration(projectQualifiedMemberName, projectName, isBuiltIn: true);

            output.Add(projectDeclaration);

            var typeCount = typeLibrary.GetTypeInfoCount();

            for (var i = 0; i < typeCount; i++)
            {
                ITypeInfo info;
                try
                {
                    typeLibrary.GetTypeInfo(i, out info);
                }
                catch (NullReferenceException)
                {
                    return(output);
                }

                if (info == null)
                {
                    continue;
                }

                var typeName            = GetTypeName(info);
                var typeDeclarationType = GetDeclarationType(typeLibrary, i);

                QualifiedModuleName typeQualifiedModuleName;
                QualifiedMemberName typeQualifiedMemberName;
                if (typeDeclarationType == DeclarationType.Enumeration || typeDeclarationType == DeclarationType.UserDefinedType)
                {
                    typeQualifiedModuleName = projectQualifiedModuleName;
                    typeQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, typeName);
                }
                else
                {
                    typeQualifiedModuleName = new QualifiedModuleName(projectName, path, typeName);
                    typeQualifiedMemberName = new QualifiedMemberName(typeQualifiedModuleName, typeName);
                }

                IntPtr typeAttributesPointer;
                info.GetTypeAttr(out typeAttributesPointer);
                var typeAttributes = (TYPEATTR)Marshal.PtrToStructure(typeAttributesPointer, typeof(TYPEATTR));
                var attributes     = new Attributes();

                if (typeAttributes.wTypeFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FPREDECLID))
                {
                    attributes.AddPredeclaredIdTypeAttribute();
                }

                Declaration moduleDeclaration;
                switch (typeDeclarationType)
                {
                case DeclarationType.ProceduralModule:
                    moduleDeclaration = new ProceduralModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes);
                    break;

                case DeclarationType.ClassModule:
                    var module     = new ClassModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes);
                    var implements = GetImplementedInterfaceNames(typeAttributes, info);
                    foreach (var supertypeName in implements)
                    {
                        module.AddSupertype(supertypeName);
                    }
                    moduleDeclaration = module;
                    break;

                default:
                    string pseudoModuleName   = string.Format("_{0}", typeName);
                    var    pseudoParentModule = new ProceduralModuleDeclaration(
                        new QualifiedMemberName(projectQualifiedModuleName, pseudoModuleName),
                        projectDeclaration,
                        pseudoModuleName,
                        true,
                        new List <IAnnotation>(),
                        new Attributes());
                    // Enums don't define their own type but have a declared type of "Long".
                    if (typeDeclarationType == DeclarationType.Enumeration)
                    {
                        typeName = Tokens.Long;
                    }
                    // UDTs and ENUMs don't seem to have a module parent that's why we add a "fake" module
                    // so that the rest of the application can treat it normally.
                    moduleDeclaration = new Declaration(
                        typeQualifiedMemberName,
                        pseudoParentModule,
                        pseudoParentModule,
                        typeName,
                        null,
                        false,
                        false,
                        Accessibility.Global,
                        typeDeclarationType,
                        null,
                        Selection.Home,
                        false,
                        null,
                        true,
                        null,
                        attributes);
                    break;
                }
                ComInformation comInfo;
                if (_comInformation.TryGetValue(typeAttributes.guid, out comInfo))
                {
                    comInfo.TypeQualifiedModuleName = typeQualifiedModuleName;
                    comInfo.ModuleDeclaration       = moduleDeclaration;
                    comInfo.TypeDeclarationType     = typeDeclarationType;
                }
                else
                {
                    _comInformation.Add(typeAttributes.guid,
                                        new ComInformation(typeAttributes, 0, info, typeName, typeQualifiedModuleName, moduleDeclaration,
                                                           typeDeclarationType));
                }

                info.ReleaseTypeAttr(typeAttributesPointer);

                output.Add(moduleDeclaration);
            }

            foreach (var member in _comInformation.Values)
            {
                for (var memberIndex = 0; memberIndex < member.TypeAttributes.cFuncs; memberIndex++)
                {
                    string[] memberNames;

                    IntPtr memberDescriptorPointer;
                    member.TypeInfo.GetFuncDesc(memberIndex, out memberDescriptorPointer);
                    var memberDescriptor = (FUNCDESC)Marshal.PtrToStructure(memberDescriptorPointer, typeof(FUNCDESC));

                    var memberDeclaration = CreateMemberDeclaration(memberDescriptor, member.TypeAttributes.typekind, member.TypeInfo, member.ImplTypeFlags,
                                                                    member.TypeQualifiedModuleName, member.ModuleDeclaration, out memberNames);
                    if (memberDeclaration == null)
                    {
                        member.TypeInfo.ReleaseFuncDesc(memberDescriptorPointer);
                        continue;
                    }
                    if (member.ModuleDeclaration.DeclarationType == DeclarationType.ClassModule &&
                        memberDeclaration is ICanBeDefaultMember &&
                        ((ICanBeDefaultMember)memberDeclaration).IsDefaultMember)
                    {
                        ((ClassModuleDeclaration)member.ModuleDeclaration).DefaultMember = memberDeclaration;
                    }
                    output.Add(memberDeclaration);

                    var parameterCount = memberDescriptor.cParams - (memberDescriptor.invkind.HasFlag(INVOKEKIND.INVOKE_PROPERTYGET) ? 0 : 1);
                    var parameters     = new List <ParameterDeclaration>();
                    for (var paramIndex = 0; paramIndex < parameterCount; paramIndex++)
                    {
                        var parameter = CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor,
                                                                   member.TypeQualifiedModuleName, memberDeclaration, member.TypeInfo);
                        var declaration = memberDeclaration as IDeclarationWithParameter;
                        if (declaration != null)
                        {
                            parameters.Add(parameter);
                            declaration.AddParameter(parameter);
                        }
                        output.Add(parameter);
                    }
                    member.TypeInfo.ReleaseFuncDesc(memberDescriptorPointer);
                    if (parameters.Any() && memberDescriptor.cParamsOpt == -1)
                    {
                        parameters.Last().IsParamArray = true;
                    }
                }

                for (var fieldIndex = 0; fieldIndex < member.TypeAttributes.cVars; fieldIndex++)
                {
                    output.Add(CreateFieldDeclaration(member.TypeInfo, fieldIndex, member.TypeDeclarationType, member.TypeQualifiedModuleName,
                                                      member.ModuleDeclaration));
                }
            }

            return(output);
        }
Example #3
0
        public List <Declaration> GetDeclarationsForReference(Reference reference)
        {
            var      output      = new List <Declaration>();
            var      projectName = reference.Name;
            var      path        = reference.FullPath;
            ITypeLib typeLibrary;

            // Failure to load might mean that it's a "normal" VBProject that will get parsed by us anyway.
            LoadTypeLibEx(path, REGKIND.REGKIND_NONE, out typeLibrary);
            if (typeLibrary == null)
            {
                return(output);
            }
            var projectQualifiedModuleName = new QualifiedModuleName(projectName, path, projectName);
            var projectQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, projectName);
            var projectDeclaration         = new ProjectDeclaration(projectQualifiedMemberName, projectName, isBuiltIn: true);

            output.Add(projectDeclaration);

            var typeCount = typeLibrary.GetTypeInfoCount();

            for (var i = 0; i < typeCount; i++)
            {
                ITypeInfo info;
                try
                {
                    typeLibrary.GetTypeInfo(i, out info);
                }
                catch (NullReferenceException)
                {
                    return(output);
                }

                if (info == null)
                {
                    continue;
                }

                var typeName            = GetTypeName(info);
                var typeDeclarationType = GetDeclarationType(typeLibrary, i);

                QualifiedModuleName typeQualifiedModuleName;
                QualifiedMemberName typeQualifiedMemberName;
                if (typeDeclarationType == DeclarationType.Enumeration || typeDeclarationType == DeclarationType.UserDefinedType)
                {
                    typeQualifiedModuleName = projectQualifiedModuleName;
                    typeQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, typeName);
                }
                else
                {
                    typeQualifiedModuleName = new QualifiedModuleName(projectName, path, typeName);
                    typeQualifiedMemberName = new QualifiedMemberName(typeQualifiedModuleName, typeName);
                }

                IntPtr typeAttributesPointer;
                info.GetTypeAttr(out typeAttributesPointer);
                var typeAttributes = (TYPEATTR)Marshal.PtrToStructure(typeAttributesPointer, typeof(TYPEATTR));
                var attributes     = new Attributes();

                if (typeAttributes.wTypeFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FPREDECLID))
                {
                    attributes.AddPredeclaredIdTypeAttribute();
                }

                if (typeAttributes.wTypeFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FAPPOBJECT))
                {
                    attributes.AddGlobalClassAttribute();
                }

                Declaration moduleDeclaration;
                switch (typeDeclarationType)
                {
                case DeclarationType.ProceduralModule:
                    moduleDeclaration = new ProceduralModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes);
                    break;

                case DeclarationType.ClassModule:
                    var module     = new ClassModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes);
                    var implements = GetImplementedInterfaceNames(typeAttributes, info, module);
                    foreach (var supertypeName in implements)
                    {
                        module.AddSupertype(supertypeName);
                    }
                    moduleDeclaration = module;
                    break;

                default:
                    string pseudoModuleName   = string.Format("_{0}", typeName);
                    var    pseudoParentModule = new ProceduralModuleDeclaration(
                        new QualifiedMemberName(projectQualifiedModuleName, pseudoModuleName),
                        projectDeclaration,
                        pseudoModuleName,
                        true,
                        new List <IAnnotation>(),
                        new Attributes());
                    // Enums don't define their own type but have a declared type of "Long".
                    if (typeDeclarationType == DeclarationType.Enumeration)
                    {
                        typeName = Tokens.Long;
                    }
                    // UDTs and ENUMs don't seem to have a module parent that's why we add a "fake" module
                    // so that the rest of the application can treat it normally.
                    moduleDeclaration = new Declaration(
                        typeQualifiedMemberName,
                        pseudoParentModule,
                        pseudoParentModule,
                        typeName,
                        null,
                        false,
                        false,
                        Accessibility.Global,
                        typeDeclarationType,
                        null,
                        Selection.Home,
                        false,
                        null,
                        true,
                        null,
                        attributes);
                    break;
                }

                if (typeAttributes.guid == Guid.Empty)
                {
                    LoadDeclarationsInModule(output,
                                             new ComInformation(typeAttributes, 0, info, typeName, typeQualifiedModuleName,
                                                                moduleDeclaration,
                                                                typeDeclarationType));
                }
                else
                {
                    ComInformation comInfo;
                    if (_comInformation.TryGetValue(typeAttributes.guid, out comInfo))
                    {
                        comInfo.TypeQualifiedModuleName = typeQualifiedModuleName;
                        comInfo.ModuleDeclaration       = moduleDeclaration;
                        comInfo.TypeDeclarationType     = typeDeclarationType;
                    }
                    else
                    {
                        _comInformation.Add(typeAttributes.guid,
                                            new ComInformation(typeAttributes, 0, info, typeName, typeQualifiedModuleName,
                                                               moduleDeclaration,
                                                               typeDeclarationType));
                    }
                }

                info.ReleaseTypeAttr(typeAttributesPointer);

                output.Add(moduleDeclaration);
            }

            foreach (var member in _comInformation.Values)
            {
                LoadDeclarationsInModule(output, member);
            }

            return(output);
        }
Example #4
0
        public IEnumerable <Declaration> GetDeclarationsForReference(Reference reference)
        {
            var      projectName = reference.Name;
            var      path        = reference.FullPath;
            ITypeLib typeLibrary;

            // Failure to load might mean that it's a "normal" VBProject that will get parsed by us anyway.
            LoadTypeLibEx(path, REGKIND.REGKIND_NONE, out typeLibrary);
            if (typeLibrary == null)
            {
                yield break;
            }
            var projectQualifiedModuleName = new QualifiedModuleName(projectName, path, projectName);
            var projectQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, projectName);
            var projectDeclaration         = new ProjectDeclaration(projectQualifiedMemberName, projectName);

            yield return(projectDeclaration);

            var typeCount = typeLibrary.GetTypeInfoCount();

            for (var i = 0; i < typeCount; i++)
            {
                ITypeInfo info;
                try
                {
                    typeLibrary.GetTypeInfo(i, out info);
                }
                catch (NullReferenceException)
                {
                    yield break;
                }

                if (info == null)
                {
                    continue;
                }

                var typeName            = GetTypeName(info);
                var typeDeclarationType = GetDeclarationType(typeLibrary, i);

                QualifiedModuleName typeQualifiedModuleName;
                QualifiedMemberName typeQualifiedMemberName;
                if (typeDeclarationType == DeclarationType.Enumeration || typeDeclarationType == DeclarationType.UserDefinedType)
                {
                    typeQualifiedModuleName = projectQualifiedModuleName;
                    typeQualifiedMemberName = new QualifiedMemberName(projectQualifiedModuleName, typeName);
                }
                else
                {
                    typeQualifiedModuleName = new QualifiedModuleName(projectName, path, typeName);
                    typeQualifiedMemberName = new QualifiedMemberName(typeQualifiedModuleName, typeName);
                }

                IntPtr typeAttributesPointer;
                info.GetTypeAttr(out typeAttributesPointer);

                var typeAttributes = (TYPEATTR)Marshal.PtrToStructure(typeAttributesPointer, typeof(TYPEATTR));
                //var implements = GetImplementedInterfaceNames(typeAttributes, info);

                var attributes = new Attributes();
                if (typeAttributes.wTypeFlags.HasFlag(TYPEFLAGS.TYPEFLAG_FPREDECLID))
                {
                    attributes.AddPredeclaredIdTypeAttribute();
                }

                Declaration moduleDeclaration;
                if (typeDeclarationType == DeclarationType.ProceduralModule)
                {
                    moduleDeclaration = new ProceduralModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes);
                }
                else
                {
                    moduleDeclaration = new ClassModuleDeclaration(typeQualifiedMemberName, projectDeclaration, typeName, true, new List <IAnnotation>(), attributes, isExposed: true);
                }
                yield return(moduleDeclaration);

                for (var memberIndex = 0; memberIndex < typeAttributes.cFuncs; memberIndex++)
                {
                    FUNCDESC memberDescriptor;
                    string[] memberNames;
                    var      memberDeclaration = CreateMemberDeclaration(out memberDescriptor, typeAttributes.typekind, info, memberIndex, typeQualifiedModuleName, moduleDeclaration, out memberNames);
                    if (memberDeclaration == null)
                    {
                        continue;
                    }

                    yield return(memberDeclaration);

                    var parameterCount = memberDescriptor.cParams - 1;
                    for (var paramIndex = 0; paramIndex < parameterCount; paramIndex++)
                    {
                        yield return(CreateParameterDeclaration(memberNames, paramIndex, memberDescriptor, typeQualifiedModuleName, memberDeclaration));
                    }
                }

                for (var fieldIndex = 0; fieldIndex < typeAttributes.cVars; fieldIndex++)
                {
                    yield return(CreateFieldDeclaration(info, fieldIndex, typeDeclarationType, typeQualifiedModuleName, moduleDeclaration));
                }
            }
        }