Skip to content

Commit

Permalink
icsharpcode#3134: A bug in DetermineEffectiveAccessibility prevented …
Browse files Browse the repository at this point in the history
…references from the enclosing type to public members of private nested types to be found.
  • Loading branch information
siegfriedpammer authored and matt committed Jul 30, 2024
1 parent 37310a2 commit 6d98e31
Showing 1 changed file with 20 additions and 18 deletions.
38 changes: 20 additions & 18 deletions ILSpy/Analyzers/AnalyzerScope.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,7 @@ public AnalyzerScope(AssemblyList assemblyList, IEntity entity)
AssemblyList = assemblyList;
assemblyListSnapshot = assemblyList.GetSnapshot();
AnalyzedSymbol = entity;
if (entity is ITypeDefinition type)
{
typeScope = type;
effectiveAccessibility = DetermineEffectiveAccessibility(ref typeScope, Accessibility.Public);
}
else
{
typeScope = entity.DeclaringTypeDefinition;
effectiveAccessibility = DetermineEffectiveAccessibility(ref typeScope, entity.Accessibility);
}
DetermineEffectiveAccessibility(entity, out typeScope, out effectiveAccessibility);
IsLocal = effectiveAccessibility.LessThanOrEqual(Accessibility.Private);
}

Expand Down Expand Up @@ -112,20 +103,31 @@ public IEnumerable<ITypeDefinition> GetTypesInScope(CancellationToken ct)
}
}

static Accessibility DetermineEffectiveAccessibility(ref ITypeDefinition typeScope, Accessibility memberAccessibility)
static void DetermineEffectiveAccessibility(IEntity input, out ITypeDefinition typeScope, out Accessibility accessibility)
{
Accessibility accessibility = memberAccessibility;
var ts = typeScope;
while (ts != null && !accessibility.LessThanOrEqual(Accessibility.Private))
if (input is ITypeDefinition td)
{
accessibility = Accessibility.Public;
typeScope = td;
}
else
{
accessibility = accessibility.Intersect(ts.Accessibility);
typeScope = ts;
ts = ts.DeclaringTypeDefinition;
accessibility = input.Accessibility;
typeScope = input.DeclaringTypeDefinition;
}
// Once we reach a private entity, we leave the loop with typeScope set to the class that
// contains the private entity = the scope that needs to be searched.
// Otherwise (if we don't find a private entity) we return the top-level class.
return accessibility;
var prevTypeScope = typeScope;
while (typeScope != null && !accessibility.LessThanOrEqual(Accessibility.Private))
{
accessibility = accessibility.Intersect(typeScope.Accessibility);
typeScope = prevTypeScope.DeclaringTypeDefinition;
}
if (typeScope == null)
{
typeScope = prevTypeScope;
}
}

#region Find modules
Expand Down

0 comments on commit 6d98e31

Please sign in to comment.