Move file-level language level processing to PythonLanguageLevelPusher

GitOrigin-RevId: f3be772f643c75652ea3557ef34ec62518a558d2
This commit is contained in:
Semyon Proshev
2020-04-29 22:04:28 +00:00
committed by intellij-monorepo-bot
parent 44ebee4295
commit e0a2c6bed7
8 changed files with 27 additions and 16 deletions
@@ -16,9 +16,9 @@
package com.jetbrains.python.psi;
import com.google.common.collect.ImmutableList;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -96,6 +96,7 @@ public enum LanguageLevel {
private static final LanguageLevel DEFAULT2 = PYTHON27;
private static final LanguageLevel DEFAULT3 = PYTHON39;
@ApiStatus.Internal
public static LanguageLevel FORCE_LANGUAGE_LEVEL = null;
@NotNull
@@ -217,8 +218,6 @@ public enum LanguageLevel {
return version / 10 + "." + version % 10;
}
public static final Key<String> KEY = new Key<>("python.language.level");
@NotNull
public static LanguageLevel forElement(@NotNull PsiElement element) {
return PyPsiFacade.getInstance(element.getProject()).getLanguageLevel(element);
@@ -582,7 +582,7 @@ public class PyUtil {
// Most of the cases should be handled by this one, PyLanguageLevelPusher pushes folders only
final VirtualFile folder = virtualFile.getParent();
if (folder != null) {
final LanguageLevel folderLevel = LanguageLevel.fromPythonVersion(folder.getUserData(LanguageLevel.KEY));
final LanguageLevel folderLevel = PythonLanguageLevelPusher.specifiedFileLanguageLevel(folder);
if (folderLevel != null) {
return folderLevel;
}
@@ -594,7 +594,7 @@ public class PyUtil {
else {
// However this allows us to setup language level per file manually
// in case when it is LightVirtualFile
final LanguageLevel level = LanguageLevel.fromPythonVersion(virtualFile.getUserData(LanguageLevel.KEY));
final LanguageLevel level = PythonLanguageLevelPusher.specifiedFileLanguageLevel(virtualFile);
if (level != null) return level;
if (ApplicationManager.getApplication().isUnitTestMode()) {
@@ -65,7 +65,7 @@ public class PyElementGeneratorImpl extends PyElementGenerator {
final PsiFileFactory factory = PsiFileFactory.getInstance(myProject);
final String name = getDummyFileName();
final LightVirtualFile virtualFile = new LightVirtualFile(name, PythonFileType.INSTANCE, contents);
virtualFile.putUserData(LanguageLevel.KEY, LanguageLevel.toPythonVersion(langLevel));
PythonLanguageLevelPusher.specifyFileLanguageLevel(virtualFile, langLevel);
final PsiFile psiFile = ((PsiFileFactoryImpl)factory).trySetupPsiForFile(virtualFile, PythonLanguage.getInstance(), physical, true);
assert psiFile != null;
return psiFile;
@@ -52,7 +52,7 @@ import java.util.stream.Collectors;
* @author yole
*/
public class PythonLanguageLevelPusher implements FilePropertyPusher<String> {
private static final Key<String> PYTHON_LANGUAGE_LEVEL = Key.create("PYTHON_LANGUAGE_LEVEL");
private static final Key<String> KEY = new Key<>("python.language.level");
/* It so happens that no single language level is compatible with more than one other.
So a map suffices for representation*/
public static final Map<LanguageLevel, LanguageLevel> COMPATIBLE_LEVELS;
@@ -85,7 +85,7 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<String> {
@Override
@NotNull
public Key<String> getFileDataKey() {
return LanguageLevel.KEY;
return KEY;
}
@Override
@@ -306,17 +306,17 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<String> {
@NotNull
public static LanguageLevel guessLanguageLevelWithCaching(@NotNull Project project) {
LanguageLevel languageLevel = LanguageLevel.fromPythonVersion(project.getUserData(PYTHON_LANGUAGE_LEVEL));
LanguageLevel languageLevel = LanguageLevel.fromPythonVersion(project.getUserData(KEY));
if (languageLevel == null) {
languageLevel = guessLanguageLevel(project);
project.putUserData(PYTHON_LANGUAGE_LEVEL, LanguageLevel.toPythonVersion(languageLevel));
project.putUserData(KEY, LanguageLevel.toPythonVersion(languageLevel));
}
return languageLevel;
}
private static void resetProjectLanguageLevel(@NotNull Project project) {
project.putUserData(PYTHON_LANGUAGE_LEVEL, null);
project.putUserData(KEY, null);
}
@NotNull
@@ -399,6 +399,15 @@ public class PythonLanguageLevelPusher implements FilePropertyPusher<String> {
PushedFilePropertiesUpdater.getInstance(project).pushAll(new PythonLanguageLevelPusher());
}
public static void specifyFileLanguageLevel(@NotNull VirtualFile file, @Nullable LanguageLevel languageLevel) {
file.putUserData(KEY, LanguageLevel.toPythonVersion(languageLevel));
}
@Nullable
public static LanguageLevel specifiedFileLanguageLevel(@NotNull VirtualFile file) {
return LanguageLevel.fromPythonVersion(file.getUserData(KEY));
}
public void flushLanguageLevelCache() {
myModuleSdks.clear();
}
@@ -12,10 +12,10 @@ import com.intellij.openapi.editor.markup.TextAttributes
import com.intellij.psi.util.PsiTreeUtil
import com.jetbrains.python.console.pydev.ConsoleCommunication
import com.jetbrains.python.console.pydev.ConsoleCommunicationListener
import com.jetbrains.python.psi.LanguageLevel
import com.jetbrains.python.psi.PyElementGenerator
import com.jetbrains.python.psi.PyFile
import com.jetbrains.python.psi.PyStatementList
import com.jetbrains.python.psi.PyUtil
import java.awt.Font
open class PydevConsoleExecuteActionHandler(private val myConsoleView: LanguageConsoleView,
@@ -51,7 +51,7 @@ open class PydevConsoleExecuteActionHandler(private val myConsoleView: LanguageC
}
override fun checkSingleLine(text: String): Boolean {
val languageLevel = LanguageLevel.fromPythonVersion(myConsoleView.virtualFile.getUserData(LanguageLevel.KEY))
val languageLevel = PyUtil.getLanguageLevelForVirtualFile(project, myConsoleView.virtualFile)
val pyFile = PyElementGenerator.getInstance(project).createDummyFile(languageLevel, text) as PyFile
return PsiTreeUtil.findChildOfAnyType(pyFile, PyStatementList::class.java) == null && pyFile.statements.size < 2
}
@@ -48,6 +48,7 @@ import com.jetbrains.python.debugger.PyStackFrame;
import com.jetbrains.python.debugger.PyStackFrameInfo;
import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import com.jetbrains.python.sdk.PythonSdkType;
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor;
import com.jetbrains.python.testing.PyTestsSharedKt;
@@ -88,7 +89,7 @@ public class PythonConsoleView extends LanguageConsoleImpl implements Observable
myTestMode = testMode;
isShowVars = PyConsoleOptions.getInstance(project).isShowVariableByDefault();
VirtualFile virtualFile = getVirtualFile();
virtualFile.putUserData(LanguageLevel.KEY, LanguageLevel.toPythonVersion(PythonSdkType.getLanguageLevelForSdk(sdk)));
PythonLanguageLevelPusher.specifyFileLanguageLevel(virtualFile, PythonSdkType.getLanguageLevelForSdk(sdk));
virtualFile.putUserData(CONSOLE_KEY, true);
// Mark editor as console one, to prevent autopopup completion
getConsoleEditor().putUserData(PythonConsoleAutopopupBlockingHandler.REPL_KEY, new Object());
@@ -12,6 +12,7 @@ import com.intellij.testFramework.ParsingTestCase;
import com.intellij.testFramework.TestDataPath;
import com.jetbrains.python.*;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import org.jetbrains.annotations.NotNull;
import java.nio.charset.StandardCharsets;
@@ -112,7 +113,7 @@ public class PythonConsoleParsingTest extends ParsingTestCase {
virtualFile.setOriginalFile(originalFile);
originalFile.setCharset(StandardCharsets.UTF_8);
originalFile.putUserData(LanguageLevel.KEY, LanguageLevel.toPythonVersion(myLanguageLevel));
PythonLanguageLevelPusher.specifyFileLanguageLevel(originalFile, myLanguageLevel);
PyConsoleUtil.markIPython(originalFile);
return createFile(virtualFile);
}
@@ -12,6 +12,7 @@ import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyPsiFacade;
import com.jetbrains.python.psi.impl.PyPsiFacadeImpl;
import com.jetbrains.python.psi.impl.PythonASTFactory;
import com.jetbrains.python.psi.impl.PythonLanguageLevelPusher;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
@@ -954,7 +955,7 @@ public class PythonParsingTest extends ParsingTestCase {
@Override
protected PsiFile createFile(@NotNull String name, @NotNull String text) {
final PsiFile file = super.createFile(name, text);
file.getVirtualFile().putUserData(LanguageLevel.KEY, LanguageLevel.toPythonVersion(myLanguageLevel));
PythonLanguageLevelPusher.specifyFileLanguageLevel(file.getVirtualFile(), myLanguageLevel);
return file;
}