public override IMethodBody Rewrite(IMethodBody body) { var method = body.MethodDefinition; _log.Info("Rewriting IMethodBody of: " + method + " Pass: " + MutationTarget.PassInfo); var newBody = new SourceMethodBody(Host) { MethodDefinition = method, LocalsAreZeroed = true }; var block = new BlockStatement(); newBody.Block = block; var replacement = method.ContainingTypeDefinition.Methods.Single(m => m.ToString() == MutationTarget.PassInfo); var methodCall = new MethodCall { MethodToCall = replacement, Type = replacement.Type, ThisArgument = new ThisReference() {Type = method.ContainingTypeDefinition} }; foreach (var param in replacement.Parameters) { methodCall.Arguments.Add(new BoundExpression() { Definition = method.Parameters .First(p => ((INamedTypeReference)p.Type).Name.Value == ((INamedTypeReference)param.Type).Name.Value) }); // methodCall.Arguments.Add(method.Parameters.First(p => new )); } if (replacement.Type == Host.PlatformType.SystemVoid) { block.Statements.Add(new ExpressionStatement { Expression = methodCall }); block.Statements.Add(new ReturnStatement()); } else { block.Statements.Add(new ReturnStatement { Expression = methodCall }); } return newBody; }
public override void TraverseChildren(IFieldReference fieldReference) { log.WriteTrace("Visiting field: {0}.", fieldReference.Name.Value); var replaceableField = fieldReference.AsReplaceable(ReplaceableReferenceTypes.FieldAccessor); if (registry.IsRegistered(replaceableField)) { var replacementMethodToCall = registry.GetReplacement(replaceableField); var replacementExpression = new MethodCall(); replacementExpression.Type = replacementMethodToCall.Type; replacementExpression.Arguments = new List<IExpression>(); replacementExpression.MethodToCall = replacementMethodToCall; replacementExpression.IsStaticCall = true; var expressionStatement = parent as ExpressionStatement; if (expressionStatement != null) { var assignment = expressionStatement.Expression as Assignment; if (assignment != null) { var source = assignment.Source as BoundExpression; if (source != null) { var assignmentSource = source.Definition as FieldReference; if (assignmentSource != null) { if (fieldReference.ResolvedField.Equals(assignmentSource.ResolvedField)) { assignment.Source = replacementExpression; } } } } } var returnStatement = parent as ReturnStatement; if (returnStatement != null) { returnStatement.Expression = replacementExpression; } } }
public object BuildReplacement() { var replaceableField = field.AsReplaceable(ReplaceableReferenceTypes.FieldAccessor); if (registry.IsRegistered(replaceableField)) //if (FieldReferenceReplacementRegistry.HasReplacementFor(field.AsReplaceable())) { //var replacementCall = FieldReferenceReplacementRegistry.GetReplacementFor(field); var replacementCall = registry.GetReplacement(replaceableField); var methodCall = new MethodCall(); methodCall.Type = field.Type; methodCall.Arguments = new List<IExpression>(); methodCall.MethodToCall = replacementCall; methodCall.IsStaticCall = true; return methodCall; } return null; }
public object BuildReplacement() { var replaceableField = field.AsReplaceable(ReplaceableReferenceTypes.FieldAssignment); if (registry.IsRegistered(replaceableField)) //if (FieldAssignmentReplacementRegistry.HasReplacementFor()) { var replacementCall = registry.GetReplacement(replaceableField); //var replacementCall = FieldAssignmentReplacementRegistry.GetReplacementFor(field); var methodCall = new MethodCall(); methodCall.Type = host.PlatformType.SystemVoid; methodCall.IsStaticCall = true; methodCall.Arguments = new List<IExpression>(); methodCall.Arguments.Add((assignment.Expression as Assignment).Source); methodCall.MethodToCall = replacementCall; return methodCall; } return null; }
public override void TraverseChildren(IFieldReference fieldReference) { log.WriteTrace("Visiting field: {0}.", fieldReference.Name.Value); var replaceableField = fieldReference.AsReplaceable(ReplaceableReferenceTypes.FieldAssignment); if (registry.IsRegistered(replaceableField)) { var replacementMethodToCall = registry.GetReplacement(replaceableField); var replacementExpression = new MethodCall(); replacementExpression.Type = replacementMethodToCall.Type; replacementExpression.Arguments = new List<IExpression>(); replacementExpression.MethodToCall = replacementMethodToCall; replacementExpression.IsStaticCall = true; var expressionStatement = parent as ExpressionStatement; if (expressionStatement != null) { var assignment = expressionStatement.Expression as Assignment; if (assignment != null) { var target = assignment.Target.Definition as FieldReference; if (target != null) { // If the target is what we're visiting ... if (target.ResolvedField.Equals(fieldReference.ResolvedField)) { if (!fieldReference.ResolvedField.IsStatic) { replacementExpression.Arguments.Add(assignment.Target.Instance); } replacementExpression.Arguments.Add(assignment.Source); expressionStatement.Expression = replacementExpression; } } } } } }
/// <summary /> public override IStatement Rewrite(IForEachStatement forEachStatement) { ILocalDefinition foreachLocal; var key = forEachStatement.Collection.Type.InternedKey; ITypeReference enumeratorType; IMethodReference getEnumerator; IMethodReference getCurrent; var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference; if (gtir != null) { var typeArguments = gtir.GenericArguments; ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory); enumeratorType = genericEnumeratorType; getEnumerator = new SpecializedMethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = genericEnumerableType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = genericEnumeratorType, UnspecializedVersion = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator, }, }; var getEnumerator2 = (IMethodReference) IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)); getEnumerator = getEnumerator2; getCurrent = (IMethodReference) IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)); } else { enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; getEnumerator = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsIEnumerable, }; getCurrent = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("get_Current"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemObject, }; } var initializer = new MethodCall() { Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getEnumerator, ThisArgument = forEachStatement.Collection, Type = enumeratorType, }; IStatement initialization; if (!this.foreachLocals.TryGetValue(key, out foreachLocal)) { foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) }; this.foreachLocals.Add(key, foreachLocal); initialization = new LocalDeclarationStatement() { InitialValue = initializer, LocalVariable = foreachLocal, }; } else { initialization = new ExpressionStatement() { Expression = new Assignment() { Source = initializer, Target = new TargetExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, Type = foreachLocal.Type, }, }; } var newStmts = new List<IStatement>(); newStmts.Add(new ExpressionStatement(){ Expression = new Assignment(){ Source = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getCurrent, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = forEachStatement.Variable.Type, }, Target = new TargetExpression(){ Definition = forEachStatement.Variable, Instance = null, }, Type = forEachStatement.Variable.Type, }, }); newStmts.Add(forEachStatement.Body); var newBody = new BlockStatement(){ Statements = newStmts,}; var result = new BlockStatement() { Statements = new List<IStatement>(){ initialization, new TryCatchFinallyStatement(){ TryBody = new BlockStatement() { Statements = new List<IStatement>(){ new WhileDoStatement(){ Body = newBody, Condition = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = moveNext, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemBoolean, }, }, }, }, FinallyBody = new BlockStatement() { Statements = new List<IStatement>(){ new ConditionalStatement(){ Condition = new Equality(){ LeftOperand = new BoundExpression(){ Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, RightOperand = new CompileTimeConstant(){ Type = foreachLocal.Type, Value = null, }, Type = this.host.PlatformType.SystemBoolean, }, FalseBranch = new EmptyStatement(), TrueBranch = new ExpressionStatement(){ Expression = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = this.disposeMethod, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemVoid, }, }, }, }, }, }, }, }; return result; }
/// <summary> /// Create the body of the generic version of GetEnumerator for the iterator closure class. /// /// The body's pseudo code. /// { /// if (Thread.CurrentThread.ManagedThreadId == this.l_initialThreadId AND this.state == -2) { /// this.state = 0; /// return this; /// } /// else { /// return a new copy of the iterator instance with state being zero. /// } /// } /// </summary> private BlockStatement GetBodyOfGenericGetEnumerator(IteratorClosureInformation iteratorClosure) { var thisDotState = new BoundExpression() { Definition = iteratorClosure.StateFieldReference, Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32 }; var thisDotThreadId = new BoundExpression() { Definition = iteratorClosure.InitThreadIdFieldReference, Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32 }; var currentThreadId = new MethodCall() { MethodToCall = ThreadDotManagedThreadId.Getter, ThisArgument = ThreadDotCurrentThread, Type = this.host.PlatformType.SystemInt32 }; var stateEqMinus2 = new Equality() { LeftOperand = thisDotState, RightOperand = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = -2 }, Type = this.host.PlatformType.SystemBoolean }; var threadIdEqCurrentThreadId = new Equality { LeftOperand = thisDotThreadId, RightOperand = currentThreadId, Type = this.host.PlatformType.SystemBoolean }; var thisDotStateEq0 = new ExpressionStatement() { Expression = new Assignment() { Source = new CompileTimeConstant() { Type = this.host.PlatformType.SystemInt32, Value = 0 }, Target = new TargetExpression() { Definition = iteratorClosure.StateFieldReference, Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32 }, Type = this.host.PlatformType.SystemInt32 }, }; var returnThis = new BlockStatement(); returnThis.Statements.Add(thisDotStateEq0); returnThis.Statements.Add(new ReturnStatement() { Expression = new ThisReference() }); var returnNew = new BlockStatement(); var args = new List<IExpression>(); args.Add(new CompileTimeConstant() { Value = 0, Type = this.host.PlatformType.SystemInt32 }); var closureInstanceLocalDecl = new LocalDeclarationStatement() { LocalVariable = new LocalDefinition() { Name = this.host.NameTable.GetNameFor("local0"), Type = iteratorClosure.ClosureDefinitionReference }, InitialValue = new CreateObjectInstance() { MethodToCall = iteratorClosure.ConstructorReference, Arguments = args, Type = iteratorClosure.ClosureDefinitionReference } }; var returnNewClosureInstance = new ReturnStatement() { Expression = new BoundExpression() { Instance = null, Type = iteratorClosure.ClosureDefinitionReference, Definition = closureInstanceLocalDecl.LocalVariable } }; returnNew.Statements.Add(closureInstanceLocalDecl); if (!method.IsStatic) { ExpressionStatement assignThisDotThisToNewClosureDotThis = new ExpressionStatement() { Expression = new Assignment() { Source = new BoundExpression() { Definition = iteratorClosure.ThisFieldReference, Instance = new ThisReference(), Type = iteratorClosure.ClosureDefinitionReference }, Type = iteratorClosure.ClosureDefinition, Target = new TargetExpression() { Instance = new BoundExpression() { Instance = null, Definition = closureInstanceLocalDecl.LocalVariable, Type = iteratorClosure.ClosureDefinitionReference }, Definition = iteratorClosure.ThisFieldReference, Type = iteratorClosure.ClosureDefinitionReference } } }; returnNew.Statements.Add(assignThisDotThisToNewClosureDotThis); } returnNew.Statements.Add(returnNewClosureInstance); ConditionalStatement returnThisOrNew = new ConditionalStatement() { Condition = new Conditional() { Condition = stateEqMinus2, ResultIfTrue = threadIdEqCurrentThreadId, ResultIfFalse = new CompileTimeConstant() { Type = this.host.PlatformType.SystemBoolean, Value = false }, Type = this.host.PlatformType.SystemBoolean }, TrueBranch = returnThis, FalseBranch = returnNew }; BlockStatement block = new BlockStatement(); block.Statements.Add(returnThisOrNew); return block; }
public override IExpression Rewrite(IEquality operation) { _log.Info("Rewriting IEquality: " + operation + " Pass: "******"Left") { thisArgument = operation.LeftOperand; argument = operation.RightOperand; } else { thisArgument = operation.RightOperand; argument = operation.LeftOperand; } methodCall.ThisArgument = thisArgument; methodCall.MethodToCall = TypeHelper.GetMethod(Host.PlatformType.SystemObject.ResolvedType.Members, Host.NameTable.GetNameFor("Equals"), Host.PlatformType.SystemObject); methodCall.Arguments = argument.InList(); return methodCall; }
public override IExpression Rewrite(IMethodCall methodCall) { _log.Info("Rewrite IMethodCall: " + OperatorUtils.Formatter.Format(methodCall)); var methodDefinition = TypeHelper.GetMethod(methodCall.MethodToCall.ContainingType.ResolvedType, NameTable.GetNameFor(MutationTarget.PassInfo), methodCall.Arguments.Select(a => a.Type).ToArray()); var newCall = new MethodCall(methodCall); newCall.MethodToCall = methodDefinition;// // (IMethodReference)MutationTarget.StoredObjects.Values.Single(); _log.Info("Returning MethodCall to: " + OperatorUtils.Formatter.Format(methodCall)); return newCall; }
/// <summary> /// Rewrites the children of the given method call. /// </summary> /// <param name="methodCall"></param> public override void RewriteChildren(MethodCall methodCall) { base.RewriteChildren(methodCall); if (!methodCall.IsStaticCall && !methodCall.IsJumpCall && methodCall.ThisArgument is IThisReference && this.targetType.IsValueType && !this.sourceType.IsValueType) { methodCall.ThisArgument = new ThisReference() { Type = MutableModelHelper.GetManagedPointerTypeReference(methodCall.ThisArgument.Type, this.host.InternFactory, methodCall.ThisArgument.Type) }; } }
/// <summary> /// Visits the specified method call. /// </summary> /// <param name="methodCall">The method call.</param> /// <returns></returns> public virtual IExpression Visit(MethodCall methodCall) { if (!methodCall.IsStaticCall) methodCall.ThisArgument = this.Visit(methodCall.ThisArgument); methodCall.Arguments = this.Visit(methodCall.Arguments); methodCall.MethodToCall = this.Visit(methodCall.MethodToCall); methodCall.Type = this.Visit(methodCall.Type); return methodCall; }
/// <summary> /// Visits the specified method call. /// </summary> /// <param name="methodCall">The method call.</param> public override void Visit(IMethodCall methodCall) { MethodCall mutableMethodCall = new MethodCall(methodCall); this.resultExpression = this.myCodeCopier.DeepCopy(mutableMethodCall); }
/// <summary> /// If the <paramref name="typeDefinition"/> has a type contract, generate a /// contract invariant method and add it to the Methods of the <paramref name="typeDefinition"/>. /// </summary> private void VisitTypeDefinition(ITypeDefinition typeDefinition) { ITypeContract typeContract = this.contractProvider.GetTypeContractFor(typeDefinition); if (typeContract != null) { #region Define the method List<IStatement> statements = new List<IStatement>(); var methodBody = new SourceMethodBody(this.host) { LocalsAreZeroed = true, Block = new BlockStatement() { Statements = statements } }; List<ICustomAttribute> attributes = new List<ICustomAttribute>(); MethodDefinition m = new MethodDefinition() { Attributes = attributes, Body = methodBody, CallingConvention = CallingConvention.HasThis, ContainingTypeDefinition = typeDefinition, InternFactory = this.host.InternFactory, IsStatic = false, Name = this.host.NameTable.GetNameFor("$InvariantMethod$"), Type = systemVoid, Visibility = TypeMemberVisibility.Private, }; methodBody.MethodDefinition = m; #region Add calls to Contract.Invariant foreach (var inv in typeContract.Invariants) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { inv.Condition, }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Invariant, Type = systemVoid, Locations = new List<ILocation>(inv.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; statements.Add(es); } statements.Add(new ReturnStatement()); #endregion #region Add [ContractInvariantMethod] var contractInvariantMethodType = new Immutable.NamespaceTypeReference( this.host, this.host.PlatformType.SystemDiagnosticsContractsContract.ContainingUnitNamespace, this.host.NameTable.GetNameFor("ContractInvariantMethodAttribute"), 0, false, false, true, PrimitiveTypeCode.NotPrimitive ); var contractInvariantMethodCtor = new Microsoft.Cci.MutableCodeModel.MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = contractInvariantMethodType, GenericParameterCount = 0, InternFactory = this.host.InternFactory, Name = host.NameTable.Ctor, Type = host.PlatformType.SystemVoid, }; var contractInvariantMethodAttribute = new CustomAttribute(); contractInvariantMethodAttribute.Constructor = contractInvariantMethodCtor; attributes.Add(contractInvariantMethodAttribute); #endregion var namedTypeDefinition = (NamedTypeDefinition)typeDefinition; var newMethods = new List<IMethodDefinition>(namedTypeDefinition.Methods == null ? 1 : namedTypeDefinition.Methods.Count() + 1); if (namedTypeDefinition.Methods != null) { foreach (var meth in namedTypeDefinition.Methods) { if (!ContractHelper.IsInvariantMethod(this.host, meth)) newMethods.Add(meth); } } namedTypeDefinition.Methods = newMethods; namedTypeDefinition.Methods.Add(m); #endregion Define the method } }
/// <summary> /// The inherited contract might have a method call of the form "this.M(...)" where "this" had been /// a reference type in the original contract (e.g., in an interface contract). But if it is /// inherited into a method belonging to a struct (or other value type), then the "this" reference /// needs to have its type changed to be a managed pointer. /// </summary> public override void RewriteChildren(MethodCall methodCall) { base.RewriteChildren(methodCall); if (!methodCall.IsStaticCall && !methodCall.IsJumpCall && methodCall.ThisArgument is IThisReference && methodCall.ThisArgument.Type.IsValueType) { var t = methodCall.ThisArgument.Type; var ntd = t as INamedTypeDefinition; if (ntd != null) t = Microsoft.Cci.MutableCodeModel.NamedTypeDefinition.SelfInstance(ntd, this.host.InternFactory); methodCall.ThisArgument = new ThisReference() { Type = MutableModelHelper.GetManagedPointerTypeReference(t, this.host.InternFactory, t) }; } }
/// <summary> /// Converts the return value into a call to Contract.Result /// </summary> public override IExpression Rewrite(IReturnValue returnValue) { var mref = this.contractProvider.ContractMethods.Result; var methodToCall = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference() { CallingConvention = CallingConvention.Generic, ContainingType = mref.ContainingType, GenericArguments = new List<ITypeReference> { returnValue.Type }, GenericMethod = mref, InternFactory = this.host.InternFactory, Name = mref.Name, Type = returnValue.Type, }; var methodCall = new MethodCall() { IsStaticCall = true, MethodToCall = methodToCall, Type = returnValue.Type, Locations = new List<ILocation>(returnValue.Locations), }; return methodCall; }
/// <summary> /// Converts the old value into a call to Contract.OldValue /// </summary> public override IExpression Rewrite(IOldValue oldValue) { var mref = this.contractProvider.ContractMethods.Old; var methodToCall = new Microsoft.Cci.MutableCodeModel.GenericMethodInstanceReference() { CallingConvention = CallingConvention.Generic, ContainingType = mref.ContainingType, GenericArguments = new List<ITypeReference> { oldValue.Type }, GenericMethod = mref, InternFactory = this.host.InternFactory, Name = mref.Name, Parameters = new List<IParameterTypeInformation>{ new ParameterTypeInformation { Type = oldValue.Type, } }, Type = oldValue.Type, }; var methodCall = new MethodCall() { Arguments = new List<IExpression> { oldValue.Expression, }, IsStaticCall = true, MethodToCall = methodToCall, Type = oldValue.Type, Locations = new List<ILocation>(oldValue.Locations), }; return methodCall; }
/// <summary> /// Converts the assume statement into a call to Contract.Assume /// </summary> public override IStatement Rewrite(IAssumeStatement assumeStatement) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { assumeStatement.Condition, }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Assume, Type = systemVoid, Locations = new List<ILocation>(assumeStatement.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; return es; }
public override IExpression Visit(MethodCall methodCall) { if (methodCall.Arguments.Count == 1) { var tokenOf = methodCall.Arguments[0] as TokenOf; if (tokenOf != null) { var typeRef = tokenOf.Definition as ITypeReference; if (typeRef != null && methodCall.MethodToCall.InternedKey == this.GetTypeFromHandle.InternedKey) { return new TypeOf() { Locations = methodCall.Locations, Type = methodCall.Type, TypeToGet = typeRef }; } } } return base.Visit(methodCall); }
private MethodCall GetPointerValidationCall(IExpression pointer) { CompileTimeConstant pointerSize = new CompileTimeConstant(); pointerSize.Type = pointer.Type.PlatformType.SystemInt32.ResolvedType; pointerSize.Value = pointer.Type.PlatformType.PointerSize; MethodCall mcall = new MethodCall(); mcall.Arguments.Add(pointer); mcall.Arguments.Add(pointerSize); mcall.Locations.Add(PointerIsValidationLocation.For(pointerSize, pointer.Locations)); mcall.MethodToCall = this.PointerValidator; mcall.Type = this.PointerValidator.Type; return mcall; }
private IEnumerable<IStatement> getCodeForSettingEnabledness(ControlInfoStructure controlInfo) { IList<IStatement> code = new List<IStatement>(); BoundExpression boundControl = makeBoundControlFromControlInfo(controlInfo); MethodCall setEnablednessCall = new MethodCall() { IsStaticCall = false, IsVirtualCall = true, IsTailCall = false, Type = ((Microsoft.Cci.Immutable.PlatformType) host.PlatformType).SystemVoid, MethodToCall = isEnabledSetter, ThisArgument = boundControl, }; setEnablednessCall.Arguments.Add(controlInfo.IsEnabled ? trueConstant : falseConstant); ExpressionStatement callStmt = new ExpressionStatement() { Expression = setEnablednessCall, }; code.Add(callStmt); return code; }
private void ParseInstruction(Instruction instruction, List<IStatement> statements) { Contract.Requires(instruction != null); Contract.Requires(statements != null); Statement/*?*/ statement = null; Expression/*?*/ expression = null; ITypeReference/*?*/ elementType = null; IOperation currentOperation = instruction.Operation; OperationCode currentOpcode = currentOperation.OperationCode; if (this.host.PreserveILLocations) { if (this.lastLocation == null) this.lastLocation = currentOperation.Location; } else if (this.sourceLocationProvider != null) { if (this.lastSourceLocation == null) { foreach (var sourceLocation in this.sourceLocationProvider.GetPrimarySourceLocationsFor(currentOperation.Location)) { Contract.Assume(sourceLocation != null); if (sourceLocation.StartLine != 0x00feefee) { this.lastSourceLocation = sourceLocation; break; } } } } if (this.synchronizatonPointLocationFor != null) { uint currentOffset = currentOperation.Offset; var syncPointLocation = this.synchronizatonPointLocationFor[currentOffset]; if (syncPointLocation != null) { if (syncPointLocation.SynchronizationPoint.ContinuationOffset == currentOffset) this.lastContinuationLocation = new ContinuationLocation(syncPointLocation); else this.lastSynchronizationLocation = syncPointLocation; } } switch (currentOpcode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.And: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Or: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Xor: expression = this.ParseBinaryOperation(currentOpcode); break; case OperationCode.Arglist: expression = new RuntimeArgumentHandleExpression(); break; case OperationCode.Array_Addr: elementType = ((IArrayTypeReference)currentOperation.Value).ElementType; expression = this.ParseArrayElementAddres(currentOperation, elementType); break; case OperationCode.Ldelema: elementType = (ITypeReference)currentOperation.Value; expression = this.ParseArrayElementAddres(currentOperation, elementType, treatArrayAsSingleDimensioned: true); break; case OperationCode.Array_Create: case OperationCode.Array_Create_WithLowerBound: case OperationCode.Newarr: expression = this.ParseArrayCreate(currentOperation); break; case OperationCode.Array_Get: elementType = ((IArrayTypeReference)currentOperation.Value).ElementType; expression = this.ParseArrayIndexer(currentOperation, elementType??this.platformType.SystemObject, treatArrayAsSingleDimensioned: false); break; case OperationCode.Ldelem: elementType = (ITypeReference)currentOperation.Value; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I: elementType = this.platformType.SystemIntPtr; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I1: elementType = this.platformType.SystemInt8; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I2: elementType = this.platformType.SystemInt16; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I4: elementType = this.platformType.SystemInt32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I8: elementType = this.platformType.SystemInt64; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_R4: elementType = this.platformType.SystemFloat32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_R8: elementType = this.platformType.SystemFloat64; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U1: elementType = this.platformType.SystemUInt8; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U2: elementType = this.platformType.SystemUInt16; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U4: elementType = this.platformType.SystemUInt32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_Ref: expression = this.ParseArrayIndexer(currentOperation, elementType??this.platformType.SystemObject, treatArrayAsSingleDimensioned: true); break; case OperationCode.Array_Set: statement = this.ParseArraySet(currentOperation); break; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: statement = this.ParseBinaryConditionalBranch(currentOperation); break; case OperationCode.Box: expression = this.ParseConversion(currentOperation); break; case OperationCode.Br: case OperationCode.Br_S: case OperationCode.Leave: case OperationCode.Leave_S: statement = this.ParseUnconditionalBranch(currentOperation); break; case OperationCode.Break: statement = new DebuggerBreakStatement(); break; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: statement = this.ParseUnaryConditionalBranch(currentOperation); break; case OperationCode.Call: case OperationCode.Callvirt: MethodCall call = this.ParseCall(currentOperation); if (call.MethodToCall.Type.TypeCode == PrimitiveTypeCode.Void) { call.Locations.Add(currentOperation.Location); // turning it into a statement prevents the location from being attached to the expresssion ExpressionStatement es = new ExpressionStatement(); es.Expression = call; statement = es; } else expression = call; break; case OperationCode.Calli: expression = this.ParsePointerCall(currentOperation); break; case OperationCode.Castclass: case OperationCode.Conv_I: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_R_Un: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U: case OperationCode.Conv_U1: case OperationCode.Conv_U2: case OperationCode.Conv_U4: case OperationCode.Conv_U8: case OperationCode.Unbox: case OperationCode.Unbox_Any: expression = this.ParseConversion(currentOperation); break; case OperationCode.Ckfinite: var operand = this.PopOperandStack(); var chkfinite = new MutableCodeModel.MethodReference() { CallingConvention = Cci.CallingConvention.FastCall, ContainingType = host.PlatformType.SystemFloat64, Name = this.host.NameTable.GetNameFor("__ckfinite__"), Type = host.PlatformType.SystemFloat64, InternFactory = host.InternFactory, }; expression = new MethodCall() { Arguments = new List<IExpression>(1) { operand }, IsStaticCall = true, Type = operand.Type, MethodToCall = chkfinite }; break; case OperationCode.Constrained_: //This prefix is redundant and is not represented in the code model. break; case OperationCode.Cpblk: var copyMemory = new CopyMemoryStatement(); copyMemory.NumberOfBytesToCopy = this.PopOperandStack(); copyMemory.SourceAddress = this.PopOperandStack(); copyMemory.TargetAddress = this.PopOperandStack(); statement = copyMemory; break; case OperationCode.Cpobj: expression = this.ParseCopyObject(); break; case OperationCode.Dup: expression = this.ParseDup(instruction.Type); break; case OperationCode.Endfilter: statement = this.ParseEndfilter(); break; case OperationCode.Endfinally: statement = new EndFinally(); break; case OperationCode.Initblk: var fillMemory = new FillMemoryStatement(); fillMemory.NumberOfBytesToFill = this.PopOperandStack(); fillMemory.FillValue = this.PopOperandStack(); fillMemory.TargetAddress = this.PopOperandStack(); statement = fillMemory; break; case OperationCode.Initobj: statement = this.ParseInitObject(currentOperation); break; case OperationCode.Isinst: expression = this.ParseCastIfPossible(currentOperation); break; case OperationCode.Jmp: var methodToCall = (IMethodReference)currentOperation.Value; expression = new MethodCall() { IsJumpCall = true, MethodToCall = methodToCall, Type = methodToCall.Type }; break; case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: case OperationCode.Ldfld: case OperationCode.Ldsfld: expression = this.ParseBoundExpression(instruction); break; case OperationCode.Ldarga: case OperationCode.Ldarga_S: case OperationCode.Ldflda: case OperationCode.Ldsflda: case OperationCode.Ldloca: case OperationCode.Ldloca_S: case OperationCode.Ldftn: case OperationCode.Ldvirtftn: expression = this.ParseAddressOf(instruction); break; case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: case OperationCode.Ldc_I8: case OperationCode.Ldc_R4: case OperationCode.Ldc_R8: case OperationCode.Ldnull: case OperationCode.Ldstr: expression = this.ParseCompileTimeConstant(currentOperation); break; case OperationCode.Ldind_I: case OperationCode.Ldind_I1: case OperationCode.Ldind_I2: case OperationCode.Ldind_I4: case OperationCode.Ldind_I8: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Ldind_U1: case OperationCode.Ldind_U2: case OperationCode.Ldind_U4: case OperationCode.Ldobj: expression = this.ParseAddressDereference(currentOperation); break; case OperationCode.Ldlen: expression = this.ParseVectorLength(); break; case OperationCode.Ldtoken: expression = ParseToken(currentOperation); break; case OperationCode.Localloc: expression = this.ParseStackArrayCreate(); break; case OperationCode.Mkrefany: expression = this.ParseMakeTypedReference(currentOperation); break; case OperationCode.Neg: expression = this.ParseUnaryOperation(new UnaryNegation()); break; case OperationCode.Not: expression = this.ParseUnaryOperation(new OnesComplement()); break; case OperationCode.Newobj: expression = this.ParseCreateObjectInstance(currentOperation); break; case OperationCode.No_: Contract.Assume(false); //if code out there actually uses this, I need to know sooner rather than later. //TODO: need object model support break; case OperationCode.Nop: statement = new EmptyStatement(); break; case OperationCode.Pop: statement = this.ParsePop(); break; case OperationCode.Readonly_: this.sawReadonly = true; break; case OperationCode.Refanytype: expression = this.ParseGetTypeOfTypedReference(); break; case OperationCode.Refanyval: expression = this.ParseGetValueOfTypedReference(currentOperation); break; case OperationCode.Ret: statement = this.ParseReturn(); break; case OperationCode.Rethrow: statement = new RethrowStatement(); break; case OperationCode.Sizeof: expression = ParseSizeOf(currentOperation); break; case OperationCode.Starg: case OperationCode.Starg_S: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: case OperationCode.Stobj: case OperationCode.Stsfld: statement = this.ParseAssignment(currentOperation); break; case OperationCode.Switch: statement = this.ParseSwitchInstruction(currentOperation); break; case OperationCode.Tail_: this.sawTailCall = true; break; case OperationCode.Throw: statement = this.ParseThrow(); break; case OperationCode.Unaligned_: Contract.Assume(currentOperation.Value is byte); var alignment = (byte)currentOperation.Value; Contract.Assume(alignment == 1 || alignment == 2 || alignment == 4); this.alignment = alignment; break; case OperationCode.Volatile_: this.sawVolatile = true; break; } if (expression != null) { if (expression.Type is Dummy) expression.Type = instruction.Type; Contract.Assume(!(expression.Type is Dummy)); if (expression.Type.TypeCode != PrimitiveTypeCode.Void) { if (this.host.PreserveILLocations) { expression.Locations.Add(currentOperation.Location); } this.operandStack.Push(expression); } } else if (statement != null) { this.TurnOperandStackIntoPushStatements(statements); statements.Add(statement); if (this.host.PreserveILLocations) { if (this.lastLocation != null) { statement.Locations.Add(this.lastLocation); this.lastLocation = null; } } else if (this.lastSourceLocation != null) { statement.Locations.Add(this.lastSourceLocation); this.lastSourceLocation = null; } if (this.lastSynchronizationLocation != null) { statement.Locations.Add(this.lastSynchronizationLocation); this.lastSynchronizationLocation = null; } else if (this.lastContinuationLocation != null) { statement.Locations.Add(this.lastContinuationLocation); this.lastContinuationLocation = null; } } }
/// <summary> /// Visits the specified method call. /// </summary> /// <param name="methodCall">The method call.</param> /// <returns></returns> protected virtual IExpression DeepCopy(MethodCall methodCall) { if (!methodCall.IsStaticCall) methodCall.ThisArgument = this.Substitute(methodCall.ThisArgument); methodCall.Arguments = this.DeepCopy(methodCall.Arguments); methodCall.MethodToCall = this.Substitute(methodCall.MethodToCall); methodCall.Type = this.Substitute(methodCall.Type); return methodCall; }
/// <summary> /// Rewrites the children of the given method call. /// </summary> public virtual void RewriteChildren(MethodCall methodCall) { this.RewriteChildren((ConstructorOrMethodCall)methodCall); if (!methodCall.IsStaticCall) methodCall.ThisArgument = this.Rewrite(methodCall.ThisArgument); }
public override IExpression Rewrite(IMethodCall methodCall) { _log.Info("Rewrite IMethodCall: " + methodCall.MethodToCall.ResolvedMethod + methodCall.MethodToCall.ResolvedMethod.GetType()); IMethodDefinition accessor; if (!TryGetCompatibileAccessor(methodCall.MethodToCall.ResolvedMethod, out accessor)) { throw new InvalidOperationException("The same accessor was not found."); } // var methodDefinition = TypeHelper.GetMethod(methodCall.MethodToCall.ContainingType.ResolvedType, // NameTable.GetNameFor(MutationTarget.PassInfo), methodCall.Arguments.Select(a => a.Type).ToArray()); var newCall = new MethodCall(methodCall); newCall.MethodToCall = accessor; return newCall; }
public override void RewriteChildren(MethodDefinition methodDefinition) { IMethodContract methodContract = this.contractProvider.GetMethodContractFor(methodDefinition); if (methodContract == null) return; ISourceMethodBody sourceMethodBody = methodDefinition.Body as ISourceMethodBody; if (sourceMethodBody == null) return; List<IStatement> contractStatements = new List<IStatement>(); foreach (var precondition in methodContract.Preconditions) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { precondition.Condition, }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Requires, Type = systemVoid, Locations = new List<ILocation>(precondition.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; contractStatements.Add(es); } foreach (var postcondition in methodContract.Postconditions) { var methodCall = new MethodCall() { Arguments = new List<IExpression> { this.Rewrite(postcondition.Condition), }, IsStaticCall = true, MethodToCall = this.contractProvider.ContractMethods.Ensures, Type = systemVoid, Locations = new List<ILocation>(postcondition.Locations), }; ExpressionStatement es = new ExpressionStatement() { Expression = methodCall }; contractStatements.Add(es); } List<IStatement> existingStatements = new List<IStatement>(sourceMethodBody.Block.Statements); existingStatements = this.Rewrite(existingStatements); // keep the call to the base constructor at the top if (methodDefinition.IsConstructor && existingStatements.Count > 0) { contractStatements.Insert(0, existingStatements[0]); existingStatements.RemoveAt(0); } contractStatements.AddRange(existingStatements); // replaces assert/assume var newSourceMethodBody = new SourceMethodBody(this.host, this.sourceLocationProvider) { Block = new BlockStatement() { Statements = contractStatements, }, IsNormalized = false, LocalsAreZeroed = sourceMethodBody.LocalsAreZeroed, MethodDefinition = methodDefinition, }; methodDefinition.Body = newSourceMethodBody; return; }
private MethodCall ParseCall(IOperation currentOperation) { Contract.Requires(currentOperation != null); Contract.Assume(currentOperation.Value is IMethodReference); IMethodReference methodRef = (IMethodReference)currentOperation.Value; MethodCall result = new MethodCall(); result.IsTailCall = this.sawTailCall; foreach (var par in methodRef.Parameters) result.Arguments.Add(this.PopOperandStack()); foreach (var par in methodRef.ExtraParameters) result.Arguments.Add(this.PopOperandStack()); result.Arguments.Reverse(); //Convert ints to bools and enums var i = 0; foreach (var par in methodRef.Parameters) { Contract.Assume(par != null); Contract.Assume(i < result.Arguments.Count); Contract.Assume(result.Arguments[i] != null); result.Arguments[i] = TypeInferencer.Convert(result.Arguments[i++], par.Type); //TODO: special case out arguments and ref arguments } foreach (var par in methodRef.ExtraParameters) { Contract.Assume(par != null); Contract.Assume(i < result.Arguments.Count); Contract.Assume(result.Arguments[i] != null); result.Arguments[i] = TypeInferencer.Convert(result.Arguments[i++], par.Type); } result.IsVirtualCall = currentOperation.OperationCode == OperationCode.Callvirt; result.MethodToCall = methodRef; result.Type = methodRef.Type; if (!methodRef.IsStatic) result.ThisArgument = this.PopOperandStack(); else result.IsStaticCall = true; this.sawTailCall = false; return result; }
/// <summary> /// Create the constuctor of the iterator class. The pseudo-code is: /// /// Ctor(int state) { /// object.Ctor(); /// this.state = state; /// this.threadid = Thread.CurrentThread.ManagedThreadId; /// } /// </summary> private void CreateIteratorClosureConstructor(IteratorClosureInformation iteratorClosure) { MethodDefinition constructor = new MethodDefinition() { InternFactory = this.host.InternFactory, Parameters = new List<IParameterDefinition>(1), }; // Parameter ParameterDefinition stateParameter = new ParameterDefinition() { ContainingSignature = constructor, Index = 0, Name = this.host.NameTable.GetNameFor("state"), Type = this.host.PlatformType.SystemInt32 }; constructor.Parameters.Add(stateParameter); // Statements MethodCall baseConstructorCall = new MethodCall() { ThisArgument = new ThisReference(), MethodToCall = this.ObjectCtor, Type = this.host.PlatformType.SystemVoid }; ExpressionStatement baseConstructorCallStatement = new ExpressionStatement() { Expression = baseConstructorCall }; List<IStatement> statements = new List<IStatement>(); ExpressionStatement thisDotStateEqState = new ExpressionStatement() { Expression = new Assignment() { Source = new BoundExpression() { Definition = stateParameter, Instance = null, Type = this.host.PlatformType.SystemInt32 }, Target = new TargetExpression() { Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32, Definition = iteratorClosure.StateFieldReference }, Type = this.host.PlatformType.SystemInt32 } }; ExpressionStatement thisThreadIdEqCurrentThreadId = new ExpressionStatement() { Expression = new Assignment() { Source = new MethodCall() { MethodToCall = this.ThreadDotManagedThreadId.Getter, ThisArgument = this.ThreadDotCurrentThread, Type = this.host.PlatformType.SystemInt32 }, Target = new TargetExpression() { Instance = new ThisReference(), Type = this.host.PlatformType.SystemInt32, Definition = iteratorClosure.InitThreadIdFieldReference }, Type = this.host.PlatformType.SystemInt32 } }; statements.Add(baseConstructorCallStatement); statements.Add(thisDotStateEqState); statements.Add(thisThreadIdEqCurrentThreadId); BlockStatement block = new BlockStatement() { Statements = statements }; SourceMethodBody body = new SourceMethodBody(this.host, this.sourceLocationProvider); body.LocalsAreZeroed = true; body.IsNormalized = true; body.Block = block; constructor.Body = body; body.MethodDefinition = constructor; // Metadata of the constructor constructor.CallingConvention = CallingConvention.HasThis; constructor.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; constructor.IsCil = true; constructor.IsHiddenBySignature = true; constructor.IsRuntimeSpecial = true; constructor.IsSpecialName = true; constructor.Name = this.host.NameTable.Ctor; constructor.Type = this.host.PlatformType.SystemVoid; constructor.Visibility = TypeMemberVisibility.Public; iteratorClosure.Constructor = constructor; }
private MethodCall ParseCall(IOperation currentOperation) { IMethodReference methodRef = (IMethodReference)currentOperation.Value; MethodCall result = new MethodCall(); result.IsTailCall = this.sawTailCall; foreach (var par in methodRef.Parameters) result.Arguments.Add(this.PopOperandStack()); foreach (var par in methodRef.ExtraParameters) result.Arguments.Add(this.PopOperandStack()); result.Arguments.Reverse(); result.IsVirtualCall = currentOperation.OperationCode == OperationCode.Callvirt; result.MethodToCall = methodRef; if (!methodRef.IsStatic) result.ThisArgument = this.PopOperandStack(); else result.IsStaticCall = true; result.Type = methodRef.Type; this.sawTailCall = false; return result; }
/// <summary> /// Visits the specified method call. /// </summary> /// <param name="methodCall">The method call.</param> public override void Visit(IMethodCall methodCall) { MethodCall mutableMethodCall = methodCall as MethodCall; if (alwaysMakeACopy || mutableMethodCall == null) mutableMethodCall = new MethodCall(methodCall); this.resultExpression = this.myCodeMutator.Visit(mutableMethodCall); }