in resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/UnityEventFunctionAnalyzer.cs [34:116]
protected override void Analyze(IMemberOwnerDeclaration element, ElementProblemAnalyzerData data,
IHighlightingConsumer consumer)
{
var typeElement = element.DeclaredElement;
if (typeElement == null)
return;
if (!Api.IsUnityType(typeElement))
return;
var project = element.GetProject();
if (project == null)
return;
var unityVersion = Api.GetNormalisedActualVersion(project);
var map = new CompactOneToListMap<UnityEventFunction, Candidate>(new UnityEventFunctionKeyComparer());
foreach (var instance in typeElement.GetAllClassMembers<IMethod>())
{
var unityEventFunction = Api.GetUnityEventFunction(instance.Member, unityVersion, out var match);
if (unityEventFunction != null)
map.AddValue(unityEventFunction, new Candidate(instance.Member, match));
}
foreach (var (function, candidates) in map)
{
if (candidates.Count == 1)
{
// Only one function, mark it as a unity function, even if it's not an exact match
// We'll let other inspections handle invalid signatures
var method = candidates[0].Method;
PutEventToCustomData(method, data);
AddMethodSignatureInspections(consumer, method, function, candidates[0].Match);
}
else
{
var hasExactMatch = false;
// All exact matches should be marked as an event function
var duplicates = new FrugalLocalList<IMethod>();
foreach (var candidate in candidates)
{
if (candidate.Match == MethodSignatureMatch.ExactMatch)
{
hasExactMatch = true;
if (Equals(candidate.Method.GetContainingType(), typeElement))
{
PutEventToCustomData(candidate.Method, data);
duplicates.Add(candidate.Method);
}
}
}
// Multiple exact matches should be marked as duplicate/ambiguous
if (duplicates.Count > 1)
{
foreach (var method in duplicates)
{
foreach (var declaration in method.GetDeclarations())
{
consumer.AddHighlighting(
new DuplicateEventFunctionWarning((IMethodDeclaration) declaration));
}
}
}
// If there are no exact matches, mark all as unity functions, with inspections
// to fix up signature errors
if (!hasExactMatch)
{
foreach (var candidate in candidates)
{
if (Equals(candidate.Method.GetContainingType(), typeElement))
{
var method = candidate.Method;
PutEventToCustomData(method, data);
AddMethodSignatureInspections(consumer, method, function, candidate.Match);
}
}
}
}
}
}