mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixes PY-105: "with" statement becomes a name definer and resolutions to its 'as' name works.
This commit is contained in:
@@ -586,7 +586,7 @@ public class StatementParsing
|
||||
getExpressionParser().parseExpression();
|
||||
if (myBuilder.getTokenType() == PyTokenTypes.AS_KEYWORD) {
|
||||
myBuilder.advanceLexer();
|
||||
getExpressionParser().parseExpression();
|
||||
getExpressionParser().parseExpression(true, true); // 'as' is followed by a target
|
||||
}
|
||||
checkMatches(PyTokenTypes.COLON, "colon expected");
|
||||
parseSuite();
|
||||
|
||||
@@ -3,5 +3,5 @@ package com.jetbrains.python.psi;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public interface PyWithStatement extends PyStatement {
|
||||
public interface PyWithStatement extends PyStatement, NameDefiner {
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.jetbrains.python.psi.PyElementVisitor;
|
||||
import com.jetbrains.python.psi.PyWithStatement;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -15,4 +18,26 @@ public class PyWithStatementImpl extends PyElementImpl implements PyWithStatemen
|
||||
protected void acceptPyVisitor(final PyElementVisitor pyVisitor) {
|
||||
pyVisitor.visitPyWithStatement(this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyExpression getTargetExpression() {
|
||||
final ASTNode asNameNode = getNode().findChildByType(PyElementTypes.TARGET_EXPRESSION);
|
||||
if (asNameNode == null) return null;
|
||||
return (PyTargetExpression)asNameNode.getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Iterable<PyElement> iterateNames() {
|
||||
PyElement ret = getTargetExpression();
|
||||
return new SingleIterable<PyElement>(ret);
|
||||
}
|
||||
|
||||
public PsiElement getElementNamed(final String the_name) {
|
||||
PyElement named_elt = IterHelper.findName(iterateNames(), the_name);
|
||||
return named_elt;
|
||||
}
|
||||
|
||||
public boolean mustResolveOutside() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ PyFile:WithStatement.py
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:AS_KEYWORD)('as')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: y
|
||||
PyTargetExpression: y
|
||||
PsiElement(Py:IDENTIFIER)('y')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
|
||||
@@ -55,7 +55,7 @@ PyFile:WithStatement2.py
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:AS_KEYWORD)('as')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: y
|
||||
PyTargetExpression: y
|
||||
PsiElement(Py:IDENTIFIER)('y')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from __future__ import with_statement
|
||||
with None as boom:
|
||||
<ref>boom + 1
|
||||
@@ -140,6 +140,11 @@ public class PyResolveTest extends ResolveTestCase {
|
||||
assertNotNull(PsiTreeUtil.getParentOfType(targetElement, PyAssignmentStatement.class)); // it's deep in a tuple
|
||||
}
|
||||
|
||||
public void testWithStatement() throws Exception {
|
||||
PsiElement targetElement = resolve();
|
||||
assertTrue(targetElement instanceof PyTargetExpression);
|
||||
assertTrue(targetElement.getParent() instanceof PyWithStatement);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user