private void ProcessRegularMethodInvocation(Ast.MethodInvocationExpression node, Ast.MethodReferenceExpression methodRef) { if (node.Arguments.Count != 0) { UnsupportedExpression(node); } var target = methodRef.Target; switch (target.CodeElementType) { case Ast.CodeElementType.ThisReferenceExpression: if (!InsideCandidate) { UnsupportedExpression(node); } ProcessCandidateMethodInvocation(node, methodRef); break; case Ast.CodeElementType.ArgumentReferenceExpression: ProcessCandidateMethodInvocation(node, methodRef); break; default: Push(ToFieldValue(target)); ProcessCandidateMethodInvocation(node, methodRef); break; } }
private void ProcessStringMethod(Ast.MethodInvocationExpression node, Ast.MethodReferenceExpression methodRef) { var method = methodRef.Method; if (method.Parameters.Count != 1 || !IsSystemString(method.Parameters[0].ParameterType)) { UnsupportedExpression(methodRef); } switch (method.Name) { case "Contains": PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.Contains); break; case "StartsWith": PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.StartsWith); break; case "EndsWith": PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.EndsWith); break; case "Equals": PushComparison(methodRef.Target, node.Arguments[0], ComparisonOperator.ValueEquality); break; default: UnsupportedExpression(methodRef); break; } }
public override void Visit(Ast.MethodInvocationExpression node) { var methodRef = node.Target as Ast.MethodReferenceExpression; if (null == methodRef) { UnsupportedExpression(node); } var method = methodRef.Method; if (IsOperator(method)) { ProcessOperatorMethodInvocation(node, method); return; } if (IsSystemString(method.DeclaringType)) { ProcessStringMethod(node, methodRef); return; } ProcessRegularMethodInvocation(node, methodRef); }
private static bool IsActivateInvocation(Ast.MethodInvocationExpression invocation) { var methodRef = invocation.Target as Ast.MethodReferenceExpression; if (null == methodRef) { return(false); } return(IsActivateMethod(methodRef.Method)); }
private static MethodDefinition MethodDefinitionFor(Ast.MethodInvocationExpression invocation) { var methodRef = invocation.Target as Ast.MethodReferenceExpression; if (null == methodRef) { return(null); } return(GetMethodDefinition(methodRef)); }
private static bool IsNoSideEffectIndirectActivationInvocation(Ast.MethodInvocationExpression invocation) { var methodDefinition = MethodDefinitionFor(invocation); if (null == methodDefinition) { return(false); } var afg = FlowGraphFactory.CreateActionFlowGraph(FlowGraphFactory.CreateControlFlowGraph(methodDefinition)); if (afg.Blocks.Count == 2 && afg.Blocks[0].ActionType == ActionType.Invoke) { var invocationBlock = (InvokeActionBlock)afg.Blocks[0]; return(IsActivateInvocation(invocationBlock.Expression)); } return(false); }
private void ProcessOperatorMethodInvocation(Ast.MethodInvocationExpression node, MemberReference methodReference) { switch (methodReference.Name) { case "op_Equality": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.ValueEquality); break; case "op_Inequality": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.ValueEquality); Negate(); break; // XXX: check if the operations below are really supported for the // data types in question case "op_GreaterThanOrEqual": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Smaller); Negate(); break; case "op_LessThanOrEqual": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Greater); Negate(); break; case "op_LessThan": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Smaller); break; case "op_GreaterThan": PushComparison(node.Arguments[0], node.Arguments[1], ComparisonOperator.Greater); break; default: UnsupportedExpression(node); break; } }