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); }
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); }
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); }
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); }
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. }
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); }
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)); } } }