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(); } }