Skip to content

Commit 5d0eeb4

Browse files
authored
Merge pull request #4752 from rubberduck-vba/next
Release 2.4.0
2 parents 7e17257 + 6ce3d6d commit 5d0eeb4

File tree

362 files changed

+27806
-7327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

362 files changed

+27806
-7327
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
name: Bug report
3+
about: Rubberduck does not work as expected
4+
title: ''
5+
labels: bug
6+
assignees: ''
7+
8+
---
9+
**Rubberduck version information**
10+
The info below can be copy-paste-completed from the first lines of Rubberduck's Log or the About box:
11+
12+
Rubberduck version [...]
13+
Operating System: [...]
14+
Host Product: [...]
15+
Host Version: [...]
16+
Host Executable: [...]
17+
18+
19+
**Description**
20+
A clear and concise description of what the bug is.
21+
22+
**To Reproduce**
23+
Steps to reproduce the behavior:
24+
1. Go to '...'
25+
2. Click on '....'
26+
3. Scroll down to '....'
27+
4. See error
28+
29+
**Expected behavior**
30+
A clear and concise description of what you expected to happen.
31+
32+
**Screenshots**
33+
If applicable, add screenshots to help explain your problem.
34+
35+
**Logfile**
36+
Rubberduck generates extensive logging in TRACE-Level. If no log was created at `%APP_DATA%\Rubberduck\Logs`, check your settings. Include this Log for bugreports about the behavior of Rubbberduck
37+
38+
**Additional context**
39+
Add any other context about the problem here.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ If you like this project and would like to thank its contributors, you are welco
1717
[masterBuildStatus]:https://ci.appveyor.com/api/projects/status/we3pdnkeebo4nlck/branch/master?svg=true
1818
[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/Rubberduck-vba/rubberduck.svg)](http://isitmaintained.com/project/Rubberduck-vba/rubberduck "Average time to resolve an issue")
1919
[![Percentage of issues still open](http://isitmaintained.com/badge/open/Rubberduck-vba/rubberduck.svg)](http://isitmaintained.com/project/Rubberduck-vba/rubberduck "Percentage of issues still open")
20+
[![Chat on stackexchange](https://img.shields.io/badge/chat-on%20stackexchange-blue.svg)](https://chat.stackexchange.com/rooms/14929/vba-rubberducking)
21+
[![License](https://img.shields.io/github/license/rubberduck-vba/Rubberduck.svg)](https://github.com/rubberduck-vba/Rubberduck/blob/next/LICENSE)
2022

2123
> **[rubberduckvba.com](http://rubberduckvba.com)** [Wiki](https://github.com/rubberduck-vba/Rubberduck/wiki) [Rubberduck News](https://rubberduckvba.wordpress.com/)
2224
> devs@rubberduckvba.com

Rubberduck.CodeAnalysis/CodePathAnalysis/Walker.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Collections.Generic;
66
using System.Collections.Immutable;
77
using System.Linq;
8-
using Antlr4.Runtime;
98

109
namespace Rubberduck.Inspections.CodePathAnalysis
1110
{

Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionBase.cs

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,28 +86,22 @@ protected virtual IEnumerable<Declaration> BuiltInDeclarations
8686

8787
protected bool IsIgnoringInspectionResultFor(QualifiedModuleName module, int line)
8888
{
89-
var annotations = State.GetModuleAnnotations(module).ToList();
90-
91-
if (State.GetModuleAnnotations(module) == null)
92-
{
93-
return false;
94-
}
95-
96-
// VBE 1-based indexing
97-
for (var i = line; i >= 1; i--)
89+
var lineScopedAnnotations = State.DeclarationFinder.FindAnnotations(module, line);
90+
foreach (var ignoreAnnotation in lineScopedAnnotations.OfType<IgnoreAnnotation>())
9891
{
99-
var annotation = annotations.SingleOrDefault(a => a.QualifiedSelection.Selection.StartLine == i);
100-
var ignoreAnnotation = annotation as IgnoreAnnotation;
101-
var ignoreModuleAnnotation = annotation as IgnoreModuleAnnotation;
102-
103-
if (ignoreAnnotation?.InspectionNames.Contains(AnnotationName) == true)
92+
if (ignoreAnnotation.InspectionNames.Contains(AnnotationName))
10493
{
10594
return true;
10695
}
96+
}
97+
98+
var moduleDeclaration = State.DeclarationFinder.Members(module)
99+
.First(decl => decl.DeclarationType.HasFlag(DeclarationType.Module));
107100

108-
if (ignoreModuleAnnotation != null
109-
&& (ignoreModuleAnnotation.InspectionNames.Contains(AnnotationName)
110-
|| !ignoreModuleAnnotation.InspectionNames.Any()))
101+
foreach (var ignoreModuleAnnotation in moduleDeclaration.Annotations.OfType<IgnoreModuleAnnotation>())
102+
{
103+
if (ignoreModuleAnnotation.InspectionNames.Contains(AnnotationName)
104+
|| !ignoreModuleAnnotation.InspectionNames.Any())
111105
{
112106
return true;
113107
}
@@ -119,7 +113,10 @@ protected bool IsIgnoringInspectionResultFor(QualifiedModuleName module, int lin
119113
protected bool IsIgnoringInspectionResultFor(Declaration declaration, string inspectionName)
120114
{
121115
var module = Declaration.GetModuleParent(declaration);
122-
if (module == null) { return false; }
116+
if (module == null)
117+
{
118+
return false;
119+
}
123120

124121
var isIgnoredAtModuleLevel = module.Annotations
125122
.Any(annotation => annotation.AnnotationType == AnnotationType.IgnoreModule
@@ -169,5 +166,10 @@ public IEnumerable<IInspectionResult> GetInspectionResults(CancellationToken tok
169166
_logger.Trace("Intercepted invocation of '{0}.{1}' ran for {2}ms", GetType().Name, nameof(DoGetInspectionResults), _stopwatch.ElapsedMilliseconds);
170167
return result;
171168
}
169+
170+
public virtual bool ChangesInvalidateResult(IInspectionResult result, ICollection<QualifiedModuleName> modifiedModules)
171+
{
172+
return true;
173+
}
172174
}
173175
}

Rubberduck.CodeAnalysis/Inspections/Abstract/InspectionResultBase.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.IO;
1+
using System.Collections.Generic;
2+
using System.IO;
23
using Antlr4.Runtime;
34
using Rubberduck.Common;
45
using Rubberduck.Parsing.Inspections;
@@ -39,6 +40,12 @@ protected InspectionResultBase(IInspection inspection,
3940
public Declaration Target { get; }
4041
public dynamic Properties { get; }
4142

43+
public virtual bool ChangesInvalidateResult(ICollection<QualifiedModuleName> modifiedModules)
44+
{
45+
return modifiedModules.Contains(QualifiedName)
46+
|| Inspection.ChangesInvalidateResult(this, modifiedModules);
47+
}
48+
4249
/// <summary>
4350
/// Gets the information needed to select the target instruction in the VBE.
4451
/// </summary>

Rubberduck.CodeAnalysis/Inspections/Concrete/AssignmentNotUsedInspection.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Rubberduck.Parsing.Symbols;
77
using Rubberduck.Inspections.CodePathAnalysis.Extensions;
88
using System.Linq;
9+
using Rubberduck.Inspections.CodePathAnalysis.Nodes;
910
using Rubberduck.Inspections.Results;
1011
using Rubberduck.Parsing;
1112
using Rubberduck.Parsing.Grammar;
@@ -30,7 +31,15 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
3031
var nodes = new List<IdentifierReference>();
3132
foreach (var variable in variables)
3233
{
33-
var tree = _walker.GenerateTree(variable.ParentScopeDeclaration.Context, variable);
34+
var parentScopeDeclaration = variable.ParentScopeDeclaration;
35+
36+
if (parentScopeDeclaration.DeclarationType.HasFlag(DeclarationType.Module))
37+
{
38+
continue;
39+
}
40+
41+
var tree = _walker.GenerateTree(parentScopeDeclaration.Context, variable);
42+
3443

3544
nodes.AddRange(tree.GetIdentifierReferences());
3645
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Rubberduck.Inspections.Abstract;
4+
using Rubberduck.Inspections.Results;
5+
using Rubberduck.Parsing;
6+
using Rubberduck.Parsing.Annotations;
7+
using Rubberduck.Parsing.Inspections;
8+
using Rubberduck.Parsing.Inspections.Abstract;
9+
using Rubberduck.Parsing.Symbols;
10+
using Rubberduck.Parsing.VBA;
11+
using Rubberduck.Resources.Inspections;
12+
using Rubberduck.VBEditor.SafeComWrappers;
13+
14+
namespace Rubberduck.Inspections.Concrete
15+
{
16+
[CannotAnnotate]
17+
public sealed class AttributeValueOutOfSyncInspection : InspectionBase
18+
{
19+
public AttributeValueOutOfSyncInspection(RubberduckParserState state)
20+
:base(state)
21+
{
22+
}
23+
24+
protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
25+
{
26+
var declarationsWithAttributeAnnotations = State.DeclarationFinder.AllUserDeclarations
27+
.Where(declaration => declaration.Annotations.Any(annotation => annotation.AnnotationType.HasFlag(AnnotationType.Attribute)));
28+
var results = new List<DeclarationInspectionResult>();
29+
foreach (var declaration in declarationsWithAttributeAnnotations.Where(decl => decl.QualifiedModuleName.ComponentType != ComponentType.Document))
30+
{
31+
foreach (var annotation in declaration.Annotations.OfType<IAttributeAnnotation>())
32+
{
33+
if (HasDifferingAttributeValues(declaration, annotation, out var attributeValues))
34+
{
35+
var description = string.Format(InspectionResults.AttributeValueOutOfSyncInspection,
36+
annotation.Attribute,
37+
string.Join(", ", attributeValues),
38+
annotation.AnnotationType);
39+
40+
var result = new DeclarationInspectionResult(this, description, declaration,
41+
new QualifiedContext(declaration.QualifiedModuleName, annotation.Context));
42+
result.Properties.Annotation = annotation;
43+
result.Properties.AttributeName = annotation.Attribute;
44+
result.Properties.AttributeValues = attributeValues;
45+
46+
results.Add(result);
47+
}
48+
}
49+
}
50+
51+
return results;
52+
}
53+
54+
private static bool HasDifferingAttributeValues(Declaration declaration, IAttributeAnnotation annotation, out IReadOnlyList<string> attributeValues)
55+
{
56+
var attributeNodes = declaration.DeclarationType.HasFlag(DeclarationType.Module)
57+
? declaration.Attributes.AttributeNodesFor(annotation)
58+
: declaration.Attributes.AttributeNodesFor(annotation, declaration.IdentifierName);
59+
60+
foreach (var attributeNode in attributeNodes)
61+
{
62+
var values = attributeNode.Values;
63+
if (!annotation.AttributeValues.SequenceEqual(values))
64+
{
65+
attributeValues = values;
66+
return true;
67+
}
68+
}
69+
attributeValues = new List<string>();
70+
return false;
71+
}
72+
}
73+
}

Rubberduck.CodeAnalysis/Inspections/Concrete/IllegalAnnotationInspection.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
using Rubberduck.Parsing.Symbols;
99
using Rubberduck.Resources.Inspections;
1010
using Rubberduck.Parsing.VBA;
11+
using Rubberduck.Parsing.VBA.DeclarationCaching;
1112
using Rubberduck.Parsing.VBA.Extensions;
13+
using Rubberduck.VBEditor.SafeComWrappers;
1214

1315
namespace Rubberduck.Inspections.Concrete
1416
{
@@ -24,8 +26,12 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
2426
var identifierReferences = State.DeclarationFinder.AllIdentifierReferences().ToList();
2527
var annotations = State.AllAnnotations;
2628

27-
var illegalAnnotations = UnboundAnnotations(annotations, userDeclarations, identifierReferences)
28-
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.GeneralAnnotation));
29+
var unboundAnnotations = UnboundAnnotations(annotations, userDeclarations, identifierReferences)
30+
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.GeneralAnnotation)
31+
|| annotation.AnnotatedLine == null);
32+
var attributeAnnotationsInDocuments = AttributeAnnotationsInDocuments(userDeclarations);
33+
34+
var illegalAnnotations = unboundAnnotations.Concat(attributeAnnotationsInDocuments).ToHashSet();
2935

3036
return illegalAnnotations.Select(annotation =>
3137
new QualifiedContextInspectionResult(
@@ -34,7 +40,7 @@ protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
3440
new QualifiedContext(annotation.QualifiedSelection.QualifiedName, annotation.Context)));
3541
}
3642

37-
private static ICollection<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotation> annotations, IEnumerable<Declaration> userDeclarations, IEnumerable<IdentifierReference> identifierReferences)
43+
private static IEnumerable<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotation> annotations, IEnumerable<Declaration> userDeclarations, IEnumerable<IdentifierReference> identifierReferences)
3844
{
3945
var boundAnnotationsSelections = userDeclarations
4046
.SelectMany(declaration => declaration.Annotations)
@@ -44,5 +50,12 @@ private static ICollection<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotati
4450

4551
return annotations.Where(annotation => !boundAnnotationsSelections.Contains(annotation.QualifiedSelection)).ToList();
4652
}
53+
54+
private static IEnumerable<IAnnotation> AttributeAnnotationsInDocuments(IEnumerable<Declaration> userDeclarations)
55+
{
56+
var declarationsInDocuments = userDeclarations
57+
.Where(declaration => declaration.QualifiedModuleName.ComponentType == ComponentType.Document);
58+
return declarationsInDocuments.SelectMany(doc => doc.Annotations).OfType<IAttributeAnnotation>();
59+
}
4760
}
4861
}

0 commit comments

Comments
 (0)