mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/ultimate
This commit is contained in:
@@ -108,7 +108,7 @@ def zipSources() {
|
||||
target('default': "Build artifacts") {
|
||||
|
||||
def modules = [
|
||||
"python", "python-ide", "python-py", platformApiModules(), platformImplementationModules(), pluginFilter
|
||||
"python", "python-ide", platformApiModules(), platformImplementationModules(), pluginFilter
|
||||
].flatten()
|
||||
|
||||
loadProject()
|
||||
@@ -343,7 +343,7 @@ def buildTarGz() {
|
||||
|
||||
def layoutFull(String target, Set usedJars) {
|
||||
def openapiModules = platformApiModules()
|
||||
def implementationModules = [platformImplementationModules(), "python", "python-ide", "python-py", "sass"].flatten()
|
||||
def implementationModules = [platformImplementationModules(), "python", "python-ide", "sass"].flatten()
|
||||
|
||||
layout(target) {
|
||||
dir("lib") {
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
<dir name="lib">
|
||||
<jar name="python.jar">
|
||||
<module name="python"> <patternset refid="resources.excluded"/> </module>
|
||||
<module name="python-py">
|
||||
<patternset refid="classes.excluded"/>
|
||||
</module>
|
||||
<module name="python-plugin"/>
|
||||
</jar>
|
||||
<jar name="resources_en.jar">
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/pySrc">
|
||||
<sourceFolder url="file://$MODULE_DIR$/pySrc" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="python" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -152,22 +152,25 @@
|
||||
order="last, before default"/>
|
||||
<readWriteAccessDetector implementation="com.jetbrains.python.findUsages.PyReadWriteAccessDetector"/>
|
||||
|
||||
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.RenamePyFunctionProcessor" order="last" />
|
||||
<renamePsiElementProcessor implementation="com.jetbrains.python.refactoring.RenamePyFunctionProcessor" order="last"/>
|
||||
|
||||
<lang.importOptimizer language="Python" implementationClass="com.jetbrains.python.codeInsight.PyImportOptimizer"/>
|
||||
|
||||
<codeStyleSettingsProvider implementation="com.jetbrains.python.formatter.PyCodeStyleSettingsProvider"/>
|
||||
<langCodeStyleSettingsProvider implementation="com.jetbrains.python.configuration.PyLanguageCodeStyleSettingsProvider"/>
|
||||
|
||||
<lang.elementManipulator forClass="com.jetbrains.python.psi.PyStringLiteralExpression"
|
||||
implementationClass="com.jetbrains.python.psi.impl.PyStringLiteralExpressionManipulator"/>
|
||||
|
||||
<!-- Django -->
|
||||
<codeInsight.lineMarkerProvider language="Python" implementationClass="com.jetbrains.django.annotator.ViewMethodLineMarkerProvider"/>
|
||||
<configurationType implementation="com.jetbrains.django.run.DjangoServerRunConfigurationType"/>
|
||||
<configurationType implementation="com.jetbrains.django.testRunner.DjangoTestsConfigurationType"/>
|
||||
<configurationProducer implementation="com.jetbrains.django.testRunner.DjangoTestsConfigurationProducer"/>
|
||||
|
||||
<lang.substitutor language="XHTML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageProvider"/>
|
||||
<lang.substitutor language="HTML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageProvider"/>
|
||||
<lang.substitutor language="XML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageProvider"/>
|
||||
<lang.substitutor language="XHTML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageSubstitutor"/>
|
||||
<lang.substitutor language="HTML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageSubstitutor"/>
|
||||
<lang.substitutor language="XML" implementationClass="com.jetbrains.django.lang.template.DjangoTemplateLanguageSubstitutor"/>
|
||||
<highlightErrorFilter implementation="com.jetbrains.django.inspection.DjangoErrorFilter"/>
|
||||
|
||||
<lang.parserDefinition language="DjangoTemplate"
|
||||
@@ -202,33 +205,44 @@
|
||||
<colorSettingsPage implementation="com.jetbrains.django.lang.template.highlighting.DjangoTemplateColorsPage"/>
|
||||
|
||||
<lang.commenter language="DjangoTemplate" implementationClass="com.jetbrains.django.editor.DjangoTemplateCommenter"/>
|
||||
|
||||
|
||||
<basicWordSelectionFilter implementation="com.jetbrains.django.editor.DjangoTemplateWordSelectionFilter"/>
|
||||
<extendWordSelectionHandler implementation="com.jetbrains.django.editor.DjangoTemplateTagSelectionHandler"/>
|
||||
<extendWordSelectionHandler implementation="com.jetbrains.django.editor.DjangoTemplateTagNameSelectionHandler"/>
|
||||
|
||||
<lang.namesValidator language="DjangoTemplate" implementationClass="com.jetbrains.django.inspection.DjangoTemplateNamesValidator"/>
|
||||
|
||||
<renamePsiElementProcessor implementation="com.jetbrains.django.refactoring.RenameDjangoNamedExpressionProcessor" order="last" />
|
||||
<renamePsiElementProcessor implementation="com.jetbrains.django.refactoring.RenameDjangoNamedExpressionProcessor" order="last"/>
|
||||
|
||||
<projectService serviceInterface="com.jetbrains.django.model.DjangoElementGenerator"
|
||||
serviceImplementation="com.jetbrains.django.model.DjangoElementGenerator"/>
|
||||
|
||||
<lang.refactoringSupport language="DjangoTemplate" implementationClass="com.jetbrains.django.refactoring.DjangoRefactoringProvider"/>
|
||||
|
||||
<lang.surroundDescriptor language="DjangoTemplate" implementationClass="com.jetbrains.django.surround.DjangoTemplateSurroundDescriptor" order="first"/>
|
||||
<lang.surroundDescriptor language="DjangoTemplate" implementationClass="com.jetbrains.django.surround.DjangoTemplateSurroundDescriptor"
|
||||
order="first"/>
|
||||
<lang.surroundDescriptor language="HTML" implementationClass="com.jetbrains.django.surround.DjangoXmlSurroundDescriptor" order="first"/>
|
||||
<lang.surroundDescriptor language="XML" implementationClass="com.jetbrains.django.surround.DjangoXmlSurroundDescriptor" order="first"/>
|
||||
|
||||
<lang.elementManipulator forClass="com.jetbrains.django.lang.template.psi.impl.DjangoStringLiteralImpl"
|
||||
implementationClass="com.jetbrains.django.lang.template.ref.DjangoStringLiteralManipulator"/>
|
||||
|
||||
<lang.findUsagesProvider language="DjangoTemplate"
|
||||
implementationClass="com.jetbrains.django.lang.template.ref.DjangoTemplateFindUsagesProvider"/>
|
||||
|
||||
<referencesSearch implementation="com.jetbrains.django.lang.template.ref.DjangoTemplateStringReferenceSearch"/>
|
||||
|
||||
<quoteHandler fileType="DjangoTemplate" className="com.jetbrains.django.lang.template.editor.DjangoTemplateQuoteHandler"/>
|
||||
|
||||
<!-- App Engine -->
|
||||
<facetType implementation="com.jetbrains.appengine.facet.AppEngineFacetType"/>
|
||||
|
||||
<configurationType implementation="com.jetbrains.appengine.run.AppEngineServerRunConfigurationType"/>
|
||||
|
||||
<lang.parserDefinition language="GQL" implementationClass="com.jetbrains.appengine.lang.gql.parsing.GqlParserDefinition" />
|
||||
<lang.parserDefinition language="GQL" implementationClass="com.jetbrains.appengine.lang.gql.parsing.GqlParserDefinition"/>
|
||||
<multiHostInjector implementation="com.jetbrains.appengine.lang.gql.GqlLanguageInjector"/>
|
||||
<lang.syntaxHighlighterFactory key="GQL"
|
||||
implementationClass="com.jetbrains.appengine.lang.gql.highlighting.GqlHighlighterFactory"/>
|
||||
implementationClass="com.jetbrains.appengine.lang.gql.highlighting.GqlHighlighterFactory"/>
|
||||
|
||||
<completion.contributor language="Python" implementationClass="com.jetbrains.appengine.model.ModelAttributeCompletionContributor"/>
|
||||
<completion.contributor language="yaml" implementationClass="com.jetbrains.appengine.completion.AppYamlKeyCompletionContributor"/>
|
||||
@@ -248,7 +262,8 @@
|
||||
<extensionPoint qualifiedName="Pythonid.pyOverridingMethodsSearch" interface="com.intellij.util.QueryExecutor"/>
|
||||
<extensionPoint qualifiedName="Pythonid.runnableScriptFilter" interface="com.jetbrains.python.run.RunnableScriptFilter"/>
|
||||
<extensionPoint qualifiedName="Pythonid.runnableUnitTestFilter" interface="com.jetbrains.python.testing.RunnableUnitTestFilter"/>
|
||||
<extensionPoint qualifiedName="Pythonid.unresolvedReferenceQuickFixProvider" interface="com.jetbrains.python.inspections.PyUnresolvedReferenceQuickFixProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.unresolvedReferenceQuickFixProvider"
|
||||
interface="com.jetbrains.python.inspections.PyUnresolvedReferenceQuickFixProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.dumbAnnotator" interface="com.jetbrains.python.validation.PyAnnotator"/>
|
||||
</extensionPoints>
|
||||
|
||||
@@ -289,7 +304,8 @@
|
||||
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="Macros"/>
|
||||
</action>
|
||||
|
||||
<action id="Devmode.AnalyzeReturns" class="com.jetbrains.python.devmode.AnalyzeReturnsAction" text="Analyze return types" internal="true">
|
||||
<action id="Devmode.AnalyzeReturns" class="com.jetbrains.python.devmode.AnalyzeReturnsAction" text="Analyze return types"
|
||||
internal="true">
|
||||
<add-to-group group-id="ProjectViewPopupMenu" anchor="last"/>
|
||||
</action>
|
||||
|
||||
@@ -353,11 +369,11 @@
|
||||
<keyboard-shortcut keymap="Mac OS X" first-keystroke="alt R"/>
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt R"/>
|
||||
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="meta alt R" remove="true"/>
|
||||
<keyboard-shortcut keymap="visual studio" first-keystroke="ctrl alt R" remove="true"/>
|
||||
<keyboard-shortcut keymap="Visual Studio" first-keystroke="ctrl alt R" remove="true"/>
|
||||
<keyboard-shortcut keymap="Eclipse" first-keystroke="ctrl alt R" remove="true"/>
|
||||
</action>
|
||||
|
||||
<add-to-group group-id="ToolsMenu" anchor="last"/>
|
||||
</group>
|
||||
</actions>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorModificationUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -20,10 +22,14 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.source.codeStyle.Helper;
|
||||
import com.intellij.psi.impl.source.codeStyle.HelperFactory;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.net.NetUtils;
|
||||
import com.jetbrains.django.run.Runner;
|
||||
import com.jetbrains.django.util.DjangoUtil;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonHelpersLocator;
|
||||
import com.jetbrains.python.console.pydev.ICallback;
|
||||
import com.jetbrains.python.console.pydev.InterpreterResponse;
|
||||
@@ -46,6 +52,8 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory {
|
||||
private PydevConsoleCommunication myPydevConsoleCommunication;
|
||||
public static Key<PydevConsoleCommunication> CONSOLE_KEY = new Key<PydevConsoleCommunication>("PYDEV_CONSOLE_KEY");
|
||||
private static final String PYTHON_ENV_COMMAND = "import sys; print('Python %s on %s' % (sys.version, sys.platform))\n";
|
||||
private Helper myHelper;
|
||||
private int currentPythonIndentSize;
|
||||
|
||||
protected PydevConsoleRunner(@NotNull final Project project,
|
||||
@NotNull final String consoleTitle,
|
||||
@@ -54,6 +62,8 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory {
|
||||
int[] ports) {
|
||||
super(project, consoleTitle, provider, workingDir);
|
||||
myPorts = ports;
|
||||
myHelper = HelperFactory.createHelper(PythonFileType.INSTANCE, myProject);
|
||||
currentPythonIndentSize = CodeStyleSettingsManager.getSettings(myProject).getIndentSize(PythonFileType.INSTANCE);
|
||||
}
|
||||
|
||||
public static void run(@NotNull final Project project,
|
||||
@@ -198,6 +208,7 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory {
|
||||
|
||||
@Override
|
||||
public void sendInput(final String input) {
|
||||
|
||||
if (myPydevConsoleCommunication != null){
|
||||
myPydevConsoleCommunication.execInterpreter(input, new ICallback<Object, InterpreterResponse>() {
|
||||
public Object call(final InterpreterResponse interpreterResponse) {
|
||||
@@ -206,6 +217,9 @@ public class PydevConsoleRunner extends AbstractConsoleRunnerWithHistory {
|
||||
if (interpreterResponse.more){
|
||||
if (!PyConsoleHighlightingUtil.INDENT_PROMPT.equals(console.getPrompt())){
|
||||
console.setPrompt(PyConsoleHighlightingUtil.INDENT_PROMPT);
|
||||
// In this case we can insert indent automatically
|
||||
final int indent = myHelper.getIndent(input, false);
|
||||
EditorModificationUtil.insertStringAtCaret(console.getConsoleEditor(), myHelper.fillIndent(indent + currentPythonIndentSize));
|
||||
}
|
||||
} else {
|
||||
if (!PyConsoleHighlightingUtil.ORDINARY_PROMPT.equals(console.getPrompt())){
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.jetbrains.python.editor;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.SimpleTokenSetQuoteHandler;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class BaseQuoteHandler extends SimpleTokenSetQuoteHandler {
|
||||
|
||||
private final char[] ourAutoClosingChars; // we add auto-close quotes before these
|
||||
|
||||
public BaseQuoteHandler(TokenSet tokenSet, char[] autoClosingChars) {
|
||||
super(tokenSet);
|
||||
ourAutoClosingChars = autoClosingChars;
|
||||
Arrays.sort(ourAutoClosingChars);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpeningQuote(HighlighterIterator iterator, int offset) {
|
||||
// don't assume an opening quote unless we're in an explicitly "blank" context
|
||||
CharSequence text = iterator.getDocument().getCharsSequence();
|
||||
if (offset+1 >= text.length() || Arrays.binarySearch(ourAutoClosingChars, text.charAt(offset+1)) >= 0) {
|
||||
char the_quote = text.charAt(offset);
|
||||
// if we're next to two same quotes, don't auto-close, the user may want a triple quote
|
||||
if (
|
||||
offset >= 2 &&
|
||||
text.charAt(offset-1) == the_quote &&
|
||||
text.charAt(offset-2) == the_quote &&
|
||||
(offset < 3 || text.charAt(offset-3) != the_quote)
|
||||
) return false;
|
||||
// handle string literal context
|
||||
if (super.isOpeningQuote(iterator, offset)) {
|
||||
return true;
|
||||
}
|
||||
if (myLiteralTokenSet.contains(iterator.getTokenType())) {
|
||||
int start = iterator.getStart();
|
||||
if (offset - start <= 2) {
|
||||
if (getLiteralStartOffset(text, start) == offset) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int getLiteralStartOffset(CharSequence text, int start) {
|
||||
char c = Character.toUpperCase(text.charAt(start));
|
||||
if (c == 'U' || c == 'B') {
|
||||
start++;
|
||||
c = Character.toUpperCase(text.charAt(start));
|
||||
}
|
||||
if (c == 'R') {
|
||||
start++;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNonClosedLiteral(HighlighterIterator iterator, CharSequence chars) {
|
||||
if (getLiteralStartOffset(chars, iterator.getStart()) >= iterator.getEnd() - 1) return true;
|
||||
if (chars.charAt(iterator.getEnd() - 1) != '\"' && chars.charAt(iterator.getEnd() - 1) != '\'') return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +1,13 @@
|
||||
package com.jetbrains.python.editor;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.SimpleTokenSetQuoteHandler;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
* @author traff
|
||||
*/
|
||||
public class PythonQuoteHandler extends SimpleTokenSetQuoteHandler {
|
||||
|
||||
private static final char[] ourAutoClosingChars; // we add auto-close quotes before these
|
||||
static {
|
||||
ourAutoClosingChars = new char[]{'}', ']', ')', ',', ':', ';', ' ', '\t', '\n'};
|
||||
Arrays.sort(ourAutoClosingChars);
|
||||
}
|
||||
|
||||
public class PythonQuoteHandler extends BaseQuoteHandler {
|
||||
public PythonQuoteHandler() {
|
||||
super(PyTokenTypes.STRING_LITERAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOpeningQuote(HighlighterIterator iterator, int offset) {
|
||||
// don't assume an opening quote unless we're in an explicitly "blank" context
|
||||
CharSequence text = iterator.getDocument().getCharsSequence();
|
||||
if (offset+1 >= text.length() || Arrays.binarySearch(ourAutoClosingChars, text.charAt(offset+1)) >= 0) {
|
||||
char the_quote = text.charAt(offset);
|
||||
// if we're next to two same quotes, don't auto-close, the user may want a triple quote
|
||||
if (
|
||||
offset >= 2 &&
|
||||
text.charAt(offset-1) == the_quote &&
|
||||
text.charAt(offset-2) == the_quote &&
|
||||
(offset < 3 || text.charAt(offset-3) != the_quote)
|
||||
) return false;
|
||||
// handle string literal context
|
||||
if (super.isOpeningQuote(iterator, offset)) {
|
||||
return true;
|
||||
}
|
||||
if (myLiteralTokenSet.contains(iterator.getTokenType())) {
|
||||
int start = iterator.getStart();
|
||||
if (offset - start <= 2) {
|
||||
if (getLiteralStartOffset(text, start) == offset) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int getLiteralStartOffset(CharSequence text, int start) {
|
||||
char c = Character.toUpperCase(text.charAt(start));
|
||||
if (c == 'U' || c == 'B') {
|
||||
start++;
|
||||
c = Character.toUpperCase(text.charAt(start));
|
||||
}
|
||||
if (c == 'R') {
|
||||
start++;
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isNonClosedLiteral(HighlighterIterator iterator, CharSequence chars) {
|
||||
if (getLiteralStartOffset(chars, iterator.getStart()) >= iterator.getEnd() - 1) return true;
|
||||
if (chars.charAt(iterator.getEnd() - 1) != '\"' && chars.charAt(iterator.getEnd() - 1) != '\'') return true;
|
||||
return false;
|
||||
super(TokenSet.create(PyTokenTypes.STRING_LITERAL), new char[]{'}', ']', ')', ',', ':', ';', ' ', '\t', '\n'});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public class PythonFindUsagesProvider implements FindUsagesProvider {
|
||||
|
||||
@NotNull
|
||||
public String getType(@NotNull PsiElement element) {
|
||||
if (element instanceof PyNamedParameter) return "parameter";
|
||||
if (element instanceof PyNamedParameter) return "parameter"; //TODO: replace strings to messages
|
||||
if (element instanceof PyFunction) {
|
||||
if (((PyFunction) element).getContainingClass() != null) {
|
||||
return "method";
|
||||
|
||||
@@ -24,7 +24,7 @@ public class PyFileElementType extends IStubFileElementType {
|
||||
|
||||
@Override
|
||||
public int getStubVersion() {
|
||||
return 22;
|
||||
return 23;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -115,6 +115,9 @@ public class PyParameterListImpl extends PyBaseElementImpl<PyParameterListStub>
|
||||
if (nextParameter.isKeywordContainer() || nextParameter.isPositionalContainer()) {
|
||||
++i;
|
||||
}
|
||||
while (nextParameter.isKeywordContainer() && j<anotherParametersLength && anotherParameters[j].hasDefaultValue()) {
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,6 +127,9 @@ public class PyParameterListImpl extends PyBaseElementImpl<PyParameterListStub>
|
||||
if (nextParameter.isKeywordContainer() || nextParameter.isPositionalContainer()) {
|
||||
++j;
|
||||
}
|
||||
while (nextParameter.isKeywordContainer() && i<parametersLength && parameters[i].hasDefaultValue()) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (i >= parametersLength) && (j >= anotherParametersLength);
|
||||
|
||||
@@ -126,8 +126,8 @@ public class PyQualifiedReferenceImpl extends PyReferenceImpl {
|
||||
|
||||
PyType qualifierType = qualifier.getType(TypeEvalContext.slow());
|
||||
ProcessingContext ctx = new ProcessingContext();
|
||||
final Set<String> names_already = new HashSet<String>();
|
||||
ctx.put(PyType.CTX_NAMES, names_already);
|
||||
final Set<String> namesAlready = new HashSet<String>();
|
||||
ctx.put(PyType.CTX_NAMES, namesAlready);
|
||||
if (qualifierType != null) {
|
||||
Collection<Object> variants = new ArrayList<Object>();
|
||||
if (qualifier instanceof PyQualifiedExpression) {
|
||||
@@ -135,12 +135,12 @@ public class PyQualifiedReferenceImpl extends PyReferenceImpl {
|
||||
variants.addAll(attrs);
|
||||
for (PyExpression ex : attrs) {
|
||||
if (ex instanceof PyReferenceExpression) {
|
||||
PyReferenceExpression refex = (PyReferenceExpression)ex;
|
||||
names_already.add(refex.getReferencedName());
|
||||
PyReferenceExpression refExpr = (PyReferenceExpression)ex;
|
||||
namesAlready.add(refExpr.getReferencedName());
|
||||
}
|
||||
else if (ex instanceof PyTargetExpression) {
|
||||
PyTargetExpression targetExpr = (PyTargetExpression)ex;
|
||||
names_already.add(targetExpr.getName());
|
||||
namesAlready.add(targetExpr.getName());
|
||||
}
|
||||
}
|
||||
Collections.addAll(variants, qualifierType.getCompletionVariants(myElement, ctx));
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.jetbrains.django.util.DjangoStringUtil;
|
||||
import com.jetbrains.python.psi.PyElementGenerator;
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
public class PyStringLiteralExpressionManipulator extends AbstractElementManipulator<PyStringLiteralExpressionImpl> {
|
||||
public PyStringLiteralExpressionImpl handleContentChange(PyStringLiteralExpressionImpl element, TextRange range, String newContent) {
|
||||
String newName = range.replace(element.getText(), newContent);
|
||||
if (!DjangoStringUtil.isQuoted(newName)) {
|
||||
newName = '\'' + newName + '\'';
|
||||
}
|
||||
return (PyStringLiteralExpressionImpl)element
|
||||
.replace(PyElementGenerator.getInstance(element.getProject()).createStringLiteralAlreadyEscaped(newName));
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import com.intellij.util.Icons;
|
||||
import com.jetbrains.python.codeInsight.PyClassInsertHandler;
|
||||
import com.jetbrains.python.codeInsight.PyFunctionInsertHandler;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -37,10 +39,10 @@ public class VariantsProcessor implements PsiScopeProcessor {
|
||||
myNodeFilter = nodefilter;
|
||||
}
|
||||
|
||||
public VariantsProcessor(PsiElement context, final Condition<PsiElement> nodefilter, final Condition<String> namefilter) {
|
||||
public VariantsProcessor(PsiElement context, final Condition<PsiElement> nodeFilter, final Condition<String> nameFilter) {
|
||||
myContext = context;
|
||||
myNodeFilter = nodefilter;
|
||||
myNameFilter = namefilter;
|
||||
myNodeFilter = nodeFilter;
|
||||
myNameFilter = nameFilter;
|
||||
}
|
||||
|
||||
public void setNotice(@Nullable String notice) {
|
||||
@@ -110,18 +112,25 @@ 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 (nameIsAcceptable(referencedName)) {
|
||||
LookupElementBuilder lookup_item = setupItem(LookupElementBuilder.create(referencedName).setIcon(icon));
|
||||
LookupElementBuilder lookupItem = setupItem(LookupElementBuilder.create(referencedName).setIcon(icon));
|
||||
if (definer instanceof PyImportElement) { // set notice to imported module name if needed
|
||||
PsiElement maybe_from_import = definer.getParent();
|
||||
if (maybe_from_import instanceof PyFromImportStatement) {
|
||||
final PyFromImportStatement from_import = (PyFromImportStatement)maybe_from_import;
|
||||
PyReferenceExpression src = from_import.getImportSource();
|
||||
PsiElement maybeFromImport = definer.getParent();
|
||||
if (maybeFromImport instanceof PyFromImportStatement) {
|
||||
final PyFromImportStatement fromImport = (PyFromImportStatement)maybeFromImport;
|
||||
PyReferenceExpression src = fromImport.getImportSource();
|
||||
if (src != null) {
|
||||
lookup_item = setItemNotice(lookup_item, src.getName());
|
||||
lookupItem = setItemNotice(lookupItem, src.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
myVariants.put(referencedName, lookup_item);
|
||||
if (definer instanceof PyAssignmentStatement) {
|
||||
PyExpression value = ((PyAssignmentStatement)definer).getAssignedValue();
|
||||
PyType type = value.getType(TypeEvalContext.fast());
|
||||
if (type != null) {
|
||||
lookupItem = lookupItem.setTypeText(type.getName());
|
||||
}
|
||||
}
|
||||
myVariants.put(referencedName, lookupItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.jetbrains.python.psi.search;
|
||||
|
||||
import com.intellij.ide.highlighter.HtmlFileType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -15,7 +17,9 @@ import com.intellij.psi.search.UsageSearchContext;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.QueryExecutor;
|
||||
import com.jetbrains.django.lang.template.DjangoTemplateFileType;
|
||||
import com.jetbrains.django.lang.template.psi.impl.DjangoTemplateFileImpl;
|
||||
import com.jetbrains.django.util.PythonUtil;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
@@ -31,43 +35,13 @@ public class PyStringReferenceSearch implements QueryExecutor<PsiReference, Refe
|
||||
if (!(element instanceof PyElement) && !(element instanceof PsiDirectory) && !(element instanceof DjangoTemplateFileImpl)) {
|
||||
return true;
|
||||
}
|
||||
final String name = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
if (element instanceof PyFile) {
|
||||
return FileUtil.getNameWithoutExtension(((PyFile)element).getName());
|
||||
} else
|
||||
if (element instanceof PsiDirectory) {
|
||||
return ((PsiDirectory) element).getName();
|
||||
}
|
||||
if (element instanceof DjangoTemplateFileImpl) {
|
||||
return ((DjangoTemplateFileImpl) element).getName();
|
||||
}
|
||||
else {
|
||||
return ((PyElement)element).getName();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (StringUtil.isEmpty(name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SearchScope searchScope = params.getEffectiveSearchScope();
|
||||
if (searchScope instanceof GlobalSearchScope) {
|
||||
searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)searchScope, PythonFileType.INSTANCE);
|
||||
searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)searchScope, PythonFileType.INSTANCE
|
||||
);
|
||||
}
|
||||
|
||||
final TextOccurenceProcessor processor = new TextOccurenceProcessor() {
|
||||
public boolean execute(PsiElement e, int offsetInElement) {
|
||||
final PsiReference[] refs = e.getReferences();
|
||||
for (PsiReference ref : refs) {
|
||||
if (ref.isReferenceTo(element)) {
|
||||
return consumer.process(ref);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
return PsiManager.getInstance(element.getProject()).getSearchHelper().
|
||||
processElementsWithWord(processor, searchScope, name, UsageSearchContext.IN_STRINGS, true);
|
||||
return PythonUtil.searchElementStringReferences(consumer, element, searchScope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,31 +146,31 @@ public class PyClassType implements PyType {
|
||||
}
|
||||
|
||||
public Object[] getCompletionVariants(final PyQualifiedExpression referenceExpression, ProcessingContext context) {
|
||||
List<? extends PsiElement> class_list = new ParentMatcher(PyClass.class).search(referenceExpression);
|
||||
boolean within_our_class = class_list != null && class_list.get(0) == this;
|
||||
Set<String> names_already = context.get(CTX_NAMES);
|
||||
List<? extends PsiElement> classList = new ParentMatcher(PyClass.class).search(referenceExpression);
|
||||
boolean withinOurClass = classList != null && classList.get(0) == this;
|
||||
Set<String> namesAlready = context.get(CTX_NAMES);
|
||||
List<Object> ret = new ArrayList<Object>();
|
||||
Condition<String> underscore_filter = new PyUtil.UnderscoreFilter(PyUtil.getInitialUnderscores(referenceExpression.getName()));
|
||||
Condition<String> underscoreFilter = new PyUtil.UnderscoreFilter(PyUtil.getInitialUnderscores(referenceExpression.getName()));
|
||||
// from providers
|
||||
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
|
||||
for (PyDynamicMember member : provider.getMembers(myClass)) {
|
||||
final String name = member.getName();
|
||||
if (underscore_filter.value(name) || provider.hasUnderscoreWildCard(name)) {
|
||||
if (underscoreFilter.value(name) || provider.hasUnderscoreWildCard(name)) {
|
||||
ret.add(LookupElementBuilder.create(name).setIcon(member.getIcon()).setTypeText(member.getShortType()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// from our own class
|
||||
final VariantsProcessor processor = new VariantsProcessor(
|
||||
referenceExpression, new PyResolveUtil.FilterNotInstance(myClass), underscore_filter
|
||||
referenceExpression, new PyResolveUtil.FilterNotInstance(myClass), underscoreFilter
|
||||
);
|
||||
myClass.processDeclarations(processor, ResolveState.initial(), null, referenceExpression);
|
||||
if (names_already != null) {
|
||||
if (namesAlready != null) {
|
||||
for (LookupElement le : processor.getResultList()) {
|
||||
String name = le.getLookupString();
|
||||
if (names_already.contains(name)) continue;
|
||||
if (!within_our_class && isClassPrivate(name)) continue;
|
||||
names_already.add(name);
|
||||
if (namesAlready.contains(name)) continue;
|
||||
if (!withinOurClass && isClassPrivate(name)) continue;
|
||||
namesAlready.add(name);
|
||||
ret.add(le);
|
||||
}
|
||||
}
|
||||
@@ -181,8 +181,8 @@ public class PyClassType implements PyType {
|
||||
Object[] ancestry = (new PyClassType(ancestor, true)).getCompletionVariants(referenceExpression, context);
|
||||
for (Object ob : ancestry) {
|
||||
if (ob instanceof LookupElementBuilder) {
|
||||
final LookupElementBuilder lookup_elt = (LookupElementBuilder)ob;
|
||||
if (!isClassPrivate(lookup_elt.getLookupString())) ret.add(lookup_elt.setTypeText(ancestor.getName()));
|
||||
final LookupElementBuilder lookupElt = (LookupElementBuilder)ob;
|
||||
if (!isClassPrivate(lookupElt.getLookupString())) ret.add(lookupElt.setTypeText(ancestor.getName()));
|
||||
}
|
||||
else {
|
||||
if (!isClassPrivate(ob.toString())) ret.add(ob);
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -344,9 +345,16 @@ public class PyExtractMethodUtil {
|
||||
if (name == null){
|
||||
name = "foo";
|
||||
}
|
||||
final String result = validator.check(name);
|
||||
if (result != null){
|
||||
throw new CommonRefactoringUtil.RefactoringErrorHintException(result);
|
||||
final String error = validator.check(name);
|
||||
if (error != null){
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()){
|
||||
throw new CommonRefactoringUtil.RefactoringErrorHintException(error);
|
||||
}
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append(error).append(". ").append(RefactoringBundle.message("do.you.wish.to.continue"));
|
||||
if (Messages.showOkCancelDialog(builder.toString(), RefactoringBundle.message("warning.title"), Messages.getWarningIcon()) != 0){
|
||||
throw new CommonRefactoringUtil.RefactoringErrorHintException(error);
|
||||
}
|
||||
}
|
||||
final List<AbstractVariableData> data = new ArrayList<AbstractVariableData>();
|
||||
for (String in : fragment.getInputVariables()) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jetbrains.python.refactoring;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.fixtures.LightMarkedTestCase;
|
||||
import com.jetbrains.python.psi.PyReferenceExpression;
|
||||
@@ -22,14 +23,21 @@ public class PyInlineLocalTest extends LightMarkedTestCase {
|
||||
try {
|
||||
PsiElement element = map.values().iterator().next().getParent();
|
||||
PyReferenceExpression ref = null;
|
||||
if (element instanceof PyReferenceExpression) {
|
||||
while (element instanceof PyReferenceExpression) {
|
||||
ref = (PyReferenceExpression)element;
|
||||
element = ((PyReferenceExpression)element).getReference().resolve();
|
||||
PsiElement newElement = ((PyReferenceExpression)element).getReference().resolve();
|
||||
if (element == newElement) {
|
||||
break;
|
||||
}
|
||||
element = newElement;
|
||||
}
|
||||
PyInlineLocalHandler.invoke(myFixture.getProject(), myFixture.getEditor(), (PyTargetExpression)element, ref);
|
||||
if (expectedError != null) fail("expected error: '" + expectedError + "', got none");
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (!Comparing.equal(e.getMessage(), expectedError)) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
assertEquals(expectedError, e.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user