From 52322bf02d2514b64ce5bdfcd2eb7811380be92f Mon Sep 17 00:00:00 2001 From: Mathieu Guindon Date: Mon, 20 Jan 2025 03:11:45 -0500 Subject: [PATCH] fixes #6200 --- .../ObjectVariableNotSetInspection.cs | 5 ++- Rubberduck.Parsing/Symbols/Declaration.cs | 30 +++++++------ .../Symbols/ParameterDeclaration.cs | 10 ++--- RubberduckTests/Grammar/ResolverTests.cs | 44 +++++++++++++------ .../ObjectVariableNotSetInspectionTests.cs | 33 +++++++++++++- 5 files changed, 87 insertions(+), 35 deletions(-) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ObjectVariableNotSetInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ObjectVariableNotSetInspection.cs index 836f4c3ce1..3a9b94c878 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ObjectVariableNotSetInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ObjectVariableNotSetInspection.cs @@ -60,7 +60,7 @@ protected override IEnumerable ReferencesInModule(Qualified private static IEnumerable FailedLetResolutionAssignments(QualifiedModuleName module, DeclarationFinder finder) { return finder.FailedLetCoercions(module) - .Where(reference => reference.IsAssignment); + .Where(reference => reference.IsAssignment && !reference.Declaration.IsArray); } private static IEnumerable PossiblyObjectLhsLetAssignmentsWithNonValueOnRhs(QualifiedModuleName module, DeclarationFinder finder) @@ -89,11 +89,12 @@ private static IEnumerable PossiblyObjectNonSetAssignments( { var assignments = finder.IdentifierReferences(module) .Where(reference => reference.IsAssignment + && !reference.Declaration.IsArray && !reference.IsSetAssignment && (reference.IsNonIndexedDefaultMemberAccess || Tokens.Variant.Equals(reference.Declaration.AsTypeName, StringComparison.InvariantCultureIgnoreCase))); var unboundAssignments = finder.UnboundDefaultMemberAccesses(module) - .Where(reference => reference.IsAssignment); + .Where(reference => reference.IsAssignment && !reference.Declaration.IsArray); return assignments.Concat(unboundAssignments); } diff --git a/Rubberduck.Parsing/Symbols/Declaration.cs b/Rubberduck.Parsing/Symbols/Declaration.cs index 4fcea4a729..89de2c658c 100644 --- a/Rubberduck.Parsing/Symbols/Declaration.cs +++ b/Rubberduck.Parsing/Symbols/Declaration.cs @@ -1,5 +1,6 @@ using Antlr4.Runtime; using Rubberduck.Parsing.Annotations; +using Rubberduck.Parsing.Annotations.Concrete; using Rubberduck.Parsing.ComReflection; using Rubberduck.Parsing.Grammar; using Rubberduck.VBEditor; @@ -8,7 +9,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using Rubberduck.Parsing.Annotations.Concrete; namespace Rubberduck.Parsing.Symbols { @@ -117,7 +117,7 @@ public Declaration( IEnumerable annotations = null, Attributes attributes = null) { - QualifiedName = qualifiedName; + QualifiedName = qualifiedName; ParentDeclaration = parentDeclaration; ParentScopeDeclaration = ParentDeclaration; ParentScope = parentScope ?? string.Empty; @@ -145,7 +145,7 @@ public Declaration( ProjectName = IdentifierName; } - IsArray = isArray; + IsArray = isArray || AsTypeName != null && (AsTypeNameWithoutArrayDesignator.Length == AsTypeName.Length - "()".Length); AsTypeContext = asTypeContext; TypeHint = typeHint; } @@ -168,7 +168,8 @@ public Declaration(ComEnumeration enumeration, Declaration parent, QualifiedModu null, false, null, - new Attributes()) { } + new Attributes()) + { } public Declaration(ComStruct structure, Declaration parent, QualifiedModuleName module) : this( @@ -188,7 +189,8 @@ public Declaration(ComStruct structure, Declaration parent, QualifiedModuleName null, false, null, - new Attributes()) { } + new Attributes()) + { } public Declaration(ComEnumerationMember member, Declaration parent, QualifiedModuleName module) : this( module.QualifyMemberName(member.Name), @@ -207,7 +209,8 @@ public Declaration(ComEnumerationMember member, Declaration parent, QualifiedMod null, false, null, - new Attributes()) { } + new Attributes()) + { } public Declaration(ComField field, Declaration parent, QualifiedModuleName module) : this( @@ -227,7 +230,8 @@ public Declaration(ComField field, Declaration parent, QualifiedModuleName modul null, false, null, - new Attributes()) { } + new Attributes()) + { } public static Declaration GetModuleParent(Declaration declaration) { @@ -289,8 +293,8 @@ public string DescriptionString { string literalDescription; - var memberAttribute = Attributes.SingleOrDefault(a => - a.Name == Attributes.MemberAttributeName("VB_Description", IdentifierName) || + var memberAttribute = Attributes.SingleOrDefault(a => + a.Name == Attributes.MemberAttributeName("VB_Description", IdentifierName) || a.Name == Attributes.MemberAttributeName("VB_VarDescription", IdentifierName)); if (memberAttribute != null) @@ -323,10 +327,10 @@ public string DescriptionString private static string CorrectlyFormatedDescription(string literalDescription) { - if (string.IsNullOrEmpty(literalDescription) - || literalDescription.Length < 2 + if (string.IsNullOrEmpty(literalDescription) + || literalDescription.Length < 2 || literalDescription[0] != '"' - || literalDescription[literalDescription.Length -1] != '"') + || literalDescription[literalDescription.Length - 1] != '"') { return literalDescription; } @@ -350,7 +354,7 @@ private bool IsObjectOrObjectArray { get { - if (AsTypeName == Tokens.Object + if (AsTypeName == Tokens.Object || (AsTypeDeclaration?.DeclarationType.HasFlag(DeclarationType.ClassModule) ?? false)) { return true; diff --git a/Rubberduck.Parsing/Symbols/ParameterDeclaration.cs b/Rubberduck.Parsing/Symbols/ParameterDeclaration.cs index 64a73cba5a..b8d48b1dbe 100644 --- a/Rubberduck.Parsing/Symbols/ParameterDeclaration.cs +++ b/Rubberduck.Parsing/Symbols/ParameterDeclaration.cs @@ -1,6 +1,3 @@ -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; using Antlr4.Runtime; using Rubberduck.Parsing.Annotations; using Rubberduck.Parsing.Binding; @@ -8,6 +5,9 @@ using Rubberduck.Parsing.Grammar; using Rubberduck.Parsing.VBA.Extensions; using Rubberduck.VBEditor; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; namespace Rubberduck.Parsing.Symbols { @@ -39,7 +39,7 @@ public ParameterDeclaration(QualifiedMemberName qualifiedName, null, null, Selection.Home, - isArray, + isArray || isParamArray, asTypeContext, false) { @@ -78,7 +78,7 @@ public ParameterDeclaration(QualifiedMemberName qualifiedName, context, null, selection, - isArray, + isArray || isParamArray, asTypeContext, isUserDefined) { diff --git a/RubberduckTests/Grammar/ResolverTests.cs b/RubberduckTests/Grammar/ResolverTests.cs index a3ba8b07c7..4d2fa74f77 100644 --- a/RubberduckTests/Grammar/ResolverTests.cs +++ b/RubberduckTests/Grammar/ResolverTests.cs @@ -1,17 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; using NUnit.Framework; using Rubberduck.InternalApi.Extensions; +using Rubberduck.Parsing.Annotations.Concrete; using Rubberduck.Parsing.Symbols; using Rubberduck.Parsing.VBA; -using RubberduckTests.Mocks; -using Rubberduck.Parsing.Annotations; -using Rubberduck.Parsing.Annotations.Concrete; using Rubberduck.VBEditor; using Rubberduck.VBEditor.SafeComWrappers; using Rubberduck.VBEditor.SafeComWrappers.Abstract; +using RubberduckTests.Mocks; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; namespace RubberduckTests.Grammar { @@ -120,6 +119,23 @@ End Sub } } + [Category("Resolver")] + [Test] + public void ParamArrayParameter_IsArray() + { + var code = @"Option Explicit + +Public Sub Test(ParamArray Values) +End Sub +"; + using (var state = Resolve(code)) + { + var declaration = state.AllUserDeclarations.Single(item => item.DeclarationType == DeclarationType.Parameter && item.IdentifierName == "Values") as ParameterDeclaration; + Assert.IsTrue(declaration.IsParamArray); + Assert.IsTrue(declaration.IsArray); + } + } + [Category("Resolver")] [Test] public void OptionalParameterDefaultConstValue_IsReferenceToDeclaredConst() @@ -1017,7 +1033,7 @@ End Sub item.DeclarationType == DeclarationType.Variable && item.IdentifierName == "foo"); - Assert.AreEqual(1,declaration.References.Count(item => + Assert.AreEqual(1, declaration.References.Count(item => item.ParentScoping.DeclarationType == DeclarationType.Procedure && item.ParentScoping.IdentifierName == "DoSomething" && item.IsAssignment)); @@ -2278,7 +2294,7 @@ End Sub var printReference = printDeclaration.References.Single(); var module = state.DeclarationFinder.AllModules.Single(qmn => qmn.ComponentType == ComponentType.ClassModule); - var expectedPrintSelection = new QualifiedSelection(module, new Selection(4, 5,4, 10)); + var expectedPrintSelection = new QualifiedSelection(module, new Selection(4, 5, 4, 10)); var actualPrintSelection = new QualifiedSelection(printReference.QualifiedModuleName, printReference.Selection); Assert.AreEqual(4, referencedDeclaration.References.Count()); @@ -3632,7 +3648,7 @@ End Function Assert.AreEqual(expectedReferencedDeclarationName, actualReferencedDeclarationName); Assert.IsTrue(reference.IsIndexedDefaultMemberAccess); - Assert.AreEqual(2,reference.DefaultMemberRecursionDepth); + Assert.AreEqual(2, reference.DefaultMemberRecursionDepth); } } @@ -3832,7 +3848,7 @@ End Function { var module = state.DeclarationFinder.AllModules.First(qmn => qmn.ComponentName == "Module1"); var defaultMemberAccess = state.DeclarationFinder.UnboundDefaultMemberAccesses(module).First(); - + var expectedReferencedSelection = new QualifiedSelection(module, selection); var actualReferencedSelection = new QualifiedSelection(defaultMemberAccess.QualifiedModuleName, defaultMemberAccess.Selection); @@ -5703,7 +5719,7 @@ End Function .Single(param => param.IdentifierName.Equals("furtherArgs")); var argumentReferences = parameter.ArgumentReferences; - var expectedExpressionTexts = new HashSet{"4", "5", "6"}; + var expectedExpressionTexts = new HashSet { "4", "5", "6" }; var actualExpressionTexts = argumentReferences.Select(reference => reference.Context.GetText()).ToList(); var expectedCount = expectedExpressionTexts.Count; @@ -7334,7 +7350,7 @@ End Sub var undeclared = finder.Members(module.QualifiedModuleName) .Where(declaration => declaration.IsUndeclared) .ToList(); - + Assert.AreEqual(4, undeclared.Count); } } @@ -7402,7 +7418,7 @@ End Sub using (var state = Resolve(vbe.Object)) { var finder = state.DeclarationFinder; - + var classModule = finder.UserDeclarations(DeclarationType.ClassModule).Single(); var barDeclaration = finder.Members(classModule.QualifiedModuleName, DeclarationType.Function).Single(); var barReference = barDeclaration.References.Single(); diff --git a/RubberduckTests/Inspections/ObjectVariableNotSetInspectionTests.cs b/RubberduckTests/Inspections/ObjectVariableNotSetInspectionTests.cs index 691683245a..185e4ab1c0 100644 --- a/RubberduckTests/Inspections/ObjectVariableNotSetInspectionTests.cs +++ b/RubberduckTests/Inspections/ObjectVariableNotSetInspectionTests.cs @@ -1,4 +1,3 @@ -using System.Linq; using NUnit.Framework; using Rubberduck.CodeAnalysis.Inspections; using Rubberduck.CodeAnalysis.Inspections.Concrete; @@ -6,6 +5,7 @@ using Rubberduck.VBEditor; using Rubberduck.VBEditor.SafeComWrappers; using RubberduckTests.Mocks; +using System.Linq; namespace RubberduckTests.Inspections { @@ -210,6 +210,37 @@ Dim target As Variant AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount); } + [Test] + [Category("Inspections")] + public void ObjectVariableNotSet_GivenObjectArray_ReturnsNoResult() + { + var expectResultCount = 0; + var input = +@" +Private myObjectArray() As Object + +Public Property Get ObjectArray() As Object() + ObjectArray = myObjectArray +End Property + + +Public Sub Test() + + Dim oArr1(0) As Object + Set oArr1(0) = New Something + + myObjectArray = oArr1 + + Dim oArr2() As Object + oArr2 = ObjectArray + + Debug.Print oArr2(0).Name + +End Sub +"; + AssertInputCodeYieldsExpectedInspectionResultCount(input, expectResultCount); + } + [Test] [Category("Inspections")] public void ObjectVariableNotSet_GivenObjectVariableNotSet_Ignored_DoesNotReturnResult()