List<TextRange> (int mainRangeStartOffset, CharSequence text, IndexPattern[] allIndexPatterns, List<CommentRange> commentRanges, int commentNum) { CommentRange commentRange = commentRanges.get(commentNum); int lineStartOffset = CharArrayUtil.shiftBackwardUntil(text, mainRangeStartOffset - 1, "\n") + 1; int lineEndOffset = CharArrayUtil.shiftForwardUntil(text, mainRangeStartOffset, "\n"); int offsetInLine = mainRangeStartOffset - lineStartOffset; int maxCommentStartOffsetInLine = Math.max(0, commentRange.startOffset - lineStartOffset); List<TextRange> result = new ArrayList<>(); outer: while (lineEndOffset < text.length()) { lineStartOffset = lineEndOffset + 1; lineEndOffset = CharArrayUtil.shiftForwardUntil(text, lineStartOffset, "\n"); int refOffset = lineStartOffset + offsetInLine; int continuationStartOffset = CharArrayUtil.shiftForward(text, refOffset, lineEndOffset, WHITESPACE); if (continuationStartOffset == refOffset || continuationStartOffset >= lineEndOffset) break; if (continuationStartOffset >= commentRange.endOffset) { commentNum++; if (commentNum >= commentRanges.size()) break; commentRange = commentRanges.get(commentNum); if (continuationStartOffset < commentRange.startOffset || continuationStartOffset >= commentRange.endOffset) break; } int commentStartOffset = Math.max(lineStartOffset, commentRange.startOffset); int continuationEndOffset = Math.min(lineEndOffset, commentRange.endOffset); if (refOffset < commentStartOffset || commentStartOffset > lineStartOffset + maxCommentStartOffsetInLine || CharArrayUtil.shiftBackward(text, commentStartOffset, refOffset - 1, WHITESPACE + commentRange.allowedContinuationPrefixChars) + 1 != commentStartOffset) { break; } CharSequence commentText = StringPattern.newBombedCharSequence(text.subSequence(commentStartOffset, continuationEndOffset)); for (IndexPattern pattern: allIndexPatterns) { Pattern p = pattern.getPattern(); if (p != null && p.matcher(commentText).find()) break outer; } result.add(new TextRange(continuationStartOffset, continuationEndOffset)); } return result.isEmpty() ? Collections.emptyList() : result; }