Skip to content

Commit 626e6ce

Browse files
committed
Merge branch 'next' into FixURCInspectionForInternationalUsers
2 parents 7b60e98 + ac318dd commit 626e6ce

File tree

11 files changed

+767
-737
lines changed

11 files changed

+767
-737
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<img src="https://user-images.githubusercontent.com/5751684/46272484-347c0080-c51f-11e8-8fc1-ca817971c8b9.png" />
1+
<img src="https://user-images.githubusercontent.com/5751684/46327997-aeb98d00-c5d2-11e8-9de5-ba6f9cd1eea3.png" />
22

33
<!-- campaign is no longer accepting donations
44
### Donate!

Rubberduck.Core/Navigation/CodeExplorer/CodeExplorerViewModel.cs

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,7 @@ public ObservableCollection<CodeExplorerItemViewModel> Projects
260260
get => _projects;
261261
set
262262
{
263-
ReorderChildNodes(value);
264-
_projects = new ObservableCollection<CodeExplorerItemViewModel>(value.OrderBy(o => o.NameWithSignature));
265-
CanSearch = _projects.Any();
263+
_projects = ForceProjectsRefresh(value);
266264

267265
OnPropertyChanged();
268266
// Once a Project has been set, show the TreeView
@@ -271,6 +269,14 @@ public ObservableCollection<CodeExplorerItemViewModel> Projects
271269
}
272270
}
273271

272+
private ObservableCollection<CodeExplorerItemViewModel> ForceProjectsRefresh(ObservableCollection<CodeExplorerItemViewModel> projects)
273+
{
274+
ReorderChildNodes(projects);
275+
CanSearch = projects.Any();
276+
277+
return new ObservableCollection<CodeExplorerItemViewModel>(projects.OrderBy(o => o.NameWithSignature));
278+
}
279+
274280
private void HandleStateChanged(object sender, ParserStateEventArgs e)
275281
{
276282
if (Projects == null)
@@ -304,6 +310,8 @@ private void HandleStateChanged(object sender, ParserStateEventArgs e)
304310
UpdateNodes(Projects, newProjects);
305311

306312
Projects = new ObservableCollection<CodeExplorerItemViewModel>(newProjects);
313+
314+
FilterByName(Projects, _filterText);
307315
}
308316

309317
private void UpdateNodes(IEnumerable<CodeExplorerItemViewModel> oldList, IEnumerable<CodeExplorerItemViewModel> newList)
@@ -388,7 +396,7 @@ private void ParserState_ModuleStateChanged(object sender, ParseProgressEventArg
388396
folderNode.AddChild(newNode);
389397

390398
// Force a refresh. OnPropertyChanged("Projects") didn't work.
391-
Projects = Projects;
399+
ForceProjectsRefresh(Projects);
392400
}
393401
catch (Exception exception)
394402
{
@@ -480,7 +488,37 @@ private void SwitchNodeState(CodeExplorerItemViewModel node, bool expandedState)
480488
}
481489
}
482490

491+
private string _filterText;
492+
public string FilterText
493+
{
494+
get => _filterText;
495+
set
496+
{
497+
if (!_filterText?.Equals(value) ?? true)
498+
{
499+
_filterText = value;
500+
OnPropertyChanged();
501+
FilterByName(Projects, _filterText);
502+
}
503+
}
504+
}
483505

506+
public ObservableCollection<double> FontSizes { get; } = new ObservableCollection<double> { 8, 10, 12, 14, 16 };
507+
508+
private double _fontSize = 10;
509+
public double FontSize
510+
{
511+
get => _fontSize;
512+
set
513+
{
514+
if (!_fontSize.Equals(value))
515+
{
516+
_fontSize = value;
517+
OnPropertyChanged();
518+
}
519+
}
520+
}
521+
484522
public ReparseCommand RefreshCommand { get; set; }
485523

486524
public OpenCommand OpenCommand { get; set; }
@@ -554,10 +592,10 @@ public void FilterByName(IEnumerable<CodeExplorerItemViewModel> nodes, string se
554592
{
555593
FilterByName(item.Items, searchString);
556594
}
557-
558-
item.IsVisible = item.Items.Any(c => c.IsVisible) ||
559-
item.Name.ToLowerInvariant().Contains(searchString.ToLowerInvariant()) ||
560-
string.IsNullOrEmpty(searchString);
595+
596+
item.IsVisible = string.IsNullOrEmpty(searchString) ||
597+
item.Items.Any(c => c.IsVisible) ||
598+
item.Name.ToLowerInvariant().Contains(searchString.ToLowerInvariant());
561599
}
562600
}
563601

Rubberduck.Core/UI/CodeExplorer/CodeExplorerControl.xaml

Lines changed: 101 additions & 71 deletions
Large diffs are not rendered by default.

Rubberduck.Core/UI/CodeExplorer/CodeExplorerControl.xaml.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public CodeExplorerControl()
1616
}
1717

1818
private CodeExplorerViewModel ViewModel => DataContext as CodeExplorerViewModel;
19-
19+
2020
private void TreeView_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
2121
{
2222
if (ViewModel != null && ViewModel.OpenCommand.CanExecute(ViewModel.SelectedItem))
@@ -32,11 +32,6 @@ private void TreeView_OnMouseRightButtonDown(object sender, MouseButtonEventArgs
3232
e.Handled = true;
3333
}
3434

35-
private void SearchBox_OnTextChanged(object sender, TextChangedEventArgs e)
36-
{
37-
ViewModel.FilterByName(ViewModel.Projects, ((TextBox)sender).Text);
38-
}
39-
4035
private void SearchIcon_OnMouseDown(object sender, MouseButtonEventArgs e)
4136
{
4237
SearchBox.Focus();

Rubberduck.Refactorings/MoveCloserToUsage/MoveCloserToUsageRefactoring.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ private void UpdateCallsToOtherModule(IEnumerable<IdentifierReference> reference
192192
{
193193
foreach (var reference in references.OrderByDescending(o => o.Selection.StartLine).ThenByDescending(t => t.Selection.StartColumn))
194194
{
195+
// todo: Grab `GetAncestor` and use that
195196
var parent = reference.Context.Parent;
196197
while (!(parent is VBAParser.MemberAccessExprContext) && parent.Parent != null)
197198
{
@@ -203,6 +204,14 @@ private void UpdateCallsToOtherModule(IEnumerable<IdentifierReference> reference
203204
continue;
204205
}
205206

207+
// member access might be to something unrelated to the rewritten target.
208+
// check we're not accidentally overwriting some other member-access who just happens to be a parent context
209+
var memberAccessContext = (VBAParser.MemberAccessExprContext)parent;
210+
if (memberAccessContext.unrestrictedIdentifier().GetText() != _target.IdentifierName)
211+
{
212+
continue;
213+
}
214+
206215
var rewriter = _state.GetRewriter(reference.QualifiedModuleName);
207216
var tokenInterval = Interval.Of(parent.SourceInterval.a, reference.Context.SourceInterval.b);
208217
rewriter.Replace(tokenInterval, reference.IdentifierName);

Rubberduck.Refactorings/RemoveParameters/RemoveParametersRefactoring.cs

Lines changed: 115 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ public void Refactor(Declaration target)
9090
public void QuickFix(RubberduckParserState state, QualifiedSelection selection)
9191
{
9292
_model = new RemoveParametersModel(state, selection, new MessageBox());
93-
93+
9494
var target = _model.Parameters.SingleOrDefault(p => selection.Selection.Contains(p.Declaration.QualifiedSelection.Selection));
9595
Debug.Assert(target != null, "Target was not found");
96-
96+
9797
if (target != null)
9898
{
9999
_model.RemoveParameters.Add(target);
@@ -165,6 +165,7 @@ private void RemoveCallArguments(VBAParser.ArgumentListContext argList, Qualifie
165165
var rewriter = _model.State.GetRewriter(module);
166166
_rewriters.Add(rewriter);
167167

168+
var usesNamedArguments = false;
168169
var args = argList.children.OfType<VBAParser.ArgumentContext>().ToList();
169170
for (var i = 0; i < _model.Parameters.Count; i++)
170171
{
@@ -173,7 +174,7 @@ private void RemoveCallArguments(VBAParser.ArgumentListContext argList, Qualifie
173174
{
174175
continue;
175176
}
176-
177+
177178
if (_model.Parameters[i].IsParamArray)
178179
{
179180
//The following code works because it is neither allowed to use both named arguments
@@ -192,6 +193,7 @@ private void RemoveCallArguments(VBAParser.ArgumentListContext argList, Qualifie
192193
}
193194
else
194195
{
196+
usesNamedArguments = true;
195197
var arg = args.Where(a => a.namedArgument() != null)
196198
.SingleOrDefault(a =>
197199
a.namedArgument().unrestrictedIdentifier().GetText() ==
@@ -203,6 +205,8 @@ private void RemoveCallArguments(VBAParser.ArgumentListContext argList, Qualifie
203205
}
204206
}
205207
}
208+
209+
RemoveTrailingComma(rewriter, argList, usesNamedArguments);
206210
}
207211

208212
private void AdjustSignatures()
@@ -251,23 +255,127 @@ private void AdjustSignatures()
251255

252256
private Declaration GetLetterOrSetter(Declaration declaration, DeclarationType declarationType)
253257
{
254-
return _model.Declarations.FirstOrDefault(item => item.QualifiedModuleName.Equals(declaration.QualifiedModuleName)
255-
&& item.IdentifierName == declaration.IdentifierName
258+
return _model.Declarations.FirstOrDefault(item => item.QualifiedModuleName.Equals(declaration.QualifiedModuleName)
259+
&& item.IdentifierName == declaration.IdentifierName
256260
&& item.DeclarationType == declarationType);
257261
}
258262

259263
private void RemoveSignatureParameters(Declaration target)
260264
{
261265
var rewriter = _model.State.GetRewriter(target);
262266

263-
var parameters = ((IParameterizedDeclaration) target).Parameters.OrderBy(o => o.Selection).ToList();
264-
267+
var parameters = ((IParameterizedDeclaration)target).Parameters.OrderBy(o => o.Selection).ToList();
268+
265269
foreach (var index in _model.RemoveParameters.Select(rem => _model.Parameters.IndexOf(rem)))
266270
{
267271
rewriter.Remove(parameters[index]);
268272
}
269273

274+
RemoveTrailingComma(rewriter);
270275
_rewriters.Add(rewriter);
271276
}
277+
278+
//Issue 4319. If there are 3 or more arguments and the user elects to remove 2 or more of
279+
//the last arguments, then we need to specifically remove the trailing comma from
280+
//the last 'kept' argument.
281+
private void RemoveTrailingComma(IModuleRewriter rewriter, VBAParser.ArgumentListContext argList = null, bool usesNamedParams = false)
282+
{
283+
var commaLocator = RetrieveTrailingCommaInfo(_model.RemoveParameters, _model.Parameters);
284+
if (!commaLocator.RequiresTrailingCommaRemoval)
285+
{
286+
return;
287+
}
288+
289+
var tokenStart = 0;
290+
var tokenStop = 0;
291+
292+
if (argList is null)
293+
{
294+
//Handle Signatures only
295+
tokenStart = commaLocator.LastRetainedArg.Param.Declaration.Context.Stop.TokenIndex + 1;
296+
tokenStop = commaLocator.FirstOfRemovedArgSeries.Param.Declaration.Context.Start.TokenIndex - 1;
297+
rewriter.RemoveRange(tokenStart, tokenStop);
298+
return;
299+
}
300+
301+
302+
//Handles References
303+
var args = argList.children.OfType<VBAParser.ArgumentContext>().ToList();
304+
305+
if (usesNamedParams)
306+
{
307+
var lastKeptArg = args.Where(a => a.namedArgument() != null)
308+
.SingleOrDefault(a => a.namedArgument().unrestrictedIdentifier().GetText() ==
309+
commaLocator.LastRetainedArg.Identifier);
310+
311+
var firstOfRemovedArgSeries = args.Where(a => a.namedArgument() != null)
312+
.SingleOrDefault(a => a.namedArgument().unrestrictedIdentifier().GetText() ==
313+
commaLocator.FirstOfRemovedArgSeries.Identifier);
314+
315+
tokenStart = lastKeptArg.Stop.TokenIndex + 1;
316+
tokenStop = firstOfRemovedArgSeries.Start.TokenIndex - 1;
317+
rewriter.RemoveRange(tokenStart, tokenStop);
318+
return;
319+
}
320+
tokenStart = args[commaLocator.LastRetainedArg.Index].Stop.TokenIndex + 1;
321+
tokenStop = args[commaLocator.FirstOfRemovedArgSeries.Index].Start.TokenIndex - 1;
322+
rewriter.RemoveRange(tokenStart, tokenStop);
323+
}
324+
325+
private CommaLocator RetrieveTrailingCommaInfo(List<Parameter> toRemove, List<Parameter> allParams)
326+
{
327+
if (toRemove.Count == allParams.Count || allParams.Count < 3)
328+
{
329+
return new CommaLocator();
330+
}
331+
332+
var reversedAllParams = allParams.OrderByDescending(tr => tr.Declaration.Selection);
333+
var rangeRemoval = new List<Parameter>();
334+
for (var idx = 0; idx < reversedAllParams.Count(); idx++)
335+
{
336+
if (toRemove.Contains(reversedAllParams.ElementAt(idx)))
337+
{
338+
rangeRemoval.Add(reversedAllParams.ElementAt(idx));
339+
continue;
340+
}
341+
342+
if (rangeRemoval.Count >= 2)
343+
{
344+
var startIndex = allParams.FindIndex(par => par == reversedAllParams.ElementAt(idx));
345+
var stopIndex = allParams.FindIndex(par => par == rangeRemoval.First());
346+
347+
return new CommaLocator()
348+
{
349+
RequiresTrailingCommaRemoval = true,
350+
LastRetainedArg = new CommaBoundary()
351+
{
352+
Param = reversedAllParams.ElementAt(idx),
353+
Index = startIndex,
354+
},
355+
FirstOfRemovedArgSeries = new CommaBoundary()
356+
{
357+
Param = rangeRemoval.First(),
358+
Index = stopIndex,
359+
}
360+
};
361+
}
362+
break;
363+
}
364+
return new CommaLocator();
365+
}
366+
367+
private struct CommaLocator
368+
{
369+
public bool RequiresTrailingCommaRemoval;
370+
public CommaBoundary LastRetainedArg;
371+
public CommaBoundary FirstOfRemovedArgSeries;
372+
}
373+
374+
private struct CommaBoundary
375+
{
376+
public Parameter Param;
377+
public int Index;
378+
public string Identifier => Param.Declaration.IdentifierName;
379+
}
272380
}
273381
}

Rubberduck.Resources/CodeExplorer/CodeExplorerUI.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Rubberduck.Resources/CodeExplorer/CodeExplorerUI.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,9 @@
370370
<data name="CodeExplorer_AddVBFormText" xml:space="preserve">
371371
<value>Form (.frm)</value>
372372
</data>
373+
<data name="CodeExplorer_Rename" xml:space="preserve">
374+
<value>Rename</value>
375+
</data>
373376
<data name="CodeExplorer_SetAsStartupProject" xml:space="preserve">
374377
<value>Set as start up</value>
375378
</data>

Rubberduck.Resources/Rubberduck.Resources.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@
363363
<EmbeddedResource Include="CodeExplorer\CodeExplorerUI.resx">
364364
<Generator>PublicResXFileCodeGenerator</Generator>
365365
<LastGenOutput>CodeExplorerUI.Designer.cs</LastGenOutput>
366+
<SubType>Designer</SubType>
366367
</EmbeddedResource>
367368
<EmbeddedResource Include="CodeExplorer\CodeExplorerUI.cs.resx">
368369
<Generator>PublicResXFileCodeGenerator</Generator>

0 commit comments

Comments
 (0)