/**
   * converts back slashes to forward slashes removes double slashes inside the path, e.g. "x/y//z"
   * => "x/y/z"
   */
  @NotNull
  public static String normalize(@NotNull String path) {
    final StringBuilder result = new StringBuilder(path.length());

    int start = 0;
    boolean separator = false;
    if (SystemInfo.isWindows && (path.startsWith("//") || path.startsWith("\\\\"))) {
      start = 2;
      result.append("//");
      separator = true;
    }

    for (int i = start; i < path.length(); ++i) {
      final char c = path.charAt(i);
      if (c == '/' || c == '\\') {
        if (!separator) result.append('/');
        separator = true;
      } else {
        result.append(c);
        separator = false;
      }
    }

    return result.toString();
  }
示例#2
1
  @Contract("null, _, _ -> null")
  private static String toCanonicalPath(
      @Nullable String path, char separatorChar, boolean removeLastSlash) {
    if (path == null || path.isEmpty()) {
      return path;
    } else if (".".equals(path)) {
      return "";
    }

    path = path.replace(separatorChar, '/');
    if (path.indexOf('/') == -1) {
      return path;
    }

    int start = pathRootEnd(path) + 1, dots = 0;
    boolean separator = true;

    StringBuilder result = new StringBuilder(path.length());
    result.append(path, 0, start);

    for (int i = start; i < path.length(); ++i) {
      char c = path.charAt(i);
      if (c == '/') {
        if (!separator) {
          processDots(result, dots, start);
          dots = 0;
        }
        separator = true;
      } else if (c == '.') {
        if (separator || dots > 0) {
          ++dots;
        } else {
          result.append('.');
        }
        separator = false;
      } else {
        if (dots > 0) {
          StringUtil.repeatSymbol(result, '.', dots);
          dots = 0;
        }
        result.append(c);
        separator = false;
      }
    }

    if (dots > 0) {
      processDots(result, dots, start);
    }

    int lastChar = result.length() - 1;
    if (removeLastSlash && lastChar >= 0 && result.charAt(lastChar) == '/' && lastChar > start) {
      result.deleteCharAt(lastChar);
    }

    return result.toString();
  }
  protected String doCalculateSignature(PsiMethod method) {
    final StringBuilder buffer = new StringBuilder();
    final PsiModifierList modifierList = method.getModifierList();
    String modifiers = modifierList.getText();
    final String oldModifier = VisibilityUtil.getVisibilityModifier(modifierList);
    final String newModifier = getVisibility();
    String newModifierStr = VisibilityUtil.getVisibilityString(newModifier);
    if (!newModifier.equals(oldModifier)) {
      int index = modifiers.indexOf(oldModifier);
      if (index >= 0) {
        final StringBuilder buf = new StringBuilder(modifiers);
        buf.replace(
            index,
            index + oldModifier.length() + ("".equals(newModifierStr) ? 1 : 0),
            newModifierStr);
        modifiers = buf.toString();
      } else {
        if (!StringUtil.isEmpty(newModifierStr)) {
          newModifierStr += " ";
        }
        modifiers = newModifierStr + modifiers;
      }
    }

    buffer.append(modifiers);
    if (modifiers.length() > 0
        && !StringUtil.endsWithChar(modifiers, '\n')
        && !StringUtil.endsWithChar(modifiers, '\r')
        && !StringUtil.endsWithChar(modifiers, ' ')) {
      buffer.append(" ");
    }

    if (!method.isConstructor()) {
      final CanonicalTypes.Type type = getReturnType();
      if (type != null) {
        buffer.append(type.getTypeText());
      }
      buffer.append(" ");
    }
    buffer.append(getMethodName());
    buffer.append("(");

    final int lineBreakIdx = buffer.lastIndexOf("\n");
    String indent =
        StringUtil.repeatSymbol(
            ' ', lineBreakIdx >= 0 ? buffer.length() - lineBreakIdx - 1 : buffer.length());
    List<ParameterTableModelItemBase<ParameterInfoImpl>> items = myParametersTableModel.getItems();
    int curIndent = indent.length();
    for (int i = 0; i < items.size(); i++) {
      final ParameterTableModelItemBase<ParameterInfoImpl> item = items.get(i);
      if (i > 0) {
        buffer.append(",");
        buffer.append("\n");
        buffer.append(indent);
      }
      final String text = item.typeCodeFragment.getText();
      buffer.append(text).append(" ");
      final String name = item.parameter.getName();
      buffer.append(name);
      curIndent = indent.length() + text.length() + 1 + name.length();
    }
    // if (!items.isEmpty()) {
    //  buffer.append("\n");
    // }
    buffer.append(")");
    PsiTypeCodeFragment[] thrownExceptionsFragments = myExceptionsModel.getTypeCodeFragments();
    if (thrownExceptionsFragments.length > 0) {
      // buffer.append("\n");
      buffer.append(" throws ");
      curIndent += 9; // ") throws ".length()
      indent = StringUtil.repeatSymbol(' ', curIndent);
      for (int i = 0; i < thrownExceptionsFragments.length; i++) {
        String text = thrownExceptionsFragments[i].getText();
        if (i != 0) buffer.append(indent);
        buffer.append(text);
        if (i < thrownExceptionsFragments.length - 1) {
          buffer.append(",");
        }
        buffer.append("\n");
      }
    }

    return buffer.toString();
  }
 private static String printLogData(DetailedLogData firstBlockSyncData) {
   StringBuilder sb = new StringBuilder();
   sb.append("Last 100 commits:\n");
   sb.append(printCommits(firstBlockSyncData.getCommits()));
   sb.append("\nRefs:\n");
   sb.append(printRefs(firstBlockSyncData.getRefs()));
   return sb.toString();
 }
  @NonNls
  public static String toString(Iterable<?> collection) {
    if (!collection.iterator().hasNext()) {
      return "<empty>";
    }

    final StringBuilder builder = new StringBuilder();
    for (final Object o : collection) {
      if (o instanceof THashSet) {
        builder.append(new TreeSet<Object>((THashSet) o));
      } else {
        builder.append(o);
      }
      builder.append("\n");
    }
    return builder.toString();
  }
  private static int processRoot(String path, StringBuilder result) {
    if (SystemInfo.isWindows
        && path.length() > 1
        && path.charAt(0) == '/'
        && path.charAt(1) == '/') {
      result.append("//");

      int hostStart = 2;
      while (hostStart < path.length() && path.charAt(hostStart) == '/') hostStart++;
      if (hostStart == path.length()) return hostStart;
      int hostEnd = path.indexOf('/', hostStart);
      if (hostEnd < 0) hostEnd = path.length();
      result.append(path, hostStart, hostEnd);
      result.append('/');

      int shareStart = hostEnd;
      while (shareStart < path.length() && path.charAt(shareStart) == '/') shareStart++;
      if (shareStart == path.length()) return shareStart;
      int shareEnd = path.indexOf('/', shareStart);
      if (shareEnd < 0) shareEnd = path.length();
      result.append(path, shareStart, shareEnd);
      result.append('/');

      return shareEnd;
    } else if (path.length() > 0 && path.charAt(0) == '/') {
      result.append('/');
      return 1;
    } else if (path.length() > 2 && path.charAt(1) == ':' && path.charAt(2) == '/') {
      result.append(path, 0, 3);
      return 3;
    } else {
      return 0;
    }
  }
  /**
   * Has duplicate: {@link
   * com.intellij.coverage.listeners.CoverageListener#sanitize(java.lang.String, java.lang.String)}
   * as FileUtil is not available in client's vm
   */
  @NotNull
  public static String sanitizeFileName(@NotNull String name) {
    StringBuilder result = new StringBuilder();

    for (int i = 0; i < name.length(); i++) {
      final char ch = name.charAt(i);

      if (ch > 0 && ch < 255) {
        if (Character.isLetterOrDigit(ch)) {
          result.append(ch);
        } else {
          result.append("_");
        }
      }
    }

    return result.toString();
  }
  /**
   * Returns the relative path from one virtual file to another.
   *
   * @param src the file from which the relative path is built.
   * @param dst the file to which the path is built.
   * @param separatorChar the separator for the path components.
   * @return the relative path, or null if the files have no common ancestor.
   * @since 5.0.2
   */
  @Nullable
  public static String getPath(
      @NotNull VirtualFile src, @NotNull VirtualFile dst, char separatorChar) {
    final VirtualFile commonAncestor = getCommonAncestor(src, dst);
    if (commonAncestor != null) {
      StringBuilder buffer = new StringBuilder();
      if (src != commonAncestor) {
        while (src.getParent() != commonAncestor) {
          buffer.append("..").append(separatorChar);
          src = src.getParent();
        }
      }
      buffer.append(getRelativePath(dst, commonAncestor, separatorChar));
      return buffer.toString();
    }

    return null;
  }
 public static String toString(Collection<?> collection, String separator) {
   List<String> list =
       ContainerUtil.map2List(
           collection,
           new Function<Object, String>() {
             @Override
             public String fun(final Object o) {
               return String.valueOf(o);
             }
           });
   Collections.sort(list);
   StringBuilder builder = new StringBuilder();
   boolean flag = false;
   for (final String o : list) {
     if (flag) {
       builder.append(separator);
     }
     builder.append(o);
     flag = true;
   }
   return builder.toString();
 }
 private static void processDots(StringBuilder result, int dots, int start) {
   if (dots == 2) {
     int pos = -1;
     if (!StringUtil.endsWith(result, "/../") && !StringUtil.equals(result, "../")) {
       pos = StringUtil.lastIndexOf(result, '/', start, result.length() - 1);
       if (pos >= 0) {
         ++pos; // separator found, trim to next char
       } else if (start > 0) {
         pos = start; // path is absolute, trim to root ('/..' -> '/')
       } else if (result.length() > 0) {
         pos = 0; // path is relative, trim to default ('a/..' -> '')
       }
     }
     if (pos >= 0) {
       result.delete(pos, result.length());
     } else {
       result.append("../"); // impossible to traverse, keep as-is
     }
   } else if (dots != 1) {
     StringUtil.repeatSymbol(result, '.', dots);
     result.append('/');
   }
 }
 private static String printCommits(List<VcsCommitMetadata> commits) {
   StringBuilder sb = new StringBuilder();
   for (int i = 0; i < Math.min(commits.size(), 100); i++) {
     GraphCommit<Hash> commit = commits.get(i);
     sb.append(
         String.format(
             "%s -> %s\n",
             commit.getId().toShortString(),
             StringUtil.join(
                 commit.getParents(),
                 new Function<Hash, String>() {
                   @Override
                   public String fun(Hash hash) {
                     return hash.toShortString();
                   }
                 },
                 ", ")));
   }
   return sb.toString();
 }
  @Nullable
  private static String getContent(File file) {
    try {
      StringBuilder content = new StringBuilder();
      BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
      try {
        do {
          String line = reader.readLine();
          if (line == null) break;
          content.append(line);
          content.append('\n');
        } while (true);
      } finally {
        reader.close();
      }

      return content.toString();
    } catch (Exception e) {
      return null;
    }
  }
  /**
   * @param antPattern ant-style path pattern
   * @return java regexp pattern. Note that no matter whether forward or backward slashes were used
   *     in the antPattern the returned regexp pattern will use forward slashes ('/') as file
   *     separators. Paths containing windows-style backslashes must be converted before matching
   *     against the resulting regexp
   * @see com.intellij.openapi.util.io.FileUtil#toSystemIndependentName
   */
  @RegExp
  @NotNull
  public static String convertAntToRegexp(@NotNull String antPattern, boolean ignoreStartingSlash) {
    final StringBuilder builder = new StringBuilder();
    int asteriskCount = 0;
    boolean recursive = true;
    final int start =
        ignoreStartingSlash
                && (StringUtil.startsWithChar(antPattern, '/')
                    || StringUtil.startsWithChar(antPattern, '\\'))
            ? 1
            : 0;
    for (int idx = start; idx < antPattern.length(); idx++) {
      final char ch = antPattern.charAt(idx);

      if (ch == '*') {
        asteriskCount++;
        continue;
      }

      final boolean foundRecursivePattern =
          recursive && asteriskCount == 2 && (ch == '/' || ch == '\\');
      final boolean asterisksFound = asteriskCount > 0;

      asteriskCount = 0;
      recursive = ch == '/' || ch == '\\';

      if (foundRecursivePattern) {
        builder.append("(?:[^/]+/)*?");
        continue;
      }

      if (asterisksFound) {
        builder.append("[^/]*?");
      }

      if (ch == '(' || ch == ')' || ch == '[' || ch == ']' || ch == '^' || ch == '$' || ch == '.'
          || ch == '{' || ch == '}' || ch == '+' || ch == '|') {
        // quote regexp-specific symbols
        builder.append('\\').append(ch);
        continue;
      }
      if (ch == '?') {
        builder.append("[^/]{1}");
        continue;
      }
      if (ch == '\\') {
        builder.append('/');
        continue;
      }
      builder.append(ch);
    }

    // handle ant shorthand: mypackage/test/ is interpreted as if it were mypackage/test/**
    final boolean isTrailingSlash =
        builder.length() > 0 && builder.charAt(builder.length() - 1) == '/';
    if (asteriskCount == 0 && isTrailingSlash || recursive && asteriskCount == 2) {
      if (isTrailingSlash) {
        builder.setLength(builder.length() - 1);
      }
      if (builder.length() == 0) {
        builder.append(".*");
      } else {
        builder.append("(?:$|/.+)");
      }
    } else if (asteriskCount > 0) {
      builder.append("[^/]*?");
    }
    return builder.toString();
  }
  @SuppressWarnings("StringConcatenationInsideStringBufferAppend")
  private static String printErrorDetails(
      @NotNull VirtualFile root,
      @NotNull Set<VcsRef> allRefs,
      @NotNull List<VcsCommitMetadata> sortedCommits,
      @NotNull DetailedLogData firstBlockSyncData,
      @NotNull Set<VcsRef> manuallyReadBranches,
      @Nullable Set<String> currentTagNames,
      @Nullable DetailedLogData commitsFromTags) {

    StringBuilder sb = new StringBuilder();
    sb.append("[" + root.getName() + "]\n");
    sb.append("First block data from Git:\n");
    sb.append(printLogData(firstBlockSyncData));
    sb.append("\n\nManually read refs:\n");
    sb.append(printRefs(manuallyReadBranches));
    sb.append("\n\nCurrent tag names:\n");
    if (currentTagNames != null) {
      sb.append(StringUtil.join(currentTagNames, ", "));
      if (commitsFromTags != null) {
        sb.append(printLogData(commitsFromTags));
      } else {
        sb.append("\n\nCommits from new tags were not read.\n");
      }
    } else {
      sb.append("\n\nCurrent tags were not read\n");
    }

    sb.append("\n\nResult:\n");
    sb.append("\nCommits (last 100): \n");
    sb.append(printCommits(sortedCommits));
    sb.append("\nAll refs:\n");
    sb.append(printRefs(allRefs));
    return sb.toString();
  }