Skip to content
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Security.Policy;
using Rubberduck.Common;
using Rubberduck.Parsing;
using Rubberduck.Parsing.Grammar;
using Rubberduck.Parsing.Symbols;
using Rubberduck.Parsing.VBA;
using NLog;
using Rubberduck.Inspections.Abstract;
Expand Down Expand Up @@ -39,52 +41,30 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
Logger.Debug("Aborting GetInspectionResults because ParseTree results were not passed");
return new InspectionResultBase[] { };
}
var subStmts = ParseTreeResults.OfType<QualifiedContext<VBAParser.ArgListContext>>()
.Where(context => context.Context.Parent is VBAParser.SubStmtContext)
.Select(context => (VBAParser.SubStmtContext)context.Context.Parent)
.ToList();

var subStmtsNotImplementingInterfaces = subStmts
.Where(c =>
{
var declaration =
UserDeclarations.SingleOrDefault(d => d.Context == c);

if (UserDeclarations.FindInterfaceMembers().Contains(declaration))
{
return false;
}

var interfaceImplementation = UserDeclarations.FindInterfaceImplementationMembers().SingleOrDefault(m => m.Equals(declaration));
if (interfaceImplementation == null)
{
return true;
}

var interfaceMember = UserDeclarations.FindInterfaceMember(interfaceImplementation);

return interfaceMember == null;
});

var subStmtsNotImplementingEvents = subStmts
.Where(c =>
{
var declaration = UserDeclarations.SingleOrDefault(d => d.Context == c);

if (declaration == null) { return false; } // rather be safe than sorry

return UserDeclarations.Where(item => item.IsWithEvents)
.All(withEvents => UserDeclarations.FindEventProcedures(withEvents) == null) &&
!State.AllDeclarations.FindBuiltInEventHandlers().Contains(declaration);
});

return ParseTreeResults
.Where(result => result.Context.Parent is VBAParser.SubStmtContext &&
subStmtsNotImplementingInterfaces.Contains(result.Context.Parent) &&
subStmtsNotImplementingEvents.Contains(result.Context.Parent)
&& !IsIgnoringInspectionResultFor(result.ModuleName.Component, result.Context.Start.Line))
.Select(result => new ProcedureCanBeWrittenAsFunctionInspectionResult(this, State, result,
new QualifiedContext<VBAParser.SubStmtContext>(result.ModuleName, result.Context.Parent as VBAParser.SubStmtContext)));
var userDeclarations = UserDeclarations.ToList();
var allDeclarations = State.AllDeclarations.ToList();

var contextLookup = userDeclarations.Where(decl => decl.Context != null).ToDictionary(decl => decl.Context);

var ignored = new HashSet<Declaration>( State.DeclarationFinder.FindAllInterfaceMembers()
.Concat(State.DeclarationFinder.FindAllInterfaceImplementingMembers())
.Concat(allDeclarations.FindBuiltInEventHandlers())
.Concat(userDeclarations.Where(item => item.IsWithEvents)));

return ParseTreeResults.Where(context => context.Context.Parent is VBAParser.SubStmtContext)
.Select(context => contextLookup[(VBAParser.SubStmtContext)context.Context.Parent])
.Where(decl => !IsIgnoringInspectionResultFor(decl, AnnotationName) &&
!ignored.Contains(decl) &&
userDeclarations.Where(item => item.IsWithEvents)
.All(withEvents => userDeclarations.FindEventProcedures(withEvents) == null) &&
!allDeclarations.FindBuiltInEventHandlers().Contains(decl))
.Select(result => new ProcedureCanBeWrittenAsFunctionInspectionResult(
this,
State,
new QualifiedContext<VBAParser.ArgListContext>(result.QualifiedName,result.Context.GetChild<VBAParser.ArgListContext>(0)),
new QualifiedContext<VBAParser.SubStmtContext>(result.QualifiedName, (VBAParser.SubStmtContext)result.Context))
);
}

public class SingleByRefParamArgListListener : VBAParserBaseListener
Expand Down
5 changes: 5 additions & 0 deletions Rubberduck.Parsing/ComReflection/ComModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ public ComMember DefaultMember
get { return null; }
}

public bool IsExtensible
{
get { return false; }
}

private readonly List<ComField> _fields = new List<ComField>();
public IEnumerable<ComField> Fields
{
Expand Down
3 changes: 2 additions & 1 deletion Rubberduck.Parsing/ComReflection/ComType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ public interface IComType : IComBase
bool IsAppObject { get; }
bool IsPreDeclared { get; }
bool IsHidden { get; }
bool IsRestricted { get; }
bool IsRestricted { get; }
}

public interface IComTypeWithMembers : IComType
{
IEnumerable<ComMember> Members { get; }
ComMember DefaultMember { get; }
bool IsExtensible { get; }
}

public interface IComTypeWithFields : IComType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ private static Attributes GetModuleAttributes(IComType module)
{
attributes.AddGlobalClassAttribute();
}
if (module as ComInterface != null && ((ComInterface)module).IsExtensible)
if (module as IComTypeWithMembers != null && ((IComTypeWithMembers)module).IsExtensible)
{
attributes.AddExtensibledClassAttribute();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ private static ParseCoordinator ArrangeParser(string inputCode)
[TestCategory("Inspections")]
public void MemberNotOnInterface_ReturnsResult_UnDeclaredMember()
{
Assert.Inconclusive("Pending post-merge fix.");
const string inputCode =
@"Sub Foo()
Dim dict As Dictionary
Expand All @@ -63,7 +62,6 @@ Dim dict As Dictionary
[TestCategory("Inspections")]
public void MemberNotOnInterface_ReturnsResult_UnDeclaredInterfaceMember()
{
Assert.Inconclusive("Pending post-merge fix.");
const string inputCode =
@"Sub Foo()
Dim dict As Dictionary
Expand All @@ -88,7 +86,6 @@ Dim dict As Dictionary
[TestCategory("Inspections")]
public void MemberNotOnInterface_ReturnsResult_UnDeclaredMemberOnParameter()
{
Assert.Inconclusive("Pending post-merge fix.");
const string inputCode =
@"Sub Foo(dict As Dictionary)
dict.NonMember
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,6 @@ Dim target As Range
[TestCategory("Inspections")]
public void ObjectVariableNotSet_FunctionReturnsArrayOfType_ReturnsNoResult()
{
Assert.Inconclusive("Pending reserialization.");
const string inputCode = @"
Private Function GetSomeDictionaries() As Dictionary()
Dim temp(0 To 1) As Worksheet
Expand Down
2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/ADODB.6.1.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/Excel.1.8.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/MSForms.2.0.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/MSXML2.6.0.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/Office.2.7.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/SHDocVw.1.1.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/Scripting.1.0.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/VBA.4.2.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/VBIDE.5.3.xml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion RubberduckTests/Testfiles/Resolver/stdole.2.0.xml

Large diffs are not rendered by default.