Skip to content

Commit

Permalink
Add qualifying references to identifier references
Browse files Browse the repository at this point in the history
There are multiple pieces in the codebase that need information about the qualifying reference/declaration of a reference, e.g. to determine whether the reference is a member access on the return value of a specific member. Currently, checking this is achieved by navigating the parse tree each time, also taking into account with blocks. This commit moves the qualifier resolution to the BoundExpressionVisitor, which already has all the information present to easily determine the qualifying reference.

The following qualifier structure has been implemented:

- Member accesses are qualified by the reference for their lExpression.
- Member accesses return their own reference as the one qualifying a potential access.
- For (recursive) default member accesses the innermost access is qualified by the reference of the lExpression and each other access is qualified by the immediately contained one.
- For (recursive) default member accesses the outermost access is returned as potentially qualifying.
- Array accessed are qualified by the reference of their lExpression (potentially with default member accesses in between), i.e. by the reference of the array variable or array returning member.
- Array accesses return themselves as potentially qualifying. (To get the array, one has to go up the chain again.)
- Index accesses other than array and default member accesses are qualified by the reference of their lExpression.
- Index accesses other than array and default member accesses return the reference of their lExpression as potentially qualifying.
- Dictionary access expressions work like default member access expressions.
- Other expressions neither take nor return a reference as (potentially) qualifying.
  • Loading branch information
MDoerner committed Apr 22, 2021
1 parent a1f784d commit f927335
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 203 deletions.
10 changes: 6 additions & 4 deletions Rubberduck.Parsing/Symbols/Declaration.cs
Expand Up @@ -8,7 +8,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Rubberduck.VBEditor.SafeComWrappers.Abstract;
using Rubberduck.Parsing.Annotations.Concrete;

namespace Rubberduck.Parsing.Symbols
Expand Down Expand Up @@ -365,7 +364,7 @@ private bool IsObjectOrObjectArray
}
}

public void AddReference(
public IdentifierReference AddReference(
QualifiedModuleName module,
Declaration scope,
Declaration parent,
Expand All @@ -382,7 +381,8 @@ private bool IsObjectOrObjectArray
int defaultMemberRecursionDepth = 0,
bool isArrayAccess = false,
bool isProcedureCoercion = false,
bool isInnerRecursiveDefaultMemberAccess = false
bool isInnerRecursiveDefaultMemberAccess = false,
IdentifierReference qualifyingReference = null
)
{
var oldReference = _references.FirstOrDefault(r =>
Expand Down Expand Up @@ -415,8 +415,10 @@ private bool IsObjectOrObjectArray
defaultMemberRecursionDepth,
isArrayAccess,
isProcedureCoercion,
isInnerRecursiveDefaultMemberAccess);
isInnerRecursiveDefaultMemberAccess,
qualifyingReference);
_references.AddOrUpdate(newReference, 1, (key, value) => 1);
return newReference;
}

/// <summary>
Expand Down
6 changes: 5 additions & 1 deletion Rubberduck.Parsing/Symbols/IdentifierReference.cs
Expand Up @@ -29,7 +29,8 @@ public class IdentifierReference : IEquatable<IdentifierReference>
int defaultMemberRecursionDepth = 0,
bool isArrayAccess = false,
bool isProcedureCoercion = false,
bool isInnerRecursiveDefaultMemberAccess = false)
bool isInnerRecursiveDefaultMemberAccess = false,
IdentifierReference qualifyingReference = null)
{
ParentScoping = parentScopingDeclaration;
ParentNonScoping = parentNonScopingDeclaration;
Expand All @@ -47,6 +48,7 @@ public class IdentifierReference : IEquatable<IdentifierReference>
IsProcedureCoercion = isProcedureCoercion;
Annotations = annotations ?? new List<IParseTreeAnnotation>();
IsInnerRecursiveDefaultMemberAccess = isInnerRecursiveDefaultMemberAccess;
QualifyingReference = qualifyingReference;
}

public QualifiedSelection QualifiedSelection { get; }
Expand All @@ -67,6 +69,8 @@ public class IdentifierReference : IEquatable<IdentifierReference>
/// </summary>
public Declaration ParentNonScoping { get; }

public IdentifierReference QualifyingReference { get; }

public bool IsAssignment { get; }

public bool IsSetAssignment { get; }
Expand Down

0 comments on commit f927335

Please sign in to comment.