public void ModulesCanBeAccessedFromWithinThemselves() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, null, moduleDeclatation)); }
public void ModulesCanBeAccessedFromTheSameProject() { var projectDeclatation = GetTestProject("test_project"); var calleeModuleDeclatation = GetTestClassModule(projectDeclatation, "calleeModule"); var callingModuleDeclatation = GetTestClassModule(projectDeclatation, "callingModule"); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, callingModuleDeclatation, null, calleeModuleDeclatation)); }
public void CalleeMembersWhichAreNullAreNotAcessibleFromOtherProjects() { var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var callingFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsFalse(AccessibilityCheck.IsMemberAccessible(callingProjectDeclatation, callingModuleDeclatation, callingFunctionDeclaration, null)); }
public void PrivateProceduresAreAccessibleFromTheEnclosingModule() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateCalleeFunctionDeclaration = GetTestFunction(moduleDeclatation, "calleeFoo", Accessibility.Private); var privateCallingFunctionDeclaration = GetTestFunction(moduleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, privateCallingFunctionDeclaration, privateCalleeFunctionDeclaration)); }
public void StaticLocalMembersAreAcessibleFromTheMethodTheyAreDefinedIn() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateFunctionDeclaration = GetTestFunction(moduleDeclatation, "foo", Accessibility.Private); var localVariable = GetTestVariable(privateFunctionDeclaration, "x", Accessibility.Static); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, privateFunctionDeclaration, localVariable)); }
public void NonPrivateProceduralModulesCanBeAccessedFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("calleeProject"); var calleeModuleDeclatation = GetTestProceduralModule(calleeProjectDeclatation, "caleeModule"); var callingProjectDeclatation = GetTestProject("callingProject"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "callingModule"); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, null, calleeModuleDeclatation)); }
public void ImplicitlyScopedInstanceVariablesAreAcessibleWithinTheirEnclosingModule() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateFunctionDeclaration = GetTestFunction(moduleDeclatation, "foo", Accessibility.Private); var instanceVariable = GetTestVariable(moduleDeclatation, "x", Accessibility.Implicit); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, privateFunctionDeclaration, instanceVariable)); }
public void PrivateUserTypesAreAccessibleInTheSameModule() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "callee_test_Module", true); var userType = GetTestUserType(calleeModuleDeclatation, "x", Accessibility.Private); var functionDeclaration = GetTestFunction(calleeModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(calleeProjectDeclatation, calleeModuleDeclatation, functionDeclaration, userType)); }
public void PrivateInstanceVariablesAreAccessibleFromTheEnclosingModule() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateFunctionDeclaration = GetTestFunction(moduleDeclatation, "foo", Accessibility.Private); var privateInstanceVariable = GetTestVariable(moduleDeclatation, "x", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, privateFunctionDeclaration, privateInstanceVariable)); }
public void NonExposedClassModulesCannotBeAccessedFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("calleeProject"); var calleeModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "caleeModule", false); var callingProjectDeclatation = GetTestProject("callingProject"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "callingModule"); Assert.IsFalse(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, null, calleeModuleDeclatation)); }
public void PrivateProceduresAreNotAcessibleFromOtherUnrelatedModules() { var projectDeclatation = GetTestProject("test_project"); var calleeModuleDeclatation = GetTestClassModule(projectDeclatation, "callee_test_Module"); var calleeFunctionDeclaration = GetTestFunction(calleeModuleDeclatation, "calleeFoo", Accessibility.Private); var callingModuleDeclatation = GetTestClassModule(projectDeclatation, "calling_test_Module"); var callingFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsFalse(AccessibilityCheck.IsAccessible(projectDeclatation, callingModuleDeclatation, callingFunctionDeclaration, calleeFunctionDeclaration)); }
public void PrivateEnumsAreNotAccessibleFromOtherModules() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "callee_test_Module", true); var enumDeclarartion = GetTestEnum(calleeModuleDeclatation, "x", Accessibility.Private); var callingModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "calling_test_Module"); var functionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsFalse(AccessibilityCheck.IsAccessible(calleeProjectDeclatation, callingModuleDeclatation, functionDeclaration, enumDeclarartion)); }
public void StaticLocalMembersAreNotAcessibleFromOtherMethods() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateFunctionDeclaration = GetTestFunction(moduleDeclatation, "calleeFoo", Accessibility.Private); var localVariable = GetTestVariable(privateFunctionDeclaration, "x", Accessibility.Static); var otherPrivateFunctionDeclaration = GetTestFunction(moduleDeclatation, "callingFoo", Accessibility.Private); Assert.IsFalse(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, otherPrivateFunctionDeclaration, localVariable)); }
public void AccessibilityCheckDoesNotTakeIntoAccountThatAMemberMightNotBeAccessibleBecauseItIsCoveredByAnotherMemberInNarrowerScope() { var projectDeclatation = GetTestProject("test_project"); var moduleDeclatation = GetTestClassModule(projectDeclatation, "test_Module"); var privateInstanceVariable = GetTestVariable(moduleDeclatation, "x", Accessibility.Private); var privateFunctionDeclaration = GetTestFunction(moduleDeclatation, "foo", Accessibility.Private); var localVariable = GetTestVariable(privateFunctionDeclaration, "x", Accessibility.Implicit); //This variable makes the instance variable of the same name inaccessible inside the function. Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, moduleDeclatation, privateFunctionDeclaration, privateInstanceVariable)); }
public void ImplicitlyScopedInstanceVariablesAreNotAcessibleFromOtherModules() { var projectDeclatation = GetTestProject("test_project"); var calleeModuleDeclatation = GetTestClassModule(projectDeclatation, "callee_test_Module"); var instanceVariable = GetTestVariable(calleeModuleDeclatation, "x", Accessibility.Implicit); var callingModuleDeclatation = GetTestClassModule(projectDeclatation, "calliong_test_Module"); var functionDeclaration = GetTestFunction(callingModuleDeclatation, "foo", Accessibility.Private); Assert.IsFalse(AccessibilityCheck.IsAccessible(projectDeclatation, callingModuleDeclatation, functionDeclaration, instanceVariable)); }
public void FriendProceduresAreAcessibleFromOtherModulesInTheSameProject() { var projectDeclatation = GetTestProject("test_project"); var calleeModuleDeclatation = GetTestClassModule(projectDeclatation, "callee_test_Module"); var friendFunctionDeclaration = GetTestFunction(calleeModuleDeclatation, "calleeFoo", Accessibility.Friend); var callingModuleDeclatation = GetTestClassModule(projectDeclatation, "calling_test_Module"); var otherPrivateFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, callingModuleDeclatation, otherPrivateFunctionDeclaration, friendFunctionDeclaration)); }
public void PublicInstanceVariablesInNonPrivateProceduralModulesAreAcessibleFromTheSameProject() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestProceduralModule(calleeProjectDeclatation, "callee_test_Module"); var instanceVariable = GetTestVariable(calleeModuleDeclatation, "x", Accessibility.Public); var callingModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "calling_test_Module"); var otherPrivateFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(calleeProjectDeclatation, callingModuleDeclatation, otherPrivateFunctionDeclaration, instanceVariable)); }
public void ImplicitelyScopedUserTypesInNonPrivateProceduralModulesAreNotAcessibleFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestProceduralModule(calleeProjectDeclatation, "callee_test_Module"); var userType = GetTestUserType(calleeModuleDeclatation, "x", Accessibility.Implicit); var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var functionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, functionDeclaration, userType)); }
public void ImplicitelyScopedEnumsInExposedClassesAreAcessibleFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclaration = GetTestClassModule(calleeProjectDeclatation, "callee_test_Module", true); var enumDeclarartion = GetTestEnum(calleeModuleDeclaration, "x", Accessibility.Implicit); var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var functionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, functionDeclaration, enumDeclarartion)); }
public void UserTypeMembersInNonPrivateProceduralModulesAreNotAcessibleFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestProceduralModule(calleeProjectDeclatation, "callee_test_Module"); var instanceVariable = GetTestUserTypeMember(calleeModuleDeclatation, "x"); var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var otherPrivateFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, otherPrivateFunctionDeclaration, instanceVariable)); }
public void GlobalEnumsInNonPrivateProceduralModulesAreAccessibleFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestProceduralModule(calleeProjectDeclatation, "callee_test_Module"); var enumDeclarartion = GetTestEnum(calleeModuleDeclatation, "x", Accessibility.Global); var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var functionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, functionDeclaration, enumDeclarartion)); }
public void PublicProceduresInExposedClassModulesAreAcessibleFromOtherProjects() { var calleeProjectDeclatation = GetTestProject("callee_test_project"); var calleeModuleDeclatation = GetTestClassModule(calleeProjectDeclatation, "callee_test_Module", true); var calleeFunctionDeclaration = GetTestFunction(calleeModuleDeclatation, "calleeFoo", Accessibility.Public); var callingProjectDeclatation = GetTestProject("calling_test_project"); var callingModuleDeclatation = GetTestClassModule(callingProjectDeclatation, "calling_test_Module"); var otherPrivateFunctionDeclaration = GetTestFunction(callingModuleDeclatation, "callingFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(callingProjectDeclatation, callingModuleDeclatation, otherPrivateFunctionDeclaration, calleeFunctionDeclaration)); }
public void PrivateInstanceVariablesAreAccessibleIfTheyAreInAClassAboveTheEnclosingModuleOfTheCallerInTheClassHierarchy() { var projectDeclatation = GetTestProject("test_project"); var callingModule = GetTestClassModule(projectDeclatation, "callingModule"); var privateCallingFunction = GetTestFunction(callingModule, "callingFoo", Accessibility.Private); var supertypeOfCallingModule = GetTestClassModule(projectDeclatation, "callingModuleSuper"); callingModule.AddSupertype(supertypeOfCallingModule); var supertypeOfSupertypeOfCallingModule = GetTestClassModule(projectDeclatation, "callingModuleSuperSuper"); supertypeOfCallingModule.AddSupertype(supertypeOfSupertypeOfCallingModule); var privateCalleeInstanceVariable = GetTestVariable(supertypeOfSupertypeOfCallingModule, "calleeFoo", Accessibility.Private); Assert.IsTrue(AccessibilityCheck.IsAccessible(projectDeclatation, callingModule, privateCallingFunction, privateCalleeInstanceVariable)); }
/// <summary> /// Determines whether the 'Set' keyword is required (whether it's present or not) for the specified identifier reference. /// </summary> /// <param name="reference">The identifier reference to analyze</param> /// <param name="declarationFinderProvider">The parser state</param> public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider) { if (!reference.IsAssignment) { // reference isn't assigning its declaration; not interesting return(false); } if (reference.IsSetAssignment) { // don't assume Set keyword is legit... return(reference.Declaration.IsObject); } var declaration = reference.Declaration; if (declaration.IsArray) { // arrays don't need a Set statement... todo figure out if array items are objects return(false); } var isObjectVariable = declaration.IsObject; if (!isObjectVariable && !(declaration.IsUndeclared || Tokens.Variant.Equals(declaration.AsTypeName))) { return(false); } // For Each iterators are implicitly set. var letStmtContext = reference.Context.GetAncestor <VBAParser.LetStmtContext>(); if (reference.Context.GetAncestor <VBAParser.ForEachStmtContext>() != null && letStmtContext == null) { return(false); } if (isObjectVariable) { // get the members of the returning type, a default member could make us lie otherwise var classModule = declaration.AsTypeDeclaration as ClassModuleDeclaration; if (classModule?.DefaultMember == null) { return(true); } var parameters = (classModule.DefaultMember as IParameterizedDeclaration)?.Parameters; // assign declaration is an object without a default parameterless (or with all parameters optional) member - LHS needs a 'Set' keyword. return(parameters != null && parameters.All(p => p.IsOptional)); } // assigned declaration is a variant. we need to know about the RHS of the assignment. if (letStmtContext == null) { // not an assignment return(false); } var expression = letStmtContext.expression(); if (expression == null) { Debug.Assert(false, "RHS expression is empty? What's going on here?"); return(false); } if (expression is VBAParser.NewExprContext) { // RHS expression is newing up an object reference - LHS needs a 'Set' keyword: return(true); } var literalExpression = expression as VBAParser.LiteralExprContext; if (literalExpression?.literalExpression()?.literalIdentifier()?.objectLiteralIdentifier() != null) { // RHS is a 'Nothing' token - LHS needs a 'Set' keyword: return(true); } if (literalExpression != null) { return(false); // any other literal expression definitely isn't an object. } // todo resolve expression return type var project = Declaration.GetProjectParent(reference.ParentScoping); var module = Declaration.GetModuleParent(reference.ParentScoping); var simpleName = expression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleName != null) { return(declarationFinderProvider.DeclarationFinder.MatchName(simpleName.identifier().GetText()) .Any(d => AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, d) && d.IsObject)); } // is the reference referring to something else in scope that's a object? return(declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText()) .Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName)) && AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl))); }
public void ProjectsAreAlwaysAccessible() { var projectDeclatation = GetTestProject("test_project"); Assert.IsTrue(AccessibilityCheck.IsAccessible(null, null, null, projectDeclatation)); }
/// <summary> /// Determines whether the 'Set' keyword is required (whether it's present or not) for the specified identifier reference. /// </summary> /// <param name="reference">The identifier reference to analyze</param> /// <param name="declarationFinderProvider">The parser state</param> public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider) { if (!reference.IsAssignment) { // reference isn't assigning its declaration; not interesting return(false); } if (reference.IsSetAssignment) { // don't assume Set keyword is legit... return(reference.Declaration.IsObject); } var declaration = reference.Declaration; if (declaration.IsArray) { // arrays don't need a Set statement... todo figure out if array items are objects return(false); } var isObjectVariable = declaration.IsObject; if (!isObjectVariable && !(declaration.IsUndeclared || Tokens.Variant.Equals(declaration.AsTypeName))) { return(false); } // For Each iterators are implicitly set. var letStmtContext = reference.Context.GetAncestor <VBAParser.LetStmtContext>(); if (reference.Context.GetAncestor <VBAParser.ForEachStmtContext>() != null && letStmtContext == null) { return(false); } if (isObjectVariable) { // get the members of the returning type, a default member could make us lie otherwise var classModule = declaration.AsTypeDeclaration as ClassModuleDeclaration; return(!HasPotentiallyNonObjectParameterlessDefaultMember(classModule)); } // assigned declaration is a variant. we need to know about the RHS of the assignment. if (letStmtContext == null) { // not an assignment return(false); } var expression = letStmtContext.expression(); if (expression == null) { Debug.Assert(false, "RHS expression is empty? What's going on here?"); return(false); } var module = Declaration.GetModuleParent(reference.ParentScoping); if (expression is VBAParser.NewExprContext newExpr) { var newTypeExpression = newExpr.expression(); // todo resolve expression type //Covers the case of a single type on the RHS of the assignment. var simpleTypeName = newTypeExpression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleTypeName != null && simpleTypeName.GetText() == newTypeExpression.GetText()) { var qualifiedIdentifierSelection = new QualifiedSelection(module.QualifiedModuleName, simpleTypeName.identifier().GetSelection()); var identifierText = simpleTypeName.identifier().GetText(); return(declarationFinderProvider.DeclarationFinder.IdentifierReferences(qualifiedIdentifierSelection) .Select(identifierReference => identifierReference.Declaration) .Where(decl => identifierText == decl.IdentifierName) .OfType <ClassModuleDeclaration>() .Any(typeDecl => !HasPotentiallyNonObjectParameterlessDefaultMember(typeDecl))); } //Here, we err on the side of false-positives, but that seems more appropriate than not to treat qualified type expressions incorrectly. //Whether there is a legitimate use here for default members is questionable anyway. return(true); } var literalExpression = expression as VBAParser.LiteralExprContext; if (literalExpression?.literalExpression()?.literalIdentifier()?.objectLiteralIdentifier() != null) { // RHS is a 'Nothing' token - LHS needs a 'Set' keyword: return(true); } if (literalExpression != null) { return(false); // any other literal expression definitely isn't an object. } // todo resolve expression return type //Covers the case of a single variable on the RHS of the assignment. var simpleName = expression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleName != null && simpleName.GetText() == expression.GetText()) { var qualifiedIdentifierSelection = new QualifiedSelection(module.QualifiedModuleName, simpleName.identifier().GetSelection()); return(declarationFinderProvider.DeclarationFinder.IdentifierReferences(qualifiedIdentifierSelection) .Select(identifierReference => identifierReference.Declaration) .Where(decl => decl.IsObject && simpleName.identifier().GetText() == decl.IdentifierName) .Select(typeDeclaration => typeDeclaration.AsTypeDeclaration as ClassModuleDeclaration) .Any(typeDecl => !HasPotentiallyNonObjectParameterlessDefaultMember(typeDecl))); } var project = Declaration.GetProjectParent(reference.ParentScoping); //todo: Use code path analysis to ensure that we are really picking up the last assignment to the RHS. // is the reference referring to something else in scope that's a object? return(declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText()) .Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName)) && AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl))); }