Search in sources :

Example 16 with FastStringBuffer

use of org.python.pydev.shared_core.string.FastStringBuffer in project Pydev by fabioz.

the class RefactoringRenameTestBase method asStr.

@SuppressWarnings("unchecked")
protected String asStr(Map<Tuple<String, File>, HashSet<ASTEntry>> referencesForModuleRename) throws Exception {
    Set<Entry<Tuple<String, File>, HashSet<ASTEntry>>> entrySet = referencesForModuleRename.entrySet();
    FastStringBuffer buf = new FastStringBuffer();
    ArrayList<Entry<Tuple<String, File>, HashSet<ASTEntry>>> lst = new ArrayList<>(entrySet);
    Comparator<Entry<Tuple<String, File>, HashSet<ASTEntry>>> c = new Comparator<Entry<Tuple<String, File>, HashSet<ASTEntry>>>() {

        @Override
        public int compare(Entry<Tuple<String, File>, HashSet<ASTEntry>> o1, Entry<Tuple<String, File>, HashSet<ASTEntry>> o2) {
            return o1.getKey().o1.compareTo(o2.getKey().o1);
        }
    };
    Collections.sort(lst, c);
    for (Entry<Tuple<String, File>, HashSet<ASTEntry>> entry : lst) {
        HashSet<ASTEntry> value = entry.getValue();
        if (value.size() > 0) {
            ArrayList<ASTEntry> lst2 = new ArrayList<>(value);
            Comparator<ASTEntry> c2 = new Comparator<ASTEntry>() {

                @Override
                public int compare(ASTEntry o1, ASTEntry o2) {
                    return o1.toString().compareTo(o2.toString());
                }
            };
            Collections.sort(lst2, c2);
            File f = entry.getKey().o2;
            String fileContents = FileUtils.getFileContents(f);
            Document initialDoc = new Document(fileContents);
            buf.append(entry.getKey().o1).append("\n");
            for (ASTEntry e : lst2) {
                buf.append("  ");
                buf.append(e.toString()).append("\n");
                List<TextEdit> edits = (List<TextEdit>) e.getAdditionalInfo(AstEntryScopeAnalysisConstants.AST_ENTRY_REPLACE_EDIT, null);
                if (edits == null) {
                    if (!(e instanceof ASTEntryWithSourceModule)) {
                        throw new AssertionError("Only ASTEntryWithSourceModule can have null edits. Found: " + e);
                    }
                } else {
                    Document changedDoc = new Document(fileContents);
                    for (TextEdit textEdit : edits) {
                        textEdit.apply(changedDoc);
                    }
                    List<String> changedLines = getChangedLines(initialDoc, changedDoc);
                    for (String i : changedLines) {
                        buf.append("    ");
                        buf.append(StringUtils.rightTrim(i)).append("\n");
                    }
                }
            }
            buf.append("\n");
        }
    }
    return buf.toString();
}
Also used : FastStringBuffer(org.python.pydev.shared_core.string.FastStringBuffer) ArrayList(java.util.ArrayList) Document(org.eclipse.jface.text.Document) Comparator(java.util.Comparator) Entry(java.util.Map.Entry) ASTEntry(org.python.pydev.parser.visitors.scope.ASTEntry) TextEdit(org.eclipse.text.edits.TextEdit) ASTEntry(org.python.pydev.parser.visitors.scope.ASTEntry) ASTEntryWithSourceModule(org.python.pydev.ast.codecompletion.revisited.modules.ASTEntryWithSourceModule) List(java.util.List) ArrayList(java.util.ArrayList) IFile(org.eclipse.core.resources.IFile) File(java.io.File) Tuple(org.python.pydev.shared_core.structure.Tuple) HashSet(java.util.HashSet)

Example 17 with FastStringBuffer

use of org.python.pydev.shared_core.string.FastStringBuffer in project Pydev by fabioz.

the class ShellConvert method convertStringToCompletions.

/**
 * @throws IOException
 */
static /*default*/
Tuple<String, List<String[]>> convertStringToCompletions(FastStringBuffer read) throws IOException {
    if (read == null) {
        return getInvalidCompletion();
    }
    ArrayList<String[]> list = new ArrayList<String[]>();
    FastStringBuffer string = read.replaceAll("(", "").replaceAll(")", "");
    StringTokenizer tokenizer = new StringTokenizer(string.toString(), ",");
    string = null;
    ObjectsPoolMap map = new ObjectsPoolMap();
    // the first token is always the file for the module (no matter what)
    String file = "";
    if (tokenizer.hasMoreTokens()) {
        file = URLDecoder.decode(tokenizer.nextToken(), ENCODING_UTF_8);
        while (tokenizer.hasMoreTokens()) {
            String token = ObjectsInternPool.internLocal(map, URLDecoder.decode(tokenizer.nextToken(), ENCODING_UTF_8));
            if (!tokenizer.hasMoreTokens()) {
                return new Tuple<String, List<String[]>>(file, list);
            }
            String description = ObjectsInternPool.internLocal(map, URLDecoder.decode(tokenizer.nextToken(), ENCODING_UTF_8));
            String args = "";
            if (tokenizer.hasMoreTokens()) {
                args = ObjectsInternPool.internLocal(map, URLDecoder.decode(tokenizer.nextToken(), ENCODING_UTF_8));
            }
            String type = TYPE_UNKNOWN_STR;
            if (tokenizer.hasMoreTokens()) {
                type = ObjectsInternPool.internLocal(map, URLDecoder.decode(tokenizer.nextToken(), ENCODING_UTF_8));
            }
            if (!token.equals("ERROR:")) {
                list.add(new String[] { token, description, args, type });
            } else {
                if (DebugSettings.DEBUG_CODE_COMPLETION) {
                    org.python.pydev.shared_core.log.ToLogFile.addLogLevel();
                    try {
                        org.python.pydev.shared_core.log.ToLogFile.toLogFile("Code completion shell error:", AbstractShell.class);
                        org.python.pydev.shared_core.log.ToLogFile.toLogFile(token, AbstractShell.class);
                        org.python.pydev.shared_core.log.ToLogFile.toLogFile(description, AbstractShell.class);
                        org.python.pydev.shared_core.log.ToLogFile.toLogFile(args, AbstractShell.class);
                        org.python.pydev.shared_core.log.ToLogFile.toLogFile(type, AbstractShell.class);
                    } finally {
                        org.python.pydev.shared_core.log.ToLogFile.remLogLevel();
                    }
                }
            }
        }
    }
    return new Tuple<String, List<String[]>>(file, list);
}
Also used : ObjectsPoolMap(org.python.pydev.core.ObjectsInternPool.ObjectsPoolMap) StringTokenizer(java.util.StringTokenizer) FastStringBuffer(org.python.pydev.shared_core.string.FastStringBuffer) ArrayList(java.util.ArrayList) Tuple(org.python.pydev.shared_core.structure.Tuple)

Example 18 with FastStringBuffer

use of org.python.pydev.shared_core.string.FastStringBuffer in project Pydev by fabioz.

the class PyFormatter method formatStr.

/**
 * 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
 */
public static FastStringBuffer formatStr(String doc, FormatStd std, int parensLevel, String delimiter, boolean throwSyntaxError) throws SyntaxErrorException {
    final char[] cs = doc.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';
    final int length = cs.length;
    for (int i = 0; i < 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;
            // & ^ ~ |
            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 while
                                break;
                            }
                            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 switch
                    break;
                }
            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 for
                            break;
                        }
                    }
                    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.rightTrimWhitespacesAndTabs();
                        buf.append(c);
                        // skip the next whitespaces from the buffer
                        int initial = i;
                        do {
                            i++;
                        } while (i < length && (c = cs[i]) == ' ' || c == '\t');
                        if (i > initial) {
                            // backup 1 because we walked 1 too much.
                            i--;
                        }
                        // break switch
                        break;
                    }
                // Otherwise, FALLTHROUGH
                }
            case '/':
            case '%':
            case '<':
            case '>':
            case '!':
            case '&':
            case '^':
            case '~':
            case '|':
            case ':':
                i = handleOperator(std, cs, buf, parsingUtils, i, c);
                c = cs[i];
                break;
            case '@':
                // @ can mean either a decorator or matrix multiplication,
                // If decorator, do nothing, for matrix multiplication, '@' is an operator which
                // may or may not be followed by an '='
                String append = "@";
                if (i < length - 1 && cs[i + 1] == '=') {
                    // @= found
                    i++;
                    append = "@=";
                } else if (buf.getLastWord().trim().isEmpty()) {
                    // decorator
                    buf.append('@');
                    break;
                }
                while (buf.length() > 0 && buf.lastChar() == ' ') {
                    buf.deleteLast();
                }
                if (std.operatorsWithSpace) {
                    buf.append(' ');
                }
                buf.append(append);
                // add space after
                if (std.operatorsWithSpace) {
                    buf.append(' ');
                }
                i = parsingUtils.eatWhitespaces(null, i + 1);
                break;
            // check for = and == (other cases that have an = as the operator should already be treated)
            case '=':
                if (i < 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;
            case '\r':
            case '\n':
                if (lastChar == ',' && std.spaceAfterComma && buf.lastChar() == ' ') {
                    buf.deleteLast();
                }
                if (std.trimLines) {
                    buf.rightTrimWhitespacesAndTabs();
                }
                buf.append(c);
                break;
            default:
                buf.append(c);
        }
        lastChar = c;
    }
    if (parensLevel == 0 && std.trimLines) {
        buf.rightTrimWhitespacesAndTabs();
    }
    return buf;
}
Also used : FastStringBuffer(org.python.pydev.shared_core.string.FastStringBuffer) ParsingUtils(org.python.pydev.core.docutils.ParsingUtils)

Example 19 with FastStringBuffer

use of org.python.pydev.shared_core.string.FastStringBuffer in project Pydev by fabioz.

the class PyFormatter method formatStrAutopep8OrPyDev.

/**
 * This method formats a string given some standard.
 *
 * @param str the string to be formatted
 * @param std the standard to be used
 * @return a new (formatted) string
 * @throws SyntaxErrorException
 */
/*default*/
public static String formatStrAutopep8OrPyDev(IPythonNature nature, IDocument doc, FormatStd std, String delimiter, boolean throwSyntaxError, boolean allowChangingBlankLines, File workingDir) throws SyntaxErrorException {
    switch(std.formatterStyle) {
        case AUTOPEP8:
            String parameters = std.autopep8Parameters;
            String formatted = Pep8Runner.runWithPep8BaseScript(doc, parameters, "autopep8.py");
            if (formatted == null) {
                formatted = doc.get();
            }
            formatted = StringUtils.replaceNewLines(formatted, delimiter);
            return formatted;
        case BLACK:
            formatted = BlackRunner.formatWithBlack(nature, doc, std, workingDir);
            if (formatted == null) {
                formatted = doc.get();
            }
            formatted = StringUtils.replaceNewLines(formatted, delimiter);
            return formatted;
        default:
            FastStringBuffer buf = formatStr(doc.get(), std, 0, delimiter, throwSyntaxError);
            if (allowChangingBlankLines && std.manageBlankLines) {
                List<LineOffsetAndInfo> computed = PyFormatStdManageBlankLines.computeBlankLinesAmongMethodsAndClasses(std, buf, delimiter);
                return PyFormatStdManageBlankLines.fixBlankLinesAmongMethodsAndClasses(computed, std, doc, buf, delimiter).toString();
            } else {
                return buf.toString();
            }
    }
}
Also used : FastStringBuffer(org.python.pydev.shared_core.string.FastStringBuffer) LineOffsetAndInfo(org.python.pydev.core.formatter.PyFormatStdManageBlankLines.LineOffsetAndInfo)

Example 20 with FastStringBuffer

use of org.python.pydev.shared_core.string.FastStringBuffer in project Pydev by fabioz.

the class PyFormatter method formatForPar.

/**
 * Formats the contents for when a parenthesis is found (so, go until the closing parens and format it accordingly)
 * @param throwSyntaxError
 * @throws SyntaxErrorException
 */
private static 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);
            }
        }
        FastStringBuffer formatStr = formatStr(trim(locBuf).toString(), std, parensLevel, delimiter, throwSyntaxError);
        FastStringBuffer formatStrBuf = trim(formatStr);
        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;
    }
}
Also used : FastStringBuffer(org.python.pydev.shared_core.string.FastStringBuffer) SyntaxErrorException(org.python.pydev.core.docutils.SyntaxErrorException)

Aggregations

FastStringBuffer (org.python.pydev.shared_core.string.FastStringBuffer)300 ArrayList (java.util.ArrayList)32 Tuple (org.python.pydev.shared_core.structure.Tuple)26 File (java.io.File)25 IOException (java.io.IOException)20 CoreException (org.eclipse.core.runtime.CoreException)19 MisconfigurationException (org.python.pydev.core.MisconfigurationException)18 IDocument (org.eclipse.jface.text.IDocument)16 SimpleNode (org.python.pydev.parser.jython.SimpleNode)15 Document (org.eclipse.jface.text.Document)14 HashSet (java.util.HashSet)13 IFile (org.eclipse.core.resources.IFile)13 BadLocationException (org.eclipse.jface.text.BadLocationException)12 HashMap (java.util.HashMap)11 List (java.util.List)10 IRegion (org.eclipse.jface.text.IRegion)10 ModulesKey (org.python.pydev.core.ModulesKey)10 ParseException (org.python.pydev.parser.jython.ParseException)10 Entry (java.util.Map.Entry)9 IPythonNature (org.python.pydev.core.IPythonNature)9