protected static RangeInfo subListBorders(int size, Range range) { if (range instanceof IntRange) { return ((IntRange)range).subListBorders(size); } int from = normaliseIndex(DefaultTypeTransformation.intUnbox(range.getFrom()), size); int to = normaliseIndex(DefaultTypeTransformation.intUnbox(range.getTo()), size); boolean reverse = range.isReverse(); if (from > to) { // support list[1..-1] int tmp = to; to = from; from = tmp; reverse = !reverse; } return new RangeInfo(from, to + 1, reverse); }
/** * Sub-range access for annotation sets (mapping to getContained). * Allows <code>someAnnotationSet[15..20]</code>. This works with ranges * whose end points are any numeric type, so as well as using integer * literals you can do <code>someAnnotationSet[ann.start()..ann.end()]</code> * (as start and end return Long). * @see AnnotationSet#getContained(Long, Long) */ @SuppressWarnings("unchecked") public static AnnotationSet getAt(AnnotationSet self, Range<?> range) { if(range.getFrom() instanceof Number) { return self.getContained( Long.valueOf(((Number)range.getFrom()).longValue()), Long.valueOf(((Number)range.getTo()).longValue())); } else if(range.getFrom() instanceof String) { return getAt(self, (List<String>)range); } else { throw new IllegalArgumentException( "AnnotationSet.getAt expects a numeric or string range"); } }
/** * Sub-range access for document content. Allows * <code>documentContent[15..20]</code>. This works with ranges * whose end points are any numeric type, so as well as using integer * literals you can do <code>documentContent[ann.start()..ann.end()]</code> * (as start and end return Long). * @param self * @param range * @return */ public static DocumentContent getAt(DocumentContent self, Range<?> range) { if(range.getFrom() instanceof Number) { try { return self.getContent( Long.valueOf(((Number)range.getFrom()).longValue()), Long.valueOf(((Number)range.getTo()).longValue())); } catch(InvalidOffsetException ioe) { throw new IndexOutOfBoundsException(ioe.getMessage()); } } else { throw new IllegalArgumentException( "DocumentContent.getAt expects a numeric range"); } }
/** * Support the range subscript operator for an eager or lazy List. * <pre class="groovyTestCase">def list = [].withDefault { 42 } * assert list[1..2] == [null, 42]</pre> * * @param self a ListWithDefault * @param range a Range indicating the items to get * * @return a new eager or lazy list instance based on range borders */ public static <T> List<T> getAt(ListWithDefault<T> self, Range range) { RangeInfo info = subListBorders(self.size(), range); // if a positive index is accessed not initialized so far // initialization up to that index takes place if (self.size() < info.to) { self.get(info.to - 1); } List<T> answer = self.subList(info.from, info.to); if (info.reverse) { answer = ListWithDefault.newInstance(reverse(answer), self.isLazyDefaultValues(), self.getInitClosure()); } else { // instead of using the SubList backed by the parent list, a new ArrayList instance is used answer = ListWithDefault.newInstance(new ArrayList<T>(answer), self.isLazyDefaultValues(), self.getInitClosure()); } return answer; }
/** * Sub-range access for document content. Allows * <code>documentContent[15..20]</code>. This works with ranges * whose end points are any numeric type, so as well as using integer * literals you can do <code>documentContent[ann.start()..ann.end()]</code> * (as start and end return Long). * @param self * @param range * @return */ public static DocumentContent getAt(DocumentContent self, Range range) { if(range.getFrom() instanceof Number) { try { return self.getContent( Long.valueOf(((Number)range.getFrom()).longValue()), Long.valueOf(((Number)range.getTo()).longValue())); } catch(InvalidOffsetException ioe) { throw new IndexOutOfBoundsException(ioe.getMessage()); } } else { throw new IllegalArgumentException( "DocumentContent.getAt expects a numeric range"); } }
@Override public void visitRangeExpression(final RangeExpression expression) { super.visitRangeExpression(expression); ClassNode fromType = getWrapper(getType(expression.getFrom())); ClassNode toType = getWrapper(getType(expression.getTo())); if (Integer_TYPE.equals(fromType) && Integer_TYPE.equals(toType)) { storeType(expression, ClassHelper.make(IntRange.class)); } else { ClassNode rangeType = ClassHelper.make(Range.class).getPlainNodeReference(); rangeType.setGenericsTypes(new GenericsType[] { new GenericsType(WideningCategories.lowestUpperBound(fromType, toType))}); storeType(expression, rangeType); } }
/** * Support the range subscript operator for a List. * <pre class="groovyTestCase">def list = [1, "a", 4.5, true] * assert list[1..2] == ["a", 4.5]</pre> * * @param self a List * @param range a Range indicating the items to get * @return a new list instance based on range borders * * @since 1.0 */ public static <T> List<T> getAt(List<T> self, Range range) { RangeInfo info = subListBorders(self.size(), range); List<T> subList = self.subList(info.from, info.to); if (info.reverse) { subList = reverse(subList); } // trying to guess the concrete list type and create a new instance from it List<T> answer = createSimilarList(self, subList.size()); answer.addAll(subList); return answer; }
/** * Select a List of items from an eager or lazy List using a Collection to * identify the indices to be selected. * <pre class="groovyTestCase">def list = [].withDefault { 42 } * assert list[1,0,2] == [42, 42, 42]</pre> * * @param self a ListWithDefault * @param indices a Collection of indices * * @return a new eager or lazy list of the values at the given indices */ public static <T> List<T> getAt(ListWithDefault<T> self, Collection indices) { List<T> answer = ListWithDefault.newInstance(new ArrayList<T>(indices.size()), self.isLazyDefaultValues(), self.getInitClosure()); for (Object value : indices) { if (value instanceof Range || value instanceof Collection) { answer.addAll((List<T>) InvokerHelper.invokeMethod(self, "getAt", value)); } else { int idx = normaliseIndex(DefaultTypeTransformation.intUnbox(value), self.size()); answer.add(self.getAt(idx)); } } return answer; }
/** * Select a List of items from a List using a Collection to * identify the indices to be selected. * <pre class="groovyTestCase">def list = [true, 1, 3.4, false] * assert list[1,0,2] == [1, true, 3.4]</pre> * * @param self a List * @param indices a Collection of indices * @return a new list of the values at the given indices * @since 1.0 */ public static <T> List<T> getAt(List<T> self, Collection indices) { List<T> answer = new ArrayList<T>(indices.size()); for (Object value : indices) { if (value instanceof Range || value instanceof Collection) { answer.addAll((List<T>)InvokerHelper.invokeMethod(self, "getAt", value)); } else { int idx = DefaultTypeTransformation.intUnbox(value); answer.add(getAt(self, idx)); } } return answer; }
/** * Select a List of items from an array using a Collection to * identify the indices to be selected. * * @param self an array * @param indices a Collection of indices * @return a new list of the values at the given indices * @since 1.0 */ public static <T> List<T> getAt(T[] self, Collection indices) { List<T> answer = new ArrayList<T>(indices.size()); for (Object value : indices) { if (value instanceof Range) { answer.addAll(getAt(self, (Range) value)); } else if (value instanceof Collection) { answer.addAll(getAt(self, (Collection) value)); } else { int idx = DefaultTypeTransformation.intUnbox(value); answer.add(getAtImpl(self, idx)); } } return answer; }
/** * Implements the getAt(Range) method for primitive type arrays. * * @param self an array object * @param range the range of indices of interest * @return the returned values from the array corresponding to the range * @since 1.5.0 */ protected static List primitiveArrayGet(Object self, Range range) { List answer = new ArrayList(); for (Object next : range) { int idx = DefaultTypeTransformation.intUnbox(next); answer.add(primitiveArrayGet(self, idx)); } return answer; }
/** * Implements the getAt(Collection) method for primitive type arrays. Each * value in the collection argument is assumed to be a valid array index. * The value at each index is then added to a list which is returned. * * @param self an array object * @param indices the indices of interest * @return the returned values from the array * @since 1.0 */ protected static List primitiveArrayGet(Object self, Collection indices) { List answer = new ArrayList(); for (Object value : indices) { if (value instanceof Range) { answer.addAll(primitiveArrayGet(self, (Range) value)); } else if (value instanceof List) { answer.addAll(primitiveArrayGet(self, (List) value)); } else { int idx = DefaultTypeTransformation.intUnbox(value); answer.add(primitiveArrayGet(self, idx)); } } return answer; }
/** * Select a List of characters from a CharSequence using a Collection * to identify the indices to be selected. * * @param self a CharSequence * @param indices a Collection of indices * @return a String consisting of the characters at the given indices * @since 1.0 */ public static String getAt(CharSequence self, Collection indices) { StringBuilder answer = new StringBuilder(); for (Object value : indices) { if (value instanceof Range) { answer.append(getAt(self, (Range) value)); } else if (value instanceof Collection) { answer.append(getAt(self, (Collection) value)); } else { int idx = DefaultTypeTransformation.intUnbox(value); answer.append(getAt(self, idx)); } } return answer.toString(); }
/** * Support the range subscript operator for String * * @param text a String * @param range a Range * @return a substring corresponding to the Range * @since 1.0 */ public static String getAt(String text, Range range) { RangeInfo info = subListBorders(text.length(), range); String answer = text.substring(info.from, info.to); if (info.reverse) { answer = reverse((CharSequence)answer); } return answer; }
/** * Sub-range access for annotation sets (mapping to getContained). * Allows <code>someAnnotationSet[15..20]</code>. This works with ranges * whose end points are any numeric type, so as well as using integer * literals you can do <code>someAnnotationSet[ann.start()..ann.end()]</code> * (as start and end return Long). * @see AnnotationSet#getContained(Long, Long) */ public static AnnotationSet getAt(AnnotationSet self, Range range) { if(range.getFrom() instanceof Number) { return self.getContained( Long.valueOf(((Number)range.getFrom()).longValue()), Long.valueOf(((Number)range.getTo()).longValue())); } else if(range.getFrom() instanceof String) { return getAt(self, (List<String>)range); } else { throw new IllegalArgumentException( "AnnotationSet.getAt expects a numeric or string range"); } }
@Deprecated public static CharSequence getAt(CharSequence text, Range range) { return StringGroovyMethods.getAt(text, range); }
@Deprecated public static String getAt(String text, Range range) { return StringGroovyMethods.getAt(text, range); }
/** * Support the range subscript operator for an Array * * @param array an Array of Objects * @param range a Range * @return a range of a list from the range's from index up to but not * including the range's to value * @since 1.0 */ public static <T> List<T> getAt(T[] array, Range range) { List<T> list = Arrays.asList(array); return getAt(list, range); }
/** * Support the subscript operator with a range for a byte array * * @param array a byte array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved bytes * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Byte> getAt(byte[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a char array * * @param array a char array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved chars * @since 1.5.0 */ @SuppressWarnings("unchecked") public static List<Character> getAt(char[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a short array * * @param array a short array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved shorts * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Short> getAt(short[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for an int array * * @param array an int array * @param range a range indicating the indices for the items to retrieve * @return list of the ints at the given indices * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Integer> getAt(int[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a long array * * @param array a long array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved longs * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Long> getAt(long[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a float array * * @param array a float array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved floats * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Float> getAt(float[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a double array * * @param array a double array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved doubles * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Double> getAt(double[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the subscript operator with a range for a boolean array * * @param array a boolean array * @param range a range indicating the indices for the items to retrieve * @return list of the retrieved booleans * @since 1.0 */ @SuppressWarnings("unchecked") public static List<Boolean> getAt(boolean[] array, Range range) { return primitiveArrayGet(array, range); }
/** * Support the range subscript operator for CharSequence with IntRange * * @param text a CharSequence * @param range an IntRange * @return the subsequence CharSequence * @since 1.0 */ public static CharSequence getAt(CharSequence text, IntRange range) { return getAt(text, (Range) range); }
/** * Support the range subscript operator for GString with IntRange * * @param text a GString * @param range an IntRange * @return the String of characters corresponding to the provided range * @since 2.3.7 */ public static String getAt(GString text, IntRange range) { return getAt(text, (Range) range); }
/** * Support the range subscript operator for CharSequence * * @param text a CharSequence * @param range a Range * @return the subsequence CharSequence * @since 1.0 */ public static CharSequence getAt(CharSequence text, Range range) { RangeInfo info = subListBorders(text.length(), range); CharSequence sequence = text.subSequence(info.from, info.to); return info.reverse ? reverse(sequence) : sequence; }
/** * Support the range subscript operator for GString * * @param text a GString * @param range a Range * @return the String of characters corresponding to the provided range * @since 2.3.7 */ public static String getAt(GString text, Range range) { return getAt(text.toString(), range); }
/** * Support the range subscript operator for String with IntRange * * @param text a String * @param range an IntRange * @return the resulting String * @since 1.0 */ public static String getAt(String text, IntRange range) { return getAt(text, (Range) range); }