Esempio n. 1
0
            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();
                    }
                }