Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f071f01
Merge pull request #2526 from retailcoder/next
retailcoder Jan 12, 2017
2dcf02e
Merge pull request #2527 from retailcoder/next
retailcoder Jan 12, 2017
2b7a0c9
Initial Hungarian notation inspection commit
comintern Jan 13, 2017
d14dd60
Merge branch 'next' of https://github.com/comintern/Rubberduck.git
comintern Jan 13, 2017
10e5f45
Allow BF to be used as an identifier.
comintern Jan 13, 2017
83cce66
Add Hungarian notation inspection, whitelist quickfix.
comintern Jan 13, 2017
c26d64a
Merge branch 'next' into next
comintern Jan 13, 2017
c315079
Fix missed identifier name changes.
comintern Jan 13, 2017
faaec3d
Merge branch 'next' of https://github.com/comintern/Rubberduck.git
comintern Jan 13, 2017
d759da5
Merge pull request #2529 from comintern/next
retailcoder Jan 13, 2017
2368233
Merge pull request #194 from rubberduck-vba/next
retailcoder Jan 13, 2017
edc0acb
Add IsExtensible member to declarations, restrict to interfaces (per …
comintern Jan 14, 2017
5573eb8
Remove unused Declaration.MemberCalls and Declaration.AddMemberCall m…
comintern Jan 14, 2017
36eb021
Added MemberNotOnInterfaceInspection.
comintern Jan 15, 2017
f5c6733
Change GetInspectionResults to Linq expression, correct annotation name.
comintern Jan 15, 2017
b71b08e
Add stub for MemberNotOnInterfaceInspectionTests (WIP).
comintern Jan 15, 2017
a967195
Merge branch 'next' into next
comintern Jan 15, 2017
6d6c9a4
Add annotations to undeclared variables, add tests. Closes #2525
comintern Jan 15, 2017
c6b6ef4
Merge branch 'next' of https://github.com/comintern/Rubberduck.git
comintern Jan 15, 2017
c43f013
Merge pull request #2535 from comintern/next
retailcoder Jan 15, 2017
e081c1c
Merge pull request #195 from rubberduck-vba/next
retailcoder Jan 15, 2017
8746511
Traverse declarationList once in FindBuiltInEventHandlers instead of …
comintern Jan 15, 2017
9bb68d0
can't rename built-in targets anymore
retailcoder Jan 15, 2017
8ab4b85
prevent execute with builtin target
retailcoder Jan 15, 2017
7cbf020
Fix the fix for #2239 - now only supresses results in Excel.
comintern Jan 15, 2017
f860474
Merge branch 'next' into next
comintern Jan 15, 2017
b120475
Merge pull request #2537 from comintern/next
retailcoder Jan 15, 2017
f0b8687
handle/ignore TYPEKIND.TKIND_UNION
retailcoder Jan 15, 2017
6edab41
disable menu item when command can't execute
retailcoder Jan 15, 2017
6312529
moved references count to its own commandbar button + command
retailcoder Jan 15, 2017
f4ba97d
fixed implicit active sheet/book inspections (again)
retailcoder Jan 15, 2017
d8be835
Merge branch 'next' into next
retailcoder Jan 15, 2017
795727e
Merge pull request #2539 from retailcoder/next
retailcoder Jan 15, 2017
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
6 changes: 3 additions & 3 deletions RetailCoder.VBE/App.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Infralution.Localization.Wpf;
using NLog;
using NLog.Fluent;
using Rubberduck.Common;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Symbols;
Expand All @@ -13,6 +11,7 @@
using Rubberduck.UI.Command.MenuItems;
using System;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using Rubberduck.UI.Command.MenuItems.CommandBars;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
Expand Down Expand Up @@ -87,8 +86,9 @@ private void RefreshSelection()
if (!pane.IsWrappingNullReference)
{
selectedDeclaration = _parser.State.FindSelectedDeclaration(pane);
var refCount = selectedDeclaration == null ? 0 : selectedDeclaration.References.Count();
var caption = _stateBar.GetContextSelectionCaption(_vbe.ActiveCodePane, selectedDeclaration);
_stateBar.SetContextSelectionCaption(caption);
_stateBar.SetContextSelectionCaption(caption, refCount);
}

var currentStatus = _parser.State.Status;
Expand Down
38 changes: 21 additions & 17 deletions RetailCoder.VBE/Common/DeclarationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Rubberduck.Properties;
using Rubberduck.UI;
using Rubberduck.VBEditor;
using Rubberduck.VBEditor.Extensions;
using Rubberduck.VBEditor.SafeComWrappers;

// ReSharper disable LocalizableElement
Expand Down Expand Up @@ -292,25 +293,28 @@ public static IEnumerable<Declaration> FindBuiltInEventHandlers(this IEnumerable
: new[] { e.ParentDeclaration.IdentifierName + "_" + e.IdentifierName };
});

// class module built-in events
var classModuleHandlers = declarationList.Where(item =>
var user = declarationList.FirstOrDefault(decl => !decl.IsBuiltIn);
var host = user != null ? user.Project.VBE.HostApplication() : null ;

var handlers = declarationList.Where(item =>
// class module built-in events
(item.DeclarationType == DeclarationType.Procedure &&
item.ParentDeclaration.DeclarationType == DeclarationType.ClassModule && (
item.IdentifierName.Equals("Class_Initialize", StringComparison.InvariantCultureIgnoreCase) ||
item.IdentifierName.Equals("Class_Terminate", StringComparison.InvariantCultureIgnoreCase))) ||
// standard module built-in handlers (Excel specific):
(host != null &&
host.ApplicationName.Equals("Excel", StringComparison.InvariantCultureIgnoreCase) &&
item.DeclarationType == DeclarationType.Procedure &&
item.ParentDeclaration.DeclarationType == DeclarationType.ClassModule &&
(item.IdentifierName.Equals("Class_Initialize", StringComparison.InvariantCultureIgnoreCase)
|| item.IdentifierName.Equals("Class_Terminate", StringComparison.InvariantCultureIgnoreCase)));
item.ParentDeclaration.DeclarationType == DeclarationType.ProceduralModule && (
item.IdentifierName.Equals("auto_open", StringComparison.InvariantCultureIgnoreCase) ||
item.IdentifierName.Equals("auto_close", StringComparison.InvariantCultureIgnoreCase))) ||
// user handlers:
(!item.IsBuiltIn &&
item.DeclarationType == DeclarationType.Procedure &&
handlerNames.Contains(item.IdentifierName))
).ToList();

// standard module built-in handlers:
var stdModuleHandlers = declarationList.Where(item =>
item.DeclarationType == DeclarationType.Procedure &&
item.ParentDeclaration.DeclarationType == DeclarationType.ProceduralModule &&
(item.IdentifierName.Equals("auto_open", StringComparison.InvariantCultureIgnoreCase)
|| item.IdentifierName.Equals("auto_close", StringComparison.InvariantCultureIgnoreCase)));

var handlers = declarationList.Where(declaration => !declaration.IsBuiltIn
&& declaration.DeclarationType == DeclarationType.Procedure
&& handlerNames.Contains(declaration.IdentifierName)).ToList();

handlers.AddRange(classModuleHandlers.Concat(stdModuleHandlers));
return handlers;
}

Expand Down
135 changes: 135 additions & 0 deletions RetailCoder.VBE/Inspections/HungarianNotationInspection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Inspections.Resources;
using Rubberduck.Inspections.Results;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.Settings;
using Rubberduck.SettingsProvider;
using Rubberduck.UI;

namespace Rubberduck.Inspections
{
public sealed class HungarianNotationInspection : InspectionBase
{
#region statics
private static readonly List<string> HungarianPrefixes = new List<string>
{
"chk",
"cbo",
"cmd",
"btn",
"fra",
"img",
"lbl",
"lst",
"mnu",
"opt",
"pic",
"shp",
"txt",
"tmr",
"chk",
"dlg",
"drv",
"frm",
"grd",
"obj",
"rpt",
"fld",
"idx",
"tbl",
"tbd",
"bas",
"cls",
"g",
"m",
"bln",
"byt",
"col",
"dtm",
"dbl",
"cur",
"int",
"lng",
"sng",
"str",
"udt",
"vnt",
"var",
"pgr",
"dao",
"b",
"by",
"c",
"chr",
"i",
"l",
"s",
"o",
"n",
"dt",
"dat",
"a",
"arr"
};

private static readonly Regex HungarianIdentifierRegex = new Regex(string.Format("^({0})[A-Z0-9].*$", string.Join("|", HungarianPrefixes)));

private static readonly List<DeclarationType> TargetDeclarationTypes = new List<DeclarationType>
{
DeclarationType.Parameter,
DeclarationType.Constant,
DeclarationType.Control,
DeclarationType.ClassModule,
DeclarationType.Member,
DeclarationType.Module,
DeclarationType.ProceduralModule,
DeclarationType.UserForm,
DeclarationType.UserDefinedType,
DeclarationType.UserDefinedTypeMember,
DeclarationType.Variable
};

#endregion

private readonly IMessageBox _messageBox;
private readonly IPersistanceService<CodeInspectionSettings> _settings;

public HungarianNotationInspection(IMessageBox messageBox, RubberduckParserState state, IPersistanceService<CodeInspectionSettings> settings)
: base(state, CodeInspectionSeverity.Suggestion)
{
_messageBox = messageBox;
_settings = settings;
}

public override string Description
{
get { return InspectionsUI.HungarianNotationInspectionName; }
}

public override CodeInspectionType InspectionType
{
get { return CodeInspectionType.MaintainabilityAndReadabilityIssues; }
}

public override IEnumerable<InspectionResultBase> GetInspectionResults()
{
var settings = _settings.Load(new CodeInspectionSettings()) ?? new CodeInspectionSettings();
var whitelistedNames = settings.WhitelistedIdentifiers.Select(s => s.Identifier).ToList();

var hungarians = UserDeclarations
.Where(declaration => !whitelistedNames.Contains(declaration.IdentifierName) &&
TargetDeclarationTypes.Contains(declaration.DeclarationType) &&
HungarianIdentifierRegex.IsMatch(declaration.IdentifierName))
.Select(issue => new IdentifierNameInspectionResult(this, issue, State, _messageBox, _settings))
.ToList();
return hungarians;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
var matches = BuiltInDeclarations.Where(item =>
item.ProjectName == "Excel" &&
Targets.Contains(item.IdentifierName) &&
item.ParentDeclaration.ComponentName == "_Global" &&
(item.ParentDeclaration.ComponentName == "_Global" || item.ParentDeclaration.ComponentName == "Global") &&
item.AsTypeName == "Range").ToList();

var issues = matches.Where(item => item.References.Any())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ public ImplicitActiveWorkbookReferenceInspection(RubberduckParserState state)
private static readonly string[] ParentScopes =
{
"_Global",
"Global",
"_Application",
"Application",
"Sheets",
//"Worksheets",
};
Expand All @@ -37,11 +39,10 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
.Where(item => item.ProjectName == "Excel" && ParentScopes.Contains(item.ComponentName)
&& item.References.Any(r => Targets.Contains(r.IdentifierName)))
.SelectMany(declaration => declaration.References.Distinct())
.Where(item => Targets.Contains(item.IdentifierName))
.ToList();

return issues.Select(issue =>
new ImplicitActiveWorkbookReferenceInspectionResult(this, issue));
var filtered = issues.Where(item => Targets.Contains(item.IdentifierName));
return filtered.Select(issue => new ImplicitActiveWorkbookReferenceInspectionResult(this, issue));
}
}
}
83 changes: 83 additions & 0 deletions RetailCoder.VBE/Inspections/MemberNotOnInterfaceInspection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Inspections.Resources;
using Rubberduck.Inspections.Results;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using Rubberduck.VBEditor;

namespace Rubberduck.Inspections
{
public sealed class MemberNotOnInterfaceInspection : InspectionBase
{
private static readonly List<Type> InterestingTypes = new List<Type>
{
typeof(VBAParser.MemberAccessExprContext),
typeof(VBAParser.WithMemberAccessExprContext),
typeof(VBAParser.DictionaryAccessExprContext),
typeof(VBAParser.WithDictionaryAccessExprContext)
};

public MemberNotOnInterfaceInspection(RubberduckParserState state, CodeInspectionSeverity defaultSeverity = CodeInspectionSeverity.Warning)
: base(state, defaultSeverity)
{
}

public override string Meta { get { return InspectionsUI.MemberNotOnInterfaceInspectionMeta; } }
public override string Description { get { return InspectionsUI.MemberNotOnInterfaceInspectionName; } }
public override CodeInspectionType InspectionType { get { return CodeInspectionType.CodeQualityIssues; } }

public override IEnumerable<InspectionResultBase> GetInspectionResults()
{
var targets = Declarations.Where(decl => decl.AsTypeDeclaration != null &&
decl.AsTypeDeclaration.DeclarationType == DeclarationType.ClassModule &&
((ClassModuleDeclaration)decl.AsTypeDeclaration).IsExtensible &&
decl.References.Any(usage => InterestingTypes.Contains(usage.Context.Parent.GetType())))
.ToList();

//Unfortunately finding implemented members is fairly expensive, so group by the return type.
return (from access in targets.GroupBy(t => t.AsTypeDeclaration)
let typeDeclaration = access.Key
let typeMembers = new HashSet<string>(BuiltInDeclarations.Where(d => d.ParentDeclaration != null && d.ParentDeclaration.Equals(typeDeclaration))
.Select(d => d.IdentifierName)
.Distinct())
from references in access.Select(usage => usage.References.Where(r => InterestingTypes.Contains(r.Context.Parent.GetType())))
from reference in references.Where(r => !r.IsInspectionDisabled(AnnotationName))
let identifier = reference.Context.Parent.GetChild(reference.Context.Parent.ChildCount - 1)
where !typeMembers.Contains(identifier.GetText())
let pseudoDeclaration = CreatePseudoDeclaration((ParserRuleContext) identifier, reference)
where !pseudoDeclaration.Annotations.Any()
select new MemberNotOnInterfaceInspectionResult(this, pseudoDeclaration, (ParserRuleContext) identifier, typeDeclaration))
.Cast<InspectionResultBase>().ToList();
}

//Builds a throw-away Declaration for the indentifiers found by the inspection. These aren't (and shouldn't be) created by the parser.
//Used to pass to the InspectionResult to make it selectable.
private static Declaration CreatePseudoDeclaration(ParserRuleContext context, IdentifierReference reference)
{
return new Declaration(
new QualifiedMemberName(reference.QualifiedModuleName, context.GetText()),
null,
null,
string.Empty,
string.Empty,
false,
false,
Accessibility.Implicit,
DeclarationType.Variable,
context,
context.GetSelection(),
false,
null,
true,
null,
null,
true);
}
}
}
4 changes: 2 additions & 2 deletions RetailCoder.VBE/Inspections/ProcedureNotUsedInspection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ProcedureNotUsedInspection(RubberduckParserState state)
"Workbook_",
"Document_",
"Application_",
"Session_",
"Session_"
};

public override IEnumerable<InspectionResultBase> GetInspectionResults()
Expand All @@ -43,7 +43,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
.SelectMany(control => declarations.FindEventHandlers(control)).ToList();

var withEventFields = declarations.Where(item => item.DeclarationType == DeclarationType.Variable && item.IsWithEvents);
handlers.AddRange(withEventFields.SelectMany(field => declarations.FindEventProcedures(field)));
handlers.AddRange(withEventFields.SelectMany(declarations.FindEventProcedures));

var forms = declarations.Where(item => item.DeclarationType == DeclarationType.ClassModule
&& item.QualifiedName.QualifiedModuleName.Component.Type == ComponentType.UserForm)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Antlr4.Runtime;
using Rubberduck.Inspections.Abstract;
using Rubberduck.Inspections.Resources;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Settings;
using Rubberduck.SettingsProvider;
using Rubberduck.VBEditor;

namespace Rubberduck.Inspections.QuickFixes
{
public class AddIdentifierToWhiteListQuickFix : QuickFixBase
{
private readonly IPersistanceService<CodeInspectionSettings> _settings;
private readonly Declaration _target;

public AddIdentifierToWhiteListQuickFix(ParserRuleContext context, QualifiedSelection selection, Declaration target, IPersistanceService<CodeInspectionSettings> settings)
: base(context, selection, InspectionsUI.WhiteListIdentifierQuickFix)
{
_settings = settings;
_target = target;
}

public override void Fix()
{
var inspectionSettings = _settings.Load(new CodeInspectionSettings()) ?? new CodeInspectionSettings();
var whitelist = inspectionSettings.WhitelistedIdentifiers;
inspectionSettings.WhitelistedIdentifiers =
whitelist.Concat(new[] { new WhitelistedIdentifierSetting(_target.IdentifierName) }).ToArray();
_settings.Save(inspectionSettings);
}
}
}
Loading