[Pydev-cvs] org.python.pydev.core/src/org/python/pydev/core/docutils ImportNotRecognizedException.j
Brought to you by:
fabioz
Update of /cvsroot/pydev/org.python.pydev.core/src/org/python/pydev/core/docutils In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv28562/src/org/python/pydev/core/docutils Modified Files: ParsingUtils.java ImportsSelection.java StringUtils.java ImportHandle.java Added Files: ImportNotRecognizedException.java Log Message: Created structure to help dealing with imports in files, even if the file does not have a correct AST Refactor: Moved methods from FullRepIterable to StringUtils --- NEW FILE: ImportNotRecognizedException.java --- package org.python.pydev.core.docutils; public class ImportNotRecognizedException extends Exception { public ImportNotRecognizedException(String msg) { super(msg); } } Index: ImportHandle.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.core/src/org/python/pydev/core/docutils/ImportHandle.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ImportHandle.java 17 May 2008 14:26:57 -0000 1.1 --- ImportHandle.java 18 May 2008 20:02:26 -0000 1.2 *************** *** 1,4 **** --- 1,9 ---- package org.python.pydev.core.docutils; + import java.util.ArrayList; + import java.util.List; + import java.util.regex.Matcher; + import java.util.regex.Pattern; + import org.eclipse.jface.text.IDocument; *************** *** 9,14 **** --- 14,192 ---- */ public class ImportHandle { + /** + * Class representing some import information + * + * @author Fabio + */ + public static class ImportHandleInfo{ + + //spaces* 'from' space+ module space+ import (mod as y) + private static final Pattern FromImportPattern = Pattern.compile("(from\\s+)(\\.*\\w+)(\\s+import\\s+)(\\w+|\\s|,|#|\\(|\\))*(\\z)"); + private static final Pattern ImportPattern = Pattern.compile("(import\\s+)(\\w+|\\s|,|#|\\(|\\))*(\\z)"); + + /** + * Holds the 'KKK' if the import is from KKK import YYY + * If it's not a From Import, it should be null. + */ + private String fromStr; + + /** + * This is the alias that's been imported. E.g.: in from KKK import YYY, ZZZ, this is a list + * with YYY and ZZZ + */ + private List<String> importedStr; + + /** + * Comments (one for each imported string) E.g.: in from KKK import (YYY, #comment\n ZZZ), this is a list + * with #comment and an empty string. + */ + private List<String> importedStrComments; + + /** + * Constructor. + * + * Creates the information to be returned later + * + * @param importFound + * @throws ImportNotRecognizedException + */ + public ImportHandleInfo(String importFound) throws ImportNotRecognizedException { + importFound=importFound.trim(); + char firstChar = importFound.charAt(0); + + + if (firstChar == 'f') { + //from import + Matcher matcher = FromImportPattern.matcher(importFound); + if(matcher.matches()){ + this.fromStr = matcher.group(2); + + //we have to do that because the last group will only have the last match in the string + String importedStr = importFound.substring(matcher.end(3), + matcher.end(4)).trim(); + + buildImportedList(importedStr); + + }else{ + throw new ImportNotRecognizedException("Could not recognize import: "+importFound); + } + + + }else if(firstChar == 'i'){ + //regular import + Matcher matcher = ImportPattern.matcher(importFound); + if(matcher.matches()){ + //we have to do that because the last group will only have the last match in the string + String importedStr = importFound.substring(matcher.end(1), + matcher.end(2)).trim(); + + buildImportedList(importedStr); + + }else{ + throw new ImportNotRecognizedException("Could not recognize import: "+importFound); + } + + }else{ + throw new ImportNotRecognizedException("Could not recognize import: "+importFound); + } + } + + /** + * Fills the importedStrComments and importedStr given the importedStr passed + * + * @param importedStr string with the tokens imported in an import + */ + private void buildImportedList(String importedStr) { + ArrayList<String> lst = new ArrayList<String>(); + ArrayList<String> importComments = new ArrayList<String>(); + + StringBuffer alias = new StringBuffer(); + for(int i=0;i<importedStr.length();i++){ + char c = importedStr.charAt(i); + if(c == '#'){ + StringBuffer comments = new StringBuffer(); + i = ParsingUtils.eatComments(importedStr, comments, i); + addImportAlias(lst, importComments, alias, comments.toString()); + alias = new StringBuffer(); + + }else if(c == ',' || c == '\r' || c == '\n'){ + addImportAlias(lst, importComments, alias, ""); + alias = new StringBuffer(); + + }else if(c == '(' || c == ')'){ + //do nothing + + + }else if(c == ' ' || c == '\t'){ + String curr = alias.toString(); + if(curr.endsWith(" as") | curr.endsWith("\tas")){ + alias = new StringBuffer(); + } + alias.append(c); + + }else{ + alias.append(c); + } + } + + if(alias.length() > 0){ + addImportAlias(lst, importComments, alias, ""); + + } + + this.importedStrComments = importComments; + this.importedStr = lst; + } + + /** + * Adds an import and its related comment to the given lists (if there's actually something available to be + * added) + * + * @param lst list where the alias will be added + * @param importComments list where the comment will be added + * @param alias the name of the import to be added + * @param importComment the comment related to the import + */ + private void addImportAlias(ArrayList<String> lst, ArrayList<String> importComments, StringBuffer alias, + String importComment) { + + String aliasStr = alias.toString().trim(); + importComment = importComment.trim(); + + if(aliasStr.length() > 0){ + lst.add(aliasStr); + importComments.add(importComment); + }else if(importComment.length() > 0 && importComments.size() > 0){ + importComments.set(importComments.size()-1, importComment); + } + } + + /** + * @return the from module in the import + */ + public String getFromImportStr() { + return this.fromStr; + } + + /** + * @return the tokens imported from the module (or the alias if it's specified) + */ + public List<String> getImportedStr() { + return this.importedStr; + } + + /** + * @return a list with a string for each imported token correspondent to a comment related to that import. + */ + public List<String> getCommentsForImports() { + return this.importedStrComments; + } + + } + + + /** * Document where the import was found */ *************** *** 29,32 **** --- 207,215 ---- */ public int endFoundLine; + + /** + * Import informatiot for the import found and handled in this class (only created on request) + */ + private List<ImportHandleInfo> importInfo; /** *************** *** 42,44 **** --- 225,299 ---- } + /** + * @param realImportRep the import to match. Note that only a single import statement may be passed as a parameter. + * + * @return true if the passed import matches the import in this handle (note: as this class can actually wrap more + * than 1 import, it'll return true if any of the internal imports match the passed import) + * @throws ImportNotRecognizedException if the passed import could not be recognized + */ + public boolean contains(String realImportRep) throws ImportNotRecognizedException { + ImportHandleInfo otherImportInfo = new ImportHandleInfo(realImportRep); + List<ImportHandleInfo> importHandleInfo = this.getImportInfo(); + + for(ImportHandleInfo info : importHandleInfo) { + if(info.fromStr != otherImportInfo.fromStr){ + if(otherImportInfo.fromStr == null || info.fromStr == null){ + continue; //keep on to the next possible match + } + if(!otherImportInfo.fromStr.equals(info.fromStr)){ + continue; //keep on to the next possible match + } + } + + if(otherImportInfo.importedStr.size() != 1){ + continue; + } + + if(info.importedStr.contains(otherImportInfo.importedStr.get(0))){ + return true; + } + + } + + + return false; + } + + + /** + * @return a list with the import information generated from the import this handle is wrapping. + */ + public List<ImportHandleInfo> getImportInfo() { + if(this.importInfo == null){ + this.importInfo = new ArrayList<ImportHandleInfo>(); + + StringBuffer imp = new StringBuffer(); + for(int i=0;i<importFound.length();i++){ + char c = importFound.charAt(i); + + if(c == '#'){ + i = ParsingUtils.eatComments(importFound, imp, i); + + }else if(c == ';'){ + try { + this.importInfo.add(new ImportHandleInfo(imp.toString())); + } catch (ImportNotRecognizedException e) { + //that's ok, not a valid import (at least, we couldn't parse it) + } + imp = new StringBuffer(); + + }else{ + imp.append(c); + } + + } + try { + this.importInfo.add(new ImportHandleInfo(imp.toString())); + } catch (ImportNotRecognizedException e) { + //that's ok, not a valid import (at least, we couldn't parse it) + } + } + return this.importInfo; + } + } Index: ParsingUtils.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.core/src/org/python/pydev/core/docutils/ParsingUtils.java,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** ParsingUtils.java 5 Mar 2008 12:44:45 -0000 1.18 --- ParsingUtils.java 18 May 2008 20:02:26 -0000 1.19 *************** *** 10,14 **** import org.eclipse.jface.text.IDocumentExtension3; import org.eclipse.jface.text.IDocumentPartitionerExtension2; - import org.python.pydev.core.FullRepIterable; import org.python.pydev.core.IPythonPartitions; --- 10,13 ---- *************** *** 534,538 **** } ! String[] strings = FullRepIterable.split(code, toSplit); return strings[strings.length-1]; } --- 533,537 ---- } ! String[] strings = StringUtils.split(code, toSplit); return strings[strings.length-1]; } Index: StringUtils.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.core/src/org/python/pydev/core/docutils/StringUtils.java,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** StringUtils.java 6 Jan 2008 13:32:16 -0000 1.13 --- StringUtils.java 18 May 2008 20:02:26 -0000 1.14 *************** *** 15,18 **** --- 15,25 ---- public class StringUtils { + /** + * Formats a string, replacing %s with the arguments passed. + * + * @param str string to be formatted + * @param args arguments passed + * @return a string with the %s replaced by the arguments passed + */ public static String format(String str, Object... args) { StringBuffer buffer = new StringBuffer(); *************** *** 39,42 **** --- 46,55 ---- } + /** + * Counts the number of %s in the string + * + * @param str the string to be analyzide + * @return the number of %s in the string + */ public static int countPercS(String str) { int j = 0; *************** *** 55,58 **** --- 68,74 ---- } + /** + * Removes whitespaces at the beggining of the string. + */ public static String rightTrim(String input) { int len = input.length(); *************** *** 67,70 **** --- 83,89 ---- } + /** + * Removes whitespaces at the end of the string. + */ public static String leftTrim(String input) { int len = input.length(); *************** *** 109,112 **** --- 128,134 ---- } + /** + * Removes the occurrences of the passed char in the beggining of the string. + */ public static String rightTrim(String input, char charToTrim) { int len = input.length(); *************** *** 121,124 **** --- 143,149 ---- } + /** + * Removes the occurrences of the passed char in the end of the string. + */ public static String leftTrim(String input, char charToTrim) { int len = input.length(); *************** *** 160,163 **** --- 185,194 ---- } + /** + * Splits the given string in a list where each element is a line. + * + * @param string string to be splitted. + * @return list of strings where each string is a line. + */ public static List<String> splitInLines(String string) { ArrayList<String> ret = new ArrayList<String>(); *************** *** 273,275 **** --- 304,349 ---- } + /** + * Splits some string given some char + */ + public static String[] split(String string, char toSplit) { + ArrayList<String> ret = new ArrayList<String>(); + int len = string.length(); + + int last = 0; + + char c = 0; + + for (int i = 0; i < len; i++) { + c = string.charAt(i); + if(c == toSplit){ + if(last != i){ + ret.add(string.substring(last, i)); + } + while(c == toSplit && i < len-1){ + i++; + c = string.charAt(i); + } + last = i; + } + } + if(c != toSplit){ + if(last == 0 && len > 0){ + ret.add(string); //it is equal to the original (no dots) + + }else if(last < len){ + ret.add(string.substring(last, len)); + + } + } + return ret.toArray(new String[ret.size()]); + } + + /** + * Splits the string as would string.split("\\."), but without yielding empty strings + */ + public static String[] dotSplit(String string) { + return split(string, '.'); + } + } Index: ImportsSelection.java =================================================================== RCS file: /cvsroot/pydev/org.python.pydev.core/src/org/python/pydev/core/docutils/ImportsSelection.java,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** ImportsSelection.java 25 Mar 2007 18:36:15 -0000 1.1 --- ImportsSelection.java 18 May 2008 20:02:26 -0000 1.2 *************** *** 25,30 **** // check if we have a from or an import. if (fromIndex != -1 || importIndex != -1) { ! trimmedLine = trimmedLine.replaceAll("#.*", ""); // remove ! // comments String[] strings = trimmedLine.split(" "); --- 25,29 ---- // check if we have a from or an import. if (fromIndex != -1 || importIndex != -1) { ! trimmedLine = trimmedLine.replaceAll("#.*", ""); // remove comments String[] strings = trimmedLine.split(" "); |