Skip to content

Commit

Permalink
UDT-typed fields no longer cause a VariableNotAssignedInspectionResult
Browse files Browse the repository at this point in the history
  • Loading branch information
retailcoder committed Mar 8, 2015
1 parent 2a6eef1 commit 1ca3c27
Showing 1 changed file with 26 additions and 14 deletions.
40 changes: 26 additions & 14 deletions RetailCoder.VBE/Inspections/IdentifierUsageInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class IdentifierUsageInspector
private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _fields;
private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _locals;
private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _parameters;
private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _userDefinedTypes = new HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>>();

private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _assignments;
private readonly HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _usages;
Expand Down Expand Up @@ -171,18 +172,8 @@ public IEnumerable<QualifiedContext<VBParser.AmbiguousIdentifierContext>> Unassi
return _unassignedFields;
}

var userTypes = _fields.Select(field => field.Context.Parent)
.OfType<VBParser.TypeStmtContext>()
.Select(t => t.AmbiguousIdentifier());

var userTypeFields = _fields.Select(field => field.Context.Parent)
.OfType<VBParser.VariableSubStmtContext>()
.Where(v => v.AsTypeClause() != null
&& userTypes.Any(udt => udt.GetText() == v.AsTypeClause().Type().GetText()))
.Select(v => v.AmbiguousIdentifier());

_unassignedFields = new HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>>(
_fields.Where(context => userTypeFields.All(f => f.GetText() != context.Context.GetText()) // note: weak
_fields.Where(context => !IsUserDefinedType(context.Context.Parent as VBParser.VariableSubStmtContext)
&& context.Context.Parent.GetType() != typeof(VBParser.ConstSubStmtContext))
.Where(field => _assignments.Where(assignment => assignment.QualifiedName.Equals(field.QualifiedName))
.All(assignment => field.Context.GetText() != assignment.Context.GetText()))
Expand All @@ -191,6 +182,22 @@ public IEnumerable<QualifiedContext<VBParser.AmbiguousIdentifierContext>> Unassi
return _unassignedFields;
}

private bool IsUserDefinedType(VBParser.VariableSubStmtContext context)
{
if (context == null)
{
return false;
}

var type = context.AsTypeClause() == null
? string.Empty
: context.AsTypeClause().Type().GetText();

// note: scoping issue; a private type could be used in another module (but that wouldn't compile)
// Rubberduck inspections assume VBA code compiles though.
return _userDefinedTypes.Any(udt => udt.Context.GetText() == type);
}

private HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> _unassignedLocals;
/// <summary>
/// Gets all procedure-scope locals that are not assigned.
Expand Down Expand Up @@ -313,11 +320,11 @@ private HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> GetGlobal
var listener = new DeclarationSectionListener(module.QualifiedName);
var declarations = module.ParseTree
.GetContexts<DeclarationSectionListener, ParserRuleContext>(listener)
.Select(declaration => declaration.Context)
.OfType<VBParser.VariableStmtContext>()
.Select(declaration => declaration.Context).OfType<VBParser.VariableStmtContext>()
.Where(declaration => IsGlobal(declaration.Visibility()))
.SelectMany(declaration => declaration.VariableListStmt().VariableSubStmt())
.Select(identifier => identifier.AmbiguousIdentifier().ToQualifiedContext(scope.QualifiedName));
.Select(identifier => identifier.AmbiguousIdentifier().ToQualifiedContext(scope.QualifiedName))
.ToList();

result.AddRange(declarations);
}
Expand All @@ -338,6 +345,11 @@ private HashSet<QualifiedContext<VBParser.AmbiguousIdentifierContext>> GetGlobal
&& global.Context.GetText() != field.Context.GetText()))
.ToList();

foreach (var udt in declarations.Where(declaration => declaration.Context.Parent is VBParser.TypeStmtContext))
{
_userDefinedTypes.Add(((VBParser.TypeStmtContext)udt.Context.Parent).AmbiguousIdentifier().ToQualifiedContext(module.QualifiedName));
}

result.AddRange(declarations.Select(declaration => declaration.Context)
.OfType<VBParser.VariableSubStmtContext>()
.Select(context =>
Expand Down

0 comments on commit 1ca3c27

Please sign in to comment.