/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.intellij.diff.comparison; import com.intellij.diff.util.IntPair; import com.intellij.diff.util.MergeRange; import com.intellij.diff.util.Range; import org.jetbrains.annotations.NotNull; import java.util.List; import static com.intellij.openapi.util.text.StringUtil.isWhiteSpace; @SuppressWarnings({"Duplicates", "unused", "TypeParameterExplicitlyExtendsObject"}) public class TrimUtil { public static boolean isPunctuation(char c) { if (c == '_') return false; boolean isPunctuation = false; isPunctuation |= c >= 33 & c <= 47; // !"#$%&'()*+,-./ isPunctuation |= c >= 58 & c <= 64; // :;<=>?@ isPunctuation |= c >= 91 & c <= 96; // [\]^_` isPunctuation |= c >= 123 & c <= 126; // {|}~ return isPunctuation; } public static boolean isAlpha(char c) { return !isWhiteSpace(c) && !isPunctuation(c); } // // Trim // @NotNull public static Range trim(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { start1 = trimStart(text1, start1, end1); end1 = trimEnd(text1, start1, end1); start2 = trimStart(text2, start2, end2); end2 = trimEnd(text2, start2, end2); return new Range(start1, end1, start2, end2); } @NotNull public static MergeRange trim(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, int start1, int start2, int start3, int end1, int end2, int end3) { start1 = trimStart(text1, start1, end1); end1 = trimEnd(text1, start1, end1); start2 = trimStart(text2, start2, end2); end2 = trimEnd(text2, start2, end2); start3 = trimStart(text3, start3, end3); end3 = trimEnd(text3, start3, end3); return new MergeRange(start1, end1, start2, end2, start3, end3); } @NotNull public static IntPair trim(@NotNull CharSequence text, int start, int end) { start = trimStart(text, start, end); end = trimEnd(text, start, end); return new IntPair(start, end); } public static int trimStart(@NotNull CharSequence text, int start, int end) { while (start < end) { char c = text.charAt(start); if (!isWhiteSpace(c)) break; start++; } return start; } public static int trimEnd(@NotNull CharSequence text, int start, int end) { while (start < end) { char c = text.charAt(end - 1); if (!isWhiteSpace(c)) break; end--; } return end; } // // Expand // @NotNull public static Range expand(@NotNull List<?> text1, @NotNull List<?> text2, int start1, int start2, int end1, int end2) { int count1 = expandForward(text1, text2, start1, start2, end1, end2); start1 += count1; start2 += count1; int count2 = expandBackward(text1, text2, start1, start2, end1, end2); end1 -= count2; end2 -= count2; return new Range(start1, end1, start2, end2); } @NotNull public static Range expand(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int count1 = expandForward(text1, text2, start1, start2, end1, end2); start1 += count1; start2 += count1; int count2 = expandBackward(text1, text2, start1, start2, end1, end2); end1 -= count2; end2 -= count2; return new Range(start1, end1, start2, end2); } @NotNull public static Range expandW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int count1 = expandForwardW(text1, text2, start1, start2, end1, end2); start1 += count1; start2 += count1; int count2 = expandBackwardW(text1, text2, start1, start2, end1, end2); end1 -= count2; end2 -= count2; return new Range(start1, end1, start2, end2); } @NotNull public static MergeRange expandW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, int start1, int start2, int start3, int end1, int end2, int end3) { int count1 = expandForwardW(text1, text2, text3, start1, start2, start3, end1, end2, end3); start1 += count1; start2 += count1; start3 += count1; int count2 = expandBackwardW(text1, text2, text3, start1, start2, start3, end1, end2, end3); end1 -= count2; end2 -= count2; end3 -= count2; return new MergeRange(start1, end1, start2, end2, start3, end3); } public static int expandForward(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int oldStart1 = start1; while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(start1); char c2 = text2.charAt(start2); if (c1 != c2) break; start1++; start2++; } return start1 - oldStart1; } public static int expandForward(@NotNull List<?> text1, @NotNull List<?> text2, int start1, int start2, int end1, int end2) { int oldStart1 = start1; while (start1 < end1 && start2 < end2) { Object c1 = text1.get(start1); Object c2 = text2.get(start2); if (!c1.equals(c2)) break; start1++; start2++; } return start1 - oldStart1; } public static int expandForwardW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int oldStart1 = start1; while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(start1); char c2 = text2.charAt(start2); if (c1 != c2 || !isWhiteSpace(c1)) break; start1++; start2++; } return start1 - oldStart1; } public static int expandBackward(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int oldEnd1 = end1; while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(end1 - 1); char c2 = text2.charAt(end2 - 1); if (c1 != c2) break; end1--; end2--; } return oldEnd1 - end1; } public static int expandBackward(@NotNull List<?> text1, @NotNull List<?> text2, int start1, int start2, int end1, int end2) { int oldEnd1 = end1; while (start1 < end1 && start2 < end2) { Object c1 = text1.get(end1 - 1); Object c2 = text2.get(end2 - 1); if (!c1.equals(c2)) break; end1--; end2--; } return oldEnd1 - end1; } public static int expandBackwardW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { int oldEnd1 = end1; while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(end1 - 1); char c2 = text2.charAt(end2 - 1); if (c1 != c2 || !isWhiteSpace(c1)) break; end1--; end2--; } return oldEnd1 - end1; } public static int expandForwardW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, int start1, int start2, int start3, int end1, int end2, int end3) { int oldStart1 = start1; while (start1 < end1 && start2 < end2 && start3 < end3) { char c1 = text1.charAt(start1); char c2 = text2.charAt(start2); char c3 = text3.charAt(start3); if (c1 != c2 || c1 != c3 || !isWhiteSpace(c1)) break; start1++; start2++; start3++; } return start1 - oldStart1; } public static int expandBackwardW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, int start1, int start2, int start3, int end1, int end2, int end3) { int oldEnd1 = end1; while (start1 < end1 && start2 < end2 && start3 < end3) { char c1 = text1.charAt(end1 - 1); char c2 = text2.charAt(end2 - 1); char c3 = text3.charAt(end3 - 1); if (c1 != c2 || c1 != c3|| !isWhiteSpace(c1)) break; end1--; end2--; end3--; } return oldEnd1 - end1; } @NotNull public static IntPair expandForwardIW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(start1); char c2 = text2.charAt(start2); if (c1 == c2) { start1++; start2++; continue; } boolean skipped = false; if (isWhiteSpace(c1)) { skipped = true; start1++; } if (isWhiteSpace(c2)) { skipped = true; start2++; } if (!skipped) break; } start1 = trimStart(text1, start1, end1); start2 = trimStart(text2, start2, end2); return new IntPair(start1, start2); } @NotNull public static IntPair expandBackwardIW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { while (start1 < end1 && start2 < end2) { char c1 = text1.charAt(end1 - 1); char c2 = text2.charAt(end2 - 1); if (c1 == c2) { end1--; end2--; continue; } boolean skipped = false; if (isWhiteSpace(c1)) { skipped = true; end1--; } if (isWhiteSpace(c2)) { skipped = true; end2--; } if (!skipped) break; } end1 = trimEnd(text1, start1, end1); end2 = trimEnd(text2, start2, end2); return new IntPair(end1, end2); } @NotNull public static Range expandIW(@NotNull CharSequence text1, @NotNull CharSequence text2, int start1, int start2, int end1, int end2) { IntPair start = expandForwardIW(text1, text2, start1, start2, end1, end2); start1 = start.val1; start2 = start.val2; IntPair end = expandBackwardIW(text1, text2, start1, start2, end1, end2); end1 = end.val1; end2 = end.val2; return new Range(start1, end1, start2, end2); } // // Misc // @NotNull public static Range expand(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull Range range) { return expand(text1, text2, range.start1, range.start2, range.end1, range.end2); } @NotNull public static Range expandW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull Range range) { return expandW(text1, text2, range.start1, range.start2, range.end1, range.end2); } @NotNull public static Range trim(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull Range range) { return trim(text1, text2, range.start1, range.start2, range.end1, range.end2); } @NotNull public static MergeRange trim(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, @NotNull MergeRange range) { return trim(text1, text2, text3, range.start1, range.start2, range.start3, range.end1, range.end2, range.end3); } @NotNull public static MergeRange expandW(@NotNull CharSequence text1, @NotNull CharSequence text2, @NotNull CharSequence text3, @NotNull MergeRange range) { return expandW(text1, text2, text3, range.start1, range.start2, range.start3, range.end1, range.end2, range.end3); } @NotNull public static Range expandIW(@NotNull CharSequence text1, @NotNull CharSequence text2) { return expandIW(text1, text2, 0, 0, text1.length(), text2.length()); } }