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. |