in resharper/resharper-unity/src/Unity/CSharp/Daemon/Stages/Analysis/ComponentPropertyAccessProblemAnalyzer.cs [162:243]
public void InvalidateCachedValues(IReferenceExpression key)
{
if (!myPropertiesMap.ContainsKey(key))
return;
var highlighitingElements = myPropertiesMap[key];
Assertion.Assert(highlighitingElements.Count > 0, "highlighitingElements.Length > 0");
// calculate read/write operations for property
int write = 0;
int read = 0;
int startHighlightIndex = -1;
ICSharpTreeNode readAnchor = null;
bool inlineCacheValue = false;
ICSharpTreeNode writeAnchor = null;
IReferenceExpression lastWriteExpression = null;
bool inlineRestoreValue = false;
for (int i = 0; i < highlighitingElements.Count; i++)
{
var referenceExpression = highlighitingElements[i];
var accessType = referenceExpression.GetAccessType();
if (read == 0 && write == 0)
{
readAnchor = referenceExpression.GetContainingStatementLike().NotNull("readAnchor != null");
var previousRelatedExpression = GetPreviousRelatedExpression(referenceExpression, readAnchor);
// if we have related expression before considered reference expression, we can only inline reading into statement
// Example:
// transform.Position = (transform.localPosition = Vector3.Up) + transform.position + transform.position;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// transform.localPosition is related to transform.position, but we need cache our variable
// The result is:
// var cache = transform.position;
// transform.position = (transform.localPosition = Vector3.Up) + (cache = transform.position) + cache;
inlineCacheValue = previousRelatedExpression != null;
}
if (accessType.HasFlag(ExpressionAccessType.Write))
{
write++;
lastWriteExpression = referenceExpression;
}
if (accessType.HasFlag(ExpressionAccessType.Read))
{
read++;
}
if (startHighlightIndex == -1 && (read == 2|| write == 2 | read + write == 3))
{
startHighlightIndex = i;
}
}
if (lastWriteExpression != null)
{
writeAnchor = lastWriteExpression.GetContainingStatementLike().NotNull("writeAnchor != null");
if (writeAnchor is IReturnStatement ||
writeAnchor is IYieldStatement yieldStatement && yieldStatement.StatementType == YieldStatementType.YIELD_RETURN)
{
inlineRestoreValue = true;
} else {
var relatedExpressions = GetFinder(lastWriteExpression).GetRelatedExpressions(writeAnchor, lastWriteExpression);
inlineRestoreValue = relatedExpressions.Any();
}
}
if (startHighlightIndex != -1)
{
for (int i = startHighlightIndex; i < highlighitingElements.Count; i++)
{
var warning = new InefficientPropertyAccessWarning(highlighitingElements[i], highlighitingElements,
readAnchor, inlineCacheValue, writeAnchor, inlineRestoreValue);
myConsumer.AddHighlighting(warning);
}
}
myPropertiesMap.Remove(key);
}