Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/next' into Issue5395_Filters_f…
Browse files Browse the repository at this point in the history
…or_synchronizing_document_types
  • Loading branch information
IvenBach committed Apr 19, 2021
2 parents cff0958 + b341d6e commit 17e72f5
Show file tree
Hide file tree
Showing 27 changed files with 930 additions and 1,598 deletions.
Expand Up @@ -34,13 +34,13 @@ protected override IEnumerable<Declaration> ObjectionableDeclarations(Declaratio
&& declaration.AsTypeName == "Range");
}

private static readonly string[] GlobalObjectClassNames =
protected virtual string[] GlobalObjectClassNames => new[]
{
"Global", "_Global",
"Worksheet", "_Worksheet"
};

private static readonly string[] TargetMemberNames =
protected virtual string[] TargetMemberNames => new[]
{
"Cells", "Range", "Columns", "Rows"
};
Expand Down
Expand Up @@ -47,10 +47,13 @@ public ImplicitActiveSheetReferenceInspection(IDeclarationFinderProvider declara
: base(declarationFinderProvider)
{}

protected override string[] GlobalObjectClassNames => new[] { "Global", "_Global", };

protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder)
{
return !(Declaration.GetModuleParent(reference.ParentNonScoping) is DocumentModuleDeclaration document)
var result = !(Declaration.GetModuleParent(reference.ParentNonScoping) is DocumentModuleDeclaration document)
|| !document.SupertypeNames.Contains("Worksheet");
return result;
}

protected override string ResultDescription(IdentifierReference reference)
Expand Down
Expand Up @@ -3,6 +3,7 @@
using Rubberduck.CodeAnalysis.Inspections.Abstract;
using Rubberduck.CodeAnalysis.Inspections.Attributes;
using Rubberduck.Common;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
Expand Down Expand Up @@ -59,41 +60,104 @@ public SheetAccessedUsingStringInspection(IDeclarationFinderProvider declaration
_projectsProvider = projectsProvider;
}

private static readonly string[] InterestingMembers =
/// <summary>
/// We're interested in both explicitly and implicitly bound retrievals from a Sheets collection.
/// </summary>
private static readonly string[] InterestingProperties =
{
"Worksheets", // gets a Sheets object containing Worksheet objects.
"Sheets", // gets a Sheets object containing all sheets (not just Worksheet sheets) in the qualifying workbook.
};

private static readonly string[] InterestingClasses =
{
"Workbook", // unqualified member call
"_Workbook", // qualified member call
"Item", // explicit member call
"_Default", // default member call (usually implicit)
};

protected override IEnumerable<Declaration> ObjectionableDeclarations(DeclarationFinder finder)
{
if (!finder.TryFindProjectDeclaration("Excel", out var excel))
{
return Enumerable.Empty<Declaration>();
// [RequiredHost] attribute puts this in "should not happen" territory.
yield break;
}
var sheetsClass = (ModuleDeclaration)finder.FindClassModule("Sheets", excel, true);
if (sheetsClass == null)
{
// [RequiredHost] attribute puts this in "should not happen" territory.
yield break;
}

var relevantClasses = InterestingClasses
.Select(className => finder.FindClassModule(className, excel, true))
.OfType<ModuleDeclaration>();
if (sheetsClass != null)
{
foreach (var property in sheetsClass.Members.OfType<PropertyDeclaration>())
{
if (InterestingProperties.Any(name => name.Equals(property.IdentifierName, System.StringComparison.InvariantCultureIgnoreCase)))
{
yield return property;
}
}
}
}

var relevantProperties = relevantClasses
.SelectMany(classDeclaration => classDeclaration.Members)
.OfType<PropertyDeclaration>()
.Where(member => InterestingMembers.Contains(member.IdentifierName));
private static ClassModuleDeclaration GetHostWorkbookDeclaration(DeclarationFinder finder)
{
var documentModuleQMNs = finder.AllModules.Where(m => m.ComponentType == ComponentType.Document);
ClassModuleDeclaration result = null;
foreach (var qmn in documentModuleQMNs)
{
var declaration = finder.ModuleDeclaration(qmn) as ClassModuleDeclaration;
if (declaration.Supertypes.Any(t => t.IdentifierName.Equals("Workbook") && t.ProjectName == "Excel" && !t.IsUserDefined))
{
result = declaration;
break;
}
}

return result ?? throw new System.InvalidOperationException("Failed to find the host Workbook declaration.");
}

return relevantProperties;
private static ClassModuleDeclaration GetHostApplicationDeclaration(DeclarationFinder finder)
{
var result = finder.MatchName("Application").OfType<ClassModuleDeclaration>().FirstOrDefault(t => t.ProjectName == "Excel" && !t.IsUserDefined) as ClassModuleDeclaration;
return result ?? throw new System.InvalidOperationException("Failed to find the host Application declaration.");
}

protected override (bool isResult, string properties) IsResultReferenceWithAdditionalProperties(IdentifierReference reference, DeclarationFinder finder)
{
var sheetNameArgumentLiteralExpressionContext = SheetNameArgumentLiteralExpressionContext(reference);
if (reference.IdentifierName.Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase))
{
// if Me is a worksheet module,
return (false, null);
}

var hostWorkbookDeclaration = GetHostWorkbookDeclaration(finder);

var context = reference.Context as VBAParser.MemberAccessExprContext
?? reference.Context.Parent as VBAParser.MemberAccessExprContext
?? reference.Context.Parent.Parent as VBAParser.MemberAccessExprContext;

if (context is VBAParser.MemberAccessExprContext memberAccess)
{
var appObjectDeclaration = GetHostApplicationDeclaration(finder);
var isApplicationQualifier = appObjectDeclaration.References.Any(appRef =>
context.GetSelection().Contains(appRef.Selection)
&& appRef.QualifiedModuleName.Equals(reference.QualifiedModuleName));

if (isApplicationQualifier)
{
// Application.Sheets(...) is referring to the ActiveWorkbook, not necessarily ThisWorkbook.
return (false, null);
}
}

var isHostWorkbookQualifier = hostWorkbookDeclaration.References.Any(thisWorkbookRef =>
context.GetSelection().Contains(thisWorkbookRef.Selection)
&& thisWorkbookRef.QualifiedModuleName.Equals(reference.QualifiedModuleName));

var parentModule = finder.ModuleDeclaration(reference.QualifiedModuleName);
if (!isHostWorkbookQualifier && parentModule is ProceduralModuleDeclaration)
{
// in a standard module the reference is against ActiveWorkbook unless it's explicitly against ThisWorkbook.
return (false, null);
}

var sheetNameArgumentLiteralExpressionContext = SheetNameArgumentLiteralExpressionContext(reference);
if (sheetNameArgumentLiteralExpressionContext?.STRINGLITERAL() == null)
{
return (false, null);
Expand Down
10 changes: 10 additions & 0 deletions Rubberduck.Core/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Rubberduck.Core/Properties/Resources.resx
Expand Up @@ -117,4 +117,8 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Splash2021f" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Splash2021f.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file added Rubberduck.Core/Resources/Splash2021f.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 12 additions & 1 deletion Rubberduck.Core/Rubberduck.Core.csproj
Expand Up @@ -5,7 +5,7 @@
<AssemblyName>Rubberduck.Core</AssemblyName>
<Title>Rubberduck.Core</Title>
<Product>Rubberduck.Core</Product>
<Copyright>Copyright © 2014-2019</Copyright>
<Copyright>Copyright © 2014-2021</Copyright>
<ProjectGuid>{A1587EAC-7B54-407E-853F-4C7493D0323E}</ProjectGuid>
<DocumentationFile>bin\Debug\Rubberduck.Core.xml</DocumentationFile>
<!-- Disable "Missing XML documentation" warning (CS1591) -->
Expand Down Expand Up @@ -92,6 +92,17 @@
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
Expand Down
18 changes: 0 additions & 18 deletions Rubberduck.Core/UI/Splash.cs

This file was deleted.

0 comments on commit 17e72f5

Please sign in to comment.