private readonly String LambdaClassName;      // Generated name for the generated class "X$$Lambda$1"

        /// <summary>
        /// General meta-factory constructor, supporting both standard cases and
        /// allowing for uncommon options such as serialization or bridging.
        /// </summary>
        /// <param name="caller"> Stacked automatically by VM; represents a lookup context
        ///               with the accessibility privileges of the caller. </param>
        /// <param name="invokedType"> Stacked automatically by VM; the signature of the
        ///                    invoked method, which includes the expected static
        ///                    type of the returned lambda object, and the static
        ///                    types of the captured arguments for the lambda.  In
        ///                    the event that the implementation method is an
        ///                    instance method, the first argument in the invocation
        ///                    signature will correspond to the receiver. </param>
        /// <param name="samMethodName"> Name of the method in the functional interface to
        ///                      which the lambda or method reference is being
        ///                      converted, represented as a String. </param>
        /// <param name="samMethodType"> Type of the method in the functional interface to
        ///                      which the lambda or method reference is being
        ///                      converted, represented as a MethodType. </param>
        /// <param name="implMethod"> The implementation method which should be called (with
        ///                   suitable adaptation of argument types, return types,
        ///                   and adjustment for captured arguments) when methods of
        ///                   the resulting functional interface instance are invoked. </param>
        /// <param name="instantiatedMethodType"> The signature of the primary functional
        ///                               interface method after type variables are
        ///                               substituted with their instantiation from
        ///                               the capture site </param>
        /// <param name="isSerializable"> Should the lambda be made serializable?  If set,
        ///                       either the target type or one of the additional SAM
        ///                       types must extend {@code Serializable}. </param>
        /// <param name="markerInterfaces"> Additional interfaces which the lambda object
        ///                       should implement. </param>
        /// <param name="additionalBridges"> Method types for additional signatures to be
        ///                          bridged to the implementation method </param>
        /// <exception cref="LambdaConversionException"> If any of the meta-factory protocol
        /// invariants are violated </exception>
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
//ORIGINAL LINE: public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, String samMethodName, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, boolean isSerializable, Class[] markerInterfaces, MethodType[] additionalBridges) throws LambdaConversionException
        public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, MethodType invokedType, String samMethodName, MethodType samMethodType, MethodHandle implMethod, MethodType instantiatedMethodType, bool isSerializable, Class[] markerInterfaces, MethodType[] additionalBridges) : base(caller, invokedType, samMethodName, samMethodType, implMethod, instantiatedMethodType, isSerializable, markerInterfaces, additionalBridges)
        {
            ImplMethodClassName   = ImplDefiningClass.Name.Replace('.', '/');
            ImplMethodName        = ImplInfo.Name;
            ImplMethodDesc        = ImplMethodType.ToMethodDescriptorString();
            ImplMethodReturnClass = (ImplKind == MethodHandleInfo.REF_newInvokeSpecial) ? ImplDefiningClass : ImplMethodType.ReturnType();
            ConstructorType       = invokedType.ChangeReturnType(Void.TYPE);
            LambdaClassName       = TargetClass.Name.Replace('.', '/') + "$$Lambda$" + Counter.IncrementAndGet();
            Cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            int parameterCount = invokedType.ParameterCount();

            if (parameterCount > 0)
            {
                ArgNames = new String[parameterCount];
                ArgDescs = new String[parameterCount];
                for (int i = 0; i < parameterCount; i++)
                {
                    ArgNames[i] = "arg$" + (i + 1);
                    ArgDescs[i] = BytecodeDescriptor.unparse(invokedType.ParameterType(i));
                }
            }
            else
            {
                ArgNames = ArgDescs = EMPTY_STRING_ARRAY;
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Convert an argument of type 'arg' to be passed to 'target' assuring that it is 'functional'.
 /// Insert the needed conversion instructions in the method code. </summary>
 /// <param name="arg"> </param>
 /// <param name="target"> </param>
 /// <param name="functional"> </param>
 internal virtual void ConvertType(Class arg, Class target, Class functional)
 {
     if (arg.Equals(target) && arg.Equals(functional))
     {
         return;
     }
     if (arg == Void.TYPE || target == Void.TYPE)
     {
         return;
     }
     if (arg.Primitive)
     {
         Wrapper wArg = Wrapper.forPrimitiveType(arg);
         if (target.Primitive)
         {
             // Both primitives: widening
             Widen(wArg, Wrapper.forPrimitiveType(target));
         }
         else
         {
             // Primitive argument to reference target
             String  dTarget     = BytecodeDescriptor.unparse(target);
             Wrapper wPrimTarget = WrapperOrNullFromDescriptor(dTarget);
             if (wPrimTarget != null)
             {
                 // The target is a boxed primitive type, widen to get there before boxing
                 Widen(wArg, wPrimTarget);
                 Box(wPrimTarget);
             }
             else
             {
                 // Otherwise, box and cast
                 Box(wArg);
                 Cast(WrapperName(wArg), dTarget);
             }
         }
     }
     else
     {
         String dArg = BytecodeDescriptor.unparse(arg);
         String dSrc;
         if (functional.Primitive)
         {
             dSrc = dArg;
         }
         else
         {
             // Cast to convert to possibly more specific type, and generate CCE for invalid arg
             dSrc = BytecodeDescriptor.unparse(functional);
             Cast(dArg, dSrc);
         }
         String dTarget = BytecodeDescriptor.unparse(target);
         if (target.Primitive)
         {
             Wrapper wTarget = ToWrapper(dTarget);
             // Reference argument to primitive target
             Wrapper wps = WrapperOrNullFromDescriptor(dSrc);
             if (wps != null)
             {
                 if (wps.Signed || wps.Floating)
                 {
                     // Boxed number to primitive
                     Unbox(WrapperName(wps), wTarget);
                 }
                 else
                 {
                     // Character or Boolean
                     Unbox(WrapperName(wps), wps);
                     Widen(wps, wTarget);
                 }
             }
             else
             {
                 // Source type is reference type, but not boxed type,
                 // assume it is super type of target type
                 String intermediate;
                 if (wTarget.Signed || wTarget.Floating)
                 {
                     // Boxed number to primitive
                     intermediate = "java/lang/Number";
                 }
                 else
                 {
                     // Character or Boolean
                     intermediate = WrapperName(wTarget);
                 }
                 Cast(dSrc, intermediate);
                 Unbox(intermediate, wTarget);
             }
         }
         else
         {
             // Both reference types: just case to target type
             Cast(dSrc, dTarget);
         }
     }
 }