Skip to content

Commit 0692667

Browse files
authored
Merge pull request #4529 from retailcoder/bugfix
last-minute fixes
2 parents 588cb23 + 8a0d7dd commit 0692667

25 files changed

+496
-66
lines changed

Rubberduck.CodeAnalysis/Inspections/Concrete/NonReturningFunctionInspection.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Linq;
33
using Rubberduck.Inspections.Abstract;
44
using Rubberduck.Inspections.Results;
5+
using Rubberduck.Parsing;
56
using Rubberduck.Parsing.Grammar;
67
using Rubberduck.Parsing.Inspections.Abstract;
78
using Rubberduck.Resources.Inspections;
@@ -34,7 +35,8 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
3435
var unassigned = (from function in functions
3536
let isUdt = IsReturningUserDefinedType(function)
3637
let inScopeRefs = function.References.Where(r => r.ParentScoping.Equals(function))
37-
where (!isUdt && (!inScopeRefs.Any(r => r.IsAssignment)))
38+
where (!isUdt && (!inScopeRefs.Any(r => r.IsAssignment) &&
39+
!inScopeRefs.Any(reference => IsAssignedByRefArgument(function, reference))))
3840
|| (isUdt && !IsUserDefinedTypeAssigned(function))
3941
select function)
4042
.ToList();
@@ -46,6 +48,17 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
4648
issue));
4749
}
4850

51+
private bool IsAssignedByRefArgument(Declaration enclosingProcedure, IdentifierReference reference)
52+
{
53+
var argExpression = reference.Context.GetAncestor<VBAParser.ArgumentExpressionContext>();
54+
var parameter = State.DeclarationFinder.FindParameterFromArgument(argExpression, enclosingProcedure);
55+
56+
// note: not recursive, by design.
57+
return parameter != null
58+
&& (parameter.IsImplicitByRef || parameter.IsByRef)
59+
&& parameter.References.Any(r => r.IsAssignment);
60+
}
61+
4962
private bool IsReturningUserDefinedType(Declaration member)
5063
{
5164
return member.AsTypeDeclaration != null &&

Rubberduck.CodeAnalysis/Inspections/Concrete/UnassignedVariableUsageInspection.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
4141

4242
return declarations
4343
.Where(d => d.References.Any() && !excludedDeclarations.Any(excl => DeclarationReferencesContainsReference(excl, d)))
44-
.SelectMany(d => d.References)
44+
.SelectMany(d => d.References.Where(r => !IsAssignedByRefArgument(r.ParentScoping, r)))
4545
.Distinct()
4646
.Where(r => !r.IsIgnoringInspectionResultFor(AnnotationName))
4747
.Where(r => !r.Context.TryGetAncestor<VBAParser.RedimStmtContext>(out _) && !IsArraySubscriptAssignment(r))
@@ -51,6 +51,17 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
5151
r)).ToList();
5252
}
5353

54+
private bool IsAssignedByRefArgument(Declaration enclosingProcedure, IdentifierReference reference)
55+
{
56+
var argExpression = reference.Context.GetAncestor<VBAParser.ArgumentExpressionContext>();
57+
var parameter = State.DeclarationFinder.FindParameterFromArgument(argExpression, enclosingProcedure);
58+
59+
// note: not recursive, by design.
60+
return parameter != null
61+
&& (parameter.IsImplicitByRef || parameter.IsByRef)
62+
&& parameter.References.Any(r => r.IsAssignment);
63+
}
64+
5465
private static bool IsArraySubscriptAssignment(IdentifierReference reference)
5566
{
5667
var isLetAssignment = reference.Context.TryGetAncestor<VBAParser.LetStmtContext>(out var letStmt);

Rubberduck.CodeAnalysis/Inspections/Concrete/VariableNotAssignedInspection.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Linq;
33
using Rubberduck.Inspections.Abstract;
44
using Rubberduck.Inspections.Results;
5+
using Rubberduck.Parsing;
6+
using Rubberduck.Parsing.Grammar;
57
using Rubberduck.Parsing.Inspections.Abstract;
68
using Rubberduck.Resources.Inspections;
79
using Rubberduck.Parsing.Symbols;
@@ -25,11 +27,22 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
2527
!declaration.IsWithEvents
2628
&& State.DeclarationFinder.MatchName(declaration.AsTypeName).All(item => item.DeclarationType != DeclarationType.UserDefinedType) // UDT variables don't need to be assigned
2729
&& !declaration.IsSelfAssigned
28-
&& !declaration.References.Any(reference => reference.IsAssignment))
30+
&& !declaration.References.Any(reference => reference.IsAssignment || IsAssignedByRefArgument(reference.ParentScoping, reference)))
2931
.Where(result => !IsIgnoringInspectionResultFor(result, AnnotationName));
3032

3133
return declarations.Select(issue =>
3234
new DeclarationInspectionResult(this, string.Format(InspectionResults.VariableNotAssignedInspection, issue.IdentifierName), issue));
3335
}
36+
37+
private bool IsAssignedByRefArgument(Declaration enclosingProcedure, IdentifierReference reference)
38+
{
39+
var argExpression = reference.Context.GetAncestor<VBAParser.ArgumentExpressionContext>();
40+
var parameter = State.DeclarationFinder.FindParameterFromArgument(argExpression, enclosingProcedure);
41+
42+
// note: not recursive, by design.
43+
return parameter != null
44+
&& (parameter.IsImplicitByRef || parameter.IsByRef)
45+
&& parameter.References.Any(r => r.IsAssignment);
46+
}
3447
}
3548
}

Rubberduck.CodeAnalysis/Inspections/Concrete/VariableRequiresSetAssignmentEvaluator.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public static bool RequiresSetAssignment(IdentifierReference reference, IDeclara
7272
if (expression == null)
7373
{
7474
Debug.Assert(false, "RHS expression is empty? What's going on here?");
75+
return false;
7576
}
7677

7778
if (expression is VBAParser.NewExprContext)
@@ -86,25 +87,24 @@ public static bool RequiresSetAssignment(IdentifierReference reference, IDeclara
8687
// RHS is a 'Nothing' token - LHS needs a 'Set' keyword:
8788
return true;
8889
}
90+
if (literalExpression != null)
91+
{
92+
return false; // any other literal expression definitely isn't an object.
93+
}
8994

9095
// todo resolve expression return type
96+
var project = Declaration.GetProjectParent(reference.ParentScoping);
97+
var module = Declaration.GetModuleParent(reference.ParentScoping);
9198

92-
var memberRefs = declarationFinderProvider.DeclarationFinder.IdentifierReferences(reference.ParentScoping.QualifiedName);
93-
var lastRef = memberRefs.LastOrDefault(r => !Equals(r, reference) && r.Context.GetAncestor<VBAParser.LetStmtContext>() == letStmtContext);
94-
if (lastRef?.Declaration.AsTypeDeclaration?.DeclarationType.HasFlag(DeclarationType.ClassModule) ?? false)
99+
var simpleName = expression.GetDescendent<VBAParser.SimpleNameExprContext>();
100+
if (simpleName != null)
95101
{
96-
// the last reference in the expression is referring to an object type
97-
return true;
98-
}
99-
if (lastRef?.Declaration.AsTypeName == Tokens.Object)
100-
{
101-
return true;
102+
return declarationFinderProvider.DeclarationFinder.MatchName(simpleName.identifier().GetText())
103+
.Any(d => AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, d) && d.IsObject);
102104
}
103105

104106
// is the reference referring to something else in scope that's a object?
105-
var project = Declaration.GetProjectParent(reference.ParentScoping);
106-
var module = Declaration.GetModuleParent(reference.ParentScoping);
107-
return declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText().ToLowerInvariant())
107+
return declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText())
108108
.Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName))
109109
&& AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl));
110110
}

Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override void Fix(IInspectionResult result, IRewriteSession rewriteSessio
3333

3434
int annotationLine;
3535
//TODO: Make this use the parse tree instead of the code module.
36-
using (var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName))
36+
var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName);
3737
using (var module = component.CodeModule)
3838
{
3939
annotationLine = result.QualifiedSelection.Selection.StartLine;

Rubberduck.CodeAnalysis/QuickFixes/UseSetKeywordForObjectAssignmentQuickFix.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using Rubberduck.Inspections.Abstract;
22
using Rubberduck.Inspections.Concrete;
3+
using Rubberduck.Parsing;
4+
using Rubberduck.Parsing.Grammar;
35
using Rubberduck.Parsing.Inspections.Abstract;
46
using Rubberduck.Parsing.Rewriter;
57

@@ -14,7 +16,16 @@ public UseSetKeywordForObjectAssignmentQuickFix()
1416
public override void Fix(IInspectionResult result, IRewriteSession rewriteSession)
1517
{
1618
var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName);
17-
rewriter.InsertBefore(result.Context.Start.TokenIndex, "Set ");
19+
var letStmt = result.Context.GetAncestor<VBAParser.LetStmtContext>();
20+
var letToken = letStmt.LET();
21+
if (letToken != null)
22+
{
23+
rewriter.Replace(letToken, "Set");
24+
}
25+
else
26+
{
27+
rewriter.InsertBefore(letStmt.Start.TokenIndex, "Set ");
28+
}
1829
}
1930

2031
public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.SetObjectVariableQuickFix;

Rubberduck.Core/UI/Controls/NumberPicker.xaml.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.ComponentModel;
33
using System.Windows;
4+
using Rubberduck.Settings;
45

56
// credit to http://stackoverflow.com/a/2752538
67
namespace Rubberduck.UI.Controls
@@ -11,19 +12,40 @@ namespace Rubberduck.UI.Controls
1112
public partial class NumberPicker : IDataErrorInfo
1213
{
1314
public static readonly DependencyProperty NumValueProperty =
14-
DependencyProperty.Register("NumValue", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null));
15+
DependencyProperty.Register(nameof(NumValue), typeof(int), typeof(NumberPicker), new UIPropertyMetadata(default(int), PropertyChangedCallback));
1516
public static readonly DependencyProperty MinNumberProperty =
16-
DependencyProperty.Register("MinNumber", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null));
17+
DependencyProperty.Register(nameof(MinNumber), typeof(int), typeof(NumberPicker), new UIPropertyMetadata(default(int), PropertyChangedCallback));
1718
public static readonly DependencyProperty MaxNumberProperty =
18-
DependencyProperty.Register("MaxNumber", typeof(int), typeof(NumberPicker), new UIPropertyMetadata(null));
19+
DependencyProperty.Register(nameof(MaxNumber), typeof(int), typeof(NumberPicker), new UIPropertyMetadata(default(int), PropertyChangedCallback));
20+
21+
private static void PropertyChangedCallback(DependencyObject source, DependencyPropertyChangedEventArgs args)
22+
{
23+
if (source is NumberPicker control)
24+
{
25+
var newValue = (int) args.NewValue;
26+
switch (args.Property.Name)
27+
{
28+
case "NumValue":
29+
control.NumValue = newValue;
30+
break;
31+
case "MinNumber":
32+
control.MinNumber = newValue;
33+
break;
34+
case "MaxNumber":
35+
control.MaxNumber = newValue;
36+
break;
37+
}
38+
}
39+
}
1940

2041
public int NumValue
2142
{
2243
get => (int)GetValue(NumValueProperty);
2344
set
2445
{
46+
var old = GetValue(MinNumberProperty);
2547
SetValue(NumValueProperty, value);
26-
OnPropertyChanged(new DependencyPropertyChangedEventArgs(NumValueProperty, NumValue - 1, NumValue));
48+
OnPropertyChanged(new DependencyPropertyChangedEventArgs(NumValueProperty, old, value));
2749
}
2850
}
2951

Rubberduck.Core/UI/Settings/AutoCompleteSettings.xaml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,11 +112,24 @@
112112
Content="{Resx ResxName=Rubberduck.Resources.Settings.AutoCompletesPage, Key=ConcatVbNewLine}" />
113113

114114
<Label Margin="15,0,15,0" Content="{Resx ResxName=Rubberduck.Resources.Settings.AutoCompletesPage, Key=MaxConcatLines}" />
115-
<controls:NumberPicker Margin="15,0,15,0"
116-
NumValue="{Binding ConcatMaxLines}"
117-
MinNumber="{Binding ConcatMaxLinesMinValue}"
118-
MaxNumber="{Binding ConcatMaxLinesMaxValue}"/>
115+
<StackPanel Orientation="Horizontal" Margin="15,0,15,0">
116+
<TextBox Margin="5,5,0,5" Height="24" Width="50" Text="{Binding ConcatMaxLines, Mode=TwoWay, StringFormat=\{0:D\}, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" VerticalAlignment="Top" VerticalContentAlignment="Center" />
117+
<StackPanel Margin="0,5" >
118+
<Button Height="12" Width="20" Command="{Binding IncrementMaxConcatLinesCommand}">
119+
<TextBlock Text="" FontSize="10" Margin="0,-4,0,0"/>
120+
</Button>
121+
<Button Height="12" Width="20" Command="{Binding DecrementMaxConcatLinesCommand}">
122+
<TextBlock Text="" FontSize="10" Margin="0,-3,0,0"/>
123+
</Button>
124+
</StackPanel>
125+
</StackPanel>
119126

127+
<!--<controls:NumberPicker Margin="15,0,15,0" DataContext="{Binding Path=DataContext, Mode=OneWay, NotifyOnTargetUpdated=True, NotifyOnSourceUpdated=True, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type settings:AutoCompleteSettings}}}"
128+
NumValue="{Binding Path=DataContext.ConcatMaxLines, RelativeSource={RelativeSource Self}, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
129+
MinNumber="{Binding Path=DataContext.ConcatMaxLinesMinValue, RelativeSource={RelativeSource Self}}"
130+
MaxNumber="{Binding Path=DataContext.ConcatMaxLinesMaxValue, RelativeSource={RelativeSource Self}}">
131+
132+
</controls:NumberPicker>-->
120133
<Label Margin="10"
121134
Content="{Resx ResxName=Rubberduck.Resources.Settings.AutoCompletesPage, Key=BlockCompletion}"
122135
FontWeight="Bold" />

Rubberduck.Core/UI/Settings/AutoCompleteSettingsViewModel.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using NLog;
1+
using System.Windows.Input;
2+
using NLog;
23
using Rubberduck.Resources;
34
using Rubberduck.Resources.Settings;
45
using Rubberduck.Settings;
@@ -14,8 +15,21 @@ public AutoCompleteSettingsViewModel(Configuration config)
1415
TransferSettingsToView(config.UserSettings.AutoCompleteSettings);
1516
ExportButtonCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ => ExportSettings());
1617
ImportButtonCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ => ImportSettings());
18+
19+
IncrementMaxConcatLinesCommand = new DelegateCommand(null, ExecuteIncrementMaxConcatLines, CanExecuteIncrementMaxConcatLines);
20+
DecrementMaxConcatLinesCommand = new DelegateCommand(null, ExecuteDecrementMaxConcatLines, CanExecuteDecrementMaxConcatLines);
1721
}
1822

23+
public ICommand IncrementMaxConcatLinesCommand { get; }
24+
25+
private bool CanExecuteIncrementMaxConcatLines(object parameter) => ConcatMaxLines < ConcatMaxLinesMaxValue;
26+
private void ExecuteIncrementMaxConcatLines(object parameter) => ConcatMaxLines++;
27+
28+
public ICommand DecrementMaxConcatLinesCommand { get; }
29+
30+
private bool CanExecuteDecrementMaxConcatLines(object parameter) => ConcatMaxLines > ConcatMaxLinesMinValue;
31+
private void ExecuteDecrementMaxConcatLines(object parameter) => ConcatMaxLines--;
32+
1933
public void SetToDefaults(Configuration config)
2034
{
2135
TransferSettingsToView(config.UserSettings.AutoCompleteSettings);

Rubberduck.Core/UI/Splash.Designer.cs

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Core/UI/Splash.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public Splash()
1111

1212
public string Version
1313
{
14-
get { return VersionLabel.Text; }
15-
set { VersionLabel.Text = value; }
14+
get => VersionLabel.Text;
15+
set => VersionLabel.Text = value;
1616
}
1717
}
1818
}

Rubberduck.Core/UI/Splash.resx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1081,4 +1081,8 @@
10811081
AAAASUVORK5CYII=
10821082
</value>
10831083
</data>
1084+
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
1085+
<data name="$this.Icon" type="System.Resources.ResXFileRef, System.Windows.Forms">
1086+
<value>..\Ducky.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
1087+
</data>
10841088
</root>

Rubberduck.Main/VbeProvider.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ internal static void Initialize(IVBE vbe)
2424

2525
internal static void Terminate()
2626
{
27-
Vbe.Dispose();
2827
Vbe = null;
2928
VbeRuntime = null;
3029
}

Rubberduck.Parsing/VBA/AccessibilityCheck.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ namespace Rubberduck.Parsing.VBA
55
{
66
public static class AccessibilityCheck
77
{
8-
public static bool IsAccessible(Declaration callingProject, Declaration callingModule, Declaration callingParent, Declaration callee)
8+
public static bool IsAccessible(Declaration callingParent, Declaration callee)
99
{
10-
return callee != null
11-
&& (callee.DeclarationType.HasFlag(DeclarationType.Project)
12-
|| (callee.DeclarationType.HasFlag(DeclarationType.Module) && IsModuleAccessible(callingProject, callingModule, callee))
13-
|| (!callee.DeclarationType.HasFlag(DeclarationType.Module) && IsMemberAccessible(callingProject, callingModule, callingParent, callee)));
10+
var callingModule = callingParent.ParentScopeDeclaration;
11+
var callingProject = callingModule.ParentDeclaration;
12+
return IsAccessible(callingProject, callingModule, callingParent, callee);
1413
}
1514

15+
public static bool IsAccessible(Declaration callingProject, Declaration callingModule, Declaration callingParent, Declaration callee)
16+
{
17+
return callee != null
18+
&& (callee.DeclarationType.HasFlag(DeclarationType.Project)
19+
|| (callee.DeclarationType.HasFlag(DeclarationType.Module) && IsModuleAccessible(callingProject, callingModule, callee))
20+
|| (!callee.DeclarationType.HasFlag(DeclarationType.Module) && IsMemberAccessible(callingProject, callingModule, callingParent, callee)));
21+
}
1622

1723
public static bool IsModuleAccessible(Declaration callingProject, Declaration callingModule, Declaration calleeModule)
1824
{

0 commit comments

Comments
 (0)