jdk/src/java.base/share/classes/java/lang/invoke/MethodType.java
changeset 33874 46651fd30c0b
parent 33526 e6ea816cd6c6
child 34384 439c06c76808
equal deleted inserted replaced
33873:32ba74411aba 33874:46651fd30c0b
   467         return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
   467         return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
   468     }
   468     }
   469 
   469 
   470     /** Replace the last arrayLength parameter types with the component type of arrayType.
   470     /** Replace the last arrayLength parameter types with the component type of arrayType.
   471      * @param arrayType any array type
   471      * @param arrayType any array type
       
   472      * @param pos position at which to spread
   472      * @param arrayLength the number of parameter types to change
   473      * @param arrayLength the number of parameter types to change
   473      * @return the resulting type
   474      * @return the resulting type
   474      */
   475      */
   475     /*non-public*/ MethodType asSpreaderType(Class<?> arrayType, int arrayLength) {
   476     /*non-public*/ MethodType asSpreaderType(Class<?> arrayType, int pos, int arrayLength) {
   476         assert(parameterCount() >= arrayLength);
   477         assert(parameterCount() >= arrayLength);
   477         int spreadPos = ptypes.length - arrayLength;
   478         int spreadPos = pos;
   478         if (arrayLength == 0)  return this;  // nothing to change
   479         if (arrayLength == 0)  return this;  // nothing to change
   479         if (arrayType == Object[].class) {
   480         if (arrayType == Object[].class) {
   480             if (isGeneric())  return this;  // nothing to change
   481             if (isGeneric())  return this;  // nothing to change
   481             if (spreadPos == 0) {
   482             if (spreadPos == 0) {
   482                 // no leading arguments to preserve; go generic
   483                 // no leading arguments to preserve; go generic
   487                 return res;
   488                 return res;
   488             }
   489             }
   489         }
   490         }
   490         Class<?> elemType = arrayType.getComponentType();
   491         Class<?> elemType = arrayType.getComponentType();
   491         assert(elemType != null);
   492         assert(elemType != null);
   492         for (int i = spreadPos; i < ptypes.length; i++) {
   493         for (int i = spreadPos; i < spreadPos + arrayLength; i++) {
   493             if (ptypes[i] != elemType) {
   494             if (ptypes[i] != elemType) {
   494                 Class<?>[] fixedPtypes = ptypes.clone();
   495                 Class<?>[] fixedPtypes = ptypes.clone();
   495                 Arrays.fill(fixedPtypes, i, ptypes.length, elemType);
   496                 Arrays.fill(fixedPtypes, i, spreadPos + arrayLength, elemType);
   496                 return methodType(rtype, fixedPtypes);
   497                 return methodType(rtype, fixedPtypes);
   497             }
   498             }
   498         }
   499         }
   499         return this;  // arguments check out; no change
   500         return this;  // arguments check out; no change
   500     }
   501     }
   510         return ptype;
   511         return ptype;
   511     }
   512     }
   512 
   513 
   513     /** Delete the last parameter type and replace it with arrayLength copies of the component type of arrayType.
   514     /** Delete the last parameter type and replace it with arrayLength copies of the component type of arrayType.
   514      * @param arrayType any array type
   515      * @param arrayType any array type
       
   516      * @param pos position at which to insert parameters
   515      * @param arrayLength the number of parameter types to insert
   517      * @param arrayLength the number of parameter types to insert
   516      * @return the resulting type
   518      * @return the resulting type
   517      */
   519      */
   518     /*non-public*/ MethodType asCollectorType(Class<?> arrayType, int arrayLength) {
   520     /*non-public*/ MethodType asCollectorType(Class<?> arrayType, int pos, int arrayLength) {
   519         assert(parameterCount() >= 1);
   521         assert(parameterCount() >= 1);
   520         assert(lastParameterType().isAssignableFrom(arrayType));
   522         assert(pos < ptypes.length);
       
   523         assert(ptypes[pos].isAssignableFrom(arrayType));
   521         MethodType res;
   524         MethodType res;
   522         if (arrayType == Object[].class) {
   525         if (arrayType == Object[].class) {
   523             res = genericMethodType(arrayLength);
   526             res = genericMethodType(arrayLength);
   524             if (rtype != Object.class) {
   527             if (rtype != Object.class) {
   525                 res = res.changeReturnType(rtype);
   528                 res = res.changeReturnType(rtype);
   530             res = methodType(rtype, Collections.nCopies(arrayLength, elemType));
   533             res = methodType(rtype, Collections.nCopies(arrayLength, elemType));
   531         }
   534         }
   532         if (ptypes.length == 1) {
   535         if (ptypes.length == 1) {
   533             return res;
   536             return res;
   534         } else {
   537         } else {
   535             return res.insertParameterTypes(0, parameterList().subList(0, ptypes.length-1));
   538             // insert after (if need be), then before
       
   539             if (pos < parameterList().size() - 1) {
       
   540                 res = res.insertParameterTypes(arrayLength, parameterList().subList(pos + 1, parameterList().size()));
       
   541             }
       
   542             return res.insertParameterTypes(0, parameterList().subList(0, pos));
   536         }
   543         }
   537     }
   544     }
   538 
   545 
   539     /**
   546     /**
   540      * Finds or creates a method type with some parameter types omitted.
   547      * Finds or creates a method type with some parameter types omitted.