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

Conflicts:
	python/src/com/jetbrains/python/psi/impl/PyReferenceImpl.java
This commit is contained in:
Dmitry Cheryasov
2010-10-26 16:46:36 +03:00
51 changed files with 640 additions and 465 deletions
+164 -165
View File
@@ -1,197 +1,196 @@
<project name="build Python plugin jar" default="dist">
<!--
You can set idea.home property here
<property name="idea.home" value="c:\Program Files\JetBrains\IntelliJ IDEA 6951"/>
-->
<!--<property file="build-plugin.properties"/>-->
<!--
You can set idea.home property here
<property name="idea.home" value="c:\Program Files\JetBrains\IntelliJ IDEA 6951"/>
-->
<!--<property file="build-plugin.properties"/>-->
<property name="plugin.home" value="${basedir}/.."/>
<property name="plugin.revision" value="${build.number}"/>
<property name="plugin.home" value="${basedir}/.."/>
<property name="plugin.revision" value="${build.number}"/>
<property name="idea.lib" value="${idea.home}/lib"/>
<property name="idea.plugins" value="${idea.home}/plugins"/>
<property name="idea.lib" value="${idea.home}/lib"/>
<property name="idea.plugins" value="${idea.home}/plugins"/>
<property name="build.number" value="snapshot"/>
<property name="build.number" value="snapshot"/>
<dirname property="basedir" file="${ant.file}"/>
<property name="output" value="${basedir}/../dist"/>
<property name="test.output.dir" value="${output}/testClasses"/>
<property name="reports.dir" location="${output}/report"/>
<!--<property name="ruby.mock.sdk" value="${output}/mockSdk"/>-->
<!--<property name="rubystubs" value="${plugin.home}/rubystubs/rubystubs"/>-->
<dirname property="basedir" file="${ant.file}"/>
<property name="output" value="${basedir}/../dist"/>
<property name="test.output.dir" value="${output}/testClasses"/>
<property name="reports.dir" location="${output}/report"/>
<!--<property name="ruby.mock.sdk" value="${output}/mockSdk"/>-->
<!--<property name="rubystubs" value="${plugin.home}/rubystubs/rubystubs"/>-->
<property name="zipdir" value="${output}/zip"/>
<property name="plugindir" value="${zipdir}/python"/>
<property name="zipname" value="python-${plugin.revision}.zip"/>
<property name="zipdir" value="${output}/zip"/>
<property name="plugindir" value="${zipdir}/python"/>
<property name="zipname" value="python-${plugin.revision}.zip"/>
<property name="src.dir" location="${plugin.home}/src"/>
<property name="resources.dir" location="${plugin.home}/resources"/>
<property name="plugin.resources.dir" location="${plugin.home}/pluginResources"/>
<property name="test.src.dir" location="${plugin.home}/testSrc"/>
<property name="artifacts.dir" location="${output}/artifacts"/>
<property name="src.dir" location="${plugin.home}/src"/>
<property name="resources.dir" location="${plugin.home}/resources"/>
<property name="plugin.resources.dir" location="${plugin.home}/pluginResources"/>
<property name="test.src.dir" location="${plugin.home}/testSrc"/>
<property name="artifacts.dir" location="${output}/artifacts"/>
<property name="classes.dir" value="${basedir}/dist/classes"/>
<property name="test.classes.dir" value="${basedir}/dist/test-classes"/>
<property name="classes.dir" value="${basedir}/dist/classes"/>
<property name="test.classes.dir" value="${basedir}/dist/test-classes"/>
<path id="classpath.lib">
<fileset dir="${idea.lib}">
<include name="?*.jar"/>
</fileset>
<fileset dir="${plugin.home}/lib">
<include name = "**/*.jar"/>
</fileset>
<fileset dir="${idea.plugins}/yaml/lib">
<include name="yaml.jar"/>
</fileset>
</path>
<path id="classpath.lib">
<fileset dir="${idea.lib}">
<include name="?*.jar"/>
</fileset>
<fileset dir="${plugin.home}/lib">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${idea.plugins}/yaml/lib">
<include name="yaml.jar"/>
</fileset>
</path>
<path id="sourcepath">
<dirset dir="${plugin.home}">
<include name="resources"/>
<include name="src"/>
<include name="pluginSrc"/>
<include name="pydevSrc"/>
</dirset>
<dirset dir="${plugin.home}/../ultimate/ultimate-verifier">
<include name="src"/>
</dirset>
</path>
<path id="sourcepath">
<dirset dir="${plugin.home}">
<include name="resources"/>
<include name="src"/>
<include name="pluginSrc"/>
<include name="pydevSrc"/>
</dirset>
<dirset dir="${plugin.home}/../ultimate/ultimate-verifier">
<include name="src"/>
</dirset>
</path>
<!-- The task requires the following libraries from IntelliJ IDEA distribution: -->
<!-- javac2.jar; jdom.jar; asm.jar; asm-commons.jar -->
<taskdef name="javac2" classname="com.intellij.ant.Javac2">
<classpath refid="classpath.lib"/>
</taskdef>
<!-- The task requires the following libraries from IntelliJ IDEA distribution: -->
<!-- javac2.jar; jdom.jar; asm.jar; asm-commons.jar -->
<taskdef name="javac2" classname="com.intellij.ant.Javac2">
<classpath refid="classpath.lib"/>
</taskdef>
<!-- Compiler options -->
<property name="compiler.debug" value="on"/>
<property name="compiler.generate.no.warnings" value="off"/>
<property name="compiler.args" value=""/>
<property name="compiler.max.memory" value="256m"/>
<!-- Compiler options -->
<property name="compiler.debug" value="on"/>
<property name="compiler.generate.no.warnings" value="off"/>
<property name="compiler.args" value=""/>
<property name="compiler.max.memory" value="256m"/>
<patternset id="sources.pt">
<exclude name="**/.svn/**"/>
</patternset>
<patternset id="testsources.pt">
<exclude name="**/data/**"/>
<exclude name="**/.svn/**"/>
</patternset>
<patternset id="resources.pt">
<include name="**/?*.properties"/>
<include name="**/?*.template"/>
<include name="**/?*.xml"/>
<include name="**/?*.gif"/>
<include name="**/?*.png"/>
<include name="**/?*.txt"/>
<include name="**/?*.jpeg"/>
<include name="**/?*.jpg"/>
<include name="**/?*.html"/>
<include name="**/?*.dtd"/>
<include name="**/?*.tld"/>
<include name="**/?*.py"/>
</patternset>
<patternset id="sources.pt">
<exclude name="**/.svn/**"/>
</patternset>
<patternset id="resources.pt">
<include name="**/?*.properties"/>
<include name="**/?*.template"/>
<include name="**/?*.xml"/>
<include name="**/?*.gif"/>
<include name="**/?*.png"/>
<include name="**/?*.txt"/>
<include name="**/?*.jpeg"/>
<include name="**/?*.jpg"/>
<include name="**/?*.html"/>
<include name="**/?*.dtd"/>
<include name="**/?*.tld"/>
<include name="**/?*.py"/>
<include name="**/?*.ft"/>
</patternset>
<target name="clean" description="Cleanup output">
<delete dir="${output}"/>
</target>
<target name="clean" description="Cleanup output">
<delete dir="${output}"/>
</target>
<target name="compile" description="Compile module python">
<mkdir dir="${classes.dir}"/>
<!-- compile -->
<javac2 destdir="${classes.dir}"
debug="${compiler.debug}"
nowarn="${compiler.generate.no.warnings}"
memorymaximumsize="${compiler.max.memory}"
fork="true">
<compilerarg line="${compiler.args}"/>
<classpath refid="classpath.lib"/>
<src refid="sourcepath"/>
<patternset refid="sources.pt"/>
</javac2>
<target name="compile" description="Compile module python">
<mkdir dir="${classes.dir}"/>
<!-- compile -->
<javac2 destdir="${classes.dir}"
debug="${compiler.debug}"
nowarn="${compiler.generate.no.warnings}"
memorymaximumsize="${compiler.max.memory}"
fork="true">
<compilerarg line="${compiler.args}"/>
<classpath refid="classpath.lib"/>
<src refid="sourcepath"/>
<patternset refid="sources.pt"/>
</javac2>
<!-- copy resources -->
<copy todir="${classes.dir}">
<fileset dir="${resources.dir}">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
<fileset dir="${plugin.resources.dir}">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
<fileset dir="${plugin.home}/src">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
</copy>
<!-- copy resources -->
<copy todir="${classes.dir}">
<fileset dir="${resources.dir}">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
<fileset dir="${plugin.resources.dir}">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
<fileset dir="${plugin.home}/src">
<patternset refid="resources.pt"/>
<type type="file"/>
</fileset>
</copy>
<!-- copy plugin.xml -->
<mkdir dir="${classes.dir}/META-INF"/>
<copy todir="${classes.dir}/META-INF">
<fileset dir="${plugin.home}/pluginSrc/META-INF"/>
</copy>
<!-- adding revision version number to plugin version -->
<!--<replace file="${classes.dir}/META-INF/plugin.xml" token="VERSION" value="${plugin.version}"/>-->
</target>
<!-- copy plugin.xml -->
<mkdir dir="${classes.dir}/META-INF"/>
<copy todir="${classes.dir}/META-INF">
<fileset dir="${plugin.home}/pluginSrc/META-INF"/>
</copy>
<!-- adding revision version number to plugin version -->
<!--<replace file="${classes.dir}/META-INF/plugin.xml" token="VERSION" value="${plugin.version}"/>-->
</target>
<target name="jar" description="Generate jar file" depends="compile">
<mkdir dir="${output}"/>
<jar destfile="${output}/python.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Revision" value="${plugin.revision}"/>
<!--<attribute name="Build" value="${plugin.version}"/>-->
</manifest>
</jar>
</target>
<target name="jar" description="Generate jar file" depends="compile">
<mkdir dir="${output}"/>
<jar destfile="${output}/python.jar" basedir="${classes.dir}">
<manifest>
<attribute name="Revision" value="${plugin.revision}"/>
<!--<attribute name="Build" value="${plugin.version}"/>-->
</manifest>
</jar>
</target>
<target name="zip" description="Generate zip plugin file" depends="jar">
<mkdir dir="${zipdir}"/>
<target name="zip" description="Generate zip plugin file" depends="jar">
<mkdir dir="${zipdir}"/>
<!--copy plugin jar-->
<mkdir dir="${plugindir}/lib"/>
<move todir="${plugindir}/lib" file="${output}/python.jar"/>
<!--copy plugin jar-->
<mkdir dir="${plugindir}/lib"/>
<move todir="${plugindir}/lib" file="${output}/python.jar"/>
<!--copy common libraries jars-->
<copy todir="${plugindir}/lib">
<fileset dir="${plugin.home}/lib" includes="*.jar"/>
</copy>
<!--copy common libraries jars-->
<copy todir="${plugindir}/lib">
<fileset dir="${plugin.home}/lib" includes="*.jar"/>
</copy>
<mkdir dir="${plugindir}/helpers"/>
<copy todir="${plugindir}/helpers">
<fileset dir="${plugin.home}/helpers" includes="**/*.py"/>
</copy>
<mkdir dir="${plugindir}/helpers"/>
<copy todir="${plugindir}/helpers">
<fileset dir="${plugin.home}/helpers" includes="**/*.py"/>
</copy>
<zip basedir="${zipdir}" destfile="${output}/${zipname}"/>
</target>
<copy todir="${plugindir}" file="${plugin.home}/../bin/runnerw.exe"/>
<!--
<zip basedir="${zipdir}" destfile="${output}/${zipname}"/>
</target>
<target name="jflex" description="Builds lexers from ruby.flex, output.flex, rhtml.flex">
<ant antfile="${rubylexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${rubylexer.dir}"/>
</ant>
<ant antfile="${outputlexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${outputlexer.dir}"/>
</ant>
<ant antfile="${rhtmllexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${rhtmllexer.dir}"/>
</ant>
</target>
-->
<!--
<target name="build" depends="clean, compile"/>
<target name="jflex" description="Builds lexers from ruby.flex, output.flex, rhtml.flex">
<ant antfile="${rubylexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${rubylexer.dir}"/>
</ant>
<ant antfile="${outputlexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${outputlexer.dir}"/>
</ant>
<ant antfile="${rhtmllexer.build.file}">
<property name="jflex.dir" location="${plugin.home}/lib"/>
<property name="lexer.dir" location="${rhtmllexer.dir}"/>
</ant>
</target>
-->
<target name="dist" depends="build, zip" description="main target"/>
<target name="build" depends="clean, compile"/>
<target name="artifacts" depends="dist">
<mkdir dir="${artifacts.dir}"/>
<move file="${output}/${zipname}" todir="${artifacts.dir}"/>
</target>
<target name="dist" depends="build, zip" description="main target"/>
<target name="build.artifacts" depends="dist, artifacts"/>
<target name="artifacts" depends="dist">
<mkdir dir="${artifacts.dir}"/>
<move file="${output}/${zipname}" todir="${artifacts.dir}"/>
</target>
<target name="build.artifacts" depends="dist, artifacts"/>
</project>
+1 -1
View File
@@ -83,7 +83,7 @@ if [ -z "$PYCHARM_VM_OPTIONS" ]; then
fi
# isEap
if ["@@isEap@@" -eq "true" ]
if [ "@@isEap@@" -eq "true" ]; then
$AGENT="-agentlib:yjpagent$BITS=disablej2ee,sessionname=pycharm"
fi
+6 -1
View File
@@ -486,10 +486,15 @@ def layoutMac(Map args, String target) {
layout(target) {
dir("bin") {
fileset(dir: "$home/community/bin/mac")
fileset(dir: "$home/community/bin/nix")
fileset(dir: "$home/community/bin/nix") {
exclude(name: "idea.sh")
}
fileset(dir: "$home/bin") {
include(name: "*.jnilib")
}
fileset(dir: "$home/python/build") {
include(name: "pycharm.sh")
}
}
dir("lib") {
fileset(dir: "$home/community/build/conf/mac/lib")
+7 -2
View File
@@ -1,8 +1,13 @@
#!/usr/bin/env python
from pycharm.fix_getpass import fixGetpass
from django.core.management import execute_manager
from pycharm import django_settings
import os
from runpy import run_module
manage_file = os.getenv('PYCHARM_DJANGO_MANAGE_MODULE')
if not manage_file:
manage_file = 'manage'
if __name__ == "__main__":
fixGetpass()
execute_manager(django_settings)
run_module(manage_file)
+42 -6
View File
@@ -3,9 +3,19 @@ import os
import imp
import sys
import types
import re
from pycharm.tcmessages import TeamcityServiceMessages
from pycharm.tcunittest import TeamcityTestRunner
try:
import unittest2 as unittest
except:
# python version doesn't have unittest2
pass
PYTHON_VERSION_MAJOR = sys.version_info[0]
PYTHON_VERSION_MINOR = sys.version_info[1]
ENABLE_DEBUG_LOGGING = False
if os.getenv("UTRUNNER_ENABLE_DEBUG_LOGGING"):
ENABLE_DEBUG_LOGGING = True
@@ -39,9 +49,28 @@ def walkModules(modules, dirname, names):
def loadModulesFromFolderRec(folder):
modules = []
os.path.walk(folder, walkModules, modules)
if PYTHON_VERSION_MAJOR == 3:
for root, dirs, files in os.walk(folder, walkModules, modules):
for name in files:
if name.endswith(".py"):
modules.append(loadSource(os.path.join(root, name)))
else:
os.path.walk(folder, walkModules, modules)
return modules
def loadModulesFromFolderUsingPattern(folder, pattern):
''' loads modules from folder ,
check if module name matches given pattern'''
modules = loadModulesFromFolderRec(folder)
result = []
prog = re.compile(pattern)
for module in modules:
if prog.match(module.__name__):
result.append(module)
return result
testLoader = unittest.TestLoader()
all = unittest.TestSuite()
@@ -53,12 +82,19 @@ for arg in sys.argv[1:]:
a = arg.split("::")
if len(a) == 1:
# From module or folder
if a[0].endswith("/"):
debug("/ from folder " + a[0])
modules = loadModulesFromFolderRec(a[0])
a_splitted = a[0].split(";")
if len(a_splitted) != 1:
# means we have pattern to match against
if a_splitted[0].endswith("/"):
debug("/ from folder " + a_splitted[0] + ". Use pattern: " + a_splitted[1])
modules = loadModulesFromFolderUsingPattern(a_splitted[0], a_splitted[1])
else:
debug("/ from module " + a[0])
modules = [loadSource(a[0])]
if a[0].endswith("/"):
debug("/ from folder " + a[0])
modules = loadModulesFromFolderRec(a[0])
else:
debug("/ from module " + a[0])
modules = [loadSource(a[0])]
for module in modules:
all.addTests(testLoader.loadTestsFromModule(module)._tests)
+4 -4
View File
@@ -48,11 +48,11 @@ each command has a format:
120 CMD_GET_COMPLETIONS JAVA
500 series diagnostics/ok
901 VERSION either Version string (1.0) Currently just used at startup
902 RETURN either Depends on caller -
501 VERSION either Version string (1.0) Currently just used at startup
502 RETURN either Depends on caller -
900 series: errors
501 ERROR either - This is reserved for unexpected errors.
901 ERROR either - This is reserved for unexpected errors.
* JAVA - remote debugger, the java end
* PYDB - pydevd, the python end
@@ -755,7 +755,7 @@ class InternalGetCompletions(InternalThreadCommand):
except:
exc = GetExceptionTracebackStr()
sys.stderr.write('%s\n' % (exc,))
cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, "Error evaluating expression " + exc)
cmd = dbg.cmdFactory.makeErrorMessage(self.sequence, "Error getting completion " + exc)
dbg.writer.addCommand(cmd)
+6 -1
View File
@@ -325,6 +325,11 @@ def resolveCompoundVariable(thread_id, frame_id, scope, attrs):
del attrList[0] # globals are special, and they get a single dummy unused attribute
else:
var = frame.f_locals
type, _typeName, resolver = getType(var)
try:
resolver.resolve(var, attrList[0])
except:
var = frame.f_globals
for k in attrList:
type, _typeName, resolver = getType(var)
@@ -423,7 +428,7 @@ def changeAttrExpression(thread_id, frame_id, attr, expression):
#default way (only works for changing it in the topmost frame)
result = eval(expression, frame.f_globals, frame.f_locals)
exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals)
return result;
return result
except Exception:
+7 -2
View File
@@ -4,10 +4,11 @@
<id>Pythonid</id>
<name>Python</name>
<idea-version since-build="96.1121" until-build="97.0"/>
<idea-version since-build="98.187" until-build="99.0"/>
<description>Smart editing for Python scripts</description>
<version>2.6.2</version>
<version>2.6.3</version>
<depends>com.intellij.modules.ultimate</depends>
<depends>com.intellij.modules.java</depends>
<depends>org.jetbrains.plugins.yaml</depends>
<vendor url="http://www.jetbrains.com/idea/" logo="/com/jetbrains/python/python.png">JetBrains, Keith Lea</vendor>
@@ -22,6 +23,8 @@
<moduleConfigurationEditorProvider implementation="com.jetbrains.python.module.PythonModuleConfigurationEditorProvider"/>
<applicationService serviceInterface="com.jetbrains.python.run.PyCommonOptionsFormFactory"
serviceImplementation="com.jetbrains.python.run.PyPluginCommonOptionsFormFactory"/>
<applicationService serviceInterface="com.intellij.execution.process.RunnerMediatorManager"
serviceImplementation="com.jetbrains.django.run.PythonPluginRunnerMediatorManager"/>
</extensions>
<extensions defaultExtensionNs="Pythonid">
@@ -42,4 +45,6 @@
</component>
</module-components>
</idea-plugin>
@@ -57,7 +57,7 @@ public class PythonSdkChooserPanel extends JComponent {
myJdkChooser.setAllowedJdkTypes(new SdkType[]{PythonSdkType.getInstance()});
final Sdk selectedJdk = project == null ? null : ProjectRootManager.getInstance(project).getProjectJdk();
final Sdk selectedJdk = project == null ? null : ProjectRootManager.getInstance(project).getProjectSdk();
myJdkChooser.updateList(selectedJdk, null);
}
+1
View File
@@ -17,6 +17,7 @@
<orderEntry type="module" module-name="xdebugger-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="sass" scope="RUNTIME" />
<orderEntry type="module" module-name="dom-impl" scope="RUNTIME" />
<orderEntry type="library" name="Guava" level="project" />
</component>
</module>
+6 -1
View File
@@ -41,7 +41,7 @@
serviceImplementation="com.jetbrains.python.psi.impl.PyElementGeneratorImpl"/>
<typedHandler implementation="com.jetbrains.python.codeInsight.KeywordTypedHandler" id="pyCommaAfterKwd"/>
<typedHandler implementation="com.jetbrains.django.codeInsight.InterpolationTypedHandler" id="pyDjangoBraceInterpolation"/>
<typedHandler implementation="com.jetbrains.django.lang.template.editor.DjangoBracesInterpolationTypedHandler" id="pyDjangoBraceInterpolation"/>
<typedHandler implementation="com.jetbrains.python.editor.ColonTypedHandler" id="pyColonUnindent"/>
<stubIndex implementation="com.jetbrains.python.psi.stubs.PyClassNameIndex"/>
@@ -150,6 +150,8 @@
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.PyDefaultLiveTemplatesProvider"/>
<completion.contributor language="Python" implementationClass="com.jetbrains.python.codeInsight.PyClassNameCompletionContributor"/>
<typedHandler implementation="com.jetbrains.python.console.PydevCompletionAutopopupBlockingHandler" id="pydevBlockAutoPopup"
order="before completionAutoPopup"/>
<referencesSearch implementation="com.jetbrains.python.psi.search.PyInitReferenceSearchExecutor"/>
<referencesSearch implementation="com.jetbrains.python.psi.search.PyStringReferenceSearch"/>
@@ -274,6 +276,8 @@
<renamePsiElementProcessor implementation="com.jetbrains.django.refactoring.RenameDjangoParameterProcessor"/>
<elementDescriptionProvider implementation="com.jetbrains.django.refactoring.DjangoElementDescriptionProvider"/>
<completion.contributor language="Python" implementationClass="com.jetbrains.django.lang.template.DjangoUrlsCompletionContributor"/>
<!-- App Engine -->
<facetType implementation="com.jetbrains.appengine.facet.AppEngineFacetType"/>
@@ -363,6 +367,7 @@
id="Devmode.DumpPsi"
class="com.jetbrains.python.devmode.DumpPsiToClipboardAction"
text="Dump PSI to clipboard"
internal="true"
>
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="Macros"/>
</action>
@@ -437,6 +437,7 @@ runcfg.captions.script_parameters_dialog=Enter script parameters
runcfg.captions.interpreter_options_dialog=Enter interpreter options
sdk.error.invalid.interpreter.name.$0=Invalid Python interpeter name '{0}'!
sdk.select.path=Select Python Interpreter
runcfg.unittest.dlg.pattern=Pattern:
# Consoles messages
python.console=Python Console
@@ -25,7 +25,7 @@ public abstract class PythonModuleTypeBase<T extends ModuleBuilder> extends Modu
}
public String getDescription() {
return "Provides facilities for developing Python applications";
return "Provides facilities for developing Python and Django applications";
}
public Icon getBigIcon() {
@@ -80,7 +80,7 @@ public class BuildoutConfigurable implements Configurable, NonDefaultProjectConf
@Override
public Icon getIcon() {
return BuildoutFacetType.ourIcon;
return BuildoutFacetType.BUILDOUT_ICON;
}
@Override
@@ -4,11 +4,8 @@ import com.intellij.facet.Facet;
import com.intellij.facet.FacetType;
import com.intellij.facet.FacetTypeId;
import com.intellij.facet.FacetTypeRegistry;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.IconLoader;
import com.jetbrains.python.PythonModuleTypeBase;
import org.jetbrains.annotations.NotNull;
@@ -51,10 +48,10 @@ public class BuildoutFacetType extends FacetType<BuildoutFacet, BuildoutFacetCon
return (BuildoutFacetType)FacetTypeRegistry.getInstance().findFacetType(ID);
}
public final static Icon ourIcon = IconLoader.getIcon("/com/jetbrains/python/icons/buildout/buildout.png");
public final static Icon BUILDOUT_ICON = IconLoader.getIcon("/com/jetbrains/python/icons/buildout/buildout.png");
@Override
public Icon getIcon() {
return ourIcon;
return BUILDOUT_ICON;
}
}
@@ -1,7 +1,7 @@
package com.jetbrains.python.buildout.config;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.jetbrains.python.buildout.BuildoutFacetType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -38,7 +38,7 @@ public class BuildoutCfgFileType extends LanguageFileType {
@Nullable
public Icon getIcon() {
return PlainTextFileType.INSTANCE.getIcon();
return BuildoutFacetType.BUILDOUT_ICON;
}
}
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.codeFragment.Position;
import com.intellij.codeInsight.controlflow.ConditionalInstruction;
import com.intellij.codeInsight.controlflow.Instruction;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.HashSet;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
@@ -83,6 +84,10 @@ public class PyCodeFragmentUtil {
if (nextElement instanceof PyExceptPart){
continue;
}
// We allow raise statements in code
if (nextElement == null && PsiTreeUtil.getParentOfType(element, PyRaiseStatement.class) != null){
continue;
}
if (!CodeFragmentUtil.elementFit(nextElement, start, end)){
outerInstructions.add(next);
}
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.generation.PsiElementMemberChooserObject;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.ui.SimpleColoredComponent;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFunction;
@@ -21,6 +22,9 @@ public class PyMethodMember extends PsiElementMemberChooserObject implements Cla
if (element instanceof PyFunction) {
return element.getName() + ((PyFunction)element).getParameterList().getText();
}
if (element instanceof PyClass && PyNames.FAKE_OLD_BASE.equals(element.getName())) {
return "<old-style class>";
}
return element.getName();
}
@@ -169,24 +169,29 @@ public class PyOverrideImplementUtil {
}, ArrayUtil.EMPTY_STRING_ARRAY);
int startIndex = 0;
if (baseFunction.getReturnType() != PyNoneType.INSTANCE) {
statementBody.append("return ");
}
if (baseClass.isNewStyleClass()) {
statementBody.append(PyNames.SUPER);
statementBody.append("(");
final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel();
if (!langLevel.isPy3K()) {
statementBody.append(pyClass.getName()).append(", ").append(PyUtil.getFirstParameterName(baseFunction));
}
statementBody.append(").").append(baseFunction.getName()).append("(");
startIndex = 1;
if (PyNames.FAKE_OLD_BASE.equals(baseFunction.getContainingClass().getName())) {
statementBody.append("pass");
}
else {
statementBody.append(baseClass.getName()).append(".").append(baseFunction.getName()).append("(");
if (baseFunction.getReturnType() != PyNoneType.INSTANCE) {
statementBody.append("return ");
}
if (baseClass.isNewStyleClass()) {
statementBody.append(PyNames.SUPER);
statementBody.append("(");
final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel();
if (!langLevel.isPy3K()) {
statementBody.append(pyClass.getName()).append(", ").append(PyUtil.getFirstParameterName(baseFunction));
}
statementBody.append(").").append(baseFunction.getName()).append("(");
startIndex = 1;
}
else {
statementBody.append(baseClass.getName()).append(".").append(baseFunction.getName()).append("(");
}
statementBody.append(StringUtil.join(paramTexts, startIndex, paramTexts.length, ", "));
statementBody.append(")");
}
statementBody.append(StringUtil.join(paramTexts, startIndex, paramTexts.length, ", "));
statementBody.append(")");
pyFunctionBuilder.statement(statementBody.toString());
return pyFunctionBuilder;
@@ -0,0 +1,24 @@
package com.jetbrains.python.console;
import com.intellij.codeInsight.editorActions.TypedHandlerDelegate;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiFile;
/**
* @author oleg
* @date 10/26/10
*/
public class PydevCompletionAutopopupBlockingHandler extends TypedHandlerDelegate {
public static final Key<Object> REPL_KEY = new Key<Object>("python.repl.console.editor");
@Override
public Result checkAutoPopup(final char charTyped, final Project project, final Editor editor, final PsiFile file) {
if (editor.getUserData(REPL_KEY) != null){
return Result.DEFAULT;
}
return Result.CONTINUE;
}
}
@@ -11,6 +11,8 @@ import com.jetbrains.python.console.pydev.PydevConsoleCommunication;
public class PydevLanguageConsole extends LanguageConsoleImpl {
public PydevLanguageConsole(final Project project, final String title) {
super(project, title, PythonLanguage.getInstance(), false);
// Mark editor as console one, to prevent autopopup completion
getConsoleEditor().putUserData(PydevCompletionAutopopupBlockingHandler.REPL_KEY, new Object());
}
public void setPydevConsoleCommunication(final PydevConsoleCommunication communication) {
@@ -3,8 +3,10 @@ package com.jetbrains.python.debugger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class PyDebuggerEvaluator extends XDebuggerEvaluator {
@@ -18,7 +20,7 @@ public class PyDebuggerEvaluator extends XDebuggerEvaluator {
}
@Override
public void evaluate(@NotNull String expression, final XEvaluationCallback callback) {
public void evaluate(@NotNull String expression, XEvaluationCallback callback, @Nullable XSourcePosition expressionPosition) {
expression = expression.trim();
if ("".equals(expression)) {
callback.evaluated(NONE);
@@ -31,7 +31,8 @@ public class PythonEnterHandler implements EnterHandlerDelegate {
PyArgumentList.class,
PyParameterList.class,
PyFunction.class,
PySliceExpression.class
PySliceExpression.class,
PySubscriptionExpression.class
};
@Override
@@ -46,7 +46,8 @@ public class PyBlock implements ASTBlock {
PyElementTypes.PARAMETER_LIST,
PyElementTypes.TUPLE_EXPRESSION,
PyElementTypes.PARENTHESIZED_EXPRESSION,
PyElementTypes.SLICE_EXPRESSION);
PyElementTypes.SLICE_EXPRESSION,
PyElementTypes.SUBSCRIPTION_EXPRESSION);
private static final TokenSet ourBrackets = TokenSet.create(PyTokenTypes.LPAR, PyTokenTypes.RPAR,
PyTokenTypes.LBRACE, PyTokenTypes.RBRACE,
@@ -74,9 +74,6 @@ public class PyUtil {
}
seeker = seeker.getPrevSibling();
}
if (seeker instanceof PyExpressionStatement && seeker.getFirstChild() instanceof PyStringLiteralExpression) {
comments.add(seeker);
}
return comments;
}
@@ -85,7 +85,7 @@ public class PyBuiltinCache {
final VirtualFile vfile = psifile.getVirtualFile();
if (vfile != null) { // reality
final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project);
sdk = projectRootManager.getProjectJdk();
sdk = projectRootManager.getProjectSdk();
if (sdk == null) {
final List<OrderEntry> orderEntries = projectRootManager.getFileIndex().getOrderEntriesForFile(vfile);
for (OrderEntry orderEntry : orderEntries) {
@@ -1,5 +1,6 @@
package com.jetbrains.python.psi.impl;
import com.google.common.collect.Lists;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.lang.ASTNode;
@@ -15,11 +16,11 @@ import com.intellij.util.Icons;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.SortedList;
import com.jetbrains.django.util.PythonDataflowUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.*;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.psi.types.PyModuleType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
@@ -351,7 +352,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
@NotNull
public Object[] getVariants() {
final List<Object> ret = new ArrayList<Object>();
final List<LookupElement> ret = Lists.newArrayList();
// Use real context here to enable correct completion and resolve in case of PyExpressionCodeFragment!!!
final PsiElement realContext = PyPsiUtils.getRealContext(myElement);
@@ -364,24 +365,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
PyResolveUtil.scanOuterContext(processor, realContext); // possible names from around us at call time
// in a call, include function's arg names
PyCallExpression call_expr = PsiTreeUtil.getParentOfType(myElement, PyCallExpression.class);
if (call_expr != null) {
PyExpression callee = call_expr.getCallee();
if (callee instanceof PyReferenceExpression) {
if (PsiTreeUtil.getParentOfType(myElement, PyKeywordArgument.class) == null) {
PsiElement def = ((PyReferenceExpression)callee).getReference().resolve();
if (def instanceof PyFunction) {
addKeywordArgumentVariants((PyFunction)def, ret);
}
else if (def instanceof PyClass) {
PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true); // search in superclasses
if (init != null) {
addKeywordArgumentVariants(init, ret);
}
}
}
}
}
PythonDataflowUtil.collectFunctionArgNames(myElement, ret);
// scan all "import *" and include names provided by them
CollectProcessor collect_proc = new CollectProcessor(IS_STAR_IMPORT);
@@ -428,155 +412,6 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
return ret.toArray();
}
private static void addKeywordArgumentVariants(PyFunction def, final List<Object> ret) {
addKeywordArgumentVariants(def, ret, new HashSet<PyFunction>());
}
private static void addKeywordArgumentVariants(PyFunction def, List<Object> ret, Collection<PyFunction> visited) {
if (visited.contains(def)) {
return;
}
visited.add(def);
final Set<PyFunction.Flag> flags = def.getContainingClass() != null ? PyUtil.detectDecorationsAndWrappersOf(def) : null;
final KwArgParameterCollector collector = new KwArgParameterCollector(flags, ret);
def.getParameterList().acceptChildren(collector);
if (collector.hasKwArgs()) {
KwArgFromStatementCallCollector fromStatementCallCollector = new KwArgFromStatementCallCollector(ret, collector.getKwArgs());
def.getStatementList().acceptChildren(fromStatementCallCollector);
//if (collector.hasOnlySelfAndKwArgs()) {
// nothing interesting besides self and **kwargs, let's look at superclass (PY-778)
if (fromStatementCallCollector.isKwArgsTransit()) {
final PsiElement superMethod = PySuperMethodsSearch.search(def).findFirst();
if (superMethod instanceof PyFunction) {
addKeywordArgumentVariants((PyFunction)superMethod, ret, visited);
}
}
}
//}
}
private static class KwArgParameterCollector extends PyElementVisitor {
private int myCount;
private final Set<PyFunction.Flag> myFlags;
private final List<Object> myRet;
private boolean myHasSelf = false;
private boolean myHasKwArgs = false;
private PyParameter kwArgsParam = null;
public KwArgParameterCollector(Set<PyFunction.Flag> flags, List<Object> ret) {
myFlags = flags;
myRet = ret;
}
@Override
public void visitPyParameter(PyParameter par) {
myCount++;
if (myCount == 1 && myFlags != null && !myFlags.contains(PyFunction.Flag.STATICMETHOD)) {
myHasSelf = true;
return;
}
PyNamedParameter namedParam = par.getAsNamed();
if (namedParam != null) {
if (!namedParam.isKeywordContainer() && !namedParam.isPositionalContainer()) {
final LookupElement item = PyUtil.createNamedParameterLookup(namedParam.getName());
myRet.add(item);
}
else if (namedParam.isKeywordContainer()) {
myHasKwArgs = true;
kwArgsParam = namedParam;
}
}
else {
PyTupleParameter nestedTupleParam = par.getAsTuple();
if (nestedTupleParam != null) {
nestedTupleParam.acceptChildren(this);
}
// else it's a lone star parameter, it can't contribute to completion
}
}
public PyParameter getKwArgs() {
return kwArgsParam;
}
public boolean hasKwArgs() {
return myHasKwArgs;
}
public boolean hasOnlySelfAndKwArgs() {
return myCount == 2 && myHasSelf && myHasKwArgs;
}
}
private static class KwArgFromStatementCallCollector extends PyElementVisitor {
private final List<Object> myRet;
private final PyParameter myKwArgs;
private boolean kwArgsTransit = true;
public KwArgFromStatementCallCollector(List<Object> ret, @NotNull PyParameter kwArgs) {
myRet = ret;
this.myKwArgs = kwArgs;
}
@Override
public void visitPyElement(PyElement node) {
node.acceptChildren(this);
}
@Override
public void visitPySubscriptionExpression(PySubscriptionExpression node) {
String operandName = node.getOperand().getName();
processGet(operandName, node.getIndexExpression());
}
@Override
public void visitPyCallExpression(PyCallExpression node) {
if (node.isCalleeText("pop", "get", "getattr")) {
PyReferenceExpression child = PsiTreeUtil.getChildOfType(node.getCallee(), PyReferenceExpression.class);
if (child != null) {
String operandName = child.getName();
if (node.getArguments().length > 0) {
PyExpression argument = node.getArguments()[0];
processGet(operandName, argument);
}
}
}
else if (node.isCalleeText("__init__")) {
kwArgsTransit = false;
for (PyExpression e : node.getArguments()) {
if (e instanceof PyStarArgument) {
PyStarArgument kw = (PyStarArgument)e;
if (Comparing.equal(myKwArgs.getName(), kw.getFirstChild().getNextSibling().getText())) {
kwArgsTransit = true;
break;
}
}
}
}
super.visitPyCallExpression(node);
}
private void processGet(String operandName, PyExpression argument) {
if (Comparing.equal(myKwArgs.getName(), operandName) &&
argument instanceof PyStringLiteralExpression) {
String name = ((PyStringLiteralExpression)argument).getStringValue();
if (PyUtil.isPythonIdentifier(name)) {
myRet.add(PyUtil.createNamedParameterLookup(name));
}
}
}
/**
* is name of kwargs parameter the same as transmitted to __init__ call
* @return
*/
public boolean isKwArgsTransit() {
return kwArgsTransit;
}
}
public boolean isSoft() {
return false;
}
@@ -1,5 +1,6 @@
package com.jetbrains.python.psi.resolve;
import com.google.common.collect.Sets;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
@@ -23,9 +24,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.AS_MODULE;
import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.AS_NAME;
import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.NONE;
import static com.jetbrains.python.psi.resolve.ResolveImportUtil.PointInImport.ROLE.*;
/**
* @author dcheryasov
@@ -96,7 +95,7 @@ public class ResolveImportUtil {
for (PsiElement element : psiElements) {
final PsiElement init = PyUtil.turnDirIntoInit(element);
if (init instanceof PsiFile) {
VirtualFile vFile = ((PsiFile) init).getVirtualFile();
VirtualFile vFile = ((PsiFile)init).getVirtualFile();
if (vFile != null && vFile.getLength() > 0) {
return element;
}
@@ -299,6 +298,32 @@ public class ResolveImportUtil {
return visitor.results;
}
@NotNull
public static List<PsiElement> resolveModulesInRoots(@NotNull Module module, @NotNull PyQualifiedName moduleQualifiedName) {
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);
visitRoots(module, visitor);
cache.put(moduleQualifiedName, visitor.results);
return visitor.results;
}
@NotNull
public static List<PsiElement> resolveModulesInRootProvider(@NotNull RootProvider rootProvider,
@NotNull Module module,
@NotNull PyQualifiedName moduleQualifiedName) {
ResolveInRootVisitor visitor = new ResolveInRootVisitor(moduleQualifiedName, PsiManager.getInstance(module.getProject()), null);
if (!visitModuleContentEntries(module, visitor)) {
for (VirtualFile file : rootProvider.getFiles(OrderRootType.CLASSES)) {
visitor.visitRoot(file);
}
}
return visitor.results;
}
// TODO: rewrite using resolveImportReference
/**
@@ -375,7 +400,6 @@ public class ResolveImportUtil {
}
else {
visitSdkRoots(elt, visitor);
}
}
@@ -395,26 +419,36 @@ 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);
// look in module sources
boolean sourceEntriesMissing = true;
Set<VirtualFile> contentRoots = new java.util.HashSet<VirtualFile>();
Set<VirtualFile> contentRoots = Sets.newHashSet();
for (ContentEntry entry : rootManager.getContentEntries()) {
VirtualFile rootFile = entry.getFile();
if (rootFile != null && !visitor.visitRoot(rootFile)) return;
if (rootFile != null && !visitor.visitRoot(rootFile)) return true;
contentRoots.add(rootFile);
for (VirtualFile folder : entry.getSourceFolderFiles()) {
sourceEntriesMissing = false;
if (!visitor.visitRoot(folder)) return;
if (!visitor.visitRoot(folder)) return true;
}
}
if (sourceEntriesMissing) {
// fallback for a case without any source entries: use project root
VirtualFile projectRoot = module.getProject().getBaseDir();
if (projectRoot != null && !contentRoots.contains(projectRoot) && !visitor.visitRoot(projectRoot)) return;
if (projectRoot != null && !contentRoots.contains(projectRoot) && !visitor.visitRoot(projectRoot)) return true;
}
// else look in SDK roots
return false;
}
private static void visitModuleSdkRoots(@NotNull RootVisitor visitor, @NotNull Module module) {
ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
rootManager.orderEntries().process(new SdkRootVisitingPolicy(visitor), null);
}
@@ -478,22 +512,22 @@ public class ResolveImportUtil {
}
static class ResolveInRootVisitor implements RootVisitor {
final PsiFile foothold_file;
final PsiFile myFootholdFile;
final @NotNull PyQualifiedName qualifiedName;
final @NotNull PsiManager psiManager;
final List<PsiElement> results = new ArrayList<PsiElement>();
public ResolveInRootVisitor(@NotNull PyQualifiedName qName, @NotNull PsiManager psiManager, PsiFile foothold_file) {
public ResolveInRootVisitor(@NotNull PyQualifiedName qName, @NotNull PsiManager psiManager, @Nullable PsiFile foothold_file) {
this.qualifiedName = qName;
this.psiManager = psiManager;
this.foothold_file = foothold_file;
myFootholdFile = foothold_file;
}
public boolean visitRoot(final VirtualFile root) {
if (!root.isValid()) {
return true;
}
PsiElement module = resolveInRoot(root, qualifiedName, psiManager, foothold_file);
PsiElement module = resolveInRoot(root, qualifiedName, psiManager, myFootholdFile);
if (module != null) {
results.add(module);
}
@@ -502,7 +536,10 @@ public class ResolveImportUtil {
}
@Nullable
private static PsiElement resolveInRoot(VirtualFile root, PyQualifiedName qualifiedName, PsiManager psiManager, PsiFile foothold_file) {
private static PsiElement resolveInRoot(VirtualFile root,
PyQualifiedName qualifiedName,
PsiManager psiManager,
@Nullable PsiFile foothold_file) {
PsiElement module = root.isDirectory() ? psiManager.findDirectory(root) : psiManager.findFile(root);
for (String component : qualifiedName.getComponents()) {
if (component == null) {
@@ -530,7 +567,7 @@ public class ResolveImportUtil {
*/
@Nullable
public static PsiElement resolveChild(@Nullable final PsiElement parent, @NotNull final String referencedName,
final PsiFile containingFile, @Nullable VirtualFile root, boolean fileOnly) {
@Nullable final PsiFile containingFile, @Nullable VirtualFile root, boolean fileOnly) {
PsiDirectory dir = null;
PsiElement ret = null;
PsiElement possible_ret = null;
@@ -569,7 +606,7 @@ public class ResolveImportUtil {
}
@Nullable
private static PsiElement resolveInDirectory(final String referencedName, final PsiFile containingFile,
private static PsiElement resolveInDirectory(final String referencedName, @Nullable final PsiFile containingFile,
final PsiDirectory dir, @Nullable VirtualFile root, boolean isFileOnly) {
if (referencedName == null) return null;
final PsiElement module = findModuleInDir(dir, referencedName);
@@ -635,7 +672,8 @@ public class ResolveImportUtil {
}
VirtualFile skeletonsRoot = findSkeletonsRoot(dir);
if (skeletonsRoot != null && relativeName != null) {
VirtualFile skeletonsVFile = relativeName.length() == 0 ? skeletonsRoot : skeletonsRoot.findFileByRelativePath(relativeName.replace(".", "/"));
VirtualFile skeletonsVFile =
relativeName.length() == 0 ? skeletonsRoot : skeletonsRoot.findFileByRelativePath(relativeName.replace(".", "/"));
if (skeletonsVFile != null) {
return dir.getManager().findDirectory(skeletonsVFile);
}
@@ -675,7 +713,7 @@ public class ResolveImportUtil {
List<String> result = StringUtil.split(relativePath, "/");
if (myResult == null || result.size() < myResult.size()) {
if (result.size() > 0) {
result.set(result.size()-1, FileUtil.getNameWithoutExtension(result.get(result.size()-1)));
result.set(result.size() - 1, FileUtil.getNameWithoutExtension(result.get(result.size() - 1)));
}
myResult = result;
}
@@ -750,8 +788,9 @@ public class ResolveImportUtil {
/**
* When a name is imported from a module, tries to find the definition of that name inside the module,
* as opposed to looking for submodules.
*
* @param where an element related to the name, presumably inside import
* @param name the name to find
* @param name the name to find
* @return found element, or null.
*/
@Nullable
@@ -815,7 +854,6 @@ public class ResolveImportUtil {
*/
AS_NAME
}
}
/**
@@ -96,7 +96,7 @@ public class VariantsProcessor implements PsiScopeProcessor {
PyReferenceExpression expr = (PyReferenceExpression)element;
String referencedName = expr.getReferencedName();
if (nameIsAcceptable(referencedName)) {
myVariants.put(referencedName, setupItem(LookupElementBuilder.create(referencedName)));
myVariants.put(referencedName, setupItem(LookupElementBuilder.create(expr, referencedName)));
}
}
else if (element instanceof NameDefiner) {
@@ -123,7 +123,7 @@ public class VariantsProcessor implements PsiScopeProcessor {
// things like PyTargetExpression cannot have a general icon, but here we only have variables
if (icon == null) icon = Icons.VARIABLE_ICON;
if (referencedName != null && nameIsAcceptable(referencedName)) {
LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(referencedName).setIcon(icon));
LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(expr, referencedName).setIcon(icon));
if (definer instanceof PyImportElement) { // set notice to imported module name if needed
PsiElement maybeFromImport = definer.getParent();
if (maybeFromImport instanceof PyFromImportStatement) {
@@ -49,7 +49,7 @@ public class PyClassNameIndex extends StringStubIndexExtension<PyClass> {
* @return the resulting scope
*/
public static GlobalSearchScope projectWithLibrariesScope(Project project) {
final Sdk sdk = ProjectRootManager.getInstance(project).getProjectJdk();
final Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk();
// TODO cache the scope in project userdata (update when SDK paths change or different project SDK is selected)
if (sdk != null && sdk.getSdkType() instanceof PythonSdkType) {
VirtualFile libDir = findLibDir(sdk.getRootProvider().getFiles(OrderRootType.CLASSES));
@@ -8,6 +8,7 @@ import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.TextComponentAccessor;
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel;
@@ -69,9 +70,9 @@ public class PyExtractSuperclassDialog extends UpDirectedMembersMovingDialog {
}
boolean found_root = false;
try {
String target_dir = new File(myTargetDirField.getText()).getCanonicalPath();
String target_dir = FileUtil.toSystemIndependentName(new File(myTargetDirField.getText()).getCanonicalPath());
for (VirtualFile file : ProjectRootManager.getInstance(myClass.getProject()).getContentRoots()) {
if (target_dir.startsWith(file.getPath())) {
if (StringUtil.startsWithIgnoreCase(target_dir, file.getPath())) {
found_root = true;
break;
}
@@ -1,5 +1,6 @@
package com.jetbrains.python.run;
import com.google.common.collect.Maps;
import com.intellij.execution.configuration.EnvironmentVariablesComponent;
import com.intellij.execution.configurations.*;
import com.intellij.openapi.module.Module;
@@ -33,7 +34,7 @@ public abstract class AbstractPythonRunConfiguration extends ModuleBasedConfigur
private String myWorkingDirectory = "";
private String mySdkHome = "";
private boolean myPassParentEnvs = true;
private Map<String, String> myEnvs = new HashMap<String, String>();
private Map<String, String> myEnvs = Maps.newHashMap();
private boolean myUseModuleSdk;
public AbstractPythonRunConfiguration(final String name, final RunConfigurationModule module, final ConfigurationFactory factory) {
@@ -65,7 +66,7 @@ public abstract class AbstractPythonRunConfiguration extends ModuleBasedConfigur
else {
if (!myUseModuleSdk) {
if (StringUtil.isEmptyOrSpaces(getSdkHome())) {
final Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectJdk();
final Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectSdk();
if (projectSdk == null || !(projectSdk.getSdkType() instanceof PythonSdkType)) {
throw new RuntimeConfigurationError(PyBundle.message("runcfg.unittest.no_sdk"));
}
@@ -1,5 +1,6 @@
package com.jetbrains.python.run;
import com.google.common.collect.Lists;
import com.intellij.execution.DefaultExecutionResult;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -17,9 +18,14 @@ import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashMap;
import com.jetbrains.python.sdk.PythonEnvUtil;
import com.jetbrains.python.sdk.PythonSdkFlavor;
import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -61,12 +67,13 @@ public abstract class PythonCommandLineState extends CommandLineState {
}
@NotNull
protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor) throws ExecutionException {
protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor)
throws ExecutionException {
final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project);
for (Filter filter : myFilters) {
consoleBuilder.addFilter(filter);
}
final ConsoleView consoleView = consoleBuilder.getConsole();
consoleView.attachToProcess(processHandler);
return consoleView;
@@ -78,6 +85,7 @@ public abstract class PythonCommandLineState extends CommandLineState {
/**
* Patches the command line parameters applying patchers from first to last, and then runs it.
*
* @param patchers any number of patchers; any patcher may be null, and the whole argument may be null.
* @return handler of the started process
* @throws ExecutionException
@@ -93,7 +101,7 @@ public abstract class PythonCommandLineState extends CommandLineState {
public GeneralCommandLine generateCommandLine(CommandLinePatcher[] patchers) throws ExecutionException {
GeneralCommandLine commandLine = generateCommandLine();
if (patchers != null) {
for (CommandLinePatcher patcher: patchers) {
for (CommandLinePatcher patcher : patchers) {
if (patcher != null) patcher.patchCommandLine(commandLine);
}
}
@@ -121,7 +129,8 @@ public abstract class PythonCommandLineState extends CommandLineState {
/**
* Creates a number of parameter groups in the command line:
* GROUP_EXE_OPTIONS, GROUP_DEBUGGER, GROUP_SCRIPT.
* These are necessary for command line patchers to work properly.
* These are necessary for command line patchers to work properly.
*
* @param commandLine
*/
public static void createStandardGroupsIn(GeneralCommandLine commandLine) {
@@ -133,10 +142,12 @@ public abstract class PythonCommandLineState extends CommandLineState {
protected void initEnvironment(GeneralCommandLine commandLine) {
Map<String, String> envs = myConfig.getEnvs();
if (envs == null)
if (envs == null) {
envs = new HashMap<String, String>();
else
}
else {
envs = new HashMap<String, String>(envs);
}
addPredefinedEnvironmentVariables(envs, myConfig.isPassParentEnvs());
addCommonEnvironmentVariables(envs);
@@ -154,6 +165,14 @@ public abstract class PythonCommandLineState extends CommandLineState {
if (flavor != null) {
flavor.addPredefinedEnvironmentVariables(envs);
}
Sdk pythonSdk = PythonSdkType.findSdkByPath(myConfig.getSdkHome());
VirtualFile[] paths = pythonSdk.getRootProvider().getFiles(OrderRootType.CLASSES);
List<String> pathList = Lists.newArrayList();
for (VirtualFile file : paths) {
pathList.add(FileUtil.toSystemDependentName(file.getPath()));
}
PythonSdkFlavor.initPythonPath(envs, passParentEnvs, pathList);
}
protected void setRunnerPath(GeneralCommandLine commandLine) throws ExecutionException {
@@ -0,0 +1,107 @@
package com.jetbrains.python.sdk;
import com.google.common.collect.Sets;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.projectRoots.SdkAdditionalData;
import com.intellij.openapi.projectRoots.SdkModel;
import com.intellij.openapi.vfs.VirtualFile;
import com.jetbrains.django.util.VirtualFileUtil;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
/**
* @author traff
*/
public class PythonSdkAdditionalData implements SdkAdditionalData {
@NonNls private static final String PATHS_ADDED_BY_USER_ROOT = "PATHS_ADDED_BY_USER_ROOT";
@NonNls private static final String PATH_ADDED_BY_USER = "PATH_ADDED_BY_USER";
@NonNls private static final String PATHS_REMOVED_BY_USER_ROOT = "PATHS_REMOVED_BY_USER_ROOT";
@NonNls private static final String PATH_REMOVED_BY_USER = "PATH_REMOVED_BY_USER";
private Set<VirtualFile> myAddedPaths = Sets.newHashSet();
private Set<VirtualFile> myExcludedPaths = Sets.newHashSet();
public Object clone() throws CloneNotSupportedException {
try {
final PythonSdkAdditionalData copy = (PythonSdkAdditionalData)super.clone();
copy.setAddedPaths(getAddedPaths());
copy.setExcludedPaths(getExcludedPaths());
return copy;
}
catch (CloneNotSupportedException e) {
return null;
}
}
public Set<VirtualFile> getAddedPaths() {
return myAddedPaths;
}
public void setAddedPaths(Set<VirtualFile> addedPaths) {
myAddedPaths = Sets.newHashSet(addedPaths);
}
public Set<VirtualFile> getExcludedPaths() {
return myExcludedPaths;
}
public void setExcludedPaths(Set<VirtualFile> excludedPaths) {
myExcludedPaths = Sets.newHashSet(excludedPaths);
}
@Override
public void checkValid(SdkModel sdkModel) throws ConfigurationException {
}
public void save(@NotNull final Element rootElement) {
for (VirtualFile addedPath : myAddedPaths) {
final Element child = new Element(PATHS_ADDED_BY_USER_ROOT);
child.setAttribute(PATH_ADDED_BY_USER, addedPath.getPath());
rootElement.addContent(child);
}
for (VirtualFile removed : myExcludedPaths) {
final Element child = new Element(PATHS_REMOVED_BY_USER_ROOT);
child.setAttribute(PATH_REMOVED_BY_USER, removed.getPath());
rootElement.addContent(child);
}
}
@NotNull
public static PythonSdkAdditionalData load(@Nullable Element element) {
final PythonSdkAdditionalData data = new PythonSdkAdditionalData();
data.setAddedPaths(loadStringList(element, PATHS_ADDED_BY_USER_ROOT, PATH_ADDED_BY_USER));
data.setExcludedPaths(loadStringList(element, PATHS_REMOVED_BY_USER_ROOT, PATH_REMOVED_BY_USER));
return data;
}
private static Set<VirtualFile> loadStringList(Element element, String rootName, String attrName) {
final List<String> paths = new LinkedList<String>();
if (element != null) {
final List list = element.getChildren(rootName);
if (list != null) {
for (Object o : list) {
paths.add(((Element)o).getAttribute(attrName).getValue());
}
}
}
final Set<VirtualFile> files = Sets.newHashSet();
for (String path : paths) {
VirtualFile vf = VirtualFileUtil.findFile(path);
if (vf != null) {
files.add(vf);
}
}
return files;
}
}
@@ -4,6 +4,7 @@ import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.process.ProcessOutput;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import org.jetbrains.annotations.Nullable;
import java.io.File;
@@ -22,6 +23,14 @@ public abstract class PythonSdkFlavor {
return pythonPath;
}
public static void initPythonPath(Map<String, String> envs, boolean passParentEnvs, List<String> pythonPathList) {
String pythonPath = StringUtil.join(pythonPathList, File.pathSeparator);
if (passParentEnvs && !envs.containsKey(PYTHONPATH)) {
pythonPath = appendSystemPythonPath(pythonPath);
}
addToPythonPath(envs, pythonPath);
}
public Collection<String> suggestHomePaths() {
return Collections.emptyList();
}
@@ -78,6 +78,12 @@ public class PythonSdkType extends SdkType {
return PythonFileType.INSTANCE.getIcon();
}
@NotNull
@Override
public String getHelpTopic() {
return "reference.project.structure.sdk.python";
}
public Icon getIconForAddAction() {
return PythonFileType.INSTANCE.getIcon();
}
@@ -281,6 +287,9 @@ public class PythonSdkType extends SdkType {
}
public void saveAdditionalData(final SdkAdditionalData additionalData, final Element additional) {
if (additionalData instanceof PythonSdkAdditionalData ) {
((PythonSdkAdditionalData)additionalData).save(additional);
}
}
@Override
@@ -315,7 +324,7 @@ public class PythonSdkType extends SdkType {
// Don't fix skeletons here, PythonSdkUpdater will take care of that (see PY-1226 - no progress will be displayed if skeletons
// generation is invoked from here
return null;
return PythonSdkAdditionalData.load(additional);
}
private boolean switchPathToInterpreter(Sdk currentSdk, String... variants) {
@@ -396,7 +405,7 @@ public class PythonSdkType extends SdkType {
final ProgressManager progman = ProgressManager.getInstance();
final Ref<Boolean> success = new Ref<Boolean>();
success.set(true);
final Task.Modal setup_task = new Task.Modal(project, "Setting up library files for " + sdk.getName(), false) {
final Task.Modal setupTask = new Task.Modal(project, "Setting up library files for " + sdk.getName(), false) {
public void run(@NotNull final ProgressIndicator indicator) {
try {
@@ -412,7 +421,7 @@ public class PythonSdkType extends SdkType {
}
}
};
progman.run(setup_task);
progman.run(setupTask);
return success.get();
}
@@ -28,4 +28,9 @@ public class PyStructureViewModel extends StructureViewModelBase implements Stru
public boolean isAlwaysLeaf(StructureViewTreeElement element) {
return element.getValue() instanceof PyTargetExpression;
}
@Override
public boolean shouldEnterElement(Object element) {
return element instanceof PyClass;
}
}
@@ -56,7 +56,11 @@ public class PythonUnitTestCommandLineState extends PythonTestCommandLineStateBa
specs.add(myConfig.getScriptName() + "::" + myConfig.getClassName() + "::" + myConfig.getMethodName());
break;
case TEST_FOLDER:
specs.add(myConfig.getFolderName() + "/");
if (!myConfig.getPattern().isEmpty())
specs.add(myConfig.getFolderName() + "/" + ";" + myConfig.getPattern() + "$");
else
specs.add(myConfig.getFolderName() + "/");
// TODO[kate]:think about delimiter between folderName and Pattern
break;
default:
throw new IllegalArgumentException("Unknown test type: " + myConfig.getTestType());
@@ -25,6 +25,7 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati
private String myScriptName = "";
private String myMethodName = "";
private String myFolderName = "";
private String myPattern = ""; // pattern for modules in folder to match against
private TestType myTestType = TestType.TEST_SCRIPT;
protected PythonUnitTestRunConfiguration(RunConfigurationModule module, ConfigurationFactory configurationFactory, String name) {
@@ -42,6 +43,7 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati
myClassName = JDOMExternalizerUtil.readField(element, "CLASS_NAME");
myMethodName = JDOMExternalizerUtil.readField(element, "METHOD_NAME");
myFolderName = JDOMExternalizerUtil.readField(element, "FOLDER_NAME");
myPattern = JDOMExternalizerUtil.readField(element, "PATTERN");
try {
myTestType = TestType.valueOf(JDOMExternalizerUtil.readField(element, "TEST_TYPE"));
@@ -54,10 +56,12 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati
@Override
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
JDOMExternalizerUtil.writeField(element, "SCRIPT_NAME", myScriptName);
JDOMExternalizerUtil.writeField(element, "CLASS_NAME", myClassName);
JDOMExternalizerUtil.writeField(element, "METHOD_NAME", myMethodName);
JDOMExternalizerUtil.writeField(element, "FOLDER_NAME", myFolderName);
JDOMExternalizerUtil.writeField(element, "PATTERN", myPattern);
JDOMExternalizerUtil.writeField(element, "TEST_TYPE", myTestType.toString());
}
@@ -77,6 +81,14 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati
myClassName = className;
}
public String getPattern() {
return myPattern;
}
public void setPattern(String pattern) {
myPattern = pattern;
}
public String getFolderName() {
return myFolderName;
}
@@ -188,5 +200,6 @@ public class PythonUnitTestRunConfiguration extends AbstractPythonRunConfigurati
target.setFolderName(source.getFolderName());
target.setMethodName(source.getMethodName());
target.setTestType(source.getTestType());
target.setPattern(source.getPattern());
}
}
@@ -8,7 +8,7 @@
<properties/>
<border type="none"/>
<children>
<grid id="ad5c8" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="ad5c8" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="5" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
@@ -18,7 +18,7 @@
<children>
<component id="59c0c" class="com.intellij.openapi.ui.LabeledComponent" binding="myTestClassComponent" custom-create="true">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="com/jetbrains/python/PyBundle" key="runcfg.unittest.dlg.class_label"/>
@@ -26,7 +26,7 @@
</component>
<component id="45ace" class="com.intellij.openapi.ui.LabeledComponent" binding="myTestMethodComponent" custom-create="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="com/jetbrains/python/PyBundle" key="runcfg.unittest.dlg.method_label"/>
@@ -42,12 +42,20 @@
</component>
<component id="3da8f" class="com.intellij.openapi.ui.LabeledComponent" binding="myTestScriptComponent" custom-create="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="com/jetbrains/python/PyBundle" key="runcfg.unittest.dlg.test_script_label"/>
</properties>
</component>
<component id="11ef2" class="com.intellij.openapi.ui.LabeledComponent" binding="myPatternComponent" custom-create="true">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="com/jetbrains/python/PyBundle" key="runcfg.unittest.dlg.pattern"/>
</properties>
</component>
</children>
</grid>
<grid id="b1281" layout-manager="GridLayoutManager" row-count="1" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
@@ -30,11 +30,13 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf
private JRadioButton myTestClassRB;
private JRadioButton myTestMethodRB;
private JPanel myCommonOptionsPlaceholder;
private LabeledComponent myPatternComponent;
private TextFieldWithBrowseButton myTestFolderTextField;
private TextFieldWithBrowseButton myTestScriptTextField;
private JTextField myTestMethodTextField;
private JTextField myTestClassTextField;
private JTextField myPatternTextField;
private final Project myProject;
private final AbstractPyCommonOptionsForm myCommonOptionsForm;
@@ -74,6 +76,14 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf
myTestClassTextField.setText(className);
}
public String getPattern() {
return myPatternTextField.getText().trim();
}
public void setPattern(String pattern) {
myPatternTextField.setText(pattern);
}
public String getFolderName() {
return toSystemIndependentName(myTestFolderTextField.getText().trim());
}
@@ -129,6 +139,7 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf
myTestScriptComponent.setEnabled(testType != TestType.TEST_FOLDER);
myTestClassComponent.setEnabled(testType == TestType.TEST_CLASS || testType == TestType.TEST_METHOD);
myTestMethodComponent.setEnabled(testType == TestType.TEST_METHOD);
myPatternComponent.setEnabled(testType == TestType.TEST_FOLDER);
}
public JComponent getPanel() {
@@ -182,6 +193,7 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf
private void createUIComponents() {
myTestClassComponent = createTestClassComponent();
myTestMethodComponent = createTestMethodComponent();
myPatternComponent = createPatternComponent();
final Ref<TextFieldWithBrowseButton> testsFolderTextFieldWrapper = new Ref<TextFieldWithBrowseButton>();
myTestFolderComponent = createTestFolderComponent(testsFolderTextFieldWrapper);
@@ -195,6 +207,16 @@ public class PythonUnitTestRunConfigurationForm implements PythonUnitTestRunConf
title = PyBundle.message("runcfg.unittest.dlg.select.script.path");
PythonRunConfigurationFormUtil.addFileChooser(title, myTestScriptTextField, myProject);
}
private LabeledComponent createPatternComponent() {
myPatternTextField = new JTextField();
LabeledComponent<JTextField> myComponent = new LabeledComponent<JTextField>();
myComponent.setComponent(myPatternTextField);
myComponent.setText(PyBundle.message("runcfg.unittest.dlg.pattern"));
return myComponent;
}
}
@@ -22,4 +22,8 @@ public interface PythonUnitTestRunConfigurationParams {
PythonUnitTestRunConfiguration.TestType getTestType();
void setTestType(PythonUnitTestRunConfiguration.TestType testType);
String getPattern();
void setPattern(String pattern);
}
@@ -0,0 +1,17 @@
foo()
<begin>
for i in range(l):
if foo:
if tag is None:
if bar:
do
else:
if baz:
raise ValueError(i)
else:
bzzzz
<end>
bar()
<result>
In:
Out:
@@ -2,13 +2,12 @@ class Foo:
def foo(self):
print("a")
'''
this is boo
very long boo
'''
def boo(self):
print "rrrrr"
class Boo(Foo):
pass
'''
this is boo
very long boo
'''
@@ -146,6 +146,10 @@ public class PyEditingTest extends PyLightFixtureTestCase {
doTestEnter("a = some_list[<caret>slice_start:slice_end]", "a = some_list[\n slice_start:slice_end]");
}
public void testEnterInSubscriptionExpression() { // PY-1992
doTestEnter("a = some_list[<caret>slice_start]", "a = some_list[\n slice_start]");
}
private void doTestEnter(String before, final String after) {
int pos = before.indexOf("<caret>");
before = before.replace("<caret>", "");
@@ -12,12 +12,7 @@ public class PyIndentTest extends PyLightFixtureTestCase {
private void doTest(final String before, String after) {
final String name = getTestName(false);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFixture.configureByText(name + ".py", before);
}
});
myFixture.configureByText(name + ".py", before);
CommandProcessor.getInstance().executeCommand(myFixture.getProject(), new Runnable() {
@Override
public void run() {
@@ -107,12 +107,7 @@ public class PyTypeTest extends PyLightFixtureTestCase {
}
private PyType doTest(final String text) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFixture.configureByText(PythonFileType.INSTANCE, text);
}
});
myFixture.configureByText(PythonFileType.INSTANCE, text);
PyExpression expr = myFixture.findElementByText("expr", PyExpression.class);
return expr.getType(TypeEvalContext.slow());
}
@@ -196,12 +196,7 @@ public class PythonCompletionTest extends PyLightFixtureTestCase {
}
public void testEmptyFile() { // PY-1845
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFixture.configureByText(PythonFileType.INSTANCE, "");
}
});
myFixture.configureByText(PythonFileType.INSTANCE, "");
myFixture.completeBasic();
final List<String> elements = myFixture.getLookupElementStrings();
assertTrue(elements.contains("import"));
@@ -229,4 +224,4 @@ public class PythonCompletionTest extends PyLightFixtureTestCase {
myFixture.completeBasic();
myFixture.checkResultByFile(dirname + "importedModule.after.py");
}
}
}
@@ -94,13 +94,8 @@ public abstract class LightMarkedTestCase extends PyLightFixtureTestCase {
// create a file and map marks to PSI elements
Map<String, PsiElement> result = new HashMap<String, PsiElement>();
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFile = myFixture.addFileToProject(fileName, text.toString());
myFixture.configureFromExistingVirtualFile(myFile.getVirtualFile());
}
});
myFile = myFixture.addFileToProject(fileName, text.toString());
myFixture.configureFromExistingVirtualFile(myFile.getVirtualFile());
for (Map.Entry<String, Integer> entry : offsets.entrySet()) {
result.put(entry.getKey(), myFile.findElementAt(entry.getValue()));
}
@@ -111,4 +106,4 @@ public abstract class LightMarkedTestCase extends PyLightFixtureTestCase {
String fname = getTestName(false) + ".py";
return configureByFile(fname);
}
}
}
@@ -38,12 +38,7 @@ public abstract class PyResolveTestCase extends PyLightFixtureTestCase {
assertTrue(offset >= 0);
fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length());
final String finalFileText = fileText;
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
myFixture.configureByText(new File(filePath).getName(), finalFileText);
}
});
myFixture.configureByText(new File(filePath).getName(), finalFileText);
final PsiReference reference = myFixture.getFile().findReferenceAt(offset);
return reference;
}
@@ -159,5 +159,10 @@ public class PyCodeFragmentTest extends LightMarkedTestCase {
public void testForIfReturn() throws Exception {
doTest();
}
public void testRaise2102() throws Exception {
doTest();
}
}