public override IEnumerable <CodeStatement> GetStubStatements() { /* * Required output: * 1. Call the constructor with the correct number of args * (No optimization available for constructors) */ var arguments = new List <CodeExpression>(); foreach (var parameterInfo in stub.GetParameters()) { var parameterType = Code.TypeRef(parameterInfo.UnderlyingParameterType(), true); var argumentName = $"arg{arguments.Count}"; yield return(Code.VarDecl(parameterType, argumentName, parameterType.DefaultValue())); CodeParameterDirection direction; if (parameterInfo.IsOut) { direction = CodeParameterDirection.Out; } else if (parameterInfo.ParameterType.IsByRef) { direction = CodeParameterDirection.Ref; } else { direction = CodeParameterDirection.Default; } var argument = Code.ArgumentDirection(direction, Code.VarRef(argumentName)); arguments.Add(argument); } if (manipulator.isPubliclyInvocable) { yield return(Code.TypeRef(stub.DeclaringType).ObjectCreate(arguments).Statement()); } }
public override IEnumerable <CodeStatement> GetStubStatements() { /* * Required output: * 1. Create a target expression * 2. Call its method with the correct number of args * 3. Call its optimized method with the correct number of args * 4. Call its optimized method with an args array */ var targetType = Code.TypeRef(manipulator.targetType, true); var declaringType = Code.TypeRef(stub.DeclaringType, true); CodeExpression targetValue; CodeExpression targetReference; if (manipulator.requiresTarget && !manipulator.isExtension) { // default(Material) targetValue = targetType.DefaultValue(); // 1. Material target = default(Material); yield return(Code.VarDecl(targetType, "target", targetValue)); targetReference = Code.VarRef("target"); } else { targetValue = Code.Primitive(null); targetReference = targetType.Expression(); if (manipulator.isExtension) { // 1. ShortcutExtensions targetReference = new CodeTypeReferenceExpression(declaringType); } else { // 1. Material targetReference = new CodeTypeReferenceExpression(targetType); } } // target.SetColor var methodReference = targetReference.Method(manipulator.name); var arguments = new List <CodeExpression>(); var includesOutOrRef = false; foreach (var parameterInfo in stub.GetParameters()) { var parameterType = Code.TypeRef(parameterInfo.UnderlyingParameterType(), true); var argumentName = $"arg{arguments.Count}"; // arg0 = default(string) // arg1 = default(Color) yield return(Code.VarDecl(parameterType, argumentName, parameterType.DefaultValue())); CodeParameterDirection direction; if (parameterInfo.IsOut) { direction = CodeParameterDirection.Out; includesOutOrRef = true; } else if (parameterInfo.ParameterType.IsByRef) { direction = CodeParameterDirection.Ref; includesOutOrRef = true; } else { direction = CodeParameterDirection.Default; } var argument = Code.ArgumentDirection(direction, Code.VarRef(argumentName)); arguments.Add(argument); } if (operatorTypes.ContainsKey(manipulator.name)) { // arg0 * arg1 var operation = arguments[0].BinaryOp(operatorTypes[manipulator.name], arguments[1]); // 2. var operator = arg0 * arg1; yield return(Code.VarDecl(Code.TypeRef(manipulator.type), "operator", operation)); } else if (manipulator.isConversion) { // (Vector3)arg0 var cast = arguments[0].Cast(Code.TypeRef(manipulator.type)); // 2. var conversion = (Vector3)arg0; yield return(Code.VarDecl(Code.TypeRef(manipulator.type), "conversion", cast)); } else if (manipulator.isPubliclyInvocable && !manipulator.isConversion) { // 2. target.SetColor(arg0, arg1); yield return(methodReference.Invoke(arguments.ToArray()).Statement()); } if (supportsOptimization) { var optimizedInvokerType = Code.TypeRef(stub.Prewarm().GetType(), true); // var invoker = new InstanceActionInvoker<Material, string, Color>(default(MethodInfo)); yield return(Code.VarDecl(optimizedInvokerType, "optimized", optimizedInvokerType.ObjectCreate(Code.TypeRef(typeof(MethodInfo), true).DefaultValue()))); // [default(Material), arg0, arg1] var argumentsWithTarget = targetValue.Yield().Concat(arguments).ToArray(); // Ref and out parameters are not supported in the numbered argument signatures if (!includesOutOrRef) { // 3. invoker.Invoke(default(Material), arg0, arg1); yield return(Code.VarRef("optimized").Method(nameof(IOptimizedInvoker.Invoke)).Invoke(argumentsWithTarget).Statement()); } // 4. invoker.Invoke(default(Material), default(object[])); yield return(Code.VarRef("optimized").Method(nameof(IOptimizedInvoker.Invoke)).Invoke(Code.TypeRef(typeof(object[])).DefaultValue()).Statement()); } }