/// <summary> /// Returns syntax for retrieving the value of this field, deep copying it if necessary. /// </summary> /// <param name="instance">The instance of the containing type.</param> /// <param name="serializationContextExpression">The expression used to retrieve the serialization context.</param> /// <param name="forceAvoidCopy">Whether or not to ensure that no copy of the field is made.</param> /// <returns>Syntax for retrieving the value of this field.</returns> public ExpressionSyntax GetGetter(ExpressionSyntax instance, ExpressionSyntax serializationContextExpression = null, bool forceAvoidCopy = false) { // Retrieve the value of the field. var getValueExpression = this.GetValueExpression(instance); // Avoid deep-copying the field if possible. if (forceAvoidCopy || this.FieldInfo.FieldType.IsOrleansShallowCopyable()) { // Return the value without deep-copying it. return(getValueExpression); } // Addressable arguments must be converted to references before passing. // IGrainObserver instances cannot be directly converted to references, therefore they are not included. ExpressionSyntax deepCopyValueExpression; if (typeof(IAddressable).IsAssignableFrom(this.FieldInfo.FieldType) && this.FieldInfo.FieldType.GetTypeInfo().IsInterface && !typeof(IGrainObserver).IsAssignableFrom(this.FieldInfo.FieldType)) { var getAsReference = getValueExpression.Member( (IAddressable grain) => grain.AsReference <IGrain>(), this.FieldInfo.FieldType); // If the value is not a GrainReference, convert it to a strongly-typed GrainReference. // C#: (value == null || value is GrainReference) ? value : value.AsReference<TInterface>() deepCopyValueExpression = SF.ConditionalExpression( SF.ParenthesizedExpression( SF.BinaryExpression( SyntaxKind.LogicalOrExpression, SF.BinaryExpression( SyntaxKind.EqualsExpression, getValueExpression, SF.LiteralExpression(SyntaxKind.NullLiteralExpression)), SF.BinaryExpression( SyntaxKind.IsExpression, getValueExpression, typeof(GrainReference).GetTypeSyntax()))), getValueExpression, SF.InvocationExpression(getAsReference)); } else { deepCopyValueExpression = getValueExpression; } // Deep-copy the value. Expression <Action> deepCopyInner = () => SerializationManager.DeepCopyInner(default(object), default(ICopyContext)); var typeSyntax = this.FieldInfo.FieldType.GetTypeSyntax(); return(SF.CastExpression( typeSyntax, deepCopyInner.Invoke() .AddArgumentListArguments( SF.Argument(deepCopyValueExpression), SF.Argument(serializationContextExpression)))); }
private static ExpressionSyntax GetParameterForInvocation(ParameterInfo arg, int argIndex) { var argIdentifier = arg.GetOrCreateName(argIndex).ToIdentifierName(); // Addressable arguments must be converted to references before passing. if (typeof(IAddressable).GetTypeInfo().IsAssignableFrom(arg.ParameterType) && arg.ParameterType.GetTypeInfo().IsInterface) { return (SF.ConditionalExpression( SF.BinaryExpression(SyntaxKind.IsExpression, argIdentifier, typeof(Grain).GetTypeSyntax()), SF.InvocationExpression(argIdentifier.Member("AsReference", arg.ParameterType)), argIdentifier)); } return(argIdentifier); }