Merge branch 'master' of git.labs.intellij.net:idea/ultimate

This commit is contained in:
Ekaterina Tuzova
2011-02-18 12:43:44 +03:00
11 changed files with 166 additions and 102 deletions
-2
View File
@@ -281,11 +281,9 @@ def build_searchable_options() {
arg(line: "traverseUI ${dest_dir}/searchableOptions.xml")
classpath() {
pathelement(location: "$ch/lib/junit.jar")
project["python-ide"].runtimeClasspath().each {
pathelement(location: it)
}
pathelement(location: project.builder.moduleOutput(project["testFramework"])) // contains headless implementation classes
}
}
}
+46 -14
View File
@@ -26,7 +26,7 @@ but seemingly no one uses them in C extensions yet anyway.
from datetime import datetime
OUR_OWN_DATETIME = datetime(2011, 02, 13, 1, 55, 0) # datetime.now() of edit time
OUR_OWN_DATETIME = datetime(2011, 2, 17, 15, 30, 0) # datetime.now() of edit time
# we could use script's ctime, but the actual running copy may have it all wrong.
#
# Note: DON'T FORGET TO UPDATE!
@@ -1432,18 +1432,19 @@ class ModuleRedeclarator(object):
@param indent indentation level
@param p_class the class that contains this function as a method
@param p_modname module name
@param seen {func: name} map of functions already seen in the same namespace
@param seen {id(func): name} map of functions already seen in the same namespace;
id() because *some* functions are unhashable (eg _elementtree.Comment in py2.7)
"""
action("redoing func %r of class %r", p_name, p_class)
if seen is not None:
other_func = seen.get(p_func, None)
other_func = seen.get(id(p_func), None)
if other_func and getattr(other_func, "__doc__", None) is getattr(p_func, "__doc__", None):
# _bisect.bisect == _bisect.bisect_right in py31, but docs differ
out(indent, p_name, " = ", seen[p_func])
out(indent, p_name, " = ", seen[id(p_func)])
out(indent, "")
return
else:
seen[p_func] = p_name
seen[id(p_func)] = p_name
# real work
classname = p_class and p_class.__name__ or None
if p_class and hasattr(p_class, '__mro__'):
@@ -1691,6 +1692,23 @@ class ModuleRedeclarator(object):
out(0, "# from file " + self.module.__file__)
self.outDocAttr(out, self.module, 0)
def redoImports(self):
module_type = type(sys)
for item_name in self.module.__dict__.keys():
try:
item = self.module.__dict__[item_name]
except:
continue
if isinstance(item, module_type):
self.imported_modules[item_name] = item
self.addImportHeaderIfNeeded()
ref_notice = getattr(item, "__file__", str(item))
if hasattr(item, "__name__"):
self.imports_buf.out(0, "import ", item.__name__, " as ", item_name, " # ", ref_notice)
else:
self.imports_buf.out(0, item_name, " = None # ??? name unknown; ", ref_notice)
def addImportHeaderIfNeeded(self):
if self.imports_buf.isEmpty():
self.imports_buf.out(0, "")
@@ -1702,12 +1720,18 @@ class ModuleRedeclarator(object):
Intended for built-in modules and thus does not handle import statements.
@param p_name name of module
"""
action("redong module %r", p_name)
action("redoing module %r %r", p_name, str(self.module))
self.redoSimpleHeader(p_name)
# find whatever other self.imported_modules the module knows; effectively these are imports
try:
self.redoImports()
except:
pass
module_type = type(sys)
for item_name, item in self.module.__dict__.items():
if isinstance(item, module_type):
if type(item) is module_type: # not isinstance, py2.7 + PyQt4.QtCore on windows have a bug here
self.imported_modules[item_name] = item
self.addImportHeaderIfNeeded()
ref_notice = getattr(item, "__file__", str(item))
@@ -1898,7 +1922,7 @@ class ModuleRedeclarator(object):
if names:
self._defined[mod_name] = True
right_pos = 0 # tracks width of list to fold it at right margin
import_heading = "from % s import " % mod_name
import_heading = "from % s import (" % mod_name
right_pos += len(import_heading)
names_pack = [import_heading]
indent_level = 0
@@ -1915,10 +1939,15 @@ class ModuleRedeclarator(object):
names_pack.append(n)
names_pack.append(", ")
right_pos += (len_n + 2)
if names_pack: # last line
self.imports_buf.out(indent_level, *names_pack[:-1]) # cut last comma
# last line is...
if indent_level == 0: # one line
names_pack[0] = names_pack[0][:-1] # cut off lpar
names_pack[-1] = "" # cut last comma
else: # last line of multiline
names_pack[-1] = ")" # last comma -> rpar
self.imports_buf.out(indent_level, *names_pack)
self.imports_buf.out(0, "") # empty line after group
self.imports_buf.out(0, "") # empty line after group
def hasRegularPythonExt(name):
@@ -1959,7 +1988,7 @@ def redoModule(name, fname, imported_module_names):
# sys.modules
mod = sys.modules[name]
if not mod:
sys.stderr.write("Failed to find imported module in sys.modules")
report("Failed to find imported module in sys.modules")
#sys.exit(0)
if update_mode and hasattr(mod, "__file__"):
@@ -2083,7 +2112,10 @@ if __name__ == "__main__":
try:
__import__(name) # sys.modules will fill up with what we want
except ImportError:
report("Name %r failed to import", name)
exctype, value = sys.exc_info()[:2]
report("Name %r failed to import: %r", name, str(value))
if debug_mode:
sys.exit(1)
continue
if my_finder:
@@ -2100,7 +2132,7 @@ if __name__ == "__main__":
# if module has __file__ defined, it has Python source code and doesn't need a skeleton
if m not in old_modules and m not in imported_module_names and m != name and not hasattr(sys.modules[m], '__file__'):
if not quiet:
sys.stdout.write(m + "\n")
say(m)
sys.stdout.flush()
fname = buildOutputName(subdir, m)
redoModule(m, fname, imported_module_names)
+1 -1
View File
@@ -81,7 +81,7 @@ class PyDBFrame:
line = frame.f_lineno
if event == 'exception' and info.pydev_state != STATE_SUSPEND: #and breakpoint is not None:
(exception, value, traceback) = arg
(exception, value, trace) = arg
global exception_set
exception_breakpoint = get_exception_breakpoint(exception, tuple(exception_set), NOTIFY_ALWAYS)
@@ -12,6 +12,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiDocumentManagerImpl;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyPsiUtils;
import org.jetbrains.annotations.NotNull;
@@ -92,7 +93,7 @@ public class StatementMover extends LineMover {
return PsiElement.EMPTY_ARRAY;
}
}
return array.toArray(new PsiElement[array.size()]);
return PsiUtilBase.toPsiElementArray(array);
}
private static boolean isNotValidStatementRange(Pair<PsiElement, PsiElement> range) {
@@ -75,7 +75,7 @@ public class PyBuiltinCache {
sdk = PythonSdkType.findPythonSdk(module);
}
else {
final VirtualFile vfile = psifile.getVirtualFile();
final VirtualFile vfile = psifile instanceof PsiFile ? ((PsiFile) psifile).getOriginalFile().getVirtualFile() : psifile.getVirtualFile();
if (vfile != null) { // reality
final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project);
sdk = projectRootManager.getProjectSdk();
@@ -137,7 +137,7 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
}
}
}
return superClasses.toArray(new PsiElement[superClasses.size()]);
return PsiUtilBase.toPsiElementArray(superClasses);
}
/* The implementation is manifestly lazy wrt psi scanning and uses stack rather sparingly.
@@ -11,10 +11,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Iconable;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
@@ -94,7 +91,23 @@ public class PyImportReferenceImpl extends PyReferenceImpl {
// qualifier's type must be module, it should know how to complete
PyType type = qualifier.getType(TypeEvalContext.fast());
if (type != null) {
return getTypeCompletionVariants(myElement, type);
Object[] variants = getTypeCompletionVariants(myElement, type);
if (!alreadyHasImportKeyword()) {
for (int i=0; i < variants.length; i+=1) {
Object item = variants[i];
if (item instanceof LookupElementBuilder) {
variants[i] = ((LookupElementBuilder)item).setInsertHandler(ImportKeywordHandler.INSTANCE);
}
else if (item instanceof PsiNamedElement) {
final PsiNamedElement element = (PsiNamedElement)item;
variants[i] = LookupElementBuilder
.create(element.getName()) // it can't really have null name
.setIcon(element.getIcon(0))
.setInsertHandler(ImportKeywordHandler.INSTANCE);
}
}
}
return variants;
}
else {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
@@ -106,6 +119,19 @@ public class PyImportReferenceImpl extends PyReferenceImpl {
}
}
private boolean alreadyHasImportKeyword() {
ASTNode node = myElement.getNode();
while (node != null) {
final IElementType node_type = node.getElementType();
if (node_type == PyTokenTypes.IMPORT_KEYWORD) {
return true;
}
node = node.getTreeNext();
}
return false;
}
class ImportVariantCollector {
private final PsiFile myCurrentFile;
private final Set<String> myNamesAlready;
@@ -209,18 +235,6 @@ public class PyImportReferenceImpl extends PyReferenceImpl {
}
}
private boolean alreadyHasImportKeyword() {
ASTNode node = myElement.getNode();
while (node != null) {
final IElementType node_type = node.getElementType();
if (node_type == PyTokenTypes.IMPORT_KEYWORD) {
return true;
}
node = node.getTreeNext();
}
return false;
}
private void addImportedNames(@NotNull PyImportElement[] import_elts) {
for (PyImportElement ielt : import_elts) {
PyReferenceExpression ref = ielt.getImportReference();
@@ -2,7 +2,6 @@ package com.jetbrains.python.psi.resolve;
import com.google.common.collect.Sets;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ProjectFacetManager;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
@@ -229,17 +228,7 @@ public class ResolveImportUtil {
}
List<PsiElement> found_in_roots = resolveModulesInRoots(qualifiedName, source_file);
if (found_in_roots.size() > 0) return found_in_roots;
// resolve the name considering every source root as a package dir, as if it's a deployed package. django console does so.
boolean has_djando_facet = false;
final Module source_module = ModuleUtil.findModuleForPsiElement(source_file);
if (source_module != null) {
has_djando_facet = FacetManager.getInstance(source_module).getFacetByType(DjangoFacetType.ID) != null;
}
if (has_djando_facet) {
ResolveInRootVisitor visitor = new ResolveInRootAsTopPackageVisitor(qualifiedName, source_file.getManager(), source_file, true);
visitRoots(source_file, visitor);
return visitor.results;
}
return Collections.emptyList();
}
}
@@ -274,7 +263,7 @@ public class ResolveImportUtil {
}
@Nullable
public static PsiElement resolveModuleInRoots(@NotNull PyQualifiedName moduleQualifiedName, PsiElement foothold) {
public static PsiElement resolveModuleInRoots(@NotNull PyQualifiedName moduleQualifiedName, @Nullable PsiElement foothold) {
final List<PsiElement> candidates = resolveModulesInRoots(moduleQualifiedName, foothold);
return candidates.isEmpty() ? null : candidates.get(0);
}
@@ -287,7 +276,7 @@ public class ResolveImportUtil {
* @return the list of matching directories or files, or an empty list if nothing was found
*/
@NotNull
public static List<PsiElement> resolveModulesInRoots(@NotNull PyQualifiedName moduleQualifiedName, PsiElement foothold) {
public static List<PsiElement> resolveModulesInRoots(@NotNull PyQualifiedName moduleQualifiedName, @Nullable PsiElement foothold) {
if (foothold == null || !foothold.isValid()) return Collections.emptyList();
PsiFile footholdFile = foothold.getContainingFile();
if (footholdFile == null || !footholdFile.isValid()) return Collections.emptyList();
@@ -299,12 +288,45 @@ public class ResolveImportUtil {
return cachedResults;
}
}
ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, foothold.getManager(), footholdFile, true);
visitRoots(foothold, visitor);
List<PsiElement> results =
visitRoots(moduleQualifiedName, foothold.getManager(), ModuleUtil.findModuleForPsiElement(foothold), foothold, true);
if (cache != null) {
cache.put(moduleQualifiedName, visitor.results);
cache.put(moduleQualifiedName, results);
}
return results;
}
private static List<PsiElement> visitRoots(@NotNull PyQualifiedName moduleQualifiedName,
@NotNull PsiManager manager,
@Nullable Module module,
@Nullable PsiElement foothold,
boolean checkForPackage) {
// resolve the name considering every source root as a package dir, as if it's a deployed package. django console does so.
PsiFile footholdFile = foothold != null ? foothold.getContainingFile() : null;
boolean has_djando_facet = false;
if (module != null) {
has_djando_facet = FacetManager.getInstance(module).getFacetByType(DjangoFacetType.ID) != null;
}
ResolveInRootVisitor visitor;
if (has_djando_facet) {
visitor = new ResolveInRootAsTopPackageVisitor(moduleQualifiedName, manager, footholdFile, checkForPackage);
}
else {
visitor = new ResolveInRootVisitor(moduleQualifiedName, manager, footholdFile, checkForPackage);
}
if (module != null) {
visitRoots(module, visitor);
return visitor.results;
}
else if (foothold != null) {
visitRoots(foothold, visitor);
return visitor.results;
}
else {
throw new IllegalStateException();
}
return visitor.results;
}
@Nullable
@@ -328,16 +350,12 @@ public class ResolveImportUtil {
boolean checkForPackage) {
PythonPathCache cache = PythonModulePathCache.getInstance(module);
final List<PsiElement> cachedResults = cache.get(moduleQualifiedName);
if (cachedResults != null) {
return cachedResults;
}
ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName,
PsiManager.getInstance(module.getProject()),
null,
checkForPackage);
visitRoots(module, visitor);
cache.put(moduleQualifiedName, visitor.results);
return visitor.results;
//if (cachedResults != null) {
// return cachedResults;
//}
List<PsiElement> results = visitRoots(moduleQualifiedName, PsiManager.getInstance(module.getProject()), module, null, checkForPackage);
cache.put(moduleQualifiedName, results);
return results;
}
@NotNull
@@ -422,7 +440,7 @@ public class ResolveImportUtil {
}
public static void visitRoots(final PsiElement elt, @NotNull final RootVisitor visitor) {
public static void visitRoots(@NotNull final PsiElement elt, @NotNull final RootVisitor visitor) {
// real search
final Module module = ModuleUtil.findModuleForPsiElement(elt);
if (module != null) {
@@ -433,11 +451,19 @@ public class ResolveImportUtil {
}
}
private static void visitRoots(@NotNull Module module, RootVisitor visitor) {
// TODO: implement a proper module-like approach in PyCharm for "project's dirs on pythonpath", minding proper search order
// Module-based approach works only in the IDEA plugin.
if (visitModuleContentEntries(module, visitor)) return;
// else look in SDK roots
visitModuleSdkRoots(visitor, module);
}
private static void visitSdkRoots(PsiElement elt, RootVisitor visitor) {
// no module, another way to look in SDK roots
final PsiFile elt_psifile = elt.getContainingFile();
if (elt_psifile != null) { // formality
final VirtualFile elt_vfile = elt_psifile.getVirtualFile();
final VirtualFile elt_vfile = elt_psifile.getOriginalFile().getVirtualFile();
if (elt_vfile != null) { // reality
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(elt.getProject()).getFileIndex();
final List<OrderEntry> orderEntries = fileIndex.getOrderEntriesForFile(elt_vfile);
@@ -462,13 +488,6 @@ public class ResolveImportUtil {
}
}
private static void visitRoots(Module module, RootVisitor visitor) {
// TODO: implement a proper module-like approach in PyCharm for "project's dirs on pythonpath", minding proper search order
// Module-based approach works only in the IDEA plugin.
if (visitModuleContentEntries(module, visitor)) return;
// else look in SDK roots
visitModuleSdkRoots(visitor, module);
}
private static boolean visitModuleContentEntries(Module module, RootVisitor visitor) {
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
@@ -513,7 +532,7 @@ public class ResolveImportUtil {
/**
* Looks for a name among element's module's roots; if there's no module, then among project's roots.
*
* @param context PSI element that defines the module and/or the project.
* @param context PSI element that defines the module and/or the project.
* @param refName module name to be found among roots.
* @return a PsiFile, a child of a root.
*/
@@ -559,7 +578,7 @@ public class ResolveImportUtil {
static class ResolveInRootVisitor implements RootVisitor {
final PsiFile myFootholdFile;
private final boolean myCheckForPackage;
final boolean myCheckForPackage;
final @NotNull PyQualifiedName myQualifiedName;
final @NotNull PsiManager myPsiManager;
final List<PsiElement> results = new ArrayList<PsiElement>();
@@ -582,17 +601,17 @@ public class ResolveImportUtil {
if (module != null) {
results.add(module);
}
return true;
}
@Nullable
private PsiElement resolveInRoot(VirtualFile root,
PyQualifiedName qualifiedName,
PsiManager psiManager,
@Nullable PsiFile foothold_file,
boolean checkForPackage) {
protected PsiElement resolveInRoot(VirtualFile root,
PyQualifiedName qualifiedName,
PsiManager psiManager,
@Nullable PsiFile foothold_file,
boolean checkForPackage) {
PsiElement module = root.isDirectory() ? psiManager.findDirectory(root) : psiManager.findFile(root);
module = patchModule(module, qualifiedName);
if (module == null) return null;
for (String component : qualifiedName.getComponents()) {
if (component == null) {
@@ -603,18 +622,6 @@ public class ResolveImportUtil {
}
return module;
}
/**
* @param root_module file or dir representing a module's root.
* @param name what we try to resolve
* @return altered parent module; this implementation returns root_module unmodified.
*/
@Nullable
@SuppressWarnings({"MethodMayBeStatic"})
protected PsiElement patchModule(PsiElement root_module, PyQualifiedName name) {
return root_module;
}
}
/**
@@ -629,13 +636,24 @@ public class ResolveImportUtil {
super(qName, psiManager, foothold_file, checkForPackage);
}
@Nullable
@Override
protected PsiElement patchModule(PsiElement root_module, PyQualifiedName name) {
if (name.matchesPrefix(PyQualifiedName.fromDottedString(((PsiNamedElement)root_module).getName()))) {
return root_module.getParent();
public boolean visitRoot(VirtualFile root) {
if (!root.isValid()) {
return true;
}
return null;
PsiElement module = resolveInRoot(root, myQualifiedName, myPsiManager, myFootholdFile, myCheckForPackage);
if (module != null) {
results.add(module);
}
if (myQualifiedName.matchesPrefix(PyQualifiedName.fromDottedString(root.getName()))) {
module = resolveInRoot(root.getParent(), myQualifiedName, myPsiManager, myFootholdFile, myCheckForPackage);
if (module != null) {
results.add(module);
}
}
return true;
}
}
@@ -234,7 +234,7 @@ public class PyRefactoringUtil {
return PsiElement.EMPTY_ARRAY;
}
}
return array.toArray(new PsiElement[array.size()]);
return PsiUtilBase.toPsiElementArray(array);
}
private PyRefactoringUtil() {
@@ -7,6 +7,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilBase;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.actions.AddImportHelper;
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
@@ -113,7 +114,7 @@ public class PyClassRefactoringUtil {
for (PyElement element : elements) {
final Set<PsiElement> comments = PyUtil.getComments(element);
if (comments.size() > 0) {
PyPsiUtils.removeElements(comments.toArray(new PsiElement[comments.size()]));
PyPsiUtils.removeElements(PsiUtilBase.toPsiElementArray(comments));
}
}
PyPsiUtils.removeElements(elements);
@@ -1 +1 @@
from package1.submodule2
from package1.submodule2 import <caret>