private Declaration CreateModuleDeclaration(IComType module, QualifiedModuleName project, Declaration parent, Attributes attributes) { var enumeration = module as ComEnumeration; if (enumeration != null) { return(new ProceduralModuleDeclaration(enumeration, parent, project)); } var types = module as ComStruct; if (types != null) { return(new ProceduralModuleDeclaration(types, parent, project)); } var coClass = module as ComCoClass; var intrface = module as ComInterface; if (coClass != null || intrface != null) { var output = coClass != null ? new ClassModuleDeclaration(coClass, parent, project, attributes) : new ClassModuleDeclaration(intrface, parent, project, attributes); if (coClass != null) { var members = coClass.Members.Where(m => !m.IsRestricted && !IgnoredInterfaceMembers.Contains(m.Name)) .Select(m => m.Name); _state.CoClasses.TryAdd(members.ToList(), output); } return(output); } return(new ProceduralModuleDeclaration(module as ComModule, parent, project, attributes)); }
private static Attributes GetModuleAttributes(IComType module) { var attributes = new Attributes(); if (module.IsPreDeclared) { attributes.AddPredeclaredIdTypeAttribute(); } if (module.IsAppObject) { attributes.AddGlobalClassAttribute(); } if (module is IComTypeWithMembers members && members.IsExtensible) { attributes.AddExtensibledClassAttribute(); } return(attributes); }
private static Declaration CreateModuleDeclaration(IComType module, QualifiedModuleName project, Declaration parent, Attributes attributes) { switch (module) { case ComEnumeration enumeration: return(new ProceduralModuleDeclaration(enumeration, parent, project)); case ComStruct types: return(new ProceduralModuleDeclaration(types, parent, project)); case ComCoClass coClass: return(new ClassModuleDeclaration(coClass, parent, project, attributes)); case ComInterface intrface: return(new ClassModuleDeclaration(intrface, parent, project, attributes)); default: return(new ProceduralModuleDeclaration(module as ComModule, parent, project, attributes)); } }
private static IEnumerable <string> SuperTypeNamesForDocumentFromComType(IComType comModule) { var inheritedInterfaces = comModule is ComCoClass documentCoClass ? documentCoClass.ImplementedInterfaces.ToList() : (comModule as ComInterface)?.InheritedInterfaces.ToList(); if (inheritedInterfaces == null) { return(Enumerable.Empty <string>()); } var relevantInterfaces = inheritedInterfaces .Where(i => !i.IsRestricted && !IgnoredComInterfaces.Contains(i.Name)) .ToList(); //todo: Find a way to deal with the VBE's document type assignment and interface behaviour not relying on an assumption about an interface naming conventions. //Some hosts like Access chose to have a separate hidden interface for each document module and only let that inherit the built-in base interface. //Since we do not have a declaration for the hidden interface, we have to go one more step up the hierarchy. var additionalInterfaces = relevantInterfaces .Where(i => i.Name.Equals("_" + comModule.Name)) .SelectMany(i => i.InheritedInterfaces) .ToList(); relevantInterfaces.AddRange(additionalInterfaces); var superTypeNames = relevantInterfaces .Select(i => i.Name) .ToList(); //This emulates the VBE's behaviour to allow assignment to the coclass type instead on the interface. var additionalSuperTypeNames = superTypeNames .Where(name => name.StartsWith("_")) .Select(name => name.Substring(1)) .Where(name => !name.Equals(comModule.Name)) .ToList(); superTypeNames.AddRange(additionalSuperTypeNames); return(superTypeNames); }
private static ICollection <Declaration> GetDeclarationsForModule(IComType module, QualifiedModuleName moduleName, ProjectDeclaration project) { var declarations = new List <Declaration>(); var attributes = GetModuleAttributes(module); var moduleDeclaration = CreateModuleDeclaration(module, moduleName, project, attributes); declarations.Add(moduleDeclaration); switch (module) { case IComTypeWithMembers membered: var(memberDeclarations, defaultMember) = GetDeclarationsForProperties(membered.Properties, moduleName, moduleDeclaration); declarations.AddRange(memberDeclarations); AssignDefaultMember(moduleDeclaration, defaultMember); (memberDeclarations, defaultMember) = GetDeclarationsForMembers(membered.Members, moduleName, moduleDeclaration, membered.DefaultMember); declarations.AddRange(memberDeclarations); AssignDefaultMember(moduleDeclaration, defaultMember); if (membered is ComCoClass coClass) { (memberDeclarations, defaultMember) = GetDeclarationsForMembers(coClass.SourceMembers, moduleName, moduleDeclaration, coClass.DefaultMember, true); declarations.AddRange(memberDeclarations); AssignDefaultMember(moduleDeclaration, defaultMember); } break; case ComEnumeration enumeration: { var enumDeclaration = new Declaration(enumeration, moduleDeclaration, moduleName); declarations.Add(enumDeclaration); var members = enumeration.Members .Select(enumMember => new ValuedDeclaration(enumMember, enumDeclaration, moduleName)) .ToList(); declarations.AddRange(members); break; } case ComStruct structure: { var typeDeclaration = new Declaration(structure, moduleDeclaration, moduleName); declarations.Add(typeDeclaration); var members = structure.Fields .Select(f => new Declaration(f, typeDeclaration, moduleName)) .ToList(); declarations.AddRange(members); break; } } if (module is IComTypeWithFields fields && fields.Fields.Any()) { var projectName = project.QualifiedModuleName; var fieldDeclarations = new List <Declaration>(); foreach (var field in fields.Fields) { fieldDeclarations.Add(field.Type == DeclarationType.Constant ? new ValuedDeclaration(field, moduleDeclaration, projectName) : new Declaration(field, moduleDeclaration, projectName)); } declarations.AddRange(fieldDeclarations); } return(declarations); }