private Expression WidenType <T>(Expression source) { var tref = ShaderDefinition.ToCecil(typeof(T)); var n = new ObjectCreateExpression(AstBuilder.ConvertType(tref), new[] { source.Clone() }); return(n); }
private void WritePart(Expression expression, bool toString, ResolveResult rr) { if (toString) { var toStringMethod = rr.Type.GetMembers().FirstOrDefault(m => { if (m.Name == "ToString" && !m.IsStatic && m.ReturnType.IsKnownType(KnownTypeCode.String) && m.IsOverride) { var method = m as IMethod; if (method != null && method.Parameters.Count == 0 && method.TypeParameters.Count == 0) { return(true); } } return(false); }); if (toStringMethod != null) { var inline = this.Emitter.GetInline(toStringMethod); if (inline != null) { var writer = new Writer { InlineCode = inline, Output = this.Emitter.Output, IsNewLine = this.Emitter.IsNewLine }; this.Emitter.IsNewLine = false; this.Emitter.Output = new StringBuilder(); expression.AcceptVisitor(this.Emitter); string result = this.Emitter.Output.ToString(); this.Emitter.Output = writer.Output; this.Emitter.IsNewLine = writer.IsNewLine; var argsInfo = new ArgumentsInfo(this.Emitter, expression, rr); argsInfo.ArgumentsExpressions = new Expression[] { expression }; argsInfo.ArgumentsNames = new string[] { "this" }; argsInfo.ThisArgument = result; new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode).Emit(); //result = writer.InlineCode.Replace("{this}", result); //this.Write(result); return; } } expression.AcceptVisitor(this.Emitter); } else { expression.AcceptVisitor(this.Emitter); } }
protected internal Init(NRefactory.VariableInitializer variableInitializer, IScope scope, INRefcatoryExpressionVisitor visitor) : base(scope, visitor) { NRefactory.Expression initializer = null; _variableInitializer = variableInitializer; initializer = variableInitializer.Initializer; }
private object EvaluateBinaryOperatorExpression(ICSharpCode.NRefactory.CSharp.Expression result, CodeContext codeContext) { ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression binaryExpression = result as ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression; object left = EvaluateExpression(binaryExpression.Left, codeContext); object right = EvaluateExpression(binaryExpression.Right, codeContext); switch (binaryExpression.Operator) { case BinaryOperatorType.Add: return(PrimitiveOperationManager.Self.AddObjects(left, right)); case BinaryOperatorType.ConditionalAnd: return((bool)left && (bool)right); case BinaryOperatorType.ConditionalOr: return((bool)left || (bool)right); case BinaryOperatorType.Divide: return(PrimitiveOperationManager.Self.DivideObjects(left, right)); case BinaryOperatorType.Equality: return(left == right); case BinaryOperatorType.GreaterThan: return(PrimitiveOperationManager.Self.GreaterThan(left, right)); case BinaryOperatorType.GreaterThanOrEqual: return(left == right || PrimitiveOperationManager.Self.GreaterThan(left, right)); case BinaryOperatorType.InEquality: return(left != right); case BinaryOperatorType.LessThan: return(PrimitiveOperationManager.Self.LessThan(left, right)); case BinaryOperatorType.LessThanOrEqual: return(left == right || PrimitiveOperationManager.Self.LessThan(left, right)); case BinaryOperatorType.Multiply: return(PrimitiveOperationManager.Self.MultiplyObjects(left, right)); case BinaryOperatorType.Subtract: return(PrimitiveOperationManager.Self.SubtractObjects(left, right)); default: return(null); } }
void DecompileQueries(AstNode node) { Expression query = DecompileQuery(node as InvocationExpression); if (query != null) { node.ReplaceWith(query); } for (AstNode child = (query ?? node).FirstChild; child != null; child = child.NextSibling) { DecompileQueries(child); } }
private object GetCaller(ICSharpCode.NRefactory.CSharp.Expression expression, CodeContext codeContext) { object caller; if (expression is MemberReferenceExpression) { MemberReferenceExpression mre = expression as MemberReferenceExpression; caller = EvaluateExpression(mre.Target, codeContext); if (caller == null) { Type type = TypeManager.GetTypeFromString(mre.Target.GetText()); if (type != null) { TypeReference typeReference = new TypeReference(); typeReference.Type = type; caller = typeReference; } } if (caller == null) { caller = codeContext.ContainerInstance; } return(caller); } else if (expression is InvocationExpression) { return(codeContext.ContainerInstance); } else if (expression is IdentifierExpression) { return(codeContext.ContainerInstance); } else { return(null); } }
/// <summary>Matches simple lambdas of the form "a => b"</summary> bool MatchSimpleLambda(Expression expr, out string parameterName, out Expression body) { expr = StripCastAndParenthasis(expr); LambdaExpression lambda = expr as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 1 && lambda.Body is Expression) { ParameterDeclaration p = lambda.Parameters.Single(); if (p.ParameterModifier == ParameterModifier.None) { parameterName = p.Name; body = (Expression)lambda.Body; return(true); } } parameterName = null; body = null; return(false); }
private static Expression StripCastAndParenthasis(Expression expr) { var ce = expr as CastExpression; var pe = expr as ParenthesizedExpression; while (ce != null || pe != null) { if (ce != null) { expr = ce.Expression; ce = expr as CastExpression; pe = expr as ParenthesizedExpression; } if (pe != null) { expr = pe.Expression; pe = expr as ParenthesizedExpression; ce = expr as CastExpression; } } return(expr); }
protected internal New(NRefactory.ObjectCreateExpression objectCreation, IScope scope, INRefcatoryExpressionVisitor visitor) : base(scope, visitor) { _objectCreation = objectCreation; if (!objectCreation.Type.IsNull) { InternalType = objectCreation.Type.AcceptVisitor(Visitor, ParentScope).Type; if (objectCreation.Initializer != null) { if (objectCreation.Arguments.Count == 2) { Expression expression; NRefactory.Expression @this = objectCreation.Arguments.First(); NRefactory.Expression func = objectCreation.Arguments.Last(); if (TryHandleAnonymousMethod(@this, func as NRefactory.InvocationExpression, out expression)) { Expression = expression; return; } } if (objectCreation.Initializer != NRefactory.ArrayInitializerExpression.Null) { Expression = objectCreation.Initializer.AcceptVisitor(Visitor, ParentScope); return; } } Expression = BuildConstructor(); } else { Expression = HandleAnonymousType(); } }
private bool TryHandleAnonymousMethod(NRefactory.Expression @this, NRefactory.InvocationExpression func, out Expression outExpression) { MethodReference methodReference = null; NRefactory.IdentifierExpression methodIdentifier = null; outExpression = null; if (func != null) { methodIdentifier = func.Arguments.Single() as NRefactory.IdentifierExpression; methodReference = methodIdentifier.Annotation <MethodReference>(); if (methodReference != null) { object target = null; Delegate @delegate = null; var methodInfo = methodReference.GetActualMethod() as MethodInfo; if (!methodInfo.IsStatic) { var context = RootScope.Context; if (context != null) { target = context.Value; } } @delegate = methodInfo.CreateDelegate(InternalType, target); outExpression = Expression.Constant(@delegate); return(true); } } return(false); }
bool TryRemoveTransparentIdentifier(QueryExpression query, QueryFromClause fromClause, QueryExpression innerQuery) { if (!IsTransparentIdentifier(fromClause.Identifier)) { return(false); } Match match = selectTransparentIdentifierPattern.Match(innerQuery.Clauses.Last()); if (!match.Success) { return(false); } QuerySelectClause selectClause = (QuerySelectClause)innerQuery.Clauses.Last(); NamedExpression nae1 = match.Get <NamedExpression>("nae1").SingleOrDefault(); NamedExpression nae2 = match.Get <NamedExpression>("nae2").SingleOrDefault(); if (nae1 != null && nae1.Name != ((IdentifierExpression)nae1.Expression).Identifier) { return(false); } Expression nae2Expr = match.Get <Expression>("nae2Expr").Single(); IdentifierExpression nae2IdentExpr = nae2Expr as IdentifierExpression; if (nae2IdentExpr != null && (nae2 == null || nae2.Name == nae2IdentExpr.Identifier)) { // from * in (from x in ... select new { x = x, y = y }) ... // => // from x in ... ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } } else { // from * in (from x in ... select new { x = x, y = expr }) ... // => // from x in ... let y = expr ... fromClause.Remove(); selectClause.Remove(); // Move clauses from innerQuery to query QueryClause insertionPos = null; foreach (var clause in innerQuery.Clauses) { query.Clauses.InsertAfter(insertionPos, insertionPos = Detach(clause)); } string ident; if (nae2 != null) { ident = nae2.Name; } else if (nae2Expr is MemberReferenceExpression) { ident = ((MemberReferenceExpression)nae2Expr).MemberName; } else { throw new InvalidOperationException("Could not infer name from initializer in AnonymousTypeCreateExpression"); } query.Clauses.InsertAfter(insertionPos, new QueryLetClause { Identifier = ident, Expression = Detach(nae2Expr) }); } return(true); }
QueryExpression DecompileQuery(InvocationExpression invocation) { if (invocation == null) { return(null); } if (invocation.Parent is ParenthesizedExpression == false && invocation.Parent is QueryClause == false) { return(null); } MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression; if (mre == null) { return(null); } switch (mre.MemberName) { case "Select": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = Detach(mre.Target) }); query.Clauses.Add(new QuerySelectClause { Expression = Detach(body) }); return(query); } return(null); } case "GroupBy": { if (invocation.Arguments.Count == 2) { string parameterName1, parameterName2; Expression keySelector, elementSelector; if (MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName1, out keySelector) && MatchSimpleLambda(invocation.Arguments.ElementAt(1), out parameterName2, out elementSelector) && parameterName1 == parameterName2) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName1, Expression = Detach(mre.Target) }); query.Clauses.Add(new QueryGroupClause { Projection = Detach(elementSelector), Key = Detach(keySelector) }); return(query); } } else if (invocation.Arguments.Count == 1) { string parameterName; Expression keySelector; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out keySelector)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = Detach(mre.Target) }); query.Clauses.Add(new QueryGroupClause { Projection = new IdentifierExpression(parameterName), Key = Detach(keySelector) }); return(query); } } return(null); } case "SelectMany": { if (invocation.Arguments.Count != 2) { return(null); } string parameterName; Expression collectionSelector; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(0), out parameterName, out collectionSelector)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(1) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); if (p1.Name == parameterName) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = p1.Name, Expression = Detach(mre.Target) }); query.Clauses.Add(new QueryFromClause { Identifier = p2.Name, Expression = Detach(collectionSelector) }); query.Clauses.Add(new QuerySelectClause { Expression = Detach(((Expression)lambda.Body)) }); return(query); } } return(null); } case "Where": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression body; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out body)) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = Detach(mre.Target) }); query.Clauses.Add(new QueryWhereClause { Condition = Detach(body) }); return(query); } return(null); } case "OrderBy": case "OrderByDescending": case "ThenBy": case "ThenByDescending": { if (invocation.Arguments.Count != 1) { return(null); } string parameterName; Expression orderExpression; if (MatchSimpleLambda(invocation.Arguments.Single(), out parameterName, out orderExpression)) { if (ValidateThenByChain(invocation, parameterName)) { QueryOrderClause orderClause = new QueryOrderClause(); InvocationExpression tmp = invocation; while (mre.MemberName == "ThenBy" || mre.MemberName == "ThenByDescending") { // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = Detach(orderExpression), Direction = (mre.MemberName == "ThenBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); tmp = (InvocationExpression)mre.Target; mre = (MemberReferenceExpression)tmp.Target; MatchSimpleLambda(tmp.Arguments.Single(), out parameterName, out orderExpression); } // insert new ordering at beginning orderClause.Orderings.InsertAfter( null, new QueryOrdering { Expression = Detach(orderExpression), Direction = (mre.MemberName == "OrderBy" ? QueryOrderingDirection.None : QueryOrderingDirection.Descending) }); QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = parameterName, Expression = Detach(mre.Target) }); query.Clauses.Add(orderClause); return(query); } } return(null); } case "Join": case "GroupJoin": { if (invocation.Arguments.Count != 4) { return(null); } Expression source1 = mre.Target; Expression source2 = invocation.Arguments.ElementAt(0); string elementName1, elementName2; Expression key1, key2; if (!MatchSimpleLambda(invocation.Arguments.ElementAt(1), out elementName1, out key1)) { return(null); } if (!MatchSimpleLambda(invocation.Arguments.ElementAt(2), out elementName2, out key2)) { return(null); } LambdaExpression lambda = invocation.Arguments.ElementAt(3) as LambdaExpression; if (lambda != null && lambda.Parameters.Count == 2 && lambda.Body is Expression) { ParameterDeclaration p1 = lambda.Parameters.ElementAt(0); ParameterDeclaration p2 = lambda.Parameters.ElementAt(1); if (p1.Name == elementName1 && (p2.Name == elementName2 || mre.MemberName == "GroupJoin")) { QueryExpression query = new QueryExpression(); query.Clauses.Add(new QueryFromClause { Identifier = elementName1, Expression = Detach(source1) }); QueryJoinClause joinClause = new QueryJoinClause(); joinClause.JoinIdentifier = elementName2; // join elementName2 joinClause.InExpression = Detach(source2); // in source2 joinClause.OnExpression = Detach(key1); // on key1 joinClause.EqualsExpression = Detach(key2); // equals key2 if (mre.MemberName == "GroupJoin") { joinClause.IntoIdentifier = p2.Name; // into p2.Name } query.Clauses.Add(joinClause); query.Clauses.Add(new QuerySelectClause { Expression = Detach(((Expression)lambda.Body)) }); return(query); } } return(null); } default: return(null); } }
private void WritePart(Expression expression, bool toString, ResolveResult rr, bool isCoalescing = false) { if (isCoalescing) { ConversionBlock.expressionInWork.Add(expression); } bool wrapString = false; if (this.NullStringCheck && rr.Type.IsKnownType(KnownTypeCode.String)) { wrapString = !(expression is BinaryOperatorExpression) && !(expression is PrimitiveExpression || rr.Type.IsReferenceType != null && !rr.Type.IsReferenceType.Value); } if (toString) { var toStringMethod = rr.Type.GetMembers().FirstOrDefault(m => { if (m.Name == CS.Methods.TOSTRING && !m.IsStatic && m.ReturnType.IsKnownType(KnownTypeCode.String) && m.IsOverride) { var method = m as IMethod; if (method != null && method.Parameters.Count == 0 && method.TypeParameters.Count == 0) { return(true); } } return(false); }); if (toStringMethod != null) { var inline = this.Emitter.GetInline(toStringMethod); if (inline != null) { var writer = new Writer { InlineCode = inline, Output = this.Emitter.Output, IsNewLine = this.Emitter.IsNewLine }; this.Emitter.IsNewLine = false; this.Emitter.Output = new StringBuilder(); expression.AcceptVisitor(this.Emitter); string result = this.Emitter.Output.ToString(); this.Emitter.Output = writer.Output; this.Emitter.IsNewLine = writer.IsNewLine; var argsInfo = new ArgumentsInfo(this.Emitter, expression, (IMethod)toStringMethod); argsInfo.ArgumentsExpressions = new Expression[] { expression }; argsInfo.ArgumentsNames = new string[] { "this" }; argsInfo.ThisArgument = result; new InlineArgumentsBlock(this.Emitter, argsInfo, writer.InlineCode).Emit(); return; } } } if (wrapString) { this.Write("("); } expression.AcceptVisitor(this.Emitter); if (wrapString) { this.Write(" || \"\")"); } if (isCoalescing) { ConversionBlock.expressionInWork.Remove(expression); } }
private void GetMethodInfo(ICSharpCode.NRefactory.CSharp.Expression expression, List <object> argumentValues, Type[] types, CodeContext codeContext, string invocation, object container, out MethodInfo methodInfo) { methodInfo = null; if (expression is ICSharpCode.NRefactory.CSharp.IdentifierExpression) { methodInfo = container.GetType().GetMethod(invocation, types); } else if (expression is ICSharpCode.NRefactory.CSharp.MemberReferenceExpression) { ICSharpCode.NRefactory.CSharp.MemberReferenceExpression mre = expression as ICSharpCode.NRefactory.CSharp.MemberReferenceExpression; bool doTypesHaveNull = false; foreach (var item in types) { if (item == null) { doTypesHaveNull = true; } } Type typeToCallGetMethodOn; if (container is Type) { typeToCallGetMethodOn = (container as Type); } else if (container is TypeReference) { typeToCallGetMethodOn = (container as TypeReference).Type; } else { typeToCallGetMethodOn = container.GetType(); } if (doTypesHaveNull) { // Let's hope there's no ambiguity or else we're in trouble... methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName); } else { bool shouldTryAgain = false;; try { methodInfo = typeToCallGetMethodOn.GetMethod(mre.MemberName, types); } catch { shouldTryAgain = true; } if (shouldTryAgain || methodInfo == null) { // The method doesn't exist, but it could be because // the parser evaluated the types as one type (like int) // but they are really of another type (like float). var candidates = typeToCallGetMethodOn.GetMethods(); foreach (var candidate in candidates) { if (candidate.Name == mre.MemberName && candidate.GetParameters().Length == types.Length) { methodInfo = candidate; break; } } } } } else if (expression is InvocationExpression) { InvocationExpression ie = expression as InvocationExpression; if (container is Type) { methodInfo = (container as Type).GetMethod(ie.Target.GetText(), types); } else { methodInfo = container.GetType().GetMethod(ie.Target.GetText(), types); } } else { throw new NotImplementedException(); } }
private Expression GetExpression(ICSharpCode.NRefactory.CSharp.Expression expression, ILTranslationContext data) => expression?.IsNull != false ? null : expression.AcceptVisitor(this, data).Cast <Expression>().Single();
public override AstNode VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression) { if (this.Rules.Integer == IntegerRule.Managed && (unaryOperatorExpression.Operator == UnaryOperatorType.Increment || unaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement || unaryOperatorExpression.Operator == UnaryOperatorType.Decrement || unaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement)) { var rr = this.Resolver.ResolveNode(unaryOperatorExpression, null); var expression_rr = this.Resolver.ResolveNode(unaryOperatorExpression.Expression, null); if (rr is ErrorResolveResult) { UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression); if (clonUnaryOperatorExpression == null) { clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone(); } bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement; var isStatement = unaryOperatorExpression.Parent is ExpressionStatement; var isIncr = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement; AssignmentExpression ae; ae = new AssignmentExpression(clonUnaryOperatorExpression.Expression.Clone(), new BinaryOperatorExpression(clonUnaryOperatorExpression.Expression.Clone(), isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, new PrimitiveExpression(1))); if (isPost && !isStatement) { return(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "Identity"), clonUnaryOperatorExpression.Expression.Clone(), ae)); } else { if (isStatement) { return(ae); } return(new ParenthesizedExpression(ae)); } } else { var orr = (OperatorResolveResult)rr; if (Helpers.IsFloatType(orr.Type, this.Resolver) || Helpers.Is64Type(orr.Type, this.Resolver)) { return(base.VisitUnaryOperatorExpression(unaryOperatorExpression)); } UnaryOperatorExpression clonUnaryOperatorExpression = (UnaryOperatorExpression)base.VisitUnaryOperatorExpression(unaryOperatorExpression); if (clonUnaryOperatorExpression == null) { clonUnaryOperatorExpression = (UnaryOperatorExpression)unaryOperatorExpression.Clone(); } bool isPost = clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostDecrement || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement; var isStatement = unaryOperatorExpression.Parent is ExpressionStatement; var isIncr = clonUnaryOperatorExpression.Operator == UnaryOperatorType.Increment || clonUnaryOperatorExpression.Operator == UnaryOperatorType.PostIncrement; var needReturnOriginal = isPost && !isStatement; Expression expression = clonUnaryOperatorExpression.Expression.Clone(); Expression expressionAfter = clonUnaryOperatorExpression.Expression.Clone(); AssignmentExpression ae = null; if (orr.UserDefinedOperatorMethod != null) { ae = new AssignmentExpression(expressionAfter.Clone(), clonUnaryOperatorExpression); } else if (clonUnaryOperatorExpression.Expression is MemberReferenceExpression mre && expression_rr is MemberResolveResult member_rr) { if (needReturnOriginal) { bool isSimple = (member_rr != null && (member_rr.TargetResult is ThisResolveResult || member_rr.TargetResult is LocalResolveResult || member_rr.TargetResult is TypeResolveResult || member_rr.TargetResult is ConstantResolveResult)); expression = isSimple ? mre.Clone() : new MemberReferenceExpression(new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), mre.Target.Clone()), mre.MemberName); expressionAfter = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), mre.Target.Clone()); } else { expressionAfter = null; } ae = BuildMemberReferenceReplacement(isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, mre, member_rr, expressionAfter); } else if (clonUnaryOperatorExpression.Expression is IndexerExpression ie && expression_rr is ArrayAccessResolveResult array_rr) { IndexerExpression cacheIndexer = null; if (needReturnOriginal) { var array_target_rr = array_rr.Array as MemberResolveResult; bool isSimpleTarget = (array_target_rr != null && array_target_rr.Member is IField && (array_target_rr.TargetResult is ThisResolveResult || array_target_rr.TargetResult is LocalResolveResult || array_target_rr.TargetResult is TypeResolveResult || array_target_rr.TargetResult is ConstantResolveResult)) || (array_rr.Array is ThisResolveResult || array_rr.Array is LocalResolveResult || array_rr.Array is ConstantResolveResult); bool simpleIndex = true; foreach (var index in array_rr.Indexes) { var indexMemberTargetrr = index as MemberResolveResult; bool isIndexSimple = (indexMemberTargetrr != null && indexMemberTargetrr.Member is IField && (indexMemberTargetrr.TargetResult is ThisResolveResult || indexMemberTargetrr.TargetResult is LocalResolveResult)) || index is ThisResolveResult || index is LocalResolveResult || index is ConstantResolveResult; if (!isIndexSimple) { simpleIndex = false; break; } } var leftIndexerArgs = new List <Expression>(); var rightIndexerArgs = new List <Expression>(); foreach (var index in ie.Arguments) { var expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), index.Clone()); leftIndexerArgs.Add(expr); expr = simpleIndex ? index.Clone() : new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), index.Clone()); rightIndexerArgs.Add(expr); } var leftExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "ToTemp"), new PrimitiveExpression("idx" + tempKey), ie.Target.Clone()); var rightExpr = new InvocationExpression(new MemberReferenceExpression(new MemberReferenceExpression(new TypeReferenceExpression(new MemberType(new SimpleType("global"), CS.NS.BRIDGE) { IsDoubleColon = true }), "Script"), "FromTemp"), new PrimitiveExpression("idx" + tempKey++), ie.Target.Clone()); var leftIndexer = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : leftExpr, leftIndexerArgs); var rightIndexer = new IndexerExpression(isSimpleTarget ? ie.Target.Clone() : rightExpr, rightIndexerArgs); expression = leftIndexer; cacheIndexer = rightIndexer; } ae = BuildIndexerReplacement(isStatement, isIncr ? BinaryOperatorType.Add : BinaryOperatorType.Subtract, ie, array_rr, cacheIndexer); }