Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
43c0bed
model draft1
retailcoder Dec 20, 2017
d59326f
Merge branch 'next' of https://github.com/rubberduck-vba/Rubberduck i…
retailcoder Dec 20, 2017
1efb48b
added WinForms dialog and XAML user control files.
retailcoder Dec 20, 2017
8c37b30
something like the beginnings of a UI
retailcoder Dec 21, 2017
44632fb
Added ApplyButtonText resource key
retailcoder Dec 22, 2017
97f08f7
UI completed
retailcoder Dec 22, 2017
a719779
minor UI tweaks
retailcoder Dec 22, 2017
64d3319
cleaned up image resources, added some bindings
retailcoder Dec 22, 2017
bc7acb3
added resource keys
retailcoder Dec 30, 2017
eec6cf1
removed duplicate .resx file
retailcoder Dec 30, 2017
49a3ea5
merge with conflicts
retailcoder Dec 30, 2017
a43db43
Merge branch 'next' of https://github.com/rubberduck-vba/Rubberduck i…
retailcoder Dec 30, 2017
938a48b
extracted ImageSourceConverter base class, made InspectionSeverityIma…
retailcoder Dec 30, 2017
3147d52
added RegisteredLibraryFinderService
retailcoder Dec 31, 2017
cda0896
implemented library finder
retailcoder Dec 31, 2017
bb4e8dc
Merge pull request #3658 from retailcoder/ProjectRefs
retailcoder Dec 31, 2017
b42d69b
woopsie
retailcoder Dec 31, 2017
9ec87fc
added MoveDown button, binding to VbaProjects.
retailcoder Dec 31, 2017
3a004bf
Merge pull request #3659 from retailcoder/ProjectRefs
retailcoder Dec 31, 2017
f442210
merge next
comintern Nov 26, 2018
62c4bd2
Add failing test for unexpected behaviour from issue #4558
MDoerner Nov 27, 2018
2ba2ef8
Adjust tests for new IllegalAnnotations and annotation resolution spe…
MDoerner Nov 27, 2018
8c5f900
Make tests pass for new annotation scoping design
MDoerner Nov 27, 2018
400ff2f
Remove no longer required part of IllegalAnnotationInspection
MDoerner Nov 27, 2018
908e76e
Merge branch 'next' into FixIllegalAnnotationInspection
MDoerner Nov 27, 2018
8426ac4
fix for duplicate VBERuntime and VbeRuntime
Nov 28, 2018
3a6aee5
Merge pull request #4572 from SonGokussj4/next
bclothier Nov 28, 2018
3058303
Merge branch 'next' into FixIllegalAnnotationInspection
MDoerner Nov 28, 2018
fbbe89e
Replace backticks in ignored test
MDoerner Nov 28, 2018
0bda237
Merge pull request #4568 from MDoerner/FixIllegalAnnotationInspection
retailcoder Nov 29, 2018
b6fdeef
Fix case for image references in Resources
MDoerner Nov 29, 2018
8ee81f5
Fix casing in build action
MDoerner Nov 29, 2018
1e1cc06
Fix library case and minor reference versions in tests
MDoerner Nov 29, 2018
e73ecef
Deactivate SCW release messages
MDoerner Nov 29, 2018
715d8a1
Re-arrange project tree, inital CE support for references
comintern Nov 29, 2018
8bea806
Add failing test for #4577
comintern Nov 30, 2018
3e68474
Verify identifier use in FindParameterFromArgument. Closes #4577
comintern Nov 30, 2018
44f173a
Transfer correct properties to model from VM. Closes #4571
comintern Nov 30, 2018
7ca1197
Wrap Application start logging in try block. Closes #4556
comintern Nov 30, 2018
d5b900d
Merge pull request #4569 from retailcoder/bugfix
retailcoder Nov 30, 2018
73c950d
Prevent early exit from BracketedExpression pseudo-projects. Closes #…
comintern Nov 30, 2018
87f612b
Merge pull request #4580 from MDoerner/CaseCorrections
retailcoder Nov 30, 2018
54cf6ee
Address review comments.
comintern Nov 30, 2018
64ef35f
Strong type OpenDesignerCommand to allow property injection. Closes #…
comintern Dec 1, 2018
d7c8bbf
Make IgnoreOnceQuickfix able to handle modules
MDoerner Dec 1, 2018
10114ad
Reflect resources for localization. Closes #4534
comintern Dec 1, 2018
27f3dab
Add null check in FindEvents(Declaration). Closes #4259
comintern Dec 1, 2018
b8b0b7d
Allow multiple WithEvents declarations in variable list. Closes #4591
comintern Dec 1, 2018
b011dff
Rewrite the IgnoreOnceQuickfix
MDoerner Dec 2, 2018
1fb36ef
Minor stylistic change based on review comment
MDoerner Dec 3, 2018
33eb1f5
Aways deem annotations with GeneralAnnotation flag legal
MDoerner Dec 3, 2018
a6d6d18
Merge pull request #4593 from MDoerner/FixIgnoreOnce
retailcoder Dec 4, 2018
14547be
Merge pull request #4599 from MDoerner/FixGeneralAnnotations
retailcoder Dec 4, 2018
77fa481
Merge pull request #4581 from comintern/next
retailcoder Dec 4, 2018
b40a96e
Add remove references UI implementation.
comintern Dec 4, 2018
d49b82b
merge with next
comintern Dec 4, 2018
dc2da1b
Fix reference merge.
comintern Dec 4, 2018
2c58513
Fix reference icons.
comintern Dec 4, 2018
eeb3083
Remove references node from Code Metric tree.
comintern Dec 4, 2018
04e1e00
Rewire add remove references in context menu.
comintern Dec 4, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,12 @@ public IllegalAnnotationInspection(RubberduckParserState state)

protected override IEnumerable<IInspectionResult> DoGetInspectionResults()
{
var illegalAnnotations = new List<IAnnotation>();

var userDeclarations = State.DeclarationFinder.AllUserDeclarations.ToList();
var identifierReferences = State.DeclarationFinder.AllIdentifierReferences().ToList();
var annotations = State.AllAnnotations;

illegalAnnotations.AddRange(UnboundAnnotations(annotations, userDeclarations, identifierReferences));
illegalAnnotations.AddRange(NonIdentifierAnnotationsOnIdentifiers(identifierReferences));
illegalAnnotations.AddRange(NonModuleAnnotationsOnModules(userDeclarations));
illegalAnnotations.AddRange(NonMemberAnnotationsOnMembers(userDeclarations));
illegalAnnotations.AddRange(NonVariableAnnotationsOnVariables(userDeclarations));
illegalAnnotations.AddRange(NonGeneralAnnotationsWhereOnlyGeneralAnnotationsBelong(userDeclarations));
var illegalAnnotations = UnboundAnnotations(annotations, userDeclarations, identifierReferences)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.GeneralAnnotation));

return illegalAnnotations.Select(annotation =>
new QualifiedContextInspectionResult(
Expand All @@ -50,64 +44,5 @@ private static ICollection<IAnnotation> UnboundAnnotations(IEnumerable<IAnnotati

return annotations.Where(annotation => !boundAnnotationsSelections.Contains(annotation.QualifiedSelection)).ToList();
}

private static ICollection<IAnnotation> NonIdentifierAnnotationsOnIdentifiers(IEnumerable<IdentifierReference> identifierReferences)
{
return identifierReferences
.SelectMany(reference => reference.Annotations)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.IdentifierAnnotation))
.ToList();
}

private static ICollection<IAnnotation> NonModuleAnnotationsOnModules(IEnumerable<Declaration> userDeclarations)
{
return userDeclarations
.Where(declaration => declaration.DeclarationType.HasFlag(DeclarationType.Module))
.SelectMany(moduleDeclaration => moduleDeclaration.Annotations)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.ModuleAnnotation))
.ToList();
}

private static ICollection<IAnnotation> NonMemberAnnotationsOnMembers(IEnumerable<Declaration> userDeclarations)
{
return userDeclarations
.Where(declaration => declaration.DeclarationType.HasFlag(DeclarationType.Member))
.SelectMany(member => member.Annotations)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.MemberAnnotation))
.ToList();
}

private static ICollection<IAnnotation> NonVariableAnnotationsOnVariables(IEnumerable<Declaration> userDeclarations)
{
return userDeclarations
.Where(declaration => VariableAnnotationDeclarationTypes.Contains(declaration.DeclarationType))
.SelectMany(declaration => declaration.Annotations)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.VariableAnnotation))
.ToList();
}

private static readonly HashSet<DeclarationType> VariableAnnotationDeclarationTypes = new HashSet<DeclarationType>()
{
DeclarationType.Variable,
DeclarationType.Control,
DeclarationType.Constant,
DeclarationType.Enumeration,
DeclarationType.EnumerationMember,
DeclarationType.UserDefinedType,
DeclarationType.UserDefinedType,
DeclarationType.UserDefinedTypeMember
};

private static ICollection<IAnnotation> NonGeneralAnnotationsWhereOnlyGeneralAnnotationsBelong(IEnumerable<Declaration> userDeclarations)
{
return userDeclarations
.Where(declaration => !declaration.DeclarationType.HasFlag(DeclarationType.Module)
&& !declaration.DeclarationType.HasFlag(DeclarationType.Member)
&& !VariableAnnotationDeclarationTypes.Contains(declaration.DeclarationType)
&& declaration.DeclarationType != DeclarationType.Project)
.SelectMany(member => member.Annotations)
.Where(annotation => !annotation.AnnotationType.HasFlag(AnnotationType.GeneralAnnotation))
.ToList();
}
}
}
155 changes: 84 additions & 71 deletions Rubberduck.CodeAnalysis/QuickFixes/IgnoreOnceQuickFix.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Parsing.Annotations;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Inspections;
using Rubberduck.Parsing.Inspections.Abstract;
using Rubberduck.Parsing.Rewriter;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Parsing.VBA.Parsing;

namespace Rubberduck.Inspections.QuickFixes
{
Expand All @@ -29,98 +31,109 @@ public IgnoreOnceQuickFix(RubberduckParserState state, IEnumerable<IInspection>

public override void Fix(IInspectionResult result, IRewriteSession rewriteSession)
{
var annotationText = $"'@Ignore {result.Inspection.AnnotationName}";

int annotationLine;
//TODO: Make this use the parse tree instead of the code module.
var component = _state.ProjectsProvider.Component(result.QualifiedSelection.QualifiedName);
using (var module = component.CodeModule)
if (result.Target?.DeclarationType.HasFlag(DeclarationType.Module) ?? false)
{
annotationLine = result.QualifiedSelection.Selection.StartLine;
while (annotationLine != 1 && module.GetLines(annotationLine - 1, 1).EndsWith(" _"))
{
annotationLine--;
}
FixModule(result, rewriteSession);
}

RuleContext treeRoot = result.Context;
while (treeRoot.Parent != null)
else
{
treeRoot = treeRoot.Parent;
FixNonModule(result, rewriteSession);
}
}

var listener = new CommentOrAnnotationListener();
ParseTreeWalker.Default.Walk(listener, treeRoot);
var commentContext = listener.Contexts.LastOrDefault(i => i.Stop.TokenIndex <= result.Context.Start.TokenIndex);
var commented = commentContext?.Stop.Line + 1 == annotationLine;
private void FixNonModule(IInspectionResult result, IRewriteSession rewriteSession)
{
int insertionIndex;
string insertText;
var annotationText = $"'@Ignore {result.Inspection.AnnotationName}";

var rewriter = rewriteSession.CheckOutModuleRewriter(result.QualifiedSelection.QualifiedName);
var module = result.QualifiedSelection.QualifiedName;
var parseTree = _state.GetParseTree(module, CodeKind.CodePaneCode);
var eolListener = new EndOfLineListener();
ParseTreeWalker.Default.Walk(eolListener, parseTree);
var previousEol = eolListener.Contexts
.OrderBy(eol => eol.Start.TokenIndex)
.LastOrDefault(eol => eol.Start.Line < result.QualifiedSelection.Selection.StartLine);

if (commented)
var rewriter = rewriteSession.CheckOutModuleRewriter(module);

if (previousEol == null)
{
var annotation = commentContext.annotationList()?.annotation(0);
if (annotation != null && annotation.GetText().StartsWith("Ignore"))
{
rewriter.InsertAfter(annotation.annotationName().Stop.TokenIndex, $" {result.Inspection.AnnotationName},");
}
else
{
var indent = new string(Enumerable.Repeat(' ', commentContext.Start.Column).ToArray());
rewriter.InsertAfter(commentContext.Stop.TokenIndex, $"{indent}{annotationText}{Environment.NewLine}");
}
// The context to get annotated is on the first line; we need to insert before token index 0.
insertionIndex = 0;
insertText = annotationText + Environment.NewLine;
rewriter.InsertBefore(insertionIndex, insertText);
return;
}
else

var commentContext = previousEol.commentOrAnnotation();
if (commentContext == null)
{
insertionIndex = previousEol.Start.TokenIndex;
var indent = WhitespaceAfter(previousEol);
insertText = $"{Environment.NewLine}{indent}{annotationText}";
rewriter.InsertBefore(insertionIndex, insertText);
return;
}

var ignoreAnnotation = commentContext.annotationList()?.annotation()
.FirstOrDefault(annotationContext => annotationContext.annotationName().GetText() == AnnotationType.Ignore.ToString());
if (ignoreAnnotation == null)
{
int insertIndex;

// this value is used when the annotation should be on line 1--we need to insert before token index 0
if (annotationLine == 1)
{
insertIndex = 0;
annotationText += Environment.NewLine;
}
else
{
var eol = new EndOfLineListener();
ParseTreeWalker.Default.Walk(eol, treeRoot);

// we subtract 2 here to get the insertion index to A) account for VBE's one-based indexing
// and B) to get the newline token that introduces that line
var eolContext = eol.Contexts.OrderBy(o => o.Start.TokenIndex).ElementAt(annotationLine - 2);
insertIndex = eolContext.Start.TokenIndex;

annotationText = Environment.NewLine + annotationText;
}

rewriter.InsertBefore(insertIndex, annotationText);
insertionIndex = commentContext.Stop.TokenIndex;
var indent = WhitespaceAfter(previousEol);
insertText = $"{indent}{annotationText}{Environment.NewLine}";
rewriter.InsertAfter(insertionIndex, insertText);
return;
}

insertionIndex = ignoreAnnotation.annotationName().Stop.TokenIndex;
insertText = $" {result.Inspection.AnnotationName},";
rewriter.InsertAfter(insertionIndex, insertText);
}

public override string Description(IInspectionResult result) => Resources.Inspections.QuickFixes.IgnoreOnce;
private static string WhitespaceAfter(VBAParser.EndOfLineContext endOfLine)
{
var individualEndOfStatement = (VBAParser.IndividualNonEOFEndOfStatementContext) endOfLine.Parent;
var whiteSpaceOnNextLine = individualEndOfStatement.whiteSpace(0);
return whiteSpaceOnNextLine != null
? whiteSpaceOnNextLine.GetText()
: string.Empty;
}

private class CommentOrAnnotationListener : VBAParserBaseListener
private void FixModule(IInspectionResult result, IRewriteSession rewriteSession)
{
private readonly IList<VBAParser.CommentOrAnnotationContext> _contexts = new List<VBAParser.CommentOrAnnotationContext>();
public IEnumerable<VBAParser.CommentOrAnnotationContext> Contexts => _contexts;
var module = result.QualifiedSelection.QualifiedName;
var moduleAnnotations = _state.GetModuleAnnotations(module);
var firstIgnoreModuleAnnotation = moduleAnnotations
.Where(annotation => annotation.AnnotationType == AnnotationType.IgnoreModule)
.OrderBy(annotation => annotation.Context.Start.TokenIndex)
.FirstOrDefault();

public override void ExitCommentOrAnnotation([NotNull] VBAParser.CommentOrAnnotationContext context)
var rewriter = rewriteSession.CheckOutModuleRewriter(module);

int insertionIndex;
string insertText;

if (firstIgnoreModuleAnnotation == null)
{
_contexts.Add(context);
insertionIndex = 0;
insertText = $"'@IgnoreModule {result.Inspection.AnnotationName}{Environment.NewLine}";
rewriter.InsertBefore(insertionIndex, insertText);
return;
}

insertionIndex = firstIgnoreModuleAnnotation.Context.annotationName().Stop.TokenIndex;
insertText = $" {result.Inspection.AnnotationName},";
rewriter.InsertAfter(insertionIndex, insertText);
}

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

private class EndOfLineListener : VBAParserBaseListener
{
private readonly IList<ParserRuleContext> _contexts = new List<ParserRuleContext>();
public IEnumerable<ParserRuleContext> Contexts => _contexts;

public override void ExitWhiteSpace([NotNull] VBAParser.WhiteSpaceContext context)
{
if (context.GetText().Contains(Environment.NewLine))
{
_contexts.Add(context);
}
}
private readonly IList<VBAParser.EndOfLineContext> _contexts = new List<VBAParser.EndOfLineContext>();
public IEnumerable<VBAParser.EndOfLineContext> Contexts => _contexts;

public override void ExitEndOfLine([NotNull] VBAParser.EndOfLineContext context)
{
Expand Down
18 changes: 18 additions & 0 deletions Rubberduck.Core/AddRemoveReferences/IReferenceInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Rubberduck.AddRemoveReferences
{
public interface IReferenceInfo
{
Guid Guid { get; }
string Name { get; }
string FullPath { get; }
int Major { get; }
int Minor { get; }
int? Priority { get; }
}
}
Loading