protected void saveTo(OutputStreamWriter writer, FastStringBuffer tempBuf, File pathToSave)
      throws IOException {
    synchronized (lock) {
      if (DEBUG_ADDITIONAL_INFO) {
        System.out.println(
            "Saving info "
                + this.getClass().getName()
                + " to file (size = "
                + getAllTokens().size()
                + ") "
                + pathToSave);
      }

      Map<String, Integer> dictionary = new HashMap<String, Integer>();
      tempBuf.append("-- START TREE 1\n");
      TreeIO.dumpTreeToBuffer(this.topLevelInitialsToInfo, tempBuf, dictionary);

      tempBuf.append("-- START TREE 2\n");
      TreeIO.dumpTreeToBuffer(this.innerInitialsToInfo, tempBuf, dictionary);

      FastStringBuffer buf2 = new FastStringBuffer(50 * (dictionary.size() + 4));
      TreeIO.dumpDictToBuffer(dictionary, buf2);

      // Write the dictionary before the actual trees.
      writer.write(buf2.getInternalCharsArray(), 0, buf2.length());
      buf2 = null;

      // Note: tried LZFFileInputStream from https://github.com/ning/compress
      // and Snappy from https://github.com/dain/snappy checking to see if by writing less we'd
      // get a better time but it got a bit slower (gzip was slowest, then snappy and the faster was
      // LZFFileInputStream)
      writer.write(tempBuf.getInternalCharsArray(), 0, tempBuf.length());
    }
  }
Beispiel #2
0
 /**
  * We just want to trim whitespaces, not newlines!
  *
  * @param locBuf the buffer to be trimmed
  * @return the same buffer passed as a parameter
  */
 private FastStringBuffer trim(FastStringBuffer locBuf) {
   while (locBuf.length() > 0 && (locBuf.firstChar() == ' ' || locBuf.firstChar() == '\t')) {
     locBuf.deleteCharAt(0);
   }
   rtrim(locBuf);
   return locBuf;
 }
Beispiel #3
0
    /** Check if we are still in the number */
    @Override
    public boolean isWordPart(char c) {
      // ok, we have to test for scientific notation e.g.: 10.9e10

      if ((c == 'x' || c == 'X') && buffer.length() == 1 && buffer.charAt(0) == '0') {
        // it is an hexadecimal
        buffer.append(c);
        isInHexa = true;
        return true;
      } else {
        buffer.append(c);
      }

      if (isInHexa) {
        return Character.isDigit(c)
            || c == 'a'
            || c == 'A'
            || c == 'b'
            || c == 'B'
            || c == 'c'
            || c == 'C'
            || c == 'd'
            || c == 'D'
            || c == 'e'
            || c == 'E'
            || c == 'f'
            || c == 'F';

      } else {
        return Character.isDigit(c) || c == 'e' || c == '.';
      }
    }
  public void run(IAction action) {
    FastStringBuffer buf = new FastStringBuffer();
    try {
      PyEdit pyEdit = getPyEdit();

      PySelection pySelection = new PySelection(pyEdit);

      IPythonNature nature = pyEdit.getPythonNature();
      File editorFile = pyEdit.getEditorFile();

      if (editorFile != null) {
        if (nature != null) {
          String mod = nature.resolveModule(editorFile);
          if (mod != null) {
            buf.append(mod);

          } else {
            // Support for external files (not in PYTHONPATH).
            buf.append(FullRepIterable.getFirstPart(editorFile.getName()));
          }
        } else {
          buf.append(FullRepIterable.getFirstPart(editorFile.getName()));
        }
      }

      List<stmtType> path =
          FastParser.parseToKnowGloballyAccessiblePath(
              pySelection.getDoc(), pySelection.getStartLineIndex());
      for (stmtType stmtType : path) {
        if (buf.length() > 0) {
          buf.append('.');
        }
        buf.append(NodeUtils.getRepresentationString(stmtType));
      }

    } catch (MisconfigurationException e1) {
      Log.log(e1);
      return;
    }

    Transfer[] dataTypes = new Transfer[] {TextTransfer.getInstance()};
    Object[] data = new Object[] {buf.toString()};

    Clipboard clipboard = new Clipboard(EditorUtils.getShell().getDisplay());
    try {
      clipboard.setContents(data, dataTypes);
    } catch (SWTError e) {
      if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
        throw e;
      }
      MessageDialog.openError(
          EditorUtils.getShell(), "Error copying to clipboard.", e.getMessage());
    } finally {
      clipboard.dispose();
    }
  }
Beispiel #5
0
 public static String getRunningName(IPath[] paths) {
   FastStringBuffer buf = new FastStringBuffer(20 * paths.length);
   for (IPath p : paths) {
     if (buf.length() > 0) {
       buf.append(" - ");
     }
     buf.append(p.lastSegment());
   }
   return buf.toString();
 }
  /**
   * @param lastMayBeMethod if true, it gets the path and accepts a method (if it is the last in the
   *     stack) if false, null is returned if a method is found.
   * @param tempStack is a temporary stack object (which may be cleared)
   * @return a tuple, where the first element is the path where the entry is located (may return
   *     null). and the second element is a boolean that indicates if the last was actually a method
   *     or not.
   */
  private Tuple<String, Boolean> getPathToRoot(
      ASTEntry entry, boolean lastMayBeMethod, boolean acceptAny, FastStack<SimpleNode> tempStack) {
    if (entry.parent == null) {
      return null;
    }
    // just to be sure that it's empty
    tempStack.clear();

    boolean lastIsMethod = false;
    // if the last 'may be a method', in this case, we have to remember that it will actually be the
    // first one
    // to be analyzed.

    // let's get the stack
    while (entry.parent != null) {
      if (entry.parent.node instanceof ClassDef) {
        tempStack.push(entry.parent.node);

      } else if (entry.parent.node instanceof FunctionDef) {
        if (!acceptAny) {
          if (lastIsMethod) {
            // already found a method
            return null;
          }

          if (!lastMayBeMethod) {
            return null;
          }

          // ok, the last one may be a method... (in this search, it MUST be the first one...)
          if (tempStack.size() != 0) {
            return null;
          }
        }

        // ok, there was a class, so, let's go and set it
        tempStack.push(entry.parent.node);
        lastIsMethod = true;

      } else {
        return null;
      }
      entry = entry.parent;
    }

    // now that we have the stack, let's make it into a path...
    FastStringBuffer buf = new FastStringBuffer();
    while (tempStack.size() > 0) {
      if (buf.length() > 0) {
        buf.append(".");
      }
      buf.append(NodeUtils.getRepresentationString(tempStack.pop()));
    }
    return new Tuple<String, Boolean>(buf.toString(), lastIsMethod);
  }
  public List<IInfo> addAstInfo(ModulesKey key, boolean generateDelta) throws Exception {
    boolean isZipModule = key instanceof ModulesKeyForZip;
    ModulesKeyForZip modulesKeyForZip = null;
    if (isZipModule) {
      modulesKeyForZip = (ModulesKeyForZip) key;
    }

    Object doc;
    if (isZipModule) {
      doc =
          FileUtilsFileBuffer.getCustomReturnFromZip(
              modulesKeyForZip.file, modulesKeyForZip.zipModulePath, null);

    } else {
      doc = FileUtilsFileBuffer.getCustomReturnFromFile(key.file, true, null);
    }

    char[] charArray;
    int len;
    if (doc instanceof IDocument) {
      IDocument document = (IDocument) doc;
      charArray = document.get().toCharArray();
      len = charArray.length;

    } else if (doc instanceof FastStringBuffer) {
      FastStringBuffer fastStringBuffer = (FastStringBuffer) doc;
      // In this case, we can actually get the internal array without doing any copies (and just
      // specifying the len).
      charArray = fastStringBuffer.getInternalCharsArray();
      len = fastStringBuffer.length();

    } else if (doc instanceof String) {
      String str = (String) doc;
      charArray = str.toCharArray();
      len = charArray.length;

    } else if (doc instanceof char[]) {
      charArray = (char[]) doc;
      len = charArray.length;

    } else {
      throw new RuntimeException("Don't know how to handle: " + doc + " -- " + doc.getClass());
    }

    SimpleNode node = FastDefinitionsParser.parse(charArray, key.file.getName(), len);
    if (node == null) {
      return null;
    }

    return addAstInfo(node, key, generateDelta);
  }
Beispiel #8
0
 /** Inserts a string at a given position in the buffer. */
 public FastStringBuffer insert(int offset, FastStringBuffer str) {
   int len = str.length();
   int newCount = count + len;
   if (newCount > value.length) {
     int newCapacity = (value.length + 1) * 2;
     if (newCount > newCapacity) {
       newCapacity = newCount;
     }
     char newValue[] = new char[newCapacity];
     System.arraycopy(value, 0, newValue, 0, count);
     value = newValue;
   }
   System.arraycopy(value, offset, value, offset + len, count - offset);
   System.arraycopy(str.value, 0, value, offset, str.count);
   count = newCount;
   return this;
 }
Beispiel #9
0
  public static Map<Integer, String> loadDictFrom(
      FastBufferedReader reader, FastStringBuffer buf, ObjectsPoolMap objectsPoolMap)
      throws IOException {
    int size = StringUtils.parsePositiveInt(reader.readLine());
    HashMap<Integer, String> map = new HashMap<Integer, String>(size + 5);

    FastStringBuffer line;
    int val = 0;
    while (true) {
      line = reader.readLine();
      if (line == null) {
        return map;

      } else if (line.startsWith("-- ")) {
        if (line.startsWith("-- END DICTIONARY")) {
          return map;
        }
        throw new RuntimeException("Unexpected line: " + line);

      } else {
        int length = line.length();
        // line is str=int
        for (int i = 0; i < length; i++) {
          char c = line.charAt(i);
          if (c == '=') {
            val = StringUtils.parsePositiveInt(buf);
            buf.clear();
          } else {
            buf.appendResizeOnExc(c);
          }
        }
        String bufStr = buf.toString();
        String interned = objectsPoolMap.get(bufStr);
        if (interned == null) {
          interned = bufStr;
          objectsPoolMap.put(bufStr, bufStr);
        }
        map.put(val, interned);
        buf.clear();
      }
    }
  }
Beispiel #10
0
  /**
   * Adds spaces after the '#' according to the configured settings. The first char of the buffer
   * passed (which is also the output) should always start with a '#'.
   */
  public static void formatComment(FormatStd std, FastStringBuffer bufWithComment) {
    if (std.spacesInStartComment > 0) {
      Assert.isTrue(bufWithComment.charAt(0) == '#');
      int len = bufWithComment.length();

      char firstCharFound = '\n';
      String bufAsString = bufWithComment.toString();
      // handle cases where the code-formatting should not take place
      if (FileUtils.isPythonShebangLine(bufAsString)) {
        return;
      }

      int spacesFound = 0;
      String remainingStringContent = "";
      for (int j = 1; j < len; j++) { // start at 1 because 0 should always be '#'
        if ((firstCharFound = bufWithComment.charAt(j)) != ' ') {
          remainingStringContent = bufAsString.substring(j).trim();
          break;
        }
        spacesFound += 1;
      }
      if (firstCharFound != '\r'
          && firstCharFound != '\n') { // Only add spaces if it wasn't an empty line.

        // handle cases where the code-formatting should not take place
        for (String s : BLOCK_COMMENT_SKIPS) {
          if (remainingStringContent.endsWith(s) || remainingStringContent.startsWith(s)) {
            return;
          }
        }
        int diff = std.spacesInStartComment - spacesFound;
        if (diff > 0) {
          bufWithComment.insertN(1, ' ', diff);
        }
      }
    }
  }
  protected void save(File persistingLocation) {
    try {
      FileOutputStream stream = new FileOutputStream(persistingLocation);
      OutputStreamWriter writer = new OutputStreamWriter(stream);
      try {
        FastStringBuffer tempBuf = new FastStringBuffer();
        tempBuf.append("-- VERSION_");
        tempBuf.append(AbstractAdditionalTokensInfo.version);
        tempBuf.append('\n');
        writer.write(tempBuf.getInternalCharsArray(), 0, tempBuf.length());
        tempBuf.clear();

        saveTo(writer, tempBuf, persistingLocation);
      } finally {
        try {
          writer.close();
        } finally {
          stream.close();
        }
      }
    } catch (Exception e) {
      Log.log(e);
    }
  }
Beispiel #12
0
  public static PyPublicTreeMap<String, Set<IInfo>> loadTreeFrom(
      final FastBufferedReader reader,
      final Map<Integer, String> dictionary,
      FastStringBuffer buf,
      ObjectsPoolMap objectsPoolMap,
      IPythonNature nature)
      throws IOException {
    PyPublicTreeMap<String, Set<IInfo>> tree = new PyPublicTreeMap<String, Set<IInfo>>();
    final int size = StringUtils.parsePositiveInt(reader.readLine());

    try {

      final Entry[] entries = new Entry[size];
      // each line is something as: cub|CubeColourDialog!13&999@CUBIC!263@cube!202&999@
      // note: the path (2nd int in record) is optional
      for (int iEntry = 0; iEntry < size; iEntry++) {
        buf.clear();
        FastStringBuffer line = reader.readLine();
        if (line == null || line.startsWith("-- ")) {
          throw new RuntimeException("Unexpected line: " + line);
        }
        char[] internalCharsArray = line.getInternalCharsArray();
        int length = line.length();
        String key = null;
        String infoName = null;
        String path = null;

        int i = 0;

        OUT:
        for (; i < length; i++) {
          char c = internalCharsArray[i];
          switch (c) {
            case '|':
              key = ObjectsInternPool.internLocal(objectsPoolMap, buf.toString());
              buf.clear();
              i++;
              break OUT;
            default:
              buf.appendResizeOnExc(c);
          }
        }

        int hashSize = 0;
        OUT2:
        for (; i < length; i++) {
          char c = internalCharsArray[i];
          switch (c) {
            case '|':
              hashSize = StringUtils.parsePositiveInt(buf);
              buf.clear();
              i++;
              break OUT2;
            default:
              buf.appendResizeOnExc(c);
          }
        }
        HashSet<IInfo> set = new HashSet<IInfo>(hashSize);

        for (; i < length; i++) {
          char c = internalCharsArray[i];
          switch (c) {
            case '!':
              infoName = ObjectsInternPool.internLocal(objectsPoolMap, buf.toString());
              buf.clear();
              break;

            case '&':
              path = dictionary.get(StringUtils.parsePositiveInt(buf));
              buf.clear();
              break;

            case '@':
              int dictKey = StringUtils.parsePositiveInt(buf);
              byte type = (byte) dictKey;
              type &=
                  0x07; // leave only the 3 least significant bits there (this is the type -- value
              // from 0 - 8).

              dictKey =
                  (dictKey
                      >> 3); // the entry in the dict doesn't have the least significant bits there.
              buf.clear();
              String moduleDeclared = dictionary.get(dictKey);
              if (moduleDeclared == null) {
                throw new AssertionError("Unable to find key: " + dictKey);
              }
              if (infoName == null) {
                throw new AssertionError("Info name may not be null. Line: " + line);
              }
              switch (type) {
                case IInfo.CLASS_WITH_IMPORT_TYPE:
                  set.add(new ClassInfo(infoName, moduleDeclared, path, false, nature));
                  break;
                case IInfo.METHOD_WITH_IMPORT_TYPE:
                  set.add(new FuncInfo(infoName, moduleDeclared, path, false, nature));
                  break;
                case IInfo.ATTRIBUTE_WITH_IMPORT_TYPE:
                  set.add(new AttrInfo(infoName, moduleDeclared, path, false, nature));
                  break;
                case IInfo.NAME_WITH_IMPORT_TYPE:
                  set.add(new NameInfo(infoName, moduleDeclared, path, false, nature));
                  break;
                case IInfo.MOD_IMPORT_TYPE:
                  set.add(new ModInfo(infoName, false, nature));
                  break;
                default:
                  Log.log("Unexpected type: " + type);
              }
              break;
            default:
              buf.appendResizeOnExc(c);
          }
        }

        entries[iEntry] = new MapEntry(key, set);
      }

      tree.buildFromSorted(
          size,
          new Iterator() {
            private int iNext;

            @Override
            public boolean hasNext() {
              return iNext > size;
            }

            @Override
            public Object next() {
              Object o = entries[iNext];
              iNext++;
              return o;
            }

            @Override
            public void remove() {}
          },
          null,
          null);
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
    return tree;
  }
Beispiel #13
0
  /**
   * @param operation
   * @return
   * @throws IOException
   */
  private FastStringBuffer read(IProgressMonitor monitor) throws IOException {
    synchronized (ioLock) {
      if (finishedForGood) {
        throw new RuntimeException(
            "Shells are already finished for good, so, it is an invalid state to try to read from it.");
      }
      if (inStart) {
        throw new RuntimeException(
            "The shell is still not completely started, so, it is an invalid state to try to read from it.");
      }
      if (!isConnected) {
        throw new RuntimeException(
            "The shell is still not connected, so, it is an invalid state to try to read from it.");
      }
      if (isInRead) {
        throw new RuntimeException(
            "The shell is already in read mode, so, it is an invalid state to try to read from it.");
      }
      if (isInWrite) {
        throw new RuntimeException(
            "The shell is already in write mode, so, it is an invalid state to try to read from it.");
      }

      isInRead = true;

      try {
        FastStringBuffer str = new FastStringBuffer(AbstractShell.BUFFER_SIZE);
        byte[] b = new byte[AbstractShell.BUFFER_SIZE];
        while (true) {

          int len = this.socket.getInputStream().read(b);
          if (len == 0) {
            break;
          }

          String s = new String(b, 0, len);
          str.append(s);

          if (str.indexOf("END@@") != -1) {
            break;
          } else {
            sleepALittle(10);
          }
        }

        str.replaceFirst("@@COMPLETIONS", "");
        // remove END@@
        try {
          if (str.indexOf("END@@") != -1) {
            str.setCount(str.indexOf("END@@"));
            return str;
          } else {
            throw new RuntimeException("Couldn't find END@@ on received string.");
          }
        } catch (RuntimeException e) {
          if (str.length() > 500) {
            str.setCount(499)
                .append("...(continued)..."); // if the string gets too big, it can crash Eclipse...
          }
          Log.log(IStatus.ERROR, ("ERROR WITH STRING:" + str), e);
          return new FastStringBuffer();
        }
      } finally {
        isInRead = false;
      }
    }
  }
Beispiel #14
0
  /**
   * Handles having an operator
   *
   * @param std the coding standard to be used
   * @param cs the contents of the string
   * @param buf the buffer where the contents should be added
   * @param parsingUtils helper to get the contents
   * @param i current index
   * @param c current char
   * @return the new index after handling the operator
   */
  private int handleOperator(
      FormatStd std, char[] cs, FastStringBuffer buf, ParsingUtils parsingUtils, int i, char c) {
    // let's discover if it's an unary operator (~ + -)
    boolean isUnaryWithContents = true;

    boolean isUnary = false;
    boolean changeWhitespacesBefore = true;
    if (c == '~' || c == '+' || c == '-') {
      // could be an unary operator...
      String trimmedLastWord = buf.getLastWord().trim();
      isUnary =
          trimmedLastWord.length() == 0 || PySelection.ALL_KEYWORD_TOKENS.contains(trimmedLastWord);

      if (!isUnary) {
        for (char itChar : buf.reverseIterator()) {
          if (itChar == ' ' || itChar == '\t') {
            continue;
          }

          switch (itChar) {
            case '[':
            case '{':
            case '=':
              changeWhitespacesBefore = false;

            case '(':
            case ':':
              isUnaryWithContents = false;

            case '>':
            case '<':

            case '-':
            case '+':
            case '~':

            case '*':
            case '/':
            case '%':
            case '!':
            case '&':
            case '^':
            case '|':
            case ',':
              isUnary = true;
          }
          break;
        }
      } else {
        isUnaryWithContents = buf.length() > 0;
      }
    }

    if (!isUnary) {
      // We don't want to change whitespaces before in a binary operator that is in a new line.
      for (char ch : buf.reverseIterator()) {
        if (!Character.isWhitespace(ch)) {
          break;
        }
        if (ch == '\r' || ch == '\n') {
          changeWhitespacesBefore = false;
          break;
        }
      }
    }

    if (changeWhitespacesBefore) {
      while (buf.length() > 0 && (buf.lastChar() == ' ' || buf.lastChar() == ' ')) {
        buf.deleteLast();
      }
    }

    boolean surroundWithSpaces = std.operatorsWithSpace;

    if (changeWhitespacesBefore) {
      // add spaces before
      if (isUnaryWithContents && surroundWithSpaces) {
        buf.append(' ');
      }
    }

    char localC = c;
    char prev = '\0';
    boolean backOne = true;
    while (isOperatorPart(localC, prev)) {
      buf.append(localC);
      prev = localC;
      i++;
      if (i == cs.length) {
        break;
      }
      localC = cs[i];
      if (localC == '=') {
        // when we get to an assign, we have found a full stmt (with assign) -- e.g.: a \\=  a += a
        // ==
        buf.append(localC);
        backOne = false;
        break;
      }
    }
    if (backOne) {
      i--;
    }

    // add space after only if it's not unary
    if (!isUnary && surroundWithSpaces) {
      buf.append(' ');
    }

    i = parsingUtils.eatWhitespaces(null, i + 1);
    return i;
  }
Beispiel #15
0
  public void saveToFile(File workspaceMetadataFile) {
    if (workspaceMetadataFile.exists() && !workspaceMetadataFile.isDirectory()) {
      try {
        FileUtils.deleteFile(workspaceMetadataFile);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
    if (!workspaceMetadataFile.exists()) {
      workspaceMetadataFile.mkdirs();
    }

    File modulesKeysFile = new File(workspaceMetadataFile, "modulesKeys");
    File pythonpatHelperFile = new File(workspaceMetadataFile, "pythonpath");
    FastStringBuffer buf;
    HashMap<String, Integer> commonTokens = new HashMap<String, Integer>();

    synchronized (modulesKeysLock) {
      buf = new FastStringBuffer(this.modulesKeys.size() * 50);
      buf.append(MODULES_MANAGER_V2);

      for (Iterator<ModulesKey> iter = this.modulesKeys.keySet().iterator(); iter.hasNext(); ) {
        ModulesKey next = iter.next();
        buf.append(next.name);
        if (next.file != null) {
          buf.append("|");
          if (next instanceof ModulesKeyForZip) {
            ModulesKeyForZip modulesKeyForZip = (ModulesKeyForZip) next;
            if (modulesKeyForZip.zipModulePath != null) {
              String fileStr = next.file.toString();
              Integer t = commonTokens.get(fileStr);
              if (t == null) {
                t = commonTokens.size();
                commonTokens.put(fileStr, t);
              }
              buf.append(t);
              buf.append("|");

              buf.append(modulesKeyForZip.zipModulePath);
              buf.append("|");
              buf.append(modulesKeyForZip.isFile ? '1' : '0');
            }
          } else {
            buf.append(next.file.toString());
          }
        }
        buf.append('\n');
      }
    }
    if (commonTokens.size() > 0) {
      FastStringBuffer header = new FastStringBuffer(buf.length() + (commonTokens.size() * 50));
      header.append(MODULES_MANAGER_V2);
      header.append("--COMMON--\n");
      for (Map.Entry<String, Integer> entries : commonTokens.entrySet()) {
        header.append(entries.getValue());
        header.append('=');
        header.append(entries.getKey());
        header.append('\n');
      }
      header.append("--END-COMMON--\n");
      header.append(buf);
      buf = header;
    }
    FileUtils.writeStrToFile(buf.toString(), modulesKeysFile);

    this.pythonPathHelper.saveToFile(pythonpatHelperFile);
  }
Beispiel #16
0
 public BackwardCharIterator(FastStringBuffer fastStringBuffer) {
   this.fastStringBuffer = fastStringBuffer;
   i = fastStringBuffer.length();
 }
Beispiel #17
0
  /**
   * Formats the contents for when a parenthesis is found (so, go until the closing parens and
   * format it accordingly)
   *
   * @param throwSyntaxError
   * @throws SyntaxErrorException
   */
  private int formatForPar(
      final ParsingUtils parsingUtils,
      final char[] cs,
      final int i,
      final FormatStd std,
      final FastStringBuffer buf,
      final int parensLevel,
      final String delimiter,
      boolean throwSyntaxError)
      throws SyntaxErrorException {
    char c = ' ';
    FastStringBuffer locBuf = new FastStringBuffer();

    int j = i + 1;
    int start = j;
    int end = start;
    while (j < cs.length && (c = cs[j]) != ')') {

      j++;

      if (c == '\'' || c == '"') { // ignore comments or multiline comments...
        j = parsingUtils.eatLiterals(null, j - 1, std.trimMultilineLiterals) + 1;
        end = j;

      } else if (c == '#') {
        j = parsingUtils.eatComments(null, j - 1) + 1;
        end = j;

      } else if (c == '(') { // open another par.
        if (end > start) {
          locBuf.append(cs, start, end - start);
          start = end;
        }
        j =
            formatForPar(
                    parsingUtils,
                    cs,
                    j - 1,
                    std,
                    locBuf,
                    parensLevel + 1,
                    delimiter,
                    throwSyntaxError)
                + 1;
        start = j;

      } else {
        end = j;
      }
    }
    if (end > start) {
      locBuf.append(cs, start, end - start);
      start = end;
    }

    if (c == ')') {
      // Now, when a closing parens is found, let's see the contents of the line where that parens
      // was found
      // and if it's only whitespaces, add all those whitespaces (to handle the following case:
      // a(a,
      //  b
      //   ) <-- we don't want to change this one.
      char c1;
      FastStringBuffer buf1 = new FastStringBuffer();

      if (locBuf.indexOf('\n') != -1 || locBuf.indexOf('\r') != -1) {
        for (int k = locBuf.length();
            k > 0 && (c1 = locBuf.charAt(k - 1)) != '\n' && c1 != '\r';
            k--) {
          buf1.insert(0, c1);
        }
      }

      String formatStr =
          formatStr(trim(locBuf).toString(), std, parensLevel, delimiter, throwSyntaxError);
      FastStringBuffer formatStrBuf = trim(new FastStringBuffer(formatStr, 10));

      String closing = ")";
      if (buf1.length() > 0 && PySelection.containsOnlyWhitespaces(buf1.toString())) {
        formatStrBuf.append(buf1);

      } else if (std.parametersWithSpace) {
        closing = " )";
      }

      if (std.parametersWithSpace) {
        if (formatStrBuf.length() == 0) {
          buf.append("()");

        } else {
          buf.append("( ");
          buf.append(formatStrBuf);
          buf.append(closing);
        }
      } else {
        buf.append('(');
        buf.append(formatStrBuf);
        buf.append(closing);
      }
      return j;
    } else {
      if (throwSyntaxError) {
        throw new SyntaxErrorException("No closing ')' found.");
      }
      // we found no closing parens but we finished looking already, so, let's just add anything
      // without
      // more formatting...
      buf.append('(');
      buf.append(locBuf);
      return j;
    }
  }
Beispiel #18
0
 /**
  * We just want to trim whitespaces, not newlines!
  *
  * @param locBuf the buffer to be trimmed
  * @return the same buffer passed as a parameter
  */
 private FastStringBuffer rtrim(FastStringBuffer locBuf) {
   while (locBuf.length() > 0 && (locBuf.lastChar() == ' ' || locBuf.lastChar() == '\t')) {
     locBuf.deleteLast();
   }
   return locBuf;
 }
Beispiel #19
0
  /**
   * This method formats a string given some standard.
   *
   * @param str the string to be formatted
   * @param std the standard to be used
   * @param parensLevel the level of the parenthesis available.
   * @return a new (formatted) string
   * @throws SyntaxErrorException
   */
  private String formatStr(
      String str, FormatStd std, int parensLevel, String delimiter, boolean throwSyntaxError)
      throws SyntaxErrorException {
    char[] cs = str.toCharArray();
    FastStringBuffer buf = new FastStringBuffer();

    // Temporary buffer for some operations. Must always be cleared before it's used.
    FastStringBuffer tempBuf = new FastStringBuffer();

    ParsingUtils parsingUtils = ParsingUtils.create(cs, throwSyntaxError);
    char lastChar = '\0';
    for (int i = 0; i < cs.length; i++) {
      char c = cs[i];

      switch (c) {
        case '\'':
        case '"':
          // ignore literals and multi-line literals, including comments...
          i = parsingUtils.eatLiterals(buf, i, std.trimMultilineLiterals);
          break;

        case '#':
          i = handleComment(std, cs, buf, tempBuf, parsingUtils, i);
          break;

        case ',':
          i = formatForComma(std, cs, buf, i, tempBuf);
          break;

        case '(':
          i =
              formatForPar(
                  parsingUtils, cs, i, std, buf, parensLevel + 1, delimiter, throwSyntaxError);
          break;

          // Things to treat:
          // +, -, *, /, %
          // ** // << >>
          // <, >, !=, <>, <=, >=, //=, *=, /=,
          // & ^ ~ |
        case '*':
          // for *, we also need to treat when it's used in varargs, kwargs and list expansion
          boolean isOperator = false;
          for (int j = buf.length() - 1; j >= 0; j--) {
            char localC = buf.charAt(j);
            if (Character.isWhitespace(localC)) {
              continue;
            }
            if (localC == '(' || localC == ',') {
              // it's not an operator, but vararg. kwarg or list expansion
            }
            if (Character.isJavaIdentifierPart(localC)) {
              // ok, there's a chance that it can be an operator, but we still have to check
              // the chance that it's a wild import
              tempBuf.clear();
              while (Character.isJavaIdentifierPart(localC)) {
                tempBuf.append(localC);
                j--;
                if (j < 0) {
                  break; // break while
                }
                localC = buf.charAt(j);
              }
              String reversed = tempBuf.reverse().toString();
              if (!reversed.equals("import") && !reversed.equals("lambda")) {
                isOperator = true;
              }
            }
            if (localC == '\'' || localC == ')' || localC == ']') {
              isOperator = true;
            }

            // If it got here (i.e.: not whitespace), get out of the for loop.
            break;
          }
          if (!isOperator) {
            buf.append('*');
            break; // break switch
          }
          // Otherwise, FALLTHROUGH

        case '+':
        case '-':
          if (c == '-' || c == '+') { // could also be *

            // handle exponentials correctly: e.g.: 1e-6 cannot have a space
            tempBuf.clear();
            boolean started = false;

            for (int j = buf.length() - 1; ; j--) {
              if (j < 0) {
                break;
              }
              char localC = buf.charAt(j);
              if (localC == ' ' || localC == '\t') {
                if (!started) {
                  continue;
                } else {
                  break;
                }
              }
              started = true;
              if (Character.isJavaIdentifierPart(localC) || localC == '.') {
                tempBuf.append(localC);
              } else {
                break; // break for
              }
            }
            boolean isExponential = true;
            String partialNumber = tempBuf.reverse().toString();
            int partialLen = partialNumber.length();
            if (partialLen < 2 || !Character.isDigit(partialNumber.charAt(0))) {
              // at least 2 chars: the number and the 'e'
              isExponential = false;
            } else {
              // first char checked... now, if the last is an 'e', we must leave it together no
              // matter what
              if (partialNumber.charAt(partialLen - 1) != 'e'
                  && partialNumber.charAt(partialLen - 1) != 'E') {
                isExponential = false;
              }
            }
            if (isExponential) {
              buf.rightTrim();
              buf.append(c);
              // skip the next whitespaces from the buffer
              int initial = i;
              do {
                i++;
              } while (i < cs.length && (c = cs[i]) == ' ' || c == '\t');
              if (i > initial) {
                i--; // backup 1 because we walked 1 too much.
              }
              break; // break switch
            }
            // Otherwise, FALLTHROUGH
          }

        case '/':
        case '%':
        case '<':
        case '>':
        case '!':
        case '&':
        case '^':
        case '~':
        case '|':
          i = handleOperator(std, cs, buf, parsingUtils, i, c);
          c = cs[i];
          break;

          // check for = and == (other cases that have an = as the operator should already be
          // treated)
        case '=':
          if (i < cs.length - 1 && cs[i + 1] == '=') {
            // if == handle as if a regular operator
            i = handleOperator(std, cs, buf, parsingUtils, i, c);
            c = cs[i];
            break;
          }

          while (buf.length() > 0 && buf.lastChar() == ' ') {
            buf.deleteLast();
          }

          boolean surroundWithSpaces = std.operatorsWithSpace;
          if (parensLevel > 0) {
            surroundWithSpaces = std.assignWithSpaceInsideParens;
          }

          // add space before
          if (surroundWithSpaces) {
            buf.append(' ');
          }

          // add the operator and the '='
          buf.append('=');

          // add space after
          if (surroundWithSpaces) {
            buf.append(' ');
          }

          i = parsingUtils.eatWhitespaces(null, i + 1);
          break;

        default:
          if (c == '\r' || c == '\n') {
            if (lastChar == ',' && std.spaceAfterComma && buf.lastChar() == ' ') {
              buf.deleteLast();
            }
            if (std.trimLines) {
              buf.rightTrim();
            }
          }
          buf.append(c);
      }
      lastChar = c;
    }
    if (parensLevel == 0 && std.trimLines) {
      buf.rightTrim();
    }
    return buf.toString();
  }