in resharper/resharper-unity/src/Unity/CSharp/Feature/Services/QuickFixes/CachePropertyValueQuickFix.cs [44:142]
protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
{
var factory = CSharpElementFactory.GetInstance(myHighlightedReference);
var property = (myHighlightedReference.Reference.Resolve().DeclaredElement as IProperty).NotNull();
// save declaration (in case of expression lambda)
var declaration = myHighlightedReference.GetContainingFunctionLikeDeclarationOrClosure();
var type = property.Type;
var name = GetUniqueName(myHighlightedReference, property.ShortName);
IReferenceExpression originValue = myHighlightedReference.Copy();
for (var i = 0; i < myReferences.Count; i++)
{
var reference = myReferences[i];
myReferences[i] = reference.ReplaceBy(factory.CreateReferenceExpression("$0", name));
}
var firstReference = myReferences[0];
if (declaration is IExpressionBodyOwnerDeclaration expressionBodyOwnerDeclaration
&& expressionBodyOwnerDeclaration.GetCodeBody().ExpressionBody != null)
{
using (var marker = new DisposableMarker<IReferenceExpression>(firstReference))
{
var body = expressionBodyOwnerDeclaration.EnsureStatementMemberBody();
HandleExpressionBody(body, factory, type, name, marker, originValue);
}
return null;
}
if (declaration is ILambdaExpression lambdaExpression
&& lambdaExpression.GetCodeBody().ExpressionBody != null)
{
using (var marker = new DisposableMarker<IReferenceExpression>(firstReference))
{
var body = lambdaExpression.EnsureStatementLambda();
HandleExpressionBody(body, factory, type, name, marker, originValue);
}
return null;
}
Assertion.Assert(myCacheAnchor is ICSharpStatement, "myInlineCache is IStatement");
var statementCacheAnchor = (ICSharpStatement) myCacheAnchor;
if (myInlineCache) // replace first read with assignment expression
{
foreach (var reference in myReferences)
{
if (reference.GetContainingStatement() != myCacheAnchor)
continue;
// is write first???
// example: var x = (transform.position = Vector3.Up) + transform.position + transform.position ...
// if yes, we have already save our variable in cycle above, if no use inline to cache.
if (AssignmentExpressionNavigator.GetByDest(reference.GetContainingParenthesizedExpression()) == null)
{
reference.ReplaceBy(factory.CreateExpression("($0 = $1)", name, originValue.Copy()));
}
break;
}
var cacheStatement = factory.CreateStatement("$0 $1;", type ,name);
StatementUtil.InsertStatement(cacheStatement, ref statementCacheAnchor, true);
}
else
{
var cacheStatement = factory.CreateStatement("var $0 = $1;", name, originValue.Copy());
StatementUtil.InsertStatement(cacheStatement, ref statementCacheAnchor, true);
}
if (myRestoreAnchor != null)
{
Assertion.Assert(myRestoreAnchor is ICSharpStatement, "myRestoreAnchor is IStatement");
var statementRestoreAnchor = (ICSharpStatement) myRestoreAnchor;
if (myInlineRestore)
{
var size = myReferences.Count;
for (int i = size - 1; i >= 0; i--)
{
var reference = myReferences[i];
if (reference.GetContainingStatement() == myRestoreAnchor)
{
reference.ReplaceBy(factory.CreateReferenceExpression("$0", originValue));
break;
}
}
}
else
{
var restoreStatement = factory.CreateStatement("$0 = $1;", originValue, name);
StatementUtil.InsertStatement(restoreStatement, ref statementRestoreAnchor, false);
}
}
return null;
}