diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyElementGenerator.java b/python/psi-api/src/com/jetbrains/python/psi/PyElementGenerator.java index 009acc249478..3f28b98312ff 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyElementGenerator.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyElementGenerator.java @@ -77,6 +77,8 @@ public abstract class PyElementGenerator { public abstract PyNamedParameter createParameter(@NotNull String name); + public abstract PyKeywordArgument createKeywordArgument(LanguageLevel languageLevel, String keyword, String value); + public abstract PsiFile createDummyFile(LanguageLevel langLevel, String contents); public abstract PyExpressionStatement createDocstring(String content); diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyKeywordArgument.java b/python/psi-api/src/com/jetbrains/python/psi/PyKeywordArgument.java index 9254dc1c2c7c..40d7a93453e3 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyKeywordArgument.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyKeywordArgument.java @@ -1,12 +1,13 @@ package com.jetbrains.python.psi; +import com.intellij.psi.PsiNamedElement; import org.jetbrains.annotations.Nullable; import com.intellij.lang.ASTNode; /** * @author yole */ -public interface PyKeywordArgument extends PyExpression { +public interface PyKeywordArgument extends PyExpression, PsiNamedElement { @Nullable String getKeyword(); diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java index 6b53a9eaa80a..1673b8f26977 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyControlFlowBuilder.java @@ -96,7 +96,7 @@ public class PyControlFlowBuilder extends PyRecursiveElementVisitor { @Override public void visitPyElement(PyElement node) { - if (node instanceof PsiNamedElement) { + if (node instanceof PsiNamedElement && !(node instanceof PyKeywordArgument)) { myBuilder.startNode(node); myBuilder.addNode(ReadWriteInstruction.newInstruction(myBuilder, node, node.getName(), ReadWriteInstruction.ACCESS.WRITE)); } diff --git a/python/src/com/jetbrains/python/findUsages/PythonFindUsagesProvider.java b/python/src/com/jetbrains/python/findUsages/PythonFindUsagesProvider.java index ae4f7dc6c3bd..123b177b9b75 100644 --- a/python/src/com/jetbrains/python/findUsages/PythonFindUsagesProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PythonFindUsagesProvider.java @@ -47,6 +47,9 @@ public class PythonFindUsagesProvider implements FindUsagesProvider { } return "variable"; } + if (element instanceof PyKeywordArgument) { + return "keyword argument"; + } return ""; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java index c5030321122e..f7209cf0cb9b 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyElementGeneratorImpl.java @@ -239,6 +239,12 @@ public class PyElementGeneratorImpl extends PyElementGenerator { return createFromText(LanguageLevel.getDefault(), PyNamedParameter.class, "def f(" + name + "): pass", PATH_PARAMETER); } + @Override + public PyKeywordArgument createKeywordArgument(LanguageLevel languageLevel, String keyword, String value) { + PyCallExpression callExpression = (PyCallExpression) createExpressionFromText(languageLevel, "foo(" + keyword + "=" + value + ")"); + return (PyKeywordArgument) callExpression.getArguments()[0]; + } + @NotNull public T createFromText(LanguageLevel langLevel, Class aClass, final String text, final int[] path) { PsiElement ret = createDummyFile(langLevel, text); diff --git a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java index 91c14a15db2c..c1e05dc0f364 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentImpl.java @@ -1,13 +1,18 @@ package com.jetbrains.python.psi.impl; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.psi.PyElementGenerator; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyKeywordArgument; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -53,4 +58,19 @@ public class PyKeywordArgumentImpl extends PyElementImpl implements PyKeywordArg } return null; } + + @Override + public String getName() { + return getKeyword(); + } + + @Override + public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { + PyElementGenerator generator = PyElementGenerator.getInstance(getProject()); + PyExpression expression = getValueExpression(); + PyKeywordArgument keywordArgument = generator.createKeywordArgument(LanguageLevel.forElement(this), name, + expression != null ? expression.getText() : name); + getNode().replaceChild(getKeywordNode(), keywordArgument.getKeywordNode()); + return this; + } }