mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
Drop psi builder cache on pushing or popping parsing scope (PY-36167)
Since builder could cache something related to the current scope (e.g. token type) GitOrigin-RevId: ffabda058dac874bd9187fa27d30b823f782fcf6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
64958a33d1
commit
8d1b70c5bb
@@ -42,11 +42,15 @@ public class ParsingContext {
|
||||
|
||||
@NotNull
|
||||
public ParsingScope popScope() {
|
||||
return myScopes.pop();
|
||||
final ParsingScope prevScope = myScopes.pop();
|
||||
resetBuilderCache(prevScope);
|
||||
return prevScope;
|
||||
}
|
||||
|
||||
public void pushScope(@NotNull ParsingScope scope) {
|
||||
final ParsingScope prevScope = getScope();
|
||||
myScopes.push(scope);
|
||||
resetBuilderCache(prevScope);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -77,4 +81,12 @@ public class ParsingContext {
|
||||
public ParsingScope emptyParsingScope() {
|
||||
return new ParsingScope();
|
||||
}
|
||||
|
||||
private void resetBuilderCache(@NotNull ParsingScope prevScope) {
|
||||
if (!getScope().equals(prevScope)) {
|
||||
// builder could cache some data based on the previous scope (e.g. token type)
|
||||
// and we have to reset its cache if scope has changed
|
||||
getBuilder().mark().rollbackTo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.jetbrains.python.parsing;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
@@ -82,4 +84,22 @@ public class ParsingScope {
|
||||
result.mySuite = mySuite;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof ParsingScope)) return false;
|
||||
|
||||
final ParsingScope scope = (ParsingScope)o;
|
||||
return myFunction == scope.myFunction &&
|
||||
myClass == scope.myClass &&
|
||||
mySuite == scope.mySuite &&
|
||||
myAfterSemicolon == scope.myAfterSemicolon &&
|
||||
myAsync == scope.myAsync;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(myFunction, myClass, mySuite, myAfterSemicolon, myAsync);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -925,6 +925,11 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON38);
|
||||
}
|
||||
|
||||
// PY-36167
|
||||
public void testFunctionWithPassAndAwaitAfterInPy36() {
|
||||
doTest(LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
public void doTest() {
|
||||
doTest(LanguageLevel.PYTHON26);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
async def a():
|
||||
def e(): pass
|
||||
await undefined
|
||||
32
python/testData/psi/FunctionWithPassAndAwaitAfterInPy36.txt
Normal file
32
python/testData/psi/FunctionWithPassAndAwaitAfterInPy36.txt
Normal file
@@ -0,0 +1,32 @@
|
||||
PyFile:FunctionWithPassAndAwaitAfterInPy36.py
|
||||
PyFunction('a')
|
||||
PsiElement(Py:ASYNC_KEYWORD)('async')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:DEF_KEYWORD)('def')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('a')
|
||||
PyParameterList
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
PyFunction('e')
|
||||
PsiElement(Py:DEF_KEYWORD)('def')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('e')
|
||||
PyParameterList
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyPassStatement
|
||||
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyExpressionStatement
|
||||
PyPrefixExpression
|
||||
PsiElement(Py:AWAIT_KEYWORD)('await')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: undefined
|
||||
PsiElement(Py:IDENTIFIER)('undefined')
|
||||
Reference in New Issue
Block a user