示例#1
0
        public static IReadOnlyList <Declaration> Load(Declaration parentProject, Declaration parentModule)
        {
            _logger.Debug("Loading custom declarations with {0} as parent project and {1} as parent module.", parentProject.IdentifierName, parentModule.IdentifierName);
            List <Declaration> declarations = new List <Declaration>();
            var debugModuleName             = new QualifiedModuleName(parentProject.QualifiedName.QualifiedModuleName.ProjectName, parentProject.QualifiedName.QualifiedModuleName.ProjectPath, "DebugClass");
            var debugModule    = new ProceduralModuleDeclaration(new QualifiedMemberName(debugModuleName, "DebugModule"), parentProject, "DebugModule", true, new List <IAnnotation>(), new Attributes());
            var debugClassName = new QualifiedModuleName(parentProject.QualifiedName.QualifiedModuleName.ProjectName, parentProject.QualifiedName.QualifiedModuleName.ProjectPath, "DebugClass");
            var debugClass     = new ClassModuleDeclaration(new QualifiedMemberName(debugClassName, "DebugClass"), parentProject, "DebugClass", true, new List <IAnnotation>(), new Attributes(), true);
            var debugObject    = new Declaration(new QualifiedMemberName(debugClassName, "Debug"), debugModule, "Global", "DebugClass", null, true, false, Accessibility.Global, DeclarationType.Variable, false, null);
            var debugAssert    = new SubroutineDeclaration(new QualifiedMemberName(debugClassName, "Assert"), debugClass, debugClass, null, Accessibility.Global, null, Selection.Home, true, null, new Attributes());
            var debugPrint     = new SubroutineDeclaration(new QualifiedMemberName(debugClassName, "Print"), debugClass, debugClass, null, Accessibility.Global, null, Selection.Home, true, null, new Attributes());

            declarations.Add(debugModule);
            declarations.Add(debugClass);
            declarations.Add(debugObject);
            declarations.Add(debugAssert);
            declarations.Add(debugPrint);
            declarations.AddRange(AddSpecialFormDeclarations(parentProject, parentModule));
            // Debug.Print has the same special syntax as the print and write statement.
            // Because of that it is treated specially in the grammar and normally wouldn't be resolved.
            // Since we still want it to be resolved we make it easier for the resolver to access the debug print
            // declaration by exposing it in this way.
            DEBUG_PRINT = debugPrint;
            return(declarations);
        }
示例#2
0
        public Declaration FindMemberEnclosingModule(Declaration callingModule, Declaration callingParent, string memberName, DeclarationType memberType)
        {
            // We do not explicitly pass the callingProject here because we have to walk up the type hierarchy
            // and thus the project differs depending on the callingModule.
            var callingProject = Declaration.GetProjectParent(callingModule);
            var allMatches     = MatchName(memberName);
            var memberMatches  = allMatches.Where(m =>
                                                  m.DeclarationType.HasFlag(memberType) &&
                                                  Declaration.GetProjectParent(m).Equals(callingProject) &&
                                                  callingModule.Equals(Declaration.GetModuleParent(m)));
            var accessibleMembers = memberMatches.Where(m => AccessibilityCheck.IsMemberAccessible(callingProject, callingModule, callingParent, m));
            var match             = accessibleMembers.FirstOrDefault();

            if (match != null)
            {
                return(match);
            }
            // Classes such as Worksheet have properties such as Range that can be access in a user defined class such as Sheet1,
            // that's why we have to walk the type hierarchy and find these implementations.
            foreach (var supertype in ClassModuleDeclaration.GetSupertypes(callingModule))
            {
                // Only built-in classes such as Worksheet can be considered "real base classes".
                // User created interfaces work differently and don't allow accessing accessing implementations.
                if (!supertype.IsBuiltIn)
                {
                    continue;
                }
                var supertypeMatch = FindMemberEnclosingModule(supertype, callingParent, memberName, memberType);
                if (supertypeMatch != null)
                {
                    return(supertypeMatch);
                }
            }
            return(match);
        }
示例#3
0
        public Declaration FindMemberReferencedProjectInModule(Declaration callingProject, Declaration callingModule, Declaration callingParent, Declaration memberModule, string memberName, DeclarationType memberType)
        {
            var memberMatches     = FindAllInReferencedProjectByPriority(callingProject, memberName, p => p.DeclarationType.HasFlag(memberType) && memberModule.Equals(Declaration.GetModuleParent(p)));
            var accessibleMembers = memberMatches.Where(m => AccessibilityCheck.IsMemberAccessible(callingProject, callingModule, callingParent, m));
            var match             = accessibleMembers.FirstOrDefault();

            if (match != null)
            {
                return(match);
            }
            foreach (var supertype in ClassModuleDeclaration.GetSupertypes(memberModule))
            {
                var supertypeMember = FindMemberReferencedProjectInModule(callingProject, callingModule, callingParent, supertype, memberName, memberType);
                if (supertypeMember != null)
                {
                    return(supertypeMember);
                }
            }
            return(null);
        }
示例#4
0
        public Declaration FindMemberWithParent(Declaration callingProject, Declaration callingModule, Declaration callingParent, Declaration parent, string memberName, DeclarationType memberType)
        {
            var allMatches    = MatchName(memberName);
            var memberMatches = allMatches.Where(m =>
                                                 m.DeclarationType.HasFlag(memberType) &&
                                                 parent.Equals(m.ParentDeclaration));
            var accessibleMembers = memberMatches.Where(m => AccessibilityCheck.IsMemberAccessible(callingProject, callingModule, callingParent, m));
            var match             = accessibleMembers.FirstOrDefault();

            if (match != null)
            {
                return(match);
            }
            foreach (var supertype in ClassModuleDeclaration.GetSupertypes(parent))
            {
                var supertypeMember = FindMemberWithParent(callingProject, callingModule, callingParent, supertype, memberName, memberType);
                if (supertypeMember != null)
                {
                    return(supertypeMember);
                }
            }
            return(null);
        }
        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);
        }
示例#6
0
 private static bool IsInstanceMemberOfModuleOrOneOfItsSupertypes(Declaration module, Declaration member)
 {
     return(IsInstanceMemberOfModule(module, member) ||
            ClassModuleDeclaration.GetSupertypes(module).Any(supertype => IsInstanceMemberOfModuleOrOneOfItsSupertypes(supertype, member)));         //ClassModuleDeclaration.GetSuperTypes never returns null.
 }
示例#7
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);
        }
示例#8
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));
                }
            }
        }